@pushary/agent-hooks 1.9.70 → 1.9.72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/{api-KUJYE5YZ.js → api-K4UGZNOE.js} +10 -10
  3. package/dist/bin/pushary-bell-hook.js +25 -25
  4. package/dist/bin/pushary-bell.js +10 -10
  5. package/dist/bin/pushary-claude.js +202 -67
  6. package/dist/bin/pushary-clean.js +33 -33
  7. package/dist/bin/pushary-codex-bridge.js +23 -21
  8. package/dist/bin/pushary-codex-hook.js +30 -30
  9. package/dist/bin/pushary-codex-session.js +8 -8
  10. package/dist/bin/pushary-codex.js +13 -13
  11. package/dist/bin/pushary-connect.js +26 -26
  12. package/dist/bin/pushary-cowork.js +5 -5
  13. package/dist/bin/pushary-daemon.js +38 -38
  14. package/dist/bin/pushary-disconnect.js +25 -25
  15. package/dist/bin/pushary-doctor.js +41 -41
  16. package/dist/bin/pushary-elicitation-hook.js +25 -25
  17. package/dist/bin/pushary-gemini-bridge.js +45 -48
  18. package/dist/bin/pushary-gemini-hook.js +27 -27
  19. package/dist/bin/pushary-hook.js +29 -29
  20. package/dist/bin/pushary-login.js +20 -20
  21. package/dist/bin/pushary-logout.js +24 -24
  22. package/dist/bin/pushary-mcp.js +11 -11
  23. package/dist/bin/pushary-mode.js +15 -15
  24. package/dist/bin/pushary-notification-hook.js +24 -24
  25. package/dist/bin/pushary-opencode-hook.js +26 -26
  26. package/dist/bin/pushary-permission-denied-hook.js +29 -29
  27. package/dist/bin/pushary-permission-hook.js +29 -29
  28. package/dist/bin/pushary-post-hook.js +24 -24
  29. package/dist/bin/pushary-prompt-hook.js +24 -24
  30. package/dist/bin/pushary-session-end-hook.js +26 -26
  31. package/dist/bin/pushary-session-start-hook.js +34 -34
  32. package/dist/bin/pushary-setup.js +47 -46
  33. package/dist/bin/pushary-stats.js +5 -5
  34. package/dist/bin/pushary-status.js +31 -31
  35. package/dist/bin/pushary-stop-hook.js +24 -24
  36. package/dist/bin/pushary-stopfailure-hook.js +24 -24
  37. package/dist/bin/pushary-suggestions.js +15 -15
  38. package/dist/bin/pushary-transcript-register.js +16 -16
  39. package/dist/bin/pushary-transcripts.js +20 -19
  40. package/dist/bin/pushary-upgrade.js +39 -39
  41. package/dist/bin/pushary-wait.js +15 -15
  42. package/dist/bin/pushary.js +7 -7
  43. package/dist/{chunk-PK6WI4HH.js → chunk-2BVLEMGX.js} +5 -5
  44. package/dist/{chunk-LWFSXSRG.js → chunk-2KDTIUC7.js} +1 -1
  45. package/dist/{chunk-72ILLFCY.js → chunk-37OD7FUI.js} +6 -6
  46. package/dist/{chunk-AVKD5QS4.js → chunk-3S5X7VZJ.js} +5 -5
  47. package/dist/{chunk-AQA63ZWO.js → chunk-4TRA3GDE.js} +3 -3
  48. package/dist/{chunk-AUYMNTUX.js → chunk-4U7F7VMC.js} +4 -4
  49. package/dist/{chunk-OYFGZARB.js → chunk-4W7CKRWR.js} +3 -3
  50. package/dist/{chunk-SKTZKAGH.js → chunk-4Y7EI5W5.js} +1 -1
  51. package/dist/{chunk-A7GTEZGH.js → chunk-5KQN7AIL.js} +10 -10
  52. package/dist/{chunk-XZKSUJ55.js → chunk-5KS3E3T5.js} +1 -1
  53. package/dist/{chunk-RQOT6QL3.js → chunk-5XKJH5GD.js} +489 -16
  54. package/dist/{chunk-FZ2SHXUE.js → chunk-5XYYBB5Z.js} +2 -2
  55. package/dist/{chunk-C4EDAHXI.js → chunk-6HTAOF6H.js} +1 -1
  56. package/dist/{chunk-GZHQQP7J.js → chunk-6YZ72YP3.js} +4 -4
  57. package/dist/{chunk-X2MTVD4W.js → chunk-7KMLITXH.js} +1 -1
  58. package/dist/{chunk-32OSSYGZ.js → chunk-BMVWGPYB.js} +1 -1
  59. package/dist/{chunk-NWN6GGJL.js → chunk-CAUNUTYE.js} +2 -2
  60. package/dist/{chunk-SSJDAX4E.js → chunk-CR3HOHJC.js} +5 -5
  61. package/dist/{chunk-7XS44DQX.js → chunk-D6COE26P.js} +4 -4
  62. package/dist/{chunk-VHMZPN3N.js → chunk-DNCEZWRC.js} +1 -1
  63. package/dist/{chunk-FD6KOIT2.js → chunk-DU7L7R4A.js} +5 -5
  64. package/dist/{chunk-VIQ5OS5E.js → chunk-E56VJY23.js} +4 -4
  65. package/dist/{chunk-HZNZJTGH.js → chunk-EEFFP64A.js} +12 -11
  66. package/dist/{chunk-EAJUFO7Q.js → chunk-EEQG7VF2.js} +4 -4
  67. package/dist/{chunk-WOJW23ZD.js → chunk-EPARIXRC.js} +7 -7
  68. package/dist/{chunk-JQMERLQS.js → chunk-EW7CZHYP.js} +2 -2
  69. package/dist/{chunk-KVXX5M5A.js → chunk-GNDPZBG3.js} +6 -6
  70. package/dist/{chunk-OXOYS3UG.js → chunk-GUJBS6TK.js} +3 -3
  71. package/dist/{chunk-2LI3DF7Q.js → chunk-HIHA3GOR.js} +2 -2
  72. package/dist/{chunk-KHOWMC57.js → chunk-IBHZ3JFE.js} +3 -3
  73. package/dist/{chunk-GMHQYX3D.js → chunk-ILWEGI4H.js} +1 -1
  74. package/dist/{chunk-DJPNVVJQ.js → chunk-KFGRDWAW.js} +4 -4
  75. package/dist/{chunk-7YJSDXLM.js → chunk-KYEZFN6K.js} +1 -1
  76. package/dist/chunk-L2FQBHIR.js +74 -0
  77. package/dist/{chunk-2REVIFLS.js → chunk-L3S2ZTQZ.js} +2 -2
  78. package/dist/{chunk-4BXI6WJI.js → chunk-L6F62LKX.js} +3 -3
  79. package/dist/{chunk-NFWZVY25.js → chunk-LCBZLTHW.js} +4 -4
  80. package/dist/{chunk-YSOZVBFW.js → chunk-LFBQ55OO.js} +1 -1
  81. package/dist/{chunk-NSR6IFA6.js → chunk-LISVMDVS.js} +3 -3
  82. package/dist/{chunk-HGXWC4WT.js → chunk-LKXOSW2L.js} +4 -4
  83. package/dist/{chunk-UC2J5RR4.js → chunk-LT2DOCFI.js} +1 -1
  84. package/dist/{chunk-KLDUATG5.js → chunk-MWR25RQZ.js} +3 -3
  85. package/dist/{chunk-274CV7IW.js → chunk-N4NSX5MB.js} +2 -2
  86. package/dist/chunk-N5P2FLOJ.js +82 -0
  87. package/dist/{chunk-CPYVVEJP.js → chunk-N7A44RIA.js} +36 -35
  88. package/dist/{chunk-77L2TNJW.js → chunk-NVM4S37G.js} +1 -1
  89. package/dist/{chunk-7FWZNWIO.js → chunk-OFTTOPTD.js} +6 -6
  90. package/dist/{chunk-VKZ3RJ5U.js → chunk-OGGUOTIK.js} +1 -1
  91. package/dist/{chunk-7CW63ZK3.js → chunk-PIO66HPG.js} +3 -3
  92. package/dist/{chunk-D5G2HSQ6.js → chunk-PWVQALO2.js} +2 -2
  93. package/dist/{chunk-5UIA5GLL.js → chunk-PZV27E4J.js} +6 -6
  94. package/dist/{chunk-TXRV7AOA.js → chunk-QDISUNK3.js} +6 -6
  95. package/dist/{chunk-XLKO2XEG.js → chunk-QFF3QVIV.js} +2 -2
  96. package/dist/{chunk-5LQCADHK.js → chunk-QQ7VXRIN.js} +5 -5
  97. package/dist/{chunk-N2FDORN6.js → chunk-R4B5AVFC.js} +3 -3
  98. package/dist/{chunk-N2WAXSJY.js → chunk-RO5G3OEN.js} +10 -11
  99. package/dist/{chunk-QE22XDUK.js → chunk-RRW2LVVR.js} +2 -2
  100. package/dist/{chunk-PIGBU7D3.js → chunk-RXR44U2J.js} +5 -5
  101. package/dist/{chunk-YAA6MT6O.js → chunk-S6BD346V.js} +3 -3
  102. package/dist/{chunk-QZPRCMPV.js → chunk-SAXNYDPS.js} +1 -1
  103. package/dist/{chunk-ZK5WYAMI.js → chunk-SMVTNLXU.js} +1 -1
  104. package/dist/{chunk-CJ3W7XRU.js → chunk-TM4JH7YR.js} +1 -1
  105. package/dist/{chunk-UXN73YAE.js → chunk-UTVNXB6U.js} +3 -3
  106. package/dist/{chunk-FULXDMAP.js → chunk-VFF7TP5B.js} +3 -3
  107. package/dist/{chunk-DTENGECG.js → chunk-VZG76CWC.js} +1 -1
  108. package/dist/{chunk-54O76CMR.js → chunk-WHM3OVBA.js} +2 -2
  109. package/dist/{chunk-BRWU4NT4.js → chunk-XGGAZJWJ.js} +6 -6
  110. package/dist/{chunk-3HWDWR42.js → chunk-XHVHGDMB.js} +13 -13
  111. package/dist/{chunk-KEPESIIR.js → chunk-XMSDA5WA.js} +1 -70
  112. package/dist/{chunk-JWRDCANS.js → chunk-YDSOTAZ6.js} +3 -3
  113. package/dist/{chunk-METUT7V4.js → chunk-ZWCKS65X.js} +2 -2
  114. package/dist/{codex-app-cards-switch-GBTS3OQW.js → codex-app-cards-switch-PWLWIWKG.js} +11 -11
  115. package/dist/{codex-desktop-launch-S6OULJDZ.js → codex-desktop-launch-S3PDGLAY.js} +1 -1
  116. package/dist/{codex-session-launch-K2KE3AD5.js → codex-session-launch-PY5IMFJU.js} +20 -18
  117. package/dist/{config-OBGYURFX.js → config-SWV4YOP3.js} +3 -3
  118. package/dist/{global-upgrade-ZMWRPO5G.js → global-upgrade-DI3LGOQP.js} +10 -10
  119. package/dist/{identity-OLRKDYFR.js → identity-AY35DGAO.js} +4 -4
  120. package/dist/{live-capabilities-LZECCGFQ.js → live-capabilities-IH3EGKL3.js} +5 -5
  121. package/dist/{paths-YUF2TFTA.js → paths-I4Q77ULZ.js} +3 -3
  122. package/dist/{reapply-TRR4XB6N.js → reapply-OAV4IAG3.js} +27 -27
  123. package/dist/src/index.js +28 -28
  124. package/dist/{upgrade-lock-MSBKXUKM.js → upgrade-lock-7U5BOK6V.js} +4 -4
  125. package/dist/{usage-KX2HN47E.js → usage-NTER4GHT.js} +3 -3
  126. package/package.json +2 -1
@@ -1025,6 +1025,40 @@ var toolsCoveredByGateEntry = (coverage, matcher) => {
1025
1025
  var toolMatches = (match, toolName) => match.kind === "named" ? match.tools.includes(toolName) : toolName.startsWith(match.prefix);
1026
1026
  var cursorGateOwnsToolCall = (registration, toolName) => typeof toolName === "string" && registration.some((match) => toolMatches(match, toolName));
1027
1027
 
1028
+ // ../contracts/src/conversation-text.ts
1029
+ var INTERNAL_ENVELOPE = /(^|\n) {0,3}(?:<(total_tokens|task-notification)>[\s\S]*?(?:<\/\2>|$)[\t ]*)+/g;
1030
+ var INCOMPLETE_ENVELOPE = /(^|\n) {0,3}<(?:total_tokens|task-notification)$/g;
1031
+ var SUGGESTION_REQUEST = /^This is an app-generated request for a suggested next user(?: message| prompt)/;
1032
+ var visibleProse = (text2) => text2.replace(INTERNAL_ENVELOPE, "$1").replace(INCOMPLETE_ENVELOPE, "$1");
1033
+ function conversationText(text2) {
1034
+ if (SUGGESTION_REQUEST.test(text2.trimStart())) return "";
1035
+ const output = [];
1036
+ let prose = [];
1037
+ let fence = null;
1038
+ for (const line of text2.split("\n")) {
1039
+ const marker = /^ {0,3}(`{3,}|~{3,})/.exec(line)?.[1];
1040
+ if (fence) {
1041
+ output.push(line);
1042
+ if (marker?.[0] === fence.marker && marker.length >= fence.length) fence = null;
1043
+ } else if (marker) {
1044
+ output.push(visibleProse(prose.join("\n")), line);
1045
+ prose = [];
1046
+ fence = { marker: marker.charAt(0), length: marker.length };
1047
+ } else {
1048
+ prose.push(line);
1049
+ }
1050
+ }
1051
+ output.push(visibleProse(prose.join("\n")));
1052
+ return output.join("\n").trim();
1053
+ }
1054
+ function extractMessageText(content) {
1055
+ if (typeof content === "string") return content;
1056
+ if (!Array.isArray(content)) return "";
1057
+ return content.flatMap(
1058
+ (block) => block !== null && typeof block === "object" && "type" in block && block.type === "text" && "text" in block && typeof block.text === "string" ? [block.text] : []
1059
+ ).join("\n");
1060
+ }
1061
+
1028
1062
  // ../contracts/src/shell-analysis.ts
1029
1063
  var SHELL_WORD_SEPARATOR = /[ \t\n]/;
1030
1064
  var ARITHMETIC_EVALUATING_EXPANSION = /\$[#+=~^]*(?:[A-Za-z_][A-Za-z0-9_]*|[0-9]+|[-?$!@*#])?\[/;
@@ -4073,6 +4107,7 @@ var changesProduction = (invocation) => {
4073
4107
  const words = wordsOfInvocation(invocation);
4074
4108
  return words.some((word, index) => wordSelectsProduction(word, words[index - 1])) && (deployCliChangesSomething(words) || SCHEMA_CHANGE_WORD.test(normalizedInvocation(invocation)));
4075
4109
  };
4110
+ var SQL_WORDS_THAT_CAN_FOLLOW_A_COLUMN = String.raw`(?:from|is|in|and|or|asc|desc|between|like|then|else|end|when|having|union|order\s+by|group\s+by|limit\s+\d+|offset\s+\d+)`;
4076
4111
  var SQL_WRITE_STATEMENT = new RegExp([
4077
4112
  String.raw`\b(?:insert|update|delete|merge|upsert|alter|create|drop|truncate|grant|revoke|copy|vacuum|reindex|rename|attach|detach)\b`,
4078
4113
  String.raw`\breplace\s+into\b`,
@@ -4081,9 +4116,17 @@ var SQL_WRITE_STATEMENT = new RegExp([
4081
4116
  String.raw`\bset\s+(?:global|persist)\b`,
4082
4117
  String.raw`\bkill\s+(?:query|connection|\d)`,
4083
4118
  String.raw`\bcall\b`,
4084
- String.raw`\bexecute\s+immediate\b`,
4119
+ String.raw`\bexec(?:ute)?(?:\s*\(|\s+(?!(?:${SQL_WORDS_THAT_CAN_FOLLOW_A_COLUMN}|as(?!\s+(?:login|user|caller|owner|self)\b))\b)[\w@\["])`,
4120
+ String.raw`(?:^|;|\b(?:then|else|do|loop|declare|as|is)\b)\s*begin\s+(?!(?:transaction|work|isolation|deferred|immediate|exclusive|read\s+(?:only|write)|as|${SQL_WORDS_THAT_CAN_FOLLOW_A_COLUMN})\b)[^\s;,)]`,
4121
+ String.raw`\bset\s+@@(?:global|persist)`,
4122
+ String.raw`\brefresh\s+materialized\b`,
4123
+ String.raw`\bcomment\s+(?:if\s+exists\s+)?on\s+(?:table|foreign\s+table|column|schema|database|catalog|warehouse|function|procedure|routine|procedural\s+language|aggregate|view|materialized\s+view|index|type|role|extension|trigger|event\s+trigger|constraint|sequence|policy|domain|server|foreign\s+data\s+wrapper|large\s+object|tablespace|publication|subscription|macro|collation|conversion|operator|cast|language|rule|statistics|text\s+search|transform|access\s+method)\b`,
4124
+ String.raw`\bexport\s+database\b`,
4125
+ String.raw`\bload_extension\b`,
4126
+ String.raw`\blo_(?:export|import|unlink)\b`,
4127
+ String.raw`\bdblink_exec\b`,
4128
+ String.raw`\bpg_drop_replication_slot\b`,
4085
4129
  String.raw`\bprepare\s+\S+\s+from\b`,
4086
- String.raw`\bselect\b[^;]*\binto\b(?!\s*@)`,
4087
4130
  String.raw`(?:^|;)\s*lock\b`,
4088
4131
  String.raw`(?:^|;)\s*do\b`,
4089
4132
  String.raw`\bpg_terminate_backend\b`,
@@ -4092,9 +4135,17 @@ var SQL_WRITE_STATEMENT = new RegExp([
4092
4135
  String.raw`\.(?:insert|update|delete|replace|remove|drop|rename|create|bulkwrite|findoneand)\w*\s*\(`
4093
4136
  ].join("|"), "i");
4094
4137
  var SQL_READ_PHRASE = /\bshow\s+create\b/gi;
4138
+ var SQL_SELECT = /\bselect\b/i;
4139
+ var SQL_INTO_A_TABLE = /\binto\b(?!\s*@)/i;
4140
+ var SQL_STATEMENT_SEPARATOR = ";";
4141
+ var statementSelectsIntoATable = (statement) => {
4142
+ const select = statement.search(SQL_SELECT);
4143
+ return select !== -1 && SQL_INTO_A_TABLE.test(statement.slice(select));
4144
+ };
4145
+ var selectsIntoATable = (sql) => sql.split(SQL_STATEMENT_SEPARATOR).some(statementSelectsIntoATable);
4095
4146
  var sqlTextWrites = (text2) => {
4096
4147
  const statement = text2.replace(SQL_READ_PHRASE, "");
4097
- return SQL_WRITE_STATEMENT.test(statement) || SQL_CLIENT_FILE_COMMAND.test(statement);
4148
+ return SQL_WRITE_STATEMENT.test(statement) || selectsIntoATable(statement) || SQL_CLIENT_FILE_COMMAND.test(statement);
4098
4149
  };
4099
4150
  var writesThroughSql = (sql, lexicon) => {
4100
4151
  const parsed = sqlOutsideLiterals(sql, lexicon);
@@ -5042,9 +5093,13 @@ var parseMcpToolName = (toolName) => {
5042
5093
  if (split <= 0 || split + 2 >= rest.length) return void 0;
5043
5094
  return { server: rest.slice(0, split), tool: rest.slice(split + 2) };
5044
5095
  };
5096
+ var INVISIBLE_CHARACTERS = /[\u200B-\u200D\u2060\uFEFF]/g;
5097
+ var readableText = (text2) => text2.normalize("NFKC").replace(INVISIBLE_CHARACTERS, "");
5098
+ var ACRONYM_BOUNDARY = /([A-Z]{1,63})([A-Z][a-z])/g;
5045
5099
  var CAMEL_CASE_BOUNDARY = /([a-z0-9])([A-Z])/g;
5046
- var MCP_TOOL_NAME_WORD_SEPARATOR = /[\s_.:-]+/;
5047
- var wordsOfMcpToolName = (toolName) => toolName.replace(CAMEL_CASE_BOUNDARY, "$1 $2").toLowerCase().split(MCP_TOOL_NAME_WORD_SEPARATOR).filter((word) => word.length > 0);
5100
+ var IDENTIFIER_WORD_SEPARATOR = /[^a-z0-9]+/;
5101
+ var wordsOfAnIdentifierAsWritten = (identifier3) => readableText(identifier3).toLowerCase().split(IDENTIFIER_WORD_SEPARATOR).filter((word) => word.length > 0);
5102
+ var wordsOfIdentifier = (identifier3) => readableText(identifier3).replace(ACRONYM_BOUNDARY, "$1 $2").replace(CAMEL_CASE_BOUNDARY, "$1 $2").toLowerCase().split(IDENTIFIER_WORD_SEPARATOR).filter((word) => word.length > 0);
5048
5103
  var MCP_TOOL_WORDS_THAT_MOVE_MONEY = /* @__PURE__ */ new Set([
5049
5104
  "pay",
5050
5105
  "payment",
@@ -5100,11 +5155,6 @@ var MCP_TOOL_WORDS_THAT_REACH_OTHERS = /* @__PURE__ */ new Set([
5100
5155
  "share"
5101
5156
  ]);
5102
5157
  var mcpToolWordNeedsAPerson = (word) => DESTRUCTIVE_SUBCOMMANDS.has(word) || MCP_TOOL_WORDS_THAT_MOVE_MONEY.has(word) || MCP_TOOL_WORDS_THAT_RUN_CODE.has(word) || MCP_TOOL_WORDS_THAT_REACH_OTHERS.has(word);
5103
- var mcpToolNameNeedsAPerson = (toolName) => {
5104
- const words = wordsOfMcpToolName(toolName);
5105
- const phrase = words.join(" ");
5106
- return words.some(mcpToolWordNeedsAPerson) || classifyDecisionRisk(phrase, phrase) !== "standard";
5107
- };
5108
5158
  var MCP_TOOL_VERBS_THAT_ONLY_READ = /* @__PURE__ */ new Set([
5109
5159
  "get",
5110
5160
  "list",
@@ -5121,11 +5171,429 @@ var MCP_TOOL_VERBS_THAT_ONLY_READ = /* @__PURE__ */ new Set([
5121
5171
  "browse",
5122
5172
  "count"
5123
5173
  ]);
5124
- var mcpToolLeadsWithAReadVerb = (toolName) => {
5125
- const tool = parseMcpToolName(toolName)?.tool;
5126
- return tool !== void 0 && MCP_TOOL_VERBS_THAT_ONLY_READ.has(wordsOfMcpToolName(tool)[0] ?? "");
5174
+ var MCP_TOOL_VERBS_THAT_CHANGE = /* @__PURE__ */ new Set([
5175
+ "create",
5176
+ "update",
5177
+ "add",
5178
+ "insert",
5179
+ "upsert",
5180
+ "edit",
5181
+ "modify",
5182
+ "replace",
5183
+ "put",
5184
+ "apply",
5185
+ "approve",
5186
+ "reject",
5187
+ "archive",
5188
+ "assign",
5189
+ "toggle",
5190
+ "enable",
5191
+ "disable",
5192
+ "activate",
5193
+ "deactivate",
5194
+ "save",
5195
+ "submit",
5196
+ "trigger",
5197
+ "invoke",
5198
+ "reply",
5199
+ "forward",
5200
+ "react",
5201
+ "append",
5202
+ "attach",
5203
+ "mute",
5204
+ "unblock",
5205
+ "unlock",
5206
+ "grant",
5207
+ "accept",
5208
+ "decline",
5209
+ "install",
5210
+ "navigate",
5211
+ "click",
5212
+ "fill",
5213
+ "generate",
5214
+ "subscribe",
5215
+ "unsubscribe",
5216
+ "notify",
5217
+ "tweet",
5218
+ "sms",
5219
+ "dm",
5220
+ "sell",
5221
+ "trade",
5222
+ "shutdown",
5223
+ "reboot",
5224
+ "restart",
5225
+ "revert",
5226
+ "rollback",
5227
+ "sign",
5228
+ "authorize",
5229
+ "evaluate",
5230
+ "unpublish",
5231
+ "close",
5232
+ "reopen",
5233
+ "mark",
5234
+ "pin",
5235
+ "unpin",
5236
+ "star",
5237
+ "unstar",
5238
+ "snooze",
5239
+ "copy",
5240
+ "duplicate",
5241
+ "join",
5242
+ "rsvp",
5243
+ "checkout",
5244
+ "vote",
5245
+ "kick",
5246
+ "ban",
5247
+ "unfollow"
5248
+ ]);
5249
+ var MCP_TOOL_NOUNS_THAT_ALSO_ACT = /* @__PURE__ */ new Set(["email", "post", "merge", "push", "run"]);
5250
+ var MCP_TOOL_VERB_MODIFIERS = /* @__PURE__ */ new Set(["batch", "bulk"]);
5251
+ var MCP_TOOL_CLAUSE_JOINERS = /* @__PURE__ */ new Set(["and", "or", "then"]);
5252
+ var MCP_TOOL_WORDS_THAT_NAME_A_SECRET = /* @__PURE__ */ new Set([
5253
+ "password",
5254
+ "passwords",
5255
+ "passcode",
5256
+ "passkey",
5257
+ "passphrase",
5258
+ "secret",
5259
+ "secrets",
5260
+ "credential",
5261
+ "credentials",
5262
+ "token",
5263
+ "tokens",
5264
+ "apikey",
5265
+ "otp",
5266
+ "totp",
5267
+ "cookie",
5268
+ "cookies",
5269
+ "keychain",
5270
+ "vault",
5271
+ "1password",
5272
+ "onepassword",
5273
+ "bitwarden",
5274
+ "lastpass",
5275
+ "dashlane",
5276
+ "keepass",
5277
+ "env",
5278
+ "envs",
5279
+ "envvar",
5280
+ "envvars",
5281
+ "dotenv",
5282
+ "ssh",
5283
+ "sshkey",
5284
+ "sshkeys",
5285
+ "key",
5286
+ "keys",
5287
+ "privatekey",
5288
+ "certificate",
5289
+ "cert",
5290
+ "certs",
5291
+ "jwt",
5292
+ "bearer",
5293
+ "oauth",
5294
+ "mnemonic",
5295
+ "seed",
5296
+ "recovery",
5297
+ "mfa",
5298
+ "2fa",
5299
+ "cvv",
5300
+ "logins",
5301
+ "signed",
5302
+ "presigned"
5303
+ ]);
5304
+ var MCP_TOOL_NAMESPACE_SEPARATOR = "__";
5305
+ var LONGEST_MCP_TOOL_NAME_READ = 256;
5306
+ var CODEX_CONNECTOR_SERVER = "codex_apps";
5307
+ var segmentsAfterTheConnector = (server, segments) => server === CODEX_CONNECTOR_SERVER && segments.length > 1 ? segments.slice(1) : segments;
5308
+ var mcpToolWordsOf = (toolName) => {
5309
+ if (toolName.length > LONGEST_MCP_TOOL_NAME_READ) return void 0;
5310
+ const parsed = parseMcpToolName(toolName);
5311
+ if (parsed === void 0) return void 0;
5312
+ const segments = parsed.tool.split(MCP_TOOL_NAMESPACE_SEPARATOR);
5313
+ const action = segments[segments.length - 1] ?? "";
5314
+ const namespace = [parsed.server, ...segments.slice(0, -1)];
5315
+ return {
5316
+ name: wordsOfIdentifier(toolName),
5317
+ nameAsWritten: wordsOfAnIdentifierAsWritten(toolName),
5318
+ namespace: new Set(namespace.flatMap(wordsOfIdentifier)),
5319
+ namespaceAsWritten: namespace.flatMap(wordsOfAnIdentifierAsWritten),
5320
+ afterTheConnector: segmentsAfterTheConnector(parsed.server, segments).flatMap(wordsOfIdentifier),
5321
+ namesAConnector: parsed.server === CODEX_CONNECTOR_SERVER && segments.length > 1,
5322
+ action: wordsOfIdentifier(action)
5323
+ };
5324
+ };
5325
+ var isMcpReadVerb = (word) => MCP_TOOL_VERBS_THAT_ONLY_READ.has(word);
5326
+ var leadingVerbOf = ({ namespace, action }) => action.find((word) => isMcpReadVerb(word) || !namespace.has(word) && !MCP_TOOL_VERB_MODIFIERS.has(word));
5327
+ var joinsASecondAction = (action) => action.some((word) => MCP_TOOL_CLAUSE_JOINERS.has(word));
5328
+ var mcpToolWordNeedsAPersonWherever = (word) => !MCP_TOOL_NOUNS_THAT_ALSO_ACT.has(word) && mcpToolWordNeedsAPerson(word);
5329
+ var mcpToolActionWordChanges = (word) => !MCP_TOOL_NOUNS_THAT_ALSO_ACT.has(word) && MCP_TOOL_VERBS_THAT_CHANGE.has(word);
5330
+ var MCP_TOOL_PHRASE_THAT_NAMES_A_SECRET = /\benvironment (?:variables?|vars?|values?|secrets?)\b/;
5331
+ var mcpToolNameNamesASecret = ({ name, nameAsWritten }) => [...name, ...nameAsWritten].some((word) => MCP_TOOL_WORDS_THAT_NAME_A_SECRET.has(word)) || MCP_TOOL_PHRASE_THAT_NAMES_A_SECRET.test(name.join(" "));
5332
+ var mcpToolNameIsSensitive = (toolName) => {
5333
+ const phrase = wordsOfIdentifier(toolName).join(" ");
5334
+ return classifyDecisionRisk(phrase, phrase) !== "standard";
5335
+ };
5336
+ var mcpToolOnlyReads = (toolName) => {
5337
+ const words = isPusharyOwnTool(toolName.toLowerCase()) ? void 0 : mcpToolWordsOf(toolName);
5338
+ if (words === void 0) return false;
5339
+ const verb = leadingVerbOf(words);
5340
+ return verb !== void 0 && isMcpReadVerb(verb) && !joinsASecondAction(words.action) && !words.name.some(mcpToolWordNeedsAPersonWherever) && !words.afterTheConnector.some(mcpToolActionWordChanges) && !mcpToolNameNamesASecret(words) && !mcpToolNameIsSensitive(toolName);
5341
+ };
5342
+ var MCP_TOOL_WORDS_THAT_NAME_A_DATABASE = /* @__PURE__ */ new Set([
5343
+ "sqlite",
5344
+ "postgres",
5345
+ "postgresql",
5346
+ "psql",
5347
+ "pg",
5348
+ "mysql",
5349
+ "mariadb",
5350
+ "mssql",
5351
+ "sqlserver",
5352
+ "oracle",
5353
+ "supabase",
5354
+ "neon",
5355
+ "planetscale",
5356
+ "turso",
5357
+ "libsql",
5358
+ "cockroach",
5359
+ "cockroachdb",
5360
+ "bigquery",
5361
+ "snowflake",
5362
+ "redshift",
5363
+ "databricks",
5364
+ "duckdb",
5365
+ "motherduck",
5366
+ "clickhouse",
5367
+ "athena",
5368
+ "trino",
5369
+ "presto",
5370
+ "timescale",
5371
+ "timescaledb",
5372
+ "mongo",
5373
+ "mongodb",
5374
+ "db",
5375
+ "database",
5376
+ "databases",
5377
+ "dbhub",
5378
+ "metabase",
5379
+ "redash",
5380
+ "superset",
5381
+ "looker"
5382
+ ]);
5383
+ var someWordNamesADatabase = (words) => [...words].some((word) => MCP_TOOL_WORDS_THAT_NAME_A_DATABASE.has(word));
5384
+ var mcpToolNamesADatabase = (toolName) => {
5385
+ const words = mcpToolWordsOf(toolName);
5386
+ return words !== void 0 && someWordNamesADatabase([...words.name, ...words.nameAsWritten]);
5387
+ };
5388
+ var wordsThatNameTheApp = (words) => words.namesAConnector ? [...words.namespace, ...words.namespaceAsWritten] : [...words.name, ...words.nameAsWritten];
5389
+ var mcpToolAppNamesADatabase = (toolName) => {
5390
+ const words = mcpToolWordsOf(toolName);
5391
+ return words !== void 0 && someWordNamesADatabase(wordsThatNameTheApp(words));
5392
+ };
5393
+ var isCodexConnectorTool = (toolName) => parseMcpToolName(toolName)?.server === CODEX_CONNECTOR_SERVER;
5394
+ var DEEPEST_TOOL_INPUT_READ = 16;
5395
+ var LONGEST_TOOL_INPUT_TEXT_READ = 32768;
5396
+ var LONGEST_TOOL_INPUT_FIELD_NAME_READ = 256;
5397
+ var LARGEST_TOOL_INPUT_READ = 1048576;
5398
+ var TOOL_INPUT_COST_OF_EACH_VALUE = 32;
5399
+ var LONGEST_COMBINING_MARK_RUN_ANY_LANGUAGE_WRITES = 30;
5400
+ var COMBINING_MARKS = String.raw`[\p{M}\uFF9E\uFF9F]`;
5401
+ var COMBINING_MARK_RUN_LONGER_THAN_ANY_LANGUAGE_WRITES = new RegExp(`${COMBINING_MARKS}{${LONGEST_COMBINING_MARK_RUN_ANY_LANGUAGE_WRITES + 1}}`, "u");
5402
+ var UNNAMED_TOOL_INPUT_FIELD = {
5403
+ holdsAnAddress: false,
5404
+ holdsANamedAddress: false,
5405
+ namesAnHttpMethod: false,
5406
+ holdsSql: false,
5407
+ holdsGraphql: false
5408
+ };
5409
+ var UNREADABLE_TOOL_INPUT_TEXT = { kind: "unreadable" };
5410
+ var FIELD_WORDS_THAT_HOLD_AN_ADDRESS = /* @__PURE__ */ new Set([
5411
+ "url",
5412
+ "urls",
5413
+ "uri",
5414
+ "uris",
5415
+ "href",
5416
+ "link",
5417
+ "links",
5418
+ "host",
5419
+ "hosts",
5420
+ "hostname",
5421
+ "domain",
5422
+ "domains",
5423
+ "endpoint",
5424
+ "endpoints",
5425
+ "webhook",
5426
+ "webhooks",
5427
+ "callback",
5428
+ "website",
5429
+ "redirect"
5430
+ ]);
5431
+ var FIELD_WORDS_FOR_THE_FORM_A_VALUE_TAKES = /* @__PURE__ */ new Set(["list", "string", "str", "value", "values", "text"]);
5432
+ var ADDRESS_WORDS_A_NAME_CAN_FOLLOW = /* @__PURE__ */ new Set(["host", "hosts", "hostname", "domain", "domains"]);
5433
+ var FIELD_WORDS_FOR_A_NAME = /* @__PURE__ */ new Set(["name", "names"]);
5434
+ var FIELD_WORDS_THAT_NAME_AN_HTTP_METHOD = /* @__PURE__ */ new Set(["method", "verb"]);
5435
+ var FIELD_WORDS_THAT_QUALIFY_AN_HTTP_METHOD = /* @__PURE__ */ new Set(["http", "request", "x", "override"]);
5436
+ var FIELD_WORDS_THAT_NAME_SQL = /* @__PURE__ */ new Set(["sql", "statement", "statements"]);
5437
+ var FIELD_WORDS_THAT_NAME_GRAPHQL = /* @__PURE__ */ new Set(["graphql", "gql"]);
5438
+ var FIELD_WORDS_THAT_QUALIFY_A_QUERY = /* @__PURE__ */ new Set(["query", "raw", "text", "string", "document"]);
5439
+ var NO_ADDRESS_WORD = -1;
5440
+ var lastAddressWordOf = (words) => words.reduce((last, word, index) => FIELD_WORDS_THAT_HOLD_AN_ADDRESS.has(word) ? index : last, NO_ADDRESS_WORD);
5441
+ var saysTheFormOfAValue = (word) => FIELD_WORDS_FOR_THE_FORM_A_VALUE_TAKES.has(word);
5442
+ var wordAfterAnAddressSaysItsForm = (addressWord) => (word) => saysTheFormOfAValue(word) || ADDRESS_WORDS_A_NAME_CAN_FOLLOW.has(addressWord) && FIELD_WORDS_FOR_A_NAME.has(word);
5443
+ var fieldWordsHoldAnAddress = (words) => {
5444
+ const lastAddressWord = lastAddressWordOf(words);
5445
+ const addressWord = words[lastAddressWord];
5446
+ return addressWord !== void 0 && words.slice(lastAddressWord + 1).every(wordAfterAnAddressSaysItsForm(addressWord));
5447
+ };
5448
+ var fieldWordsHoldANamedAddress = (words) => {
5449
+ const addressWord = words[lastAddressWordOf(words)];
5450
+ return addressWord !== void 0 && ADDRESS_WORDS_A_NAME_CAN_FOLLOW.has(addressWord) && fieldWordsHoldAnAddress(words);
5451
+ };
5452
+ var fieldWordsNameOnly = (words, names, qualifiers) => words.some((word) => names.has(word)) && words.every((word) => names.has(word) || qualifiers.has(word));
5453
+ var describesOnlyTheValue = (words, describes) => words.length > 0 && words.every(describes);
5454
+ var namesTheValue = (word) => FIELD_WORDS_FOR_A_NAME.has(word);
5455
+ var toolInputFieldNamed = (fieldName, parent) => {
5456
+ const words = wordsOfIdentifier(fieldName);
5457
+ const inherited = describesOnlyTheValue(words, saysTheFormOfAValue) ? parent : UNNAMED_TOOL_INPUT_FIELD;
5458
+ const namesTheParentsAddress = parent.holdsANamedAddress && describesOnlyTheValue(words, namesTheValue);
5459
+ return {
5460
+ holdsAnAddress: inherited.holdsAnAddress || namesTheParentsAddress || fieldWordsHoldAnAddress(words),
5461
+ holdsANamedAddress: inherited.holdsANamedAddress || fieldWordsHoldANamedAddress(words),
5462
+ namesAnHttpMethod: fieldWordsNameOnly(words, FIELD_WORDS_THAT_NAME_AN_HTTP_METHOD, FIELD_WORDS_THAT_QUALIFY_AN_HTTP_METHOD),
5463
+ holdsSql: inherited.holdsSql || fieldWordsNameOnly(words, FIELD_WORDS_THAT_NAME_SQL, FIELD_WORDS_THAT_QUALIFY_A_QUERY),
5464
+ holdsGraphql: inherited.holdsGraphql || fieldWordsNameOnly(words, FIELD_WORDS_THAT_NAME_GRAPHQL, FIELD_WORDS_THAT_QUALIFY_A_QUERY)
5465
+ };
5127
5466
  };
5128
- var allowsSessionToolGrant = (toolName) => SESSION_TOOL_GRANT_TOOLS.has(toolName) || mcpToolLeadsWithAReadVerb(toolName) && !isPusharyOwnTool(toolName.toLowerCase()) && !mcpToolNameNeedsAPerson(toolName);
5467
+ var readableToolInputText = (text2) => {
5468
+ if (text2.length > LONGEST_TOOL_INPUT_TEXT_READ || COMBINING_MARK_RUN_LONGER_THAN_ANY_LANGUAGE_WRITES.test(text2)) {
5469
+ return UNREADABLE_TOOL_INPUT_TEXT;
5470
+ }
5471
+ const readable = readableText(text2);
5472
+ return readable.length > LONGEST_TOOL_INPUT_TEXT_READ ? UNREADABLE_TOOL_INPUT_TEXT : { kind: "readable", text: readable };
5473
+ };
5474
+ var toolInputTextMatches = (field, text2, test) => {
5475
+ const readable = readableToolInputText(text2);
5476
+ return readable.kind === "unreadable" || test(field, readable.text);
5477
+ };
5478
+ var fieldNameTooLongToRead = (fieldName) => fieldName.length > LONGEST_TOOL_INPUT_FIELD_NAME_READ;
5479
+ var anyToolInputText = (value, field, depth, test) => {
5480
+ if (typeof value === "string") return toolInputTextMatches(field, value, test);
5481
+ if (!Array.isArray(value) && !isRecord(value)) return false;
5482
+ if (depth >= DEEPEST_TOOL_INPUT_READ) return true;
5483
+ if (Array.isArray(value)) return value.some((child) => anyToolInputText(child, field, depth + 1, test));
5484
+ return Object.entries(value).some(([fieldName, child]) => fieldNameTooLongToRead(fieldName) || toolInputTextMatches(UNNAMED_TOOL_INPUT_FIELD, fieldName, test) || anyToolInputText(child, toolInputFieldNamed(fieldName, field), depth + 1, test));
5485
+ };
5486
+ var toolInputCostFrom = (value, depth, counted) => {
5487
+ if (counted > LARGEST_TOOL_INPUT_READ) return counted;
5488
+ const charged = counted + TOOL_INPUT_COST_OF_EACH_VALUE;
5489
+ if (typeof value === "string") return charged + value.length;
5490
+ if (depth >= DEEPEST_TOOL_INPUT_READ || !Array.isArray(value) && !isRecord(value)) return charged;
5491
+ const children = Array.isArray(value) ? value : Object.entries(value).flat();
5492
+ return children.reduce((sum, child) => toolInputCostFrom(child, depth + 1, sum), charged);
5493
+ };
5494
+ var toolInputTooLargeToRead = (toolInput) => toolInputCostFrom(toolInput, 0, 0) > LARGEST_TOOL_INPUT_READ;
5495
+ var LINE_BREAKS_A_URL_PARSER_DROPS = /[\t\n\r]/g;
5496
+ var WRITTEN_WEB_ADDRESSES = [
5497
+ /[a-z][a-z0-9+.-]{0,31}:\/\//i,
5498
+ /\b(?:https?|wss?|ftp|mailto):(?=\S)/i,
5499
+ /\bfile:\//i,
5500
+ /(?:^|[\s"'(=<[,])\/\/[a-z0-9-]+\./i,
5501
+ /(?:^|[\s"'(=<[,])\\\\[a-z0-9-]+/i,
5502
+ /%3a(?:%2f|\/){2}|%2f%2f/i,
5503
+ /\b\d{1,3}(?:\.\d{1,3}){3}(?::\d+|\/)/,
5504
+ /(?<![\w\]])\[(?=[0-9a-f.]{0,45}:[0-9a-f.]{0,45}:)(?=[0-9a-f:.]{0,45}(?:::|[a-f]))[0-9a-f:.]{2,45}\]/i,
5505
+ /(?<![\w\]])\[[0-9a-f:.]{2,45}\]:\d/i,
5506
+ /\blocalhost(?::\d|\/)/i
5507
+ ];
5508
+ var WHOLE_VALUE_HOST_THAT_CARRIES_DATA_IN_ITS_QUERY = /^[<"'(\[]?(?:[^@\s/]{1,64}@)?(?:[a-z0-9-]{1,63}\.)+[a-z]{2,63}(?::\d{1,5})?(?:\/[^\s?#]*)?\?[^\s#]\S*$/i;
5509
+ var textNamesAWebAddress = (field, text2) => {
5510
+ const unbroken = text2.replace(LINE_BREAKS_A_URL_PARSER_DROPS, "");
5511
+ return field.holdsAnAddress && text2.trim().length > 0 || WRITTEN_WEB_ADDRESSES.some((pattern) => pattern.test(unbroken)) || WHOLE_VALUE_HOST_THAT_CARRIES_DATA_IN_ITS_QUERY.test(unbroken.trim());
5512
+ };
5513
+ var HTTP_METHODS_THAT_WRITE = /* @__PURE__ */ new Set([
5514
+ "POST",
5515
+ "PUT",
5516
+ "PATCH",
5517
+ "DELETE",
5518
+ "CONNECT",
5519
+ "PURGE",
5520
+ "ACL",
5521
+ "BASELINE-CONTROL",
5522
+ "BIND",
5523
+ "CHECKIN",
5524
+ "CHECKOUT",
5525
+ "COPY",
5526
+ "LABEL",
5527
+ "LINK",
5528
+ "LOCK",
5529
+ "MERGE",
5530
+ "MKACTIVITY",
5531
+ "MKCALENDAR",
5532
+ "MKCOL",
5533
+ "MKREDIRECTREF",
5534
+ "MKWORKSPACE",
5535
+ "MOVE",
5536
+ "ORDERPATCH",
5537
+ "PROPPATCH",
5538
+ "REBIND",
5539
+ "UNBIND",
5540
+ "UNCHECKOUT",
5541
+ "UNLINK",
5542
+ "UNLOCK",
5543
+ "UPDATE",
5544
+ "UPDATEREDIRECTREF",
5545
+ "VERSION-CONTROL"
5546
+ ]);
5547
+ var SQL_COMMENT = /\/\*(?:[^*]|\*(?!\/))*(?:\*\/|$)|--[^\n]*/g;
5548
+ var SQL_NAME = String.raw`(?:"[^"\n]{1,128}"|[\w.\x60[\]]{1,128})`;
5549
+ var SQL_USER = String.raw`(?:'[^'\n]{1,128}'(?:@'[^'\n]{1,128}')?|${SQL_NAME})`;
5550
+ var SQL_ALIAS = String.raw`(?:\s+(?:as\s+)?\w{1,64})?`;
5551
+ var SQL_STATEMENT_THAT_LEADS_A_SCRIPT = String.raw`(?:select|with|explain|analyze|describe|pragma|start|begin|commit|rollback|savepoint|prepare|declare|exec|execute|vacuum|reindex|attach|detach|abort)`;
5552
+ var STATEMENTS_THAT_CHANGE = [
5553
+ String.raw`\binsert\s+(?:ignore\s+)?(?:into\s+)?${SQL_NAME}\s*(?:\([^)]{0,512}\)\s*)?(?:values\s*\(|select\b|default\s+values\b|set\s+${SQL_NAME}\s*=)`,
5554
+ String.raw`\bdelete\s+from\s+(?:only\s+)?${SQL_NAME}${SQL_ALIAS}\s*(?:;|\b(?:where|using|returning|limit|order\s+by)\b)`,
5555
+ String.raw`\bdelete\s+${SQL_NAME}\s+where\b`,
5556
+ String.raw`\bupdate\s+(?:only\s+)?${SQL_NAME}${SQL_ALIAS}\s+set\s+(?:${SQL_NAME}|\([^)]{1,512}\))\s*=`,
5557
+ String.raw`\b(?:replace|upsert)\s+into\s+${SQL_NAME}\s*(?:\(|values\b|select\b|set\s+${SQL_NAME}\s*=)`,
5558
+ String.raw`\bmerge\s+into\s+${SQL_NAME}${SQL_ALIAS}\s+using\s*(?:\(|${SQL_NAME}${SQL_ALIAS}\s+on\b)`,
5559
+ String.raw`\bdrop\s+(?:materialized\s+view|table|view|function|procedure|trigger|sequence)\s+(?:if\s+exists\s+)?${SQL_NAME}`,
5560
+ String.raw`\bdrop\s+(?:user|role|index|schema|database)\s+(?:if\s+exists\s+${SQL_USER}|${SQL_USER}\s*(?:;|\b(?:cascade|restrict)\b))`,
5561
+ String.raw`\balter\s+(?:table|view|materialized\s+view|sequence|index|database|schema)\s+(?:if\s+exists\s+)?(?:only\s+)?${SQL_NAME}\s+(?:add|drop|alter|rename|set|owner|enable|disable|attach|detach)\b`,
5562
+ String.raw`\balter\s+(?:user|role)\s+${SQL_USER}\s+(?:with|superuser|nosuperuser|login|nologin|identified|password|rename|set)\b`,
5563
+ String.raw`\btruncate\s+table\s+${SQL_NAME}`,
5564
+ String.raw`^\s*\(*\s*${SQL_STATEMENT_THAT_LEADS_A_SCRIPT}\b[\s\S]*?;\s*(?:delete\s+from\s+(?:only\s+)?${SQL_NAME}|drop\s+(?:user|role|index|schema|database)\s+(?:if\s+exists\s+)?${SQL_USER}|truncate\s+(?:table\s+)?${SQL_NAME}|create\s+(?:user|role|database|schema)\s+(?:if\s+not\s+exists\s+)?${SQL_USER}|grant\s+${SQL_NAME}\s+to\s+${SQL_USER}|call\s+${SQL_NAME}\s*\()`,
5565
+ String.raw`(?:^|;)\s*truncate\s+${SQL_NAME}\s*;`,
5566
+ String.raw`\bcreate\s+(?:temp(?:orary)?\s+)?table\s+(?:if\s+not\s+exists\s+)?${SQL_NAME}\s*(?:\(|\bas\b|\blike\b)`,
5567
+ String.raw`\bcreate\s+(?:or\s+replace\s+)?(?:materialized\s+)?view\s+(?:if\s+not\s+exists\s+)?${SQL_NAME}\s+as\b`,
5568
+ String.raw`\bcreate\s+(?:or\s+replace\s+)?(?:function|procedure)\s+${SQL_NAME}\s*\(`,
5569
+ String.raw`\bcreate\s+(?:or\s+replace\s+)?trigger\s+${SQL_NAME}\s+(?:before|after|instead)\b`,
5570
+ String.raw`\bcreate\s+(?:unique\s+)?index\s+(?:concurrently\s+)?(?:if\s+not\s+exists\s+)?${SQL_NAME}\s+on\s+${SQL_NAME}`,
5571
+ String.raw`\bcreate\s+(?:unique\s+)?index\s+(?:concurrently\s+)?on\s+${SQL_NAME}\s*\(`,
5572
+ String.raw`\bcreate\s+(?:user|role)\s+(?:if\s+not\s+exists\s+)?${SQL_USER}\s*(?:;|\b(?:with|superuser|login|password|identified)\b)`,
5573
+ String.raw`\bcreate\s+(?:database|schema)\s+(?:if\s+not\s+exists\s+${SQL_NAME}|${SQL_NAME}\s*;)`,
5574
+ String.raw`\b(?:grant|revoke)\s+(?:all(?:\s+privileges)?|select|insert|update|delete|usage|execute|create|connect|references|trigger|truncate)(?:\s*,\s*\w{1,32})*\s+on\b`,
5575
+ String.raw`\bexec(?:ute)?\s+(?:sp|xp)_\w+`,
5576
+ String.raw`\bexecute\s+immediate\b`,
5577
+ String.raw`\bcopy\s+${SQL_NAME}\s+(?:to|from)\s+(?:program\b|stdout\b|stdin\b|')`,
5578
+ String.raw`\bpg_(?:terminate|cancel)_backend\b`,
5579
+ String.raw`\bmutation\b(?:\s+[a-z_]\w{0,127})?\s*(?:\{|@[a-z_]|\(\s*\$)`
5580
+ ].map((source) => new RegExp(source, "i"));
5581
+ var fieldSetsAnHttpMethodThatWrites = (field, text2) => field.namesAnHttpMethod && HTTP_METHODS_THAT_WRITE.has(text2.trim().toUpperCase());
5582
+ var sqlTextWritesAsAClientReadsIt = (text2) => writesThroughSql(text2, UNVERIFIED_SQL_LEXICON);
5583
+ var fieldHoldsSqlThatWrites = (field, text2) => field.holdsSql && sqlTextWritesAsAClientReadsIt(text2);
5584
+ var fieldHoldsAGraphqlMutation = (field, text2) => field.holdsGraphql && GRAPHQL_MUTATION.test(text2);
5585
+ var COPY_OF_A_SUBQUERY = /\bcopy\s*\((?:\s*\()*\s*(?:select|with|values|table|insert|update|delete|merge)\b/i;
5586
+ var COPY_TO_A_PROGRAM_OR_A_FILE = /\)\s*to\s+(?:program\b|')/i;
5587
+ var copiesASubqueryOut = (text2) => {
5588
+ const copy = text2.search(COPY_OF_A_SUBQUERY);
5589
+ return copy !== -1 && COPY_TO_A_PROGRAM_OR_A_FILE.test(text2.slice(copy));
5590
+ };
5591
+ var carriesAStatementThatChanges = (text2) => STATEMENTS_THAT_CHANGE.some((pattern) => pattern.test(text2)) || copiesASubqueryOut(text2);
5592
+ var textCarriesAStatementThatChanges = (text2) => carriesAStatementThatChanges(text2) || carriesAStatementThatChanges(text2.replace(SQL_COMMENT, " "));
5593
+ var textAsksToChange = (field, text2) => fieldSetsAnHttpMethodThatWrites(field, text2) || fieldHoldsSqlThatWrites(field, text2) || fieldHoldsAGraphqlMutation(field, text2) || textCarriesAStatementThatChanges(text2);
5594
+ var textNeedsAPersonFor = (toolNamesADatabase) => (field, text2) => textNamesAWebAddress(field, text2) || textAsksToChange(field, text2) || toolNamesADatabase && sqlTextWritesAsAClientReadsIt(text2);
5595
+ var mcpToolInputOnlyReads = (toolName, toolInput) => !toolInputTooLargeToRead(toolInput) && !anyToolInputText(toolInput, UNNAMED_TOOL_INPUT_FIELD, 0, textNeedsAPersonFor(mcpToolNamesADatabase(toolName)));
5596
+ var allowsSessionToolGrant = (toolName) => SESSION_TOOL_GRANT_TOOLS.has(toolName) || mcpToolOnlyReads(toolName);
5129
5597
  var isSessionToolGrant = (policy) => Boolean(policy.sessionId) && allowsSessionToolGrant(policy.tool) && isAutoApprove(policy);
5130
5598
  var API_KEY_PREFIX_SHAPE = "pk_[a-f0-9]+";
5131
5599
  var API_KEY_PREFIX_PATTERN = new RegExp(`^${API_KEY_PREFIX_SHAPE}$`);
@@ -5681,6 +6149,7 @@ var unmatchedPolicyOf = (config, toolName) => ({
5681
6149
  mode: config.defaultMode ?? "push_first",
5682
6150
  pushFirstSeconds: config.defaultPushFirstSeconds ?? 20
5683
6151
  });
6152
+ var sessionToolGrantCannotCover = (toolName, arg, toolInput) => typeof arg === "string" && commandNeedsAPerson(toolName, arg) || parseMcpToolName(toolName) !== void 0 && (toolInput === void 0 || !mcpToolInputOnlyReads(toolName, toolInput));
5684
6153
  var stricterOfTheReadings = (asWritten, asSpelled, unmatched) => comparePolicyStrictness(asWritten?.policy ?? unmatched, asSpelled?.policy ?? unmatched) > 0 ? asWritten : asSpelled;
5685
6154
  var resolvePolicy = (config, toolName, modeOverride, toolInput, cwd, repoKey, sessionId) => {
5686
6155
  const args = toolInput ? policyArgForms(toolName, toolInput, cwd) : [];
@@ -5696,7 +6165,7 @@ var resolvePolicy = (config, toolName, modeOverride, toolInput, cwd, repoKey, se
5696
6165
  const governingMode = base.mode;
5697
6166
  const aRuleNamesASpelling = isSpecificArgumentRank(asSpelled?.rank);
5698
6167
  const approvedByReadOnlyFloor = !isAutoDeny(base) && (shellReadOnlyFloorApplies(toolName, arg, match?.rank) && !aRuleNamesASpelling || coordinationFloorApplies(toolName, match?.rank));
5699
- if (governedBySessionToolGrant && !approvedByReadOnlyFloor && typeof arg === "string" && commandNeedsAPerson(toolName, arg)) {
6168
+ if (governedBySessionToolGrant && !approvedByReadOnlyFloor && sessionToolGrantCannotCover(toolName, arg, toolInput)) {
5700
6169
  return resolvePolicy(withoutSessionToolGrants(config), toolName, modeOverride, toolInput, cwd, repoKey, sessionId);
5701
6170
  }
5702
6171
  if (approvedByReadOnlyFloor) {
@@ -5935,7 +6404,9 @@ var runsADestructiveCommand = ({ toolName, toolInputs }) => SHELL_DIALECT_BY_TOO
5935
6404
  return command !== void 0 && commandIsDestructive(toolName, command);
5936
6405
  });
5937
6406
  var codexCallIsDestructive = (input, call) => call.deletesFiles || runsADestructiveCommand(input);
5938
- var codexCallNeedsAPerson = (input, verdict, call) => onlyCodexPreToolUseCanAsk(verdict, call.permissionMode) || verdict.kind === "gate" && (aChosenRuleGoverns(input) || call.deletesFiles || runsACommandThatNeedsAPerson(input) || editsAFileThatNeedsAPerson(input));
6407
+ var connectorCallOnlyReads = ({ toolName, toolInputs }) => isCodexConnectorTool(toolName) && mcpToolOnlyReads(toolName) && !mcpToolAppNamesADatabase(toolName) && toolInputs.length > 0 && toolInputs.every((toolInput) => mcpToolInputOnlyReads(toolName, toolInput));
6408
+ var fullAccessRunsThisConnectorReadUnasked = (input, verdict, call) => !codexRaisesItsOwnPrompts(call.permissionMode) && scopeBreachReasonOf(verdict) === void 0 && noModeOverrideIsActive(input) && connectorCallOnlyReads(input);
6409
+ var codexCallNeedsAPerson = (input, verdict, call) => onlyCodexPreToolUseCanAsk(verdict, call.permissionMode) && !fullAccessRunsThisConnectorReadUnasked(input, verdict, call) || verdict.kind === "gate" && (aChosenRuleGoverns(input) || call.deletesFiles || runsACommandThatNeedsAPerson(input) || editsAFileThatNeedsAPerson(input));
5939
6410
  var CODEX_PRE_TOOL_USE_PASSES = { kind: "pass" };
5940
6411
  var codexPreToolUseDelivery = (input, verdict, call) => {
5941
6412
  if (verdict.kind !== "gate" || !codexCallNeedsAPerson(input, verdict, call)) return CODEX_PRE_TOOL_USE_PASSES;
@@ -6334,6 +6805,8 @@ var hookActivationResult = (report) => {
6334
6805
  };
6335
6806
 
6336
6807
  export {
6808
+ conversationText,
6809
+ extractMessageText,
6337
6810
  isRecord,
6338
6811
  AGENT_QUESTION_HEADER_MAX,
6339
6812
  AGENT_QUESTION_OPTION_MAX,
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  pusharyDir
3
- } from "./chunk-274CV7IW.js";
3
+ } from "./chunk-N4NSX5MB.js";
4
4
  import {
5
5
  writeFileAtomic
6
- } from "./chunk-OXOYS3UG.js";
6
+ } from "./chunk-GUJBS6TK.js";
7
7
 
8
8
  // src/identity.ts
9
9
  import { randomUUID } from "crypto";
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-3EGEA4KH.js";
10
10
  import {
11
11
  getBaseUrl
12
- } from "./chunk-32OSSYGZ.js";
12
+ } from "./chunk-BMVWGPYB.js";
13
13
 
14
14
  // src/cli/login-ui.ts
15
15
  import { hostname } from "os";
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  resolveInstallSourceFor
3
- } from "./chunk-METUT7V4.js";
3
+ } from "./chunk-ZWCKS65X.js";
4
4
  import {
5
5
  backupFile,
6
6
  readJsonSafe,
7
7
  writeFileAtomic,
8
8
  writeJsonAtomic
9
- } from "./chunk-OXOYS3UG.js";
9
+ } from "./chunk-GUJBS6TK.js";
10
10
  import {
11
11
  configFilePath
12
- } from "./chunk-32OSSYGZ.js";
12
+ } from "./chunk-BMVWGPYB.js";
13
13
  import {
14
14
  API_KEY_PREFIX_PATTERN,
15
15
  isRecord
16
- } from "./chunk-RQOT6QL3.js";
16
+ } from "./chunk-5XKJH5GD.js";
17
17
 
18
18
  // src/shell-alias.ts
19
19
  import { homedir } from "os";
@@ -2,7 +2,7 @@ import {
2
2
  DISCONNECT_AGENT_IDS,
3
3
  SETUP_AGENT_CHOICES,
4
4
  isApprovalMode
5
- } from "./chunk-RQOT6QL3.js";
5
+ } from "./chunk-5XKJH5GD.js";
6
6
 
7
7
  // src/cli/mode-request.ts
8
8
  var parseDuration = (value) => {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  NPX_LATEST_COMMAND
3
- } from "./chunk-X2MTVD4W.js";
3
+ } from "./chunk-7KMLITXH.js";
4
4
 
5
5
  // src/config.ts
6
6
  import { readFileSync } from "fs";
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  getBaseUrl
3
- } from "./chunk-32OSSYGZ.js";
3
+ } from "./chunk-BMVWGPYB.js";
4
4
  import {
5
5
  compressTranscriptRecord,
6
6
  redactSecretsFromContent
7
- } from "./chunk-RQOT6QL3.js";
7
+ } from "./chunk-5XKJH5GD.js";
8
8
 
9
9
  // src/transcript-api.ts
10
10
  var fetchTranscriptRecipients = async (apiKey, baseUrl = getBaseUrl()) => {