@qwen-code/qwen-code 0.19.12-preview.0 → 0.19.12

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 (149) hide show
  1. package/bundled/qc-helper/docs/features/channels/overview.md +4 -2
  2. package/chunks/{MaxSizedBox-3KIWAU6Z.js → MaxSizedBox-QOXLJGAF.js} +4 -4
  3. package/chunks/{StandaloneSessionPicker-TF626NO7.js → StandaloneSessionPicker-FLV6CGYJ.js} +16 -16
  4. package/chunks/{acpAgent-JDVJXVBO.js → acpAgent-OB2CTF3P.js} +46 -46
  5. package/chunks/{agent-BONWC4VY.js → agent-CKSI7BTR.js} +4 -4
  6. package/chunks/{agent-headless-H7HKMGLZ.js → agent-headless-U36LIYTU.js} +4 -4
  7. package/chunks/{bridge-ATN2TLWJ.js → bridge-AIKTINJG.js} +7 -7
  8. package/chunks/{channel-worker-group-S3H5QHTI.js → channel-worker-group-NEUVTPB2.js} +4 -4
  9. package/chunks/{channel-worker-manager-ZJ4HTMO2.js → channel-worker-manager-7CQVOVWV.js} +4 -4
  10. package/chunks/{channel-worker-supervisor-JA6VZ5V5.js → channel-worker-supervisor-3BU2KNCZ.js} +3 -3
  11. package/chunks/{chunk-SMASS3CY.js → chunk-2476XGOU.js} +1 -1
  12. package/chunks/{chunk-QGONRHUS.js → chunk-2CCDMJM7.js} +1 -1
  13. package/chunks/{chunk-F2YCCUXI.js → chunk-3B6PSWHE.js} +3 -3
  14. package/chunks/{chunk-XACBIZJB.js → chunk-3ESL7JXA.js} +1 -1
  15. package/chunks/{chunk-DYUPBU7H.js → chunk-42VIHAYT.js} +1 -1
  16. package/chunks/{chunk-PTXVHS2O.js → chunk-4MPYGENG.js} +4 -4
  17. package/chunks/{chunk-IQRQVPGN.js → chunk-4SJJT466.js} +20 -20
  18. package/chunks/{chunk-WTHRMVKB.js → chunk-5N7M4XYN.js} +3 -3
  19. package/chunks/{chunk-ZFHHBRRA.js → chunk-5QSVANRT.js} +1 -1
  20. package/chunks/{chunk-TFV3XVAZ.js → chunk-64GC5EMF.js} +1 -1
  21. package/chunks/{chunk-JUNVFQVY.js → chunk-67Q33DQY.js} +4 -4
  22. package/chunks/{chunk-7KS72E2N.js → chunk-6ETOSWAO.js} +1 -1
  23. package/chunks/{chunk-ILQ42UG6.js → chunk-6IITZE7O.js} +5 -5
  24. package/chunks/{chunk-7O7WZH7N.js → chunk-APOFULHK.js} +1 -1
  25. package/chunks/{chunk-53UMEONK.js → chunk-BABX5XRO.js} +1 -1
  26. package/chunks/{chunk-MHEZV3OY.js → chunk-BKNPMEN6.js} +157 -58
  27. package/chunks/{chunk-66F4IJ4L.js → chunk-CHPQFLW6.js} +3 -3
  28. package/chunks/{chunk-YN2I5I42.js → chunk-CPU6I5YV.js} +4 -4
  29. package/chunks/{chunk-OZWJAFFE.js → chunk-DJ4VHAFJ.js} +3 -3
  30. package/chunks/{chunk-SNONG66P.js → chunk-DUR7BZYK.js} +7 -7
  31. package/chunks/{chunk-CHVH4DVN.js → chunk-EDFD7VOX.js} +1 -1
  32. package/chunks/{chunk-NJQPQ4IO.js → chunk-EFAXBOQO.js} +7 -7
  33. package/chunks/{chunk-BEFQGC6H.js → chunk-EISVEV45.js} +2 -2
  34. package/chunks/{chunk-NVUGS23Y.js → chunk-ETN2G32U.js} +4 -4
  35. package/chunks/{chunk-54KPEDM2.js → chunk-FUSMC3SZ.js} +3 -3
  36. package/chunks/{chunk-6TDA4EVC.js → chunk-GCY7QTCE.js} +708 -292
  37. package/chunks/{chunk-JCYMQU5F.js → chunk-GFYFLDEG.js} +2 -2
  38. package/chunks/{chunk-W4DFAUAO.js → chunk-GLH2NTPB.js} +1 -1
  39. package/chunks/{chunk-XFJU7SVP.js → chunk-GMUPIMHF.js} +1 -1
  40. package/chunks/{chunk-CXWUXRD5.js → chunk-GSPWDTYY.js} +10 -10
  41. package/chunks/{chunk-6WZZHJSZ.js → chunk-GW7BONBU.js} +3 -3
  42. package/chunks/{chunk-WACI4VES.js → chunk-GXFYV7MP.js} +4 -4
  43. package/chunks/{chunk-HQ7MDVBO.js → chunk-HD6EGS5K.js} +5 -5
  44. package/chunks/{chunk-2DZ7E27L.js → chunk-HVGJWOR6.js} +2 -2
  45. package/chunks/{chunk-7LMAKIWE.js → chunk-HZ4M2UQD.js} +1 -1
  46. package/chunks/{chunk-HVWPSGDY.js → chunk-I7RRHHYG.js} +1 -1
  47. package/chunks/{chunk-IKLWU6YS.js → chunk-KGWA7XYL.js} +4 -4
  48. package/chunks/{chunk-DULSE2SH.js → chunk-KMJOMWHE.js} +1 -1
  49. package/chunks/{chunk-R32BTEZY.js → chunk-KNGZ5EYL.js} +1 -1
  50. package/chunks/{chunk-4AGBO6RB.js → chunk-KRMARA3A.js} +2 -2
  51. package/chunks/{chunk-675SVDMD.js → chunk-LUJQUNKY.js} +9 -9
  52. package/chunks/{chunk-6QGZVKOO.js → chunk-MRE77ST5.js} +4 -4
  53. package/chunks/{chunk-LODZMRXC.js → chunk-N47VAEAJ.js} +10 -10
  54. package/chunks/{chunk-PSISZNIT.js → chunk-NALRQ3SG.js} +36 -28
  55. package/chunks/{chunk-K7P34F2J.js → chunk-NE6HHLL3.js} +1 -1
  56. package/chunks/{chunk-Z4ZCVYJ5.js → chunk-NPMVLWYL.js} +3 -3
  57. package/chunks/{chunk-4W55BHOC.js → chunk-OBSLEYCD.js} +1 -1
  58. package/chunks/{chunk-MCYZTKBV.js → chunk-OEHCAWUA.js} +2 -2
  59. package/chunks/{chunk-ZPVGEMVC.js → chunk-PK7COE5O.js} +1 -1
  60. package/chunks/{chunk-NGTQA57Y.js → chunk-PR5XQ73G.js} +1 -1
  61. package/chunks/{chunk-FEZXQXW2.js → chunk-PUKUUASO.js} +1 -1
  62. package/chunks/{chunk-LHEQDKAR.js → chunk-QIFTJDBY.js} +1 -1
  63. package/chunks/{chunk-LYFDJTXE.js → chunk-R3EDIMYZ.js} +1 -1
  64. package/chunks/{chunk-HZXU6YZW.js → chunk-RKUMFUFM.js} +4 -4
  65. package/chunks/{chunk-3PE7OY2G.js → chunk-TKASNYDS.js} +1 -1
  66. package/chunks/{chunk-EWPLL4OT.js → chunk-UCTCDLDS.js} +1 -1
  67. package/chunks/{chunk-LLIGYAQU.js → chunk-UZC5VPOJ.js} +2 -2
  68. package/chunks/{chunk-CMHJEUVB.js → chunk-VEFR4XJQ.js} +1 -1
  69. package/chunks/{chunk-AWOU24F6.js → chunk-VLHQMOZK.js} +3 -3
  70. package/chunks/{chunk-4OVECYBM.js → chunk-W4UN42YP.js} +4 -4
  71. package/chunks/{chunk-E655RDRL.js → chunk-W6CQPLWM.js} +1 -1
  72. package/chunks/{chunk-Y5UDBQYF.js → chunk-WIYV7CSF.js} +2 -2
  73. package/chunks/{chunk-7OZGMFHC.js → chunk-XSEWNUMZ.js} +5 -5
  74. package/chunks/{chunk-R4RIMOJL.js → chunk-ZGT623SG.js} +10 -10
  75. package/chunks/{chunk-NSZJQACR.js → chunk-ZSDFNE6Y.js} +1 -1
  76. package/chunks/{computer-use-UY4A72X7.js → computer-use-4PUGCUQK.js} +4 -4
  77. package/chunks/{config-utils-KWTRFP7D.js → config-utils-6PJUXHLI.js} +3 -3
  78. package/chunks/{contextCommand-3DZ2SVH6.js → contextCommand-C57KTWFV.js} +6 -6
  79. package/chunks/{create-sub-session-OT7WXLDO.js → create-sub-session-5Q42XR6I.js} +4 -4
  80. package/chunks/{daemon-status-provider-GTZOYSBO.js → daemon-status-provider-YPV3UXHT.js} +11 -11
  81. package/chunks/{dist-RZBJT5O2.js → dist-3DQNQJ6H.js} +1 -1
  82. package/chunks/{dist-HCUUS6IH.js → dist-IEQSDXS7.js} +2 -2
  83. package/chunks/{dist-Y54RURGT.js → dist-IGZMVS5R.js} +1 -1
  84. package/chunks/{dist-O2IP3G5D.js → dist-J2H4KTLB.js} +1 -1
  85. package/chunks/{dist-ZJHKKWUD.js → dist-NUXRQHC5.js} +1 -1
  86. package/chunks/{dist-YTPTCUAD.js → dist-XLE6ODMB.js} +1 -1
  87. package/chunks/{earlyInputCapture-GGWVGBZ7.js → earlyInputCapture-5VDWSYAM.js} +4 -4
  88. package/chunks/{edit-JN467GIR.js → edit-GORZTX2U.js} +5 -5
  89. package/chunks/{enter-worktree-MMO4VBQE.js → enter-worktree-LJB2AW4L.js} +4 -4
  90. package/chunks/{enterPlanMode-BRZOG4DB.js → enterPlanMode-LIIPP37T.js} +4 -4
  91. package/chunks/{environment-LOCDCWMZ.js → environment-HQ2UHJ35.js} +6 -6
  92. package/chunks/{errors-XXSL5HGG.js → errors-6JD5VMVQ.js} +6 -6
  93. package/chunks/{exit-worktree-UD7PI5H5.js → exit-worktree-IEP2WHOV.js} +4 -4
  94. package/chunks/{exitPlanMode-EIUETQI6.js → exitPlanMode-U5Z6XBLO.js} +4 -4
  95. package/chunks/{fast-path-ULGAEUVK.js → fast-path-HFKNMP23.js} +2 -2
  96. package/chunks/{gemini-KW3APZ4P.js → gemini-C2SCJH3N.js} +40 -40
  97. package/chunks/{geminiContentGenerator-4BQ5QHPR.js → geminiContentGenerator-ADZTXEKV.js} +1 -1
  98. package/chunks/{glob-FPKAMR6B.js → glob-GOAPGD6G.js} +4 -4
  99. package/chunks/{grep-MOGRCYB4.js → grep-HZLSTX7D.js} +4 -4
  100. package/chunks/{handleAutoUpdate-QUMRZZOS.js → handleAutoUpdate-UF74WGFE.js} +8 -8
  101. package/chunks/{i18n-F3W6YUYP.js → i18n-FMXIYUOC.js} +5 -5
  102. package/chunks/{initializer-KLU2KAIZ.js → initializer-ERDBM3DU.js} +9 -9
  103. package/chunks/{installationInfo-P3ZP2SIZ.js → installationInfo-LROMXYLX.js} +5 -5
  104. package/chunks/{list-4X6D5JD2.js → list-6JPJROU5.js} +12 -12
  105. package/chunks/{loadedSettingsAdapter-446B6WKA.js → loadedSettingsAdapter-QCWYUBBF.js} +9 -9
  106. package/chunks/{mcp-JYVOJZOD.js → mcp-3P3KWYWO.js} +9 -9
  107. package/chunks/{monitor-KY7YH7TL.js → monitor-LMYKCF6R.js} +4 -4
  108. package/chunks/{nonInteractiveCli-EK35TLVJ.js → nonInteractiveCli-YURFHZV5.js} +39 -39
  109. package/chunks/{notebook-edit-IHGW42QK.js → notebook-edit-IBEOVZ6A.js} +5 -5
  110. package/chunks/{openaiContentGenerator-FURUCKQJ.js → openaiContentGenerator-42PZKET5.js} +2 -2
  111. package/chunks/{pidfile-WKUVXDMR.js → pidfile-VTBDIGOH.js} +4 -4
  112. package/chunks/{processUtils-LHSRN76X.js → processUtils-L7ZKOGDG.js} +2 -2
  113. package/chunks/{qwenContentGenerator-NRLM7R36.js → qwenContentGenerator-VR2CNFGI.js} +5 -5
  114. package/chunks/{qwenOAuth2-5FNX3AWH.js → qwenOAuth2-6LS2T3Q6.js} +3 -3
  115. package/chunks/{read-file-VLEAEXFP.js → read-file-VSKOE22I.js} +1 -1
  116. package/chunks/{ripGrep-MT23EIDD.js → ripGrep-5V5FLW2A.js} +4 -4
  117. package/chunks/{run-qwen-serve-5HWOQFLI.js → run-qwen-serve-LSOPP4R2.js} +30 -30
  118. package/chunks/{runtime-6IVKJSLW.js → runtime-LT7R4CS5.js} +13 -13
  119. package/chunks/{scheduler-63GJG75U.js → scheduler-YOWQ7KZP.js} +4 -4
  120. package/chunks/{serve-3LL7RRDP.js → serve-VWLBXKGK.js} +9 -9
  121. package/chunks/{server-AA24QLPA.js → server-3RW3FYOH.js} +32 -32
  122. package/chunks/{session-LRVCFQQQ.js → session-ZONXFOBQ.js} +40 -40
  123. package/chunks/{settings-ZX3OKUT4.js → settings-JC3VC53L.js} +8 -8
  124. package/chunks/{shell-KR3IMYH6.js → shell-2NGEMAVM.js} +4 -4
  125. package/chunks/{skill-QLM2LSF7.js → skill-3U2T6H3E.js} +1 -1
  126. package/chunks/{spawnChannel-6WFOK3SA.js → spawnChannel-QEAUPARQ.js} +6 -6
  127. package/chunks/{src-ADLNIPHD.js → src-75ZPXO7B.js} +4 -4
  128. package/chunks/{standalone-update-C54OTJWJ.js → standalone-update-UUJWJWYY.js} +6 -6
  129. package/chunks/{startInteractiveUI-KFAOS6HC.js → startInteractiveUI-V7XISPQ6.js} +62 -54
  130. package/chunks/{team-create-Q5B5M7UD.js → team-create-R6AXDYPG.js} +4 -4
  131. package/chunks/{team-plan-approval-J55PXNY2.js → team-plan-approval-O2ZPPT64.js} +4 -4
  132. package/chunks/{theme-manager-QWTDRPHV.js → theme-manager-YIX2IC2D.js} +4 -4
  133. package/chunks/{tool-search-LSSKWZKH.js → tool-search-5IE2VO7X.js} +1 -1
  134. package/chunks/{total-session-admission-S6ATY5HY.js → total-session-admission-K6APQYEF.js} +7 -7
  135. package/chunks/{trustedFolders-CY4TUPDJ.js → trustedFolders-GPSSPVBF.js} +5 -5
  136. package/chunks/{update-relaunch-IOKOUV3K.js → update-relaunch-4BVAPX6Y.js} +5 -5
  137. package/chunks/{updateCheck-YNRFE4V7.js → updateCheck-AHTHWLAM.js} +6 -6
  138. package/chunks/{validateNonInterActiveAuth-OXTECS4B.js → validateNonInterActiveAuth-UKAPCWDM.js} +35 -35
  139. package/chunks/{version-2CZQQDL5.js → version-EXGWKKQE.js} +1 -1
  140. package/chunks/{web-fetch-7QTEGJI5.js → web-fetch-ZDNE6FF2.js} +2 -2
  141. package/chunks/{workflow-G3CZU256.js → workflow-G7U6OQWS.js} +5 -5
  142. package/chunks/{workspace-providers-status-UHQOIPAZ.js → workspace-providers-status-W6CEA6YM.js} +12 -12
  143. package/chunks/{workspace-registration-store-5WPCMX4F.js → workspace-registration-store-OGBMWCLC.js} +1 -1
  144. package/chunks/{workspace-registry-LAQCRQTH.js → workspace-registry-ZUWQM44P.js} +7 -7
  145. package/chunks/{workspace-service-6ZEUJY2Z.js → workspace-service-UXX5P7GU.js} +13 -13
  146. package/chunks/{workspace-skills-status-YG6OITSM.js → workspace-skills-status-635B5R7N.js} +10 -10
  147. package/chunks/{write-file-E7T3PU3B.js → write-file-DR3HN7IH.js} +5 -5
  148. package/cli.js +11 -11
  149. package/package.json +3 -3
@@ -149,7 +149,7 @@ import {
149
149
  isFallbackEligible,
150
150
  isUnattendedMode,
151
151
  retryWithBackoff
152
- } from "./chunk-7KS72E2N.js";
152
+ } from "./chunk-6ETOSWAO.js";
153
153
  import {
154
154
  openBrowserSecurely,
155
155
  shouldAttemptBrowserLaunch
@@ -300,7 +300,7 @@ import {
300
300
  updateMCPServerStatus,
301
301
  writeLine,
302
302
  writeLineSync
303
- } from "./chunk-YN2I5I42.js";
303
+ } from "./chunk-CPU6I5YV.js";
304
304
  import {
305
305
  E_TIMEOUT,
306
306
  Mutex,
@@ -49800,6 +49800,301 @@ __name(doesToolInvocationMatch, "doesToolInvocationMatch");
49800
49800
  // packages/core/src/utils/shellReadOnlyChecker.ts
49801
49801
  init_esbuild_shims();
49802
49802
  var import_shell_quote2 = __toESM(require_shell_quote(), 1);
49803
+
49804
+ // packages/core/src/utils/shell-safety-rules.ts
49805
+ init_esbuild_shims();
49806
+ var SED_ADDRESS = /^\s*(?:(?:\d+|\$)(?:\s*,\s*(?:\d+|\$))?|\/(?:\\[\s\S]|[^/\\])*\/)?\s*/;
49807
+ var SED_ADDRESS_AT = /\s*(?:(?:\d+|\$)(?:\s*,\s*(?:\d+|\$))?|\/(?:\\[\s\S]|[^/\\])*\/)?\s*/y;
49808
+ var SAFE_SED_COMMAND = /^[dDgGhHlnNpPqQxz=]$/;
49809
+ var SAFE_SUBSTITUTION_FLAGS = /^[0-9gIpM]*$/;
49810
+ var SAFE_SED_OPTION = /^(?:-[nElrsuz]|--(?:quiet|silent|line-length(?:=.*)?))$/;
49811
+ var SED_VALUE_OPTIONS = "-f --file -e --expression -l --line-length".split(
49812
+ " "
49813
+ );
49814
+ var AWK_STATIC_WRITE = /^\s*(?:print|printf)\b(?!\s*\()(?:(?:"(?:\\[\s\S]|[^"\\])*")|[^">|])*>>?\s*"[^"]*"\s*$/;
49815
+ var AWK_UNKNOWN_OPERATION = /(?:system|close)\s*\(|getline\b/;
49816
+ var AWK_PRINT = /\b(?:print|printf)\b/;
49817
+ function scanDelimitedSection(script, start, delimiter2) {
49818
+ let escaped = false;
49819
+ for (let i2 = start; i2 < script.length; i2++) {
49820
+ const char = script[i2];
49821
+ if (escaped) {
49822
+ escaped = false;
49823
+ } else if (char === "\\") {
49824
+ escaped = true;
49825
+ } else if (char === delimiter2) {
49826
+ return i2 + 1;
49827
+ }
49828
+ }
49829
+ return -1;
49830
+ }
49831
+ __name(scanDelimitedSection, "scanDelimitedSection");
49832
+ function classifySingleSedCommandSafety(script) {
49833
+ const compatibilityUnknown = /(?:^|[^\\])[ewr]\s/.test(script);
49834
+ const commandOffset = SED_ADDRESS.exec(script)?.[0].length ?? 0;
49835
+ if (commandOffset === script.length) return "read-only";
49836
+ const command = script[commandOffset];
49837
+ if (command === "w" || command === "W")
49838
+ return script.slice(commandOffset + 1).trim() ? "write" : "unknown";
49839
+ if (/[eErR]/.test(command)) return "unknown";
49840
+ if (command === "s") {
49841
+ const delimiter2 = script[commandOffset + 1];
49842
+ if (!delimiter2 || delimiter2 === "\\" || /\s/.test(delimiter2))
49843
+ return "unknown";
49844
+ const replacementStart = scanDelimitedSection(
49845
+ script,
49846
+ commandOffset + 2,
49847
+ delimiter2
49848
+ );
49849
+ if (replacementStart < 0) return "unknown";
49850
+ const flagsStart = scanDelimitedSection(
49851
+ script,
49852
+ replacementStart,
49853
+ delimiter2
49854
+ );
49855
+ if (flagsStart < 0) return "unknown";
49856
+ const flags = script.slice(flagsStart).trim();
49857
+ if (/[;\n{}]/.test(flags)) return "unknown";
49858
+ const writeFlag = flags.indexOf("w");
49859
+ if (writeFlag >= 0)
49860
+ return flags.slice(writeFlag + 1).trim() ? "write" : "unknown";
49861
+ if (/[eErRwW]/.test(flags)) return "unknown";
49862
+ if (!SAFE_SUBSTITUTION_FLAGS.test(flags)) return "unknown";
49863
+ return compatibilityUnknown ? "unknown" : "read-only";
49864
+ }
49865
+ if (/[;\n{}]/.test(script.slice(commandOffset + 1))) return "unknown";
49866
+ if (!SAFE_SED_COMMAND.test(command)) return "unknown";
49867
+ return compatibilityUnknown ? "unknown" : "read-only";
49868
+ }
49869
+ __name(classifySingleSedCommandSafety, "classifySingleSedCommandSafety");
49870
+ function nextSedSeparator(script, start) {
49871
+ for (let i2 = start; i2 < script.length; i2++) {
49872
+ if (script[i2] === ";" || script[i2] === "\n") return i2;
49873
+ }
49874
+ return script.length;
49875
+ }
49876
+ __name(nextSedSeparator, "nextSedSeparator");
49877
+ function classifySedScriptSafety(script) {
49878
+ let result = "read-only";
49879
+ let start = 0;
49880
+ while (start < script.length) {
49881
+ SED_ADDRESS_AT.lastIndex = start;
49882
+ const address = SED_ADDRESS_AT.exec(script);
49883
+ if (!address) return "unknown";
49884
+ const commandOffset = SED_ADDRESS_AT.lastIndex;
49885
+ if (commandOffset === script.length) return result;
49886
+ const command = script[commandOffset];
49887
+ if (command === "w" || command === "W") {
49888
+ const writer = classifySingleSedCommandSafety(script.slice(start));
49889
+ return writer === "write" ? "write" : "unknown";
49890
+ }
49891
+ if (/[eErR]/.test(command)) return "unknown";
49892
+ if (command !== "s" && !SAFE_SED_COMMAND.test(command)) return "unknown";
49893
+ let separator;
49894
+ if (command === "s") {
49895
+ const delimiter2 = script[commandOffset + 1];
49896
+ if (!delimiter2 || delimiter2 === "\\" || /\s/.test(delimiter2))
49897
+ return "unknown";
49898
+ const replacementStart = scanDelimitedSection(
49899
+ script,
49900
+ commandOffset + 2,
49901
+ delimiter2
49902
+ );
49903
+ if (replacementStart < 0) return "unknown";
49904
+ const flagsStart = scanDelimitedSection(
49905
+ script,
49906
+ replacementStart,
49907
+ delimiter2
49908
+ );
49909
+ if (flagsStart < 0) return "unknown";
49910
+ separator = nextSedSeparator(script, flagsStart);
49911
+ } else {
49912
+ separator = nextSedSeparator(script, commandOffset + 1);
49913
+ }
49914
+ const current = classifySingleSedCommandSafety(
49915
+ script.slice(start, separator)
49916
+ );
49917
+ if (current === "write") return "write";
49918
+ if (current === "unknown") result = "unknown";
49919
+ if (separator === script.length) return result;
49920
+ start = separator + 1;
49921
+ }
49922
+ return result;
49923
+ }
49924
+ __name(classifySedScriptSafety, "classifySedScriptSafety");
49925
+ function classifySedCommandSafety(args) {
49926
+ const terminator = args.indexOf("--");
49927
+ const options2 = args.slice(0, terminator < 0 ? args.length : terminator);
49928
+ if (options2.some(
49929
+ (arg, index) => /^(?:--help|--version)$/i.test(arg) && !SED_VALUE_OPTIONS.includes(options2[index - 1])
49930
+ ))
49931
+ return "unknown";
49932
+ for (let i2 = 0; i2 < args.length; i2++) {
49933
+ const arg = args[i2];
49934
+ if (arg === "--") break;
49935
+ if (SED_VALUE_OPTIONS.includes(arg)) i2++;
49936
+ else if (/^-[nErsuz]*e.+/.test(arg)) continue;
49937
+ else if (/^(?:-[nErsuz]*[iI]|--in-place(?:=|$))/.test(arg)) return "write";
49938
+ }
49939
+ const scripts = [];
49940
+ const scriptArguments = /* @__PURE__ */ new Set();
49941
+ for (let i2 = 0; i2 < args.length; i2++) {
49942
+ const arg = args[i2];
49943
+ if (arg === "--") {
49944
+ if (scripts.length === 0) {
49945
+ const script = args[i2 + 1];
49946
+ if (script === void 0 || script.startsWith("-")) return "unknown";
49947
+ scripts.push(script);
49948
+ scriptArguments.add(i2 + 1);
49949
+ }
49950
+ break;
49951
+ }
49952
+ if (/^(?:-l|--line-length)$/.test(arg) && !args[++i2]) return "unknown";
49953
+ if (/^(?:-f|--file(?:=|$))/.test(arg)) return "unknown";
49954
+ if (arg === "-e" || arg === "--expression") {
49955
+ const script = args[++i2];
49956
+ if (!script || script.startsWith("-")) return "unknown";
49957
+ scripts.push(script);
49958
+ scriptArguments.add(i2);
49959
+ } else if (/^(?:-e.+|--expression=)/.test(arg)) {
49960
+ const script = arg.slice(arg.startsWith("-e") ? 2 : 13);
49961
+ if (script.startsWith("-")) return "unknown";
49962
+ scripts.push(script);
49963
+ scriptArguments.add(i2);
49964
+ } else if (/^--(?!line-length(?:=|$))/.test(arg)) {
49965
+ return "unknown";
49966
+ } else if (arg.startsWith("-") && !SAFE_SED_OPTION.test(arg)) {
49967
+ return "unknown";
49968
+ } else if (!arg.startsWith("-") && scripts.length === 0) {
49969
+ scripts.push(arg);
49970
+ scriptArguments.add(i2);
49971
+ }
49972
+ }
49973
+ let result = "read-only";
49974
+ for (const script of scripts) {
49975
+ const current = classifySedScriptSafety(script);
49976
+ if (current === "write") return "write";
49977
+ if (current === "unknown") result = "unknown";
49978
+ }
49979
+ const remainingArgs = args.filter((_3, index) => !scriptArguments.has(index));
49980
+ return /(?:^|[^\\])[ewr]\s/.test(remainingArgs.join(" ")) ? "unknown" : result;
49981
+ }
49982
+ __name(classifySedCommandSafety, "classifySedCommandSafety");
49983
+ function splitAwkStatements(script) {
49984
+ const statements = [];
49985
+ let ambiguousSlash = false;
49986
+ let unsupportedAt = false;
49987
+ let start = 0;
49988
+ let escaped = false;
49989
+ let inString = false;
49990
+ let inRegex = false;
49991
+ let previousSignificant = "";
49992
+ for (let i2 = 0; i2 < script.length; i2++) {
49993
+ const char = script[i2];
49994
+ if (escaped) {
49995
+ escaped = false;
49996
+ continue;
49997
+ }
49998
+ if ((inString || inRegex) && char === "\\") {
49999
+ escaped = true;
50000
+ continue;
50001
+ }
50002
+ if (inString) {
50003
+ if (char === '"') inString = false;
50004
+ continue;
50005
+ }
50006
+ if (inRegex) {
50007
+ if (char === "/") inRegex = false;
50008
+ continue;
50009
+ }
50010
+ if (char === '"') {
50011
+ inString = true;
50012
+ continue;
50013
+ }
50014
+ if (char === "/" && (!previousSignificant || "({[=,:;!~?&|".includes(previousSignificant))) {
50015
+ inRegex = true;
50016
+ continue;
50017
+ }
50018
+ if (char === "/") ambiguousSlash = true;
50019
+ if (char === "@") unsupportedAt = true;
50020
+ if (char === "#") {
50021
+ statements.push(script.slice(start, i2));
50022
+ const newline2 = script.indexOf("\n", i2 + 1);
50023
+ if (newline2 < 0) return { statements, ambiguousSlash, unsupportedAt };
50024
+ start = newline2 + 1;
50025
+ i2 = newline2;
50026
+ previousSignificant = "\n";
50027
+ continue;
50028
+ }
50029
+ if (/[;{}\n]/.test(char)) {
50030
+ statements.push(script.slice(start, i2));
50031
+ start = i2 + 1;
50032
+ previousSignificant = char;
50033
+ continue;
50034
+ }
50035
+ if (!/\s/.test(char)) previousSignificant = char;
50036
+ }
50037
+ statements.push(script.slice(start));
50038
+ return { statements, ambiguousSlash, unsupportedAt };
50039
+ }
50040
+ __name(splitAwkStatements, "splitAwkStatements");
50041
+ function classifyAwkScriptSafety(script) {
50042
+ const { statements, ambiguousSlash, unsupportedAt } = splitAwkStatements(script);
50043
+ if (!ambiguousSlash && statements.some((statement) => AWK_STATIC_WRITE.test(statement)))
50044
+ return "write";
50045
+ if (unsupportedAt || AWK_UNKNOWN_OPERATION.test(script)) return "unknown";
50046
+ return AWK_PRINT.test(script) && /[>|]/.test(script) ? "unknown" : "read-only";
50047
+ }
50048
+ __name(classifyAwkScriptSafety, "classifyAwkScriptSafety");
50049
+ function classifyAwkCommandSafety(args) {
50050
+ let programIndex = -1;
50051
+ for (let i2 = 0; i2 < args.length; i2++) {
50052
+ const arg = args[i2];
50053
+ if (arg === "--") {
50054
+ programIndex = i2 + 1;
50055
+ break;
50056
+ }
50057
+ if (arg === "-F" || arg === "-v") {
50058
+ if (!args[++i2]) return "unknown";
50059
+ continue;
50060
+ }
50061
+ if (/^-[Fv].+/.test(arg)) continue;
50062
+ if (arg.startsWith("-")) return "unknown";
50063
+ programIndex = i2;
50064
+ break;
50065
+ }
50066
+ if (programIndex < 0) return "read-only";
50067
+ const program = args[programIndex];
50068
+ if (program === void 0) return "unknown";
50069
+ const result = classifyAwkScriptSafety(program);
50070
+ if (result !== "read-only") return result;
50071
+ return classifyAwkScriptSafety(args.join(" ")) === "read-only" ? "read-only" : "unknown";
50072
+ }
50073
+ __name(classifyAwkCommandSafety, "classifyAwkCommandSafety");
50074
+ function hasShellBraceExpansion(text) {
50075
+ let braceDepth = 0;
50076
+ let previousDot = false;
50077
+ for (const char of text) {
50078
+ if (char === "{") {
50079
+ braceDepth++;
50080
+ previousDot = false;
50081
+ } else if (char === "}") {
50082
+ braceDepth = Math.max(0, braceDepth - 1);
50083
+ previousDot = false;
50084
+ } else if (braceDepth > 0) {
50085
+ if (char === "," || char === "." && previousDot) return true;
50086
+ previousDot = char === ".";
50087
+ }
50088
+ }
50089
+ return false;
50090
+ }
50091
+ __name(hasShellBraceExpansion, "hasShellBraceExpansion");
50092
+ function hasShellPatternExpansion(text) {
50093
+ return /[[*?]/.test(text) || hasShellBraceExpansion(text);
50094
+ }
50095
+ __name(hasShellPatternExpansion, "hasShellPatternExpansion");
50096
+
50097
+ // packages/core/src/utils/shellReadOnlyChecker.ts
49803
50098
  var READ_ONLY_ROOT_COMMANDS = /* @__PURE__ */ new Set([
49804
50099
  "awk",
49805
50100
  "basename",
@@ -49815,21 +50110,13 @@ var READ_ONLY_ROOT_COMMANDS = /* @__PURE__ */ new Set([
49815
50110
  "git",
49816
50111
  "grep",
49817
50112
  "head",
49818
- "less",
49819
50113
  "ls",
49820
- "more",
49821
50114
  "printenv",
49822
- "printf",
49823
50115
  "ps",
49824
50116
  "pwd",
49825
- "rg",
49826
- "ripgrep",
49827
50117
  "sed",
49828
- "sort",
49829
50118
  "stat",
49830
50119
  "tail",
49831
- "tree",
49832
- "uniq",
49833
50120
  "wc",
49834
50121
  "which",
49835
50122
  "where",
@@ -49842,7 +50129,7 @@ var BLOCKED_FIND_FLAGS = /* @__PURE__ */ new Set([
49842
50129
  "-ok",
49843
50130
  "-okdir"
49844
50131
  ]);
49845
- var BLOCKED_FIND_PREFIXES = ["-fprint", "-fprintf"];
50132
+ var BLOCKED_FIND_PREFIXES = ["-fls", "-fprint", "-fprintf"];
49846
50133
  var READ_ONLY_GIT_SUBCOMMANDS = /* @__PURE__ */ new Set([
49847
50134
  "blame",
49848
50135
  "branch",
@@ -49860,56 +50147,18 @@ var READ_ONLY_GIT_SUBCOMMANDS = /* @__PURE__ */ new Set([
49860
50147
  var BLOCKED_GIT_REMOTE_ACTIONS = /* @__PURE__ */ new Set([
49861
50148
  "add",
49862
50149
  "remove",
50150
+ "rm",
49863
50151
  "rename",
50152
+ "set-branches",
50153
+ "set-head",
49864
50154
  "set-url",
49865
50155
  "prune",
49866
50156
  "update"
49867
50157
  ]);
49868
- var BLOCKED_GIT_BRANCH_FLAGS = /* @__PURE__ */ new Set([
49869
- "-d",
49870
- "-D",
49871
- "--delete",
49872
- "--move",
49873
- "-m"
49874
- ]);
49875
- var BLOCKED_SED_PREFIXES = ["-i"];
49876
- var AWK_SIDE_EFFECT_PATTERNS = [
49877
- /system\s*\(/,
49878
- // system() function calls
49879
- /print\s+[^>|]*>\s*"[^"]*"/,
49880
- // print > "file"
49881
- /printf\s+[^>|]*>\s*"[^"]*"/,
49882
- // printf > "file"
49883
- /print\s+[^>|]*>>\s*"[^"]*"/,
49884
- // print >> "file"
49885
- /printf\s+[^>|]*>>\s*"[^"]*"/,
49886
- // printf >> "file"
49887
- /print\s+[^|]*\|\s*"[^"]*"/,
49888
- // print | "command"
49889
- /printf\s+[^|]*\|\s*"[^"]*"/,
49890
- // printf | "command"
49891
- /getline\s*<\s*"[^"]*"/,
49892
- // getline < "command"
49893
- /"[^"]*"\s*\|\s*getline/,
49894
- // "command" | getline
49895
- /close\s*\(/
49896
- // close() can trigger command execution
49897
- ];
49898
- var SED_SIDE_EFFECT_PATTERNS = [
49899
- /[^\\]e\s/,
49900
- // e command (execute)
49901
- /^e\s/,
49902
- // e command at start
49903
- /[^\\]w\s/,
49904
- // w command (write)
49905
- /^w\s/,
49906
- // w command at start
49907
- /[^\\]r\s/,
49908
- // r command (read file)
49909
- /^r\s/
49910
- // r command at start
49911
- ];
50158
+ var GIT_EXTERNAL_HELPER_OPTION = /(?:^--(?:ext-diff|filters|show-signature|textconv|open-files-in-pager)(?:=|$)|%G[?GKFPST])/;
50159
+ var SAFE_SED_OPTION2 = /^(?:-[nErsuz]|--(?:quiet|silent))$/;
49912
50160
  var ENV_ASSIGNMENT_REGEX2 = /^[A-Za-z_][A-Za-z0-9_]*=/;
50161
+ var MALFORMED_CONTROL_OPERATOR = /(?:^|[({])\s*(?:&&|\|\||\|&|[|;&])|(?:&&|\|\||\|&|[|;&])\s+(?:&&|\|\||\|&|[|;&])|(?!(?:&&|\|\||\|&))[|;&]{2}|[|;&]{3,}|(?:\|&?|&&|\|\|)\s*[)}]*\s*$/;
49913
50162
  function containsWriteRedirection(command) {
49914
50163
  let inSingleQuotes = false;
49915
50164
  let inDoubleQuotes = false;
@@ -49939,11 +50188,13 @@ function containsWriteRedirection(command) {
49939
50188
  }
49940
50189
  __name(containsWriteRedirection, "containsWriteRedirection");
49941
50190
  function normalizeTokens(segment) {
49942
- const parsed = (0, import_shell_quote2.parse)(segment);
50191
+ const parsed = (0, import_shell_quote2.parse)(segment, (key) => `\0${key}`);
49943
50192
  const tokens = [];
49944
50193
  for (const token of parsed) {
49945
50194
  if (typeof token === "string") {
49946
50195
  tokens.push(token);
50196
+ } else if ("op" in token && token.op === "glob") {
50197
+ tokens.push(`\0${token.pattern}`);
49947
50198
  }
49948
50199
  }
49949
50200
  return tokens;
@@ -49965,6 +50216,7 @@ function skipEnvironmentAssignments(tokens) {
49965
50216
  __name(skipEnvironmentAssignments, "skipEnvironmentAssignments");
49966
50217
  function evaluateFindCommand(tokens) {
49967
50218
  const [, ...rest] = tokens;
50219
+ if (rest.at(-1)?.startsWith("-")) return false;
49968
50220
  for (const token of rest) {
49969
50221
  const lower = token.toLowerCase();
49970
50222
  if (BLOCKED_FIND_FLAGS.has(lower)) {
@@ -49980,56 +50232,38 @@ __name(evaluateFindCommand, "evaluateFindCommand");
49980
50232
  function evaluateSedCommand(tokens) {
49981
50233
  const [, ...rest] = tokens;
49982
50234
  for (const token of rest) {
49983
- if (BLOCKED_SED_PREFIXES.some((prefix) => token.startsWith(prefix)) || token === "--in-place") {
50235
+ if (["-i", "-I"].some((prefix) => token.startsWith(prefix)) || token === "--in-place" || token.startsWith("--in-place=") || token === "-f" || token === "--file" || token.startsWith("-f") && token.length > 2 || token.startsWith("--file=") || token.startsWith("-") && !SAFE_SED_OPTION2.test(token)) {
49984
50236
  return false;
49985
50237
  }
49986
50238
  }
49987
- const scriptContent = rest.join(" ");
49988
- for (const pattern of SED_SIDE_EFFECT_PATTERNS) {
49989
- if (pattern.test(scriptContent)) {
49990
- return false;
49991
- }
49992
- }
49993
- return true;
50239
+ return classifySedCommandSafety(rest) === "read-only";
49994
50240
  }
49995
50241
  __name(evaluateSedCommand, "evaluateSedCommand");
49996
50242
  function evaluateAwkCommand(tokens) {
49997
50243
  const [, ...rest] = tokens;
49998
- const scriptContent = rest.join(" ");
49999
- for (const pattern of AWK_SIDE_EFFECT_PATTERNS) {
50000
- if (pattern.test(scriptContent)) {
50001
- return false;
50002
- }
50003
- }
50004
- return true;
50244
+ return classifyAwkCommandSafety(rest) === "read-only";
50005
50245
  }
50006
50246
  __name(evaluateAwkCommand, "evaluateAwkCommand");
50007
50247
  function evaluateGitRemoteArgs(args) {
50248
+ const action = args.find((arg) => !arg.startsWith("-"))?.toLowerCase();
50249
+ if (action && !["show", "get-url"].includes(action)) return false;
50008
50250
  for (const arg of args) {
50009
- if (BLOCKED_GIT_REMOTE_ACTIONS.has(arg.toLowerCase())) {
50010
- return false;
50011
- }
50251
+ if (BLOCKED_GIT_REMOTE_ACTIONS.has(arg.toLowerCase())) return false;
50012
50252
  }
50013
50253
  return true;
50014
50254
  }
50015
50255
  __name(evaluateGitRemoteArgs, "evaluateGitRemoteArgs");
50016
50256
  function evaluateGitBranchArgs(args) {
50017
- for (const arg of args) {
50018
- if (BLOCKED_GIT_BRANCH_FLAGS.has(arg)) {
50019
- return false;
50020
- }
50021
- }
50022
- return true;
50257
+ return args.length === 0 || args.length === 1 && args[0] === "--list";
50023
50258
  }
50024
50259
  __name(evaluateGitBranchArgs, "evaluateGitBranchArgs");
50025
50260
  function evaluateGitCommand(tokens) {
50026
50261
  let index = 1;
50027
50262
  while (index < tokens.length && tokens[index].startsWith("-")) {
50028
- const flag = tokens[index].toLowerCase();
50029
- if (flag === "--version" || flag === "--help") {
50030
- return true;
50031
- }
50032
- index++;
50263
+ const flag = tokens[index++].toLowerCase();
50264
+ if (flag === "--version") return true;
50265
+ if (flag === "--help") return tokens.length === 2;
50266
+ return false;
50033
50267
  }
50034
50268
  if (index >= tokens.length) {
50035
50269
  return true;
@@ -50039,12 +50273,20 @@ function evaluateGitCommand(tokens) {
50039
50273
  return false;
50040
50274
  }
50041
50275
  const args = tokens.slice(index + 1);
50276
+ const end = args.indexOf("--");
50277
+ const options2 = args.slice(0, end < 0 ? args.length : end);
50278
+ if (options2.some((arg) => GIT_EXTERNAL_HELPER_OPTION.test(arg)) || subcommand === "grep" && options2.some((arg) => arg.startsWith("-O")))
50279
+ return false;
50280
+ if (options2.some((arg) => /^(?:--help|--version)$/i.test(arg))) return false;
50042
50281
  if (subcommand === "remote") {
50043
50282
  return evaluateGitRemoteArgs(args);
50044
50283
  }
50045
50284
  if (subcommand === "branch") {
50046
50285
  return evaluateGitBranchArgs(args);
50047
50286
  }
50287
+ if (["blame", "diff", "log", "show"].includes(subcommand)) {
50288
+ return !options2.some((arg) => /^--output(?:=|$)/.test(arg));
50289
+ }
50048
50290
  return true;
50049
50291
  }
50050
50292
  __name(evaluateGitCommand, "evaluateGitCommand");
@@ -50059,6 +50301,7 @@ function evaluateShellSegment(segment) {
50059
50301
  if (!stripped) {
50060
50302
  return true;
50061
50303
  }
50304
+ if (stripped !== segment.trim()) return false;
50062
50305
  if (detectCommandSubstitution(stripped)) {
50063
50306
  return false;
50064
50307
  }
@@ -50073,7 +50316,13 @@ function evaluateShellSegment(segment) {
50073
50316
  if (!root) {
50074
50317
  return true;
50075
50318
  }
50319
+ if (root !== tokens[0]) return false;
50076
50320
  const normalizedRoot = root.toLowerCase();
50321
+ if (root !== normalizedRoot) return false;
50322
+ if (/^(awk|find|git|sed)$/.test(normalizedRoot) && args.some(
50323
+ (arg) => !arg || arg.includes("\0") || hasShellBraceExpansion(arg)
50324
+ ))
50325
+ return false;
50077
50326
  if (!READ_ONLY_ROOT_COMMANDS.has(normalizedRoot)) {
50078
50327
  return false;
50079
50328
  }
@@ -50096,6 +50345,9 @@ function isShellCommandReadOnly(command) {
50096
50345
  if (typeof command !== "string" || !command.trim()) {
50097
50346
  return false;
50098
50347
  }
50348
+ if (MALFORMED_CONTROL_OPERATOR.test(command)) return false;
50349
+ if (/[({;&|]\s*[A-Za-z_][A-Za-z0-9_]*=/.test(command) || /^[A-Za-z_][A-Za-z0-9_]*=.*[;&|]/s.test(command))
50350
+ return false;
50099
50351
  const segments = splitCommands(command);
50100
50352
  for (const segment of segments) {
50101
50353
  if (!evaluateShellSegment(segment)) {
@@ -53527,6 +53779,7 @@ var READ_ONLY_ROOT_COMMANDS2 = /* @__PURE__ */ new Set([
53527
53779
  "where",
53528
53780
  "whoami"
53529
53781
  ]);
53782
+ var WRITE_ROOT_COMMAND = /^(chgrp|chmod|chown|cp|install|ln|mkdir|mkfifo|mknod|mv|rename|rm|rmdir|shred|touch|truncate|unlink)$/;
53530
53783
  var READ_ONLY_GIT_SUBCOMMANDS2 = /* @__PURE__ */ new Set([
53531
53784
  "blame",
53532
53785
  "branch",
@@ -53541,50 +53794,17 @@ var READ_ONLY_GIT_SUBCOMMANDS2 = /* @__PURE__ */ new Set([
53541
53794
  "status",
53542
53795
  "describe"
53543
53796
  ]);
53544
- var BLOCKED_GIT_REMOTE_ACTIONS2 = /* @__PURE__ */ new Set([
53545
- "add",
53546
- "remove",
53547
- "rename",
53548
- "set-url",
53549
- "prune",
53550
- "update"
53551
- ]);
53552
- var BLOCKED_GIT_BRANCH_FLAGS2 = /* @__PURE__ */ new Set([
53553
- "-d",
53554
- "-D",
53555
- "--delete",
53556
- "--move",
53557
- "-m"
53558
- ]);
53559
- var BLOCKED_FIND_FLAGS2 = /* @__PURE__ */ new Set([
53560
- "-delete",
53561
- "-exec",
53562
- "-execdir",
53563
- "-ok",
53564
- "-okdir"
53565
- ]);
53566
- var BLOCKED_FIND_PREFIXES2 = ["-fprint", "-fprintf"];
53567
- var BLOCKED_SED_PREFIXES2 = ["-i"];
53568
- var AWK_SIDE_EFFECT_PATTERNS2 = [
53569
- /system\s*\(/,
53570
- /print\s+[^>|]*>\s*"[^"]*"/,
53571
- /printf\s+[^>|]*>\s*"[^"]*"/,
53572
- /print\s+[^>|]*>>\s*"[^"]*"/,
53573
- /printf\s+[^>|]*>>\s*"[^"]*"/,
53574
- /print\s+[^|]*\|\s*"[^"]*"/,
53575
- /printf\s+[^|]*\|\s*"[^"]*"/,
53576
- /getline\s*<\s*"[^"]*"/,
53577
- /"[^"]*"\s*\|\s*getline/,
53578
- /close\s*\(/
53579
- ];
53580
- var SED_SIDE_EFFECT_PATTERNS2 = [
53581
- /[^\\]e\s/,
53582
- /^e\s/,
53583
- /[^\\]w\s/,
53584
- /^w\s/,
53585
- /[^\\]r\s/,
53586
- /^r\s/
53587
- ];
53797
+ var WRITE_GIT_SUBCOMMAND = /^(add|am|checkout|cherry-pick|clean|clone|commit|fetch|gc|init|merge|mv|pull|push|rebase|reset|restore|revert|rm|stash|switch)$/;
53798
+ var WRITE_GIT_REMOTE_ACTION = /^(add|remove|rm|rename|set-branches|set-head|set-url|update)$/;
53799
+ var GIT_EXTERNAL_HELPER_OPTION2 = /^--(?:ext-diff|filters|show-signature|textconv|open-files-in-pager)(?:=|$)/;
53800
+ var GIT_COMMIT_VALUE_OPTION = /^(?:-[CcFmt]|--(?:author|cleanup|date|file|fixup|message|pathspec-from-file|reedit-message|reuse-message|squash|template|trailer))$/;
53801
+ var WRITE_GIT_BRANCH_FLAG = /^(?:-[cCdDmMu](?:.|$)|--(?:delete|move|copy|set-upstream(?:-to)?|unset-upstream|create-reflog|edit-description)(?:=|$))/;
53802
+ var GIT_BRANCH_LIST_FLAG = /^(?:-[alr]|--(?:all|list|remotes|show-current|contains|no-contains|merged|no-merged|points-at))(?:=|$)/;
53803
+ var BLOCKED_FIND_PREFIXES2 = ["-fls", "-fprint", "-fprintf"];
53804
+ var FIND_VALUE_PREDICATE = /^-(?:[ac]?newer|newer[a-z]{2}|[acm](?:min|time)|context|fstype|gid|group|i?(?:lname|name|path|regex)|inum|links|maxdepth|mindepth|path|perm|printf|regextype|samefile|size|type|uid|used|user|wholename|xtype)$/;
53805
+ var UNIQ_VALUE_OPTIONS = new Set(
53806
+ "-f --skip-fields -s --skip-chars -w --check-chars".split(" ")
53807
+ );
53588
53808
  var WRITE_REDIRECT_OPERATORS = /* @__PURE__ */ new Set([">", ">>", "&>", "&>>", ">|"]);
53589
53809
  var KNOWN_SUBCOMMANDS = {
53590
53810
  git: /* @__PURE__ */ new Set([
@@ -53990,6 +54210,7 @@ var DOCKER_COMPOSE_SUBCOMMANDS = /* @__PURE__ */ new Set([
53990
54210
  ]);
53991
54211
  var parserInstance = null;
53992
54212
  var bashLanguage = null;
54213
+ var parserClass;
53993
54214
  var initPromise = null;
53994
54215
  var parserInitFailed = false;
53995
54216
  async function initParser() {
@@ -54006,16 +54227,24 @@ async function initParser() {
54006
54227
  "web-tree-sitter/tree-sitter.wasm"
54007
54228
  );
54008
54229
  await ParserClass.init({ wasmBinary: treeSitterWasm });
54009
- parserInstance = new ParserClass();
54010
54230
  const bashWasm = await loadWasmBinary(
54011
54231
  () => import("./tree-sitter-bash-VEJGF5XF.js"),
54012
54232
  "tree-sitter-wasms/out/tree-sitter-bash.wasm"
54013
54233
  );
54014
54234
  bashLanguage = await ParserClass.Language.load(bashWasm);
54235
+ parserClass = ParserClass;
54236
+ parserInstance = new ParserClass();
54015
54237
  parserInstance.setLanguage(bashLanguage);
54016
54238
  })().catch((err) => {
54239
+ const failedParser = parserInstance;
54240
+ parserInstance = null;
54241
+ bashLanguage = null;
54017
54242
  parserInitFailed = true;
54018
54243
  initPromise = null;
54244
+ try {
54245
+ failedParser?.delete();
54246
+ } catch {
54247
+ }
54019
54248
  throw err;
54020
54249
  });
54021
54250
  return initPromise;
@@ -54023,16 +54252,43 @@ async function initParser() {
54023
54252
  __name(initParser, "initParser");
54024
54253
  async function parseShellCommand(command) {
54025
54254
  await initParser();
54026
- return parserInstance.parse(command);
54255
+ const parser5 = parserInstance;
54256
+ try {
54257
+ return parser5.parse(command);
54258
+ } catch (error) {
54259
+ parserInstance = null;
54260
+ let replacement = null;
54261
+ try {
54262
+ replacement = new parserClass();
54263
+ replacement.setLanguage(bashLanguage);
54264
+ parserInstance = replacement;
54265
+ } catch {
54266
+ try {
54267
+ replacement?.delete();
54268
+ } catch {
54269
+ }
54270
+ bashLanguage = null;
54271
+ parserInitFailed = true;
54272
+ initPromise = null;
54273
+ } finally {
54274
+ parser5.delete();
54275
+ }
54276
+ throw error;
54277
+ }
54027
54278
  }
54028
54279
  __name(parseShellCommand, "parseShellCommand");
54029
- function collectDescendants(node, types2) {
54280
+ var SHELL_EXPANSION_TYPES = new Set(
54281
+ "simple_expansion expansion arithmetic_expansion".split(" ")
54282
+ );
54283
+ var CHILD_STATEMENT = /^(?:pipeline|list|subshell|compound_statement|negated_command)$/;
54284
+ function collectDescendants(node, types2, outermostOnly = false) {
54030
54285
  const result = [];
54031
54286
  const stack = [node];
54032
54287
  while (stack.length > 0) {
54033
54288
  const current = stack.pop();
54034
54289
  if (types2.has(current.type)) {
54035
54290
  result.push(current);
54291
+ if (outermostOnly) continue;
54036
54292
  }
54037
54293
  for (let i2 = current.childCount - 1; i2 >= 0; i2--) {
54038
54294
  stack.push(current.child(i2));
@@ -54041,29 +54297,6 @@ function collectDescendants(node, types2) {
54041
54297
  return result;
54042
54298
  }
54043
54299
  __name(collectDescendants, "collectDescendants");
54044
- function containsCommandSubstitutionAST(node) {
54045
- return collectDescendants(
54046
- node,
54047
- /* @__PURE__ */ new Set(["command_substitution", "process_substitution"])
54048
- ).length > 0;
54049
- }
54050
- __name(containsCommandSubstitutionAST, "containsCommandSubstitutionAST");
54051
- function hasWriteRedirection(node) {
54052
- if (node.type !== "redirected_statement") return false;
54053
- for (let i2 = 0; i2 < node.childCount; i2++) {
54054
- const child = node.child(i2);
54055
- if (child.type === "file_redirect") {
54056
- for (let j3 = 0; j3 < child.childCount; j3++) {
54057
- const op = child.child(j3);
54058
- if (op.type === "file_descriptor") continue;
54059
- if (WRITE_REDIRECT_OPERATORS.has(op.type)) return true;
54060
- break;
54061
- }
54062
- }
54063
- }
54064
- return false;
54065
- }
54066
- __name(hasWriteRedirection, "hasWriteRedirection");
54067
54300
  function getCommandName(commandNode) {
54068
54301
  const nameNode = commandNode.childForFieldName("name");
54069
54302
  if (!nameNode) return null;
@@ -54090,136 +54323,319 @@ function stripOuterQuotes(text) {
54090
54323
  return text;
54091
54324
  }
54092
54325
  __name(stripOuterQuotes, "stripOuterQuotes");
54093
- function evaluateCommandReadOnly(commandNode) {
54094
- const root = getCommandName(commandNode);
54095
- if (!root) return true;
54096
- const argNodes = getArgumentNodes(commandNode);
54097
- const argTexts = argNodes.map((n) => stripOuterQuotes(n.text));
54098
- if (!READ_ONLY_ROOT_COMMANDS2.has(root)) return false;
54099
- if (root === "git") return evaluateGitReadOnly(argTexts);
54100
- if (root === "find") return evaluateFindReadOnly(argTexts);
54101
- if (root === "sed") return evaluateSedReadOnly(argTexts);
54102
- if (root === "awk") return evaluateAwkReadOnly(argTexts);
54103
- return true;
54104
- }
54105
- __name(evaluateCommandReadOnly, "evaluateCommandReadOnly");
54106
- function evaluateGitReadOnly(args) {
54107
- let idx = 0;
54108
- while (idx < args.length && args[idx].startsWith("-")) {
54109
- const flag = args[idx].toLowerCase();
54110
- if (flag === "--version" || flag === "--help") return true;
54111
- idx++;
54112
- }
54113
- if (idx >= args.length) return true;
54114
- const subcommand = args[idx].toLowerCase();
54115
- if (!READ_ONLY_GIT_SUBCOMMANDS2.has(subcommand)) return false;
54116
- const rest = args.slice(idx + 1);
54117
- if (subcommand === "remote") {
54118
- return !rest.some((a) => BLOCKED_GIT_REMOTE_ACTIONS2.has(a.toLowerCase()));
54119
- }
54120
- if (subcommand === "branch") {
54121
- return !rest.some((a) => BLOCKED_GIT_BRANCH_FLAGS2.has(a));
54122
- }
54123
- return true;
54326
+ function hasShellExpansion(node) {
54327
+ return collectDescendants(node, SHELL_EXPANSION_TYPES).length > 0 || ["word", "concatenation"].includes(node.type) && hasShellPatternExpansion(node.text);
54328
+ }
54329
+ __name(hasShellExpansion, "hasShellExpansion");
54330
+ function mergeSafety(...results) {
54331
+ if (results.includes("write")) return "write";
54332
+ if (results.includes("unknown")) return "unknown";
54333
+ return "read-only";
54334
+ }
54335
+ __name(mergeSafety, "mergeSafety");
54336
+ function beforeTerminator(args) {
54337
+ const end = args.indexOf("--");
54338
+ return args.slice(0, end < 0 ? args.length : end);
54339
+ }
54340
+ __name(beforeTerminator, "beforeTerminator");
54341
+ function hasHelp(args, valueOptions = []) {
54342
+ return beforeTerminator(args).some(
54343
+ (arg, index, options2) => /^(?:--help|--version)$/i.test(arg) && !valueOptions.includes(options2[index - 1])
54344
+ );
54124
54345
  }
54125
- __name(evaluateGitReadOnly, "evaluateGitReadOnly");
54126
- function evaluateFindReadOnly(args) {
54127
- for (const arg of args) {
54128
- const lower = arg.toLowerCase();
54129
- if (BLOCKED_FIND_FLAGS2.has(lower)) return false;
54130
- if (BLOCKED_FIND_PREFIXES2.some((p3) => lower.startsWith(p3))) return false;
54346
+ __name(hasHelp, "hasHelp");
54347
+ function withoutOptionValues(args, valueOption) {
54348
+ const result = [];
54349
+ for (let i2 = 0; i2 < args.length; i2++) {
54350
+ result.push(args[i2]);
54351
+ if (valueOption.test(args[i2])) i2++;
54131
54352
  }
54132
- return true;
54353
+ return result;
54133
54354
  }
54134
- __name(evaluateFindReadOnly, "evaluateFindReadOnly");
54135
- function evaluateSedReadOnly(args) {
54136
- for (const arg of args) {
54137
- if (BLOCKED_SED_PREFIXES2.some((p3) => arg.startsWith(p3)) || arg === "--in-place") {
54138
- return false;
54355
+ __name(withoutOptionValues, "withoutOptionValues");
54356
+ function evaluateOutputOption(args, long = true, short = true) {
54357
+ for (let i2 = 0; i2 < args.length; i2++) {
54358
+ const arg = args[i2];
54359
+ if (arg === "--") break;
54360
+ if (short && arg === "-o" || long && arg === "--output") {
54361
+ return args[i2 + 1] ? "write" : "unknown";
54362
+ }
54363
+ if (short && arg.startsWith("-o") && arg.length > 2) return "write";
54364
+ if (long && arg.startsWith("--output=")) {
54365
+ return arg.length > 9 ? "write" : "unknown";
54139
54366
  }
54140
54367
  }
54141
- const scriptContent = args.join(" ");
54142
- return !SED_SIDE_EFFECT_PATTERNS2.some((p3) => p3.test(scriptContent));
54143
- }
54144
- __name(evaluateSedReadOnly, "evaluateSedReadOnly");
54145
- function evaluateAwkReadOnly(args) {
54146
- const scriptContent = args.join(" ");
54147
- return !AWK_SIDE_EFFECT_PATTERNS2.some((p3) => p3.test(scriptContent));
54368
+ return null;
54148
54369
  }
54149
- __name(evaluateAwkReadOnly, "evaluateAwkReadOnly");
54150
- function evaluateStatementReadOnly(node) {
54151
- if (containsCommandSubstitutionAST(node)) return false;
54152
- switch (node.type) {
54153
- case "command":
54154
- return evaluateCommandReadOnly(node);
54155
- case "pipeline": {
54156
- for (const child of node.namedChildren) {
54157
- if (!evaluateStatementReadOnly(child)) return false;
54158
- }
54159
- return true;
54160
- }
54161
- case "list": {
54162
- for (const child of node.namedChildren) {
54163
- if (!evaluateStatementReadOnly(child)) return false;
54164
- }
54165
- return true;
54370
+ __name(evaluateOutputOption, "evaluateOutputOption");
54371
+ function evaluateGitSafety(args) {
54372
+ const first2 = args[0];
54373
+ if (!first2 || first2 === "--version") return "read-only";
54374
+ if (first2 === "--help") return args.length === 1 ? "read-only" : "unknown";
54375
+ if (first2.startsWith("-")) return "unknown";
54376
+ const subcommand = first2.toLowerCase();
54377
+ const rest = args.slice(1);
54378
+ const options2 = beforeTerminator(rest);
54379
+ const invokesHelper = options2.some((arg) => GIT_EXTERNAL_HELPER_OPTION2.test(arg)) || subcommand === "grep" && options2.some((arg) => arg.startsWith("-O")) || ["log", "show"].includes(subcommand) && options2.some((arg) => /%G[?GKFPST]/.test(arg));
54380
+ if (WRITE_GIT_SUBCOMMAND.test(subcommand)) {
54381
+ const effectiveArgs = subcommand === "commit" ? withoutOptionValues(rest, GIT_COMMIT_VALUE_OPTION) : rest;
54382
+ const effectiveOptions = beforeTerminator(effectiveArgs);
54383
+ const help = hasHelp(effectiveArgs);
54384
+ const dryRun = effectiveOptions.includes("--dry-run") || effectiveOptions.includes("-n") && ["add", "clean", "mv", "push", "rm"].includes(subcommand);
54385
+ return help || dryRun ? "unknown" : "write";
54386
+ }
54387
+ if (!READ_ONLY_GIT_SUBCOMMANDS2.has(subcommand)) return "unknown";
54388
+ if (["diff", "log", "show"].includes(subcommand)) {
54389
+ const output = evaluateOutputOption(rest, true, false);
54390
+ if (output) return output;
54391
+ }
54392
+ if (subcommand === "blame" && beforeTerminator(rest).some((arg) => /^--output(?:=|$)/.test(arg)))
54393
+ return "unknown";
54394
+ if (subcommand !== "branch" && hasHelp(rest)) return "unknown";
54395
+ if (subcommand === "remote") {
54396
+ const action = rest.find((arg) => !arg.startsWith("-"))?.toLowerCase();
54397
+ if (!action) return invokesHelper ? "unknown" : "read-only";
54398
+ if (["show", "get-url"].includes(action))
54399
+ return rest.some(
54400
+ (arg) => /^(?:add|remove|rm|rename|set-branches|set-head|set-url|update|prune)$/i.test(
54401
+ arg
54402
+ )
54403
+ ) || invokesHelper ? "unknown" : "read-only";
54404
+ if (WRITE_GIT_REMOTE_ACTION.test(action)) return "write";
54405
+ if (action === "prune")
54406
+ return rest.some((arg) => ["-n", "--dry-run"].includes(arg)) ? "unknown" : "write";
54407
+ return "unknown";
54408
+ }
54409
+ if (subcommand === "branch") {
54410
+ const actions = withoutOptionValues(rest, /^--(?:format|sort)$/);
54411
+ const actionOptions = beforeTerminator(actions);
54412
+ if (hasHelp(actions)) return "unknown";
54413
+ if (actions.some((arg) => WRITE_GIT_BRANCH_FLAG.test(arg)))
54414
+ return actionOptions.some((arg) => WRITE_GIT_BRANCH_FLAG.test(arg)) ? "write" : "unknown";
54415
+ if (actions.length !== rest.length) return "unknown";
54416
+ const lists = actionOptions.some((arg) => GIT_BRANCH_LIST_FLAG.test(arg));
54417
+ if (lists) return "read-only";
54418
+ if (rest.some((arg) => !arg.startsWith("-"))) return "write";
54419
+ if (rest.includes("--")) return "unknown";
54420
+ if (invokesHelper) return "unknown";
54421
+ return rest.length === 0 ? "read-only" : "unknown";
54422
+ }
54423
+ if (invokesHelper) return "unknown";
54424
+ return "read-only";
54425
+ }
54426
+ __name(evaluateGitSafety, "evaluateGitSafety");
54427
+ function evaluateFindSafety(args) {
54428
+ let result = "read-only";
54429
+ for (let i2 = 0; i2 < args.length; i2++) {
54430
+ const lower = args[i2].toLowerCase();
54431
+ if (lower === "--") return mergeSafety(result, "unknown");
54432
+ if (/^--(?:help|version)$/.test(lower)) return "unknown";
54433
+ if (FIND_VALUE_PREDICATE.test(lower)) {
54434
+ if (!args[++i2]?.match(/^[^-]/)) result = mergeSafety(result, "unknown");
54435
+ continue;
54166
54436
  }
54167
- case "redirected_statement": {
54168
- if (hasWriteRedirection(node)) return false;
54169
- const body = node.namedChildren[0];
54170
- return body ? evaluateStatementReadOnly(body) : true;
54437
+ if (lower === "-delete") {
54438
+ result = "write";
54439
+ continue;
54171
54440
  }
54172
- case "subshell": {
54173
- for (const child of node.namedChildren) {
54174
- if (!evaluateStatementReadOnly(child)) return false;
54175
- }
54176
- return true;
54441
+ if (BLOCKED_FIND_PREFIXES2.some((prefix) => lower.startsWith(prefix))) {
54442
+ result = "write";
54443
+ i2 += lower.startsWith("-fprintf") ? 2 : 1;
54444
+ continue;
54177
54445
  }
54178
- case "compound_statement": {
54179
- for (const child of node.namedChildren) {
54180
- if (!evaluateStatementReadOnly(child)) return false;
54446
+ if (["-exec", "-execdir", "-ok", "-okdir"].includes(lower)) {
54447
+ const invoked = args[i2 + 1]?.toLowerCase();
54448
+ let end = -1;
54449
+ for (let index = i2 + 2; index < args.length; index++) {
54450
+ if ([";", "\\;", "+"].includes(args[index])) {
54451
+ end = index;
54452
+ break;
54453
+ }
54181
54454
  }
54182
- return true;
54455
+ const invokedArgs = args.slice(i2 + 2, end < 0 ? void 0 : end);
54456
+ let nested = "unknown";
54457
+ if (invoked && WRITE_ROOT_COMMAND.test(invoked))
54458
+ nested = hasHelp(invokedArgs) ? "unknown" : "write";
54459
+ else if (invoked && /^(kill|killall|pkill)$/.test(invoked))
54460
+ nested = processSafety(invoked, invokedArgs);
54461
+ result = mergeSafety(result, nested);
54462
+ i2 = end < 0 ? args.length : end;
54183
54463
  }
54184
- case "variable_assignment":
54185
- case "variable_assignments":
54186
- return true;
54187
- case "negated_command": {
54188
- const inner = node.namedChildren[0];
54189
- return inner ? evaluateStatementReadOnly(inner) : true;
54464
+ }
54465
+ return result;
54466
+ }
54467
+ __name(evaluateFindSafety, "evaluateFindSafety");
54468
+ function evaluateSedSafety(args) {
54469
+ return classifySedCommandSafety(args);
54470
+ }
54471
+ __name(evaluateSedSafety, "evaluateSedSafety");
54472
+ function evaluateAwkSafety(args) {
54473
+ return classifyAwkCommandSafety(args);
54474
+ }
54475
+ __name(evaluateAwkSafety, "evaluateAwkSafety");
54476
+ function evaluateUniqSafety(args) {
54477
+ let positional = 0;
54478
+ for (let i2 = 0; i2 < args.length; i2++) {
54479
+ const arg = args[i2];
54480
+ if (arg === "--") {
54481
+ return args.length - i2 + positional > 2 ? "write" : "read-only";
54482
+ } else if (UNIQ_VALUE_OPTIONS.has(arg)) {
54483
+ if (!args[++i2]) return "unknown";
54484
+ } else if (arg === "-" || !arg.startsWith("-")) positional++;
54485
+ }
54486
+ return positional >= 2 ? "write" : "read-only";
54487
+ }
54488
+ __name(evaluateUniqSafety, "evaluateUniqSafety");
54489
+ function processSafety(root, args) {
54490
+ const options2 = beforeTerminator(args);
54491
+ const signalZero = /^(?:SIG)?0+$/i;
54492
+ const signalValueOptions = [
54493
+ "--signal",
54494
+ ...root === "pkill" ? [] : ["-s"],
54495
+ ...root === "kill" ? ["-n"] : []
54496
+ ];
54497
+ if (args.length === 0 || hasHelp(args) || options2.some((arg) => ["-h", "-V", "-help", "-version"].includes(arg)))
54498
+ return "unknown";
54499
+ if (options2.some(
54500
+ (arg, index) => /[$`*?()[\]{}]/.test(arg) && (arg.startsWith("-") || signalValueOptions.includes(options2[index - 1])) || /^-(?:[lL0]|-(?:.*list|table)(?:=|$))/.test(arg) || /^--signal=/.test(arg) && signalZero.test(arg.slice(9)) || /^-(?:SIG)?0+$/i.test(arg) || root === "kill" && /^-[sn](?:SIG)?0+$/i.test(arg) || root === "killall" && /^-s(?:SIG)?0+$/i.test(arg) || index > 0 && signalValueOptions.includes(options2[index - 1]) && signalZero.test(arg)
54501
+ ))
54502
+ return "unknown";
54503
+ return "write";
54504
+ }
54505
+ __name(processSafety, "processSafety");
54506
+ function evaluateSubstitutions(node) {
54507
+ const substitutions = collectDescendants(
54508
+ node,
54509
+ /* @__PURE__ */ new Set(["command_substitution", "process_substitution"]),
54510
+ true
54511
+ );
54512
+ if (substitutions.length === 0) return "read-only";
54513
+ return mergeSafety(
54514
+ "unknown",
54515
+ ...substitutions.flatMap((substitution) => substitution.namedChildren).map(evaluateStatementSafety)
54516
+ );
54517
+ }
54518
+ __name(evaluateSubstitutions, "evaluateSubstitutions");
54519
+ function evaluateCommandSafety(commandNode) {
54520
+ const rawRoot = commandNode.childForFieldName("name")?.text;
54521
+ const root = getCommandName(commandNode);
54522
+ const argNodes = getArgumentNodes(commandNode);
54523
+ const args = argNodes.map((node) => stripOuterQuotes(node.text));
54524
+ let result;
54525
+ if (!root) result = "read-only";
54526
+ else if (rawRoot !== root) result = "unknown";
54527
+ else if (WRITE_ROOT_COMMAND.test(root)) {
54528
+ result = hasHelp(args) ? "unknown" : "write";
54529
+ } else if (/^(kill|killall|pkill)$/.test(root)) {
54530
+ result = processSafety(root, args);
54531
+ } else if (root === "git") result = evaluateGitSafety(args);
54532
+ else if (root === "find") result = evaluateFindSafety(args);
54533
+ else if (root === "sed") result = evaluateSedSafety(args);
54534
+ else if (root === "awk") result = evaluateAwkSafety(args);
54535
+ else if (root === "sort" || root === "tree") {
54536
+ result = evaluateOutputOption(args, root === "sort") ?? "read-only";
54537
+ if (hasHelp(args, ["-o", "--output"])) result = "unknown";
54538
+ if (beforeTerminator(args).some(
54539
+ (arg) => /^(?:--o|-[^-]+o)/.test(arg) || root === "sort" && arg.startsWith("--co")
54540
+ )) {
54541
+ result = mergeSafety(result, "unknown");
54542
+ }
54543
+ } else if (root === "uniq") {
54544
+ result = hasHelp(args) ? "unknown" : evaluateUniqSafety(args);
54545
+ } else if (root === "tee") {
54546
+ const writesFile = args.some(
54547
+ (arg, index) => !arg.startsWith("-") || args[index - 1] === "--"
54548
+ );
54549
+ result = writesFile ? "write" : "unknown";
54550
+ } else if (root === "dd") {
54551
+ result = args.some((arg) => arg.startsWith("of=")) ? "write" : "unknown";
54552
+ } else if (root === "printf" && beforeTerminator(args).some((arg) => /^-[^-]*v/.test(arg)) || ["less", "more"].includes(root) || ["rg", "ripgrep"].includes(root) && beforeTerminator(args).some(
54553
+ (arg) => /^(?:--(?:hostname-bin|pre)(?:=|$)|--search-zip$|-[^-]*z)/.test(arg)
54554
+ )) {
54555
+ result = "unknown";
54556
+ } else {
54557
+ result = READ_ONLY_ROOT_COMMANDS2.has(root) ? "read-only" : "unknown";
54558
+ }
54559
+ if (result === "read-only" && root && /^(awk|find|git|printf|rg|ripgrep|sed|sort|tree|uniq)$/.test(root) && argNodes.some((node) => hasShellExpansion(node))) {
54560
+ result = "unknown";
54561
+ }
54562
+ if (result === "write" && !["find", "git", "sed", "sort", "tree"].includes(root ?? "") && hasHelp(args))
54563
+ result = "unknown";
54564
+ const hasEnvironment = commandNode.namedChildren.some(
54565
+ (child) => child.type === "variable_assignment"
54566
+ );
54567
+ if (root && hasEnvironment) result = mergeSafety(result, "unknown");
54568
+ return mergeSafety(
54569
+ result,
54570
+ evaluateRedirectionSafety(commandNode),
54571
+ ...commandNode.namedChildren.filter((child) => !child.type.endsWith("_redirect")).map(evaluateSubstitutions)
54572
+ );
54573
+ }
54574
+ __name(evaluateCommandSafety, "evaluateCommandSafety");
54575
+ function evaluateRedirectionSafety(node) {
54576
+ let result = "read-only";
54577
+ for (const redirect of node.namedChildren) {
54578
+ if (!redirect.type.endsWith("_redirect")) continue;
54579
+ result = mergeSafety(result, evaluateSubstitutions(redirect));
54580
+ if (redirect.type !== "file_redirect") continue;
54581
+ const operator = redirect.children.find(
54582
+ (child) => child.type !== "file_descriptor"
54583
+ );
54584
+ if (!operator) return "unknown";
54585
+ if (WRITE_REDIRECT_OPERATORS.has(operator.type)) return "write";
54586
+ if (operator.type === ">&") {
54587
+ const destination = redirect.childForFieldName("destination");
54588
+ if (!destination) return "unknown";
54589
+ const target = stripOuterQuotes(destination.text);
54590
+ if (/^(?:\d+|-)$/.test(target)) continue;
54591
+ result = mergeSafety(
54592
+ result,
54593
+ /[$`*?()[\]{}]/.test(target) ? "unknown" : "write"
54594
+ );
54190
54595
  }
54191
- case "function_definition":
54192
- return false;
54193
- case "if_statement":
54194
- case "while_statement":
54195
- case "for_statement":
54196
- case "case_statement":
54197
- case "c_style_for_statement":
54198
- return false;
54199
- case "declaration_command":
54200
- return false;
54201
- default:
54202
- return false;
54203
54596
  }
54597
+ return result;
54204
54598
  }
54205
- __name(evaluateStatementReadOnly, "evaluateStatementReadOnly");
54599
+ __name(evaluateRedirectionSafety, "evaluateRedirectionSafety");
54600
+ function childrenSafety(node, floor = "read-only") {
54601
+ return mergeSafety(floor, ...node.namedChildren.map(evaluateStatementSafety));
54602
+ }
54603
+ __name(childrenSafety, "childrenSafety");
54604
+ function evaluateStatementSafety(node) {
54605
+ if (node.type === "command") return evaluateCommandSafety(node);
54606
+ if (CHILD_STATEMENT.test(node.type)) return childrenSafety(node);
54607
+ if (node.type === "redirected_statement")
54608
+ return mergeSafety(
54609
+ ...node.namedChildren.filter((child) => !child.type.endsWith("_redirect")).map((child) => evaluateStatementSafety(child)),
54610
+ evaluateRedirectionSafety(node)
54611
+ );
54612
+ if (/^variable_assignments?$/.test(node.type))
54613
+ return mergeSafety(
54614
+ node.parent?.namedChildCount === 1 ? "read-only" : "unknown",
54615
+ evaluateSubstitutions(node)
54616
+ );
54617
+ if (node.type === "function_definition") return "unknown";
54618
+ return childrenSafety(node, "unknown");
54619
+ }
54620
+ __name(evaluateStatementSafety, "evaluateStatementSafety");
54621
+ async function classifyInternal(command) {
54622
+ const tree = await parseShellCommand(command);
54623
+ try {
54624
+ const root = tree.rootNode;
54625
+ if (root.namedChildCount === 0 || root.hasError) return "unknown";
54626
+ return mergeSafety(...root.namedChildren.map(evaluateStatementSafety));
54627
+ } finally {
54628
+ tree.delete();
54629
+ }
54630
+ }
54631
+ __name(classifyInternal, "classifyInternal");
54206
54632
  async function isShellCommandReadOnlyAST(command) {
54207
54633
  if (typeof command !== "string" || !command.trim()) return false;
54208
54634
  if (parserInitFailed) {
54209
54635
  return isShellCommandReadOnly(command);
54210
54636
  }
54211
54637
  try {
54212
- const tree = await parseShellCommand(command);
54213
- const root = tree.rootNode;
54214
- if (root.namedChildCount === 0) return false;
54215
- for (const stmt of root.namedChildren) {
54216
- if (!evaluateStatementReadOnly(stmt)) {
54217
- tree.delete();
54218
- return false;
54219
- }
54220
- }
54221
- tree.delete();
54222
- return true;
54638
+ return await classifyInternal(command) === "read-only";
54223
54639
  } catch {
54224
54640
  return isShellCommandReadOnly(command);
54225
54641
  }
@@ -138286,7 +138702,7 @@ function isToolCallConcurrencySafe(name, kind, args) {
138286
138702
  const command = args?.command;
138287
138703
  if (typeof command !== "string") return false;
138288
138704
  try {
138289
- return isShellCommandReadOnly(stripShellWrapper(command));
138705
+ return isShellCommandReadOnly(command);
138290
138706
  } catch {
138291
138707
  return false;
138292
138708
  }
@@ -154801,19 +155217,19 @@ var Config = class {
154801
155217
  }, "registerStructuredOutputIfRequested");
154802
155218
  if (this.getBareMode()) {
154803
155219
  await registerLazy(ToolNames.READ_FILE, async () => {
154804
- const { ReadFileTool } = await import("./read-file-VLEAEXFP.js");
155220
+ const { ReadFileTool } = await import("./read-file-VSKOE22I.js");
154805
155221
  return new ReadFileTool(this);
154806
155222
  });
154807
155223
  await registerLazy(ToolNames.EDIT, async () => {
154808
- const { EditTool } = await import("./edit-JN467GIR.js");
155224
+ const { EditTool } = await import("./edit-GORZTX2U.js");
154809
155225
  return new EditTool(this);
154810
155226
  });
154811
155227
  await registerLazy(ToolNames.NOTEBOOK_EDIT, async () => {
154812
- const { NotebookEditTool } = await import("./notebook-edit-IHGW42QK.js");
155228
+ const { NotebookEditTool } = await import("./notebook-edit-IBEOVZ6A.js");
154813
155229
  return new NotebookEditTool(this);
154814
155230
  });
154815
155231
  await registerLazy(ToolNames.SHELL, async () => {
154816
- const { ShellTool: ShellTool2 } = await import("./shell-KR3IMYH6.js");
155232
+ const { ShellTool: ShellTool2 } = await import("./shell-2NGEMAVM.js");
154817
155233
  return new ShellTool2(this);
154818
155234
  });
154819
155235
  await registerStructuredOutputIfRequested();
@@ -154823,7 +155239,7 @@ var Config = class {
154823
155239
  return registry;
154824
155240
  }
154825
155241
  await registerLazy(ToolNames.TOOL_SEARCH, async () => {
154826
- const { ToolSearchTool } = await import("./tool-search-LSSKWZKH.js");
155242
+ const { ToolSearchTool } = await import("./tool-search-5IE2VO7X.js");
154827
155243
  return new ToolSearchTool(this);
154828
155244
  });
154829
155245
  await registerLazy(ToolNames.READ_MCP_RESOURCE, async () => {
@@ -154831,7 +155247,7 @@ var Config = class {
154831
155247
  return new ReadMcpResourceTool(this);
154832
155248
  });
154833
155249
  await registerLazy(ToolNames.AGENT, async () => {
154834
- const { AgentTool: AgentTool2 } = await import("./agent-BONWC4VY.js");
155250
+ const { AgentTool: AgentTool2 } = await import("./agent-CKSI7BTR.js");
154835
155251
  return new AgentTool2(this);
154836
155252
  });
154837
155253
  await registerLazy(ToolNames.TASK_STOP, async () => {
@@ -154843,7 +155259,7 @@ var Config = class {
154843
155259
  return new SendMessageTool(this);
154844
155260
  });
154845
155261
  await registerLazy(ToolNames.SKILL, async () => {
154846
- const { SkillTool } = await import("./skill-QLM2LSF7.js");
155262
+ const { SkillTool } = await import("./skill-3U2T6H3E.js");
154847
155263
  return new SkillTool(this);
154848
155264
  });
154849
155265
  await registerLazy(ToolNames.LS, async () => {
@@ -154851,7 +155267,7 @@ var Config = class {
154851
155267
  return new LSTool(this);
154852
155268
  });
154853
155269
  await registerLazy(ToolNames.READ_FILE, async () => {
154854
- const { ReadFileTool } = await import("./read-file-VLEAEXFP.js");
155270
+ const { ReadFileTool } = await import("./read-file-VSKOE22I.js");
154855
155271
  return new ReadFileTool(this);
154856
155272
  });
154857
155273
  if (this.getUseRipgrep()) {
@@ -154866,7 +155282,7 @@ var Config = class {
154866
155282
  recordStartupEvent("config_initialize_ripgrep_probe_end");
154867
155283
  if (useRipgrep) {
154868
155284
  await registerLazy(ToolNames.GREP, async () => {
154869
- const { RipGrepTool: RipGrepTool2 } = await import("./ripGrep-MT23EIDD.js");
155285
+ const { RipGrepTool: RipGrepTool2 } = await import("./ripGrep-5V5FLW2A.js");
154870
155286
  return new RipGrepTool2(this);
154871
155287
  });
154872
155288
  } else {
@@ -154879,7 +155295,7 @@ var Config = class {
154879
155295
  )
154880
155296
  );
154881
155297
  await registerLazy(ToolNames.GREP, async () => {
154882
- const { GrepTool } = await import("./grep-MOGRCYB4.js");
155298
+ const { GrepTool } = await import("./grep-HZLSTX7D.js");
154883
155299
  return new GrepTool(this);
154884
155300
  });
154885
155301
  }
@@ -154887,28 +155303,28 @@ var Config = class {
154887
155303
  recordStartupEvent("config_initialize_ripgrep_probe_start");
154888
155304
  recordStartupEvent("config_initialize_ripgrep_probe_end");
154889
155305
  await registerLazy(ToolNames.GREP, async () => {
154890
- const { GrepTool } = await import("./grep-MOGRCYB4.js");
155306
+ const { GrepTool } = await import("./grep-HZLSTX7D.js");
154891
155307
  return new GrepTool(this);
154892
155308
  });
154893
155309
  }
154894
155310
  await registerLazy(ToolNames.GLOB, async () => {
154895
- const { GlobTool } = await import("./glob-FPKAMR6B.js");
155311
+ const { GlobTool } = await import("./glob-GOAPGD6G.js");
154896
155312
  return new GlobTool(this);
154897
155313
  });
154898
155314
  await registerLazy(ToolNames.EDIT, async () => {
154899
- const { EditTool } = await import("./edit-JN467GIR.js");
155315
+ const { EditTool } = await import("./edit-GORZTX2U.js");
154900
155316
  return new EditTool(this);
154901
155317
  });
154902
155318
  await registerLazy(ToolNames.NOTEBOOK_EDIT, async () => {
154903
- const { NotebookEditTool } = await import("./notebook-edit-IHGW42QK.js");
155319
+ const { NotebookEditTool } = await import("./notebook-edit-IBEOVZ6A.js");
154904
155320
  return new NotebookEditTool(this);
154905
155321
  });
154906
155322
  await registerLazy(ToolNames.WRITE_FILE, async () => {
154907
- const { WriteFileTool } = await import("./write-file-E7T3PU3B.js");
155323
+ const { WriteFileTool } = await import("./write-file-DR3HN7IH.js");
154908
155324
  return new WriteFileTool(this);
154909
155325
  });
154910
155326
  await registerLazy(ToolNames.SHELL, async () => {
154911
- const { ShellTool: ShellTool2 } = await import("./shell-KR3IMYH6.js");
155327
+ const { ShellTool: ShellTool2 } = await import("./shell-2NGEMAVM.js");
154912
155328
  return new ShellTool2(this);
154913
155329
  });
154914
155330
  await registerLazy(ToolNames.TODO_WRITE, async () => {
@@ -154921,24 +155337,24 @@ var Config = class {
154921
155337
  });
154922
155338
  if (!this.sdkMode) {
154923
155339
  await registerLazy(ToolNames.EXIT_PLAN_MODE, async () => {
154924
- const { ExitPlanModeTool } = await import("./exitPlanMode-EIUETQI6.js");
155340
+ const { ExitPlanModeTool } = await import("./exitPlanMode-U5Z6XBLO.js");
154925
155341
  return new ExitPlanModeTool(this);
154926
155342
  });
154927
155343
  await registerLazy(ToolNames.ENTER_PLAN_MODE, async () => {
154928
- const { EnterPlanModeTool } = await import("./enterPlanMode-BRZOG4DB.js");
155344
+ const { EnterPlanModeTool } = await import("./enterPlanMode-LIIPP37T.js");
154929
155345
  return new EnterPlanModeTool(this);
154930
155346
  });
154931
155347
  }
154932
155348
  await registerLazy(ToolNames.ENTER_WORKTREE, async () => {
154933
- const { EnterWorktreeTool } = await import("./enter-worktree-MMO4VBQE.js");
155349
+ const { EnterWorktreeTool } = await import("./enter-worktree-LJB2AW4L.js");
154934
155350
  return new EnterWorktreeTool(this);
154935
155351
  });
154936
155352
  await registerLazy(ToolNames.EXIT_WORKTREE, async () => {
154937
- const { ExitWorktreeTool } = await import("./exit-worktree-UD7PI5H5.js");
155353
+ const { ExitWorktreeTool } = await import("./exit-worktree-IEP2WHOV.js");
154938
155354
  return new ExitWorktreeTool(this);
154939
155355
  });
154940
155356
  await registerLazy(ToolNames.WEB_FETCH, async () => {
154941
- const { WebFetchTool } = await import("./web-fetch-7QTEGJI5.js");
155357
+ const { WebFetchTool } = await import("./web-fetch-ZDNE6FF2.js");
154942
155358
  return new WebFetchTool(this);
154943
155359
  });
154944
155360
  if (this.isArtifactEnabled()) {
@@ -154984,7 +155400,7 @@ var Config = class {
154984
155400
  });
154985
155401
  if (this.isAgentTeamEnabled()) {
154986
155402
  await registerLazy(ToolNames.TEAM_CREATE, async () => {
154987
- const { TeamCreateTool } = await import("./team-create-Q5B5M7UD.js");
155403
+ const { TeamCreateTool } = await import("./team-create-R6AXDYPG.js");
154988
155404
  return new TeamCreateTool(this);
154989
155405
  });
154990
155406
  await registerLazy(ToolNames.TEAM_DELETE, async () => {
@@ -154992,7 +155408,7 @@ var Config = class {
154992
155408
  return new TeamDeleteTool(this);
154993
155409
  });
154994
155410
  await registerLazy(ToolNames.TEAM_PLAN_APPROVAL, async () => {
154995
- const { TeamPlanApprovalTool } = await import("./team-plan-approval-J55PXNY2.js");
155411
+ const { TeamPlanApprovalTool } = await import("./team-plan-approval-O2ZPPT64.js");
154996
155412
  return new TeamPlanApprovalTool(this);
154997
155413
  });
154998
155414
  await registerLazy(ToolNames.TASK_CREATE, async () => {
@@ -155010,16 +155426,16 @@ var Config = class {
155010
155426
  }
155011
155427
  if (this.isWorkflowsEnabled()) {
155012
155428
  await registerLazy(ToolNames.WORKFLOW, async () => {
155013
- const { WorkflowTool } = await import("./workflow-G3CZU256.js");
155429
+ const { WorkflowTool } = await import("./workflow-G7U6OQWS.js");
155014
155430
  return new WorkflowTool(this);
155015
155431
  });
155016
155432
  }
155017
155433
  if (this.isComputerUseEnabled()) {
155018
- const { registerComputerUseTools } = await import("./computer-use-UY4A72X7.js");
155434
+ const { registerComputerUseTools } = await import("./computer-use-4PUGCUQK.js");
155019
155435
  await registerComputerUseTools(registerLazy, this);
155020
155436
  }
155021
155437
  await registerLazy(ToolNames.MONITOR, async () => {
155022
- const { MonitorTool } = await import("./monitor-KY7YH7TL.js");
155438
+ const { MonitorTool } = await import("./monitor-LMYKCF6R.js");
155023
155439
  return new MonitorTool(this);
155024
155440
  });
155025
155441
  if (this.pendingMcpBudgetCallback) {