pushary 1.9.82 → 1.9.84
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 +12 -0
- package/data/SKILL.md +132 -465
- package/data/cowork/SKILL.md +8 -8
- package/data/cursor-plugin/.cursor-plugin/plugin.json +1 -1
- package/data/cursor-plugin/CHANGELOG.md +8 -0
- package/data/cursor-plugin/commands/notify-when-done.md +1 -1
- package/data/cursor-plugin/rules/pushary.mdc +5 -4
- package/data/cursor-plugin/skills/pushary/SKILL.md +131 -464
- package/data/vscode-plugin/.claude-plugin/plugin.json +1 -1
- package/data/vscode-plugin/CHANGELOG.md +8 -0
- package/data/vscode-plugin/commands/notify-when-done.md +1 -1
- package/data/vscode-plugin/skills/pushary/SKILL.md +131 -464
- package/dist/{api-TZO5ACOS.js → api-4WEMR2G3.js} +10 -10
- package/dist/bin/pushary-bell-hook.js +26 -26
- package/dist/bin/pushary-bell.js +10 -10
- package/dist/bin/pushary-claude.js +32 -31
- package/dist/bin/pushary-clean.js +37 -33
- package/dist/bin/pushary-codex-bridge.js +21 -21
- package/dist/bin/pushary-codex-hook.js +44 -43
- package/dist/bin/pushary-codex-session.js +8 -8
- package/dist/bin/pushary-codex.js +14 -13
- package/dist/bin/pushary-connect.js +27 -26
- package/dist/bin/pushary-cowork.js +5 -5
- package/dist/bin/pushary-daemon.js +70 -43
- package/dist/bin/pushary-disconnect.js +26 -25
- package/dist/bin/pushary-display-hook.js +17 -17
- package/dist/bin/pushary-doctor.js +42 -41
- package/dist/bin/pushary-elicitation-hook.js +26 -26
- package/dist/bin/pushary-gemini-bridge.js +15 -15
- package/dist/bin/pushary-gemini-hook.js +35 -34
- package/dist/bin/pushary-hook.js +30 -30
- package/dist/bin/pushary-login.js +20 -20
- package/dist/bin/pushary-logout.js +25 -24
- package/dist/bin/pushary-mcp.js +11 -11
- package/dist/bin/pushary-mode.js +15 -15
- package/dist/bin/pushary-notification-hook.js +25 -25
- package/dist/bin/pushary-opencode-hook.js +35 -34
- package/dist/bin/pushary-permission-denied-hook.js +30 -30
- package/dist/bin/pushary-permission-hook.js +30 -30
- package/dist/bin/pushary-post-hook.js +25 -25
- package/dist/bin/pushary-prompt-hook.js +25 -25
- package/dist/bin/pushary-session-end-hook.js +27 -27
- package/dist/bin/pushary-session-start-hook.js +35 -35
- package/dist/bin/pushary-setup.js +48 -47
- package/dist/bin/pushary-stats.js +5 -5
- package/dist/bin/pushary-status.js +32 -31
- package/dist/bin/pushary-stop-hook.js +25 -25
- package/dist/bin/pushary-stopfailure-hook.js +25 -25
- package/dist/bin/pushary-suggestions.js +15 -15
- package/dist/bin/pushary-transcript-register.js +21 -20
- package/dist/bin/pushary-transcripts.js +30 -20
- package/dist/bin/pushary-upgrade.js +40 -39
- package/dist/bin/pushary-wait.js +15 -15
- package/dist/bin/pushary.js +7 -7
- package/dist/{chunk-3BFCJZBU.js → chunk-254B34JU.js} +1 -1
- package/dist/{chunk-NEWGYFKC.js → chunk-2VZY5XQ5.js} +7 -7
- package/dist/chunk-3MWQZKIO.js +843 -0
- package/dist/{chunk-RL2KE6HG.js → chunk-42DNYOC4.js} +23 -21
- package/dist/{chunk-DS5BR4K6.js → chunk-4J3NGYHG.js} +2 -2
- package/dist/{chunk-2TEX3APZ.js → chunk-4OP5GWHQ.js} +5 -5
- package/dist/{chunk-UYTPCZ4M.js → chunk-4QGV3II7.js} +4 -4
- package/dist/{chunk-MHUKYYYR.js → chunk-4TMKTLQX.js} +44 -1
- package/dist/{chunk-O6T3CLWT.js → chunk-5Z43EFX2.js} +2 -2
- package/dist/{chunk-2BJZFA7X.js → chunk-64XK7DLE.js} +3 -3
- package/dist/{chunk-IXVMMDIG.js → chunk-6HBWJXU6.js} +3 -3
- package/dist/{chunk-W3VRQEL3.js → chunk-7GYDMVHV.js} +2 -2
- package/dist/{chunk-TO77OYLM.js → chunk-7ZYVX2KN.js} +1 -1
- package/dist/{chunk-LGWTITVK.js → chunk-BGMYSRMY.js} +1 -1
- package/dist/{chunk-C6FQ4YST.js → chunk-BS5MTP34.js} +2 -2
- package/dist/{chunk-LNSCANYY.js → chunk-BUS7MXEE.js} +3 -3
- package/dist/{chunk-FJZSJZCT.js → chunk-CIICMXVH.js} +3 -3
- package/dist/{chunk-GUM3WG4B.js → chunk-CSOVOAX5.js} +6 -6
- package/dist/{chunk-AM3H6HWG.js → chunk-CZ7C5AJT.js} +1 -1
- package/dist/{chunk-3V6G2GBJ.js → chunk-DNBBWBYA.js} +5 -5
- package/dist/{chunk-72CIQCBA.js → chunk-EKWDNEPN.js} +3 -3
- package/dist/{chunk-6224ENW3.js → chunk-EX33ZFJ6.js} +3 -3
- package/dist/{chunk-6355HHSR.js → chunk-FNC4SPOD.js} +2 -2
- package/dist/{chunk-CXZAKS7S.js → chunk-FRPR4OTH.js} +4 -4
- package/dist/{chunk-PJ26BODT.js → chunk-FSSA76HW.js} +1 -1
- package/dist/{chunk-RRMRP62I.js → chunk-G2GOVKBU.js} +6 -6
- package/dist/{chunk-TTTK44RK.js → chunk-GGGOFJBL.js} +1 -1
- package/dist/{chunk-OXTRF7CP.js → chunk-GWHZUHIK.js} +1 -1
- package/dist/{chunk-TKFDPYXS.js → chunk-H6IJOGDH.js} +4 -4
- package/dist/{chunk-JXE4UQFJ.js → chunk-HARHFDZM.js} +1 -1
- package/dist/{chunk-AXE2ZOKS.js → chunk-HLAW7HUT.js} +2 -2
- package/dist/{chunk-G5BYSS6C.js → chunk-HVZJ2EEI.js} +6 -6
- package/dist/{chunk-OIW3JAWH.js → chunk-HWT42Z4O.js} +5 -5
- package/dist/{chunk-WG67W43Y.js → chunk-JHWOM55B.js} +3 -1
- package/dist/{chunk-JNCD2ZG3.js → chunk-JJCMQRBF.js} +3 -3
- package/dist/{chunk-FHPSVTS5.js → chunk-JLJWVKMJ.js} +54 -835
- package/dist/{chunk-ONUAAXAW.js → chunk-JSZT4Q23.js} +1 -1
- package/dist/{chunk-UB7VUSSX.js → chunk-LUSWC2MV.js} +3 -3
- package/dist/{chunk-M5XNFUXN.js → chunk-OGTZ7JR7.js} +1 -1
- package/dist/{chunk-QJJJENT2.js → chunk-OKWHHDV5.js} +5 -5
- package/dist/{chunk-5LLZSX7I.js → chunk-OSEGZLCO.js} +3 -3
- package/dist/{chunk-UOUUTDWF.js → chunk-PHBZK4SC.js} +3 -3
- package/dist/{chunk-JTYZEP4Q.js → chunk-POKCUYIQ.js} +1 -1
- package/dist/{chunk-D3QGBMO3.js → chunk-QF6OJUWQ.js} +1 -1
- package/dist/{chunk-APSYBSMG.js → chunk-QG5Y5A36.js} +10 -10
- package/dist/{chunk-J4TQYGHU.js → chunk-QSDZE2B7.js} +5 -5
- package/dist/{chunk-4S5XVFDV.js → chunk-RPNT4D3K.js} +1 -1
- package/dist/{chunk-6L2U3TP3.js → chunk-SAPRO7FI.js} +6 -6
- package/dist/{chunk-ESRKYHWE.js → chunk-SBK7WGSE.js} +2 -2
- package/dist/{chunk-L77YWBMK.js → chunk-TD5PW2VI.js} +6 -6
- package/dist/{chunk-WLOVGZ7R.js → chunk-TFJQAPIA.js} +2 -2
- package/dist/{chunk-I4RNLK5G.js → chunk-TNPKYKXU.js} +166 -24
- package/dist/{chunk-CV56MBIZ.js → chunk-TSCFJJIB.js} +6 -6
- package/dist/{chunk-ER4UCECJ.js → chunk-TZDEHPYZ.js} +1 -1
- package/dist/{chunk-NPBPH7KI.js → chunk-UGELL4RB.js} +2 -2
- package/dist/{chunk-6WOG2SCC.js → chunk-UIDWJ24H.js} +6 -13
- package/dist/{chunk-N3C3D4AV.js → chunk-UWL6VVE3.js} +4 -4
- package/dist/{chunk-YAMNJXCD.js → chunk-V4JZHAOY.js} +17 -11
- package/dist/{chunk-4TR4G7A4.js → chunk-VD24OIWR.js} +1 -1
- package/dist/{chunk-5TMGEQAC.js → chunk-VJZGR4N3.js} +7 -5
- package/dist/{chunk-GUI2NYCX.js → chunk-VVWL6AB4.js} +5 -5
- package/dist/{chunk-OXKVR2FP.js → chunk-W2IRYDG5.js} +4 -4
- package/dist/{chunk-3UBYG4G7.js → chunk-WRKRZJCW.js} +10 -8
- package/dist/{chunk-DJILSCSU.js → chunk-YQCCJ6U5.js} +3 -3
- package/dist/{chunk-IEAABGST.js → chunk-YU5ACKJP.js} +4 -4
- package/dist/{chunk-DX45XQ36.js → chunk-Z75D2NJN.js} +3 -3
- package/dist/{chunk-S2DLTWFG.js → chunk-ZHL6F2KC.js} +3 -3
- package/dist/{chunk-X2P3O4PX.js → chunk-ZNFAF74M.js} +1 -1
- package/dist/{chunk-WUS2LFTM.js → chunk-ZUZ7NTWO.js} +181 -75
- package/dist/{chunk-Z5HLACZT.js → chunk-ZWKF7WE4.js} +4 -4
- package/dist/{codex-app-cards-switch-3FAIEEB2.js → codex-app-cards-switch-26N5XSSZ.js} +11 -11
- package/dist/{codex-desktop-launch-LHMHRVGF.js → codex-desktop-launch-UU6CPB2I.js} +1 -1
- package/dist/{codex-session-launch-MXUBSTL2.js → codex-session-launch-66LBR4MG.js} +18 -18
- package/dist/{config-MZDRETL2.js → config-ESAAVJWO.js} +3 -3
- package/dist/{global-upgrade-ZDENZA42.js → global-upgrade-QJONTWQI.js} +10 -10
- package/dist/{identity-YZRDJOGY.js → identity-IZVPSC7B.js} +4 -4
- package/dist/{live-capabilities-KSQDWVT6.js → live-capabilities-OEUPZX67.js} +5 -5
- package/dist/{paths-DYZZBVYI.js → paths-GDWS3B46.js} +3 -3
- package/dist/{reapply-L3AI5KJH.js → reapply-P2VOZGWQ.js} +28 -27
- package/dist/src/index.js +29 -29
- package/dist/{upgrade-lock-X7F2OFYB.js → upgrade-lock-3QABNXBZ.js} +4 -4
- package/dist/{usage-TKZALYXF.js → usage-KDRZPUZS.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-VHLRXIMC.js +0 -74
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
verifyRecipients
|
|
6
|
-
} from "./chunk-VHLRXIMC.js";
|
|
7
|
-
import {
|
|
8
|
-
SESSION_HISTORY_RETENTION_DAYS
|
|
9
|
-
} from "./chunk-MHUKYYYR.js";
|
|
2
|
+
SESSION_HISTORY_RETENTION_DAYS,
|
|
3
|
+
savedTranscriptReadPositions
|
|
4
|
+
} from "./chunk-4TMKTLQX.js";
|
|
10
5
|
import {
|
|
11
6
|
ensureDaemonRunning
|
|
12
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-SAPRO7FI.js";
|
|
13
8
|
import {
|
|
14
9
|
hookOwnerOf
|
|
15
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-YU5ACKJP.js";
|
|
16
11
|
import {
|
|
17
12
|
buildTranscriptRecords,
|
|
18
13
|
decodePublicKey,
|
|
@@ -23,46 +18,112 @@ import {
|
|
|
23
18
|
recordSealerFor,
|
|
24
19
|
uploadTranscriptRecords,
|
|
25
20
|
wrapSessionKey
|
|
26
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-7GYDMVHV.js";
|
|
27
22
|
import {
|
|
28
23
|
external_exports
|
|
29
24
|
} from "./chunk-XMSDA5WA.js";
|
|
30
25
|
import {
|
|
31
26
|
transcriptEnvironmentPreference,
|
|
32
27
|
transcriptsEnabled
|
|
33
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-GWHZUHIK.js";
|
|
34
29
|
import {
|
|
35
30
|
readTranscriptPreference
|
|
36
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-FRPR4OTH.js";
|
|
32
|
+
import {
|
|
33
|
+
hookMeaning
|
|
34
|
+
} from "./chunk-3MWQZKIO.js";
|
|
37
35
|
import {
|
|
38
36
|
claudeConfigDir,
|
|
39
37
|
codexHome,
|
|
40
38
|
pusharyDir
|
|
41
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-PHBZK4SC.js";
|
|
42
40
|
import {
|
|
43
41
|
writeJsonAtomic,
|
|
44
42
|
writeJsonAtomicDurable
|
|
45
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-64XK7DLE.js";
|
|
46
44
|
import {
|
|
47
45
|
getApiKey,
|
|
48
46
|
getBaseUrl
|
|
49
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-JSZT4Q23.js";
|
|
50
48
|
import {
|
|
51
49
|
PENDING_COMMAND_PREFIX,
|
|
52
50
|
SESSION_HISTORY_BACKFILL_LIMIT_BYTES,
|
|
53
51
|
canonicalJsonText,
|
|
52
|
+
isHookSource,
|
|
54
53
|
isRecord,
|
|
55
54
|
redactSecretsFromContent
|
|
56
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-JHWOM55B.js";
|
|
56
|
+
|
|
57
|
+
// src/transcript-recipient-pin.ts
|
|
58
|
+
import { existsSync, mkdirSync, readFileSync, rmSync } from "fs";
|
|
59
|
+
import { homedir } from "os";
|
|
60
|
+
import { dirname, join } from "path";
|
|
61
|
+
var pinFile = () => process.env.PUSHARY_RECIPIENT_PIN_FILE?.trim() || join(homedir(), ".pushary", "recipients.json");
|
|
62
|
+
var asPin = (offer) => ({
|
|
63
|
+
phonePublicKey: offer.phonePublicKey,
|
|
64
|
+
providerKeyId: offer.provider?.keyId ?? null,
|
|
65
|
+
providerPublicKey: offer.provider?.publicKey ?? null
|
|
66
|
+
});
|
|
67
|
+
var loadPin = (path = pinFile()) => {
|
|
68
|
+
if (!existsSync(path)) return null;
|
|
69
|
+
try {
|
|
70
|
+
const raw = JSON.parse(readFileSync(path, "utf-8"));
|
|
71
|
+
if (typeof raw.phonePublicKey !== "string" || raw.phonePublicKey.length === 0) return null;
|
|
72
|
+
return {
|
|
73
|
+
phonePublicKey: raw.phonePublicKey,
|
|
74
|
+
providerKeyId: typeof raw.providerKeyId === "string" ? raw.providerKeyId : null,
|
|
75
|
+
providerPublicKey: typeof raw.providerPublicKey === "string" ? raw.providerPublicKey : null
|
|
76
|
+
};
|
|
77
|
+
} catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
var savePin = (pin, path = pinFile()) => {
|
|
82
|
+
try {
|
|
83
|
+
mkdirSync(dirname(path), { recursive: true, mode: 448 });
|
|
84
|
+
writeJsonAtomicDurable(path, pin, 384);
|
|
85
|
+
return true;
|
|
86
|
+
} catch {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var clearPin = () => {
|
|
91
|
+
try {
|
|
92
|
+
rmSync(pinFile(), { force: true });
|
|
93
|
+
} catch {
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
var verifyRecipients = (offer, pinned) => {
|
|
97
|
+
if (!pinned) return { kind: "first-use", pin: asPin(offer) };
|
|
98
|
+
const next = asPin(offer);
|
|
99
|
+
const changed = [];
|
|
100
|
+
if (next.phonePublicKey !== pinned.phonePublicKey) changed.push("the phone key this machine seals to");
|
|
101
|
+
if (next.providerKeyId !== pinned.providerKeyId) changed.push("the compliance recovery key id");
|
|
102
|
+
if (next.providerPublicKey !== pinned.providerPublicKey) changed.push("the compliance recovery key");
|
|
103
|
+
return changed.length === 0 ? { kind: "match" } : { kind: "changed", changed };
|
|
104
|
+
};
|
|
105
|
+
var fingerprint = (publicKey) => {
|
|
106
|
+
const hex = Buffer.from(publicKey, "base64").toString("hex").toUpperCase();
|
|
107
|
+
return (hex.slice(0, 8).match(/.{2}/g) ?? []).join(" ");
|
|
108
|
+
};
|
|
109
|
+
var changedRecipientsMessage = (verdict, offer) => [
|
|
110
|
+
"[pushary] Transcript sync stopped: the keys this machine seals transcripts to have changed.",
|
|
111
|
+
...verdict.changed.map((what) => `[pushary] changed: ${what}`),
|
|
112
|
+
`[pushary] now offered: phone ${fingerprint(offer.phonePublicKey)}${offer.provider ? `, recovery ${offer.provider.keyId.slice(0, 8)}` : ", no recovery key"}`,
|
|
113
|
+
"[pushary] If you reinstalled the app or rotated a key, this is expected. Compare the",
|
|
114
|
+
"[pushary] fingerprint above with the one in the app under Settings, then run:",
|
|
115
|
+
"[pushary] pushary transcripts trust --rotate",
|
|
116
|
+
"[pushary] Until then nothing is uploaded, so no turn is sealed to a key you have not seen."
|
|
117
|
+
].join("\n");
|
|
57
118
|
|
|
58
119
|
// src/transcript-registration.ts
|
|
59
120
|
import { createHash as createHash4 } from "crypto";
|
|
60
|
-
import { readFileSync as
|
|
61
|
-
import { basename, dirname as
|
|
121
|
+
import { lstatSync as lstatSync3, readFileSync as readFileSync7, readdirSync as readdirSync2, realpathSync, statSync as statSync3, unlinkSync as unlinkSync2 } from "fs";
|
|
122
|
+
import { basename, dirname as dirname3, isAbsolute, join as join6, relative, resolve as resolve2, sep } from "path";
|
|
62
123
|
|
|
63
124
|
// src/claude-display-draft.ts
|
|
64
|
-
import { closeSync, fstatSync, lstatSync, openSync, readFileSync, readSync, unlinkSync } from "fs";
|
|
65
|
-
import { join } from "path";
|
|
125
|
+
import { closeSync, fstatSync, lstatSync, openSync, readFileSync as readFileSync2, readSync, unlinkSync } from "fs";
|
|
126
|
+
import { join as join2 } from "path";
|
|
66
127
|
|
|
67
128
|
// src/transcript-redaction.ts
|
|
68
129
|
var redactDraft = (text, complete = false) => {
|
|
@@ -115,14 +176,14 @@ var stateSchema = external_exports.object({
|
|
|
115
176
|
startedAt: external_exports.number().int().positive(),
|
|
116
177
|
updatedAt: external_exports.number().int().positive()
|
|
117
178
|
});
|
|
118
|
-
var fileFor = (id, directory) =>
|
|
179
|
+
var fileFor = (id, directory) => join2(directory, `${id}.display`);
|
|
119
180
|
var readState = (sessionId, runtime) => {
|
|
120
181
|
if (!identifier.safeParse(sessionId).success) return null;
|
|
121
182
|
try {
|
|
122
183
|
const path = fileFor(sessionId, runtime.directory);
|
|
123
184
|
const info = lstatSync(path);
|
|
124
185
|
if (!info.isFile() || info.nlink !== 1 || info.size > MAX_TAIL || (info.mode & 511) !== 384) return null;
|
|
125
|
-
const envelope = external_exports.object({ content: external_exports.string() }).parse(JSON.parse(
|
|
186
|
+
const envelope = external_exports.object({ content: external_exports.string() }).parse(JSON.parse(readFileSync2(path, "utf8")));
|
|
126
187
|
const plain = decryptRecord(envelope.content, runtime.sessionKey);
|
|
127
188
|
if (!plain) return null;
|
|
128
189
|
const state = stateSchema.parse(JSON.parse(plain));
|
|
@@ -205,18 +266,18 @@ var readDisplayDraft = (sessionId, runtime) => {
|
|
|
205
266
|
};
|
|
206
267
|
|
|
207
268
|
// src/transcript-session-key.ts
|
|
208
|
-
import { existsSync, mkdirSync, readFileSync as
|
|
209
|
-
import { homedir } from "os";
|
|
210
|
-
import { join as
|
|
211
|
-
var sessionKeyDirectory = () => process.env.PUSHARY_SESSION_KEY_DIR?.trim() ||
|
|
269
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, readdirSync, rmSync as rmSync2, statSync } from "fs";
|
|
270
|
+
import { homedir as homedir2 } from "os";
|
|
271
|
+
import { join as join3 } from "path";
|
|
272
|
+
var sessionKeyDirectory = () => process.env.PUSHARY_SESSION_KEY_DIR?.trim() || join3(homedir2(), ".pushary", "sessions");
|
|
212
273
|
var SESSION_DISPLAY_TTL_MS = 48 * 60 * 60 * 1e3;
|
|
213
274
|
var SAFE_SESSION_ID = /^[A-Za-z0-9._-]{1,128}$/;
|
|
214
|
-
var fileFor2 = (sessionId, directory) => SAFE_SESSION_ID.test(sessionId) ?
|
|
275
|
+
var fileFor2 = (sessionId, directory) => SAFE_SESSION_ID.test(sessionId) ? join3(directory, `${sessionId}.json`) : null;
|
|
215
276
|
var loadSessionKey = (sessionId, directory = sessionKeyDirectory()) => {
|
|
216
277
|
const path = fileFor2(sessionId, directory);
|
|
217
|
-
if (!path || !
|
|
278
|
+
if (!path || !existsSync2(path)) return null;
|
|
218
279
|
try {
|
|
219
|
-
const raw = JSON.parse(
|
|
280
|
+
const raw = JSON.parse(readFileSync3(path, "utf-8"));
|
|
220
281
|
const key = typeof raw.sessionKey === "string" ? Buffer.from(raw.sessionKey, "base64") : null;
|
|
221
282
|
if (!key || key.length !== 32) return null;
|
|
222
283
|
return {
|
|
@@ -235,7 +296,7 @@ var saveSessionKey = (sessionId, value, directory = sessionKeyDirectory()) => {
|
|
|
235
296
|
const path = fileFor2(sessionId, directory);
|
|
236
297
|
if (!path) return false;
|
|
237
298
|
try {
|
|
238
|
-
|
|
299
|
+
mkdirSync2(directory, { recursive: true, mode: 448 });
|
|
239
300
|
writeJsonAtomicDurable(path, {
|
|
240
301
|
sessionKey: Buffer.from(value.sessionKey).toString("base64"),
|
|
241
302
|
wrappedKey: value.wrappedKey,
|
|
@@ -250,15 +311,15 @@ var saveSessionKey = (sessionId, value, directory = sessionKeyDirectory()) => {
|
|
|
250
311
|
}
|
|
251
312
|
};
|
|
252
313
|
var sweepStaleSessionDisplays = (now = Date.now(), dir = sessionKeyDirectory()) => {
|
|
253
|
-
if (!
|
|
314
|
+
if (!existsSync2(dir)) return 0;
|
|
254
315
|
let removed = 0;
|
|
255
316
|
try {
|
|
256
317
|
for (const name of readdirSync(dir)) {
|
|
257
318
|
if (!name.endsWith(".display")) continue;
|
|
258
|
-
const path =
|
|
319
|
+
const path = join3(dir, name);
|
|
259
320
|
try {
|
|
260
321
|
if (now - statSync(path).mtimeMs <= SESSION_DISPLAY_TTL_MS) continue;
|
|
261
|
-
|
|
322
|
+
rmSync2(path, { force: true });
|
|
262
323
|
removed += 1;
|
|
263
324
|
} catch {
|
|
264
325
|
}
|
|
@@ -366,8 +427,8 @@ var startDisplayPublisher = (options) => {
|
|
|
366
427
|
|
|
367
428
|
// src/transcript-reader.ts
|
|
368
429
|
import { createHash as createHash3 } from "crypto";
|
|
369
|
-
import { join as
|
|
370
|
-
import { closeSync as closeSync3, fstatSync as fstatSync3, openSync as openSync3, readFileSync as
|
|
430
|
+
import { join as join4 } from "path";
|
|
431
|
+
import { closeSync as closeSync3, fstatSync as fstatSync3, openSync as openSync3, readFileSync as readFileSync6, readSync as readSync2, statSync as statSync2 } from "fs";
|
|
371
432
|
|
|
372
433
|
// src/transcript-source.ts
|
|
373
434
|
var normalizeTranscriptLines = (lines, source) => {
|
|
@@ -422,7 +483,7 @@ var transcriptLinesSince = (lines, oldestLineMs, dropCompactionSummaries) => lin
|
|
|
422
483
|
});
|
|
423
484
|
|
|
424
485
|
// src/transcript-snapshot-file.ts
|
|
425
|
-
import { closeSync as closeSync2, fstatSync as fstatSync2, openSync as openSync2, readFileSync as
|
|
486
|
+
import { closeSync as closeSync2, fstatSync as fstatSync2, openSync as openSync2, readFileSync as readFileSync4 } from "fs";
|
|
426
487
|
|
|
427
488
|
// src/transcript-snapshot-source.ts
|
|
428
489
|
import { createHash } from "crypto";
|
|
@@ -551,10 +612,10 @@ var parseCursorSnapshot = (text) => {
|
|
|
551
612
|
const record = JSON.parse(line);
|
|
552
613
|
if (isRecord(record) && (record.type === "metadata" || record.type === "turn_ended")) continue;
|
|
553
614
|
const message = cursorMessage.parse(record);
|
|
554
|
-
const
|
|
555
|
-
const occurrence = occurrences.get(
|
|
556
|
-
occurrences.set(
|
|
557
|
-
messages.push({ id: `cursor:${
|
|
615
|
+
const fingerprint2 = createHash("sha256").update(canonicalJsonText(message)).digest("hex");
|
|
616
|
+
const occurrence = occurrences.get(fingerprint2) ?? 0;
|
|
617
|
+
occurrences.set(fingerprint2, occurrence + 1);
|
|
618
|
+
messages.push({ id: `cursor:${fingerprint2}:${occurrence}`, role: message.role, content: message.message.content });
|
|
558
619
|
}
|
|
559
620
|
return messages;
|
|
560
621
|
};
|
|
@@ -587,7 +648,7 @@ var readTranscriptSnapshot = (path, source, sessionId) => {
|
|
|
587
648
|
try {
|
|
588
649
|
const before = fstatSync2(descriptor);
|
|
589
650
|
if (!before.isFile() || before.size === 0 || before.size > SESSION_HISTORY_BACKFILL_LIMIT_BYTES) throw new Error("History snapshot is empty or exceeds its size limit");
|
|
590
|
-
const text =
|
|
651
|
+
const text = readFileSync4(descriptor, "utf8");
|
|
591
652
|
const after = fstatSync2(descriptor);
|
|
592
653
|
if (before.size !== after.size || before.mtimeMs !== after.mtimeMs) throw new Error("History snapshot changed while reading");
|
|
593
654
|
let messages;
|
|
@@ -610,8 +671,8 @@ var readTranscriptSnapshot = (path, source, sessionId) => {
|
|
|
610
671
|
};
|
|
611
672
|
|
|
612
673
|
// src/transcript-snapshot-journal.ts
|
|
613
|
-
import { lstatSync as lstatSync2, mkdirSync as
|
|
614
|
-
import { dirname } from "path";
|
|
674
|
+
import { lstatSync as lstatSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync5 } from "fs";
|
|
675
|
+
import { dirname as dirname2 } from "path";
|
|
615
676
|
|
|
616
677
|
// src/transcript-projection.ts
|
|
617
678
|
import { createHash as createHash2 } from "crypto";
|
|
@@ -619,7 +680,8 @@ var projectTranscriptSnapshot = (previous, messages) => {
|
|
|
619
680
|
const revision = (previous?.revision ?? 0) + 1;
|
|
620
681
|
const entries = /* @__PURE__ */ Object.create(null);
|
|
621
682
|
const lines = [];
|
|
622
|
-
for (const
|
|
683
|
+
for (const message of messages) {
|
|
684
|
+
const order = message.sourcePosition;
|
|
623
685
|
if (!message.id || message.id.length > 256 || Object.hasOwn(entries, message.id)) throw new Error("Invalid or duplicate history message identity");
|
|
624
686
|
const record = { timestamp: message.timestamp, observedAtMs: message.observedAtMs, historyMessage: { role: message.role, content: message.content } };
|
|
625
687
|
const digest = createHash2("sha256").update(JSON.stringify(record)).digest("hex");
|
|
@@ -660,7 +722,7 @@ var TranscriptSnapshotJournal = class {
|
|
|
660
722
|
return;
|
|
661
723
|
}
|
|
662
724
|
if (!info.isFile() || info.nlink !== 1 || info.size > MAXIMUM_JOURNAL_BYTES || process.getuid && (info.uid !== process.getuid() || (info.mode & 511) !== 384)) throw new Error("Unsafe history checkpoint");
|
|
663
|
-
const saved = journalSchema.parse(JSON.parse(
|
|
725
|
+
const saved = journalSchema.parse(JSON.parse(readFileSync5(path, "utf8")));
|
|
664
726
|
if (saved.binding !== binding) throw new Error("History checkpoint belongs to another source");
|
|
665
727
|
this.current = saved.epochStartedAtMs === epochStartedAtMs ? saved : { ...saved, epochStartedAtMs, initialized: false, observedAtMs: {}, pending: null, excludedIds: [], projection: { revision: Math.max(saved.projection?.revision ?? 0, saved.pending?.next.revision ?? 0), entries: {} } };
|
|
666
728
|
}
|
|
@@ -677,7 +739,7 @@ var TranscriptSnapshotJournal = class {
|
|
|
677
739
|
for (const message of messages) {
|
|
678
740
|
if (!message.timestamp && !excluded.has(message.id) && !Object.hasOwn(observedAtMs, message.id)) observedAtMs[message.id] = nowMs;
|
|
679
741
|
}
|
|
680
|
-
const allowed = messages.
|
|
742
|
+
const allowed = messages.flatMap((message, sourcePosition) => !excluded.has(message.id) && (message.timestamp ? Date.parse(message.timestamp) : observedAtMs[message.id] ?? 0) >= oldestMessageMs ? [{ ...message.timestamp ? message : { ...message, observedAtMs: observedAtMs[message.id] }, sourcePosition }] : []);
|
|
681
743
|
const projected = projectTranscriptSnapshot(this.current.projection, allowed);
|
|
682
744
|
if (projected.lines.length === 0) {
|
|
683
745
|
const metadataChanged = excluded.size !== this.current.excludedIds.length || Object.keys(observedAtMs).length !== Object.keys(this.current.observedAtMs).length;
|
|
@@ -705,7 +767,7 @@ var TranscriptSnapshotJournal = class {
|
|
|
705
767
|
}
|
|
706
768
|
store(next) {
|
|
707
769
|
if (Buffer.byteLength(JSON.stringify(next)) > MAXIMUM_JOURNAL_BYTES) throw new Error("History checkpoint exceeds its size limit");
|
|
708
|
-
|
|
770
|
+
mkdirSync3(dirname2(this.path), { recursive: true, mode: 448 });
|
|
709
771
|
writeJsonAtomicDurable(this.path, next, 384);
|
|
710
772
|
this.current = journalSchema.parse(next);
|
|
711
773
|
}
|
|
@@ -801,7 +863,7 @@ var appendOnlyReader = (path, source, epoch) => ({
|
|
|
801
863
|
read(retentionDays, nowMs) {
|
|
802
864
|
const version = sourceVersion(path);
|
|
803
865
|
const read2 = epoch ? linesSeenDuringEpoch(epoch, path, source, nowMs, retentionDays) : null;
|
|
804
|
-
const lines = read2?.lines ?? normalizeTranscriptLines(
|
|
866
|
+
const lines = read2?.lines ?? normalizeTranscriptLines(readFileSync6(path, "utf8").split("\n"), source);
|
|
805
867
|
return {
|
|
806
868
|
lines,
|
|
807
869
|
acknowledge() {
|
|
@@ -815,7 +877,7 @@ var appendOnlyReader = (path, source, epoch) => ({
|
|
|
815
877
|
var snapshotReader = (options, source) => {
|
|
816
878
|
const { path, epoch } = options;
|
|
817
879
|
const binding = createHash3("sha256").update(JSON.stringify([options.baseUrl, options.apiKey, options.machineId, options.sessionId, source, path])).digest("hex");
|
|
818
|
-
const journalPath =
|
|
880
|
+
const journalPath = join4(options.keyDirectory, "snapshots", binding + ".json");
|
|
819
881
|
const epochStart = epoch?.startedAtMs ?? 0;
|
|
820
882
|
const backfill = epoch ? epoch.backfill : SESSION_HISTORY_BACKFILL;
|
|
821
883
|
let journal;
|
|
@@ -866,11 +928,11 @@ var transcriptHealthReporter = (target) => {
|
|
|
866
928
|
};
|
|
867
929
|
|
|
868
930
|
// src/transcript-sync.ts
|
|
869
|
-
import { join as
|
|
931
|
+
import { join as join5, resolve } from "path";
|
|
870
932
|
var claudeTranscriptPath = (cwd, sessionId) => {
|
|
871
933
|
const projectId = resolve(cwd).replace(/[^a-zA-Z0-9-]/g, "-");
|
|
872
934
|
const configDir = claudeConfigDir();
|
|
873
|
-
return
|
|
935
|
+
return join5(configDir, "projects", projectId, `${sessionId}.jsonl`);
|
|
874
936
|
};
|
|
875
937
|
var createSyncState = () => ({
|
|
876
938
|
sessionKey: null,
|
|
@@ -977,6 +1039,8 @@ var chunkRecords = (records) => {
|
|
|
977
1039
|
};
|
|
978
1040
|
var IDLE_CEILING_MS = 6e4;
|
|
979
1041
|
var RECIPIENT_REFRESH_MS = 6e4;
|
|
1042
|
+
var MAXIMUM_READS_PASSED_OVER_PER_TICK = 16;
|
|
1043
|
+
var LONGEST_SESSION_HISTORY_RETENTION_DAYS = Math.max(...Object.values(SESSION_HISTORY_RETENTION_DAYS));
|
|
980
1044
|
var CATCH_UP_DELAY_MS = 50;
|
|
981
1045
|
var STALLED_BACKOFF_FACTOR = 4;
|
|
982
1046
|
var nothingLeftToUpload = (state) => state.sessionKey !== null && !state.keyRejected && state.unsettled === 0;
|
|
@@ -1039,6 +1103,15 @@ var startTranscriptSync = (opts) => {
|
|
|
1039
1103
|
persistedKey = state.sessionKey;
|
|
1040
1104
|
persistedUploaded = state.keyUploaded;
|
|
1041
1105
|
};
|
|
1106
|
+
const passOverConversationWhileHistoryIsOff = () => {
|
|
1107
|
+
try {
|
|
1108
|
+
for (let read2 = 0; read2 < MAXIMUM_READS_PASSED_OVER_PER_TICK; read2++) {
|
|
1109
|
+
if (reader.read(LONGEST_SESSION_HISTORY_RETENTION_DAYS, Date.now()).acknowledge() !== "more") return;
|
|
1110
|
+
}
|
|
1111
|
+
} catch {
|
|
1112
|
+
return;
|
|
1113
|
+
}
|
|
1114
|
+
};
|
|
1042
1115
|
let running = true;
|
|
1043
1116
|
let inFlight = false;
|
|
1044
1117
|
let stalled = false;
|
|
@@ -1059,6 +1132,7 @@ var startTranscriptSync = (opts) => {
|
|
|
1059
1132
|
const recipients = await fetchPinnedRecipients();
|
|
1060
1133
|
if (!recipients) {
|
|
1061
1134
|
waitingForRecipients = true;
|
|
1135
|
+
if (recipientFailure === "off_for_workspace") passOverConversationWhileHistoryIsOff();
|
|
1062
1136
|
await reportHealth(recipientFailure);
|
|
1063
1137
|
return;
|
|
1064
1138
|
}
|
|
@@ -1125,7 +1199,7 @@ var startTranscriptSync = (opts) => {
|
|
|
1125
1199
|
};
|
|
1126
1200
|
|
|
1127
1201
|
// src/transcript-registration.ts
|
|
1128
|
-
import { homedir as
|
|
1202
|
+
import { homedir as homedir3 } from "os";
|
|
1129
1203
|
var storedRegistrationSchema = external_exports.object({
|
|
1130
1204
|
sessionId: external_exports.string().min(1).max(128),
|
|
1131
1205
|
cwd: external_exports.string(),
|
|
@@ -1140,18 +1214,41 @@ var storedRegistrationSchema = external_exports.object({
|
|
|
1140
1214
|
endedAt: external_exports.number().positive().optional(),
|
|
1141
1215
|
drained: external_exports.boolean().optional()
|
|
1142
1216
|
});
|
|
1143
|
-
var defaultRegistryDirectory = () => process.env.PUSHARY_TRANSCRIPT_REGISTRY_DIR ||
|
|
1217
|
+
var defaultRegistryDirectory = () => process.env.PUSHARY_TRANSCRIPT_REGISTRY_DIR || join6(pusharyDir(), "transcript-capture");
|
|
1144
1218
|
var cliRegistry = (apiKey = getApiKey()) => ({ apiKey, baseUrl: getBaseUrl(), directory: defaultRegistryDirectory() });
|
|
1145
1219
|
var accountFor = (registry) => createHash4("sha256").update(`${registry.baseUrl}\0${registry.apiKey}`).digest("hex");
|
|
1146
1220
|
var TTL = 48 * 60 * 60 * 1e3;
|
|
1221
|
+
var registeredReadPositionsFile = (registry) => join6(registry.directory, "read-positions", `${accountFor(registry)}.json`);
|
|
1222
|
+
var SNAPSHOT_KEYS_DIRECTORY_NAME = "snapshot-keys";
|
|
1223
|
+
var SNAPSHOT_RECIPIENT_PIN_FILE_NAME = "recipients.json";
|
|
1224
|
+
var snapshotKeyDirectory = (registry) => join6(registry.directory, SNAPSHOT_KEYS_DIRECTORY_NAME, accountFor(registry));
|
|
1225
|
+
var snapshotRecipientPinFile = (registry) => join6(snapshotKeyDirectory(registry), SNAPSHOT_RECIPIENT_PIN_FILE_NAME);
|
|
1226
|
+
var entryAt = (path) => {
|
|
1227
|
+
try {
|
|
1228
|
+
return lstatSync3(path);
|
|
1229
|
+
} catch {
|
|
1230
|
+
return null;
|
|
1231
|
+
}
|
|
1232
|
+
};
|
|
1233
|
+
var removedPinFile = (path) => {
|
|
1234
|
+
const entry = entryAt(path);
|
|
1235
|
+
if (!entry || !(entry.isFile() || entry.isSymbolicLink())) return false;
|
|
1236
|
+
unlinkSync2(path);
|
|
1237
|
+
return true;
|
|
1238
|
+
};
|
|
1239
|
+
var clearSnapshotRecipientPins = (registryDirectory = defaultRegistryDirectory()) => {
|
|
1240
|
+
const accounts = join6(registryDirectory, SNAPSHOT_KEYS_DIRECTORY_NAME);
|
|
1241
|
+
if (!entryAt(accounts)?.isDirectory()) return false;
|
|
1242
|
+
return readdirSync2(accounts, { withFileTypes: true }).filter((account) => account.isDirectory()).map((account) => removedPinFile(join6(accounts, account.name, SNAPSHOT_RECIPIENT_PIN_FILE_NAME))).includes(true);
|
|
1243
|
+
};
|
|
1147
1244
|
var read = (path) => {
|
|
1148
1245
|
if (statSync3(path).size > 16384) throw new Error("History registration exceeds its size limit");
|
|
1149
|
-
return storedRegistrationSchema.parse(JSON.parse(
|
|
1246
|
+
return storedRegistrationSchema.parse(JSON.parse(readFileSync7(path, "utf8")));
|
|
1150
1247
|
};
|
|
1151
1248
|
var consent = (record) => record.consentOverride ?? readTranscriptPreference() ?? true;
|
|
1152
1249
|
var withoutTrailingSlash = (url) => url.replace(/\/+$/, "");
|
|
1153
1250
|
var sameServer = (url, registry) => withoutTrailingSlash(url) === withoutTrailingSlash(registry.baseUrl);
|
|
1154
|
-
var fileFor3 = (registry, sessionId) =>
|
|
1251
|
+
var fileFor3 = (registry, sessionId) => join6(registry.directory, `${createHash4("sha256").update(accountFor(registry) + sessionId).digest("hex")}.json`);
|
|
1155
1252
|
var permitted = (registry, raw) => raw.account === accountFor(registry) && consent(raw) && !raw.drained && (raw.source !== "claude" || !!raw.expectedSiteId || !macOwnsClaudeHooks(raw.cwd)) && (!raw.expectedSiteId || raw.expectedSiteId === raw.verifiedSiteId && !!raw.expectedBaseUrl && sameServer(raw.expectedBaseUrl, registry));
|
|
1156
1253
|
var registeredTranscriptEnabled = (apiKey, sessionId, registry = cliRegistry(apiKey)) => {
|
|
1157
1254
|
try {
|
|
@@ -1161,25 +1258,25 @@ var registeredTranscriptEnabled = (apiKey, sessionId, registry = cliRegistry(api
|
|
|
1161
1258
|
}
|
|
1162
1259
|
};
|
|
1163
1260
|
var macOwnsClaudeHooks = (cwd) => [
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1261
|
+
join6(claudeConfigDir(), "settings.json"),
|
|
1262
|
+
join6(cwd, ".claude", "settings.json"),
|
|
1263
|
+
join6(cwd, ".claude", "settings.local.json")
|
|
1167
1264
|
].some((path) => {
|
|
1168
1265
|
try {
|
|
1169
|
-
return hookOwnerOf(JSON.parse(
|
|
1266
|
+
return hookOwnerOf(JSON.parse(readFileSync7(path, "utf8"))) === "app";
|
|
1170
1267
|
} catch {
|
|
1171
1268
|
return false;
|
|
1172
1269
|
}
|
|
1173
1270
|
});
|
|
1174
1271
|
var TRANSCRIPT_ROOT_NAME = { claude: "projects", codex: "sessions", gemini: "tmp", cursor: "projects", hermes: "hermes-history" };
|
|
1175
1272
|
var transcriptRoots = (source) => {
|
|
1176
|
-
const home =
|
|
1177
|
-
if (source === "codex") return [
|
|
1178
|
-
if (source === "cursor") return [
|
|
1179
|
-
if (source === "hermes") return [
|
|
1180
|
-
if (source === "gemini") return [
|
|
1273
|
+
const home = homedir3();
|
|
1274
|
+
if (source === "codex") return [join6(codexHome(), TRANSCRIPT_ROOT_NAME.codex)];
|
|
1275
|
+
if (source === "cursor") return [join6(home, ".cursor", TRANSCRIPT_ROOT_NAME.cursor)];
|
|
1276
|
+
if (source === "hermes") return [join6(home, ".pushary", TRANSCRIPT_ROOT_NAME.hermes)];
|
|
1277
|
+
if (source === "gemini") return [join6(process.env.GEMINI_CLI_HOME || home, ".gemini", "tmp"), join6(home, ".cache", ".gemini", "tmp")];
|
|
1181
1278
|
const configured = process.env.CLAUDE_CONFIG_DIR;
|
|
1182
|
-
return [
|
|
1279
|
+
return [join6(configured || join6(home, ".claude"), TRANSCRIPT_ROOT_NAME.claude), join6(home, ".claude", TRANSCRIPT_ROOT_NAME.claude)];
|
|
1183
1280
|
};
|
|
1184
1281
|
var isAgentTranscriptRoot = (root, source) => isAbsolute(root) && resolve2(root) === root && basename(root) === TRANSCRIPT_ROOT_NAME[source];
|
|
1185
1282
|
var acceptedTranscriptRoots = (source, registeredRoot) => typeof registeredRoot === "string" && isAgentTranscriptRoot(registeredRoot, source) ? [...transcriptRoots(source), registeredRoot] : transcriptRoots(source);
|
|
@@ -1188,8 +1285,8 @@ var resolvedSourcePath = (path) => {
|
|
|
1188
1285
|
try {
|
|
1189
1286
|
return realpathSync(absolute);
|
|
1190
1287
|
} catch {
|
|
1191
|
-
const parent =
|
|
1192
|
-
return parent === absolute ? absolute :
|
|
1288
|
+
const parent = dirname3(absolute);
|
|
1289
|
+
return parent === absolute ? absolute : join6(resolvedSourcePath(parent), basename(absolute));
|
|
1193
1290
|
}
|
|
1194
1291
|
};
|
|
1195
1292
|
var transcriptRootContaining = (candidate, roots) => {
|
|
@@ -1209,9 +1306,15 @@ var captureRegistration = (source, value, registeredRoot) => {
|
|
|
1209
1306
|
const segments = relative(root, path).split(sep);
|
|
1210
1307
|
if (source === "hermes" && (segments.length !== 2 || !/^[a-f0-9]{64}$/.test(segments[0] ?? "") || basename(path) !== `${sessionId}.json`)) return null;
|
|
1211
1308
|
if (source === "gemini" && (segments.length !== 3 || segments[1] !== "chats" || !basename(path).startsWith("session-"))) return null;
|
|
1212
|
-
if (source === "cursor" && (segments[1] !== "agent-transcripts" || basename(path) !== `${sessionId}.jsonl` || !(segments.length === 3 || segments.length === 4 && basename(
|
|
1309
|
+
if (source === "cursor" && (segments[1] !== "agent-transcripts" || basename(path) !== `${sessionId}.jsonl` || !(segments.length === 3 || segments.length === 4 && basename(dirname3(path)) === sessionId))) return null;
|
|
1213
1310
|
return { sessionId, cwd: input.cwd, path, source, root };
|
|
1214
1311
|
};
|
|
1312
|
+
var SESSION_END_EVENT = "SessionEnd";
|
|
1313
|
+
var closesSession = (source, input) => {
|
|
1314
|
+
const event = input.hook_event_name;
|
|
1315
|
+
if (typeof event !== "string") return false;
|
|
1316
|
+
return event === SESSION_END_EVENT || isHookSource(source) && hookMeaning(source, event)?.kind === "session_closed";
|
|
1317
|
+
};
|
|
1215
1318
|
var registerTranscript = (source, input, startDaemon = () => {
|
|
1216
1319
|
void ensureDaemonRunning({ waitTimeoutMs: 0 }).catch(() => {
|
|
1217
1320
|
});
|
|
@@ -1232,7 +1335,7 @@ var registerTranscript = (source, input, startDaemon = () => {
|
|
|
1232
1335
|
return;
|
|
1233
1336
|
}
|
|
1234
1337
|
if (source === "claude" && !options.siteId && !previous?.expectedSiteId && macOwnsClaudeHooks(registration.cwd)) return;
|
|
1235
|
-
const ending = options.ended || input
|
|
1338
|
+
const ending = options.ended || closesSession(source, input) && process.env.PUSHARY_WRAPPER_ACTIVE !== "1";
|
|
1236
1339
|
const stored = {
|
|
1237
1340
|
...registration,
|
|
1238
1341
|
path: previous?.account === account ? previous.path : registration.path,
|
|
@@ -1263,8 +1366,8 @@ var sightRegisteredTranscripts = (epoch, registry, listing) => {
|
|
|
1263
1366
|
};
|
|
1264
1367
|
var startRegisteredTranscripts = (apiKey, machineId, options = {}) => {
|
|
1265
1368
|
const { intervalMs = 3e3, enabled = () => true, storage } = options;
|
|
1266
|
-
const epoch = options.epoch ?? startTranscriptCaptureEpoch(Date.now(), void 0, SESSION_HISTORY_BACKFILL);
|
|
1267
1369
|
const registry = { apiKey, baseUrl: options.baseUrl ?? getBaseUrl(), directory: options.registryDirectory ?? defaultRegistryDirectory() };
|
|
1370
|
+
const epoch = options.epoch ?? startTranscriptCaptureEpoch(Date.now(), savedTranscriptReadPositions(registeredReadPositionsFile(registry)), SESSION_HISTORY_BACKFILL);
|
|
1268
1371
|
const active = /* @__PURE__ */ new Map();
|
|
1269
1372
|
let stopped = false;
|
|
1270
1373
|
let scanning = false;
|
|
@@ -1277,7 +1380,7 @@ var startRegisteredTranscripts = (apiKey, machineId, options = {}) => {
|
|
|
1277
1380
|
try {
|
|
1278
1381
|
let unreadable = 0;
|
|
1279
1382
|
const files = readdirSync2(registry.directory).filter((name) => name.endsWith(".json")).flatMap((name) => {
|
|
1280
|
-
const path =
|
|
1383
|
+
const path = join6(registry.directory, name);
|
|
1281
1384
|
try {
|
|
1282
1385
|
const time = statSync3(path).mtimeMs;
|
|
1283
1386
|
if (Date.now() - time > TTL) {
|
|
@@ -1326,10 +1429,9 @@ var startRegisteredTranscripts = (apiKey, machineId, options = {}) => {
|
|
|
1326
1429
|
for (const [id, registration] of wanted) {
|
|
1327
1430
|
if (active.has(id)) continue;
|
|
1328
1431
|
const current = () => read(registration.registrationPath);
|
|
1329
|
-
const snapshotKeys = join5(registry.directory, "snapshot-keys", accountFor(registry));
|
|
1330
1432
|
const keyStorage = storage ?? (registration.source === "claude" || registration.source === "codex" ? void 0 : {
|
|
1331
|
-
sessionKeyDirectory:
|
|
1332
|
-
recipientPinFile:
|
|
1433
|
+
sessionKeyDirectory: snapshotKeyDirectory(registry),
|
|
1434
|
+
recipientPinFile: snapshotRecipientPinFile(registry)
|
|
1333
1435
|
});
|
|
1334
1436
|
active.set(id, { path: registration.path, stop: startTranscriptSync({
|
|
1335
1437
|
apiKey,
|
|
@@ -1381,7 +1483,11 @@ export {
|
|
|
1381
1483
|
sessionKeyDirectory,
|
|
1382
1484
|
loadSessionKey,
|
|
1383
1485
|
startDraftPublisher,
|
|
1486
|
+
loadPin,
|
|
1487
|
+
clearPin,
|
|
1488
|
+
fingerprint,
|
|
1384
1489
|
claudeTranscriptPath,
|
|
1490
|
+
clearSnapshotRecipientPins,
|
|
1385
1491
|
registeredTranscriptEnabled,
|
|
1386
1492
|
captureRegistration,
|
|
1387
1493
|
registerTranscript,
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
keyCheckFromResponse
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-BUS7MXEE.js";
|
|
4
4
|
import {
|
|
5
5
|
installNetworkDefaults
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-JJCMQRBF.js";
|
|
7
7
|
import {
|
|
8
8
|
getBaseUrl
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-JSZT4Q23.js";
|
|
10
10
|
import {
|
|
11
11
|
isRecord,
|
|
12
12
|
isToolErrorResult,
|
|
13
13
|
toolFailureCodeOfResult
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-JHWOM55B.js";
|
|
15
15
|
|
|
16
16
|
// src/retry.ts
|
|
17
17
|
var isRetryable = (err) => {
|
|
@@ -22,22 +22,22 @@ import {
|
|
|
22
22
|
turnCodexAppCardsOff,
|
|
23
23
|
turnCodexAppCardsOn,
|
|
24
24
|
whyLaunchctlFailed
|
|
25
|
-
} from "./chunk-
|
|
26
|
-
import "./chunk-
|
|
25
|
+
} from "./chunk-OSEGZLCO.js";
|
|
26
|
+
import "./chunk-FNC4SPOD.js";
|
|
27
27
|
import "./chunk-XCEN33UP.js";
|
|
28
28
|
import "./chunk-QCGNGEGE.js";
|
|
29
|
-
import "./chunk-
|
|
29
|
+
import "./chunk-SAPRO7FI.js";
|
|
30
30
|
import "./chunk-XHKBHWLX.js";
|
|
31
|
-
import "./chunk-
|
|
31
|
+
import "./chunk-FRPR4OTH.js";
|
|
32
32
|
import "./chunk-E46NE7FB.js";
|
|
33
|
-
import "./chunk-
|
|
34
|
-
import "./chunk-
|
|
35
|
-
import "./chunk-
|
|
36
|
-
import "./chunk-
|
|
37
|
-
import "./chunk-
|
|
38
|
-
import "./chunk-
|
|
33
|
+
import "./chunk-V4JZHAOY.js";
|
|
34
|
+
import "./chunk-UGELL4RB.js";
|
|
35
|
+
import "./chunk-PHBZK4SC.js";
|
|
36
|
+
import "./chunk-64XK7DLE.js";
|
|
37
|
+
import "./chunk-JSZT4Q23.js";
|
|
38
|
+
import "./chunk-GGGOFJBL.js";
|
|
39
39
|
import "./chunk-ZVU6WMMU.js";
|
|
40
|
-
import "./chunk-
|
|
40
|
+
import "./chunk-JHWOM55B.js";
|
|
41
41
|
import "./chunk-MLKGABMK.js";
|
|
42
42
|
export {
|
|
43
43
|
CODEX_APP_CARDS_DIRECTORY,
|