@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.
- package/CHANGELOG.md +38 -0
- package/README.md +3 -2
- package/dist/bin/pushary-bell-hook.js +5 -5
- package/dist/bin/pushary-bell.js +11 -11
- package/dist/bin/pushary-claude.js +104 -32
- package/dist/bin/pushary-clean.js +39 -28
- package/dist/bin/pushary-codex-bridge.js +17 -16
- package/dist/bin/pushary-codex-hook.js +11 -10
- package/dist/bin/pushary-codex.js +7 -7
- package/dist/bin/pushary-connect.js +12 -12
- package/dist/bin/pushary-daemon-supervisor.d.ts +1 -0
- package/dist/bin/pushary-daemon-supervisor.js +27 -0
- package/dist/bin/pushary-daemon.js +22 -22
- package/dist/bin/pushary-disconnect.js +9 -9
- package/dist/bin/pushary-doctor.js +59 -49
- package/dist/bin/pushary-elicitation-hook.js +4 -4
- package/dist/bin/pushary-gemini-bridge.js +16 -15
- package/dist/bin/pushary-gemini-hook.js +10 -9
- package/dist/bin/pushary-hook.js +13 -13
- package/dist/bin/pushary-login.js +11 -11
- package/dist/bin/pushary-logout.js +11 -11
- package/dist/bin/pushary-mode.js +5 -5
- package/dist/bin/pushary-notification-hook.js +7 -7
- package/dist/bin/pushary-opencode-hook.js +10 -9
- package/dist/bin/pushary-permission-denied-hook.js +11 -11
- package/dist/bin/pushary-permission-hook.js +11 -11
- package/dist/bin/pushary-post-hook.js +7 -7
- package/dist/bin/pushary-prompt-hook.js +7 -7
- package/dist/bin/pushary-session-end-hook.js +7 -7
- package/dist/bin/pushary-session-start-hook.js +7 -7
- package/dist/bin/pushary-setup.js +87 -59
- package/dist/bin/pushary-stats.js +4 -4
- package/dist/bin/pushary-status.js +14 -14
- package/dist/bin/pushary-stop-hook.js +7 -7
- package/dist/bin/pushary-stopfailure-hook.js +7 -7
- package/dist/bin/pushary-suggestions.js +2 -2
- package/dist/bin/pushary-upgrade.js +21 -21
- package/dist/bin/pushary-wait.js +5 -5
- package/dist/bin/pushary.js +1 -1
- package/dist/{chunk-253WC6O5.js → chunk-327YMKP5.js} +1 -1
- package/dist/{chunk-6XUABEX2.js → chunk-3OXHYPZG.js} +1 -1
- package/dist/{chunk-MZGWKIUZ.js → chunk-3XSP5SML.js} +7 -3
- package/dist/{chunk-XX2V4QS5.js → chunk-4LL6LG5X.js} +2 -2
- package/dist/{chunk-DKWM5T3P.js → chunk-5NDB3YOE.js} +2 -2
- package/dist/{chunk-TEZ2FZD6.js → chunk-6GU55AQQ.js} +2 -2
- package/dist/{chunk-Q223OM5J.js → chunk-6V7ZDH3A.js} +4 -4
- package/dist/{chunk-OLAGKKSR.js → chunk-6VXNA5JB.js} +16 -6
- package/dist/{chunk-34GN3IPX.js → chunk-7DK3ZH3N.js} +1 -1
- package/dist/{chunk-PZRWFWSR.js → chunk-7HYJPOGG.js} +7 -7
- package/dist/{chunk-TY5HVMXT.js → chunk-DHR4F2CR.js} +1 -1
- package/dist/{chunk-3HFK3UXM.js → chunk-FCUUVHTS.js} +1 -1
- package/dist/{chunk-NCVIWGVA.js → chunk-GKPURU7P.js} +1 -1
- package/dist/chunk-JJV5Q4KG.js +20 -0
- package/dist/{chunk-TG3T3M4K.js → chunk-JVZX5YRJ.js} +6 -2
- package/dist/{chunk-6EKQZA6R.js → chunk-KVHP5ZME.js} +1 -1
- package/dist/{chunk-X4ZUUFKV.js → chunk-L4ZCFMWW.js} +63 -1
- package/dist/{chunk-2LPEZYMC.js → chunk-MFNQ5IMW.js} +1 -1
- package/dist/{chunk-KVE5RCQL.js → chunk-NBRM3FMD.js} +1 -1
- package/dist/{chunk-FZ73G2RO.js → chunk-NESKLV6R.js} +25 -6
- package/dist/{chunk-FXIL7RCL.js → chunk-OADGBOP7.js} +4 -4
- package/dist/{chunk-J4K75V4D.js → chunk-OCMOTJTW.js} +10 -9
- package/dist/{chunk-LURY4WNF.js → chunk-OTPJ4FUR.js} +1 -1
- package/dist/{chunk-QA72MKIT.js → chunk-OVEGEQSB.js} +5 -5
- package/dist/{chunk-3SQYKLBW.js → chunk-PS7DQ2SU.js} +46 -18
- package/dist/{chunk-UDBJHQMG.js → chunk-QFJZHVVL.js} +1 -1
- package/dist/chunk-QZCFVWA7.js +58 -0
- package/dist/{chunk-3XTFX4CL.js → chunk-RLQWNEPM.js} +3 -2
- package/dist/{chunk-3CUDMTL4.js → chunk-RNKPLUWC.js} +10 -3
- package/dist/{chunk-SYUIXXQW.js → chunk-VF3RTVWY.js} +1 -1
- package/dist/{chunk-TRVIRETT.js → chunk-VPLQFXCH.js} +1 -1
- package/dist/{chunk-IUN6VOKV.js → chunk-WDVQ6O4C.js} +2 -42
- package/dist/{chunk-IUWRVTQK.js → chunk-XREW7RQ3.js} +1 -1
- package/dist/{chunk-BLODMQKJ.js → chunk-Y4WVZIEI.js} +1 -1
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.js +15 -11
- package/package.json +2 -1
- /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-
|
|
7
|
+
} from "./chunk-L4ZCFMWW.js";
|
|
8
8
|
import {
|
|
9
9
|
getMachineId
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-5NDB3YOE.js";
|
|
11
11
|
import {
|
|
12
12
|
pusharyDir
|
|
13
|
-
} from "./chunk-
|
|
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-
|
|
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", "
|
|
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
|
|
210
|
+
const supervisorPath = win32Path.join(win32Path.dirname(input.daemonEntry), "pushary-daemon-supervisor.js");
|
|
211
|
+
const supervised = (input.entryExists ?? existsSync)(supervisorPath);
|
|
212
|
+
const args = supervised ? `"${xml(supervisorPath)}" "${xml(input.daemonEntry)}"` : `"${xml(input.daemonEntry)}"`;
|
|
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
|
|
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")
|
|
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
|
-
|
|
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
|
|
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) {
|
|
@@ -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,
|
|
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-
|
|
6
|
+
} from "./chunk-XREW7RQ3.js";
|
|
7
7
|
import {
|
|
8
8
|
backupFile,
|
|
9
9
|
readJsonSafe,
|
|
10
10
|
writeFileAtomic,
|
|
11
11
|
writeJsonAtomic
|
|
12
|
-
} from "./chunk-
|
|
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,9 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getBaseUrl
|
|
3
|
-
} from "./chunk-2UMNXADU.js";
|
|
4
1
|
import {
|
|
5
2
|
redactSecrets
|
|
6
|
-
} from "./chunk-
|
|
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
|
};
|
package/dist/src/index.d.ts
CHANGED
|
@@ -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
|
-
|
|
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-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import
|
|
6
|
-
|
|
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-
|
|
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-
|
|
23
|
-
import "../chunk-
|
|
24
|
-
import "../chunk-
|
|
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-
|
|
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-
|
|
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.
|
|
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
|