@pushary/agent-hooks 1.7.3 → 1.8.0

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 (102) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +13 -1
  3. package/data/cursor-plugin/scripts/pushary-gate.mjs +2 -21
  4. package/data/cursor-plugin/scripts/redaction.mjs +51 -0
  5. package/data/vscode-plugin/scripts/pushary-gate.mjs +1 -21
  6. package/data/vscode-plugin/scripts/redaction.mjs +51 -0
  7. package/dist/bin/pushary-bell-hook.js +23 -23
  8. package/dist/bin/pushary-bell.js +9 -9
  9. package/dist/bin/pushary-claude.js +26 -26
  10. package/dist/bin/pushary-clean.js +91 -107
  11. package/dist/bin/pushary-codex-bridge.js +18 -18
  12. package/dist/bin/pushary-codex-hook.js +42 -43
  13. package/dist/bin/pushary-codex.js +13 -13
  14. package/dist/bin/pushary-connect.js +13 -13
  15. package/dist/bin/pushary-cowork.js +5 -5
  16. package/dist/bin/pushary-daemon.js +27 -27
  17. package/dist/bin/pushary-disconnect.js +18 -18
  18. package/dist/bin/pushary-doctor.js +85 -79
  19. package/dist/bin/pushary-elicitation-hook.js +25 -25
  20. package/dist/bin/pushary-gemini-bridge.js +12 -12
  21. package/dist/bin/pushary-gemini-hook.js +29 -30
  22. package/dist/bin/pushary-hook.js +32 -32
  23. package/dist/bin/pushary-login.js +12 -12
  24. package/dist/bin/pushary-logout.js +7 -7
  25. package/dist/bin/pushary-mcp.js +85 -28
  26. package/dist/bin/pushary-mode.js +9 -9
  27. package/dist/bin/pushary-notification-hook.js +28 -28
  28. package/dist/bin/pushary-opencode-hook.js +28 -29
  29. package/dist/bin/pushary-permission-denied-hook.js +32 -32
  30. package/dist/bin/pushary-permission-hook.js +31 -31
  31. package/dist/bin/pushary-post-hook.js +28 -28
  32. package/dist/bin/pushary-prompt-hook.js +28 -28
  33. package/dist/bin/pushary-session-end-hook.js +28 -28
  34. package/dist/bin/pushary-session-start-hook.js +32 -32
  35. package/dist/bin/pushary-setup.js +60 -127
  36. package/dist/bin/pushary-stats.js +5 -5
  37. package/dist/bin/pushary-status.js +15 -15
  38. package/dist/bin/pushary-stop-hook.js +28 -28
  39. package/dist/bin/pushary-stopfailure-hook.js +28 -28
  40. package/dist/bin/pushary-suggestions.js +4 -4
  41. package/dist/bin/pushary-transcript-register.js +19 -19
  42. package/dist/bin/pushary-transcripts.js +7 -7
  43. package/dist/bin/pushary-upgrade.js +231 -105
  44. package/dist/bin/pushary-wait.js +9 -9
  45. package/dist/bin/pushary.js +6 -6
  46. package/dist/{chunk-EEEJ2JIL.js → chunk-2ABTSGFT.js} +3 -3
  47. package/dist/{chunk-DUQO4C4I.js → chunk-2OY3ZZ5N.js} +3 -3
  48. package/dist/{chunk-MIXWMA73.js → chunk-3EVPNIBE.js} +3 -3
  49. package/dist/{chunk-WTJM7PSL.js → chunk-6J2JC2RT.js} +3 -3
  50. package/dist/{chunk-EADXTSHE.js → chunk-7Z7Q4GGS.js} +2 -2
  51. package/dist/{chunk-MZBRL5H5.js → chunk-A2A2YTMG.js} +108 -25
  52. package/dist/{chunk-KEL5MXRL.js → chunk-AHV4LNB5.js} +1 -1
  53. package/dist/{chunk-G3OMOTJ4.js → chunk-AXPCESYO.js} +3 -3
  54. package/dist/{chunk-3EUBQARL.js → chunk-C2WCPBF7.js} +1 -1
  55. package/dist/chunk-CJVVKOSR.js +73 -0
  56. package/dist/{chunk-U6RVDUJ5.js → chunk-CULUZTWQ.js} +283 -41
  57. package/dist/{chunk-N5MZH5A6.js → chunk-CVQYGMSR.js} +4 -4
  58. package/dist/{chunk-VKVSRCBO.js → chunk-D2FX3EPW.js} +1 -1
  59. package/dist/{chunk-62CVUUNU.js → chunk-DB3ONZB4.js} +2 -2
  60. package/dist/{chunk-WGMW7OXW.js → chunk-DE4Y6TCC.js} +6 -6
  61. package/dist/{chunk-YYCTF4Q5.js → chunk-E4FJTUH4.js} +1 -1
  62. package/dist/{chunk-EUGNVLMG.js → chunk-EPCXUP3P.js} +3 -1
  63. package/dist/{chunk-PRNFSORD.js → chunk-EX3GAPA4.js} +1 -1
  64. package/dist/{chunk-TCVMK6GI.js → chunk-EYK3GSRH.js} +4 -4
  65. package/dist/{chunk-R6OYCUNK.js → chunk-GPEGOGRJ.js} +1 -1
  66. package/dist/chunk-GU3EJCVV.js +43 -0
  67. package/dist/{chunk-Y4ZH64UK.js → chunk-HQ6G3B5R.js} +2 -2
  68. package/dist/{chunk-5S2VBSJI.js → chunk-HZVVNGEW.js} +2 -2
  69. package/dist/{chunk-IWJKSIB4.js → chunk-IPVKH2ST.js} +1 -1
  70. package/dist/{chunk-UOQRM7JQ.js → chunk-J5TIV3J6.js} +5 -5
  71. package/dist/{chunk-IRZG3HEU.js → chunk-JU6W3XAU.js} +1 -1
  72. package/dist/{chunk-G62JL2NT.js → chunk-JYG4B33G.js} +1 -1
  73. package/dist/{chunk-OTNOANMX.js → chunk-JZTHGAPA.js} +8 -8
  74. package/dist/{chunk-7RUJKCR4.js → chunk-KGDWDSNL.js} +2 -2
  75. package/dist/{chunk-6JQFIHZC.js → chunk-KVQBWI5T.js} +3 -3
  76. package/dist/{chunk-OVC5QXN5.js → chunk-LXQ5FBBD.js} +1 -1
  77. package/dist/{chunk-VE7TXLR4.js → chunk-M5ICYGHT.js} +3 -3
  78. package/dist/{chunk-YPUBA2FL.js → chunk-M5JDZ45W.js} +4 -4
  79. package/dist/{chunk-O3JDWNLU.js → chunk-MDEPU45E.js} +183 -28
  80. package/dist/{chunk-P2VIBGXA.js → chunk-MPWXGONV.js} +1 -1
  81. package/dist/{chunk-YC27PROF.js → chunk-NGDD6TXY.js} +20 -5
  82. package/dist/{chunk-G4GLCLKK.js → chunk-NQTHFF4W.js} +138 -17
  83. package/dist/{chunk-NOI3XTCY.js → chunk-OKXS7WDZ.js} +1 -1
  84. package/dist/{chunk-LPNJLKBQ.js → chunk-OLQRRFBX.js} +1 -1
  85. package/dist/{chunk-D6OODZCM.js → chunk-P7WQEVWA.js} +2 -2
  86. package/dist/{chunk-62VT3BPH.js → chunk-Q7E4I6UA.js} +28 -16
  87. package/dist/{chunk-BIH2Y2HP.js → chunk-R7437YI3.js} +2 -2
  88. package/dist/{chunk-RLW3JWDY.js → chunk-RHR6NARM.js} +2 -2
  89. package/dist/{chunk-WPX67AKT.js → chunk-SAXBC4AZ.js} +1 -1
  90. package/dist/{chunk-IPSRMLCJ.js → chunk-SIFVFP6T.js} +1 -1
  91. package/dist/{chunk-7OA34PNW.js → chunk-SLFABHW3.js} +40 -10
  92. package/dist/{chunk-AWVNAYGD.js → chunk-TY4JT7W3.js} +1 -1
  93. package/dist/{chunk-KJXUIPS4.js → chunk-UI36QSBI.js} +28 -16
  94. package/dist/{chunk-G6RRVJOG.js → chunk-VQKRG3AC.js} +6 -6
  95. package/dist/{chunk-ZKJ34T2F.js → chunk-WE2J62NC.js} +31 -17
  96. package/dist/{chunk-LHC45YUC.js → chunk-ZSZSSJCV.js} +1 -1
  97. package/dist/{chunk-BGBLLHZ4.js → chunk-ZVSKMPBZ.js} +1 -1
  98. package/dist/{reapply-PH5T4BGR.js → reapply-CW3MA66V.js} +9 -9
  99. package/dist/src/index.js +20 -20
  100. package/package.json +1 -1
  101. package/dist/chunk-5GB22QYL.js +0 -255
  102. package/dist/chunk-VYPJHGG6.js +0 -92
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.8.0
4
+
5
+ - **An approval you give after auto mode blocks a call is no longer lost when the agent rewords the call.** Your approval covers only the exact call that was blocked. Claude Code tells the agent only that it may retry, and an agent that sent a changed command was blocked again, so the approval you gave from your phone or the Mac notch did nothing. Pushary now refuses the first changed call and tells the agent to send the blocked call again unchanged. If the agent ends its turn without sending it, Pushary tells it to send it.
6
+ - Claude Code no longer tells your phone and the Mac notch that it is waiting for you while its background tasks are still running. Claude Code reports itself idle after a minute at the prompt even when it will continue by itself once those tasks finish. A question from the agent still reaches you as before.
7
+ - A prompt longer than 500 characters, or a shell command longer than about 490, no longer stops your agent at its next phone approval. The hook sent the whole text and the server refused it, so Claude Code halted with "Pushary could not create a verifiable approval" and Codex and OpenCode denied the call. The question, intent, action, blocker and agent name are now cut to what the card can show, and a cut line ends in "…". The server now does the same for every older CLI, so this fix does not wait for you to update. (#1604)
8
+ - A line cut to fit, including a long diff, never ends on half an emoji. The server stores these lines as JSON, and Postgres refuses a half character, so the approval failed to save.
9
+ - `pushary doctor`, `pushary upgrade`, `pushary clean` and automatic updates recognise a global install under either package name, `@pushary/agent-hooks` or `pushary`. A machine keeps the name it already has, and setup on a new machine installs the name it was run from. Nothing changes for an existing install.
10
+ - `pushary doctor` flags a machine with both names installed globally, because uninstalling either one removes every Pushary command.
11
+ - `pushary upgrade` no longer installs over an automatic update that is still running. It says another upgrade is running, with its process id, and stops.
12
+
3
13
  ## 1.7.3
4
14
 
5
15
  - **Approval text never hides part of a command.** The value after a credential name is now hidden only up to the first space, quote or piece of shell syntax. 1.7.2 could still hide a command: `eval TOKEN="x; rm -rf ~"` read `eval TOKEN="[redacted]"`, `password= reboot` read `password= [redacted]`, and `rm -rf {password=x,/}` hid the `,/` that also deletes `/`. A private key block is hidden only when it holds nothing but the key. Tokens, keys and quoted values without spaces are hidden as before. A quoted value with spaces now shows what follows its first word, as in `--password='[redacted] pass'`. Logs and error reports still hide the whole value.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @pushary/agent-hooks
1
+ # Pushary
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@pushary/agent-hooks.svg)](https://www.npmjs.com/package/@pushary/agent-hooks)
4
4
  [![npm downloads](https://img.shields.io/npm/dm/@pushary/agent-hooks.svg)](https://www.npmjs.com/package/@pushary/agent-hooks)
@@ -100,6 +100,18 @@ Verify it worked:
100
100
  npx @pushary/agent-hooks@latest doctor
101
101
  ```
102
102
 
103
+ Setup installs this package globally with npm, at the version you ran, because the
104
+ hooks run from that install. You never install it by hand.
105
+
106
+ ## Remove it
107
+
108
+ ```bash
109
+ npx @pushary/agent-hooks@latest clean
110
+ ```
111
+
112
+ It removes the hooks, the MCP entries, the stored key and the background service.
113
+ Add `--dry-run` to see what it would remove first.
114
+
103
115
  ## Supported agents
104
116
 
105
117
  | Agent | Notify | Ask | Gate |
@@ -2,6 +2,8 @@
2
2
  // Pushary Cursor hooks: server policy, fenced phone approvals, and lifecycle telemetry.
3
3
  // Dependency-free for marketplace installs. Regenerate agent-hooks/data after edits.
4
4
 
5
+ import { redactSecrets, redactSecretsDeep } from './redaction.mjs'
6
+ export { redactSecrets } from './redaction.mjs'
5
7
  import { createHash, randomUUID } from 'node:crypto'
6
8
  import { hostname } from 'node:os'
7
9
  import { existsSync, readFileSync } from 'node:fs'
@@ -294,27 +296,6 @@ export const describeNetworkFailure = (error, env = process.env) => {
294
296
  // line reached the lock screen verbatim.
295
297
  const ACTION_BODY_MAX = 4000
296
298
  const ACTION_BODY_TRUNCATION_MARKER = '\n… [truncated]'
297
- const REDACTION_RULES = [
298
- [/-----BEGIN[A-Z0-9 ]*PRIVATE KEY-----(?:\r?\n|(?:\\r)?\\n)?(?:(?:Proc-Type|DEK-Info): [A-Za-z0-9,-]+(?:\r?\n|(?:\\r)?\\n))*(?:[A-Za-z0-9+/=\r\n]|\\[rn])*?-----END[A-Z0-9 ]*PRIVATE KEY-----/g, '[redacted key]'],
299
- [/\bsk-[A-Za-z0-9_-]{16,}\b/g, '[redacted]'],
300
- [/\b[spr]k_(?:live|test)_[A-Za-z0-9]{8,}\b/g, '[redacted]'],
301
- [/\bwhsec_[A-Za-z0-9]{16,}\b/g, '[redacted]'],
302
- [/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36,}\b/g, '[redacted]'],
303
- [/\bgithub_pat_[A-Za-z0-9_]{22,}\b/g, '[redacted]'],
304
- [/\bglpat-[A-Za-z0-9_-]{20,}\b/g, '[redacted]'],
305
- [/\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g, '[redacted]'],
306
- [/\bAIza[A-Za-z0-9_-]{35}\b/g, '[redacted]'],
307
- [/\bAKIA[0-9A-Z]{16}\b/g, '[redacted]'],
308
- [/\bnpm_[A-Za-z0-9]{36}\b/g, '[redacted]'],
309
- [/\bxai-[A-Za-z0-9]{16,}\b/g, '[redacted]'],
310
- [/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, '[redacted]'],
311
- [/\bbearer\s+[A-Za-z0-9._~+/=-]+/gi, 'bearer [redacted]'],
312
- [/\bauthorization:\s*(?:[A-Za-z0-9_\-./+=:@%^!#]|\\[^\s'"])+/gi, 'authorization: [redacted]'],
313
- [/((?:secret|token|password|passwd|api[_-]?key|access[_-]?key|client[_-]?secret|private[_-]?key)["']?(?:[ \t]*:[ \t]*|[ \t]+=[ \t]*|=))(?:(")(?:[A-Za-z0-9_\-./+=:@%^!#]|\\[^\s'"])*"|(')[A-Za-z0-9_\-./+=:@%^!#\\]*'|(["']?)(?:[A-Za-z0-9_\-./+=:@%^!#]|\\[^\s'"])+)/gi, '$1$2$3$4[redacted]$2$3'],
314
- ]
315
- const HIGH_ENTROPY_RULE = [/[A-Za-z0-9+/]{40,}={0,2}/g, '[redacted]']
316
- export const redactSecrets = (text) => REDACTION_RULES.reduce((acc, [pattern, replacement]) => acc.replace(pattern, replacement), text)
317
- const redactSecretsDeep = (text) => redactSecrets(text).replace(HIGH_ENTROPY_RULE[0], HIGH_ENTROPY_RULE[1])
318
299
  const capActionBody = (text) =>
319
300
  text.length <= ACTION_BODY_MAX ? text : `${text.slice(0, ACTION_BODY_MAX - ACTION_BODY_TRUNCATION_MARKER.length)}${ACTION_BODY_TRUNCATION_MARKER}`
320
301
  const deriveActionBody = (command) => capActionBody(redactSecretsDeep(command))
@@ -0,0 +1,51 @@
1
+ // Generated by scripts/generate-editor-redaction.mjs.
2
+ const CREDENTIAL_NAME = String.raw `(?:authorization|secret|token|password|passwd|api[_-]?key|access[_-]?key|client[_-]?secret|private[_-]?key)["']?`;
3
+ const CREDENTIAL_KEY = String.raw `${CREDENTIAL_NAME}\s*[=:]\s*`;
4
+ const DISPLAYED_CREDENTIAL_KEY = String.raw `${CREDENTIAL_NAME}(?:[ \t]*:[ \t]*|[ \t]+=[ \t]*|=)`;
5
+ const SHELL_INERT_UNIT = String.raw `(?:[A-Za-z0-9_\-./+=:@%^!#]|\\[^\s'"])`;
6
+ const SHELL_INERT_SINGLE_QUOTED_UNIT = String.raw `[A-Za-z0-9_\-./+=:@%^!#\\]`;
7
+ const SHELL_INERT_URL_PASSWORD_UNIT = String.raw `(?:[A-Za-z0-9_\-.+=:%^!#]|\\[^\s'"@/])`;
8
+ const PEM_LINE_BREAK = String.raw `(?:\r?\n|(?:\\r)?\\n)`;
9
+ const credentialAssignmentRule = (key, doubleQuoted, singleQuoted, bare) => ({
10
+ pattern: new RegExp(String.raw `(${key})(?:(")${doubleQuoted}|(')${singleQuoted}|(["']?)${bare})`, 'gi'),
11
+ replacement: '$1$2$3$4[redacted]$2$3',
12
+ });
13
+ const DISPLAYED_SECRET_SHAPES = {
14
+ privateKeyBody: String.raw `${PEM_LINE_BREAK}?(?:(?:Proc-Type|DEK-Info): [A-Za-z0-9,-]+${PEM_LINE_BREAK})*(?:[A-Za-z0-9+/=\r\n]|\\[rn])*?`,
15
+ urlPassword: `${SHELL_INERT_URL_PASSWORD_UNIT}+`,
16
+ authorizationValue: `${SHELL_INERT_UNIT}+`,
17
+ credentialAssignment: credentialAssignmentRule(DISPLAYED_CREDENTIAL_KEY, `${SHELL_INERT_UNIT}*"`, `${SHELL_INERT_SINGLE_QUOTED_UNIT}*'`, `${SHELL_INERT_UNIT}+`),
18
+ };
19
+ const CUT_OFF_SECRET_SHAPES = {
20
+ privateKeyBody: String.raw `[\s\S]*?`,
21
+ urlPassword: String.raw `[^\s@/]+`,
22
+ authorizationValue: String.raw `\S+`,
23
+ credentialAssignment: credentialAssignmentRule(CREDENTIAL_KEY, String.raw `(?:\\[\s\S]|[^"\\])*(?:"|\\?$)`, "[^']*(?:'|$)", String.raw `\S+`),
24
+ };
25
+ const secretRedactionRules = (shapes) => [
26
+ { pattern: /\bpk_[A-Za-z0-9_]+\.[A-Za-z0-9_]+/g, replacement: '[redacted]' },
27
+ { pattern: new RegExp(String.raw `-----BEGIN[A-Z0-9 ]*PRIVATE KEY-----${shapes.privateKeyBody}-----END[A-Z0-9 ]*PRIVATE KEY-----`, 'g'), replacement: '[redacted key]' },
28
+ { pattern: /\bsk-[A-Za-z0-9_-]{16,}\b/g, replacement: '[redacted]' },
29
+ { pattern: /\b[spr]k_(?:live|test)_[A-Za-z0-9]{8,}\b/g, replacement: '[redacted]' },
30
+ { pattern: /\bwhsec_[A-Za-z0-9]{16,}\b/g, replacement: '[redacted]' },
31
+ { pattern: /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36,}\b/g, replacement: '[redacted]' },
32
+ { pattern: /\bgithub_pat_[A-Za-z0-9_]{22,}\b/g, replacement: '[redacted]' },
33
+ { pattern: /\bglpat-[A-Za-z0-9_-]{20,}\b/g, replacement: '[redacted]' },
34
+ { pattern: /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g, replacement: '[redacted]' },
35
+ { pattern: /\bAIza[A-Za-z0-9_-]{35}\b/g, replacement: '[redacted]' },
36
+ { pattern: /\bAKIA[0-9A-Z]{16}\b/g, replacement: '[redacted]' },
37
+ { pattern: /\bnpm_[A-Za-z0-9]{36}\b/g, replacement: '[redacted]' },
38
+ { pattern: /\bxai-[A-Za-z0-9]{16,}\b/g, replacement: '[redacted]' },
39
+ { pattern: /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, replacement: '[redacted]' },
40
+ { pattern: new RegExp(String.raw `\b([a-z][a-z0-9+.-]*:\/\/[^\s:/@]+:)${shapes.urlPassword}@`, 'gi'), replacement: '$1[redacted]@' },
41
+ { pattern: /\bbearer\s+[A-Za-z0-9._~+/=-]+/gi, replacement: 'bearer [redacted]' },
42
+ { pattern: new RegExp(String.raw `\bauthorization:\s*${shapes.authorizationValue}`, 'gi'), replacement: 'authorization: [redacted]' },
43
+ shapes.credentialAssignment,
44
+ ];
45
+ export const SECRET_REDACTION_RULES = secretRedactionRules(DISPLAYED_SECRET_SHAPES);
46
+ const CUT_OFF_TEXT_REDACTION_RULES = secretRedactionRules(CUT_OFF_SECRET_SHAPES);
47
+ const HIGH_ENTROPY_RULE = { pattern: /[A-Za-z0-9+/]{40,}={0,2}/g, replacement: '[redacted]' };
48
+ const applyRedactionRules = (rules, text) => rules.reduce((acc, rule) => acc.replace(rule.pattern, rule.replacement), text);
49
+ export const redactSecrets = (text) => applyRedactionRules(SECRET_REDACTION_RULES, text);
50
+ export const redactSecretsFromContent = (text) => applyRedactionRules(CUT_OFF_TEXT_REDACTION_RULES, text);
51
+ export const redactSecretsDeep = (text) => redactSecrets(text).replace(HIGH_ENTROPY_RULE.pattern, HIGH_ENTROPY_RULE.replacement);
@@ -2,6 +2,7 @@
2
2
  // Pushary VS Code hooks: server policy, fenced phone approvals, and lifecycle telemetry.
3
3
  // Dependency-free for marketplace installs. Regenerate agent-hooks/data after edits.
4
4
 
5
+ import { redactSecrets, redactSecretsDeep } from './redaction.mjs'
5
6
  import { createHash, randomUUID } from 'node:crypto'
6
7
  import { homedir, hostname } from 'node:os'
7
8
  import { existsSync, readFileSync } from 'node:fs'
@@ -337,27 +338,6 @@ const ACTION_BODY_TRUNCATION_MARKER = '\n… [truncated]'
337
338
  // One combined list used to serve both, which meant the only text this gate
338
339
  // scrubbed was the action body. The question and the notification body carried
339
340
  // the raw command.
340
- const REDACTION_RULES = [
341
- [/-----BEGIN[A-Z0-9 ]*PRIVATE KEY-----(?:\r?\n|(?:\\r)?\\n)?(?:(?:Proc-Type|DEK-Info): [A-Za-z0-9,-]+(?:\r?\n|(?:\\r)?\\n))*(?:[A-Za-z0-9+/=\r\n]|\\[rn])*?-----END[A-Z0-9 ]*PRIVATE KEY-----/g, '[redacted key]'],
342
- [/\bsk-[A-Za-z0-9_-]{16,}\b/g, '[redacted]'],
343
- [/\b[spr]k_(?:live|test)_[A-Za-z0-9]{8,}\b/g, '[redacted]'],
344
- [/\bwhsec_[A-Za-z0-9]{16,}\b/g, '[redacted]'],
345
- [/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36,}\b/g, '[redacted]'],
346
- [/\bgithub_pat_[A-Za-z0-9_]{22,}\b/g, '[redacted]'],
347
- [/\bglpat-[A-Za-z0-9_-]{20,}\b/g, '[redacted]'],
348
- [/\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g, '[redacted]'],
349
- [/\bAIza[A-Za-z0-9_-]{35}\b/g, '[redacted]'],
350
- [/\bAKIA[0-9A-Z]{16}\b/g, '[redacted]'],
351
- [/\bnpm_[A-Za-z0-9]{36}\b/g, '[redacted]'],
352
- [/\bxai-[A-Za-z0-9]{16,}\b/g, '[redacted]'],
353
- [/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, '[redacted]'],
354
- [/\bbearer\s+[A-Za-z0-9._~+/=-]+/gi, 'bearer [redacted]'],
355
- [/\bauthorization:\s*(?:[A-Za-z0-9_\-./+=:@%^!#]|\\[^\s'"])+/gi, 'authorization: [redacted]'],
356
- [/((?:secret|token|password|passwd|api[_-]?key|access[_-]?key|client[_-]?secret|private[_-]?key)["']?(?:[ \t]*:[ \t]*|[ \t]+=[ \t]*|=))(?:(")(?:[A-Za-z0-9_\-./+=:@%^!#]|\\[^\s'"])*"|(')[A-Za-z0-9_\-./+=:@%^!#\\]*'|(["']?)(?:[A-Za-z0-9_\-./+=:@%^!#]|\\[^\s'"])+)/gi, '$1$2$3$4[redacted]$2$3'],
357
- ]
358
- const HIGH_ENTROPY_RULE = [/[A-Za-z0-9+/]{40,}={0,2}/g, '[redacted]']
359
- const redactSecrets = (text) => REDACTION_RULES.reduce((acc, [pattern, replacement]) => acc.replace(pattern, replacement), text)
360
- const redactSecretsDeep = (text) => redactSecrets(text).replace(HIGH_ENTROPY_RULE[0], HIGH_ENTROPY_RULE[1])
361
341
  const capActionBody = (text) =>
362
342
  text.length <= ACTION_BODY_MAX ? text : `${text.slice(0, ACTION_BODY_MAX - ACTION_BODY_TRUNCATION_MARKER.length)}${ACTION_BODY_TRUNCATION_MARKER}`
363
343
  const deriveActionBody = (command) => capActionBody(redactSecretsDeep(command))
@@ -0,0 +1,51 @@
1
+ // Generated by scripts/generate-editor-redaction.mjs.
2
+ const CREDENTIAL_NAME = String.raw `(?:authorization|secret|token|password|passwd|api[_-]?key|access[_-]?key|client[_-]?secret|private[_-]?key)["']?`;
3
+ const CREDENTIAL_KEY = String.raw `${CREDENTIAL_NAME}\s*[=:]\s*`;
4
+ const DISPLAYED_CREDENTIAL_KEY = String.raw `${CREDENTIAL_NAME}(?:[ \t]*:[ \t]*|[ \t]+=[ \t]*|=)`;
5
+ const SHELL_INERT_UNIT = String.raw `(?:[A-Za-z0-9_\-./+=:@%^!#]|\\[^\s'"])`;
6
+ const SHELL_INERT_SINGLE_QUOTED_UNIT = String.raw `[A-Za-z0-9_\-./+=:@%^!#\\]`;
7
+ const SHELL_INERT_URL_PASSWORD_UNIT = String.raw `(?:[A-Za-z0-9_\-.+=:%^!#]|\\[^\s'"@/])`;
8
+ const PEM_LINE_BREAK = String.raw `(?:\r?\n|(?:\\r)?\\n)`;
9
+ const credentialAssignmentRule = (key, doubleQuoted, singleQuoted, bare) => ({
10
+ pattern: new RegExp(String.raw `(${key})(?:(")${doubleQuoted}|(')${singleQuoted}|(["']?)${bare})`, 'gi'),
11
+ replacement: '$1$2$3$4[redacted]$2$3',
12
+ });
13
+ const DISPLAYED_SECRET_SHAPES = {
14
+ privateKeyBody: String.raw `${PEM_LINE_BREAK}?(?:(?:Proc-Type|DEK-Info): [A-Za-z0-9,-]+${PEM_LINE_BREAK})*(?:[A-Za-z0-9+/=\r\n]|\\[rn])*?`,
15
+ urlPassword: `${SHELL_INERT_URL_PASSWORD_UNIT}+`,
16
+ authorizationValue: `${SHELL_INERT_UNIT}+`,
17
+ credentialAssignment: credentialAssignmentRule(DISPLAYED_CREDENTIAL_KEY, `${SHELL_INERT_UNIT}*"`, `${SHELL_INERT_SINGLE_QUOTED_UNIT}*'`, `${SHELL_INERT_UNIT}+`),
18
+ };
19
+ const CUT_OFF_SECRET_SHAPES = {
20
+ privateKeyBody: String.raw `[\s\S]*?`,
21
+ urlPassword: String.raw `[^\s@/]+`,
22
+ authorizationValue: String.raw `\S+`,
23
+ credentialAssignment: credentialAssignmentRule(CREDENTIAL_KEY, String.raw `(?:\\[\s\S]|[^"\\])*(?:"|\\?$)`, "[^']*(?:'|$)", String.raw `\S+`),
24
+ };
25
+ const secretRedactionRules = (shapes) => [
26
+ { pattern: /\bpk_[A-Za-z0-9_]+\.[A-Za-z0-9_]+/g, replacement: '[redacted]' },
27
+ { pattern: new RegExp(String.raw `-----BEGIN[A-Z0-9 ]*PRIVATE KEY-----${shapes.privateKeyBody}-----END[A-Z0-9 ]*PRIVATE KEY-----`, 'g'), replacement: '[redacted key]' },
28
+ { pattern: /\bsk-[A-Za-z0-9_-]{16,}\b/g, replacement: '[redacted]' },
29
+ { pattern: /\b[spr]k_(?:live|test)_[A-Za-z0-9]{8,}\b/g, replacement: '[redacted]' },
30
+ { pattern: /\bwhsec_[A-Za-z0-9]{16,}\b/g, replacement: '[redacted]' },
31
+ { pattern: /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36,}\b/g, replacement: '[redacted]' },
32
+ { pattern: /\bgithub_pat_[A-Za-z0-9_]{22,}\b/g, replacement: '[redacted]' },
33
+ { pattern: /\bglpat-[A-Za-z0-9_-]{20,}\b/g, replacement: '[redacted]' },
34
+ { pattern: /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g, replacement: '[redacted]' },
35
+ { pattern: /\bAIza[A-Za-z0-9_-]{35}\b/g, replacement: '[redacted]' },
36
+ { pattern: /\bAKIA[0-9A-Z]{16}\b/g, replacement: '[redacted]' },
37
+ { pattern: /\bnpm_[A-Za-z0-9]{36}\b/g, replacement: '[redacted]' },
38
+ { pattern: /\bxai-[A-Za-z0-9]{16,}\b/g, replacement: '[redacted]' },
39
+ { pattern: /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, replacement: '[redacted]' },
40
+ { pattern: new RegExp(String.raw `\b([a-z][a-z0-9+.-]*:\/\/[^\s:/@]+:)${shapes.urlPassword}@`, 'gi'), replacement: '$1[redacted]@' },
41
+ { pattern: /\bbearer\s+[A-Za-z0-9._~+/=-]+/gi, replacement: 'bearer [redacted]' },
42
+ { pattern: new RegExp(String.raw `\bauthorization:\s*${shapes.authorizationValue}`, 'gi'), replacement: 'authorization: [redacted]' },
43
+ shapes.credentialAssignment,
44
+ ];
45
+ export const SECRET_REDACTION_RULES = secretRedactionRules(DISPLAYED_SECRET_SHAPES);
46
+ const CUT_OFF_TEXT_REDACTION_RULES = secretRedactionRules(CUT_OFF_SECRET_SHAPES);
47
+ const HIGH_ENTROPY_RULE = { pattern: /[A-Za-z0-9+/]{40,}={0,2}/g, replacement: '[redacted]' };
48
+ const applyRedactionRules = (rules, text) => rules.reduce((acc, rule) => acc.replace(rule.pattern, rule.replacement), text);
49
+ export const redactSecrets = (text) => applyRedactionRules(SECRET_REDACTION_RULES, text);
50
+ export const redactSecretsFromContent = (text) => applyRedactionRules(CUT_OFF_TEXT_REDACTION_RULES, text);
51
+ export const redactSecretsDeep = (text) => redactSecrets(text).replace(HIGH_ENTROPY_RULE.pattern, HIGH_ENTROPY_RULE.replacement);
@@ -1,38 +1,38 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleBell
4
- } from "../chunk-IWJKSIB4.js";
4
+ } from "../chunk-IPVKH2ST.js";
5
5
  import {
6
6
  readHookInput
7
- } from "../chunk-7RUJKCR4.js";
8
- import "../chunk-OTNOANMX.js";
7
+ } from "../chunk-KGDWDSNL.js";
8
+ import "../chunk-JZTHGAPA.js";
9
9
  import "../chunk-SGZJ5LYH.js";
10
- import "../chunk-TCVMK6GI.js";
11
- import "../chunk-BGBLLHZ4.js";
12
- import "../chunk-3EUBQARL.js";
13
- import "../chunk-WTJM7PSL.js";
14
- import "../chunk-ZKJ34T2F.js";
15
- import "../chunk-MIXWMA73.js";
16
- import "../chunk-NOI3XTCY.js";
17
- import "../chunk-P2VIBGXA.js";
18
- import "../chunk-WPX67AKT.js";
19
- import "../chunk-LPNJLKBQ.js";
10
+ import "../chunk-EYK3GSRH.js";
11
+ import "../chunk-ZVSKMPBZ.js";
12
+ import "../chunk-C2WCPBF7.js";
13
+ import "../chunk-6J2JC2RT.js";
14
+ import "../chunk-WE2J62NC.js";
15
+ import "../chunk-3EVPNIBE.js";
16
+ import "../chunk-OKXS7WDZ.js";
17
+ import "../chunk-MPWXGONV.js";
18
+ import "../chunk-SAXBC4AZ.js";
19
+ import "../chunk-OLQRRFBX.js";
20
20
  import "../chunk-XHKBHWLX.js";
21
- import "../chunk-EUGNVLMG.js";
22
- import "../chunk-N5MZH5A6.js";
21
+ import "../chunk-EPCXUP3P.js";
22
+ import "../chunk-CVQYGMSR.js";
23
23
  import "../chunk-POFBE6ZY.js";
24
24
  import "../chunk-GMXKITVA.js";
25
- import "../chunk-D6OODZCM.js";
26
- import "../chunk-DUQO4C4I.js";
27
- import "../chunk-OVC5QXN5.js";
25
+ import "../chunk-P7WQEVWA.js";
26
+ import "../chunk-2OY3ZZ5N.js";
27
+ import "../chunk-LXQ5FBBD.js";
28
28
  import "../chunk-7QLSKOSU.js";
29
29
  import "../chunk-KZERVKTD.js";
30
- import "../chunk-62CVUUNU.js";
31
- import "../chunk-MZBRL5H5.js";
30
+ import "../chunk-DB3ONZB4.js";
31
+ import "../chunk-A2A2YTMG.js";
32
32
  import "../chunk-T7E75EKA.js";
33
- import "../chunk-R6OYCUNK.js";
34
- import "../chunk-YYCTF4Q5.js";
35
- import "../chunk-G4GLCLKK.js";
33
+ import "../chunk-GPEGOGRJ.js";
34
+ import "../chunk-E4FJTUH4.js";
35
+ import "../chunk-NQTHFF4W.js";
36
36
 
37
37
  // bin/pushary-bell-hook.ts
38
38
  var main = async () => {
@@ -5,37 +5,37 @@ import {
5
5
  liveAgentCount,
6
6
  ring,
7
7
  upgradeThreshold
8
- } from "../chunk-IWJKSIB4.js";
8
+ } from "../chunk-IPVKH2ST.js";
9
9
  import {
10
10
  addBellHooks,
11
11
  bellInstalled,
12
12
  removeBellHooks
13
- } from "../chunk-NOI3XTCY.js";
13
+ } from "../chunk-OKXS7WDZ.js";
14
14
  import {
15
15
  createIo
16
16
  } from "../chunk-U4TMAANR.js";
17
17
  import {
18
18
  exitOnHelpFlag
19
- } from "../chunk-5S2VBSJI.js";
19
+ } from "../chunk-HZVVNGEW.js";
20
20
  import {
21
21
  parseFlags
22
22
  } from "../chunk-GMXKITVA.js";
23
- import "../chunk-D6OODZCM.js";
23
+ import "../chunk-P7WQEVWA.js";
24
24
  import "../chunk-7QLSKOSU.js";
25
25
  import {
26
26
  EXIT
27
27
  } from "../chunk-KZERVKTD.js";
28
- import "../chunk-62CVUUNU.js";
28
+ import "../chunk-DB3ONZB4.js";
29
29
  import {
30
30
  claudeSettings
31
- } from "../chunk-MZBRL5H5.js";
31
+ } from "../chunk-A2A2YTMG.js";
32
32
  import {
33
33
  readJsonSafe,
34
34
  writeJsonAtomic
35
35
  } from "../chunk-T7E75EKA.js";
36
- import "../chunk-R6OYCUNK.js";
37
- import "../chunk-YYCTF4Q5.js";
38
- import "../chunk-G4GLCLKK.js";
36
+ import "../chunk-GPEGOGRJ.js";
37
+ import "../chunk-E4FJTUH4.js";
38
+ import "../chunk-NQTHFF4W.js";
39
39
 
40
40
  // bin/pushary-bell.ts
41
41
  exitOnHelpFlag("bell");
@@ -8,7 +8,7 @@ import {
8
8
  describeIdleWindow,
9
9
  startProcessOwnership,
10
10
  withSpawnProcessOwnership
11
- } from "../chunk-LHC45YUC.js";
11
+ } from "../chunk-ZSZSSJCV.js";
12
12
  import {
13
13
  announceSubscriptionRequired,
14
14
  isDeferAnswer
@@ -18,24 +18,24 @@ import {
18
18
  loadSessionKey,
19
19
  registerTranscript,
20
20
  registeredTranscriptEnabled
21
- } from "../chunk-OTNOANMX.js";
21
+ } from "../chunk-JZTHGAPA.js";
22
22
  import "../chunk-SGZJ5LYH.js";
23
- import "../chunk-TCVMK6GI.js";
24
- import "../chunk-BGBLLHZ4.js";
25
- import "../chunk-3EUBQARL.js";
26
- import "../chunk-WTJM7PSL.js";
23
+ import "../chunk-EYK3GSRH.js";
24
+ import "../chunk-ZVSKMPBZ.js";
25
+ import "../chunk-C2WCPBF7.js";
26
+ import "../chunk-6J2JC2RT.js";
27
27
  import {
28
28
  ensureDaemonRunning
29
- } from "../chunk-ZKJ34T2F.js";
30
- import "../chunk-MIXWMA73.js";
31
- import "../chunk-NOI3XTCY.js";
29
+ } from "../chunk-WE2J62NC.js";
30
+ import "../chunk-3EVPNIBE.js";
31
+ import "../chunk-OKXS7WDZ.js";
32
32
  import {
33
33
  encryptRecord
34
- } from "../chunk-P2VIBGXA.js";
35
- import "../chunk-WPX67AKT.js";
34
+ } from "../chunk-MPWXGONV.js";
35
+ import "../chunk-SAXBC4AZ.js";
36
36
  import {
37
37
  transcriptsEnabled
38
- } from "../chunk-LPNJLKBQ.js";
38
+ } from "../chunk-OLQRRFBX.js";
39
39
  import {
40
40
  needsShell,
41
41
  spawnClaude
@@ -50,7 +50,7 @@ import {
50
50
  repoKeyFor,
51
51
  reportEvent,
52
52
  scopePathFor
53
- } from "../chunk-U6RVDUJ5.js";
53
+ } from "../chunk-CULUZTWQ.js";
54
54
  import {
55
55
  DEFAULT_SESSION,
56
56
  markPendingCommandDelivered,
@@ -60,7 +60,7 @@ import {
60
60
  removePendingCommand,
61
61
  savePendingCommand
62
62
  } from "../chunk-N6IOSZOE.js";
63
- import "../chunk-EUGNVLMG.js";
63
+ import "../chunk-EPCXUP3P.js";
64
64
  import {
65
65
  DECISION_STOP_REASON,
66
66
  UNVERIFIABLE_APPROVAL_REASON,
@@ -71,36 +71,36 @@ import {
71
71
  nextLongPollMs,
72
72
  waitForAnswer,
73
73
  withdrawQuestion
74
- } from "../chunk-YC27PROF.js";
75
- import "../chunk-N5MZH5A6.js";
74
+ } from "../chunk-NGDD6TXY.js";
75
+ import "../chunk-CVQYGMSR.js";
76
76
  import "../chunk-POFBE6ZY.js";
77
77
  import "../chunk-GMXKITVA.js";
78
- import "../chunk-D6OODZCM.js";
78
+ import "../chunk-P7WQEVWA.js";
79
79
  import {
80
80
  SubscriptionRequiredError
81
- } from "../chunk-VE7TXLR4.js";
82
- import "../chunk-EEEJ2JIL.js";
83
- import "../chunk-DUQO4C4I.js";
81
+ } from "../chunk-M5ICYGHT.js";
82
+ import "../chunk-2ABTSGFT.js";
83
+ import "../chunk-2OY3ZZ5N.js";
84
84
  import {
85
85
  getMachineId
86
- } from "../chunk-OVC5QXN5.js";
86
+ } from "../chunk-LXQ5FBBD.js";
87
87
  import "../chunk-7QLSKOSU.js";
88
88
  import "../chunk-KZERVKTD.js";
89
- import "../chunk-62CVUUNU.js";
90
- import "../chunk-MZBRL5H5.js";
89
+ import "../chunk-DB3ONZB4.js";
90
+ import "../chunk-A2A2YTMG.js";
91
91
  import "../chunk-T7E75EKA.js";
92
92
  import {
93
93
  getApiKey,
94
94
  getBaseUrl
95
- } from "../chunk-R6OYCUNK.js";
95
+ } from "../chunk-GPEGOGRJ.js";
96
96
  import {
97
97
  NPX_LATEST_COMMAND
98
- } from "../chunk-YYCTF4Q5.js";
98
+ } from "../chunk-E4FJTUH4.js";
99
99
  import {
100
100
  KILL_REASON,
101
101
  redactSecretsFromContent,
102
102
  resolveGate
103
- } from "../chunk-G4GLCLKK.js";
103
+ } from "../chunk-NQTHFF4W.js";
104
104
 
105
105
  // src/wrapper/localPassthrough.ts
106
106
  var SIGNAL_NUMBERS = {