@pushary/agent-hooks 1.7.1 → 1.7.3
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 +21 -0
- package/data/cursor-plugin/CHANGELOG.md +1 -0
- package/data/cursor-plugin/scripts/pushary-gate.mjs +3 -3
- package/data/cursor-plugin/scripts/pushary-gate.test.mjs +23 -1
- package/data/vscode-plugin/CHANGELOG.md +1 -0
- package/data/vscode-plugin/scripts/pushary-gate.mjs +3 -3
- package/dist/bin/pushary-bell-hook.js +23 -23
- package/dist/bin/pushary-bell.js +10 -10
- package/dist/bin/pushary-claude.js +48 -37
- package/dist/bin/pushary-clean.js +107 -60
- package/dist/bin/pushary-codex-bridge.js +18 -17
- package/dist/bin/pushary-codex-hook.js +53 -39
- package/dist/bin/pushary-codex.js +14 -12
- package/dist/bin/pushary-connect.js +16 -16
- package/dist/bin/pushary-cowork.js +5 -5
- package/dist/bin/pushary-daemon.js +27 -27
- package/dist/bin/pushary-disconnect.js +19 -17
- package/dist/bin/pushary-doctor.js +63 -35
- package/dist/bin/pushary-elicitation-hook.js +35 -26
- package/dist/bin/pushary-gemini-bridge.js +12 -12
- package/dist/bin/pushary-gemini-hook.js +47 -32
- package/dist/bin/pushary-hook.js +34 -32
- package/dist/bin/pushary-login.js +16 -16
- package/dist/bin/pushary-logout.js +8 -8
- package/dist/bin/pushary-mcp.js +9 -8
- package/dist/bin/pushary-mode.js +10 -10
- package/dist/bin/pushary-notification-hook.js +29 -27
- package/dist/bin/pushary-opencode-hook.js +46 -32
- package/dist/bin/pushary-permission-denied-hook.js +34 -32
- package/dist/bin/pushary-permission-hook.js +33 -31
- package/dist/bin/pushary-post-hook.js +29 -27
- package/dist/bin/pushary-prompt-hook.js +29 -27
- package/dist/bin/pushary-session-end-hook.js +29 -27
- package/dist/bin/pushary-session-start-hook.js +33 -31
- package/dist/bin/pushary-setup.js +69 -56
- package/dist/bin/pushary-stats.js +5 -5
- package/dist/bin/pushary-status.js +19 -19
- package/dist/bin/pushary-stop-hook.js +29 -27
- package/dist/bin/pushary-stopfailure-hook.js +29 -27
- package/dist/bin/pushary-suggestions.js +5 -5
- package/dist/bin/pushary-transcript-register.js +19 -19
- package/dist/bin/pushary-transcripts.js +7 -7
- package/dist/bin/pushary-upgrade.js +20 -20
- package/dist/bin/pushary-wait.js +10 -10
- package/dist/bin/pushary.js +6 -6
- package/dist/{chunk-MWVCDP64.js → chunk-3EUBQARL.js} +1 -1
- package/dist/{chunk-3QORH5EJ.js → chunk-5GB22QYL.js} +6 -4
- package/dist/chunk-5OP5MQI7.js +45 -0
- package/dist/{chunk-6PV2JQ64.js → chunk-5S2VBSJI.js} +2 -2
- package/dist/{chunk-UPKP67TA.js → chunk-62CVUUNU.js} +2 -2
- package/dist/{chunk-42XR73I2.js → chunk-62VT3BPH.js} +35 -35
- package/dist/chunk-6JQFIHZC.js +99 -0
- package/dist/{chunk-2FU43B5Q.js → chunk-7OA34PNW.js} +2 -2
- package/dist/{chunk-7GI6QC3M.js → chunk-7RUJKCR4.js} +2 -2
- package/dist/{chunk-H6JV44TE.js → chunk-AWVNAYGD.js} +1 -1
- package/dist/{chunk-XMN37YJH.js → chunk-BGBLLHZ4.js} +1 -1
- package/dist/{chunk-VCMFKZON.js → chunk-BIH2Y2HP.js} +2 -2
- package/dist/{chunk-YZKS3ME3.js → chunk-D6OODZCM.js} +2 -2
- package/dist/{chunk-JTQDP4ZL.js → chunk-DUQO4C4I.js} +3 -3
- package/dist/{chunk-3QE3BHBW.js → chunk-EADXTSHE.js} +2 -2
- package/dist/{chunk-43SSQCWO.js → chunk-EEEJ2JIL.js} +3 -3
- package/dist/{chunk-4C4NRDIC.js → chunk-EUGNVLMG.js} +1 -1
- package/dist/{chunk-WSC53O7I.js → chunk-G3OMOTJ4.js} +3 -3
- package/dist/{chunk-XFNVG3OV.js → chunk-G4GLCLKK.js} +44 -9
- package/dist/{chunk-62TEPRWQ.js → chunk-G62JL2NT.js} +1 -1
- package/dist/{chunk-QPR33SHS.js → chunk-G6RRVJOG.js} +6 -6
- package/dist/{chunk-Y6GKOZBT.js → chunk-IPSRMLCJ.js} +1 -1
- package/dist/{chunk-MCNS4725.js → chunk-IRZG3HEU.js} +1 -1
- package/dist/{chunk-55RO62FV.js → chunk-IWJKSIB4.js} +1 -1
- package/dist/{chunk-NID4UZDN.js → chunk-KEL5MXRL.js} +1 -1
- package/dist/{chunk-BYVB3RX3.js → chunk-KJXUIPS4.js} +2 -2
- package/dist/{chunk-SNWNA3MQ.js → chunk-LHC45YUC.js} +1 -1
- package/dist/{chunk-XPTCPU6V.js → chunk-LPNJLKBQ.js} +1 -1
- package/dist/{chunk-WZWXBTRF.js → chunk-MIXWMA73.js} +3 -3
- package/dist/{chunk-454KMJHF.js → chunk-MZBRL5H5.js} +34 -1
- package/dist/{chunk-KSNAAMU5.js → chunk-N5MZH5A6.js} +4 -4
- package/dist/chunk-N6IOSZOE.js +185 -0
- package/dist/{chunk-XPMOCJHN.js → chunk-NOI3XTCY.js} +1 -1
- package/dist/{chunk-NAAZCNKI.js → chunk-O3JDWNLU.js} +351 -37
- package/dist/{chunk-7GYGVQBU.js → chunk-OTNOANMX.js} +8 -8
- package/dist/{chunk-P5CBNSYL.js → chunk-OVC5QXN5.js} +1 -1
- package/dist/{chunk-O5JD7UI5.js → chunk-P2VIBGXA.js} +3 -3
- package/dist/{chunk-3T35OE7C.js → chunk-PRNFSORD.js} +4 -4
- package/dist/{chunk-OAL44FM2.js → chunk-R6OYCUNK.js} +1 -1
- package/dist/{chunk-6SJQ442W.js → chunk-RLW3JWDY.js} +2 -2
- package/dist/{chunk-SVEMF2VO.js → chunk-TCVMK6GI.js} +4 -4
- package/dist/{chunk-O5PRIYFZ.js → chunk-U4TMAANR.js} +3 -0
- package/dist/{chunk-WM3U2RUK.js → chunk-U6RVDUJ5.js} +75 -232
- package/dist/{chunk-KBLIVEFJ.js → chunk-UOQRM7JQ.js} +5 -5
- package/dist/{chunk-NQFGVAT6.js → chunk-VE7TXLR4.js} +19 -2
- package/dist/{chunk-IGBDOZUO.js → chunk-VKVSRCBO.js} +1 -1
- package/dist/{chunk-ZEMSCGDD.js → chunk-VYPJHGG6.js} +8 -3
- package/dist/{chunk-YQN7S57T.js → chunk-WGMW7OXW.js} +6 -6
- package/dist/{chunk-OTZHT34O.js → chunk-WPX67AKT.js} +1 -1
- package/dist/{chunk-XDASEYRS.js → chunk-WTJM7PSL.js} +3 -3
- package/dist/{chunk-Q7QRR6YL.js → chunk-Y4ZH64UK.js} +2 -2
- package/dist/{chunk-ZIIYTQHC.js → chunk-YC27PROF.js} +12 -4
- package/dist/{chunk-AHWJHLG5.js → chunk-YPUBA2FL.js} +7 -5
- package/dist/{chunk-EIZW73P5.js → chunk-YYCTF4Q5.js} +1 -1
- package/dist/{chunk-AAGLDXH4.js → chunk-ZKJ34T2F.js} +5 -5
- package/dist/{reapply-66GQIBXN.js → reapply-PH5T4BGR.js} +9 -9
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +22 -20
- package/package.json +2 -1
- package/dist/chunk-JMBG47WV.js +0 -336
- package/dist/chunk-YHG74UFF.js +0 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.7.3
|
|
4
|
+
|
|
5
|
+
- **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.
|
|
6
|
+
|
|
7
|
+
## 1.7.2
|
|
8
|
+
|
|
9
|
+
- **Approval text shows the whole command again.** A credential name that closes a quoted string, as in `grep -rl "password=" . | xargs rm -f`, made 1.7.1 redact everything after it, so the approval read `grep -rl "password="[redacted]"` and hid the `rm`. The value after a credential name is still redacted, and the rest of the command is shown.
|
|
10
|
+
- **Hermes works again after an uninstall.** When setup found Pushary's own Hermes settings already in `~/.hermes/config.yaml`, left by an earlier install, its record of your config included them, and `pushary clean` put them back: approvals stayed pointed at the plugin clean had just uninstalled, and Hermes' `clarify` tool stayed off, so Hermes could not ask you anything in the terminal. Clean now recognises Pushary's own values in that record, including records older versions wrote, and removes `transport: pushary`, the `pushary` plugin entry, and the `clarify` entry that came with Pushary's transport, while restoring everything else you set. Running clean again, or after the Mac app has disconnected Hermes, no longer fails once Hermes' defaults fill the removed settings back in.
|
|
11
|
+
- `pushary clean` says what it did to Hermes: "Pushary settings removed" only when it changed `config.yaml`, "no Pushary settings" when there was nothing of ours, and it skips the plugin uninstall when the plugin is not installed. `--dry-run` previews the exact change without saving it.
|
|
12
|
+
- `pushary doctor` checks Hermes when Pushary set it up: that the plugin is installed in Hermes' Python and enabled, and whether approvals and questions go through Pushary. A plugin the Mac app left installed but disabled is not reported as a failure.
|
|
13
|
+
- Setup on a machine without npm now says so and asks you to install Node.js, instead of printing `/bin/sh: npm: command not found` and suggesting an `npx` retry that needs npm too. Pushary still needs npm; bun, pnpm and yarn installs are not supported yet.
|
|
14
|
+
- `pushary clean` tells an npm it cannot find, a package that is not installed and a failed uninstall apart, instead of calling each of them "not installed". A failed uninstall no longer ends in "Clean complete".
|
|
15
|
+
- `pushary clean --dry-run` lists only the Mac keychain items and preference domains that exist, and the fx setup record only when there is one. It used to list every candidate it would try. A keychain that cannot be read, for example while locked, still counts as possibly holding Pushary's items, so clean tries them and reports a failure instead of calling the keychain clean.
|
|
16
|
+
- `pushary clean` honours `NO_COLOR`.
|
|
17
|
+
- Setup's agent picker shows only the names you picked once you confirm, instead of repeating every agent's description, and the transcript notice is indented like the lines around it.
|
|
18
|
+
- A message you send from your phone or the Mac notch while Claude Code is running a subagent now waits for Claude Code itself. It used to be handed to the subagent's next tool call, where the main conversation never saw it.
|
|
19
|
+
- When your Pushary workspace has no active subscription, Pushary now steps aside and your agent's own approval prompt decides, as it does when Pushary is not installed. Claude Code, Codex, Gemini CLI and OpenCode used to refuse gated tool calls instead, telling you to retry or that the approval was cancelled, and Claude Code questions, plan approvals and MCP forms stopped the same way. A kill switch and your deny rules still apply.
|
|
20
|
+
- Your agent's terminal says once per session why Pushary stepped aside, with the link to subscribe.
|
|
21
|
+
- A Claude Code or Gemini CLI session started from your phone has no prompt on your machine, so it still refuses the call, now saying the workspace has no active subscription instead of asking you to retry.
|
|
22
|
+
- Pairing your phone during setup now says when your workspace has no active subscription, and to subscribe in the Pushary app or at pushary.com before running setup again. It used to say only that pairing failed.
|
|
23
|
+
|
|
3
24
|
## 1.7.1
|
|
4
25
|
|
|
5
26
|
- **fx asks through Pushary.** Setup now adds `"ask_user_question": "deny"` as the last rule in `~/.fx/settings.json`, which removes fx's own terminal question tool from what its agent can call, so every question goes through `mcp_pushary_ask_user`: to the Mac notch at the Mac, to the phone away from it. fx cannot forward its own prompt, so a question asked there used to wait unseen once you walked away. A rule you already set for `ask_user_question` is kept, and setup names it. The instructions in `~/.fx/AGENTS.md` now tell fx's agent to load `mcp_pushary_ask_user` with `mcp_select_tool` by exact name and to ask there even while you are at the terminal, and to ask in its reply only when Pushary hands the question back or cannot be reached.
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## 0.2.3
|
|
4
4
|
|
|
5
|
+
- Approval text never hides part of a command. The value after a credential name is hidden only up to the first space, quote or piece of shell syntax, so `echo "password=" && rm -rf ~` and `eval TOKEN="x; rm -rf ~"` both show the `rm`. A private key block is hidden only when it holds nothing but the key.
|
|
5
6
|
- Updates and Terminal hand an approval back to Cursor promptly. The gate no longer waits for a phone answer that Updates never asks for, and it withdraws the phone question before Cursor decides. An answer that arrives in that moment still counts.
|
|
6
7
|
- A file change that goes back to the agent's own permissions is refused with the reason, because Cursor file hooks cannot show a local approval. Choose Every time for file changes you want to approve from your phone.
|
|
7
8
|
- With no phone or other notification channel connected, a file change is refused with a message that says so. Shell commands and MCP calls still open Cursor's own prompt with "No device connected, approve here."
|
|
@@ -295,7 +295,7 @@ export const describeNetworkFailure = (error, env = process.env) => {
|
|
|
295
295
|
const ACTION_BODY_MAX = 4000
|
|
296
296
|
const ACTION_BODY_TRUNCATION_MARKER = '\n… [truncated]'
|
|
297
297
|
const REDACTION_RULES = [
|
|
298
|
-
[/-----BEGIN[A-Z0-9 ]*PRIVATE KEY-----[\
|
|
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
299
|
[/\bsk-[A-Za-z0-9_-]{16,}\b/g, '[redacted]'],
|
|
300
300
|
[/\b[spr]k_(?:live|test)_[A-Za-z0-9]{8,}\b/g, '[redacted]'],
|
|
301
301
|
[/\bwhsec_[A-Za-z0-9]{16,}\b/g, '[redacted]'],
|
|
@@ -309,8 +309,8 @@ const REDACTION_RULES = [
|
|
|
309
309
|
[/\bxai-[A-Za-z0-9]{16,}\b/g, '[redacted]'],
|
|
310
310
|
[/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, '[redacted]'],
|
|
311
311
|
[/\bbearer\s+[A-Za-z0-9._~+/=-]+/gi, 'bearer [redacted]'],
|
|
312
|
-
[/\bauthorization:\s
|
|
313
|
-
[/((?:secret|token|password|passwd|api[_-]?key|access[_-]?key|client[_-]?secret|private[_-]?key)\
|
|
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
314
|
]
|
|
315
315
|
const HIGH_ENTROPY_RULE = [/[A-Za-z0-9+/]{40,}={0,2}/g, '[redacted]']
|
|
316
316
|
export const redactSecrets = (text) => REDACTION_RULES.reduce((acc, [pattern, replacement]) => acc.replace(pattern, replacement), text)
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import assert from 'node:assert/strict'
|
|
16
16
|
import { describe, it } from 'node:test'
|
|
17
|
-
import { describeRequest, normalizeRepoRemote } from './pushary-gate.mjs'
|
|
17
|
+
import { describeRequest, normalizeRepoRemote, redactSecrets } from './pushary-gate.mjs'
|
|
18
18
|
|
|
19
19
|
describe('repo identity', () => {
|
|
20
20
|
it('collapses the forms of one remote', () => {
|
|
@@ -113,3 +113,25 @@ describe('what the gate was asked about', () => {
|
|
|
113
113
|
assert.equal(describeRequest({}), null)
|
|
114
114
|
})
|
|
115
115
|
})
|
|
116
|
+
|
|
117
|
+
describe('approval text redaction', () => {
|
|
118
|
+
it('shows a command whole when a credential name only sits next to shell syntax', () => {
|
|
119
|
+
for (const command of [
|
|
120
|
+
'echo "password=" && rm -rf ~ && echo "x"',
|
|
121
|
+
'find / -name "token:" -o -delete -o -name "x"',
|
|
122
|
+
"grep -rl foo'password=' . | xargs rm -f 'important file'",
|
|
123
|
+
'grep "authorization:";rm important-file',
|
|
124
|
+
'echo "-----BEGIN PRIVATE KEY-----" && rm -rf ~ && echo "-----END PRIVATE KEY-----"',
|
|
125
|
+
'password= reboot',
|
|
126
|
+
]) {
|
|
127
|
+
assert.equal(redactSecrets(command), command)
|
|
128
|
+
}
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
it('stops a hidden value at the first space, quote or piece of shell syntax', () => {
|
|
132
|
+
assert.equal(redactSecrets('eval TOKEN="x; rm -rf ~"'), 'eval TOKEN="[redacted]; rm -rf ~"')
|
|
133
|
+
assert.equal(redactSecrets('TOKEN=abc;rm file'), 'TOKEN=[redacted];rm file')
|
|
134
|
+
assert.equal(redactSecrets('rm -rf {password=x,/}'), 'rm -rf {password=[redacted],/}')
|
|
135
|
+
assert.equal(redactSecrets('export API_KEY="abc123" && rm -rf build'), 'export API_KEY="[redacted]" && rm -rf build')
|
|
136
|
+
})
|
|
137
|
+
})
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## 0.2.3
|
|
4
4
|
|
|
5
|
+
- Approval text never hides part of a command. The value after a credential name is hidden only up to the first space, quote or piece of shell syntax, so `echo "password=" && rm -rf ~` and `eval TOKEN="x; rm -rf ~"` both show the `rm`. A private key block is hidden only when it holds nothing but the key.
|
|
5
6
|
- Updates hands an approval back to VS Code promptly. The gate no longer waits for a phone answer that Updates never asks for, and it withdraws the phone question before VS Code asks. An answer that arrives in that moment still counts.
|
|
6
7
|
- With no phone or other notification channel connected, VS Code's prompt says "No device connected, approve here." instead of naming a delivery mode.
|
|
7
8
|
- Approval questions carry the repository and the tool name the gate judged, so routing and repository rules apply to the question as they did to the gate. A file edit is asked about with its full path, so path rules and routing match it. A path longer than 80 characters falls back to the file type instead of making the question fail.
|
|
@@ -338,7 +338,7 @@ const ACTION_BODY_TRUNCATION_MARKER = '\n… [truncated]'
|
|
|
338
338
|
// scrubbed was the action body. The question and the notification body carried
|
|
339
339
|
// the raw command.
|
|
340
340
|
const REDACTION_RULES = [
|
|
341
|
-
[/-----BEGIN[A-Z0-9 ]*PRIVATE KEY-----[\
|
|
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
342
|
[/\bsk-[A-Za-z0-9_-]{16,}\b/g, '[redacted]'],
|
|
343
343
|
[/\b[spr]k_(?:live|test)_[A-Za-z0-9]{8,}\b/g, '[redacted]'],
|
|
344
344
|
[/\bwhsec_[A-Za-z0-9]{16,}\b/g, '[redacted]'],
|
|
@@ -352,8 +352,8 @@ const REDACTION_RULES = [
|
|
|
352
352
|
[/\bxai-[A-Za-z0-9]{16,}\b/g, '[redacted]'],
|
|
353
353
|
[/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, '[redacted]'],
|
|
354
354
|
[/\bbearer\s+[A-Za-z0-9._~+/=-]+/gi, 'bearer [redacted]'],
|
|
355
|
-
[/\bauthorization:\s
|
|
356
|
-
[/((?:secret|token|password|passwd|api[_-]?key|access[_-]?key|client[_-]?secret|private[_-]?key)\
|
|
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
357
|
]
|
|
358
358
|
const HIGH_ENTROPY_RULE = [/[A-Za-z0-9+/]{40,}={0,2}/g, '[redacted]']
|
|
359
359
|
const redactSecrets = (text) => REDACTION_RULES.reduce((acc, [pattern, replacement]) => acc.replace(pattern, replacement), text)
|
|
@@ -1,38 +1,38 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handleBell
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-IWJKSIB4.js";
|
|
5
5
|
import {
|
|
6
6
|
readHookInput
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-7RUJKCR4.js";
|
|
8
|
+
import "../chunk-OTNOANMX.js";
|
|
9
9
|
import "../chunk-SGZJ5LYH.js";
|
|
10
|
-
import "../chunk-
|
|
11
|
-
import "../chunk-
|
|
12
|
-
import "../chunk-
|
|
13
|
-
import "../chunk-
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-
|
|
17
|
-
import "../chunk-
|
|
18
|
-
import "../chunk-
|
|
19
|
-
import "../chunk-
|
|
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";
|
|
20
20
|
import "../chunk-XHKBHWLX.js";
|
|
21
|
-
import "../chunk-
|
|
22
|
-
import "../chunk-
|
|
21
|
+
import "../chunk-EUGNVLMG.js";
|
|
22
|
+
import "../chunk-N5MZH5A6.js";
|
|
23
23
|
import "../chunk-POFBE6ZY.js";
|
|
24
24
|
import "../chunk-GMXKITVA.js";
|
|
25
|
-
import "../chunk-
|
|
26
|
-
import "../chunk-
|
|
27
|
-
import "../chunk-
|
|
25
|
+
import "../chunk-D6OODZCM.js";
|
|
26
|
+
import "../chunk-DUQO4C4I.js";
|
|
27
|
+
import "../chunk-OVC5QXN5.js";
|
|
28
28
|
import "../chunk-7QLSKOSU.js";
|
|
29
29
|
import "../chunk-KZERVKTD.js";
|
|
30
|
-
import "../chunk-
|
|
31
|
-
import "../chunk-
|
|
30
|
+
import "../chunk-62CVUUNU.js";
|
|
31
|
+
import "../chunk-MZBRL5H5.js";
|
|
32
32
|
import "../chunk-T7E75EKA.js";
|
|
33
|
-
import "../chunk-
|
|
34
|
-
import "../chunk-
|
|
35
|
-
import "../chunk-
|
|
33
|
+
import "../chunk-R6OYCUNK.js";
|
|
34
|
+
import "../chunk-YYCTF4Q5.js";
|
|
35
|
+
import "../chunk-G4GLCLKK.js";
|
|
36
36
|
|
|
37
37
|
// bin/pushary-bell-hook.ts
|
|
38
38
|
var main = async () => {
|
package/dist/bin/pushary-bell.js
CHANGED
|
@@ -5,37 +5,37 @@ import {
|
|
|
5
5
|
liveAgentCount,
|
|
6
6
|
ring,
|
|
7
7
|
upgradeThreshold
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-IWJKSIB4.js";
|
|
9
9
|
import {
|
|
10
10
|
addBellHooks,
|
|
11
11
|
bellInstalled,
|
|
12
12
|
removeBellHooks
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-NOI3XTCY.js";
|
|
14
14
|
import {
|
|
15
15
|
createIo
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-U4TMAANR.js";
|
|
17
17
|
import {
|
|
18
18
|
exitOnHelpFlag
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-5S2VBSJI.js";
|
|
20
20
|
import {
|
|
21
21
|
parseFlags
|
|
22
22
|
} from "../chunk-GMXKITVA.js";
|
|
23
|
-
import "../chunk-
|
|
23
|
+
import "../chunk-D6OODZCM.js";
|
|
24
24
|
import "../chunk-7QLSKOSU.js";
|
|
25
25
|
import {
|
|
26
26
|
EXIT
|
|
27
27
|
} from "../chunk-KZERVKTD.js";
|
|
28
|
-
import "../chunk-
|
|
28
|
+
import "../chunk-62CVUUNU.js";
|
|
29
29
|
import {
|
|
30
30
|
claudeSettings
|
|
31
|
-
} from "../chunk-
|
|
31
|
+
} from "../chunk-MZBRL5H5.js";
|
|
32
32
|
import {
|
|
33
33
|
readJsonSafe,
|
|
34
34
|
writeJsonAtomic
|
|
35
35
|
} from "../chunk-T7E75EKA.js";
|
|
36
|
-
import "../chunk-
|
|
37
|
-
import "../chunk-
|
|
38
|
-
import "../chunk-
|
|
36
|
+
import "../chunk-R6OYCUNK.js";
|
|
37
|
+
import "../chunk-YYCTF4Q5.js";
|
|
38
|
+
import "../chunk-G4GLCLKK.js";
|
|
39
39
|
|
|
40
40
|
// bin/pushary-bell.ts
|
|
41
41
|
exitOnHelpFlag("bell");
|
|
@@ -8,58 +8,62 @@ import {
|
|
|
8
8
|
describeIdleWindow,
|
|
9
9
|
startProcessOwnership,
|
|
10
10
|
withSpawnProcessOwnership
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-LHC45YUC.js";
|
|
12
12
|
import {
|
|
13
|
+
announceSubscriptionRequired,
|
|
13
14
|
isDeferAnswer
|
|
14
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-5OP5MQI7.js";
|
|
15
16
|
import {
|
|
16
17
|
claudeTranscriptPath,
|
|
17
18
|
loadSessionKey,
|
|
18
19
|
registerTranscript,
|
|
19
20
|
registeredTranscriptEnabled
|
|
20
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-OTNOANMX.js";
|
|
21
22
|
import "../chunk-SGZJ5LYH.js";
|
|
22
|
-
import "../chunk-
|
|
23
|
-
import "../chunk-
|
|
24
|
-
import "../chunk-
|
|
25
|
-
import "../chunk-
|
|
23
|
+
import "../chunk-TCVMK6GI.js";
|
|
24
|
+
import "../chunk-BGBLLHZ4.js";
|
|
25
|
+
import "../chunk-3EUBQARL.js";
|
|
26
|
+
import "../chunk-WTJM7PSL.js";
|
|
26
27
|
import {
|
|
27
28
|
ensureDaemonRunning
|
|
28
|
-
} from "../chunk-
|
|
29
|
-
import "../chunk-
|
|
30
|
-
import "../chunk-
|
|
29
|
+
} from "../chunk-ZKJ34T2F.js";
|
|
30
|
+
import "../chunk-MIXWMA73.js";
|
|
31
|
+
import "../chunk-NOI3XTCY.js";
|
|
31
32
|
import {
|
|
32
33
|
encryptRecord
|
|
33
|
-
} from "../chunk-
|
|
34
|
-
import "../chunk-
|
|
34
|
+
} from "../chunk-P2VIBGXA.js";
|
|
35
|
+
import "../chunk-WPX67AKT.js";
|
|
35
36
|
import {
|
|
36
37
|
transcriptsEnabled
|
|
37
|
-
} from "../chunk-
|
|
38
|
+
} from "../chunk-LPNJLKBQ.js";
|
|
38
39
|
import {
|
|
39
40
|
needsShell,
|
|
40
41
|
spawnClaude
|
|
41
42
|
} from "../chunk-XHKBHWLX.js";
|
|
42
43
|
import {
|
|
43
|
-
DEFAULT_SESSION,
|
|
44
44
|
UNNAMED_ACTION,
|
|
45
45
|
deriveToolTarget,
|
|
46
46
|
describeToolCall,
|
|
47
47
|
fetchModeState,
|
|
48
48
|
getPolicy,
|
|
49
|
+
phoneDrivenEnv,
|
|
50
|
+
repoKeyFor,
|
|
51
|
+
reportEvent,
|
|
52
|
+
scopePathFor
|
|
53
|
+
} from "../chunk-U6RVDUJ5.js";
|
|
54
|
+
import {
|
|
55
|
+
DEFAULT_SESSION,
|
|
49
56
|
markPendingCommandDelivered,
|
|
50
57
|
markPendingCommandFailed,
|
|
51
|
-
phoneDrivenEnv,
|
|
52
58
|
readPendingCommand,
|
|
53
59
|
readPendingCommandById,
|
|
54
60
|
removePendingCommand,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
scopePathFor
|
|
59
|
-
} from "../chunk-WM3U2RUK.js";
|
|
60
|
-
import "../chunk-4C4NRDIC.js";
|
|
61
|
+
savePendingCommand
|
|
62
|
+
} from "../chunk-N6IOSZOE.js";
|
|
63
|
+
import "../chunk-EUGNVLMG.js";
|
|
61
64
|
import {
|
|
62
65
|
DECISION_STOP_REASON,
|
|
66
|
+
UNVERIFIABLE_APPROVAL_REASON,
|
|
63
67
|
askUser,
|
|
64
68
|
cancelQuestion,
|
|
65
69
|
isDecisionStopped,
|
|
@@ -67,33 +71,36 @@ import {
|
|
|
67
71
|
nextLongPollMs,
|
|
68
72
|
waitForAnswer,
|
|
69
73
|
withdrawQuestion
|
|
70
|
-
} from "../chunk-
|
|
71
|
-
import "../chunk-
|
|
74
|
+
} from "../chunk-YC27PROF.js";
|
|
75
|
+
import "../chunk-N5MZH5A6.js";
|
|
72
76
|
import "../chunk-POFBE6ZY.js";
|
|
73
77
|
import "../chunk-GMXKITVA.js";
|
|
74
|
-
import "../chunk-
|
|
75
|
-
import
|
|
76
|
-
|
|
78
|
+
import "../chunk-D6OODZCM.js";
|
|
79
|
+
import {
|
|
80
|
+
SubscriptionRequiredError
|
|
81
|
+
} from "../chunk-VE7TXLR4.js";
|
|
82
|
+
import "../chunk-EEEJ2JIL.js";
|
|
83
|
+
import "../chunk-DUQO4C4I.js";
|
|
77
84
|
import {
|
|
78
85
|
getMachineId
|
|
79
|
-
} from "../chunk-
|
|
86
|
+
} from "../chunk-OVC5QXN5.js";
|
|
80
87
|
import "../chunk-7QLSKOSU.js";
|
|
81
88
|
import "../chunk-KZERVKTD.js";
|
|
82
|
-
import "../chunk-
|
|
83
|
-
import "../chunk-
|
|
89
|
+
import "../chunk-62CVUUNU.js";
|
|
90
|
+
import "../chunk-MZBRL5H5.js";
|
|
84
91
|
import "../chunk-T7E75EKA.js";
|
|
85
92
|
import {
|
|
86
93
|
getApiKey,
|
|
87
94
|
getBaseUrl
|
|
88
|
-
} from "../chunk-
|
|
95
|
+
} from "../chunk-R6OYCUNK.js";
|
|
89
96
|
import {
|
|
90
97
|
NPX_LATEST_COMMAND
|
|
91
|
-
} from "../chunk-
|
|
98
|
+
} from "../chunk-YYCTF4Q5.js";
|
|
92
99
|
import {
|
|
93
100
|
KILL_REASON,
|
|
94
|
-
|
|
101
|
+
redactSecretsFromContent,
|
|
95
102
|
resolveGate
|
|
96
|
-
} from "../chunk-
|
|
103
|
+
} from "../chunk-G4GLCLKK.js";
|
|
97
104
|
|
|
98
105
|
// src/wrapper/localPassthrough.ts
|
|
99
106
|
var SIGNAL_NUMBERS = {
|
|
@@ -154,7 +161,7 @@ var redactDraft = (text, complete = false) => {
|
|
|
154
161
|
const close = text.indexOf(match[1], match.index + match[0].length);
|
|
155
162
|
if (close < 0 || close >= end) end = Math.min(end, match.index);
|
|
156
163
|
}
|
|
157
|
-
return
|
|
164
|
+
return redactSecretsFromContent(text.slice(0, end));
|
|
158
165
|
};
|
|
159
166
|
var DraftText = class {
|
|
160
167
|
messageId = "";
|
|
@@ -425,6 +432,8 @@ var BoundedInputQueue = class {
|
|
|
425
432
|
|
|
426
433
|
// src/wrapper/approver.ts
|
|
427
434
|
var DEFAULT_MAX_CONCURRENT = 16;
|
|
435
|
+
var NO_LOCAL_APPROVAL_UI = "This remote session has no local approval UI. Continue in an interactive session or choose a mode that permits remote approval.";
|
|
436
|
+
var SUBSCRIPTION_REQUIRED_NO_LOCAL_APPROVAL_UI = "Your Pushary workspace has no active subscription, so approvals cannot reach your phone, and this remote session has no local approval UI. Continue in an interactive session.";
|
|
428
437
|
var DEFAULT_APPROVAL_WINDOW_MS = 5 * 6e4;
|
|
429
438
|
var MAX_APPROVAL_WINDOW_MS = 30 * 6e4;
|
|
430
439
|
var allow = (input) => ({
|
|
@@ -528,8 +537,10 @@ var createRemoteApprover = (deps) => {
|
|
|
528
537
|
toolTarget,
|
|
529
538
|
repoKey: repoKeyFor(deps.cwd)
|
|
530
539
|
});
|
|
531
|
-
} catch {
|
|
532
|
-
|
|
540
|
+
} catch (error) {
|
|
541
|
+
if (!(error instanceof SubscriptionRequiredError)) return deny(UNVERIFIABLE_APPROVAL_REASON);
|
|
542
|
+
announceSubscriptionRequired(error.upgradeUrl, sessionId);
|
|
543
|
+
return deny(SUBSCRIPTION_REQUIRED_NO_LOCAL_APPROVAL_UI);
|
|
533
544
|
}
|
|
534
545
|
if (isDecisionStopped(question)) return deny(DECISION_STOP_REASON);
|
|
535
546
|
entry.correlationId = question.correlationId;
|
|
@@ -546,7 +557,7 @@ var createRemoteApprover = (deps) => {
|
|
|
546
557
|
if (isDeferAnswer(answer.value)) return deny("Deferred \u2014 handle it on the machine");
|
|
547
558
|
return answer.value === "yes" ? allow(input) : deny("Denied from your phone");
|
|
548
559
|
}
|
|
549
|
-
if (localHandoff) return deny(
|
|
560
|
+
if (localHandoff) return deny(NO_LOCAL_APPROVAL_UI);
|
|
550
561
|
return applyTimeout(policy, input);
|
|
551
562
|
} catch {
|
|
552
563
|
return deny("Approval unavailable; denied by default");
|