@pushary/agent-hooks 0.89.11 → 0.89.12

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 (77) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +3 -2
  3. package/dist/bin/pushary-bell-hook.js +5 -5
  4. package/dist/bin/pushary-bell.js +11 -11
  5. package/dist/bin/pushary-claude.js +104 -32
  6. package/dist/bin/pushary-clean.js +39 -28
  7. package/dist/bin/pushary-codex-bridge.js +17 -16
  8. package/dist/bin/pushary-codex-hook.js +11 -10
  9. package/dist/bin/pushary-codex.js +7 -7
  10. package/dist/bin/pushary-connect.js +12 -12
  11. package/dist/bin/pushary-daemon-supervisor.d.ts +1 -0
  12. package/dist/bin/pushary-daemon-supervisor.js +27 -0
  13. package/dist/bin/pushary-daemon.js +22 -22
  14. package/dist/bin/pushary-disconnect.js +9 -9
  15. package/dist/bin/pushary-doctor.js +59 -49
  16. package/dist/bin/pushary-elicitation-hook.js +4 -4
  17. package/dist/bin/pushary-gemini-bridge.js +16 -15
  18. package/dist/bin/pushary-gemini-hook.js +10 -9
  19. package/dist/bin/pushary-hook.js +13 -13
  20. package/dist/bin/pushary-login.js +11 -11
  21. package/dist/bin/pushary-logout.js +11 -11
  22. package/dist/bin/pushary-mode.js +5 -5
  23. package/dist/bin/pushary-notification-hook.js +7 -7
  24. package/dist/bin/pushary-opencode-hook.js +10 -9
  25. package/dist/bin/pushary-permission-denied-hook.js +11 -11
  26. package/dist/bin/pushary-permission-hook.js +11 -11
  27. package/dist/bin/pushary-post-hook.js +7 -7
  28. package/dist/bin/pushary-prompt-hook.js +7 -7
  29. package/dist/bin/pushary-session-end-hook.js +7 -7
  30. package/dist/bin/pushary-session-start-hook.js +7 -7
  31. package/dist/bin/pushary-setup.js +87 -59
  32. package/dist/bin/pushary-stats.js +4 -4
  33. package/dist/bin/pushary-status.js +14 -14
  34. package/dist/bin/pushary-stop-hook.js +7 -7
  35. package/dist/bin/pushary-stopfailure-hook.js +7 -7
  36. package/dist/bin/pushary-suggestions.js +2 -2
  37. package/dist/bin/pushary-upgrade.js +21 -21
  38. package/dist/bin/pushary-wait.js +5 -5
  39. package/dist/bin/pushary.js +1 -1
  40. package/dist/{chunk-253WC6O5.js → chunk-327YMKP5.js} +1 -1
  41. package/dist/{chunk-6XUABEX2.js → chunk-3OXHYPZG.js} +1 -1
  42. package/dist/{chunk-MZGWKIUZ.js → chunk-3XSP5SML.js} +7 -3
  43. package/dist/{chunk-XX2V4QS5.js → chunk-4LL6LG5X.js} +2 -2
  44. package/dist/{chunk-DKWM5T3P.js → chunk-5NDB3YOE.js} +2 -2
  45. package/dist/{chunk-TEZ2FZD6.js → chunk-6GU55AQQ.js} +2 -2
  46. package/dist/{chunk-Q223OM5J.js → chunk-6V7ZDH3A.js} +4 -4
  47. package/dist/{chunk-OLAGKKSR.js → chunk-6VXNA5JB.js} +16 -6
  48. package/dist/{chunk-34GN3IPX.js → chunk-7DK3ZH3N.js} +1 -1
  49. package/dist/{chunk-PZRWFWSR.js → chunk-7HYJPOGG.js} +7 -7
  50. package/dist/{chunk-TY5HVMXT.js → chunk-DHR4F2CR.js} +1 -1
  51. package/dist/{chunk-3HFK3UXM.js → chunk-FCUUVHTS.js} +1 -1
  52. package/dist/{chunk-NCVIWGVA.js → chunk-GKPURU7P.js} +1 -1
  53. package/dist/chunk-JJV5Q4KG.js +20 -0
  54. package/dist/{chunk-TG3T3M4K.js → chunk-JVZX5YRJ.js} +6 -2
  55. package/dist/{chunk-6EKQZA6R.js → chunk-KVHP5ZME.js} +1 -1
  56. package/dist/{chunk-X4ZUUFKV.js → chunk-L4ZCFMWW.js} +63 -1
  57. package/dist/{chunk-2LPEZYMC.js → chunk-MFNQ5IMW.js} +1 -1
  58. package/dist/{chunk-KVE5RCQL.js → chunk-NBRM3FMD.js} +1 -1
  59. package/dist/{chunk-FZ73G2RO.js → chunk-NESKLV6R.js} +25 -6
  60. package/dist/{chunk-FXIL7RCL.js → chunk-OADGBOP7.js} +4 -4
  61. package/dist/{chunk-J4K75V4D.js → chunk-OCMOTJTW.js} +10 -9
  62. package/dist/{chunk-LURY4WNF.js → chunk-OTPJ4FUR.js} +1 -1
  63. package/dist/{chunk-QA72MKIT.js → chunk-OVEGEQSB.js} +5 -5
  64. package/dist/{chunk-3SQYKLBW.js → chunk-PS7DQ2SU.js} +46 -18
  65. package/dist/{chunk-UDBJHQMG.js → chunk-QFJZHVVL.js} +1 -1
  66. package/dist/chunk-QZCFVWA7.js +58 -0
  67. package/dist/{chunk-3XTFX4CL.js → chunk-RLQWNEPM.js} +3 -2
  68. package/dist/{chunk-3CUDMTL4.js → chunk-RNKPLUWC.js} +10 -3
  69. package/dist/{chunk-SYUIXXQW.js → chunk-VF3RTVWY.js} +1 -1
  70. package/dist/{chunk-TRVIRETT.js → chunk-VPLQFXCH.js} +1 -1
  71. package/dist/{chunk-IUN6VOKV.js → chunk-WDVQ6O4C.js} +2 -42
  72. package/dist/{chunk-IUWRVTQK.js → chunk-XREW7RQ3.js} +1 -1
  73. package/dist/{chunk-BLODMQKJ.js → chunk-Y4WVZIEI.js} +1 -1
  74. package/dist/src/index.d.ts +3 -1
  75. package/dist/src/index.js +15 -11
  76. package/package.json +2 -1
  77. /package/dist/{chunk-X6RXX2NF.js → chunk-3MCEES6Z.js} +0 -0
@@ -4,13 +4,13 @@ import {
4
4
  } from "./chunk-XHKBHWLX.js";
5
5
  import {
6
6
  resolveGlobalBinary
7
- } from "./chunk-X4ZUUFKV.js";
7
+ } from "./chunk-L4ZCFMWW.js";
8
8
  import {
9
9
  getMachineId
10
- } from "./chunk-DKWM5T3P.js";
10
+ } from "./chunk-5NDB3YOE.js";
11
11
  import {
12
12
  pusharyDir
13
- } from "./chunk-QA72MKIT.js";
13
+ } from "./chunk-OVEGEQSB.js";
14
14
  import {
15
15
  getPackageVersion
16
16
  } from "./chunk-DINDL2CF.js";
@@ -19,7 +19,7 @@ import {
19
19
  writeFileAtomic,
20
20
  writeJsonAtomic,
21
21
  writeJsonAtomicDurable
22
- } from "./chunk-XX2V4QS5.js";
22
+ } from "./chunk-4LL6LG5X.js";
23
23
  import {
24
24
  getApiKey
25
25
  } from "./chunk-2UMNXADU.js";
@@ -28,7 +28,7 @@ import {
28
28
  import { dirname, join, win32 as win32Path } from "path";
29
29
  import { existsSync, mkdirSync, readFileSync, realpathSync, renameSync, unlinkSync, writeFileSync } from "fs";
30
30
  import { createHash, randomUUID } from "crypto";
31
- import { homedir } from "os";
31
+ import { homedir, userInfo } from "os";
32
32
  import { execFileSync } from "child_process";
33
33
  var daemonNeedsHandoff = (status) => status.kind === "version-mismatch" || status.kind === "configuration-mismatch" || status.kind === "unresponsive" && status.processAlive === true;
34
34
  var DAEMON_REMOTE_PROOF_MAX_AGE_MS = 18e4;
@@ -39,9 +39,14 @@ var remoteProofIsFresh = (timestamp, now) => {
39
39
  return Number.isFinite(age) && age >= -DAEMON_REMOTE_PROOF_CLOCK_SKEW_MS && age < DAEMON_REMOTE_PROOF_MAX_AGE_MS;
40
40
  };
41
41
  var daemonHasRemoteProof = (status, now = Date.now()) => status.kind === "running" && remoteProofIsFresh(status.lastSuccessfulHeartbeatAt, now) && remoteProofIsFresh(status.lastSuccessfulControlAt, now);
42
+ var readServiceDefinitionFile = (path) => {
43
+ const bytes = readFileSync(path);
44
+ const encoding = bytes.length >= 2 && bytes[0] === 255 && bytes[1] === 254 ? "utf16le" : "utf-8";
45
+ return { contents: bytes.toString(encoding), encoding };
46
+ };
42
47
  var runDaemonServiceCommand = (command, args) => execFileSync(command, [...args], {
43
48
  encoding: "utf-8",
44
- stdio: ["ignore", "pipe", "ignore"],
49
+ stdio: ["ignore", "pipe", "pipe"],
45
50
  windowsHide: true
46
51
  });
47
52
  var commandFailureOutput = (error) => {
@@ -163,7 +168,6 @@ After=network-online.target
163
168
  [Service]
164
169
  Type=simple
165
170
  ExecStart=${systemdQuote(input.execPath)} ${systemdQuote(input.daemonEntry)}
166
- WorkingDirectory=${systemdQuote(input.homeDir)}
167
171
  Environment=${systemdQuote(`PATH=${input.pathEnv}`)}
168
172
  Restart=on-failure
169
173
  RestartSec=10
@@ -199,12 +203,18 @@ WantedBy=default.target
199
203
  }
200
204
  if (input.platform === "win32") {
201
205
  const taskName = "Pushary Daemon";
206
+ const username = process.env.USERNAME?.trim() || userInfo().username;
207
+ const domain = process.env.USERDOMAIN?.trim();
208
+ const userId = input.userId?.trim() || (domain ? `${domain}\\${username}` : username);
202
209
  const definitionPath = win32Path.join(input.stateDir, "pushary-daemon-task.xml");
203
- const contents = `<?xml version="1.0" encoding="UTF-8"?>
210
+ const supervisorPath = win32Path.join(win32Path.dirname(input.daemonEntry), "pushary-daemon-supervisor.js");
211
+ const supervised = (input.entryExists ?? existsSync)(supervisorPath);
212
+ const args = supervised ? `&quot;${xml(supervisorPath)}&quot; &quot;${xml(input.daemonEntry)}&quot;` : `&quot;${xml(input.daemonEntry)}&quot;`;
213
+ const contents = `\uFEFF<?xml version="1.0" encoding="UTF-16"?>
204
214
  <Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
205
215
  <RegistrationInfo><Description>Pushary phone-to-agent daemon</Description></RegistrationInfo>
206
- <Triggers><LogonTrigger><Enabled>true</Enabled></LogonTrigger></Triggers>
207
- <Principals><Principal id="Author"><LogonType>InteractiveToken</LogonType><RunLevel>LeastPrivilege</RunLevel></Principal></Principals>
216
+ <Triggers><LogonTrigger><UserId>${xml(userId)}</UserId><Enabled>true</Enabled></LogonTrigger></Triggers>
217
+ <Principals><Principal id="Author"><UserId>${xml(userId)}</UserId><LogonType>InteractiveToken</LogonType><RunLevel>LeastPrivilege</RunLevel></Principal></Principals>
208
218
  <Settings>
209
219
  <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
210
220
  <StartWhenAvailable>true</StartWhenAvailable>
@@ -216,7 +226,7 @@ WantedBy=default.target
216
226
  <Actions Context="Author">
217
227
  <Exec>
218
228
  <Command>${xml(input.execPath)}</Command>
219
- <Arguments>&quot;${xml(input.daemonEntry)}&quot;</Arguments>
229
+ <Arguments>${args}</Arguments>
220
230
  <WorkingDirectory>${xml(input.homeDir)}</WorkingDirectory>
221
231
  </Exec>
222
232
  </Actions>
@@ -225,6 +235,7 @@ WantedBy=default.target
225
235
  return {
226
236
  definitionPath,
227
237
  contents,
238
+ encoding: "utf16le",
228
239
  install: [
229
240
  { command: "schtasks.exe", args: ["/Create", "/TN", taskName, "/XML", definitionPath, "/F"] },
230
241
  { command: "schtasks.exe", args: ["/Run", "/TN", taskName] }
@@ -302,7 +313,8 @@ var resolveDaemonServiceDefinition = (options = {}) => {
302
313
  execPath: options.execPath ?? process.execPath,
303
314
  daemonEntry,
304
315
  pathEnv: options.pathEnv ?? process.env.PATH ?? "",
305
- uid: options.uid ?? process.getuid?.()
316
+ uid: options.uid ?? process.getuid?.(),
317
+ entryExists: exists
306
318
  });
307
319
  };
308
320
  var runDaemonServiceSteps = (steps, run) => {
@@ -317,7 +329,9 @@ var runDaemonServiceSteps = (steps, run) => {
317
329
  var applyDaemonService = (action, definition, options = {}) => {
318
330
  const run = options.run ?? runDaemonServiceCommand;
319
331
  try {
320
- if (action === "install") writeFileAtomic(definition.definitionPath, definition.contents, 384);
332
+ if (action === "install") {
333
+ writeFileAtomic(definition.definitionPath, definition.contents, 384, definition.encoding);
334
+ }
321
335
  const steps = action === "uninstall" ? [...definition.stop, ...definition.uninstall] : definition[action];
322
336
  runDaemonServiceSteps(steps, run);
323
337
  if (action === "uninstall") {
@@ -674,7 +688,7 @@ var disableDaemonService = async (options = {}) => deactivateDaemonService("unin
674
688
  var parseDaemonServiceTransaction = (value) => {
675
689
  if (typeof value !== "object" || value === null) return null;
676
690
  const transaction = value;
677
- if (transaction.version !== 1 || transaction.phase !== "prepared" && transaction.phase !== "committed" || typeof transaction.definitionPath !== "string" || !(transaction.previousContents === null || typeof transaction.previousContents === "string") || typeof transaction.previousRegistered !== "boolean" || !(transaction.previousEnabled === void 0 || typeof transaction.previousEnabled === "boolean") || typeof transaction.previousRunning !== "boolean") return null;
691
+ if (transaction.version !== 1 || transaction.phase !== "prepared" && transaction.phase !== "committed" || typeof transaction.definitionPath !== "string" || !(transaction.previousContents === null || typeof transaction.previousContents === "string") || !(transaction.previousEncoding === void 0 || typeof transaction.previousEncoding === "string") || typeof transaction.previousRegistered !== "boolean" || !(transaction.previousEnabled === void 0 || typeof transaction.previousEnabled === "boolean") || typeof transaction.previousRunning !== "boolean") return null;
678
692
  return {
679
693
  ...transaction,
680
694
  previousEnabled: typeof transaction.previousEnabled === "boolean" ? transaction.previousEnabled : transaction.previousRegistered
@@ -723,12 +737,13 @@ var probeDaemonServiceState = (definition, run) => {
723
737
  return { kind: "ok", registered, enabled, running: false };
724
738
  }
725
739
  };
740
+ var previousEncoding = (snapshot) => snapshot.previousEncoding ?? "utf-8";
726
741
  var restoreDaemonServiceSnapshot = (definition, snapshot, run) => {
727
742
  const removed = applyDaemonService("uninstall", definition, { run });
728
743
  if (removed.kind !== "ok") return removed;
729
744
  try {
730
745
  if (snapshot.previousContents === null) safeUnlink(definition.definitionPath);
731
- else writeFileAtomic(definition.definitionPath, snapshot.previousContents, 384);
746
+ else writeFileAtomic(definition.definitionPath, snapshot.previousContents, 384, previousEncoding(snapshot));
732
747
  } catch (err) {
733
748
  return {
734
749
  kind: "failed",
@@ -767,7 +782,8 @@ var restoreDaemonServiceSnapshot = (definition, snapshot, run) => {
767
782
  }
768
783
  const restored = applyDaemonService("install", {
769
784
  ...definition,
770
- contents: snapshot.previousContents
785
+ contents: snapshot.previousContents,
786
+ encoding: previousEncoding(snapshot)
771
787
  }, { run });
772
788
  if (restored.kind !== "ok") return restored;
773
789
  if (!snapshot.previousRunning) applyDaemonService("stop", definition, { run });
@@ -829,9 +845,12 @@ var replaceDaemonService = async (options = {}) => {
829
845
  return { kind: "failed", detail: `Could not recover interrupted service replacement: ${recovered.detail}` };
830
846
  }
831
847
  let previousContents = null;
848
+ let previousDefinitionEncoding = "utf-8";
832
849
  try {
833
850
  if (existsSync(definition.definitionPath)) {
834
- previousContents = readFileSync(definition.definitionPath, "utf-8");
851
+ const previous = readServiceDefinitionFile(definition.definitionPath);
852
+ previousContents = previous.contents;
853
+ previousDefinitionEncoding = previous.encoding;
835
854
  }
836
855
  } catch (err) {
837
856
  return { kind: "failed", detail: `Could not snapshot the existing service: ${err instanceof Error ? err.message : String(err)}` };
@@ -846,6 +865,7 @@ var replaceDaemonService = async (options = {}) => {
846
865
  phase: "prepared",
847
866
  definitionPath: definition.definitionPath,
848
867
  previousContents,
868
+ previousEncoding: previousDefinitionEncoding,
849
869
  previousRegistered: previousState.registered,
850
870
  previousEnabled: previousState.enabled,
851
871
  previousRunning: previousState.running
@@ -869,7 +889,15 @@ var replaceDaemonService = async (options = {}) => {
869
889
  }
870
890
  let installed = applyDaemonService("install", definition, { run });
871
891
  if (installed.kind === "ok") {
872
- const state = probeDaemonServiceState(definition, run);
892
+ const sleep = options.sleep ?? wait;
893
+ const pollIntervalMs = Math.max(1, options.pollIntervalMs ?? 50);
894
+ const now = options.now ?? Date.now;
895
+ const deadline = now() + Math.max(0, options.waitTimeoutMs ?? 5e3);
896
+ let state = probeDaemonServiceState(definition, run);
897
+ while (state.kind === "ok" && (!state.registered || !state.enabled || !state.running) && now() < deadline) {
898
+ await sleep(pollIntervalMs);
899
+ state = probeDaemonServiceState(definition, run);
900
+ }
873
901
  if (state.kind !== "ok") {
874
902
  installed = { kind: "failed", detail: state.detail };
875
903
  } else if (!state.registered || !state.enabled || !state.running) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolvePathBinary
3
- } from "./chunk-X4ZUUFKV.js";
3
+ } from "./chunk-L4ZCFMWW.js";
4
4
 
5
5
  // src/hermes-config.ts
6
6
  import { execFileSync } from "child_process";
@@ -0,0 +1,58 @@
1
+ import {
2
+ getBaseUrl
3
+ } from "./chunk-2UMNXADU.js";
4
+
5
+ // src/transcript-api.ts
6
+ var fetchTranscriptRecipients = async (apiKey, baseUrl = getBaseUrl()) => {
7
+ try {
8
+ const res = await fetch(`${baseUrl}/api/agent/encryption-account`, {
9
+ headers: { Authorization: `Bearer ${apiKey}` },
10
+ signal: AbortSignal.timeout(5e3)
11
+ });
12
+ if (!res.ok) return null;
13
+ const data = await res.json();
14
+ if (typeof data.publicKey !== "string" || data.publicKey.length === 0) return null;
15
+ if (data.providerRecovery === void 0 || data.providerRecovery === null) {
16
+ return { phonePublicKey: data.publicKey, provider: null };
17
+ }
18
+ if (typeof data.providerRecovery !== "object") return null;
19
+ const provider = data.providerRecovery;
20
+ if (typeof provider.required !== "boolean" || typeof provider.keyId !== "string" || provider.keyId.length === 0 || typeof provider.publicKey !== "string" || provider.publicKey.length === 0) return null;
21
+ return {
22
+ phonePublicKey: data.publicKey,
23
+ provider: { required: provider.required, keyId: provider.keyId, publicKey: provider.publicKey }
24
+ };
25
+ } catch {
26
+ return null;
27
+ }
28
+ };
29
+ var fetchAccountPublicKey = async (apiKey, baseUrl = getBaseUrl()) => (await fetchTranscriptRecipients(apiKey, baseUrl))?.phonePublicKey ?? null;
30
+ var uploadTranscriptRecords = async (apiKey, params, baseUrl = getBaseUrl()) => {
31
+ try {
32
+ const res = await fetch(`${baseUrl}/api/agent/transcript`, {
33
+ method: "POST",
34
+ headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
35
+ body: JSON.stringify(params),
36
+ signal: AbortSignal.timeout(15e3)
37
+ });
38
+ const body = await res.json().catch(() => null);
39
+ const keyRegistered = body?.keyRegistered === true;
40
+ const keyConflict = body?.keyConflict === true;
41
+ const ids = (value) => Array.isArray(value) ? value.filter((v) => typeof v === "string") : [];
42
+ return {
43
+ ok: res.ok && !keyConflict && (params.dataEncryptionKey === void 0 || keyRegistered),
44
+ keyRegistered,
45
+ keyConflict,
46
+ settledIds: Array.isArray(body?.settledIds) ? ids(body.settledIds) : null,
47
+ rejectedIds: ids(body?.rejectedIds)
48
+ };
49
+ } catch {
50
+ return { ok: false, keyRegistered: false, keyConflict: false, settledIds: null, rejectedIds: [] };
51
+ }
52
+ };
53
+
54
+ export {
55
+ fetchTranscriptRecipients,
56
+ fetchAccountPublicKey,
57
+ uploadTranscriptRecords
58
+ };
@@ -3,7 +3,7 @@ var COMMAND_LIST = [
3
3
  {
4
4
  name: "setup",
5
5
  module: "pushary-setup",
6
- summary: "Configure Claude Code, Codex, Gemini CLI, Hermes, Cursor, or VS Code with Pushary"
6
+ summary: "Configure Claude Code, Codex, Gemini CLI, Hermes, Cursor, VS Code, or OpenCode with Pushary"
7
7
  },
8
8
  {
9
9
  name: "claude",
@@ -133,6 +133,7 @@ var SETUP_OPTIONS = [
133
133
  ["--connect web", "Legacy browser subscribe page"],
134
134
  ["--connect none", "Skip the phone connect step, same as --skip-phone"],
135
135
  ["--control auto|on|off", "Manage phone-start automatically (default), require it, or disable its background service"],
136
+ ["--transcripts on|off", "Enable or disable encrypted transcript sync on this machine"],
136
137
  ["--skip-phone", "Skip the phone connect step"],
137
138
  ["--verify roundtrip", "Send a real question and wait for you to answer it (default when a human is present)"],
138
139
  ["--verify push", "Only prove a notification was delivered. Automatic when nobody is at the terminal"],
@@ -140,7 +141,7 @@ var SETUP_OPTIONS = [
140
141
  ["--dry-run", "Print what would be written and change nothing"],
141
142
  ["--json", "Emit one machine-readable object instead of the human report"]
142
143
  ];
143
- var AGENT_IDS = "claude_code, codex, gemini_cli, hermes, cursor, custom";
144
+ var AGENT_IDS = "claude_code, codex, gemini_cli, hermes, cursor, vscode, opencode, custom";
144
145
  var USAGE_EXAMPLES = [
145
146
  "npx @pushary/agent-hooks@latest setup",
146
147
  "npx @pushary/agent-hooks@latest setup --agents auto --yes --skip-phone",
@@ -3,13 +3,13 @@ import {
3
3
  } from "./chunk-BC3VCZ3E.js";
4
4
  import {
5
5
  resolveInstallSourceFor
6
- } from "./chunk-IUWRVTQK.js";
6
+ } from "./chunk-XREW7RQ3.js";
7
7
  import {
8
8
  backupFile,
9
9
  readJsonSafe,
10
10
  writeFileAtomic,
11
11
  writeJsonAtomic
12
- } from "./chunk-XX2V4QS5.js";
12
+ } from "./chunk-4LL6LG5X.js";
13
13
  import {
14
14
  configFilePath
15
15
  } from "./chunk-2UMNXADU.js";
@@ -125,7 +125,8 @@ var writeKey = (apiKey, options = {}) => {
125
125
  ...current,
126
126
  apiKey,
127
127
  installSource: resolveInstallSourceFor(current),
128
- ...options.controlMode ? { controlMode: options.controlMode } : {}
128
+ ...options.controlMode ? { controlMode: options.controlMode } : {},
129
+ ...options.transcriptsEnabled === void 0 ? {} : { transcriptsEnabled: options.transcriptsEnabled }
129
130
  },
130
131
  KEY_FILE_MODE
131
132
  );
@@ -188,6 +189,11 @@ var readControlMode = () => {
188
189
  const value = result.value.controlMode;
189
190
  return value === "auto" || value === "on" || value === "off" ? value : null;
190
191
  };
192
+ var readTranscriptPreference = () => {
193
+ const result = readJsonSafe(configFilePath());
194
+ if (result.kind !== "ok") return null;
195
+ return typeof result.value.transcriptsEnabled === "boolean" ? result.value.transcriptsEnabled : null;
196
+ };
191
197
  var readKeySource = () => {
192
198
  const configPath = configFilePath();
193
199
  const envKey = process.env.PUSHARY_API_KEY?.trim() || null;
@@ -206,5 +212,6 @@ export {
206
212
  clearKey,
207
213
  readConfigFileKey,
208
214
  readControlMode,
215
+ readTranscriptPreference,
209
216
  readKeySource
210
217
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  quoteIfNeeded
3
- } from "./chunk-X4ZUUFKV.js";
3
+ } from "./chunk-L4ZCFMWW.js";
4
4
 
5
5
  // src/hook-command.ts
6
6
  var HOOK_SHELL = "/bin/sh -c";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  readConfigFileKey
3
- } from "./chunk-3CUDMTL4.js";
3
+ } from "./chunk-RNKPLUWC.js";
4
4
 
5
5
  // src/bell/fleet.ts
6
6
  import { closeSync, constants, futimesSync, lstatSync, mkdirSync, openSync, readdirSync, unlinkSync } from "fs";
@@ -1,9 +1,6 @@
1
- import {
2
- getBaseUrl
3
- } from "./chunk-2UMNXADU.js";
4
1
  import {
5
2
  redactSecrets
6
- } from "./chunk-X6RXX2NF.js";
3
+ } from "./chunk-3MCEES6Z.js";
7
4
 
8
5
  // src/crypto.ts
9
6
  import nacl from "tweetnacl";
@@ -79,46 +76,9 @@ var buildTranscriptRecords = (lines, sessionKey, seen = /* @__PURE__ */ new Set(
79
76
  return { records, seen: nextSeen };
80
77
  };
81
78
 
82
- // src/transcript-api.ts
83
- var fetchAccountPublicKey = async (apiKey, baseUrl = getBaseUrl()) => {
84
- try {
85
- const res = await fetch(`${baseUrl}/api/agent/encryption-account`, {
86
- headers: { Authorization: `Bearer ${apiKey}` },
87
- signal: AbortSignal.timeout(5e3)
88
- });
89
- if (!res.ok) return null;
90
- const data = await res.json();
91
- return typeof data.publicKey === "string" && data.publicKey.length > 0 ? data.publicKey : null;
92
- } catch {
93
- return null;
94
- }
95
- };
96
- var uploadTranscriptRecords = async (apiKey, params, baseUrl = getBaseUrl()) => {
97
- try {
98
- const res = await fetch(`${baseUrl}/api/agent/transcript`, {
99
- method: "POST",
100
- headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
101
- body: JSON.stringify(params),
102
- signal: AbortSignal.timeout(15e3)
103
- });
104
- const body = await res.json().catch(() => null);
105
- const keyRegistered = body?.keyRegistered === true;
106
- const keyConflict = body?.keyConflict === true;
107
- return {
108
- ok: res.ok && !keyConflict && (params.dataEncryptionKey === void 0 || keyRegistered),
109
- keyRegistered,
110
- keyConflict
111
- };
112
- } catch {
113
- return { ok: false, keyRegistered: false, keyConflict: false };
114
- }
115
- };
116
-
117
79
  export {
118
80
  decodePublicKey,
119
81
  generateSessionKey,
120
82
  wrapSessionKey,
121
- buildTranscriptRecords,
122
- fetchAccountPublicKey,
123
- uploadTranscriptRecords
83
+ buildTranscriptRecords
124
84
  };
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-2UMNXADU.js";
4
4
  import {
5
5
  normalizeInstallSource
6
- } from "./chunk-X6RXX2NF.js";
6
+ } from "./chunk-3MCEES6Z.js";
7
7
 
8
8
  // src/install-source.ts
9
9
  import { readFileSync } from "fs";
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-2UMNXADU.js";
13
13
  import {
14
14
  isValidApiKey
15
- } from "./chunk-X6RXX2NF.js";
15
+ } from "./chunk-3MCEES6Z.js";
16
16
 
17
17
  // src/session.ts
18
18
  var IDENTITY_PATH = "/api/v1/server/identity";
@@ -151,4 +151,6 @@ declare const cancelQuestion: (apiKey: string, correlationId: string) => Promise
151
151
  declare const getApiKey: () => string;
152
152
  declare const getBaseUrl: () => string;
153
153
 
154
- export { askUser, cancelQuestion, fetchModeOverride, fetchModeState, getApiKey, getBaseUrl, getPolicy, handleNotification, handlePostToolUse, handlePreToolUse, handleStop, reportEvent, waitForAnswer };
154
+ declare const fetchAccountPublicKey: (apiKey: string, baseUrl?: string) => Promise<string | null>;
155
+
156
+ export { askUser, cancelQuestion, fetchAccountPublicKey, fetchModeOverride, fetchModeState, getApiKey, getBaseUrl, getPolicy, handleNotification, handlePostToolUse, handlePreToolUse, handleStop, reportEvent, waitForAnswer };
package/dist/src/index.js CHANGED
@@ -1,9 +1,12 @@
1
1
  import {
2
2
  handlePreToolUse
3
- } from "../chunk-J4K75V4D.js";
4
- import "../chunk-6EKQZA6R.js";
5
- import "../chunk-NCVIWGVA.js";
6
- import "../chunk-3HFK3UXM.js";
3
+ } from "../chunk-OCMOTJTW.js";
4
+ import "../chunk-KVHP5ZME.js";
5
+ import {
6
+ fetchAccountPublicKey
7
+ } from "../chunk-QZCFVWA7.js";
8
+ import "../chunk-GKPURU7P.js";
9
+ import "../chunk-FCUUVHTS.js";
7
10
  import "../chunk-YHG74UFF.js";
8
11
  import {
9
12
  fetchModeOverride,
@@ -13,31 +16,32 @@ import {
13
16
  handlePostToolUse,
14
17
  handleStop,
15
18
  reportEvent
16
- } from "../chunk-FXIL7RCL.js";
19
+ } from "../chunk-OADGBOP7.js";
17
20
  import {
18
21
  askUser,
19
22
  cancelQuestion,
20
23
  waitForAnswer
21
24
  } from "../chunk-JHJHCMAF.js";
22
- import "../chunk-TG3T3M4K.js";
23
- import "../chunk-DKWM5T3P.js";
24
- import "../chunk-QA72MKIT.js";
25
+ import "../chunk-JVZX5YRJ.js";
26
+ import "../chunk-5NDB3YOE.js";
27
+ import "../chunk-OVEGEQSB.js";
25
28
  import "../chunk-BSZYIAZL.js";
26
29
  import "../chunk-SAF6HGAA.js";
27
- import "../chunk-IUWRVTQK.js";
28
30
  import "../chunk-7QLSKOSU.js";
29
31
  import "../chunk-KZERVKTD.js";
30
- import "../chunk-XX2V4QS5.js";
32
+ import "../chunk-XREW7RQ3.js";
33
+ import "../chunk-4LL6LG5X.js";
31
34
  import {
32
35
  getApiKey,
33
36
  getBaseUrl
34
37
  } from "../chunk-2UMNXADU.js";
35
38
  import {
36
39
  resolvePolicy
37
- } from "../chunk-X6RXX2NF.js";
40
+ } from "../chunk-3MCEES6Z.js";
38
41
  export {
39
42
  askUser,
40
43
  cancelQuestion,
44
+ fetchAccountPublicKey,
41
45
  fetchModeOverride,
42
46
  fetchModeState,
43
47
  getApiKey,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushary/agent-hooks",
3
- "version": "0.89.11",
3
+ "version": "0.89.12",
4
4
  "description": "Permission hooks for AI coding agents: route tool approvals through Pushary push notifications",
5
5
  "keywords": [
6
6
  "pushary",
@@ -51,6 +51,7 @@
51
51
  "pushary-elicitation-hook": "./dist/bin/pushary-elicitation-hook.js",
52
52
  "pushary-claude": "./dist/bin/pushary-claude.js",
53
53
  "pushary-daemon": "./dist/bin/pushary-daemon.js",
54
+ "pushary-daemon-supervisor": "./dist/bin/pushary-daemon-supervisor.js",
54
55
  "pushary-codex": "./dist/bin/pushary-codex.js",
55
56
  "pushary-codex-bridge": "./dist/bin/pushary-codex-bridge.js",
56
57
  "pushary-codex-hook": "./dist/bin/pushary-codex-hook.js",
File without changes