pushary 1.9.93 → 1.9.96
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 +15 -0
- package/dist/{api-QUARGXSY.js → api-FPEL3PLH.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 +34 -32
- 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-WW4OMRZX.js → chunk-2DF4TBGX.js} +1 -1
- package/dist/{chunk-JZ2MRWC4.js → chunk-2QFD5XGU.js} +3 -3
- package/dist/{chunk-ONRA5ON4.js → chunk-3GPXHHBM.js} +1 -1
- package/dist/{chunk-7DOSRSRU.js → chunk-3QS2RCCZ.js} +6 -6
- package/dist/{chunk-NHGOCUX7.js → chunk-3QT3DMNX.js} +1 -1
- package/dist/{chunk-5TQC2LS6.js → chunk-3X3ALGMP.js} +4 -4
- package/dist/{chunk-ATWH6TGY.js → chunk-4BLNOWGZ.js} +23 -19
- package/dist/{chunk-HUNGCBCF.js → chunk-6JZNZTGZ.js} +3 -3
- package/dist/{chunk-NDPOESVW.js → chunk-6YG5PZZS.js} +1 -1
- package/dist/{chunk-Y7AX6BS4.js → chunk-77HBRZJI.js} +3 -3
- package/dist/{chunk-HALVTC2N.js → chunk-7CW3K3B5.js} +5 -5
- package/dist/{chunk-UGGACQMD.js → chunk-AEOYYLXF.js} +3 -3
- package/dist/{chunk-V3LBQFQM.js → chunk-ARDQBF25.js} +1 -1
- package/dist/{chunk-LTMMFZHG.js → chunk-B4G4Q2AF.js} +1 -1
- package/dist/{chunk-CO6TQ44W.js → chunk-B75SIY5C.js} +3 -3
- package/dist/{chunk-OLMKZINV.js → chunk-BDCFB4NV.js} +6 -6
- package/dist/{chunk-7PQ66CB3.js → chunk-BKN5E4L5.js} +1 -1
- package/dist/{chunk-YLCNW7YN.js → chunk-C4IKRLT4.js} +2 -2
- package/dist/{chunk-3JVV6PMG.js → chunk-CLN5W5QP.js} +5 -5
- package/dist/{chunk-UNPDFIPQ.js → chunk-CQ3YV6QI.js} +2 -2
- package/dist/{chunk-SR44ZNZF.js → chunk-CRJDKGEF.js} +5 -5
- package/dist/{chunk-UZRKR6NZ.js → chunk-CTKJVVDL.js} +3 -3
- package/dist/{chunk-BETKU76V.js → chunk-DN3QW2TT.js} +3 -3
- package/dist/{chunk-FTJ5DQL7.js → chunk-EMVK57K7.js} +2 -2
- package/dist/{chunk-GLA6MCOG.js → chunk-EPFI6W2K.js} +1 -1
- package/dist/{chunk-7VJ7PEI3.js → chunk-GAZPL742.js} +4 -4
- package/dist/{chunk-A2FDS7E3.js → chunk-HOYWYQNC.js} +5 -5
- package/dist/{chunk-X3AHEUQ5.js → chunk-HY7G3PWJ.js} +3 -3
- package/dist/{chunk-7YB2XRY7.js → chunk-IVYKPYMH.js} +3 -3
- package/dist/{chunk-66VEUAN5.js → chunk-J3W32P43.js} +1 -1
- package/dist/{chunk-3CJFBWID.js → chunk-JCYXG6LQ.js} +3 -3
- package/dist/{chunk-373552A3.js → chunk-JU3JYEUG.js} +4 -4
- package/dist/{chunk-RXQT5FTX.js → chunk-KG7GT7UW.js} +1 -1
- package/dist/{chunk-JJWZIPDL.js → chunk-KHGW7THQ.js} +4 -4
- package/dist/{chunk-4HQTZQ4D.js → chunk-LGJPT33C.js} +2 -2
- package/dist/{chunk-MSJXRN22.js → chunk-M52UDSMQ.js} +5 -5
- package/dist/{chunk-CQMY74I2.js → chunk-M7ZV5IPA.js} +7 -7
- package/dist/{chunk-V7TNHTHH.js → chunk-MSPHJNUL.js} +1 -1
- package/dist/{chunk-CSUO5YJG.js → chunk-N2KK2NSY.js} +2 -2
- package/dist/{chunk-SPPMPM7F.js → chunk-NGSJHUQN.js} +1 -1
- package/dist/{chunk-OC47FGOY.js → chunk-OP2WJEPY.js} +1 -1
- package/dist/{chunk-PFHU3CW4.js → chunk-OQY4G7FS.js} +1 -1
- package/dist/{chunk-OMN5UCMW.js → chunk-OS32P4RZ.js} +560 -36
- package/dist/{chunk-2FL5PLA4.js → chunk-PD2DWO4X.js} +2 -2
- package/dist/{chunk-4PD7FP55.js → chunk-PDRPVVZX.js} +2 -2
- package/dist/{chunk-RFP4Q5I3.js → chunk-QDS55ODM.js} +11 -11
- package/dist/{chunk-ANDG4PUV.js → chunk-R2RCFCFW.js} +6 -6
- package/dist/{chunk-VMIWR724.js → chunk-SARU6WNW.js} +1 -1
- package/dist/{chunk-2BXWBKVN.js → chunk-SI2CJ2BB.js} +3 -3
- package/dist/{chunk-5V2YDO4U.js → chunk-SISYAMDC.js} +4 -4
- package/dist/{chunk-XDWJX7LT.js → chunk-T2Z5ITWJ.js} +3 -3
- package/dist/{chunk-DV7LLH25.js → chunk-T7X5MQ3H.js} +1 -1
- package/dist/{chunk-OFQJHWAS.js → chunk-TAMHTWQZ.js} +10 -10
- package/dist/{chunk-NPH4DJAU.js → chunk-TQKVKV76.js} +5 -5
- package/dist/{chunk-7GFWYFLO.js → chunk-TTK2DLUS.js} +10 -10
- package/dist/{chunk-LANGH7UF.js → chunk-TVGOSEWS.js} +4 -4
- package/dist/{chunk-NPZ5L2WQ.js → chunk-TXDFQD2I.js} +1 -1
- package/dist/{chunk-CFD3IESN.js → chunk-TZWK2BVY.js} +6 -6
- package/dist/{chunk-RXAQOAZI.js → chunk-UFWRBHTV.js} +3 -3
- package/dist/{chunk-XTNCXIYR.js → chunk-V7EWOHNV.js} +4 -4
- package/dist/{chunk-YT3ENXBT.js → chunk-VTFXPV4U.js} +2 -2
- package/dist/{chunk-76ROCOWD.js → chunk-VX27HJF6.js} +7 -7
- package/dist/{chunk-H4MIOBC6.js → chunk-WUYB3J3Q.js} +2 -2
- package/dist/{chunk-N7CPX5S5.js → chunk-WVDPP7OQ.js} +5 -5
- package/dist/{chunk-KJ752DUH.js → chunk-WZADX5VO.js} +6 -6
- package/dist/{chunk-2BVVMWVF.js → chunk-XLM2JZBE.js} +1 -1
- package/dist/{chunk-NZKH2RMQ.js → chunk-XLRPJHXN.js} +1 -1
- package/dist/{chunk-UHS3JZLN.js → chunk-XZHJVGR3.js} +2 -2
- package/dist/{chunk-CHVXLS7U.js → chunk-YCYFREHD.js} +2 -2
- package/dist/{chunk-PS2K6ZQ3.js → chunk-YGMSDYOH.js} +6 -6
- package/dist/{codex-app-cards-switch-XP2H2CZO.js → codex-app-cards-switch-7YTDIMCX.js} +11 -11
- package/dist/{codex-desktop-launch-QRFE2GHZ.js → codex-desktop-launch-CICLFWQX.js} +1 -1
- package/dist/{codex-session-launch-EUUWALWW.js → codex-session-launch-KW7VUPAH.js} +18 -18
- package/dist/{config-WBDMUTD4.js → config-632JSNBM.js} +3 -3
- package/dist/{global-upgrade-ZXFLRGGV.js → global-upgrade-BMCLOI2P.js} +10 -10
- package/dist/{identity-NUQ75BP7.js → identity-UCVTGQHM.js} +4 -4
- package/dist/{live-capabilities-SIQ25SSK.js → live-capabilities-5VPEAE37.js} +5 -5
- package/dist/{paths-BGO6PZFZ.js → paths-NCKEVGEI.js} +3 -3
- package/dist/{reapply-AD5ATZOO.js → reapply-UPZ2L4ID.js} +28 -28
- package/dist/src/index.js +29 -29
- package/dist/{upgrade-lock-B5HTMEWT.js → upgrade-lock-J36URBLG.js} +4 -4
- package/dist/{usage-YHFALPKW.js → usage-BL3KXNWQ.js} +3 -3
- package/package.json +1 -1
|
@@ -2062,7 +2062,7 @@ var operandTextsOf = (command) => command.args.flatMap((arg) => {
|
|
|
2062
2062
|
});
|
|
2063
2063
|
var positionalTextsOf = (command) => command.args.filter((arg) => parameterOf(arg) === null).map((arg) => arg.text);
|
|
2064
2064
|
var firstOperandOf = (command, isSwitch) => command.args.find((arg) => !isSwitch.test(arg.text))?.text;
|
|
2065
|
-
var
|
|
2065
|
+
var namesAPathThatNeedsAPerson = (text3, judge) => judge.namesAFileThatNeedsAPerson(text3.trim());
|
|
2066
2066
|
var isAssignmentTarget = (word) => POWERSHELL_ASSIGNMENT_TARGET.test(word.text) || word.text === POWERSHELL_ARRAY_SEPARATOR;
|
|
2067
2067
|
var wordsAfterAnAssignment = (words) => {
|
|
2068
2068
|
const operator = words.findIndex((word) => isPowerShellAssignmentOperator(word));
|
|
@@ -2121,10 +2121,10 @@ var copyDestinationOf = (command) => {
|
|
|
2121
2121
|
};
|
|
2122
2122
|
var writesASecretFileFromPowerShell = (command, judge) => {
|
|
2123
2123
|
if (command.cmdlet !== COPY_ITEM) {
|
|
2124
|
-
return POWERSHELL_FILE_WRITERS.has(command.cmdlet) && operandTextsOf(command).some((text3) =>
|
|
2124
|
+
return POWERSHELL_FILE_WRITERS.has(command.cmdlet) && operandTextsOf(command).some((text3) => namesAPathThatNeedsAPerson(text3, judge));
|
|
2125
2125
|
}
|
|
2126
2126
|
const destination = copyDestinationOf(command);
|
|
2127
|
-
return destination !== void 0 &&
|
|
2127
|
+
return destination !== void 0 && namesAPathThatNeedsAPerson(destination, judge);
|
|
2128
2128
|
};
|
|
2129
2129
|
var formatsADisk = (command) => DISK_ERASERS.has(command.cmdlet);
|
|
2130
2130
|
var changesAWindowsService = (command) => {
|
|
@@ -2142,7 +2142,7 @@ var stageIsDestructive = (stage, judge) => {
|
|
|
2142
2142
|
};
|
|
2143
2143
|
var stageHasAVisibleConsequence = (stage, judge) => {
|
|
2144
2144
|
const command = powerShellCommandOf(stage);
|
|
2145
|
-
return stage.redirectTargets.some((target) =>
|
|
2145
|
+
return stage.redirectTargets.some((target) => namesAPathThatNeedsAPerson(target.text, judge)) || command !== null && !onlyReads(command, judge) && powerShellCommandChangesSomething(command, judge);
|
|
2146
2146
|
};
|
|
2147
2147
|
var fetchesWithPowerShell = (stage, judge) => {
|
|
2148
2148
|
const command = powerShellCommandOf(stage);
|
|
@@ -4539,11 +4539,13 @@ var PULL_REQUEST_CLIS = /* @__PURE__ */ new Set(["gh", "glab"]);
|
|
|
4539
4539
|
var PULL_REQUEST_NOUNS = /* @__PURE__ */ new Set(["pr", "mr"]);
|
|
4540
4540
|
var MERGE_SUBCOMMAND = "merge";
|
|
4541
4541
|
var PULL_REQUEST_MERGE_PATH = /(?:^|\/)pulls\/\d+\/merge$/;
|
|
4542
|
+
var PULL_REQUEST_MERGE_PATH_SPELLED_ANY_WAY = /(?:^|\/)pulls\/[^/\s]+\/merge(?:[?#]|$)/;
|
|
4542
4543
|
var mergesAPullRequest = ({ program, args }) => {
|
|
4543
4544
|
if (program === void 0 || !PULL_REQUEST_CLIS.has(basenameOf(program.text))) return false;
|
|
4544
4545
|
const words = args.filter((arg) => !arg.text.startsWith("-"));
|
|
4545
4546
|
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
4547
|
};
|
|
4548
|
+
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
4549
|
var DEPLOY_AND_SCHEMA_COMMAND_PATTERNS = [
|
|
4548
4550
|
"Bash(kubectl apply:*)",
|
|
4549
4551
|
"Bash(kubectl replace:*)",
|
|
@@ -4594,13 +4596,131 @@ var DEPLOY_AND_SCHEMA_COMMAND_PATTERNS = [
|
|
|
4594
4596
|
"Bash(gcloud run deploy:*)",
|
|
4595
4597
|
"Bash(gcloud functions deploy:*)"
|
|
4596
4598
|
];
|
|
4599
|
+
var RELEASE_AND_CLUSTER_PROGRAMS = /* @__PURE__ */ new Set(["kubectl", "fastlane"]);
|
|
4600
|
+
var RELEASE_AND_CLUSTER_COMMAND_PATTERNS = [
|
|
4601
|
+
"Bash(kubectl patch:*)",
|
|
4602
|
+
"Bash(kubectl edit:*)",
|
|
4603
|
+
"Bash(kubectl set:*)",
|
|
4604
|
+
"Bash(kubectl create:*)",
|
|
4605
|
+
"Bash(kubectl drain:*)",
|
|
4606
|
+
"Bash(kubectl cordon:*)",
|
|
4607
|
+
"Bash(kubectl taint:*)",
|
|
4608
|
+
"Bash(fastlane deliver:*)",
|
|
4609
|
+
"Bash(fastlane supply:*)",
|
|
4610
|
+
"Bash(fastlane pilot upload:*)",
|
|
4611
|
+
"Bash(fastlane upload_to_app_store:*)",
|
|
4612
|
+
"Bash(fastlane upload_to_testflight:*)",
|
|
4613
|
+
"Bash(fastlane upload_to_play_store:*)"
|
|
4614
|
+
];
|
|
4615
|
+
var SUBMITS_THE_BUILD_TO_A_STORE = /^--auto-submit(?:-with-profile)?(?:=|$)/;
|
|
4616
|
+
var EAS_PROGRAM = /^eas(?:-cli)?(?:@[\w.-]+)?$/;
|
|
4617
|
+
var EAS_COMMANDS_THAT_PUBLISH = /^(?:submit|deploy|update|update:(?:republish|rollback|roll-back-to-embedded)|channel:(?:edit|rollout))$/;
|
|
4618
|
+
var easCommandPublishes = (invocation) => {
|
|
4619
|
+
const words = wordsOfInvocation(invocation);
|
|
4620
|
+
return words.some((word, index) => EAS_PROGRAM.test(basenameOf(word.text)) && EAS_COMMANDS_THAT_PUBLISH.test(words[index + 1]?.text ?? ""));
|
|
4621
|
+
};
|
|
4622
|
+
var publishesAnAppBuild = (invocation) => invocation.args.some((arg) => SUBMITS_THE_BUILD_TO_A_STORE.test(arg.text)) || easCommandPublishes(invocation);
|
|
4623
|
+
var PUSHES_EVERY_TAG = /* @__PURE__ */ new Set(["--tags", "--follow-tags"]);
|
|
4624
|
+
var NAMES_A_TAG = /(?:^|:)\+?refs\/tags\/|^tag$|(?:^|:)v?\d+(?:\.\d+){1,3}$|(?:^|:)v?\d+\.\d+\.\d+[-+][\w.]+$|\/v\d+\.\d+\.\d+(?:\.\d+)?(?:[-+][\w.]+)?$|^v\$/;
|
|
4625
|
+
var TAG_HELD_IN_A_VARIABLE = /^v?\$\{?(?:\w+_)?(?:tag|version)(?:_name)?\}?$/i;
|
|
4626
|
+
var GIT_PUSH = "push";
|
|
4627
|
+
var pushesATag = ({ program, args }) => {
|
|
4628
|
+
if (program === void 0 || basenameOf(program.text) !== GIT) return false;
|
|
4629
|
+
const [subcommand, ...rest] = argsAfterHarmlessGlobalFlags(args);
|
|
4630
|
+
if (subcommand?.text !== GIT_PUSH) return false;
|
|
4631
|
+
const operands = rest.filter((arg) => !FLAG.test(arg.text));
|
|
4632
|
+
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));
|
|
4633
|
+
};
|
|
4597
4634
|
var SECRET_FILE_NAME = /^(?:\.env(?:\.(?!example$|sample$|template$)[\w.-]+)?|(?:secrets?|credentials)\.(?:json|ya?ml|env|toml|ini)|credentials)$/i;
|
|
4635
|
+
var CI_WORKFLOW_FILE = /(?:^|\/)\.github\/workflows\/[^/]+$/i;
|
|
4636
|
+
var AGENT_SETTINGS_FILE = new RegExp(String.raw`(?:^|/)(?:${[
|
|
4637
|
+
String.raw`\.claude/settings(?:\.local)?\.json`,
|
|
4638
|
+
String.raw`\.claude\.json`,
|
|
4639
|
+
String.raw`\.codex/(?:config\.toml|hooks\.json)`,
|
|
4640
|
+
String.raw`\.cursor/hooks\.json`,
|
|
4641
|
+
String.raw`\.gemini/(?:settings\.json|config/hooks\.json)`,
|
|
4642
|
+
String.raw`\.qwen/settings\.json`,
|
|
4643
|
+
String.raw`\.factory/hooks\.json`,
|
|
4644
|
+
String.raw`\.hermes/config\.ya?ml`,
|
|
4645
|
+
String.raw`\.config/opencode/(?:opencode\.jsonc?|plugins?/.+)`,
|
|
4646
|
+
String.raw`\.pushary(?:/.+)?`,
|
|
4647
|
+
String.raw`\.git/hooks(?:/.+)?`,
|
|
4648
|
+
String.raw`\.ssh(?:/(?!known_hosts(?:\.old)?$).+)?`
|
|
4649
|
+
].join("|")})$`, "i");
|
|
4650
|
+
var withoutDotSegments = (path) => {
|
|
4651
|
+
const kept = [];
|
|
4652
|
+
for (const segment of path.split("/")) {
|
|
4653
|
+
if (segment === "..") kept.pop();
|
|
4654
|
+
else if (segment !== "" && segment !== ".") kept.push(segment);
|
|
4655
|
+
}
|
|
4656
|
+
return `${path.startsWith("/") ? "/" : ""}${kept.join("/")}`;
|
|
4657
|
+
};
|
|
4658
|
+
var pathNeedsAPersonToChange = (path) => {
|
|
4659
|
+
const written = withoutDotSegments(normalizeSeparators(path));
|
|
4660
|
+
return SECRET_FILE_NAME.test(basenameOf(written)) || CI_WORKFLOW_FILE.test(written) || AGENT_SETTINGS_FILE.test(written);
|
|
4661
|
+
};
|
|
4598
4662
|
var REDIRECTS_INTO_A_SECRET_FILE = />>?\s*(?:[^\s;|&<>]*\/)?\.env(?:\.[\w-]+)?(?=$|[\s;|&)])/;
|
|
4599
4663
|
var COPIES_ONTO_ITS_LAST_OPERAND = /* @__PURE__ */ new Set(["cp", "install", "ln", "rsync", "scp"]);
|
|
4600
4664
|
var WRITES_EVERY_OPERAND = /* @__PURE__ */ new Set(["mv", "tee", "rm", "unlink", "shred", "truncate"]);
|
|
4601
4665
|
var EDITS_IN_PLACE = /* @__PURE__ */ new Set(["sed", "gsed", "perl"]);
|
|
4602
4666
|
var IN_PLACE_FLAG = /^(?:-[A-Za-z]*i|--in-place(?:=.*)?)$/;
|
|
4667
|
+
var PERMISSIONS_OFF_WRITES_EVERY_OPERAND = /* @__PURE__ */ new Set([...WRITES_EVERY_OPERAND, "sponge"]);
|
|
4668
|
+
var PERMISSIONS_OFF_EDITS_IN_PLACE = /* @__PURE__ */ new Set([...EDITS_IN_PLACE, "yq"]);
|
|
4669
|
+
var IN_PLACE_LONG_FLAG = /^--in-?place(?:=|$)/;
|
|
4670
|
+
var IN_PLACE_LETTER = "i";
|
|
4671
|
+
var SED_FLAGS_THAT_TAKE_THE_REST = /* @__PURE__ */ new Set(["e", "f", "l"]);
|
|
4672
|
+
var SHORT_FLAGS_THAT_TAKE_THE_REST = /* @__PURE__ */ new Map([
|
|
4673
|
+
["sed", SED_FLAGS_THAT_TAKE_THE_REST],
|
|
4674
|
+
["gsed", SED_FLAGS_THAT_TAKE_THE_REST],
|
|
4675
|
+
["perl", /* @__PURE__ */ new Set(["M", "m", "I", "e", "E", "x", "F", "C", "d", "D"])]
|
|
4676
|
+
]);
|
|
4677
|
+
var flagEditsInPlace = (program, flag) => {
|
|
4678
|
+
if (IN_PLACE_LONG_FLAG.test(flag)) return true;
|
|
4679
|
+
if (!SHORT_OPTIONS.test(flag)) return false;
|
|
4680
|
+
const takesTheRest = SHORT_FLAGS_THAT_TAKE_THE_REST.get(program);
|
|
4681
|
+
for (const letter of flag.slice(1)) {
|
|
4682
|
+
if (letter === IN_PLACE_LETTER) return true;
|
|
4683
|
+
if (takesTheRest?.has(letter) === true) return false;
|
|
4684
|
+
}
|
|
4685
|
+
return false;
|
|
4686
|
+
};
|
|
4687
|
+
var MOVE = "mv";
|
|
4688
|
+
var TARGET_DIRECTORY_FLAG = "-t";
|
|
4689
|
+
var TARGET_DIRECTORY_ASSIGNMENT = /^--target-directory=(.+)$/;
|
|
4690
|
+
var BRACE_ALTERNATIVES = /\{([^{},]*(?:,[^{},]*)+)\}/;
|
|
4691
|
+
var MAX_SPELLINGS_OF_A_WORD = 64;
|
|
4692
|
+
var hasABraceGroup = (spelling) => BRACE_ALTERNATIVES.test(spelling);
|
|
4693
|
+
var spellingsOfAWord = (word) => {
|
|
4694
|
+
if (!word.plain) return [word];
|
|
4695
|
+
let spellings = [word.text];
|
|
4696
|
+
for (let index = spellings.findIndex(hasABraceGroup); index !== -1; index = spellings.findIndex(hasABraceGroup)) {
|
|
4697
|
+
const spelling = spellings[index] ?? "";
|
|
4698
|
+
const braces = BRACE_ALTERNATIVES.exec(spelling);
|
|
4699
|
+
if (braces === null) return null;
|
|
4700
|
+
const choices = (braces[1] ?? "").split(",");
|
|
4701
|
+
if (spellings.length - 1 + choices.length > MAX_SPELLINGS_OF_A_WORD) return null;
|
|
4702
|
+
spellings = [...spellings.slice(0, index), ...choices.map((choice) => spelling.replace(braces[0], choice)), ...spellings.slice(index + 1)];
|
|
4703
|
+
}
|
|
4704
|
+
return spellings.map((text3) => ({ ...word, text: text3 }));
|
|
4705
|
+
};
|
|
4603
4706
|
var namesASecretFile = (word) => word !== void 0 && SECRET_FILE_NAME.test(basenameOf(word.text));
|
|
4707
|
+
var namesAFileThatNeedsAPerson = (word) => word !== void 0 && pathNeedsAPersonToChange(word.text);
|
|
4708
|
+
var RECURSIVE_COPY_FLAG = /^(?:-[A-Za-z]*[rRa][A-Za-z]*|--recursive|--archive)$/;
|
|
4709
|
+
var FOLDER_THAT_NEEDS_A_PERSON = new RegExp(String.raw`(?:^|/)(?:${[
|
|
4710
|
+
String.raw`\.github/workflows`,
|
|
4711
|
+
String.raw`\.claude`,
|
|
4712
|
+
String.raw`\.codex`,
|
|
4713
|
+
String.raw`\.cursor`,
|
|
4714
|
+
String.raw`\.gemini`,
|
|
4715
|
+
String.raw`\.qwen`,
|
|
4716
|
+
String.raw`\.factory`,
|
|
4717
|
+
String.raw`\.hermes`,
|
|
4718
|
+
String.raw`\.pushary`,
|
|
4719
|
+
String.raw`\.git/hooks`,
|
|
4720
|
+
String.raw`\.ssh`,
|
|
4721
|
+
String.raw`\.config/opencode(?:/plugins?)?`
|
|
4722
|
+
].join("|")})$`, "i");
|
|
4723
|
+
var folderNeedsAPersonToChange = (path) => FOLDER_THAT_NEEDS_A_PERSON.test(withoutDotSegments(normalizeSeparators(path)));
|
|
4604
4724
|
var NETWORK_SENDERS = /* @__PURE__ */ new Set([
|
|
4605
4725
|
"curl",
|
|
4606
4726
|
"wget",
|
|
@@ -4629,6 +4749,47 @@ var writesASecretFile = ({ program, args }) => {
|
|
|
4629
4749
|
if (WRITES_EVERY_OPERAND.has(name)) return operands.some(namesASecretFile);
|
|
4630
4750
|
return EDITS_IN_PLACE.has(name) && args.some((arg) => IN_PLACE_FLAG.test(arg.text)) && operands.some(namesASecretFile);
|
|
4631
4751
|
};
|
|
4752
|
+
var referencesAFileThatNeedsAPerson = (word) => pathNeedsAPersonToChange(word.text.replace(FILE_REFERENCE_PREFIX, ""));
|
|
4753
|
+
var sendsAFileThatNeedsAPerson = ({ program, args }) => program !== void 0 && NETWORK_SENDERS.has(basenameOf(program.text)) && args.some(referencesAFileThatNeedsAPerson);
|
|
4754
|
+
var targetDirectoryOf = (args) => {
|
|
4755
|
+
const flag = args.findIndex((arg) => arg.text === TARGET_DIRECTORY_FLAG);
|
|
4756
|
+
if (flag !== -1) return args[flag + 1]?.text;
|
|
4757
|
+
return args.map((arg) => TARGET_DIRECTORY_ASSIGNMENT.exec(arg.text)?.[1]).find((directory) => directory !== void 0);
|
|
4758
|
+
};
|
|
4759
|
+
var copiesOntoAFileThatNeedsAPerson = (args, operands) => {
|
|
4760
|
+
const targetDirectory = targetDirectoryOf(args);
|
|
4761
|
+
const destination = targetDirectory ?? operands.at(-1)?.text;
|
|
4762
|
+
if (destination === void 0) return false;
|
|
4763
|
+
const sources = targetDirectory === void 0 ? operands.slice(0, -1) : operands.filter((operand) => operand.text !== targetDirectory);
|
|
4764
|
+
const landingPaths = [destination, ...sources.map((source) => `${destination}/${basenameOf(source.text)}`)];
|
|
4765
|
+
return landingPaths.some(pathNeedsAPersonToChange) || args.some((arg) => RECURSIVE_COPY_FLAG.test(arg.text)) && landingPaths.some(folderNeedsAPersonToChange);
|
|
4766
|
+
};
|
|
4767
|
+
var GIT_HOOKS_PATH_SETTING = /^core\.hookspath(?:=|$)/i;
|
|
4768
|
+
var GIT_ONE_COMMAND_SETTING_FLAG = "-c";
|
|
4769
|
+
var GIT_CONFIG_SUBCOMMAND = "config";
|
|
4770
|
+
var GIT_CONFIG_UNSET_FLAGS = /* @__PURE__ */ new Set(["--unset", "--unset-all"]);
|
|
4771
|
+
var changesWhereGitLooksForHooks = ({ program, args }) => {
|
|
4772
|
+
if (program === void 0 || basenameOf(program.text) !== GIT) return false;
|
|
4773
|
+
const setting = args.findIndex((arg) => GIT_HOOKS_PATH_SETTING.test(arg.text));
|
|
4774
|
+
if (setting === -1) return false;
|
|
4775
|
+
if (args[setting - 1]?.text === GIT_ONE_COMMAND_SETTING_FLAG) return true;
|
|
4776
|
+
return args.some((arg) => arg.text === GIT_CONFIG_SUBCOMMAND) && (args[setting + 1] !== void 0 || args.some((arg) => GIT_CONFIG_UNSET_FLAGS.has(arg.text)));
|
|
4777
|
+
};
|
|
4778
|
+
var writesAFileThatNeedsAPerson = ({ program, args }) => {
|
|
4779
|
+
if (program === void 0) return false;
|
|
4780
|
+
if (sendsAFileThatNeedsAPerson({ program, args })) return true;
|
|
4781
|
+
const name = basenameOf(program.text);
|
|
4782
|
+
const editsInPlace = PERMISSIONS_OFF_EDITS_IN_PLACE.has(name) && args.some((arg) => flagEditsInPlace(name, arg.text));
|
|
4783
|
+
if (!COPIES_ONTO_ITS_LAST_OPERAND.has(name) && !PERMISSIONS_OFF_WRITES_EVERY_OPERAND.has(name) && !editsInPlace) return false;
|
|
4784
|
+
const spelled = args.filter((arg) => !FLAG.test(arg.text)).map(spellingsOfAWord);
|
|
4785
|
+
if (spelled.includes(null)) return true;
|
|
4786
|
+
const operands = spelled.flatMap((words) => words ?? []);
|
|
4787
|
+
if (COPIES_ONTO_ITS_LAST_OPERAND.has(name)) return copiesOntoAFileThatNeedsAPerson(args, operands);
|
|
4788
|
+
if (PERMISSIONS_OFF_WRITES_EVERY_OPERAND.has(name)) {
|
|
4789
|
+
return operands.some((operand) => namesAFileThatNeedsAPerson(operand) || folderNeedsAPersonToChange(operand.text)) || name === MOVE && copiesOntoAFileThatNeedsAPerson(args, operands);
|
|
4790
|
+
}
|
|
4791
|
+
return operands.some(namesAFileThatNeedsAPerson);
|
|
4792
|
+
};
|
|
4632
4793
|
var GITHUB_COMMANDS_THAT_ONLY_READ = /* @__PURE__ */ new Set([
|
|
4633
4794
|
"search",
|
|
4634
4795
|
"browse",
|
|
@@ -4734,6 +4895,7 @@ var AWS_OPTIONS_WITH_VALUES = /* @__PURE__ */ new Set([
|
|
|
4734
4895
|
]);
|
|
4735
4896
|
var AWS_LOCAL_COMMANDS = /* @__PURE__ */ new Set(["configure", "help", "history", "sso", "login", "logout"]);
|
|
4736
4897
|
var AWS_READ_OPERATION = /^(?:describe|list|get|head|batch-get|lookup|search|filter|scan|query|select|wait|validate|estimate|simulate|tail|ls|presign|help)(?:-|$)/;
|
|
4898
|
+
var AWS_SIGN_IN_OR_QUERY_OPERATION = /^(?:login|update-kubeconfig|start-query|stop-query|assume-role)(?:-|$)/;
|
|
4737
4899
|
var AWS_S3_SERVICE = "s3";
|
|
4738
4900
|
var AWS_S3_COPIES = /* @__PURE__ */ new Set(["cp", "sync"]);
|
|
4739
4901
|
var S3_URL_PREFIX = "s3://";
|
|
@@ -4803,11 +4965,16 @@ var githubCommandOnlyReads = (noun, verb) => {
|
|
|
4803
4965
|
const readVerbs = GITHUB_READ_COMMANDS.get(noun.text);
|
|
4804
4966
|
return readVerbs !== void 0 && (verb === void 0 || readVerbs.has(verb.text));
|
|
4805
4967
|
};
|
|
4806
|
-
var
|
|
4968
|
+
var githubCommandWordsOf = (args) => {
|
|
4807
4969
|
const meaningful = argsAfterHarmlessGlobalFlags(args);
|
|
4808
4970
|
const [noun, verb] = positionalWordsOf(meaningful, GITHUB_OPTIONS_WITH_VALUES);
|
|
4809
|
-
|
|
4810
|
-
|
|
4971
|
+
return { meaningful, noun, verb };
|
|
4972
|
+
};
|
|
4973
|
+
var githubApiArgsOf = ({ meaningful, noun }) => noun === void 0 ? [] : meaningful.slice(meaningful.indexOf(noun) + 1);
|
|
4974
|
+
var githubCliWrites = (args) => {
|
|
4975
|
+
const words = githubCommandWordsOf(args);
|
|
4976
|
+
if (words.noun?.text === GITHUB_API_SUBCOMMAND) return githubApiRequestWrites(githubApiArgsOf(words));
|
|
4977
|
+
return !githubCommandOnlyReads(words.noun, words.verb);
|
|
4811
4978
|
};
|
|
4812
4979
|
var stripeCliWrites = (args) => {
|
|
4813
4980
|
const [command, operation] = positionalWordsOf(args, STRIPE_OPTIONS_WITH_VALUES);
|
|
@@ -4826,16 +4993,208 @@ var twilioCliWrites = (args) => {
|
|
|
4826
4993
|
if (topic === void 0 || !topic.text.includes(TWILIO_TOPIC_SEPARATOR)) return false;
|
|
4827
4994
|
return !TWILIO_READ_ACTIONS.has(topic.text.split(TWILIO_TOPIC_SEPARATOR).at(-1) ?? "");
|
|
4828
4995
|
};
|
|
4996
|
+
var GITHUB_CLI = "gh";
|
|
4997
|
+
var AWS_CLI = "aws";
|
|
4998
|
+
var awsOnlySignsInOrQueries = (args) => {
|
|
4999
|
+
const [service, operation] = positionalWordsOf(args, AWS_OPTIONS_WITH_VALUES);
|
|
5000
|
+
return service !== void 0 && service.text !== AWS_S3_SERVICE && operation !== void 0 && AWS_SIGN_IN_OR_QUERY_OPERATION.test(operation.text);
|
|
5001
|
+
};
|
|
4829
5002
|
var REMOTE_API_CLI_WRITES = /* @__PURE__ */ new Map([
|
|
4830
|
-
[
|
|
5003
|
+
[GITHUB_CLI, githubCliWrites],
|
|
4831
5004
|
["stripe", stripeCliWrites],
|
|
4832
|
-
[
|
|
5005
|
+
[AWS_CLI, awsCliWrites],
|
|
4833
5006
|
["twilio", twilioCliWrites]
|
|
4834
5007
|
]);
|
|
4835
5008
|
var invocationWritesThroughARemoteApi = ({ program, args }) => {
|
|
4836
5009
|
const writes = program === void 0 ? void 0 : REMOTE_API_CLI_WRITES.get(basenameOf(program.text));
|
|
4837
5010
|
return writes !== void 0 && writes(args);
|
|
4838
5011
|
};
|
|
5012
|
+
var GITHUB_REPO_NOUN = "repo";
|
|
5013
|
+
var GITHUB_EDIT_VERB = "edit";
|
|
5014
|
+
var GITHUB_CREATE_VERB = "create";
|
|
5015
|
+
var GITHUB_PUBLIC_OPTION = /^--public(?:=(?!false$).*)?$/;
|
|
5016
|
+
var GITHUB_VISIBILITY_OPTION = /^--visibility(?:=|$)/;
|
|
5017
|
+
var GITHUB_COMMANDS_WITH_A_CONSEQUENCE = /* @__PURE__ */ new Map([
|
|
5018
|
+
["secret", /* @__PURE__ */ new Set(["set"])],
|
|
5019
|
+
["variable", /* @__PURE__ */ new Set(["set"])],
|
|
5020
|
+
[GITHUB_REPO_NOUN, /* @__PURE__ */ new Set(["archive", "rename"])],
|
|
5021
|
+
["ssh-key", /* @__PURE__ */ new Set(["add"])],
|
|
5022
|
+
["gpg-key", /* @__PURE__ */ new Set(["add"])]
|
|
5023
|
+
]);
|
|
5024
|
+
var HTTP_METHODS_THAT_CHANGE_A_RESOURCE = /* @__PURE__ */ new Set(["DELETE", "PUT", "PATCH"]);
|
|
5025
|
+
var GITHUB_API_ENDPOINTS_FOR_EVERYDAY_WORK = /(?:^|\/)(?:issues|pulls|comments|notifications|labels|assignees|reviews|reactions|requested_reviewers)(?:\/|$)/;
|
|
5026
|
+
var GITHUB_API_ENDPOINTS_THAT_PUBLISH = /(?:^|\/)(?:merges|releases|dispatches|transfer|keys|deployments|hooks|git\/refs)\/?$/;
|
|
5027
|
+
var GRAPHQL_QUERY_FIELD = /^query=/;
|
|
5028
|
+
var GRAPHQL_FIELD_WORDS_THAT_DELETE_OR_PUBLISH = /delete|archive|transfer|merge|branchprotectionrule/;
|
|
5029
|
+
var GRAPHQL_FIELDS_THAT_PUBLISH = /* @__PURE__ */ new Set([
|
|
5030
|
+
"updaterepository",
|
|
5031
|
+
"createref",
|
|
5032
|
+
"updateref",
|
|
5033
|
+
"updaterefs",
|
|
5034
|
+
"createcommitonbranch"
|
|
5035
|
+
]);
|
|
5036
|
+
var WORDS_AND_THE_TEXT_BETWEEN = /(\W+)/;
|
|
5037
|
+
var OPENS_A_CALL = /^\s*\(/;
|
|
5038
|
+
var GRAPHQL_STRING = /"(?:[^"\\]|\\.)*"/g;
|
|
5039
|
+
var graphqlFieldsCalledIn = (query) => {
|
|
5040
|
+
const parts = query.replace(GRAPHQL_STRING, '""').split(WORDS_AND_THE_TEXT_BETWEEN);
|
|
5041
|
+
return parts.filter((part, index) => index % 2 === 0 && part !== "" && OPENS_A_CALL.test(parts[index + 1] ?? "")).map((field) => field.toLowerCase());
|
|
5042
|
+
};
|
|
5043
|
+
var graphqlFieldDeletesOrPublishes = (field) => GRAPHQL_FIELDS_THAT_PUBLISH.has(field) || GRAPHQL_FIELD_WORDS_THAT_DELETE_OR_PUBLISH.test(field);
|
|
5044
|
+
var SINGLE_SHORT_OPTION = /^-[A-Za-z]$/;
|
|
5045
|
+
var takesTheNextGithubApiWord = (text3) => GITHUB_API_LONG_OPTIONS_WITH_A_VALUE.has(text3) || SINGLE_SHORT_OPTION.test(text3) && GITHUB_API_SHORT_OPTIONS_WITH_A_VALUE.has(text3.charAt(1));
|
|
5046
|
+
var githubApiEndpointOf = (args) => (args.find((arg, index) => !FLAG.test(arg.text) && !takesTheNextGithubApiWord(args[index - 1]?.text ?? ""))?.text ?? "").replace(URL_QUERY_OR_FRAGMENT2, "");
|
|
5047
|
+
var graphqlQueriesOf = (options) => options.flatMap(({ name, value }) => value !== void 0 && GITHUB_API_BODY_OPTIONS.has(name) && GRAPHQL_QUERY_FIELD.test(value.text) ? [value] : []);
|
|
5048
|
+
var graphqlQueryHasAConsequence = (query) => query.expands || GITHUB_API_FILE_FIELD.test(query.text) || GRAPHQL_MUTATION.test(query.text) && graphqlFieldsCalledIn(query.text).some(graphqlFieldDeletesOrPublishes);
|
|
5049
|
+
var graphqlRequestHasAConsequence = (options) => {
|
|
5050
|
+
const queries = graphqlQueriesOf(options);
|
|
5051
|
+
return queries.length === 0 || queries.some(graphqlQueryHasAConsequence);
|
|
5052
|
+
};
|
|
5053
|
+
var HTTP_DELETE = "DELETE";
|
|
5054
|
+
var githubApiMethodHasAConsequence = (method, endpoint) => {
|
|
5055
|
+
if (method.expands) return true;
|
|
5056
|
+
const name = method.text.toUpperCase();
|
|
5057
|
+
return name === HTTP_DELETE || HTTP_METHODS_THAT_CHANGE_A_RESOURCE.has(name) && !GITHUB_API_ENDPOINTS_FOR_EVERYDAY_WORK.test(endpoint);
|
|
5058
|
+
};
|
|
5059
|
+
var githubApiRequestHasAConsequence = (args) => {
|
|
5060
|
+
const options = githubApiOptionsOf(args);
|
|
5061
|
+
if (options === null) return true;
|
|
5062
|
+
const endpoint = githubApiEndpointOf(args);
|
|
5063
|
+
if (endpoint === GITHUB_GRAPHQL_ENDPOINT) return graphqlRequestHasAConsequence(options);
|
|
5064
|
+
if (GITHUB_API_ENDPOINTS_THAT_PUBLISH.test(endpoint)) return githubApiRequestWrites(args);
|
|
5065
|
+
const method = options.filter((option) => HTTP_METHOD_OPTIONS.has(option.name)).at(-1)?.value;
|
|
5066
|
+
return method !== void 0 && githubApiMethodHasAConsequence(method, endpoint);
|
|
5067
|
+
};
|
|
5068
|
+
var githubCommandHasAConsequence = ({ program, args }) => {
|
|
5069
|
+
if (program === void 0 || basenameOf(program.text) !== GITHUB_CLI) return false;
|
|
5070
|
+
const words = githubCommandWordsOf(args);
|
|
5071
|
+
const { noun, verb } = words;
|
|
5072
|
+
if (noun === void 0) return false;
|
|
5073
|
+
if (noun.text === GITHUB_API_SUBCOMMAND) return githubApiRequestHasAConsequence(githubApiArgsOf(words));
|
|
5074
|
+
if (noun.text === GITHUB_REPO_NOUN && verb?.text === GITHUB_EDIT_VERB) return words.meaningful.some((arg) => GITHUB_VISIBILITY_OPTION.test(arg.text));
|
|
5075
|
+
if (noun.text === GITHUB_REPO_NOUN && verb?.text === GITHUB_CREATE_VERB) return words.meaningful.some((arg) => GITHUB_PUBLIC_OPTION.test(arg.text));
|
|
5076
|
+
return verb !== void 0 && (GITHUB_COMMANDS_WITH_A_CONSEQUENCE.get(noun.text)?.has(verb.text) ?? false);
|
|
5077
|
+
};
|
|
5078
|
+
var STRIPE_CLI = "stripe";
|
|
5079
|
+
var STRIPE_LIVE_MODE = /^--live$|[sr]k_live_/;
|
|
5080
|
+
var STRIPE_API_KEY_OPTION = "--api-key";
|
|
5081
|
+
var STRIPE_API_KEY_HELD_IN_A_VARIABLE = /^(?:--api-key|STRIPE_API_KEY)=.*\$/;
|
|
5082
|
+
var stripeMayUseLiveData = (words) => words.some((word, index) => STRIPE_LIVE_MODE.test(word.text) || STRIPE_API_KEY_HELD_IN_A_VARIABLE.test(word.text) || word.expands && words[index - 1]?.text === STRIPE_API_KEY_OPTION);
|
|
5083
|
+
var writesThroughAServiceApi = (invocation) => {
|
|
5084
|
+
const innermost = innermostInvocation(invocation);
|
|
5085
|
+
const name = basenameOf(innermost.program?.text ?? "");
|
|
5086
|
+
if (name === GITHUB_CLI) return false;
|
|
5087
|
+
if (name === STRIPE_CLI && !stripeMayUseLiveData(wordsOfInvocation(invocation))) return false;
|
|
5088
|
+
if (name === AWS_CLI && awsOnlySignsInOrQueries(innermost.args)) return false;
|
|
5089
|
+
return invocationWritesThroughARemoteApi(innermost);
|
|
5090
|
+
};
|
|
5091
|
+
var NO_SHORT_OPTIONS = /* @__PURE__ */ new Set();
|
|
5092
|
+
var HTTP_CLIENT_SYNTAX = /* @__PURE__ */ new Map([
|
|
5093
|
+
["curl", {
|
|
5094
|
+
bodyOption: /^--(?:data(?:-[a-z]+)?|json|form(?:-string)?|upload-file)(?:=|$)/,
|
|
5095
|
+
methodOption: /^--request(?:=|$)/,
|
|
5096
|
+
getOption: /^--get$/,
|
|
5097
|
+
shortOptionsWithAValue: /* @__PURE__ */ new Set([..."AbcCdDeEFHKmoPQrtTuUwxXyYz"]),
|
|
5098
|
+
shortBodyOptions: /* @__PURE__ */ new Set(["d", "F", "T"]),
|
|
5099
|
+
shortMethodOption: "X",
|
|
5100
|
+
shortGetOption: "G"
|
|
5101
|
+
}],
|
|
5102
|
+
["wget", {
|
|
5103
|
+
bodyOption: /^--(?:post-(?:data|file)|body-(?:data|file))(?:=|$)/,
|
|
5104
|
+
methodOption: /^--method(?:=|$)/,
|
|
5105
|
+
getOption: null,
|
|
5106
|
+
shortOptionsWithAValue: NO_SHORT_OPTIONS,
|
|
5107
|
+
shortBodyOptions: NO_SHORT_OPTIONS,
|
|
5108
|
+
shortMethodOption: null,
|
|
5109
|
+
shortGetOption: null
|
|
5110
|
+
}]
|
|
5111
|
+
]);
|
|
5112
|
+
var SHORT_OPTIONS = /^-[^-]/;
|
|
5113
|
+
var optionValueAt = (args, index, attached) => {
|
|
5114
|
+
const arg = args[index];
|
|
5115
|
+
return attached === "" || arg === void 0 ? args[index + 1] : { ...arg, text: attached };
|
|
5116
|
+
};
|
|
5117
|
+
var readHttpRequest = (args, syntax) => {
|
|
5118
|
+
let sendsABody = false;
|
|
5119
|
+
let forcesAGet = false;
|
|
5120
|
+
const methods = [];
|
|
5121
|
+
args.forEach((arg, index) => {
|
|
5122
|
+
if (LONG_OPTION.test(arg.text)) {
|
|
5123
|
+
sendsABody ||= syntax.bodyOption.test(arg.text);
|
|
5124
|
+
forcesAGet ||= syntax.getOption?.test(arg.text) ?? false;
|
|
5125
|
+
const separator = arg.text.indexOf(FLAG_VALUE_SEPARATOR);
|
|
5126
|
+
const method = syntax.methodOption.test(arg.text) ? optionValueAt(args, index, separator === -1 ? "" : arg.text.slice(separator + 1)) : void 0;
|
|
5127
|
+
if (method !== void 0) methods.push(method);
|
|
5128
|
+
return;
|
|
5129
|
+
}
|
|
5130
|
+
if (!SHORT_OPTIONS.test(arg.text)) return;
|
|
5131
|
+
for (let position = 1; position < arg.text.length; position += 1) {
|
|
5132
|
+
const letter = arg.text.charAt(position);
|
|
5133
|
+
forcesAGet ||= letter === syntax.shortGetOption;
|
|
5134
|
+
if (!syntax.shortOptionsWithAValue.has(letter)) continue;
|
|
5135
|
+
sendsABody ||= syntax.shortBodyOptions.has(letter);
|
|
5136
|
+
const method = letter === syntax.shortMethodOption ? optionValueAt(args, index, arg.text.slice(position + 1)) : void 0;
|
|
5137
|
+
if (method !== void 0) methods.push(method);
|
|
5138
|
+
return;
|
|
5139
|
+
}
|
|
5140
|
+
});
|
|
5141
|
+
return { sendsABody, forcesAGet, methods };
|
|
5142
|
+
};
|
|
5143
|
+
var requestSendsData = ({ sendsABody, forcesAGet, methods }) => methods.length === 0 ? sendsABody && !forcesAGet : methods.some((method) => method.expands || !HTTP_READ_METHODS.has(method.text.toUpperCase()));
|
|
5144
|
+
var THIS_MACHINE_ADDRESS = /^(?:(?:https?:\/\/)?(?:(?:[\w-]+\.)*localhost|127(?:\.\d{1,3}){3}|0\.0\.0\.0|\[::1\]|host\.docker\.internal)|https?:\/\/(?:10(?:\.\d{1,3}){3}|192\.168(?:\.\d{1,3}){2}|172\.(?:1[6-9]|2\d|3[01])(?:\.\d{1,3}){2}))(?::(?:\d+|\$\w+|\$\{[^}]*\}))?(?:[/?#]|$)/i;
|
|
5145
|
+
var ROUTES_THE_REQUEST_ELSEWHERE = /^(?:--(?:resolve|connect-to|proxy[\w.]*|preproxy|socks[\w-]*|config)(?:=|$)|-[A-Za-z]*[xK])/;
|
|
5146
|
+
var URL_WITH_A_SCHEME = /^[a-z][a-z\d+.-]*:\/\//i;
|
|
5147
|
+
var requestStaysOnThisMachine = (args) => {
|
|
5148
|
+
if (args.some((arg) => ROUTES_THE_REQUEST_ELSEWHERE.test(arg.text))) return false;
|
|
5149
|
+
const addresses = args.filter((arg) => !FLAG.test(arg.text) && (URL_WITH_A_SCHEME.test(arg.text) || THIS_MACHINE_ADDRESS.test(arg.text)));
|
|
5150
|
+
return addresses.length > 0 && addresses.every((arg) => THIS_MACHINE_ADDRESS.test(arg.text));
|
|
5151
|
+
};
|
|
5152
|
+
var sendsDataOffThisMachine = ({ program, args }) => {
|
|
5153
|
+
const syntax = program === void 0 ? void 0 : HTTP_CLIENT_SYNTAX.get(basenameOf(program.text));
|
|
5154
|
+
return syntax !== void 0 && requestSendsData(readHttpRequest(args, syntax)) && !requestStaysOnThisMachine(args);
|
|
5155
|
+
};
|
|
5156
|
+
var KUBECTL = "kubectl";
|
|
5157
|
+
var KUBECTL_EXEC = "exec";
|
|
5158
|
+
var kubectlExecRunsMoreThanAReadOnlyCommand = ({ program, args }) => {
|
|
5159
|
+
if (program === void 0 || basenameOf(program.text) !== KUBECTL) return false;
|
|
5160
|
+
const endOfOptions = args.findIndex((arg) => arg.text === END_OF_OPTIONS3);
|
|
5161
|
+
const kubectlWords = endOfOptions === -1 ? args : args.slice(0, endOfOptions);
|
|
5162
|
+
if (!kubectlWords.some((arg) => arg.text === KUBECTL_EXEC)) return false;
|
|
5163
|
+
const command = endOfOptions === -1 ? [] : args.slice(endOfOptions + 1);
|
|
5164
|
+
return command.length === 0 || command.some((arg) => arg.expands) || !isSafeReadOnlyCommand(posixCommandOf(command.map((arg) => arg.text)));
|
|
5165
|
+
};
|
|
5166
|
+
var SSH = "ssh";
|
|
5167
|
+
var SSH_OPTION_LETTERS_WITH_A_VALUE = /* @__PURE__ */ new Set([..."BbcDEeFIiJLlmOoPpQRSWw"]);
|
|
5168
|
+
var SSH_SHORT_OPTION_CLUSTER = /^-[A-Za-z]+$/;
|
|
5169
|
+
var SSH_OPTION_THAT_RUNS_A_COMMAND = /(?:proxy|local|remote|knownhosts)command/i;
|
|
5170
|
+
var SSH_CONFIG_OPTION = "-o";
|
|
5171
|
+
var sshOptionTakesTheNextWord = (text3) => {
|
|
5172
|
+
if (!SSH_SHORT_OPTION_CLUSTER.test(text3)) return false;
|
|
5173
|
+
const letters = text3.slice(1);
|
|
5174
|
+
const firstValueOption = [...letters].findIndex((letter) => SSH_OPTION_LETTERS_WITH_A_VALUE.has(letter));
|
|
5175
|
+
return firstValueOption === letters.length - 1;
|
|
5176
|
+
};
|
|
5177
|
+
var sshOptionRunsACommand = (args) => args.some((arg, index) => (args[index - 1]?.text === SSH_CONFIG_OPTION || arg.text.startsWith(SSH_CONFIG_OPTION)) && SSH_OPTION_THAT_RUNS_A_COMMAND.test(arg.text));
|
|
5178
|
+
var sshRemoteCommandOf = (args) => {
|
|
5179
|
+
let index = 0;
|
|
5180
|
+
while (index < args.length) {
|
|
5181
|
+
const text3 = args[index]?.text ?? "";
|
|
5182
|
+
if (text3 === END_OF_OPTIONS3) {
|
|
5183
|
+
index += 1;
|
|
5184
|
+
break;
|
|
5185
|
+
}
|
|
5186
|
+
if (!FLAG.test(text3)) break;
|
|
5187
|
+
index += sshOptionTakesTheNextWord(text3) ? 2 : 1;
|
|
5188
|
+
}
|
|
5189
|
+
return args.slice(index + 1);
|
|
5190
|
+
};
|
|
5191
|
+
var sshRunsMoreThanAReadOnlyCommand = ({ program, args }) => {
|
|
5192
|
+
if (program === void 0 || basenameOf(program.text) !== SSH) return false;
|
|
5193
|
+
if (sshOptionRunsACommand(args)) return true;
|
|
5194
|
+
const command = sshRemoteCommandOf(args);
|
|
5195
|
+
return command.length > 0 && (command.some((arg) => arg.expands) || !isSafeReadOnlyCommand(command.map((arg) => arg.text).join(" ")));
|
|
5196
|
+
};
|
|
5197
|
+
var changesSomethingHostedElsewhere = (invocation) => githubCommandHasAConsequence(invocation) || writesThroughAServiceApi(invocation) || sendsDataOffThisMachine(invocation) || kubectlExecRunsMoreThanAReadOnlyCommand(invocation) || sshRunsMoreThanAReadOnlyCommand(invocation);
|
|
4839
5198
|
var segmentWritesThroughARemoteApi = (segment, depth) => {
|
|
4840
5199
|
const innermost = innermostInvocation(segment.invocation);
|
|
4841
5200
|
return invocationWritesThroughARemoteApi(innermost) || commandsNestedIn(innermost, inlineScriptsOf(innermost, segment.heredocs)).some((nested) => commandWritesThroughARemoteApiAt(nested, depth + 1));
|
|
@@ -4964,12 +5323,12 @@ var FIND_RUNNERS = /* @__PURE__ */ new Set(["-exec", "-execdir", "-ok", "-okdir"
|
|
|
4964
5323
|
var FIND_RUNNER_END = /* @__PURE__ */ new Set([";", "+"]);
|
|
4965
5324
|
var FIND = "find";
|
|
4966
5325
|
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)) }] : []);
|
|
4967
|
-
var losesDataVisibly = (toolName, invocation, normalized, depth) => {
|
|
5326
|
+
var losesDataVisibly = (toolName, invocation, normalized, depth, line) => {
|
|
4968
5327
|
const { program, args } = invocation;
|
|
4969
5328
|
if (program === void 0) return false;
|
|
4970
5329
|
const name = basenameOf(program.text);
|
|
4971
5330
|
if (name === FIND) {
|
|
4972
|
-
return args.some((arg) => arg.text === FIND_DELETE) || commandsRunByFind(invocation).some((run) => invocationHasAVisibleConsequence(toolName, run, depth + 1));
|
|
5331
|
+
return args.some((arg) => arg.text === FIND_DELETE) || commandsRunByFind(invocation).some((run) => invocationHasAVisibleConsequence(toolName, run, depth + 1, line));
|
|
4973
5332
|
}
|
|
4974
5333
|
const destructiveArguments = destructiveArgumentsOf(name, args);
|
|
4975
5334
|
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);
|
|
@@ -5134,15 +5493,18 @@ var honoursPreviewFlags = ({ program, args }) => {
|
|
|
5134
5493
|
};
|
|
5135
5494
|
var onlyPreviews = (invocation) => invocation.program !== void 0 && honoursPreviewFlags(invocation) && invocation.args.some((arg) => !arg.expands && PREVIEW_FLAG.test(arg.text));
|
|
5136
5495
|
var changesWhatIsDeployed = (toolName, invocation, normalized) => !onlyPreviews(invocation) && (changesProduction(invocation) || mergesAPullRequest(invocation) || isCoveredByPolicy(DEPLOY_AND_SCHEMA_COMMAND_PATTERNS, toolName, normalized));
|
|
5137
|
-
var
|
|
5496
|
+
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));
|
|
5497
|
+
var invocationHasAConsequenceOnlyPermissionsOffAsksAbout = (toolName, invocation, normalized) => releasesOrChangesACluster(toolName, invocation, normalized) || mergesAPullRequestByAnyPath(invocation) || writesAFileThatNeedsAPerson(invocation) || changesWhereGitLooksForHooks(invocation) || changesSomethingHostedElsewhere(invocation);
|
|
5498
|
+
var invocationHasAVisibleConsequence = (toolName, invocation, depth, line) => {
|
|
5138
5499
|
if (depth > MAX_CONSEQUENCE_DEPTH) return true;
|
|
5139
5500
|
if (invocation.program === void 0) return false;
|
|
5140
5501
|
const normalized = quotedInvocation(invocation);
|
|
5141
5502
|
const innermost = innermostInvocation(invocation);
|
|
5142
5503
|
const script = shellScriptOf(invocation);
|
|
5143
|
-
return classifyDecisionRisk(toolName, normalized) === "destructive" || changesWhatIsDeployed(toolName, invocation, normalized) || writesASecretFile(invocation) || losesDataVisibly(toolName, invocation, normalized, depth) || subcommandDestroysVisibly(invocation) || sqlClientChangesData(invocation) || innermost !== invocation && invocationHasAVisibleConsequence(toolName, innermost, depth) || script === null && passesAnInlineScript(invocation) || script !== null && commandHasAVisibleConsequenceAt(toolName, script, depth + 1) || readingsPastGlobalFlags(invocation).some((reading) => invocationHasAVisibleConsequence(toolName, reading, depth + 1));
|
|
5504
|
+
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));
|
|
5144
5505
|
};
|
|
5145
5506
|
var RUNS_FETCHED_CODE = /(?:\$\(|`|<\()\s*(?:curl|wget)\b/;
|
|
5507
|
+
var RUNS_DECODED_CODE = /(?:^|[;&|(\s])(?:bash|sh|zsh|source|\.|python3?|node|ruby|perl)\s+(?:-[A-Za-z]+\s+)*["']?(?:<\(|\$\()[^)]*\b(?:base64|xxd|openssl)\b/;
|
|
5146
5508
|
var FETCHING_PROGRAMS = /* @__PURE__ */ new Set(["curl", "wget"]);
|
|
5147
5509
|
var READS_ITS_SCRIPT_FROM_STANDARD_INPUT = /^-[A-Za-z]*s[A-Za-z]*$/;
|
|
5148
5510
|
var interpreterNameOf = (program) => basenameOf(program.text).replace(/\d+(?:\.\d+)*$/, "");
|
|
@@ -5162,7 +5524,79 @@ var runsADownloadedScript = (invocations) => {
|
|
|
5162
5524
|
};
|
|
5163
5525
|
var pipedSegmentsOf = (command) => (shellSegmentsReadingAPipe(commandForReading(command)) ?? []).map((segment) => innermostInvocation(invocationOf(withoutShellGrouping(segment))));
|
|
5164
5526
|
var pipesIntoASqlClient = (command) => pipedSegmentsOf(command).some((invocation) => sqlClientSyntaxOf(invocation) !== void 0);
|
|
5165
|
-
var
|
|
5527
|
+
var DECODING_FLAGS_BY_PROGRAM = /* @__PURE__ */ new Map([
|
|
5528
|
+
["base64", /^(?:-[A-Za-z]*[dD]|--decode)$/],
|
|
5529
|
+
["xxd", /^-[A-Za-z]*r/],
|
|
5530
|
+
["openssl", /^-d$/]
|
|
5531
|
+
]);
|
|
5532
|
+
var decodes = (invocation) => {
|
|
5533
|
+
const { program, args } = innermostInvocation(invocation);
|
|
5534
|
+
const decodingFlags = program === void 0 ? void 0 : DECODING_FLAGS_BY_PROGRAM.get(basenameOf(program.text));
|
|
5535
|
+
return decodingFlags !== void 0 && args.some((arg) => decodingFlags.test(arg.text));
|
|
5536
|
+
};
|
|
5537
|
+
var producesCodeTheCommandDoesNotShow = (invocation) => fetches(invocation) || decodes(invocation);
|
|
5538
|
+
var pipesCodeIntoAnInterpreter = (command, invocations, producesCode) => invocations.some(producesCode) && pipedSegmentsOf(command).some(runsWhatItReads);
|
|
5539
|
+
var CODE_THAT_DELETES_RECURSIVELY = /\b(?:rmtree|rimraf|rm_rf|rm_r|removedirs)\b|\b(?:rm|rmSync|remove|rmdir|rmdirSync)\s*\([^)]*recursive/;
|
|
5540
|
+
var CODE_THAT_DECODES = /\b(?:b64decode|atob|base64)\b/;
|
|
5541
|
+
var CODE_THAT_RUNS_CODE_IT_BUILDS = /(?<![.\w])(?:eval|exec)\s*\(/;
|
|
5542
|
+
var CODE_THAT_RUNS_COMMANDS = /\b(?:execSync|execFileSync|spawnSync|execFile|spawn|exec|child_process|subprocess|popen|Popen|system)\b/;
|
|
5543
|
+
var CODE_THAT_WRITES_A_FILE = /\b(?:writeFile|appendFile|copyFile|cpSync|renameSync|symlinkSync)\w*\s*\(|(?<![\w.])(?:cp|rename|symlink)\s*\(|\bfs(?:\.promises)?\.(?:cp|rename|symlink)\s*\(|\bshutil\.(?:copy\w*|move)\s*\(|\bos\.(?:rename|replace|symlink)\s*\(|\.write_(?:text|bytes)\s*\(|\bopen\s*\([^)]*,\s*['"`][wax]/;
|
|
5544
|
+
var CODE_STRING_LITERAL = /'([^'\\\n]*)'|"([^"\\\n]*)"|`([^`\\\n]*)`/g;
|
|
5545
|
+
var CODE_PATH_DIVISION = /'\s*\/\s*'/g;
|
|
5546
|
+
var DOUBLE_QUOTE2 = /"/g;
|
|
5547
|
+
var PATH_WITH_A_DOT = /\./;
|
|
5548
|
+
var LONGEST_PATH_SPELLED_IN_PARTS = 4;
|
|
5549
|
+
var SHELL_COMMAND_IN_A_STRING = /\S\s+\S/;
|
|
5550
|
+
var stringLiteralsOf = (code) => [...code.matchAll(CODE_STRING_LITERAL)].map((literal) => literal[1] ?? literal[2] ?? literal[3] ?? "");
|
|
5551
|
+
var pathsSpelledIn = (code) => {
|
|
5552
|
+
const literals = stringLiteralsOf(code.replace(DOUBLE_QUOTE2, "'").replace(CODE_PATH_DIVISION, "/"));
|
|
5553
|
+
return literals.flatMap((_, start) => Array.from({ length: Math.min(LONGEST_PATH_SPELLED_IN_PARTS, literals.length - start) }, (_2, extra) => literals.slice(start, start + extra + 1).join("/"))).filter((spelled) => PATH_WITH_A_DOT.test(spelled));
|
|
5554
|
+
};
|
|
5555
|
+
var commandsSpelledIn = (code) => [
|
|
5556
|
+
...stringLiteralsOf(code).filter((literal) => SHELL_COMMAND_IN_A_STRING.test(literal)),
|
|
5557
|
+
...code.split("\n").map((line) => stringLiteralsOf(line).join(" ")).filter((line) => SHELL_COMMAND_IN_A_STRING.test(line))
|
|
5558
|
+
];
|
|
5559
|
+
var INTERPRETERS_THAT_TAKE_INLINE_CODE = /* @__PURE__ */ new Set([...INLINE_CODE_INTERPRETERS, "bun", "deno", "tsx", "ts-node"]);
|
|
5560
|
+
var RUNNERS_OF_AN_INTERPRETER = /* @__PURE__ */ new Set([
|
|
5561
|
+
"uv",
|
|
5562
|
+
"poetry",
|
|
5563
|
+
"pnpm",
|
|
5564
|
+
"npm",
|
|
5565
|
+
"yarn",
|
|
5566
|
+
"bundle",
|
|
5567
|
+
"pipenv",
|
|
5568
|
+
"hatch",
|
|
5569
|
+
"pdm",
|
|
5570
|
+
"rye",
|
|
5571
|
+
"conda",
|
|
5572
|
+
"mamba"
|
|
5573
|
+
]);
|
|
5574
|
+
var isAnInterpreter = (word) => INTERPRETERS_THAT_TAKE_INLINE_CODE.has(interpreterNameOf(word));
|
|
5575
|
+
var interpreterInvocationOf = (invocation) => {
|
|
5576
|
+
const innermost = innermostInvocation(invocation);
|
|
5577
|
+
const { program, args } = innermost;
|
|
5578
|
+
if (program === void 0) return [];
|
|
5579
|
+
if (isAnInterpreter(program)) return [innermost];
|
|
5580
|
+
if (!RUNNERS_OF_AN_INTERPRETER.has(basenameOf(program.text))) return [];
|
|
5581
|
+
const start = args.findIndex(isAnInterpreter);
|
|
5582
|
+
const interpreter = args[start];
|
|
5583
|
+
return interpreter === void 0 ? [] : [{ program: interpreter, args: args.slice(start + 1) }];
|
|
5584
|
+
};
|
|
5585
|
+
var inlineCodeOf = ({ args }) => args.flatMap((arg, index) => {
|
|
5586
|
+
const namesInlineCode = (FLAG.test(arg.text) || arg.text === INLINE_CODE_SUBCOMMAND) && arg.text !== STANDARD_INPUT_ARGUMENT;
|
|
5587
|
+
if (!namesInlineCode || !passesInlineCode(arg.text)) return [];
|
|
5588
|
+
const separator = arg.text.indexOf(FLAG_VALUE_SEPARATOR);
|
|
5589
|
+
if (separator !== -1) return [arg.text.slice(separator + 1)];
|
|
5590
|
+
const code = args[index + 1];
|
|
5591
|
+
return code === void 0 ? [] : [code.text];
|
|
5592
|
+
});
|
|
5593
|
+
var interpreterCodeIn = (command, invocations) => {
|
|
5594
|
+
const interpreters = invocations.flatMap(interpreterInvocationOf);
|
|
5595
|
+
const heredocs = interpreters.some(runsWhatItReads) ? withHeredocBodiesSetAside(command).bodies : [];
|
|
5596
|
+
return [...interpreters.flatMap(inlineCodeOf), ...heredocs];
|
|
5597
|
+
};
|
|
5598
|
+
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"));
|
|
5599
|
+
var runsInterpreterCodeThatNeedsAPerson = (command, invocations, depth) => interpreterCodeIn(command, invocations).some((code) => codeNeedsAPerson(code, depth));
|
|
5166
5600
|
var WORDS_THAT_OPEN_A_COMMAND = String.raw`if|then|elif|else|do|while|until|!`;
|
|
5167
5601
|
var SHELL_GROUPING_PREFIX = new RegExp(String.raw`^\s*(?:(?:${WORDS_THAT_OPEN_A_COMMAND})\s+|[({]\s*)+`);
|
|
5168
5602
|
var GROUP_OPENER_BY_CLOSER = /* @__PURE__ */ new Map([[")", "("], ["}", "{"]]);
|
|
@@ -5201,7 +5635,7 @@ var withHeredocBodiesSetAside = (command) => {
|
|
|
5201
5635
|
};
|
|
5202
5636
|
var REDIRECTION_TARGET = String.raw`(?:'[^']*'|"[^"]*"|[^\s;|&()<>]+)`;
|
|
5203
5637
|
var INPUT_REDIRECTION = new RegExp(String.raw`\d*(?:<<<|<(?![<(&>]))\s*${REDIRECTION_TARGET}`, "g");
|
|
5204
|
-
var OUTPUT_REDIRECTION = new RegExp(String.raw`(?:\d*|&)(?:>>?|>\||<>|>&|<&)\s
|
|
5638
|
+
var OUTPUT_REDIRECTION = new RegExp(String.raw`(?<!\d)(?:\d*|&)(?:>>?|>\||<>|>&|<&)\s*(${REDIRECTION_TARGET})`, "g");
|
|
5205
5639
|
var REDIRECTED_INPUT_MARK = "\uE000";
|
|
5206
5640
|
var ROUGH_SEPARATORS = ["&&", "||", "$(", "\n", ";", "|", "&", "`", "(", ")", "{", "}"];
|
|
5207
5641
|
var SEPARATORS_INSIDE_DOUBLE_QUOTES = /* @__PURE__ */ new Set(["$(", "`", ")"]);
|
|
@@ -5243,6 +5677,10 @@ var invocationOfRoughPiece = (text3) => {
|
|
|
5243
5677
|
const parsed = invocationOf(piece);
|
|
5244
5678
|
return parsed.program !== void 0 ? parsed : invocationOf(piece.replace(QUOTE_CHARACTERS, ""));
|
|
5245
5679
|
};
|
|
5680
|
+
var substitutionFedTo = (pieces, index) => {
|
|
5681
|
+
const next = pieces[index + 1];
|
|
5682
|
+
return next !== void 0 && SUBSTITUTION_OPENERS.has(next.before) ? next.text : null;
|
|
5683
|
+
};
|
|
5246
5684
|
var roughSegmentsOf = (command) => {
|
|
5247
5685
|
const { text: text3, bodies } = withHeredocBodiesSetAside(commandForReading(command));
|
|
5248
5686
|
const pieces = roughPiecesOf(text3.replace(INPUT_REDIRECTION, ` ${REDIRECTED_INPUT_MARK} `).replace(OUTPUT_REDIRECTION, " "));
|
|
@@ -5251,48 +5689,108 @@ var roughSegmentsOf = (command) => {
|
|
|
5251
5689
|
const heredocCount = occurrencesOf(piece.text, HEREDOC_MARK);
|
|
5252
5690
|
const heredocs = bodies.slice(heredocsSeen, heredocsSeen + heredocCount);
|
|
5253
5691
|
heredocsSeen += heredocCount;
|
|
5692
|
+
const substitution = substitutionFedTo(pieces, index);
|
|
5254
5693
|
return {
|
|
5255
5694
|
invocation: invocationOfRoughPiece(piece.text),
|
|
5256
5695
|
readsInput: piece.text.includes(REDIRECTED_INPUT_MARK) || heredocCount > 0 || piece.before === PIPE3,
|
|
5257
5696
|
readsAPipe: piece.before === PIPE3,
|
|
5258
|
-
feedsASubstitution:
|
|
5697
|
+
feedsASubstitution: substitution !== null,
|
|
5698
|
+
substitution,
|
|
5699
|
+
evalRunsOneEnvironmentSetup: evalRunsOneEnvironmentSetup(pieces, index),
|
|
5259
5700
|
heredocs
|
|
5260
5701
|
};
|
|
5261
5702
|
});
|
|
5262
5703
|
};
|
|
5263
|
-
var
|
|
5704
|
+
var ENVIRONMENT_SETUP_COMMANDS = [
|
|
5705
|
+
String.raw`fnm\s+env`,
|
|
5706
|
+
String.raw`brew\s+shellenv`,
|
|
5707
|
+
String.raw`(?:py|rb|nod|go|j)env\s+(?:virtualenv-)?init`,
|
|
5708
|
+
String.raw`direnv\s+(?:export|hook)`,
|
|
5709
|
+
"ssh-agent",
|
|
5710
|
+
String.raw`mise\s+(?:activate|env)`,
|
|
5711
|
+
String.raw`rtx\s+activate`,
|
|
5712
|
+
String.raw`zoxide\s+init`,
|
|
5713
|
+
String.raw`starship\s+init`,
|
|
5714
|
+
String.raw`conda\s+shell\.\w+\s+hook`,
|
|
5715
|
+
String.raw`minikube\s+docker-env`,
|
|
5716
|
+
String.raw`docker-machine\s+env`,
|
|
5717
|
+
String.raw`opam\s+env`,
|
|
5718
|
+
String.raw`aws\s+configure\s+export-credentials`,
|
|
5719
|
+
String.raw`poetry\s+env\s+activate`,
|
|
5720
|
+
"dircolors",
|
|
5721
|
+
String.raw`uv\s+generate-shell-completion`,
|
|
5722
|
+
String.raw`fzf\s+--(?:zsh|bash)`,
|
|
5723
|
+
String.raw`thefuck\s+--alias`,
|
|
5724
|
+
String.raw`luarocks\s+path`,
|
|
5725
|
+
String.raw`op\s+signin`,
|
|
5726
|
+
String.raw`(?:gh|kubectl|helm|npm|pnpm|rustup|deno|bun)\s+completion`,
|
|
5727
|
+
String.raw`(?:micro)?mamba\s+shell\s+hook`,
|
|
5728
|
+
"path_helper"
|
|
5729
|
+
];
|
|
5730
|
+
var SETS_UP_THE_ENVIRONMENT = new RegExp(
|
|
5731
|
+
String.raw`^\s*(?:[^\s()$\x60"';|&]*/)?(?:${ENVIRONMENT_SETUP_COMMANDS.join("|")})(?:\s[^()$\x60"';|&]*)?$`
|
|
5732
|
+
);
|
|
5733
|
+
var EVAL_BEFORE_ITS_ARGUMENT = /^\s*eval\s+["']?$/;
|
|
5734
|
+
var EVAL_AFTER_ITS_ARGUMENT = /^["']?\s*$/;
|
|
5735
|
+
var SUBSTITUTION_CLOSERS = /* @__PURE__ */ new Set([")", "`"]);
|
|
5736
|
+
var WHAT_MAY_FOLLOW_AN_EVAL = /* @__PURE__ */ new Set(["&&", "||", ";", "\n", "|", "&", ")", "}"]);
|
|
5737
|
+
var evalRunsOneEnvironmentSetup = (pieces, index) => {
|
|
5738
|
+
const opening = pieces[index];
|
|
5739
|
+
const substitution = pieces[index + 1];
|
|
5740
|
+
const closing = pieces[index + 2];
|
|
5741
|
+
const next = pieces[index + 3];
|
|
5742
|
+
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));
|
|
5743
|
+
};
|
|
5744
|
+
var evalRunsHiddenCode = (segment, innermost) => segment.substitution !== null && basenameOf(innermost.program?.text ?? "") === EVAL && !segment.evalRunsOneEnvironmentSetup;
|
|
5745
|
+
var roughSegmentHasAVisibleConsequence = (toolName, segment, producesHiddenCode, depth, line) => {
|
|
5264
5746
|
const innermost = innermostInvocation(segment.invocation);
|
|
5265
5747
|
const runsAHeredocScript = innermost.program !== void 0 && POSIX_SHELL_PROGRAMS.has(basenameOf(innermost.program.text));
|
|
5266
|
-
return invocationHasAVisibleConsequence(toolName, segment.invocation, depth) || sqlClientSyntaxOf(innermost) !== void 0 && (segment.readsInput || segment.feedsASubstitution) || segment.readsAPipe &&
|
|
5748
|
+
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));
|
|
5267
5749
|
};
|
|
5268
|
-
var
|
|
5750
|
+
var producesCodeTheLineCannotSee = (line) => line === "permissions_off" ? producesCodeTheCommandDoesNotShow : fetches;
|
|
5751
|
+
var roughReadingHasAVisibleConsequence = (toolName, command, depth, line) => {
|
|
5269
5752
|
const segments = roughSegmentsOf(command);
|
|
5270
5753
|
const invocations = segments.map((segment) => segment.invocation);
|
|
5271
|
-
const
|
|
5272
|
-
return segments.some((segment) => roughSegmentHasAVisibleConsequence(toolName, segment,
|
|
5754
|
+
const producesHiddenCode = invocations.some(producesCodeTheLineCannotSee(line));
|
|
5755
|
+
return segments.some((segment) => roughSegmentHasAVisibleConsequence(toolName, segment, producesHiddenCode, depth, line)) || runsADownloadedScript(invocations) || line === "permissions_off" && runsInterpreterCodeThatNeedsAPerson(command, invocations, depth);
|
|
5273
5756
|
};
|
|
5274
|
-
var
|
|
5757
|
+
var commandHidesWhatItWritesOrRuns = (command, readable) => RUNS_DECODED_CODE.test(readable) || redirectsIntoAFileThatNeedsAPerson(command);
|
|
5758
|
+
var commandHasAVisibleConsequenceAt = (toolName, command, depth, line) => {
|
|
5275
5759
|
if (toolName === "Bash" && isSafeReadOnlyCommand(command)) return false;
|
|
5276
5760
|
const readable = withHeredocSubstitutionsAsQuotedText(command);
|
|
5277
5761
|
if (classifyDecisionRisk(toolName, readable) === "destructive" || RUNS_FETCHED_CODE.test(readable) || REDIRECTS_INTO_A_SECRET_FILE.test(readable)) return true;
|
|
5762
|
+
if (line === "permissions_off" && commandHidesWhatItWritesOrRuns(command, readable)) return true;
|
|
5278
5763
|
const segments = readableCommandSegments(command);
|
|
5279
|
-
if (segments === null) return roughReadingHasAVisibleConsequence(toolName, command, depth);
|
|
5764
|
+
if (segments === null) return roughReadingHasAVisibleConsequence(toolName, command, depth, line);
|
|
5280
5765
|
const invocations = segments.map((segment) => invocationOf(withoutShellGrouping(segment)));
|
|
5281
|
-
return invocations.some((invocation) => invocationHasAVisibleConsequence(toolName, invocation, depth)) || pipesIntoASqlClient(command) ||
|
|
5766
|
+
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);
|
|
5767
|
+
};
|
|
5768
|
+
var REDIRECTION_OPERATOR_CHARACTER = /[<>]/;
|
|
5769
|
+
var redirectsIntoAFileThatNeedsAPerson = (command) => {
|
|
5770
|
+
if (!REDIRECTION_OPERATOR_CHARACTER.test(command)) return false;
|
|
5771
|
+
const text3 = withHeredocBodiesSetAside(commandForReading(command)).text;
|
|
5772
|
+
const visible = shellVisibleText(text3);
|
|
5773
|
+
return [...text3.matchAll(OUTPUT_REDIRECTION)].some((redirection) => {
|
|
5774
|
+
const operator = (redirection.index ?? 0) + redirection[0].search(REDIRECTION_OPERATOR_CHARACTER);
|
|
5775
|
+
return (visible === null || REDIRECTION_OPERATOR_CHARACTER.test(visible.charAt(operator))) && pathNeedsAPersonToChange((redirection[1] ?? "").replace(QUOTE_CHARACTERS, ""));
|
|
5776
|
+
});
|
|
5282
5777
|
};
|
|
5283
5778
|
var posixCommandOf = (words) => words.map(asOneShellWord).join(" ");
|
|
5284
|
-
var
|
|
5779
|
+
var namesASecretPowerShellPath = (path) => SECRET_FILE_NAME.test(fileNameOf(path));
|
|
5780
|
+
var posixShellJudgeFor = (toolName, line = "standing_allow") => ({
|
|
5285
5781
|
namesADestructiveAction: (text3) => classifyDecisionRisk(toolName, text3) === "destructive",
|
|
5286
|
-
invocationShowsAConsequence: (invocation) => invocationHasAVisibleConsequence(SHELL_TOOL, invocation, 0),
|
|
5287
|
-
commandShowsAConsequence: (words) => commandHasAVisibleConsequenceAt(SHELL_TOOL, posixCommandOf(words), 1),
|
|
5782
|
+
invocationShowsAConsequence: (invocation) => invocationHasAVisibleConsequence(SHELL_TOOL, invocation, 0, line),
|
|
5783
|
+
commandShowsAConsequence: (words) => commandHasAVisibleConsequenceAt(SHELL_TOOL, posixCommandOf(words), 1, line),
|
|
5288
5784
|
onlyReads: (words) => isSafeReadOnlyCommand(posixCommandOf(words)),
|
|
5289
5785
|
fetches,
|
|
5290
5786
|
runsWhatItReads,
|
|
5291
5787
|
runsScripts,
|
|
5292
|
-
|
|
5788
|
+
namesAFileThatNeedsAPerson: line === "permissions_off" ? pathNeedsAPersonToChange : namesASecretPowerShellPath
|
|
5293
5789
|
});
|
|
5294
5790
|
var commandIsDestructive = (toolName, command) => shellDialectOf(toolName) === "powershell" ? powerShellCommandIsDestructive(command, posixShellJudgeFor(toolName)) : readingsThatCanAct(command).some((reading) => classifyDecisionRisk(toolNameForAPosixReading(toolName), reading) === "destructive");
|
|
5295
|
-
var
|
|
5791
|
+
var commandHasAConsequenceOnTheLine = (toolName, command, line) => shellDialectOf(toolName) === "powershell" ? powerShellCommandHasAVisibleConsequence(command, posixShellJudgeFor(toolName, line)) : commandHasAVisibleConsequenceAt(toolNameForAPosixReading(toolName), command, 0, line);
|
|
5792
|
+
var commandHasAVisibleConsequence = (toolName, command) => commandHasAConsequenceOnTheLine(toolName, command, "standing_allow");
|
|
5793
|
+
var commandHasAConsequenceWithPermissionsOff = (toolName, command) => commandHasAConsequenceOnTheLine(toolName, command, "permissions_off");
|
|
5296
5794
|
var MAX_SPELLING_DEPTH = 3;
|
|
5297
5795
|
var GIT_GLOBAL_OPTIONS_WITH_A_VALUE = /* @__PURE__ */ new Set([
|
|
5298
5796
|
"-C",
|
|
@@ -6569,6 +7067,12 @@ var strictestScopeVerdict = (scope, paths) => {
|
|
|
6569
7067
|
};
|
|
6570
7068
|
var survivesDegraded = (config, toolName, toolInputs, cwd, repoKey, sessionId) => toolInputs.length === 1 && resolveAutoResolveOrigin(config, toolName, toolInputs[0], cwd, repoKey, sessionId) === "safe_readonly";
|
|
6571
7069
|
var FULL_DEFER_MODES = /* @__PURE__ */ new Set(["plan", "auto", "dontAsk"]);
|
|
7070
|
+
var BYPASS_PERMISSION_MODE = "bypassPermissions";
|
|
7071
|
+
var BYPASS_STOPS = ["consequences", "nothing"];
|
|
7072
|
+
var DEFAULT_BYPASS_STOPS = "consequences";
|
|
7073
|
+
var isBypassStops = (value) => typeof value === "string" && BYPASS_STOPS.includes(value);
|
|
7074
|
+
var bypassStopsOf = (config) => isBypassStops(config.bypassStops) ? config.bypassStops : DEFAULT_BYPASS_STOPS;
|
|
7075
|
+
var isBypassPermissionMode = (permissionMode) => permissionMode === BYPASS_PERMISSION_MODE;
|
|
6572
7076
|
var FILE_EDIT_TOOLS = /* @__PURE__ */ new Set([
|
|
6573
7077
|
"Write",
|
|
6574
7078
|
"Edit",
|
|
@@ -6580,7 +7084,7 @@ var shouldDeferToNativeMode = (permissionMode, toolName, options = {}) => {
|
|
|
6580
7084
|
if (typeof permissionMode !== "string") return false;
|
|
6581
7085
|
if (FULL_DEFER_MODES.has(permissionMode)) return true;
|
|
6582
7086
|
if (permissionMode === "acceptEdits" && FILE_EDIT_TOOLS.has(toolName)) return true;
|
|
6583
|
-
if (permissionMode
|
|
7087
|
+
if (isBypassPermissionMode(permissionMode)) return options.deferBypass === true;
|
|
6584
7088
|
return false;
|
|
6585
7089
|
};
|
|
6586
7090
|
var AGENT_QUESTION_TOOL = "AskUserQuestion";
|
|
@@ -6660,6 +7164,22 @@ var PRETOOLUSE_GATED_TOOLS = [
|
|
|
6660
7164
|
var PRETOOLUSE_HANDLED_TOOLS = /* @__PURE__ */ new Set([...PRETOOLUSE_GATED_TOOLS, ...ASKED_IN_EVERY_MODE_TOOLS]);
|
|
6661
7165
|
var isPermissionRequestOwnedByPreToolUse = (toolName, permissionMode, defers = shouldDeferToNativeMode) => PRETOOLUSE_HANDLED_TOOLS.has(toolName) && (isAskedInEveryMode(toolName) || !defers(permissionMode, toolName));
|
|
6662
7166
|
var CLAUDE_PRETOOLUSE_MATCHER = [...PRETOOLUSE_HANDLED_TOOLS].join("|");
|
|
7167
|
+
var LINE_BREAK = /[\r\n]/;
|
|
7168
|
+
var bypassModeCovers = (toolName, toolInput) => {
|
|
7169
|
+
const arg = extractPolicyArg(toolName, toolInput);
|
|
7170
|
+
if (SHELL_DIALECT_BY_TOOL.has(toolName)) {
|
|
7171
|
+
return arg !== void 0 && !commandIsDestructive(toolName, arg) && !commandHasAConsequenceWithPermissionsOff(toolName, arg);
|
|
7172
|
+
}
|
|
7173
|
+
if (FILE_EDIT_TOOLS.has(toolName)) return arg !== void 0 && !LINE_BREAK.test(arg) && !fileEditNeedsAPersonWithPermissionsOff(toolName, arg);
|
|
7174
|
+
return mcpToolOnlyReads(toolName) && mcpToolInputOnlyReads(toolName, toolInput);
|
|
7175
|
+
};
|
|
7176
|
+
var aChosenRuleGovernsInEitherRepository = (input, counts = everyRule) => aChosenRuleGoverns(input, counts) || input.sharedRepoKey !== void 0 && input.sharedRepoKey !== input.repoKey && aChosenRuleGoverns({ ...input, repoKey: input.sharedRepoKey }, counts);
|
|
7177
|
+
var ruleAsksOrRefuses = (rule) => !isAutoApprove(rule);
|
|
7178
|
+
var bypassModeCoversEveryInput = (input) => input.deletesFiles !== true && input.toolInputs.every((toolInput) => bypassModeCovers(input.toolName, toolInput)) && !aChosenRuleGovernsInEitherRepository(input);
|
|
7179
|
+
var bypassModeApplies = (input) => isBypassPermissionMode(input.permissionMode) && !isModeStateDegraded(input.modeState) && noModeOverrideIsActive(input) && input.toolInputs.length > 0;
|
|
7180
|
+
var bypassModeAllows = (input) => bypassModeApplies(input) && (bypassStopsOf(input.config) === "nothing" ? !aChosenRuleGovernsInEitherRepository(input, ruleAsksOrRefuses) : bypassModeCoversEveryInput(input));
|
|
7181
|
+
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.";
|
|
7182
|
+
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;
|
|
6663
7183
|
var resolveGate = (input) => {
|
|
6664
7184
|
const { modeState, config, toolName, toolInputs, cwd, sessionId } = input;
|
|
6665
7185
|
const repoKey = input.sharedRepoKey ?? input.repoKey;
|
|
@@ -6677,8 +7197,9 @@ var resolveGate = (input) => {
|
|
|
6677
7197
|
}
|
|
6678
7198
|
const policy = resolvePolicyAcross(config, toolName, modeState.mode, toolInputs, cwd, repoKey, sessionId);
|
|
6679
7199
|
const verdict = verdictForPolicy(policy);
|
|
6680
|
-
const autoApproves = verdict === "allow";
|
|
6681
7200
|
const autoDenies = verdict === "deny";
|
|
7201
|
+
const allowedByBypassMode = !autoDenies && verdict !== "allow" && bypassModeAllows(input);
|
|
7202
|
+
const autoApproves = verdict === "allow" || allowedByBypassMode;
|
|
6682
7203
|
if (autoDenies) return { kind: "deny", policy, reason: `Denied by policy for ${policy.tool}` };
|
|
6683
7204
|
if (isAskedInEveryMode(toolName)) return { kind: "gate", policy };
|
|
6684
7205
|
if (isModeStateDegraded(modeState)) {
|
|
@@ -6692,7 +7213,7 @@ var resolveGate = (input) => {
|
|
|
6692
7213
|
if (!scopeRequiresHuman(scopeVerdict)) {
|
|
6693
7214
|
return {
|
|
6694
7215
|
kind: "allow",
|
|
6695
|
-
policy,
|
|
7216
|
+
policy: allowedByBypassMode ? autoApprove(policy.tool) : policy,
|
|
6696
7217
|
source: toolInputs.length === 1 && resolveAutoResolveOrigin(config, toolName, toolInputs[0], cwd, repoKey, sessionId) === "safe_readonly" ? "allowlist" : "policy"
|
|
6697
7218
|
};
|
|
6698
7219
|
}
|
|
@@ -6718,7 +7239,7 @@ var SCOPE_BATCH_REASON = "This patch exceeds the agreed scope. Split it into sin
|
|
|
6718
7239
|
var UNREADABLE_CALL_REASON = "Pushary could not read every target of this call. Use a supported command or a single-file edit.";
|
|
6719
7240
|
var unapprovedScopeReason = (scopeReason) => `${scopeReason}. Nobody approved this path, so the change was refused.`;
|
|
6720
7241
|
var NO_RESPONSE_REASON = "No response within timeout";
|
|
6721
|
-
var codexRaisesItsOwnPrompts = (permissionMode) => permissionMode
|
|
7242
|
+
var codexRaisesItsOwnPrompts = (permissionMode) => !isBypassPermissionMode(permissionMode);
|
|
6722
7243
|
var codexHasNoPromptOfItsOwn = (scopeReason, permissionMode) => scopeReason !== void 0 || !codexRaisesItsOwnPrompts(permissionMode);
|
|
6723
7244
|
var CODEX_ASK_PASSES = { kind: "pass" };
|
|
6724
7245
|
var codexAskUnanswered = (ask) => ({ kind: "deny", reason: unansweredRefusalReason(ask.paused) });
|
|
@@ -6743,9 +7264,9 @@ var runsACommandThatNeedsAPerson = ({ toolName, toolInputs }) => SHELL_DIALECT_B
|
|
|
6743
7264
|
const command = extractPolicyArg(toolName, toolInput);
|
|
6744
7265
|
return command !== void 0 && (commandNeedsAPerson(toolName, command) || commandWritesThroughARemoteApi(command));
|
|
6745
7266
|
});
|
|
6746
|
-
var CI_WORKFLOW_FILE = /(?:^|\/)\.github\/workflows\/[^/]+$/i;
|
|
6747
7267
|
var namesASecretOrWorkflowFile = (path) => SECRET_FILE_NAME.test(basenameOf(path)) || CI_WORKFLOW_FILE.test(normalizeSeparators(path));
|
|
6748
7268
|
var fileEditNeedsAPerson = (toolName, path) => FILE_EDIT_TOOLS.has(toolName) && namesASecretOrWorkflowFile(path);
|
|
7269
|
+
var fileEditNeedsAPersonWithPermissionsOff = (toolName, path) => FILE_EDIT_TOOLS.has(toolName) && pathNeedsAPersonToChange(path);
|
|
6749
7270
|
var editsAFileThatNeedsAPerson = ({ toolName, toolInputs }) => toolInputs.some((toolInput) => {
|
|
6750
7271
|
const path = extractPolicyArg(toolName, toolInput);
|
|
6751
7272
|
return path !== void 0 && fileEditNeedsAPerson(toolName, path);
|
|
@@ -6814,14 +7335,16 @@ var approvalRoutesOf = (config) => {
|
|
|
6814
7335
|
const routes = config.approvalRoutes ?? [];
|
|
6815
7336
|
return Array.isArray(routes) && routes.every(isApprovalRoutePattern) ? routes : null;
|
|
6816
7337
|
};
|
|
6817
|
-
var
|
|
7338
|
+
var everyRule = () => true;
|
|
7339
|
+
var aChosenRuleGoverns = (input, counts = everyRule) => {
|
|
6818
7340
|
const chosen = input.config.policies.filter((policy) => !isDefaultRule(policy));
|
|
6819
7341
|
const routes = approvalRoutesOf(input.config);
|
|
6820
7342
|
if (routes === null) return true;
|
|
6821
7343
|
return input.toolInputs.some((toolInput) => {
|
|
6822
7344
|
const args = policyArgForms(input.toolName, toolInput, input.cwd);
|
|
6823
7345
|
const reading = policyReadingOf(chosen, input.toolName, args);
|
|
6824
|
-
|
|
7346
|
+
const governing = governingRuleForReading(chosen, input.toolName, args, reading, input.repoKey, input.sessionId);
|
|
7347
|
+
return governing !== void 0 && counts(governing.policy) || findBestRoute(routes, input.toolName, args, input.repoKey) !== void 0;
|
|
6825
7348
|
});
|
|
6826
7349
|
};
|
|
6827
7350
|
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);
|
|
@@ -7360,6 +7883,7 @@ export {
|
|
|
7360
7883
|
PRETOOLUSE_HANDLED_TOOLS,
|
|
7361
7884
|
isPermissionRequestOwnedByPreToolUse,
|
|
7362
7885
|
CLAUDE_PRETOOLUSE_MATCHER,
|
|
7886
|
+
permissionsOffAskReason,
|
|
7363
7887
|
resolveGate,
|
|
7364
7888
|
editGoesToTheAgentsPrompt,
|
|
7365
7889
|
SCOPE_BATCH_REASON,
|