pushary 1.9.94 → 1.9.97
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/dist/{api-QBIRIMGU.js → api-WH3DLHJB.js} +10 -10
- package/dist/bin/pushary-bell-hook.js +26 -26
- package/dist/bin/pushary-bell.js +10 -10
- package/dist/bin/pushary-claude.js +27 -27
- package/dist/bin/pushary-clean.js +34 -34
- package/dist/bin/pushary-codex-bridge.js +21 -21
- package/dist/bin/pushary-codex-hook.js +32 -34
- package/dist/bin/pushary-codex-session.js +8 -8
- package/dist/bin/pushary-codex.js +14 -14
- package/dist/bin/pushary-connect.js +27 -27
- package/dist/bin/pushary-cowork.js +5 -5
- package/dist/bin/pushary-daemon.js +39 -39
- package/dist/bin/pushary-disconnect.js +26 -26
- package/dist/bin/pushary-display-hook.js +17 -17
- package/dist/bin/pushary-doctor.js +42 -42
- package/dist/bin/pushary-elicitation-hook.js +26 -26
- package/dist/bin/pushary-gemini-bridge.js +15 -15
- package/dist/bin/pushary-gemini-hook.js +28 -28
- package/dist/bin/pushary-hook.js +30 -30
- package/dist/bin/pushary-login.js +20 -20
- package/dist/bin/pushary-logout.js +25 -25
- package/dist/bin/pushary-mcp.js +11 -11
- package/dist/bin/pushary-mode.js +15 -15
- package/dist/bin/pushary-notification-hook.js +25 -25
- package/dist/bin/pushary-opencode-hook.js +27 -27
- package/dist/bin/pushary-permission-denied-hook.js +30 -30
- package/dist/bin/pushary-permission-hook.js +30 -30
- package/dist/bin/pushary-post-hook.js +25 -25
- package/dist/bin/pushary-prompt-hook.js +25 -25
- package/dist/bin/pushary-session-end-hook.js +27 -27
- package/dist/bin/pushary-session-start-hook.js +35 -35
- package/dist/bin/pushary-setup.js +48 -48
- package/dist/bin/pushary-stats.js +5 -5
- package/dist/bin/pushary-status.js +32 -32
- package/dist/bin/pushary-stop-hook.js +25 -25
- package/dist/bin/pushary-stopfailure-hook.js +25 -25
- package/dist/bin/pushary-suggestions.js +15 -15
- package/dist/bin/pushary-transcript-register.js +18 -18
- package/dist/bin/pushary-transcripts.js +26 -26
- package/dist/bin/pushary-upgrade.js +40 -40
- package/dist/bin/pushary-wait.js +15 -15
- package/dist/bin/pushary.js +7 -7
- package/dist/{chunk-ANZECRZO.js → chunk-2ZAFA3XI.js} +3 -3
- package/dist/{chunk-AMPF5FAS.js → chunk-32577NGL.js} +1 -1
- package/dist/{chunk-K3E3NFTT.js → chunk-4D4USO5K.js} +6 -6
- package/dist/{chunk-EFCHGKAD.js → chunk-5OLBO5EB.js} +1 -1
- package/dist/{chunk-KXCSF2IK.js → chunk-5RNZP53C.js} +6 -6
- package/dist/{chunk-ZZ5QZ24I.js → chunk-5U63KUP3.js} +1 -1
- package/dist/{chunk-HHKBWPXA.js → chunk-5WOO44TA.js} +5 -5
- package/dist/{chunk-4YSFD4RY.js → chunk-5WYXFKZV.js} +1 -1
- package/dist/{chunk-5ZBYW7IO.js → chunk-5YRDZE5F.js} +1 -1
- package/dist/{chunk-GPGLRSGY.js → chunk-6CDA4R5L.js} +3 -3
- package/dist/{chunk-YQCRX4T6.js → chunk-6RGQIKAC.js} +3 -3
- package/dist/{chunk-CA2V7TKX.js → chunk-APFQBVQW.js} +6 -6
- package/dist/{chunk-4GNFBBE6.js → chunk-AUZITE2H.js} +6 -6
- package/dist/{chunk-Z4JULPCS.js → chunk-CB2RYMAO.js} +1 -1
- package/dist/{chunk-6SN6L5YT.js → chunk-CG3C2WL7.js} +11 -11
- package/dist/{chunk-FQZSKWWL.js → chunk-CMDIKFVL.js} +1 -1
- package/dist/{chunk-JLWI2HZF.js → chunk-CP72YEEA.js} +1 -1
- package/dist/{chunk-OWCWJBGW.js → chunk-E5WUBHVH.js} +4 -4
- package/dist/{chunk-ERQD5UVH.js → chunk-EAJT6RYP.js} +7 -7
- package/dist/{chunk-BE4KMA7N.js → chunk-FZQSUS3R.js} +21 -19
- package/dist/{chunk-QR7RXGNF.js → chunk-GEA6ZV2P.js} +2 -2
- package/dist/{chunk-RGMS5EDS.js → chunk-GN2L5CYF.js} +1 -1
- package/dist/{chunk-HRFOVTCQ.js → chunk-GNFUPHPZ.js} +10 -10
- package/dist/{chunk-REV2QMUD.js → chunk-HD7AURL6.js} +4 -4
- package/dist/{chunk-K56A3LSA.js → chunk-HWEEBVS7.js} +4 -4
- package/dist/{chunk-X7GKDLW7.js → chunk-HXUE6IIP.js} +5 -5
- package/dist/{chunk-E2WYLZIL.js → chunk-IED5CTYP.js} +3 -3
- package/dist/{chunk-KH3QOWTE.js → chunk-IFQKSIID.js} +3 -3
- package/dist/{chunk-JCZ7WE5G.js → chunk-JA6GCOW2.js} +7 -7
- package/dist/{chunk-AEKTC2DX.js → chunk-JR6FCHAQ.js} +3 -3
- package/dist/{chunk-LFIFIIMK.js → chunk-KNVTKFDP.js} +2 -2
- package/dist/{chunk-4N6MND55.js → chunk-KYX7VBEE.js} +2 -2
- package/dist/{chunk-F74RBPJY.js → chunk-KZTN6OXM.js} +6 -6
- package/dist/{chunk-SSXMA23D.js → chunk-LKDAMWTZ.js} +4 -4
- package/dist/{chunk-PGCDYBKG.js → chunk-MFJFN4DA.js} +3 -3
- package/dist/{chunk-TYHOBIDF.js → chunk-MGYGWHG5.js} +1 -1
- package/dist/{chunk-XASOD3XX.js → chunk-MYKZPTAL.js} +1 -1
- package/dist/{chunk-MC7I3SZW.js → chunk-NDJ7H2WF.js} +1 -1
- package/dist/{chunk-QVCDU4NT.js → chunk-NI3NSURQ.js} +1 -1
- package/dist/{chunk-X5DCL36E.js → chunk-NTCVGJFC.js} +4 -4
- package/dist/{chunk-JJ2AA3N6.js → chunk-OBB6VTSG.js} +5 -5
- package/dist/{chunk-4YPTEVZD.js → chunk-ORVMA5KJ.js} +3 -3
- package/dist/{chunk-RCDCFFG4.js → chunk-OW4WEO56.js} +3 -3
- package/dist/{chunk-AUIRBCYE.js → chunk-QCEY7TSX.js} +3 -3
- package/dist/{chunk-CS2C7S5L.js → chunk-QP3OSLKU.js} +5 -5
- package/dist/{chunk-OSDL6OND.js → chunk-R7D3PH2M.js} +6 -6
- package/dist/{chunk-QU2G6MM7.js → chunk-R7TVELKF.js} +1 -1
- package/dist/{chunk-FSMR6GJT.js → chunk-RILJLDKG.js} +5 -5
- package/dist/{chunk-SV6WE5QB.js → chunk-RPY5XCGA.js} +2 -2
- package/dist/{chunk-5QSPRDUO.js → chunk-RRA6POT5.js} +1 -1
- package/dist/{chunk-BOHUB5VP.js → chunk-RSITUL2U.js} +2 -2
- package/dist/{chunk-IB5MLSE3.js → chunk-RZD7ULBJ.js} +1 -1
- package/dist/{chunk-6YX4VASU.js → chunk-SXX47FHL.js} +2 -2
- package/dist/{chunk-7Y3AQNHV.js → chunk-T35RHO3X.js} +5 -5
- package/dist/{chunk-QYP4EEDA.js → chunk-TKOL7DJH.js} +2 -2
- package/dist/{chunk-Z5QJONDX.js → chunk-TSSV3NBD.js} +2 -2
- package/dist/{chunk-3GZCHFYV.js → chunk-TZE2S3XP.js} +3 -3
- package/dist/{chunk-CDIVGMBR.js → chunk-UAUADSJX.js} +2 -2
- package/dist/{chunk-HHE7ONVT.js → chunk-VAY5AJ6N.js} +4 -4
- package/dist/{chunk-UFT4R4V7.js → chunk-VHOGSWUF.js} +3 -3
- package/dist/{chunk-VDBRLNW7.js → chunk-VPT3RDTO.js} +1 -1
- package/dist/{chunk-HZQIC3DG.js → chunk-VVHNHETX.js} +2 -2
- package/dist/{chunk-2TA5UKNE.js → chunk-VVP4CP4O.js} +10 -10
- package/dist/{chunk-UC6IZRXP.js → chunk-W3OTAHLV.js} +4 -4
- package/dist/{chunk-5M6ASRLB.js → chunk-W5IW7NZE.js} +1 -1
- package/dist/{chunk-XERTD7VZ.js → chunk-WOFHN2IZ.js} +370 -44
- package/dist/{chunk-3DASOC3M.js → chunk-X22LLKBY.js} +3 -3
- package/dist/{chunk-SKYDYDGX.js → chunk-Z6O6CDTP.js} +5 -5
- package/dist/{chunk-QNFDU72D.js → chunk-ZDIQPYM2.js} +1 -1
- package/dist/{chunk-IMNXYNBJ.js → chunk-ZFUSWR2P.js} +2 -2
- package/dist/{codex-app-cards-switch-QEMMPNK3.js → codex-app-cards-switch-DFZK6GPW.js} +11 -11
- package/dist/{codex-desktop-launch-LNIZPXSJ.js → codex-desktop-launch-7QGN7SL7.js} +1 -1
- package/dist/{codex-session-launch-IZ4IQDS7.js → codex-session-launch-OWMNCYAH.js} +18 -18
- package/dist/{config-3J5OOY3O.js → config-ITPE5M6M.js} +3 -3
- package/dist/{global-upgrade-LQM7IFAP.js → global-upgrade-PYEFLMJA.js} +10 -10
- package/dist/{identity-IQ3JVAIM.js → identity-WTYTOLG3.js} +4 -4
- package/dist/{live-capabilities-3AWVBJSK.js → live-capabilities-HZ42KLZS.js} +5 -5
- package/dist/{paths-TAAVCO2D.js → paths-6JUJIM74.js} +3 -3
- package/dist/{reapply-37FCVQCJ.js → reapply-5WV6IS5V.js} +28 -28
- package/dist/src/index.js +29 -29
- package/dist/{upgrade-lock-GWB57A36.js → upgrade-lock-ENAQL63D.js} +4 -4
- package/dist/{usage-QJYVQ3GS.js → usage-BO7LGOA3.js} +3 -3
- package/package.json +1 -1
|
@@ -1942,6 +1942,8 @@ var POWERSHELL_FILE_WRITERS = /* @__PURE__ */ new Set([
|
|
|
1942
1942
|
"start-bitstransfer"
|
|
1943
1943
|
]);
|
|
1944
1944
|
var POWERSHELL_FETCHERS = /* @__PURE__ */ new Set(["invoke-webrequest", "invoke-restmethod", "start-bitstransfer"]);
|
|
1945
|
+
var POWERSHELL_WEB_REQUESTS = /* @__PURE__ */ new Set(["invoke-webrequest", "invoke-restmethod"]);
|
|
1946
|
+
var WEB_READ_METHODS = /* @__PURE__ */ new Set(["get", "head", "options"]);
|
|
1945
1947
|
var DISK_ERASERS = /* @__PURE__ */ new Set(["format-volume", "clear-disk", "initialize-disk", "remove-partition", "format"]);
|
|
1946
1948
|
var WINDOWS_SERVICE_CHANGERS = /* @__PURE__ */ new Set([
|
|
1947
1949
|
"start-service",
|
|
@@ -2140,9 +2142,29 @@ var stageIsDestructive = (stage, judge) => {
|
|
|
2140
2142
|
const command = powerShellCommandOf(stage);
|
|
2141
2143
|
return DOTNET_RECURSIVE_DELETE.test(stage.source) || command !== null && (removesRecursively(command) || !onlyReads(command, judge) && judge.namesADestructiveAction(keywordTextOf(command)));
|
|
2142
2144
|
};
|
|
2145
|
+
var LOOKS_LIKE_AN_ADDRESS = /^(?:[a-z][a-z\d+.-]*:\/\/|localhost\b|127\.|\[::1\])/i;
|
|
2146
|
+
var namesAWebRequestBody = (command) => command.args.some((arg) => {
|
|
2147
|
+
const parameter = parameterOf(arg);
|
|
2148
|
+
return namesTheParameter(parameter, "body", 1) || namesTheParameter(parameter, "infile", 2) || namesTheParameter(parameter, "form", 3);
|
|
2149
|
+
});
|
|
2150
|
+
var webRequestMethodOf = (command) => parameterValueOf(command, "method", 2) ?? parameterValueOf(command, "custommethod", 2);
|
|
2151
|
+
var SPLATTED_PARAMETERS = /^@\w+$/;
|
|
2152
|
+
var splatsItsParameters = (command) => command.args.some((arg) => !arg.quoted && SPLATTED_PARAMETERS.test(arg.text));
|
|
2153
|
+
var goesThroughAProxy = (command) => command.args.some((arg) => namesTheParameter(parameterOf(arg), "proxy", 5));
|
|
2154
|
+
var webRequestSendsData = (command) => {
|
|
2155
|
+
const method = webRequestMethodOf(command);
|
|
2156
|
+
if (splatsItsParameters(command)) return true;
|
|
2157
|
+
return method === void 0 ? namesAWebRequestBody(command) : method.includes("$") || !WEB_READ_METHODS.has(method.toLowerCase());
|
|
2158
|
+
};
|
|
2159
|
+
var webRequestAddressesOf = (command) => {
|
|
2160
|
+
if (splatsItsParameters(command) || goesThroughAProxy(command)) return [];
|
|
2161
|
+
const uri = parameterValueOf(command, "uri", 2);
|
|
2162
|
+
return uri === void 0 ? positionalTextsOf(command).filter((text3) => LOOKS_LIKE_AN_ADDRESS.test(text3)) : [uri];
|
|
2163
|
+
};
|
|
2164
|
+
var sendsAWebRequestThatNeedsAPerson = (command, judge) => POWERSHELL_WEB_REQUESTS.has(command.cmdlet) && judge.webRequestNeedsAPerson({ sendsData: webRequestSendsData(command), addresses: webRequestAddressesOf(command) });
|
|
2143
2165
|
var stageHasAVisibleConsequence = (stage, judge) => {
|
|
2144
2166
|
const command = powerShellCommandOf(stage);
|
|
2145
|
-
return stage.redirectTargets.some((target) => namesAPathThatNeedsAPerson(target.text, judge)) || command !== null && !onlyReads(command, judge) && powerShellCommandChangesSomething(command, judge);
|
|
2167
|
+
return stage.redirectTargets.some((target) => namesAPathThatNeedsAPerson(target.text, judge)) || command !== null && sendsAWebRequestThatNeedsAPerson(command, judge) || command !== null && !onlyReads(command, judge) && powerShellCommandChangesSomething(command, judge);
|
|
2146
2168
|
};
|
|
2147
2169
|
var fetchesWithPowerShell = (stage, judge) => {
|
|
2148
2170
|
const command = powerShellCommandOf(stage);
|
|
@@ -4538,12 +4560,14 @@ var sqlClientChangesData = (invocation) => {
|
|
|
4538
4560
|
var PULL_REQUEST_CLIS = /* @__PURE__ */ new Set(["gh", "glab"]);
|
|
4539
4561
|
var PULL_REQUEST_NOUNS = /* @__PURE__ */ new Set(["pr", "mr"]);
|
|
4540
4562
|
var MERGE_SUBCOMMAND = "merge";
|
|
4541
|
-
var PULL_REQUEST_MERGE_PATH = /(?:^|\/)pulls
|
|
4563
|
+
var PULL_REQUEST_MERGE_PATH = /(?:^|\/)pulls\/\d+\/merge$/;
|
|
4564
|
+
var PULL_REQUEST_MERGE_PATH_SPELLED_ANY_WAY = /(?:^|\/)pulls\/[^/\s]+\/merge(?:[?#]|$)/;
|
|
4542
4565
|
var mergesAPullRequest = ({ program, args }) => {
|
|
4543
4566
|
if (program === void 0 || !PULL_REQUEST_CLIS.has(basenameOf(program.text))) return false;
|
|
4544
4567
|
const words = args.filter((arg) => !arg.text.startsWith("-"));
|
|
4545
4568
|
return words.some((word, index) => PULL_REQUEST_NOUNS.has(word.text) && words[index + 1]?.text === MERGE_SUBCOMMAND) || args.some((arg) => PULL_REQUEST_MERGE_PATH.test(arg.text));
|
|
4546
4569
|
};
|
|
4570
|
+
var mergesAPullRequestByAnyPath = ({ program, args }) => program !== void 0 && PULL_REQUEST_CLIS.has(basenameOf(program.text)) && args.some((arg) => PULL_REQUEST_MERGE_PATH_SPELLED_ANY_WAY.test(arg.text));
|
|
4547
4571
|
var DEPLOY_AND_SCHEMA_COMMAND_PATTERNS = [
|
|
4548
4572
|
"Bash(kubectl apply:*)",
|
|
4549
4573
|
"Bash(kubectl replace:*)",
|
|
@@ -4622,12 +4646,15 @@ var PUSHES_EVERY_TAG = /* @__PURE__ */ new Set(["--tags", "--follow-tags"]);
|
|
|
4622
4646
|
var NAMES_A_TAG = /(?:^|:)\+?refs\/tags\/|^tag$|(?:^|:)v?\d+(?:\.\d+){1,3}$|(?:^|:)v?\d+\.\d+\.\d+[-+][\w.]+$|\/v\d+\.\d+\.\d+(?:\.\d+)?(?:[-+][\w.]+)?$|^v\$/;
|
|
4623
4647
|
var TAG_HELD_IN_A_VARIABLE = /^v?\$\{?(?:\w+_)?(?:tag|version)(?:_name)?\}?$/i;
|
|
4624
4648
|
var GIT_PUSH = "push";
|
|
4649
|
+
var NAMES_A_MAJOR_VERSION_TAG = /(?:^|:)v\d+$/;
|
|
4650
|
+
var SETS_THE_UPSTREAM_BRANCH = /* @__PURE__ */ new Set(["-u", "--set-upstream"]);
|
|
4625
4651
|
var pushesATag = ({ program, args }) => {
|
|
4626
4652
|
if (program === void 0 || basenameOf(program.text) !== GIT) return false;
|
|
4627
4653
|
const [subcommand, ...rest] = argsAfterHarmlessGlobalFlags(args);
|
|
4628
4654
|
if (subcommand?.text !== GIT_PUSH) return false;
|
|
4629
4655
|
const operands = rest.filter((arg) => !FLAG.test(arg.text));
|
|
4630
|
-
|
|
4656
|
+
const pushesABranch = rest.some((arg) => SETS_THE_UPSTREAM_BRANCH.has(arg.text));
|
|
4657
|
+
return rest.some((arg) => PUSHES_EVERY_TAG.has(arg.text)) || operands.slice(1).some((operand) => NAMES_A_TAG.test(operand.text) || TAG_HELD_IN_A_VARIABLE.test(operand.text) || !pushesABranch && NAMES_A_MAJOR_VERSION_TAG.test(operand.text));
|
|
4631
4658
|
};
|
|
4632
4659
|
var SECRET_FILE_NAME = /^(?:\.env(?:\.(?!example$|sample$|template$)[\w.-]+)?|(?:secrets?|credentials)\.(?:json|ya?ml|env|toml|ini)|credentials)$/i;
|
|
4633
4660
|
var CI_WORKFLOW_FILE = /(?:^|\/)\.github\/workflows\/[^/]+$/i;
|
|
@@ -4643,7 +4670,24 @@ var AGENT_SETTINGS_FILE = new RegExp(String.raw`(?:^|/)(?:${[
|
|
|
4643
4670
|
String.raw`\.config/opencode/(?:opencode\.jsonc?|plugins?/.+)`,
|
|
4644
4671
|
String.raw`\.pushary(?:/.+)?`,
|
|
4645
4672
|
String.raw`\.git/hooks(?:/.+)?`,
|
|
4646
|
-
String.raw`\.
|
|
4673
|
+
String.raw`\.git/config`,
|
|
4674
|
+
String.raw`\.ssh(?:/(?!known_hosts(?:\.old)?$).+)?`,
|
|
4675
|
+
String.raw`\.mcp\.json`,
|
|
4676
|
+
String.raw`\.cursor/mcp\.json`,
|
|
4677
|
+
String.raw`\.claude/hooks/.+`,
|
|
4678
|
+
String.raw`pushary-(?:policy|mode)-[^/]*\.json`
|
|
4679
|
+
].join("|")})$`, "i");
|
|
4680
|
+
var HOME_DIRECTORY = String.raw`(?:~|\$HOME|\$\{HOME\}|(?:[A-Za-z]:)?/Users/[^/]+|/home/[^/]+|/root|/var/root)`;
|
|
4681
|
+
var FILE_THE_MACHINE_RUNS_LATER = new RegExp(String.raw`^(?:${[
|
|
4682
|
+
String.raw`${HOME_DIRECTORY}/\.(?:zshrc|zshenv|zprofile|zlogin|zlogout|bashrc|bash_profile|bash_login|bash_logout|bash_aliases|profile)(?:\.[\w-]+)?`,
|
|
4683
|
+
String.raw`${HOME_DIRECTORY}/\.gitconfig(?:[-._][\w.-]+)?`,
|
|
4684
|
+
String.raw`${HOME_DIRECTORY}/\.p10k\.zsh`,
|
|
4685
|
+
String.raw`${HOME_DIRECTORY}/\.(?:zsh|zshrc\.d|oh-my-zsh)/.+`,
|
|
4686
|
+
String.raw`${HOME_DIRECTORY}/\.config/(?:fish/config\.fish|fish/conf\.d/.+|git/config|zsh/.+|systemd/user/.+)`,
|
|
4687
|
+
String.raw`(?:.*/)?Library/Launch(?:Agents|Daemons)/[^/]+`,
|
|
4688
|
+
String.raw`(?:.*/)?(?:Windows)?PowerShell/(?:Microsoft\.[\w.]+_)?profile\.ps1`,
|
|
4689
|
+
String.raw`\$profile(?:\.\w+)?`,
|
|
4690
|
+
String.raw`/(?:private/)?etc/.+`
|
|
4647
4691
|
].join("|")})$`, "i");
|
|
4648
4692
|
var withoutDotSegments = (path) => {
|
|
4649
4693
|
const kept = [];
|
|
@@ -4655,12 +4699,15 @@ var withoutDotSegments = (path) => {
|
|
|
4655
4699
|
};
|
|
4656
4700
|
var pathNeedsAPersonToChange = (path) => {
|
|
4657
4701
|
const written = withoutDotSegments(normalizeSeparators(path));
|
|
4658
|
-
return SECRET_FILE_NAME.test(basenameOf(written)) || CI_WORKFLOW_FILE.test(written) || AGENT_SETTINGS_FILE.test(written);
|
|
4702
|
+
return SECRET_FILE_NAME.test(basenameOf(written)) || CI_WORKFLOW_FILE.test(written) || AGENT_SETTINGS_FILE.test(written) || FILE_THE_MACHINE_RUNS_LATER.test(written);
|
|
4659
4703
|
};
|
|
4660
4704
|
var REDIRECTS_INTO_A_SECRET_FILE = />>?\s*(?:[^\s;|&<>]*\/)?\.env(?:\.[\w-]+)?(?=$|[\s;|&)])/;
|
|
4661
4705
|
var COPIES_ONTO_ITS_LAST_OPERAND = /* @__PURE__ */ new Set(["cp", "install", "ln", "rsync", "scp"]);
|
|
4662
|
-
var WRITES_EVERY_OPERAND = /* @__PURE__ */ new Set(["mv", "tee", "rm", "unlink", "shred", "truncate"
|
|
4663
|
-
var EDITS_IN_PLACE = /* @__PURE__ */ new Set(["sed", "gsed", "perl"
|
|
4706
|
+
var WRITES_EVERY_OPERAND = /* @__PURE__ */ new Set(["mv", "tee", "rm", "unlink", "shred", "truncate"]);
|
|
4707
|
+
var EDITS_IN_PLACE = /* @__PURE__ */ new Set(["sed", "gsed", "perl"]);
|
|
4708
|
+
var IN_PLACE_FLAG = /^(?:-[A-Za-z]*i|--in-place(?:=.*)?)$/;
|
|
4709
|
+
var PERMISSIONS_OFF_WRITES_EVERY_OPERAND = /* @__PURE__ */ new Set([...WRITES_EVERY_OPERAND, "sponge"]);
|
|
4710
|
+
var PERMISSIONS_OFF_EDITS_IN_PLACE = /* @__PURE__ */ new Set([...EDITS_IN_PLACE, "yq"]);
|
|
4664
4711
|
var IN_PLACE_LONG_FLAG = /^--in-?place(?:=|$)/;
|
|
4665
4712
|
var IN_PLACE_LETTER = "i";
|
|
4666
4713
|
var SED_FLAGS_THAT_TAKE_THE_REST = /* @__PURE__ */ new Set(["e", "f", "l"]);
|
|
@@ -4698,6 +4745,7 @@ var spellingsOfAWord = (word) => {
|
|
|
4698
4745
|
}
|
|
4699
4746
|
return spellings.map((text3) => ({ ...word, text: text3 }));
|
|
4700
4747
|
};
|
|
4748
|
+
var namesASecretFile = (word) => word !== void 0 && SECRET_FILE_NAME.test(basenameOf(word.text));
|
|
4701
4749
|
var namesAFileThatNeedsAPerson = (word) => word !== void 0 && pathNeedsAPersonToChange(word.text);
|
|
4702
4750
|
var RECURSIVE_COPY_FLAG = /^(?:-[A-Za-z]*[rRa][A-Za-z]*|--recursive|--archive)$/;
|
|
4703
4751
|
var FOLDER_THAT_NEEDS_A_PERSON = new RegExp(String.raw`(?:^|/)(?:${[
|
|
@@ -4712,7 +4760,8 @@ var FOLDER_THAT_NEEDS_A_PERSON = new RegExp(String.raw`(?:^|/)(?:${[
|
|
|
4712
4760
|
String.raw`\.pushary`,
|
|
4713
4761
|
String.raw`\.git/hooks`,
|
|
4714
4762
|
String.raw`\.ssh`,
|
|
4715
|
-
String.raw`\.config/opencode(?:/plugins?)
|
|
4763
|
+
String.raw`\.config/opencode(?:/plugins?)?`,
|
|
4764
|
+
String.raw`Library/Launch(?:Agents|Daemons)`
|
|
4716
4765
|
].join("|")})$`, "i");
|
|
4717
4766
|
var folderNeedsAPersonToChange = (path) => FOLDER_THAT_NEEDS_A_PERSON.test(withoutDotSegments(normalizeSeparators(path)));
|
|
4718
4767
|
var NETWORK_SENDERS = /* @__PURE__ */ new Set([
|
|
@@ -4732,6 +4781,17 @@ var NETWORK_SENDERS = /* @__PURE__ */ new Set([
|
|
|
4732
4781
|
"rclone"
|
|
4733
4782
|
]);
|
|
4734
4783
|
var FILE_REFERENCE_PREFIX = /^(?:[\w.-]+=)?@|^[\w.-]+:/;
|
|
4784
|
+
var namesASecretFileReference = (word) => SECRET_FILE_NAME.test(basenameOf(word.text.replace(FILE_REFERENCE_PREFIX, "")));
|
|
4785
|
+
var sendsASecretFile = ({ program, args }) => program !== void 0 && NETWORK_SENDERS.has(basenameOf(program.text)) && args.some(namesASecretFileReference);
|
|
4786
|
+
var writesASecretFile = ({ program, args }) => {
|
|
4787
|
+
if (program === void 0) return false;
|
|
4788
|
+
if (sendsASecretFile({ program, args })) return true;
|
|
4789
|
+
const name = basenameOf(program.text);
|
|
4790
|
+
const operands = args.filter((arg) => !FLAG.test(arg.text));
|
|
4791
|
+
if (COPIES_ONTO_ITS_LAST_OPERAND.has(name)) return namesASecretFile(operands.at(-1));
|
|
4792
|
+
if (WRITES_EVERY_OPERAND.has(name)) return operands.some(namesASecretFile);
|
|
4793
|
+
return EDITS_IN_PLACE.has(name) && args.some((arg) => IN_PLACE_FLAG.test(arg.text)) && operands.some(namesASecretFile);
|
|
4794
|
+
};
|
|
4735
4795
|
var referencesAFileThatNeedsAPerson = (word) => pathNeedsAPersonToChange(word.text.replace(FILE_REFERENCE_PREFIX, ""));
|
|
4736
4796
|
var sendsAFileThatNeedsAPerson = ({ program, args }) => program !== void 0 && NETWORK_SENDERS.has(basenameOf(program.text)) && args.some(referencesAFileThatNeedsAPerson);
|
|
4737
4797
|
var targetDirectoryOf = (args) => {
|
|
@@ -4758,17 +4818,52 @@ var changesWhereGitLooksForHooks = ({ program, args }) => {
|
|
|
4758
4818
|
if (args[setting - 1]?.text === GIT_ONE_COMMAND_SETTING_FLAG) return true;
|
|
4759
4819
|
return args.some((arg) => arg.text === GIT_CONFIG_SUBCOMMAND) && (args[setting + 1] !== void 0 || args.some((arg) => GIT_CONFIG_UNSET_FLAGS.has(arg.text)));
|
|
4760
4820
|
};
|
|
4821
|
+
var GIT_SETTING_THAT_RUNS_A_PROGRAM = new RegExp(`^(?:${[
|
|
4822
|
+
String.raw`core\.(?:fsmonitor|sshcommand|pager|editor|askpass|gitproxy|alternaterefscommand|hookspath)`,
|
|
4823
|
+
String.raw`pager\..+`,
|
|
4824
|
+
String.raw`sequence\.editor`,
|
|
4825
|
+
String.raw`diff\.external`,
|
|
4826
|
+
String.raw`diff\..+\.(?:textconv|command)`,
|
|
4827
|
+
String.raw`merge\..+\.driver`,
|
|
4828
|
+
String.raw`(?:diff|merge)tool\..+\.(?:cmd|path)`,
|
|
4829
|
+
String.raw`interactive\.difffilter`,
|
|
4830
|
+
String.raw`gpg\.ssh\.defaultkeycommand`,
|
|
4831
|
+
String.raw`uploadpack\.packobjectshook`,
|
|
4832
|
+
String.raw`credential\.(?:.+\.)?helper`,
|
|
4833
|
+
String.raw`gpg(?:\.[\w-]+)?\.program`,
|
|
4834
|
+
String.raw`filter\..+\.(?:clean|smudge|process)`,
|
|
4835
|
+
String.raw`remote\..+\.(?:uploadpack|receivepack)`,
|
|
4836
|
+
String.raw`protocol\.(?:.+\.)?allow`,
|
|
4837
|
+
String.raw`include\.path`,
|
|
4838
|
+
String.raw`includeif\..+\.path`
|
|
4839
|
+
].join("|")})$`, "i");
|
|
4840
|
+
var SWITCHES_A_SETTING_ON_OR_OFF = /^(?:true|false|yes|no|on|off|0|1|never|)$/i;
|
|
4841
|
+
var GIT_INCLUDE_SETTING = /^include(?:if\..+)?\.path$/i;
|
|
4842
|
+
var GIT_CREDENTIAL_HELPER_SETTING = /^credential\.(?:.+\.)?helper$/i;
|
|
4843
|
+
var NAMES_A_KNOWN_CREDENTIAL_HELPER = /^(?:osxkeychain|store|cache|manager|manager-core|libsecret|wincred|gnome-keyring)(?:\s+--[\w-]+(?:=[\w./~:@%+,-]+)?)*$/i;
|
|
4844
|
+
var namesNoNewProgram = (setting, value) => !value.expands && !GIT_INCLUDE_SETTING.test(setting) && (SWITCHES_A_SETTING_ON_OR_OFF.test(value.text) || GIT_CREDENTIAL_HELPER_SETTING.test(setting) && NAMES_A_KNOWN_CREDENTIAL_HELPER.test(value.text));
|
|
4845
|
+
var GIT_SETTING_THAT_RUNS_A_COMMAND_AFTER_A_BANG = /^(?:alias\..+|submodule\..+\.update)$/i;
|
|
4846
|
+
var RUNS_A_SHELL_COMMAND = /^!/;
|
|
4847
|
+
var setsAGitSettingThatRunsAProgram = ({ program, args }) => {
|
|
4848
|
+
if (program === void 0 || basenameOf(program.text) !== GIT || !args.some((arg) => arg.text === GIT_CONFIG_SUBCOMMAND)) return false;
|
|
4849
|
+
const operands = args.filter((arg) => !FLAG.test(arg.text));
|
|
4850
|
+
const setting = operands.findIndex((arg) => GIT_SETTING_THAT_RUNS_A_PROGRAM.test(arg.text) || GIT_SETTING_THAT_RUNS_A_COMMAND_AFTER_A_BANG.test(arg.text));
|
|
4851
|
+
const value = setting === -1 ? void 0 : operands[setting + 1];
|
|
4852
|
+
const name = operands[setting]?.text ?? "";
|
|
4853
|
+
if (value === void 0 || namesNoNewProgram(name, value)) return false;
|
|
4854
|
+
return !GIT_SETTING_THAT_RUNS_A_COMMAND_AFTER_A_BANG.test(name) || value.expands || RUNS_A_SHELL_COMMAND.test(value.text);
|
|
4855
|
+
};
|
|
4761
4856
|
var writesAFileThatNeedsAPerson = ({ program, args }) => {
|
|
4762
4857
|
if (program === void 0) return false;
|
|
4763
4858
|
if (sendsAFileThatNeedsAPerson({ program, args })) return true;
|
|
4764
4859
|
const name = basenameOf(program.text);
|
|
4765
|
-
const editsInPlace =
|
|
4766
|
-
if (!COPIES_ONTO_ITS_LAST_OPERAND.has(name) && !
|
|
4860
|
+
const editsInPlace = PERMISSIONS_OFF_EDITS_IN_PLACE.has(name) && args.some((arg) => flagEditsInPlace(name, arg.text));
|
|
4861
|
+
if (!COPIES_ONTO_ITS_LAST_OPERAND.has(name) && !PERMISSIONS_OFF_WRITES_EVERY_OPERAND.has(name) && !editsInPlace) return false;
|
|
4767
4862
|
const spelled = args.filter((arg) => !FLAG.test(arg.text)).map(spellingsOfAWord);
|
|
4768
4863
|
if (spelled.includes(null)) return true;
|
|
4769
4864
|
const operands = spelled.flatMap((words) => words ?? []);
|
|
4770
4865
|
if (COPIES_ONTO_ITS_LAST_OPERAND.has(name)) return copiesOntoAFileThatNeedsAPerson(args, operands);
|
|
4771
|
-
if (
|
|
4866
|
+
if (PERMISSIONS_OFF_WRITES_EVERY_OPERAND.has(name)) {
|
|
4772
4867
|
return operands.some((operand) => namesAFileThatNeedsAPerson(operand) || folderNeedsAPersonToChange(operand.text)) || name === MOVE && copiesOntoAFileThatNeedsAPerson(args, operands);
|
|
4773
4868
|
}
|
|
4774
4869
|
return operands.some(namesAFileThatNeedsAPerson);
|
|
@@ -4877,7 +4972,8 @@ var AWS_OPTIONS_WITH_VALUES = /* @__PURE__ */ new Set([
|
|
|
4877
4972
|
"--cli-binary-format"
|
|
4878
4973
|
]);
|
|
4879
4974
|
var AWS_LOCAL_COMMANDS = /* @__PURE__ */ new Set(["configure", "help", "history", "sso", "login", "logout"]);
|
|
4880
|
-
var AWS_READ_OPERATION = /^(?:describe|list|get|head|batch-get|lookup|search|filter|scan|query|select|wait|validate|estimate|simulate|tail|ls|presign|help
|
|
4975
|
+
var AWS_READ_OPERATION = /^(?:describe|list|get|head|batch-get|lookup|search|filter|scan|query|select|wait|validate|estimate|simulate|tail|ls|presign|help)(?:-|$)/;
|
|
4976
|
+
var AWS_SIGN_IN_OR_QUERY_OPERATION = /^(?:login|update-kubeconfig|start-query|stop-query|assume-role)(?:-|$)/;
|
|
4881
4977
|
var AWS_S3_SERVICE = "s3";
|
|
4882
4978
|
var AWS_S3_COPIES = /* @__PURE__ */ new Set(["cp", "sync"]);
|
|
4883
4979
|
var S3_URL_PREFIX = "s3://";
|
|
@@ -4976,10 +5072,15 @@ var twilioCliWrites = (args) => {
|
|
|
4976
5072
|
return !TWILIO_READ_ACTIONS.has(topic.text.split(TWILIO_TOPIC_SEPARATOR).at(-1) ?? "");
|
|
4977
5073
|
};
|
|
4978
5074
|
var GITHUB_CLI = "gh";
|
|
5075
|
+
var AWS_CLI = "aws";
|
|
5076
|
+
var awsOnlySignsInOrQueries = (args) => {
|
|
5077
|
+
const [service, operation] = positionalWordsOf(args, AWS_OPTIONS_WITH_VALUES);
|
|
5078
|
+
return service !== void 0 && service.text !== AWS_S3_SERVICE && operation !== void 0 && AWS_SIGN_IN_OR_QUERY_OPERATION.test(operation.text);
|
|
5079
|
+
};
|
|
4979
5080
|
var REMOTE_API_CLI_WRITES = /* @__PURE__ */ new Map([
|
|
4980
5081
|
[GITHUB_CLI, githubCliWrites],
|
|
4981
5082
|
["stripe", stripeCliWrites],
|
|
4982
|
-
[
|
|
5083
|
+
[AWS_CLI, awsCliWrites],
|
|
4983
5084
|
["twilio", twilioCliWrites]
|
|
4984
5085
|
]);
|
|
4985
5086
|
var invocationWritesThroughARemoteApi = ({ program, args }) => {
|
|
@@ -4995,6 +5096,7 @@ var GITHUB_COMMANDS_WITH_A_CONSEQUENCE = /* @__PURE__ */ new Map([
|
|
|
4995
5096
|
["secret", /* @__PURE__ */ new Set(["set"])],
|
|
4996
5097
|
["variable", /* @__PURE__ */ new Set(["set"])],
|
|
4997
5098
|
[GITHUB_REPO_NOUN, /* @__PURE__ */ new Set(["archive", "rename"])],
|
|
5099
|
+
["workflow", /* @__PURE__ */ new Set(["run", "enable", "disable"])],
|
|
4998
5100
|
["ssh-key", /* @__PURE__ */ new Set(["add"])],
|
|
4999
5101
|
["gpg-key", /* @__PURE__ */ new Set(["add"])]
|
|
5000
5102
|
]);
|
|
@@ -5062,6 +5164,7 @@ var writesThroughAServiceApi = (invocation) => {
|
|
|
5062
5164
|
const name = basenameOf(innermost.program?.text ?? "");
|
|
5063
5165
|
if (name === GITHUB_CLI) return false;
|
|
5064
5166
|
if (name === STRIPE_CLI && !stripeMayUseLiveData(wordsOfInvocation(invocation))) return false;
|
|
5167
|
+
if (name === AWS_CLI && awsOnlySignsInOrQueries(innermost.args)) return false;
|
|
5065
5168
|
return invocationWritesThroughARemoteApi(innermost);
|
|
5066
5169
|
};
|
|
5067
5170
|
var NO_SHORT_OPTIONS = /* @__PURE__ */ new Set();
|
|
@@ -5164,13 +5267,210 @@ var sshRemoteCommandOf = (args) => {
|
|
|
5164
5267
|
}
|
|
5165
5268
|
return args.slice(index + 1);
|
|
5166
5269
|
};
|
|
5270
|
+
var PLAIN_REMOTE_COMMAND = /^[\w ./:=,@%+-]+$/;
|
|
5271
|
+
var REMOTE_STATUS_COMMAND = new RegExp(`^(?:${[
|
|
5272
|
+
String.raw`(?:uptime|free|who|w|nproc|lscpu|lsblk|last|lsof|netstat)`,
|
|
5273
|
+
String.raw`docker (?:compose )?(?:ps|images|logs|inspect|stats|top|version|info)`,
|
|
5274
|
+
String.raw`systemctl (?:status|is-active|is-enabled|is-failed|list-units|list-timers|show|cat)`,
|
|
5275
|
+
String.raw`journalctl`
|
|
5276
|
+
].join("|")})(?: |$)`);
|
|
5277
|
+
var JOURNAL_CHANGING_OPTIONS = [
|
|
5278
|
+
"vacuum-size",
|
|
5279
|
+
"vacuum-time",
|
|
5280
|
+
"vacuum-files",
|
|
5281
|
+
"rotate",
|
|
5282
|
+
"flush",
|
|
5283
|
+
"sync",
|
|
5284
|
+
"relinquish-var",
|
|
5285
|
+
"smart-relinquish-var",
|
|
5286
|
+
"setup-keys",
|
|
5287
|
+
"update-catalog",
|
|
5288
|
+
"cursor-file"
|
|
5289
|
+
];
|
|
5290
|
+
var JOURNAL_READ_OPTIONS_SHARING_A_PREFIX = /* @__PURE__ */ new Set(["cursor"]);
|
|
5291
|
+
var LONG_OPTION_NAME = /^--([\w-]+)/;
|
|
5292
|
+
var namesAJournalChangingOption = (word) => {
|
|
5293
|
+
const name = LONG_OPTION_NAME.exec(word)?.[1];
|
|
5294
|
+
return name !== void 0 && !JOURNAL_READ_OPTIONS_SHARING_A_PREFIX.has(name) && JOURNAL_CHANGING_OPTIONS.some((option) => option.startsWith(name));
|
|
5295
|
+
};
|
|
5296
|
+
var onlyReadsTheRemoteStatus = (command) => PLAIN_REMOTE_COMMAND.test(command) && REMOTE_STATUS_COMMAND.test(command) && !command.split(" ").some(namesAJournalChangingOption);
|
|
5167
5297
|
var sshRunsMoreThanAReadOnlyCommand = ({ program, args }) => {
|
|
5168
5298
|
if (program === void 0 || basenameOf(program.text) !== SSH) return false;
|
|
5169
5299
|
if (sshOptionRunsACommand(args)) return true;
|
|
5170
5300
|
const command = sshRemoteCommandOf(args);
|
|
5171
|
-
|
|
5301
|
+
const remote = command.map((arg) => arg.text).join(" ");
|
|
5302
|
+
return command.length > 0 && (command.some((arg) => arg.expands) || !isSafeReadOnlyCommand(remote) && !onlyReadsTheRemoteStatus(remote));
|
|
5303
|
+
};
|
|
5304
|
+
var REMOTE_COPY_OPTIONS_WITH_A_VALUE = /* @__PURE__ */ new Map([
|
|
5305
|
+
["scp", /* @__PURE__ */ new Set(["-c", "-D", "-F", "-i", "-J", "-l", "-o", "-P", "-S", "-X"])],
|
|
5306
|
+
["rsync", /* @__PURE__ */ new Set([
|
|
5307
|
+
"-e",
|
|
5308
|
+
"--rsh",
|
|
5309
|
+
"--rsync-path",
|
|
5310
|
+
"--exclude",
|
|
5311
|
+
"--include",
|
|
5312
|
+
"--filter",
|
|
5313
|
+
"-f",
|
|
5314
|
+
"--exclude-from",
|
|
5315
|
+
"--include-from",
|
|
5316
|
+
"--files-from",
|
|
5317
|
+
"--chmod",
|
|
5318
|
+
"--chown",
|
|
5319
|
+
"--log-file",
|
|
5320
|
+
"--password-file",
|
|
5321
|
+
"--port",
|
|
5322
|
+
"--timeout",
|
|
5323
|
+
"--contimeout",
|
|
5324
|
+
"--bwlimit",
|
|
5325
|
+
"--max-size",
|
|
5326
|
+
"--min-size",
|
|
5327
|
+
"--max-delete",
|
|
5328
|
+
"--backup-dir",
|
|
5329
|
+
"--link-dest",
|
|
5330
|
+
"--compare-dest",
|
|
5331
|
+
"--copy-dest",
|
|
5332
|
+
"--partial-dir",
|
|
5333
|
+
"--temp-dir",
|
|
5334
|
+
"-T",
|
|
5335
|
+
"--suffix",
|
|
5336
|
+
"--out-format",
|
|
5337
|
+
"--iconv",
|
|
5338
|
+
"--usermap",
|
|
5339
|
+
"--groupmap",
|
|
5340
|
+
"-M",
|
|
5341
|
+
"--remote-option",
|
|
5342
|
+
"--info",
|
|
5343
|
+
"--debug",
|
|
5344
|
+
"--skip-compress",
|
|
5345
|
+
"--compress-level",
|
|
5346
|
+
"--block-size",
|
|
5347
|
+
"-B",
|
|
5348
|
+
"--modify-window",
|
|
5349
|
+
"--sockopts",
|
|
5350
|
+
"--outbuf",
|
|
5351
|
+
"--copy-as",
|
|
5352
|
+
"--stop-at",
|
|
5353
|
+
"--stop-after",
|
|
5354
|
+
"--time-limit",
|
|
5355
|
+
"--checksum-seed",
|
|
5356
|
+
"--max-alloc",
|
|
5357
|
+
"--early-input",
|
|
5358
|
+
"--address",
|
|
5359
|
+
"--write-batch",
|
|
5360
|
+
"--read-batch",
|
|
5361
|
+
"--only-write-batch"
|
|
5362
|
+
])]
|
|
5363
|
+
]);
|
|
5364
|
+
var SSHPASS = "sshpass";
|
|
5365
|
+
var SSHPASS_OPTIONS_WITH_A_VALUE = /* @__PURE__ */ new Set(["-p", "-f", "-d", "-P"]);
|
|
5366
|
+
var NAMES_ANOTHER_MACHINE = /^(?:(?:rsync|scp|sftp):\/\/|(?:[^\s/:@]+@)?[^\s/:@]+:)/i;
|
|
5367
|
+
var SHORT_OPTION_CLUSTER2 = /^-[A-Za-z]+$/;
|
|
5368
|
+
var clusterEndsWithAnOptionThatTakesAValue = (text3, withAValue) => {
|
|
5369
|
+
const letters = text3.slice(1);
|
|
5370
|
+
const firstWithAValue = [...letters].findIndex((letter) => withAValue.has(`-${letter}`));
|
|
5371
|
+
return firstWithAValue === letters.length - 1;
|
|
5372
|
+
};
|
|
5373
|
+
var optionTakesTheNextWord = (text3, withAValue) => withAValue.has(text3) || SHORT_OPTION_CLUSTER2.test(text3) && clusterEndsWithAnOptionThatTakesAValue(text3, withAValue);
|
|
5374
|
+
var operandsAfterOptions = (args, withAValue) => {
|
|
5375
|
+
const operands = [];
|
|
5376
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
5377
|
+
const text3 = args[index]?.text ?? "";
|
|
5378
|
+
if (text3 === END_OF_OPTIONS3) return [...operands, ...args.slice(index + 1)];
|
|
5379
|
+
if (!FLAG.test(text3)) operands.push(args[index]);
|
|
5380
|
+
else if (optionTakesTheNextWord(text3, withAValue)) index += 1;
|
|
5381
|
+
}
|
|
5382
|
+
return operands;
|
|
5383
|
+
};
|
|
5384
|
+
var optionWordsOf = (args, withAValue) => {
|
|
5385
|
+
const options = [];
|
|
5386
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
5387
|
+
const text3 = args[index]?.text ?? "";
|
|
5388
|
+
if (text3 === END_OF_OPTIONS3) break;
|
|
5389
|
+
if (!FLAG.test(text3)) continue;
|
|
5390
|
+
options.push(text3);
|
|
5391
|
+
if (optionTakesTheNextWord(text3, withAValue)) index += 1;
|
|
5392
|
+
}
|
|
5393
|
+
return options;
|
|
5394
|
+
};
|
|
5395
|
+
var withoutSshpass = (invocation) => {
|
|
5396
|
+
if (invocation.program === void 0 || basenameOf(invocation.program.text) !== SSHPASS) return invocation;
|
|
5397
|
+
const [program, ...args] = operandsAfterOptions(invocation.args, SSHPASS_OPTIONS_WITH_A_VALUE);
|
|
5398
|
+
const start = program === void 0 ? -1 : invocation.args.indexOf(program);
|
|
5399
|
+
return { program, args: start === -1 ? [] : invocation.args.slice(start + 1) };
|
|
5400
|
+
};
|
|
5401
|
+
var RSYNC = "rsync";
|
|
5402
|
+
var RSYNC_DRY_RUN = "--dry-run";
|
|
5403
|
+
var RSYNC_DRY_RUN_LETTER = "n";
|
|
5404
|
+
var RSYNC_REMOTE_SHELL_LETTER = "e";
|
|
5405
|
+
var RSYNC_NAMES_A_PROGRAM = /^--(?:rsh|rsync-path)(?:=|$)/;
|
|
5406
|
+
var clusterTurnsOn = (text3, letter, withAValue) => {
|
|
5407
|
+
if (!SHORT_OPTION_CLUSTER2.test(text3)) return false;
|
|
5408
|
+
for (const each of text3.slice(1)) {
|
|
5409
|
+
if (each === letter) return true;
|
|
5410
|
+
if (withAValue.has(`-${each}`)) return false;
|
|
5411
|
+
}
|
|
5412
|
+
return false;
|
|
5413
|
+
};
|
|
5414
|
+
var rsyncOnlyPreviews = (args, withAValue) => {
|
|
5415
|
+
const options = optionWordsOf(args, withAValue);
|
|
5416
|
+
return options.some((text3) => text3 === RSYNC_DRY_RUN || clusterTurnsOn(text3, RSYNC_DRY_RUN_LETTER, withAValue)) && !options.some((text3) => RSYNC_NAMES_A_PROGRAM.test(text3) || clusterTurnsOn(text3, RSYNC_REMOTE_SHELL_LETTER, withAValue));
|
|
5417
|
+
};
|
|
5418
|
+
var copiesOntoAnotherMachine = (invocation) => {
|
|
5419
|
+
const { program, args } = withoutSshpass(invocation);
|
|
5420
|
+
const name = program === void 0 ? void 0 : basenameOf(program.text);
|
|
5421
|
+
const withAValue = name === void 0 ? void 0 : REMOTE_COPY_OPTIONS_WITH_A_VALUE.get(name);
|
|
5422
|
+
if (withAValue === void 0 || name === RSYNC && rsyncOnlyPreviews(args, withAValue)) return false;
|
|
5423
|
+
const operands = operandsAfterOptions(args, withAValue);
|
|
5424
|
+
const destination = operands.at(-1);
|
|
5425
|
+
return operands.length > 1 && destination !== void 0 && NAMES_ANOTHER_MACHINE.test(destination.text);
|
|
5426
|
+
};
|
|
5427
|
+
var HOSTED_SECRET_WRITES = /* @__PURE__ */ new Map([
|
|
5428
|
+
["doppler", /(?:^| )secrets (?:set|delete|upload)(?: |$)/],
|
|
5429
|
+
["vercel", /(?:^| )env (?:add|rm|remove|update)(?: |$)/],
|
|
5430
|
+
["fly", /(?:^| )secrets (?:set|unset|import|deploy)(?: |$)/],
|
|
5431
|
+
["flyctl", /(?:^| )secrets (?:set|unset|import|deploy)(?: |$)/],
|
|
5432
|
+
["heroku", /(?:^| )config:(?:set|unset|add|remove)(?: |$)/],
|
|
5433
|
+
["netlify", /(?:^| )env:(?:set|unset|import|clone)(?: |$)/],
|
|
5434
|
+
["railway", /(?:^| )variables? (?:set|delete)(?: |$)/],
|
|
5435
|
+
["supabase", /(?:^| )secrets (?:set|unset)(?: |$)/],
|
|
5436
|
+
["wrangler", /(?:^| )secret (?:put|delete|bulk)(?: |$)/],
|
|
5437
|
+
["firebase", /(?:^| )functions:secrets:(?:set|destroy|prune)(?: |$)/],
|
|
5438
|
+
["gcloud", /(?:^| )secrets (?:create|delete|update|versions (?:add|destroy|disable|enable))(?: |$)/],
|
|
5439
|
+
["az", /(?:^| )keyvault secret (?:set|set-attributes|delete|purge|recover|restore)(?: |$)/]
|
|
5440
|
+
]);
|
|
5441
|
+
var RAILWAY_CLI = "railway";
|
|
5442
|
+
var RAILWAY_VARIABLES = /(?:^| )variables?(?: |$)/;
|
|
5443
|
+
var RAILWAY_SET_FLAG = /^(?:--set(?:=|$)|-s$)/;
|
|
5444
|
+
var PACKAGE_RUNNERS = /* @__PURE__ */ new Set(["npx", "bunx", "pnpx", "pnpm", "yarn", "npm", "bun"]);
|
|
5445
|
+
var CLI_OF_A_PACKAGE = /* @__PURE__ */ new Map([
|
|
5446
|
+
["netlify-cli", "netlify"],
|
|
5447
|
+
["firebase-tools", "firebase"],
|
|
5448
|
+
["@railway/cli", "railway"],
|
|
5449
|
+
["@doppler/cli", "doppler"]
|
|
5450
|
+
]);
|
|
5451
|
+
var PACKAGE_VERSION = /(?<=.)@[^/@]*$/;
|
|
5452
|
+
var cliNameOf = (program) => {
|
|
5453
|
+
const unversioned = program.text.replace(PACKAGE_VERSION, "");
|
|
5454
|
+
return CLI_OF_A_PACKAGE.get(unversioned) ?? basenameOf(unversioned);
|
|
5455
|
+
};
|
|
5456
|
+
var namesAHostingCli = (word) => {
|
|
5457
|
+
const name = cliNameOf(word);
|
|
5458
|
+
return HOSTED_SECRET_WRITES.has(name) || name === RAILWAY_CLI;
|
|
5459
|
+
};
|
|
5460
|
+
var withoutAPackageRunner = (invocation) => {
|
|
5461
|
+
const { program, args } = invocation;
|
|
5462
|
+
if (program === void 0 || !PACKAGE_RUNNERS.has(basenameOf(program.text))) return invocation;
|
|
5463
|
+
const start = args.findIndex((arg) => !FLAG.test(arg.text) && namesAHostingCli(arg));
|
|
5464
|
+
return start === -1 ? invocation : { program: args[start], args: args.slice(start + 1) };
|
|
5465
|
+
};
|
|
5466
|
+
var writesAHostedSecret = (invocation) => {
|
|
5467
|
+
const { program, args } = withoutAPackageRunner(invocation);
|
|
5468
|
+
if (program === void 0) return false;
|
|
5469
|
+
const name = cliNameOf(program);
|
|
5470
|
+
const words = args.filter((arg) => !FLAG.test(arg.text)).map((arg) => arg.text.toLowerCase()).join(" ");
|
|
5471
|
+
return (HOSTED_SECRET_WRITES.get(name)?.test(words) ?? false) || name === RAILWAY_CLI && RAILWAY_VARIABLES.test(words) && args.some((arg) => RAILWAY_SET_FLAG.test(arg.text));
|
|
5172
5472
|
};
|
|
5173
|
-
var changesSomethingHostedElsewhere = (invocation) => githubCommandHasAConsequence(invocation) || writesThroughAServiceApi(invocation) || sendsDataOffThisMachine(invocation) || kubectlExecRunsMoreThanAReadOnlyCommand(invocation) || sshRunsMoreThanAReadOnlyCommand(invocation);
|
|
5473
|
+
var changesSomethingHostedElsewhere = (invocation) => githubCommandHasAConsequence(invocation) || writesThroughAServiceApi(invocation) || writesAHostedSecret(invocation) || sendsDataOffThisMachine(invocation) || copiesOntoAnotherMachine(invocation) || kubectlExecRunsMoreThanAReadOnlyCommand(invocation) || sshRunsMoreThanAReadOnlyCommand(invocation);
|
|
5174
5474
|
var segmentWritesThroughARemoteApi = (segment, depth) => {
|
|
5175
5475
|
const innermost = innermostInvocation(segment.invocation);
|
|
5176
5476
|
return invocationWritesThroughARemoteApi(innermost) || commandsNestedIn(innermost, inlineScriptsOf(innermost, segment.heredocs)).some((nested) => commandWritesThroughARemoteApiAt(nested, depth + 1));
|
|
@@ -5188,7 +5488,6 @@ var commandNeedsAPerson = (toolName, command) => {
|
|
|
5188
5488
|
const segments = readableCommandSegments(command);
|
|
5189
5489
|
return segments === null || classifyDecisionRisk(readingTool, command) !== "standard" || segments.some((segment) => segmentNeedsAPerson(readingTool, segment)) || pipesIntoASqlClient(command) || shellDialectOf(toolName) === "powershell" && powerShellCommandHasAVisibleConsequence(command, posixShellJudgeFor(toolName));
|
|
5190
5490
|
};
|
|
5191
|
-
var sessionGrantMustAskAbout = (toolName, command) => commandNeedsAPerson(toolName, command) || SHELL_DIALECT_BY_TOOL.has(toolName) && commandHasAVisibleConsequence(toolName, command);
|
|
5192
5491
|
var VISIBLE_DATA_LOSS_PATTERNS = [
|
|
5193
5492
|
"Bash(git branch -D:*)",
|
|
5194
5493
|
"Bash(git branch --delete:*)",
|
|
@@ -5300,12 +5599,12 @@ var FIND_RUNNERS = /* @__PURE__ */ new Set(["-exec", "-execdir", "-ok", "-okdir"
|
|
|
5300
5599
|
var FIND_RUNNER_END = /* @__PURE__ */ new Set([";", "+"]);
|
|
5301
5600
|
var FIND = "find";
|
|
5302
5601
|
var commandsRunByFind = ({ program, args }) => program === void 0 || basenameOf(program.text) !== FIND ? [] : args.flatMap((arg, index) => FIND_RUNNERS.has(arg.text) ? [{ program: args[index + 1], args: args.slice(index + 2, findRunnerEnd(args, index + 2)) }] : []);
|
|
5303
|
-
var losesDataVisibly = (toolName, invocation, normalized, depth) => {
|
|
5602
|
+
var losesDataVisibly = (toolName, invocation, normalized, depth, line) => {
|
|
5304
5603
|
const { program, args } = invocation;
|
|
5305
5604
|
if (program === void 0) return false;
|
|
5306
5605
|
const name = basenameOf(program.text);
|
|
5307
5606
|
if (name === FIND) {
|
|
5308
|
-
return args.some((arg) => arg.text === FIND_DELETE) || commandsRunByFind(invocation).some((run) => invocationHasAVisibleConsequence(toolName, run, depth + 1));
|
|
5607
|
+
return args.some((arg) => arg.text === FIND_DELETE) || commandsRunByFind(invocation).some((run) => invocationHasAVisibleConsequence(toolName, run, depth + 1, line));
|
|
5309
5608
|
}
|
|
5310
5609
|
const destructiveArguments = destructiveArgumentsOf(name, args);
|
|
5311
5610
|
return destructiveArguments !== void 0 && args.some((arg) => namesDestructiveArgument(arg.text, destructiveArguments)) || namesDestructiveWordInAnyCase(name, args.map((arg) => arg.text)) || gitDiscardsWork(invocation) || changesAService(invocation) || replacesTheCrontab(invocation) || isCoveredByPolicy(VISIBLE_DATA_LOSS_PATTERNS, toolName, normalized);
|
|
@@ -5471,13 +5770,14 @@ var honoursPreviewFlags = ({ program, args }) => {
|
|
|
5471
5770
|
var onlyPreviews = (invocation) => invocation.program !== void 0 && honoursPreviewFlags(invocation) && invocation.args.some((arg) => !arg.expands && PREVIEW_FLAG.test(arg.text));
|
|
5472
5771
|
var changesWhatIsDeployed = (toolName, invocation, normalized) => !onlyPreviews(invocation) && (changesProduction(invocation) || mergesAPullRequest(invocation) || isCoveredByPolicy(DEPLOY_AND_SCHEMA_COMMAND_PATTERNS, toolName, normalized));
|
|
5473
5772
|
var releasesOrChangesACluster = (toolName, invocation, normalized) => !onlyPreviews(invocation) && (pushesATag(invocation) || publishesAnAppBuild(invocation) || RELEASE_AND_CLUSTER_PROGRAMS.has(basenameOf(invocation.program?.text ?? "")) && isCoveredByPolicy(RELEASE_AND_CLUSTER_COMMAND_PATTERNS, toolName, normalized));
|
|
5474
|
-
var
|
|
5773
|
+
var invocationHasAConsequenceOnlyPermissionsOffAsksAbout = (toolName, invocation, normalized) => releasesOrChangesACluster(toolName, invocation, normalized) || mergesAPullRequestByAnyPath(invocation) || writesAFileThatNeedsAPerson(invocation) || changesWhereGitLooksForHooks(invocation) || setsAGitSettingThatRunsAProgram(invocation) || changesSomethingHostedElsewhere(invocation);
|
|
5774
|
+
var invocationHasAVisibleConsequence = (toolName, invocation, depth, line) => {
|
|
5475
5775
|
if (depth > MAX_CONSEQUENCE_DEPTH) return true;
|
|
5476
5776
|
if (invocation.program === void 0) return false;
|
|
5477
5777
|
const normalized = quotedInvocation(invocation);
|
|
5478
5778
|
const innermost = innermostInvocation(invocation);
|
|
5479
5779
|
const script = shellScriptOf(invocation);
|
|
5480
|
-
return classifyDecisionRisk(toolName, normalized) === "destructive" || changesWhatIsDeployed(toolName, invocation, normalized) ||
|
|
5780
|
+
return classifyDecisionRisk(toolName, normalized) === "destructive" || changesWhatIsDeployed(toolName, invocation, normalized) || writesASecretFile(invocation) || line === "permissions_off" && invocationHasAConsequenceOnlyPermissionsOffAsksAbout(toolName, invocation, normalized) || losesDataVisibly(toolName, invocation, normalized, depth, line) || subcommandDestroysVisibly(invocation) || sqlClientChangesData(invocation) || innermost !== invocation && invocationHasAVisibleConsequence(toolName, innermost, depth, line) || script === null && passesAnInlineScript(invocation) || script !== null && commandHasAVisibleConsequenceAt(toolName, script, depth + 1, line) || readingsPastGlobalFlags(invocation).some((reading) => invocationHasAVisibleConsequence(toolName, reading, depth + 1, line));
|
|
5481
5781
|
};
|
|
5482
5782
|
var RUNS_FETCHED_CODE = /(?:\$\(|`|<\()\s*(?:curl|wget)\b/;
|
|
5483
5783
|
var RUNS_DECODED_CODE = /(?:^|[;&|(\s])(?:bash|sh|zsh|source|\.|python3?|node|ruby|perl)\s+(?:-[A-Za-z]+\s+)*["']?(?:<\(|\$\()[^)]*\b(?:base64|xxd|openssl)\b/;
|
|
@@ -5511,7 +5811,7 @@ var decodes = (invocation) => {
|
|
|
5511
5811
|
return decodingFlags !== void 0 && args.some((arg) => decodingFlags.test(arg.text));
|
|
5512
5812
|
};
|
|
5513
5813
|
var producesCodeTheCommandDoesNotShow = (invocation) => fetches(invocation) || decodes(invocation);
|
|
5514
|
-
var
|
|
5814
|
+
var pipesCodeIntoAnInterpreter = (command, invocations, producesCode) => invocations.some(producesCode) && pipedSegmentsOf(command).some(runsWhatItReads);
|
|
5515
5815
|
var CODE_THAT_DELETES_RECURSIVELY = /\b(?:rmtree|rimraf|rm_rf|rm_r|removedirs)\b|\b(?:rm|rmSync|remove|rmdir|rmdirSync)\s*\([^)]*recursive/;
|
|
5516
5816
|
var CODE_THAT_DECODES = /\b(?:b64decode|atob|base64)\b/;
|
|
5517
5817
|
var CODE_THAT_RUNS_CODE_IT_BUILDS = /(?<![.\w])(?:eval|exec)\s*\(/;
|
|
@@ -5571,7 +5871,7 @@ var interpreterCodeIn = (command, invocations) => {
|
|
|
5571
5871
|
const heredocs = interpreters.some(runsWhatItReads) ? withHeredocBodiesSetAside(command).bodies : [];
|
|
5572
5872
|
return [...interpreters.flatMap(inlineCodeOf), ...heredocs];
|
|
5573
5873
|
};
|
|
5574
|
-
var codeNeedsAPerson = (code, depth) => CODE_THAT_DELETES_RECURSIVELY.test(code) || CODE_THAT_RUNS_CODE_IT_BUILDS.test(code) && CODE_THAT_DECODES.test(code) || CODE_THAT_WRITES_A_FILE.test(code) && pathsSpelledIn(code).some(pathNeedsAPersonToChange) || CODE_THAT_RUNS_COMMANDS.test(code) && commandsSpelledIn(code).some((command) => commandHasAVisibleConsequenceAt(SHELL_TOOL, command, depth + 1));
|
|
5874
|
+
var codeNeedsAPerson = (code, depth) => CODE_THAT_DELETES_RECURSIVELY.test(code) || CODE_THAT_RUNS_CODE_IT_BUILDS.test(code) && CODE_THAT_DECODES.test(code) || CODE_THAT_WRITES_A_FILE.test(code) && pathsSpelledIn(code).some(pathNeedsAPersonToChange) || CODE_THAT_RUNS_COMMANDS.test(code) && commandsSpelledIn(code).some((command) => commandHasAVisibleConsequenceAt(SHELL_TOOL, command, depth + 1, "permissions_off"));
|
|
5575
5875
|
var runsInterpreterCodeThatNeedsAPerson = (command, invocations, depth) => interpreterCodeIn(command, invocations).some((code) => codeNeedsAPerson(code, depth));
|
|
5576
5876
|
var WORDS_THAT_OPEN_A_COMMAND = String.raw`if|then|elif|else|do|while|until|!`;
|
|
5577
5877
|
var SHELL_GROUPING_PREFIX = new RegExp(String.raw`^\s*(?:(?:${WORDS_THAT_OPEN_A_COMMAND})\s+|[({]\s*)+`);
|
|
@@ -5717,26 +6017,29 @@ var evalRunsOneEnvironmentSetup = (pieces, index) => {
|
|
|
5717
6017
|
const next = pieces[index + 3];
|
|
5718
6018
|
return opening !== void 0 && EVAL_BEFORE_ITS_ARGUMENT.test(opening.text) && substitution !== void 0 && SUBSTITUTION_OPENERS.has(substitution.before) && SETS_UP_THE_ENVIRONMENT.test(substitution.text) && closing !== void 0 && SUBSTITUTION_CLOSERS.has(closing.before) && EVAL_AFTER_ITS_ARGUMENT.test(closing.text) && (next === void 0 || WHAT_MAY_FOLLOW_AN_EVAL.has(next.before));
|
|
5719
6019
|
};
|
|
5720
|
-
var
|
|
6020
|
+
var evalRunsHiddenCode = (segment, innermost) => segment.substitution !== null && basenameOf(innermost.program?.text ?? "") === EVAL && !segment.evalRunsOneEnvironmentSetup;
|
|
6021
|
+
var roughSegmentHasAVisibleConsequence = (toolName, segment, producesHiddenCode, depth, line) => {
|
|
5721
6022
|
const innermost = innermostInvocation(segment.invocation);
|
|
5722
6023
|
const runsAHeredocScript = innermost.program !== void 0 && POSIX_SHELL_PROGRAMS.has(basenameOf(innermost.program.text));
|
|
5723
|
-
return invocationHasAVisibleConsequence(toolName, segment.invocation, depth) || sqlClientSyntaxOf(innermost) !== void 0 && (segment.readsInput || segment.feedsASubstitution) ||
|
|
6024
|
+
return invocationHasAVisibleConsequence(toolName, segment.invocation, depth, line) || sqlClientSyntaxOf(innermost) !== void 0 && (segment.readsInput || segment.feedsASubstitution) || line === "permissions_off" && evalRunsHiddenCode(segment, innermost) || segment.readsAPipe && producesHiddenCode && runsWhatItReads(innermost) || runsAHeredocScript && segment.heredocs.some((body) => commandHasAVisibleConsequenceAt(toolName, body, depth + 1, line));
|
|
5724
6025
|
};
|
|
5725
|
-
var
|
|
6026
|
+
var producesCodeTheLineCannotSee = (line) => line === "permissions_off" ? producesCodeTheCommandDoesNotShow : fetches;
|
|
6027
|
+
var roughReadingHasAVisibleConsequence = (toolName, command, depth, line) => {
|
|
5726
6028
|
const segments = roughSegmentsOf(command);
|
|
5727
6029
|
const invocations = segments.map((segment) => segment.invocation);
|
|
5728
|
-
const producesHiddenCode = invocations.some(
|
|
5729
|
-
return segments.some((segment) => roughSegmentHasAVisibleConsequence(toolName, segment, producesHiddenCode, depth)) || runsADownloadedScript(invocations) || runsInterpreterCodeThatNeedsAPerson(command, invocations, depth);
|
|
6030
|
+
const producesHiddenCode = invocations.some(producesCodeTheLineCannotSee(line));
|
|
6031
|
+
return segments.some((segment) => roughSegmentHasAVisibleConsequence(toolName, segment, producesHiddenCode, depth, line)) || runsADownloadedScript(invocations) || line === "permissions_off" && runsInterpreterCodeThatNeedsAPerson(command, invocations, depth);
|
|
5730
6032
|
};
|
|
5731
|
-
var
|
|
6033
|
+
var commandHidesWhatItWritesOrRuns = (command, readable) => RUNS_DECODED_CODE.test(readable) || redirectsIntoAFileThatNeedsAPerson(command);
|
|
6034
|
+
var commandHasAVisibleConsequenceAt = (toolName, command, depth, line) => {
|
|
5732
6035
|
if (toolName === "Bash" && isSafeReadOnlyCommand(command)) return false;
|
|
5733
6036
|
const readable = withHeredocSubstitutionsAsQuotedText(command);
|
|
5734
6037
|
if (classifyDecisionRisk(toolName, readable) === "destructive" || RUNS_FETCHED_CODE.test(readable) || REDIRECTS_INTO_A_SECRET_FILE.test(readable)) return true;
|
|
5735
|
-
if (
|
|
6038
|
+
if (line === "permissions_off" && commandHidesWhatItWritesOrRuns(command, readable)) return true;
|
|
5736
6039
|
const segments = readableCommandSegments(command);
|
|
5737
|
-
if (segments === null) return roughReadingHasAVisibleConsequence(toolName, command, depth);
|
|
6040
|
+
if (segments === null) return roughReadingHasAVisibleConsequence(toolName, command, depth, line);
|
|
5738
6041
|
const invocations = segments.map((segment) => invocationOf(withoutShellGrouping(segment)));
|
|
5739
|
-
return invocations.some((invocation) => invocationHasAVisibleConsequence(toolName, invocation, depth)) || pipesIntoASqlClient(command) ||
|
|
6042
|
+
return invocations.some((invocation) => invocationHasAVisibleConsequence(toolName, invocation, depth, line)) || pipesIntoASqlClient(command) || pipesCodeIntoAnInterpreter(command, invocations, producesCodeTheLineCannotSee(line)) || runsADownloadedScript(invocations) || line === "permissions_off" && runsInterpreterCodeThatNeedsAPerson(command, invocations, depth);
|
|
5740
6043
|
};
|
|
5741
6044
|
var REDIRECTION_OPERATOR_CHARACTER = /[<>]/;
|
|
5742
6045
|
var redirectsIntoAFileThatNeedsAPerson = (command) => {
|
|
@@ -5749,18 +6052,24 @@ var redirectsIntoAFileThatNeedsAPerson = (command) => {
|
|
|
5749
6052
|
});
|
|
5750
6053
|
};
|
|
5751
6054
|
var posixCommandOf = (words) => words.map(asOneShellWord).join(" ");
|
|
5752
|
-
var
|
|
6055
|
+
var webRequestSendsDataOffThisMachine = ({ sendsData, addresses }) => sendsData && !(addresses.length > 0 && addresses.every((address) => THIS_MACHINE_ADDRESS.test(address)));
|
|
6056
|
+
var noWebRequestNeedsAPerson = () => false;
|
|
6057
|
+
var namesASecretPowerShellPath = (path) => SECRET_FILE_NAME.test(fileNameOf(path));
|
|
6058
|
+
var posixShellJudgeFor = (toolName, line = "standing_allow") => ({
|
|
5753
6059
|
namesADestructiveAction: (text3) => classifyDecisionRisk(toolName, text3) === "destructive",
|
|
5754
|
-
invocationShowsAConsequence: (invocation) => invocationHasAVisibleConsequence(SHELL_TOOL, invocation, 0),
|
|
5755
|
-
commandShowsAConsequence: (words) => commandHasAVisibleConsequenceAt(SHELL_TOOL, posixCommandOf(words), 1),
|
|
6060
|
+
invocationShowsAConsequence: (invocation) => invocationHasAVisibleConsequence(SHELL_TOOL, invocation, 0, line),
|
|
6061
|
+
commandShowsAConsequence: (words) => commandHasAVisibleConsequenceAt(SHELL_TOOL, posixCommandOf(words), 1, line),
|
|
5756
6062
|
onlyReads: (words) => isSafeReadOnlyCommand(posixCommandOf(words)),
|
|
5757
6063
|
fetches,
|
|
5758
6064
|
runsWhatItReads,
|
|
5759
6065
|
runsScripts,
|
|
5760
|
-
namesAFileThatNeedsAPerson: pathNeedsAPersonToChange
|
|
6066
|
+
namesAFileThatNeedsAPerson: line === "permissions_off" ? pathNeedsAPersonToChange : namesASecretPowerShellPath,
|
|
6067
|
+
webRequestNeedsAPerson: line === "permissions_off" ? webRequestSendsDataOffThisMachine : noWebRequestNeedsAPerson
|
|
5761
6068
|
});
|
|
5762
6069
|
var commandIsDestructive = (toolName, command) => shellDialectOf(toolName) === "powershell" ? powerShellCommandIsDestructive(command, posixShellJudgeFor(toolName)) : readingsThatCanAct(command).some((reading) => classifyDecisionRisk(toolNameForAPosixReading(toolName), reading) === "destructive");
|
|
5763
|
-
var
|
|
6070
|
+
var commandHasAConsequenceOnTheLine = (toolName, command, line) => shellDialectOf(toolName) === "powershell" ? powerShellCommandHasAVisibleConsequence(command, posixShellJudgeFor(toolName, line)) : commandHasAVisibleConsequenceAt(toolNameForAPosixReading(toolName), command, 0, line);
|
|
6071
|
+
var commandHasAVisibleConsequence = (toolName, command) => commandHasAConsequenceOnTheLine(toolName, command, "standing_allow");
|
|
6072
|
+
var commandHasAConsequenceWithPermissionsOff = (toolName, command) => commandHasAConsequenceOnTheLine(toolName, command, "permissions_off");
|
|
5764
6073
|
var MAX_SPELLING_DEPTH = 3;
|
|
5765
6074
|
var GIT_GLOBAL_OPTIONS_WITH_A_VALUE = /* @__PURE__ */ new Set([
|
|
5766
6075
|
"-C",
|
|
@@ -6961,7 +7270,7 @@ var unmatchedPolicyOf = (config, toolName) => ({
|
|
|
6961
7270
|
mode: config.defaultMode ?? "push_first",
|
|
6962
7271
|
pushFirstSeconds: config.defaultPushFirstSeconds ?? 20
|
|
6963
7272
|
});
|
|
6964
|
-
var sessionToolGrantCannotCover = (toolName, arg, toolInput) => typeof arg === "string" &&
|
|
7273
|
+
var sessionToolGrantCannotCover = (toolName, arg, toolInput) => typeof arg === "string" && commandNeedsAPerson(toolName, arg) || parseMcpToolName(toolName) !== void 0 && (toolInput === void 0 || !mcpToolInputOnlyReads(toolName, toolInput));
|
|
6965
7274
|
var stricterOfTheReadings = (asWritten, asSpelled, unmatched) => comparePolicyStrictness(asWritten?.policy ?? unmatched, asSpelled?.policy ?? unmatched) > 0 ? asWritten : asSpelled;
|
|
6966
7275
|
var resolvePolicy = (config, toolName, modeOverride, toolInput, cwd, repoKey, sessionId) => {
|
|
6967
7276
|
const args = toolInput ? policyArgForms(toolName, toolInput, cwd) : [];
|
|
@@ -7038,6 +7347,10 @@ var strictestScopeVerdict = (scope, paths) => {
|
|
|
7038
7347
|
var survivesDegraded = (config, toolName, toolInputs, cwd, repoKey, sessionId) => toolInputs.length === 1 && resolveAutoResolveOrigin(config, toolName, toolInputs[0], cwd, repoKey, sessionId) === "safe_readonly";
|
|
7039
7348
|
var FULL_DEFER_MODES = /* @__PURE__ */ new Set(["plan", "auto", "dontAsk"]);
|
|
7040
7349
|
var BYPASS_PERMISSION_MODE = "bypassPermissions";
|
|
7350
|
+
var BYPASS_STOPS = ["consequences", "nothing"];
|
|
7351
|
+
var DEFAULT_BYPASS_STOPS = "consequences";
|
|
7352
|
+
var isBypassStops = (value) => typeof value === "string" && BYPASS_STOPS.includes(value);
|
|
7353
|
+
var bypassStopsOf = (config) => isBypassStops(config.bypassStops) ? config.bypassStops : DEFAULT_BYPASS_STOPS;
|
|
7041
7354
|
var isBypassPermissionMode = (permissionMode) => permissionMode === BYPASS_PERMISSION_MODE;
|
|
7042
7355
|
var FILE_EDIT_TOOLS = /* @__PURE__ */ new Set([
|
|
7043
7356
|
"Write",
|
|
@@ -7134,13 +7447,19 @@ var LINE_BREAK = /[\r\n]/;
|
|
|
7134
7447
|
var bypassModeCovers = (toolName, toolInput) => {
|
|
7135
7448
|
const arg = extractPolicyArg(toolName, toolInput);
|
|
7136
7449
|
if (SHELL_DIALECT_BY_TOOL.has(toolName)) {
|
|
7137
|
-
return arg !== void 0 && !commandIsDestructive(toolName, arg) && !
|
|
7450
|
+
return arg !== void 0 && !commandIsDestructive(toolName, arg) && !commandHasAConsequenceWithPermissionsOff(toolName, arg);
|
|
7138
7451
|
}
|
|
7139
|
-
if (FILE_EDIT_TOOLS.has(toolName)) return arg !== void 0 && !LINE_BREAK.test(arg) && !
|
|
7452
|
+
if (FILE_EDIT_TOOLS.has(toolName)) return arg !== void 0 && !LINE_BREAK.test(arg) && !fileEditNeedsAPersonWithPermissionsOff(toolName, arg);
|
|
7140
7453
|
return mcpToolOnlyReads(toolName) && mcpToolInputOnlyReads(toolName, toolInput);
|
|
7141
7454
|
};
|
|
7142
|
-
var aChosenRuleGovernsInEitherRepository = (input) => aChosenRuleGoverns(input) || input.sharedRepoKey !== void 0 && input.sharedRepoKey !== input.repoKey && aChosenRuleGoverns({ ...input, repoKey: input.sharedRepoKey });
|
|
7143
|
-
var
|
|
7455
|
+
var aChosenRuleGovernsInEitherRepository = (input, counts = everyRule) => aChosenRuleGoverns(input, counts) || input.sharedRepoKey !== void 0 && input.sharedRepoKey !== input.repoKey && aChosenRuleGoverns({ ...input, repoKey: input.sharedRepoKey }, counts);
|
|
7456
|
+
var ruleAsksOrRefuses = (rule) => !isAutoApprove(rule);
|
|
7457
|
+
var bypassModeCoversEveryInput = (input) => input.deletesFiles !== true && input.toolInputs.every((toolInput) => bypassModeCovers(input.toolName, toolInput)) && !aChosenRuleGovernsInEitherRepository(input);
|
|
7458
|
+
var bypassModeApplies = (input) => isBypassPermissionMode(input.permissionMode) && !isModeStateDegraded(input.modeState) && noModeOverrideIsActive(input) && input.toolInputs.length > 0;
|
|
7459
|
+
var bypassModeAllows = (input) => bypassModeApplies(input) && (bypassStopsOf(input.config) === "nothing" ? !aChosenRuleGovernsInEitherRepository(input, ruleAsksOrRefuses) : bypassModeCoversEveryInput(input));
|
|
7460
|
+
var PERMISSIONS_OFF_ASK_REASON = "Permissions are off in your agent, so Pushary only stops for risky steps like this one. You can change this in Settings on pushary.com.";
|
|
7461
|
+
var permissionsOffLineAppliesTo = (agentType) => agentType === CLAUDE_CODE_AGENT_TYPE;
|
|
7462
|
+
var permissionsOffAskReason = (input, verdict) => verdict.kind === "gate" && !verdict.scopeReason && !isAskedInEveryMode(input.toolName) && bypassModeApplies(input) && bypassStopsOf(input.config) === "consequences" && !aChosenRuleGovernsInEitherRepository(input) ? PERMISSIONS_OFF_ASK_REASON : void 0;
|
|
7144
7463
|
var resolveGate = (input) => {
|
|
7145
7464
|
const { modeState, config, toolName, toolInputs, cwd, sessionId } = input;
|
|
7146
7465
|
const repoKey = input.sharedRepoKey ?? input.repoKey;
|
|
@@ -7225,7 +7544,9 @@ var runsACommandThatNeedsAPerson = ({ toolName, toolInputs }) => SHELL_DIALECT_B
|
|
|
7225
7544
|
const command = extractPolicyArg(toolName, toolInput);
|
|
7226
7545
|
return command !== void 0 && (commandNeedsAPerson(toolName, command) || commandWritesThroughARemoteApi(command));
|
|
7227
7546
|
});
|
|
7228
|
-
var
|
|
7547
|
+
var namesASecretOrWorkflowFile = (path) => SECRET_FILE_NAME.test(basenameOf(path)) || CI_WORKFLOW_FILE.test(normalizeSeparators(path));
|
|
7548
|
+
var fileEditNeedsAPerson = (toolName, path) => FILE_EDIT_TOOLS.has(toolName) && namesASecretOrWorkflowFile(path);
|
|
7549
|
+
var fileEditNeedsAPersonWithPermissionsOff = (toolName, path) => FILE_EDIT_TOOLS.has(toolName) && pathNeedsAPersonToChange(path);
|
|
7229
7550
|
var editsAFileThatNeedsAPerson = ({ toolName, toolInputs }) => toolInputs.some((toolInput) => {
|
|
7230
7551
|
const path = extractPolicyArg(toolName, toolInput);
|
|
7231
7552
|
return path !== void 0 && fileEditNeedsAPerson(toolName, path);
|
|
@@ -7294,14 +7615,16 @@ var approvalRoutesOf = (config) => {
|
|
|
7294
7615
|
const routes = config.approvalRoutes ?? [];
|
|
7295
7616
|
return Array.isArray(routes) && routes.every(isApprovalRoutePattern) ? routes : null;
|
|
7296
7617
|
};
|
|
7297
|
-
var
|
|
7618
|
+
var everyRule = () => true;
|
|
7619
|
+
var aChosenRuleGoverns = (input, counts = everyRule) => {
|
|
7298
7620
|
const chosen = input.config.policies.filter((policy) => !isDefaultRule(policy));
|
|
7299
7621
|
const routes = approvalRoutesOf(input.config);
|
|
7300
7622
|
if (routes === null) return true;
|
|
7301
7623
|
return input.toolInputs.some((toolInput) => {
|
|
7302
7624
|
const args = policyArgForms(input.toolName, toolInput, input.cwd);
|
|
7303
7625
|
const reading = policyReadingOf(chosen, input.toolName, args);
|
|
7304
|
-
|
|
7626
|
+
const governing = governingRuleForReading(chosen, input.toolName, args, reading, input.repoKey, input.sessionId);
|
|
7627
|
+
return governing !== void 0 && counts(governing.policy) || findBestRoute(routes, input.toolName, args, input.repoKey) !== void 0;
|
|
7305
7628
|
});
|
|
7306
7629
|
};
|
|
7307
7630
|
var claudeAllowlistOwnsCall = (input, verdict, permissionMode, rules) => rules !== null && verdict.kind === "gate" && !verdict.scopeReason && !aChosenRuleGoverns(input) && !isAskedInEveryMode(input.toolName) && claudeConsultsItsAllowlist(permissionMode) && agentRulesAllowEveryInput(rules, input.toolName, input.toolInputs, input.cwd);
|
|
@@ -7493,6 +7816,7 @@ var PLAN_DECLINED_REASON = "Plan declined from the phone. Ask what to change bef
|
|
|
7493
7816
|
var claudeStoppedPreToolUseOutput = (reason) => stoppedOutput(claudePreToolUseOutput("deny", reason), reason);
|
|
7494
7817
|
var claudeStoppedPermissionRequestOutput = (reason) => stoppedOutput(claudePermissionRequestOutput("deny", reason), reason);
|
|
7495
7818
|
var UNANSWERED_ASKS_BEFORE_PAUSE = 3;
|
|
7819
|
+
var CLAUDE_CODE_AGENT_TYPE = "claude_code";
|
|
7496
7820
|
var SESSION_PAUSED_REASON = `Phone approvals for this session are paused because ${UNANSWERED_ASKS_BEFORE_PAUSE} of them went unanswered, so this was refused without asking anyone. A notification was sent to your phone: tap Approve on it to resume, then run this again.`;
|
|
7497
7821
|
var unansweredRefusalReason = (paused) => paused ? SESSION_PAUSED_REASON : NO_RESPONSE_REASON;
|
|
7498
7822
|
var UNHEARD_PUSH_WINDOW_DAYS = 14;
|
|
@@ -7840,6 +8164,8 @@ export {
|
|
|
7840
8164
|
PRETOOLUSE_HANDLED_TOOLS,
|
|
7841
8165
|
isPermissionRequestOwnedByPreToolUse,
|
|
7842
8166
|
CLAUDE_PRETOOLUSE_MATCHER,
|
|
8167
|
+
permissionsOffLineAppliesTo,
|
|
8168
|
+
permissionsOffAskReason,
|
|
7843
8169
|
resolveGate,
|
|
7844
8170
|
editGoesToTheAgentsPrompt,
|
|
7845
8171
|
SCOPE_BATCH_REASON,
|