@pushary/agent-hooks 1.9.62 → 1.9.64
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 +20 -0
- package/README.md +2 -2
- package/dist/{api-7HLZRIUV.js → api-HDLTZTVR.js} +10 -11
- package/dist/bin/pushary-bell-hook.js +27 -30
- package/dist/bin/pushary-bell.js +10 -11
- package/dist/bin/pushary-claude.js +29 -32
- package/dist/bin/pushary-clean.js +63 -42
- package/dist/bin/pushary-codex-bridge.js +22 -24
- package/dist/bin/pushary-codex-hook.js +33 -36
- package/dist/bin/pushary-codex-session.js +8 -8
- package/dist/bin/pushary-codex.js +13 -15
- package/dist/bin/pushary-connect.js +26 -29
- package/dist/bin/pushary-cowork.js +5 -5
- package/dist/bin/pushary-daemon.js +39 -41
- package/dist/bin/pushary-disconnect.js +60 -40
- package/dist/bin/pushary-doctor.js +89 -46
- package/dist/bin/pushary-elicitation-hook.js +28 -31
- package/dist/bin/pushary-gemini-bridge.js +16 -18
- package/dist/bin/pushary-gemini-hook.js +30 -33
- package/dist/bin/pushary-hook.js +31 -34
- package/dist/bin/pushary-login.js +27 -16
- package/dist/bin/pushary-logout.js +26 -29
- package/dist/bin/pushary-mcp.js +11 -12
- package/dist/bin/pushary-mode.js +14 -15
- package/dist/bin/pushary-notification-hook.js +26 -29
- package/dist/bin/pushary-opencode-hook.js +29 -32
- package/dist/bin/pushary-permission-denied-hook.js +31 -34
- package/dist/bin/pushary-permission-hook.js +30 -33
- package/dist/bin/pushary-post-hook.js +26 -29
- package/dist/bin/pushary-prompt-hook.js +26 -29
- package/dist/bin/pushary-session-end-hook.js +28 -31
- package/dist/bin/pushary-session-start-hook.js +35 -37
- package/dist/bin/pushary-setup.js +361 -4412
- package/dist/bin/pushary-stats.js +5 -5
- package/dist/bin/pushary-status.js +32 -35
- package/dist/bin/pushary-stop-hook.js +26 -29
- package/dist/bin/pushary-stopfailure-hook.js +26 -29
- package/dist/bin/pushary-suggestions.js +14 -15
- package/dist/bin/pushary-transcript-register.js +18 -21
- package/dist/bin/pushary-transcripts.js +63 -11
- package/dist/bin/pushary-upgrade.js +41 -43
- package/dist/bin/pushary-wait.js +14 -15
- package/dist/bin/pushary.js +7 -8
- package/dist/{chunk-SJCPIYWJ.js → chunk-2CEVEMJE.js} +3 -3
- package/dist/{chunk-3YGUWPNZ.js → chunk-2EY4HGLG.js} +3 -3
- package/dist/{chunk-ESXGCZDA.js → chunk-2KID4FK4.js} +4 -4
- package/dist/{chunk-EO6CL4PD.js → chunk-2PKHGHMA.js} +2 -2
- package/dist/{chunk-PSCXEH42.js → chunk-2VADJ6JH.js} +2 -2
- package/dist/{chunk-GV43RXR2.js → chunk-2YXBCZ3Z.js} +1 -1
- package/dist/{chunk-7GU4PXE5.js → chunk-2Z7I7DHT.js} +1 -1
- package/dist/{chunk-4K6YZPZ3.js → chunk-3KXBRSL3.js} +1 -1
- package/dist/{chunk-YQK72JGV.js → chunk-42PD2MQH.js} +5 -5
- package/dist/{chunk-EUNSJKJJ.js → chunk-57PU5OBL.js} +21 -14
- package/dist/{chunk-5R23J52J.js → chunk-5NP3OJ5P.js} +7 -9
- package/dist/{chunk-UWCPY4RY.js → chunk-5TNGBDIE.js} +2 -2
- package/dist/{chunk-ZEDGKCCM.js → chunk-5TUDGSDC.js} +1 -1
- package/dist/{chunk-M7MEVILL.js → chunk-66FRMK7V.js} +4 -4
- package/dist/{chunk-3LBB7GVF.js → chunk-6HPLEGUP.js} +4 -4
- package/dist/{chunk-LCNN7UOE.js → chunk-6QPDBD7Q.js} +3 -57
- package/dist/{chunk-AFV3FQNG.js → chunk-7UBDBJTG.js} +4 -4
- package/dist/{chunk-RFCEVROB.js → chunk-A5KQXZR7.js} +3 -3
- package/dist/{chunk-G3ZDCYMU.js → chunk-ADRPW7KU.js} +2 -2
- package/dist/{chunk-OZRT64BB.js → chunk-AN7C3CHH.js} +1 -1
- package/dist/{chunk-6JAWNRDR.js → chunk-AQAPPSDV.js} +3 -3
- package/dist/{chunk-FG5HMJ7C.js → chunk-BAGBCSXA.js} +4 -2
- package/dist/{chunk-W3CBFLIX.js → chunk-BLAIETMP.js} +18 -4
- package/dist/{chunk-CFIQ3252.js → chunk-BSZIPIFA.js} +128 -26
- package/dist/{chunk-7EHZXZB2.js → chunk-CCNH4PJ2.js} +12 -12
- package/dist/{chunk-NZLQ6GMX.js → chunk-CJADXAJU.js} +9 -9
- package/dist/{chunk-TMHE5CVX.js → chunk-DCMRNIDM.js} +4 -4
- package/dist/{chunk-QW3FRUFB.js → chunk-DVYVGBPB.js} +1 -1
- package/dist/{chunk-RSNN2TPE.js → chunk-E23RKH3T.js} +9 -9
- package/dist/{chunk-ZJFJUAHS.js → chunk-E2LB6JNV.js} +6 -6
- package/dist/{chunk-HSRNWCXJ.js → chunk-EEM65CGJ.js} +3 -3
- package/dist/chunk-H4BKC2GN.js +1201 -0
- package/dist/{chunk-7NXB7OVX.js → chunk-HVOQUPSO.js} +1 -1
- package/dist/{chunk-R3CLBNST.js → chunk-IZTDX2MX.js} +3 -3
- package/dist/{chunk-RU37NSZH.js → chunk-JTOBQUIL.js} +3 -3
- package/dist/{chunk-W6MYFAOK.js → chunk-JX3DHGZX.js} +44 -32
- package/dist/{chunk-7NJ4TDUH.js → chunk-KA7JIMTG.js} +6 -6
- package/dist/chunk-KEPESIIR.js +4117 -0
- package/dist/{chunk-EA6574W2.js → chunk-KX3RMF6T.js} +12 -6
- package/dist/{chunk-BIUSODLS.js → chunk-LA7CKRZN.js} +2 -2
- package/dist/{chunk-A4CZPUQ6.js → chunk-LMC5UPL7.js} +1 -1
- package/dist/{chunk-EVZDYG7L.js → chunk-LV6DX4P6.js} +2 -2
- package/dist/{chunk-LWR5VKNC.js → chunk-MIPJ2VXP.js} +12 -14
- package/dist/{chunk-557ZE5EX.js → chunk-ML2Q6WWE.js} +37 -214
- package/dist/{chunk-FXECTHAG.js → chunk-MNKIR2ZB.js} +37 -4
- package/dist/{chunk-LILS32LF.js → chunk-MPPTIZ2G.js} +212 -254
- package/dist/{chunk-VUFHYMSP.js → chunk-MXPOLQZH.js} +1 -1
- package/dist/{chunk-MYEALNW6.js → chunk-NOH3EJFH.js} +1 -1
- package/dist/{chunk-GFAG72LR.js → chunk-NUEPJ5W6.js} +7 -3
- package/dist/chunk-NYV45Q25.js +111 -0
- package/dist/{chunk-NAZRRXZM.js → chunk-O7PCNYEY.js} +2 -2
- package/dist/{chunk-7E2ZN7XA.js → chunk-OQKSF5ST.js} +3 -5
- package/dist/{chunk-VF3IL56Q.js → chunk-PLMX3IHG.js} +3 -3
- package/dist/{chunk-F35YILEN.js → chunk-PMLQRB3D.js} +1 -1
- package/dist/{chunk-SJJYXMJP.js → chunk-Q6ID23SU.js} +6 -6
- package/dist/{chunk-SDOWT67G.js → chunk-QECRQWLV.js} +5 -5
- package/dist/{chunk-Q4WTIKM6.js → chunk-QNATBOUH.js} +3 -3
- package/dist/{chunk-QIPW7OVB.js → chunk-QPPBH5NY.js} +5 -5
- package/dist/{chunk-7ETELRQX.js → chunk-QSW3HAKI.js} +16 -5
- package/dist/{chunk-FVERRWDP.js → chunk-RY4EPMZX.js} +2 -2
- package/dist/{chunk-MURJ4WAL.js → chunk-SROWUG5W.js} +1 -1
- package/dist/{chunk-UUAVYIWJ.js → chunk-TJUJAK5L.js} +4 -2
- package/dist/{chunk-3IFCXMC6.js → chunk-TR3GP5MH.js} +1 -1
- package/dist/{chunk-FX7KDF47.js → chunk-VHKK3US3.js} +3 -3
- package/dist/{chunk-6HIYOY6I.js → chunk-VNRWQCGU.js} +6 -6
- package/dist/{chunk-67Q3Q5IO.js → chunk-XF3AWNMO.js} +6 -6
- package/dist/{chunk-44FNEAXK.js → chunk-XJIIU36L.js} +1 -1
- package/dist/{chunk-DFKEJARZ.js → chunk-Y64JGYTB.js} +1 -1
- package/dist/{chunk-FYS27SUS.js → chunk-YUDZCJYC.js} +10 -10
- package/dist/{codex-app-cards-switch-IIL7IPP6.js → codex-app-cards-switch-JQ6356VX.js} +11 -12
- package/dist/{codex-desktop-launch-XCLMYVBD.js → codex-desktop-launch-YUB2LOAG.js} +1 -1
- package/dist/{codex-session-launch-UMVALJ3A.js → codex-session-launch-UKMAORXS.js} +19 -21
- package/dist/{config-5N3GUJD5.js → config-YY54G3CC.js} +3 -3
- package/dist/{global-upgrade-5F4CSXED.js → global-upgrade-Y4USGPS2.js} +10 -12
- package/dist/{identity-7ULYW4RL.js → identity-W5CYL5RC.js} +4 -5
- package/dist/{live-capabilities-QTSFXA6T.js → live-capabilities-JRNNA5EP.js} +5 -7
- package/dist/{paths-HEMK2ALW.js → paths-4MEBINV3.js} +7 -3
- package/dist/reapply-ZN7C3CB3.js +63 -0
- package/dist/src/index.js +20 -23
- package/dist/{upgrade-lock-IAZC5644.js → upgrade-lock-QAWUV2DO.js} +4 -5
- package/dist/{usage-NEFDYSRT.js → usage-43C2DHDU.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-6ICPEJY5.js +0 -20
- package/dist/chunk-6YSEOXP5.js +0 -615
- package/dist/chunk-LL2KHEJH.js +0 -41
- package/dist/chunk-QENTGE75.js +0 -86
- package/dist/reapply-AMFKVYZV.js +0 -63
|
@@ -1,154 +1,41 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AgentConfigError,
|
|
3
|
+
AgentConfigWriteError,
|
|
4
|
+
configFailureKind,
|
|
5
|
+
retryAgentCommand,
|
|
6
|
+
writeSetupConfigFile
|
|
7
|
+
} from "./chunk-NYV45Q25.js";
|
|
1
8
|
import {
|
|
2
9
|
MCP_BRIDGE_BINARY
|
|
3
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-2PKHGHMA.js";
|
|
4
11
|
import {
|
|
5
12
|
KEY_FILE_MODE
|
|
6
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-BLAIETMP.js";
|
|
7
14
|
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
15
|
+
CLINE_SERVER_NAME_TAKEN,
|
|
16
|
+
CLINE_SETTINGS_REFUSALS,
|
|
17
|
+
clineEntryAuthorization,
|
|
18
|
+
clineEntryHoldsLiteralKey,
|
|
19
|
+
clineEntryRunsCommand,
|
|
20
|
+
clineEntrySignedIn,
|
|
21
|
+
clineEntrySwitchedOff,
|
|
22
|
+
clineEntryUsesKey,
|
|
23
|
+
clinePusharyEntryOf,
|
|
24
|
+
clineServerNameTakenElsewhere,
|
|
25
|
+
clineSettingsText,
|
|
26
|
+
isClinePusharyEntry,
|
|
27
|
+
otherPusharyServerNames,
|
|
28
|
+
readClineSettings,
|
|
29
|
+
renderAgentInstructions,
|
|
30
|
+
withClinePusharyServer,
|
|
31
|
+
withRefreshedClineKey,
|
|
32
|
+
withoutClinePusharyServer
|
|
33
|
+
} from "./chunk-H4BKC2GN.js";
|
|
12
34
|
import {
|
|
13
35
|
readJsonSafe,
|
|
14
36
|
writeFileAtomic,
|
|
15
37
|
writeJsonAtomic
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import {
|
|
18
|
-
NPX_LATEST_COMMAND
|
|
19
|
-
} from "./chunk-FG5HMJ7C.js";
|
|
20
|
-
import {
|
|
21
|
-
readSetupAgentFailures
|
|
22
|
-
} from "./chunk-FXECTHAG.js";
|
|
23
|
-
|
|
24
|
-
// src/instruction-file.ts
|
|
25
|
-
import { accessSync, constants, existsSync, readFileSync, statSync, writeFileSync, mkdirSync, rmSync } from "fs";
|
|
26
|
-
import { dirname } from "path";
|
|
27
|
-
var PUSHARY_BEGIN = "<!-- BEGIN PUSHARY (managed by @pushary/agent-hooks; do not edit this block) -->";
|
|
28
|
-
var PUSHARY_END = "<!-- END PUSHARY -->";
|
|
29
|
-
var instructionBody = (label) => `## Pushary notifications and approvals
|
|
30
|
-
|
|
31
|
-
You have Pushary MCP tools that reach the user on their phone. Use them proactively. Do not wait for the user to ask.
|
|
32
|
-
|
|
33
|
-
- When you need the user to make a decision or answer a clarifying question, call \`ask_user\` instead of guessing or stalling. Use type "confirm" for yes/no, "select" for a fixed set of options, and "input" for free text. Read \`answered\`, \`status\` and the returned handoff instead of assuming the tool blocked. Silence is not consent; choice/text answers do not authorize a separate action.
|
|
34
|
-
- Ask once, on one channel. If you also have a built-in way to prompt the user, use that or \`ask_user\` for a given question, never both. \`ask_user\` is the one that reaches the user when they are away from this machine, so prefer it. Raising both strands the user in whichever prompt you are not waiting on.
|
|
35
|
-
- Honor authorization already granted in this session. Ask before a risky or irreversible action outside that authorization, or when an enforced host policy requires it. Do not ask again for an already authorized step, and never bypass an enforced gate. When a Pushary hook result says the user approved a specific command after a denial, rerunning that exact command is the approved path and not a bypass of that gate.
|
|
36
|
-
- Call \`propose_scope\` only for an unresolved or requested file boundary. A ratified scope narrows what may proceed; it does not bypass other approval rules. Do not add a plan approval merely because work spans several files, and do not propose a new scope mid-run just to widen it. Let the installed gate request any scope expansion before the edit executes. Only file paths are checked, and only on tool calls that carry one, so put a boundary that is not a path (recipients, channels, spend, systems you will not open) in \`promises\` and never in \`allowedPaths\`. Read the \`enforces\` field that comes back: an empty array means nothing in that contract is checked automatically, and you must say so rather than report that a scope is in force. \`hookSeen: false\` means no hook has reported that sessionId, so the gate will never find the contract: fix the session id rather than proceeding as if a scope were in force.
|
|
37
|
-
- Before a task of more than two steps, break it into steps and find the forks. Settle by yourself every fork that a file, a command or a tool call can answer, then ask the rest as one numbered round with your recommended answer against each. A question in the terminal is free; a push is not. When the user is at the terminal, ask the whole round there. When the user is away, send only the fork that stops the run, and decide the rest on your recommendation.
|
|
38
|
-
- When you are blocked, stuck, or hit an error you cannot resolve on your own, call \`send_notification\` so the user knows, and call \`ask_user\` if you need a decision to continue.
|
|
39
|
-
- When meaningful work finishes while the user is away, or they requested an alert, call \`send_notification\` so the user knows it is done. Skip trivial completions and duplicate reports to someone already reading. Always pass \`context\` with a \`type\` of "task_complete", "error" or "info": it is what tells Pushary this is a task update, so the user's own setting for where updates land can route it.
|
|
40
|
-
- Confirm notifications can offer lock-screen actions; arbitrary choices and text open the app. The Mac notch handles personal account questions, not Partner customer enrollment.
|
|
41
|
-
- Use \`cancel_question\` to retract a pending question once it is no longer needed.
|
|
42
|
-
- When the user asks to be reminded later, call \`schedule_reminder\` with \`body\` and either \`inMinutes\` or \`at\` with an explicit UTC offset. Confirm the returned time, never guess their timezone, and do not use \`ask_user\` as a reminder. Pushary saves it and delivers after this agent exits. Call with no arguments to list pending reminders or \`cancelReminderId\` to cancel one before dispatch starts.
|
|
43
|
-
- Respect the user's Pushary delivery mode: it decides where an approval is surfaced (phone, terminal, or awareness only), not whether it is required. In Terminal mode do not expect a phone answer; the approval waits in the terminal. If the Pushary hook already gated an action, a single approval is enough, do not ask again.
|
|
44
|
-
|
|
45
|
-
Pass \`agentName\` as "${label} - <project folder name>" so the user knows which session is asking. If a question times out, follow \`handoffAction\` when present, otherwise \`nextAction\`: keep waiting with the same correlationId while pending. A poll ending is not question expiry. Cancel only for an explicit handoff or when the answer is no longer needed. If cancellation returns \`handoffAction: "stop"\`, stop. Otherwise, if cancellation returns false, poll once for 1 second and honor the answer that won the race.`;
|
|
46
|
-
var SHARED_AGENTS_MD_LABEL = "<your agent's name, such as Codex or Hermes>";
|
|
47
|
-
var CODEX_INSTRUCTIONS_LABEL = "Codex";
|
|
48
|
-
var GEMINI_INSTRUCTIONS_LABEL = "Gemini";
|
|
49
|
-
var OPENCODE_INSTRUCTIONS_LABEL = "OpenCode";
|
|
50
|
-
var renderAgentInstructions = (label) => instructionBody(label);
|
|
51
|
-
var KEYLESS_FALLBACK_LINE = "This repo uses Pushary phone approvals. Your teammates get agent questions on their lock screens; you do not have a key yet, so questions will fall back to the terminal. Get your own key (3-day trial): https://pushary.com/sign-up?utm_source=agents-md&utm_medium=teammate";
|
|
52
|
-
var renderProjectAgentInstructions = (label) => `${instructionBody(label)}
|
|
53
|
-
|
|
54
|
-
If this environment has no Pushary API key (no PUSHARY_API_KEY and no key in ~/.pushary/config.json), the tools above are unavailable in this session. In that case, treat the following as a statement of fact about this session and continue in the terminal: ${KEYLESS_FALLBACK_LINE}`;
|
|
55
|
-
var wrap = (body) => `${PUSHARY_BEGIN}
|
|
56
|
-
${body}
|
|
57
|
-
${PUSHARY_END}`;
|
|
58
|
-
var withInstructionBlockAppended = (existing, body) => {
|
|
59
|
-
const prefix = existing.trim() ? existing.replace(/\s*$/, "") + "\n\n" : "";
|
|
60
|
-
return prefix + wrap(body) + "\n";
|
|
61
|
-
};
|
|
62
|
-
var managedBlockRange = (text) => {
|
|
63
|
-
const start = text.indexOf(PUSHARY_BEGIN);
|
|
64
|
-
const end = text.indexOf(PUSHARY_END);
|
|
65
|
-
return start !== -1 && end > start ? { start, end: end + PUSHARY_END.length } : null;
|
|
66
|
-
};
|
|
67
|
-
var withInstructionBlockReplaced = (existing, body) => {
|
|
68
|
-
const range = managedBlockRange(existing);
|
|
69
|
-
return range ? existing.slice(0, range.start) + wrap(body) + existing.slice(range.end) : null;
|
|
70
|
-
};
|
|
71
|
-
var writeInstructionBlock = (filePath, body) => {
|
|
72
|
-
const dir = dirname(filePath);
|
|
73
|
-
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
74
|
-
let existing = "";
|
|
75
|
-
try {
|
|
76
|
-
existing = readFileSync(filePath, "utf-8");
|
|
77
|
-
} catch {
|
|
78
|
-
}
|
|
79
|
-
writeFileSync(filePath, withInstructionBlockReplaced(existing, body) ?? withInstructionBlockAppended(existing, body), "utf-8");
|
|
80
|
-
};
|
|
81
|
-
var occurrencesOf = (marker, text) => text.split(marker).length - 1;
|
|
82
|
-
var soleManagedBlock = (text) => {
|
|
83
|
-
const begins = occurrencesOf(PUSHARY_BEGIN, text);
|
|
84
|
-
const ends = occurrencesOf(PUSHARY_END, text);
|
|
85
|
-
if (begins === 0 && ends === 0) return { kind: "none" };
|
|
86
|
-
const range = managedBlockRange(text);
|
|
87
|
-
return begins === 1 && ends === 1 && range ? { kind: "one", range } : { kind: "ambiguous" };
|
|
88
|
-
};
|
|
89
|
-
var CRLF = "\r\n";
|
|
90
|
-
var withLineEndingsOf = (sample, block) => sample.includes(CRLF) ? block.replaceAll("\n", CRLF) : block;
|
|
91
|
-
var readUtf8 = (filePath) => {
|
|
92
|
-
try {
|
|
93
|
-
const bytes = readFileSync(filePath);
|
|
94
|
-
const text = bytes.toString("utf-8");
|
|
95
|
-
return Buffer.from(text, "utf-8").equals(bytes) ? { kind: "text", text } : { kind: "not_utf8" };
|
|
96
|
-
} catch {
|
|
97
|
-
return { kind: "unreadable" };
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
var isWritable = (filePath) => {
|
|
101
|
-
try {
|
|
102
|
-
accessSync(filePath, constants.W_OK);
|
|
103
|
-
return true;
|
|
104
|
-
} catch {
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
var refreshInstructionBlock = (filePath, body) => {
|
|
109
|
-
if (!existsSync(filePath)) return "absent";
|
|
110
|
-
const read = readUtf8(filePath);
|
|
111
|
-
if (read.kind !== "text") return read.kind;
|
|
112
|
-
const block = soleManagedBlock(read.text);
|
|
113
|
-
if (block.kind === "none") return "absent";
|
|
114
|
-
if (block.kind === "ambiguous") return "ambiguous_markers";
|
|
115
|
-
const existing = read.text.slice(block.range.start, block.range.end);
|
|
116
|
-
const fresh = withLineEndingsOf(existing, wrap(body));
|
|
117
|
-
if (existing === fresh) return "current";
|
|
118
|
-
if (!isWritable(filePath)) return "read_only";
|
|
119
|
-
try {
|
|
120
|
-
const refreshed = read.text.slice(0, block.range.start) + fresh + read.text.slice(block.range.end);
|
|
121
|
-
writeFileAtomic(filePath, refreshed, statSync(filePath).mode & 511);
|
|
122
|
-
return "refreshed";
|
|
123
|
-
} catch {
|
|
124
|
-
return "write_failed";
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
var removeInstructionBlock = (filePath) => {
|
|
128
|
-
let existing = "";
|
|
129
|
-
try {
|
|
130
|
-
existing = readFileSync(filePath, "utf-8");
|
|
131
|
-
} catch {
|
|
132
|
-
return false;
|
|
133
|
-
}
|
|
134
|
-
const start = existing.indexOf(PUSHARY_BEGIN);
|
|
135
|
-
const end = existing.indexOf(PUSHARY_END);
|
|
136
|
-
if (start === -1 || end === -1 || end < start) return false;
|
|
137
|
-
const remaining = (existing.slice(0, start) + existing.slice(end + PUSHARY_END.length)).trim();
|
|
138
|
-
if (remaining === "") {
|
|
139
|
-
rmSync(filePath, { force: true });
|
|
140
|
-
} else {
|
|
141
|
-
writeFileSync(filePath, remaining + "\n", "utf-8");
|
|
142
|
-
}
|
|
143
|
-
return true;
|
|
144
|
-
};
|
|
145
|
-
var hasInstructionBlock = (filePath) => {
|
|
146
|
-
try {
|
|
147
|
-
return readFileSync(filePath, "utf-8").includes(PUSHARY_BEGIN);
|
|
148
|
-
} catch {
|
|
149
|
-
return false;
|
|
150
|
-
}
|
|
151
|
-
};
|
|
38
|
+
} from "./chunk-BSZIPIFA.js";
|
|
152
39
|
|
|
153
40
|
// src/fx-config.ts
|
|
154
41
|
var FX_SERVER_NAME = "pushary";
|
|
@@ -491,13 +378,13 @@ var workspaceShowsQuestionTool = (workspace) => {
|
|
|
491
378
|
var workspacesShowingQuestionTool = (settings) => Object.entries(asRecord(settings[WORKSPACES_KEY]) ?? {}).filter(([, workspace]) => workspaceShowsQuestionTool(workspace)).map(([path]) => path);
|
|
492
379
|
|
|
493
380
|
// src/fx-files.ts
|
|
494
|
-
import { existsSync
|
|
381
|
+
import { existsSync, lstatSync, readFileSync, realpathSync } from "fs";
|
|
495
382
|
import { relative, isAbsolute } from "path";
|
|
496
383
|
var readFxFile = (path, read) => {
|
|
497
|
-
if (!
|
|
384
|
+
if (!existsSync(path)) return { kind: "missing" };
|
|
498
385
|
let text;
|
|
499
386
|
try {
|
|
500
|
-
text =
|
|
387
|
+
text = readFileSync(path, "utf-8");
|
|
501
388
|
} catch {
|
|
502
389
|
return { kind: "unreadable" };
|
|
503
390
|
}
|
|
@@ -517,91 +404,8 @@ var fxIgnoresInstructionsFile = (path, fxDir) => {
|
|
|
517
404
|
}
|
|
518
405
|
};
|
|
519
406
|
|
|
520
|
-
// src/setup/config-write.ts
|
|
521
|
-
var AgentConfigWriteError = class extends Error {
|
|
522
|
-
constructor(error) {
|
|
523
|
-
super(error instanceof Error ? error.message : String(error), { cause: error });
|
|
524
|
-
this.name = "AgentConfigWriteError";
|
|
525
|
-
}
|
|
526
|
-
};
|
|
527
|
-
var writeSetupConfigFile = (path, content, mode = 384) => {
|
|
528
|
-
try {
|
|
529
|
-
writeFileAtomic(path, content, mode);
|
|
530
|
-
} catch (error) {
|
|
531
|
-
throw new AgentConfigWriteError(error);
|
|
532
|
-
}
|
|
533
|
-
};
|
|
534
|
-
var writeSetupConfigJson = (path, value, mode) => writeSetupConfigFile(path, `${JSON.stringify(value, null, 2)}
|
|
535
|
-
`, mode);
|
|
536
|
-
|
|
537
|
-
// src/setup/agent-failure.ts
|
|
538
|
-
var AgentConfigError = class extends Error {
|
|
539
|
-
kind;
|
|
540
|
-
filePath;
|
|
541
|
-
constructor(kind, filePath, message) {
|
|
542
|
-
super(message);
|
|
543
|
-
this.name = "AgentConfigError";
|
|
544
|
-
this.kind = kind;
|
|
545
|
-
this.filePath = filePath;
|
|
546
|
-
}
|
|
547
|
-
};
|
|
548
|
-
var configFailureKind = (readFailure) => readFailure === "unparseable" ? "config-unparseable" : "config-unreadable";
|
|
549
|
-
var AGENT_FAILURE_DETAILS = {
|
|
550
|
-
"not-wired": "reported success but its config is not there.",
|
|
551
|
-
"app-account-mismatch": "Pushary for Mac set it up with an account that does not match this setup, so it was left as it is."
|
|
552
|
-
};
|
|
553
|
-
var DESCRIBED_FAILURE_REMEDIES = {
|
|
554
|
-
"not-wired": "retry-agent",
|
|
555
|
-
"app-account-mismatch": "match-mac-account"
|
|
556
|
-
};
|
|
557
|
-
var describedAgentFailure = (agent, kind) => ({
|
|
558
|
-
agent,
|
|
559
|
-
kind,
|
|
560
|
-
detail: AGENT_FAILURE_DETAILS[kind],
|
|
561
|
-
remedy: DESCRIBED_FAILURE_REMEDIES[kind],
|
|
562
|
-
stage: kind === "not-wired" ? "hook-validation" : "account-check"
|
|
563
|
-
});
|
|
564
|
-
var NPM_PERMISSION_REMEDIES = {
|
|
565
|
-
"global-prefix": "fix-npm-prefix",
|
|
566
|
-
"file-in-use": "close-node-programs"
|
|
567
|
-
};
|
|
568
|
-
var remedyForError = (error) => {
|
|
569
|
-
if (error instanceof NpmMissingError) return "install-node";
|
|
570
|
-
if (error instanceof NpmPermissionError) return NPM_PERMISSION_REMEDIES[error.kind];
|
|
571
|
-
return "retry-agent";
|
|
572
|
-
};
|
|
573
|
-
var setupFailureDiagnostic = (error) => {
|
|
574
|
-
if (error instanceof AgentConfigError) return { stage: "config-read" };
|
|
575
|
-
if (error instanceof AgentConfigWriteError) return { stage: "config-write", diagnosticCode: "config-write-failed" };
|
|
576
|
-
if (error instanceof NpmMissingError) return { stage: "runtime-install", diagnosticCode: "npm-missing" };
|
|
577
|
-
if (error instanceof NpmPermissionError) {
|
|
578
|
-
return { stage: "runtime-install", diagnosticCode: error.kind === "global-prefix" ? "npm-global-prefix-denied" : "npm-file-in-use" };
|
|
579
|
-
}
|
|
580
|
-
if (error instanceof NpmInstallError) return { stage: "runtime-install", diagnosticCode: "npm-install-failed" };
|
|
581
|
-
return { stage: "unknown" };
|
|
582
|
-
};
|
|
583
|
-
var agentFailureFromError = (agent, error, describeError) => ({
|
|
584
|
-
agent,
|
|
585
|
-
kind: error instanceof AgentConfigError ? error.kind : "installer-error",
|
|
586
|
-
detail: describeError(error),
|
|
587
|
-
remedy: remedyForError(error),
|
|
588
|
-
...setupFailureDiagnostic(error)
|
|
589
|
-
});
|
|
590
|
-
var retryAgentCommand = (agent) => `${NPX_LATEST_COMMAND} setup --agents ${agent}`;
|
|
591
|
-
var takeOverHooksCommand = (agent) => `${retryAgentCommand(agent)} --take-over-hooks`;
|
|
592
|
-
var matchMacAccountStep = (agent, setupAccount) => `Sign Pushary for Mac into ${setupAccount ?? "this setup's account"}, or run ${takeOverHooksCommand(agent)}`;
|
|
593
|
-
var UNCHECKED_ACCOUNT = "an account that could not be checked";
|
|
594
|
-
var describeMacAccountMismatch = (mismatch) => [
|
|
595
|
-
`${mismatch.agentName}: Pushary for Mac uses ${mismatch.macAccount ?? UNCHECKED_ACCOUNT}. This setup uses ${mismatch.setupAccount ?? UNCHECKED_ACCOUNT}.`,
|
|
596
|
-
matchMacAccountStep(mismatch.agent, mismatch.setupAccount)
|
|
597
|
-
];
|
|
598
|
-
var REMAINING_AGENTS_CONTINUE = "Other agents will continue. Re-run setup to retry.";
|
|
599
|
-
var afterAgentFailureNote = (agentsStillToSetUp) => agentsStillToSetUp > 0 ? REMAINING_AGENTS_CONTINUE : null;
|
|
600
|
-
var failedAgentsContext = (configuredAgentNames) => configuredAgentNames.length > 0 ? `(configured: ${configuredAgentNames.join(", ")})` : null;
|
|
601
|
-
var agentFailureWire = (failures) => readSetupAgentFailures(failures);
|
|
602
|
-
|
|
603
407
|
// src/fx-lifecycle.ts
|
|
604
|
-
import { existsSync as
|
|
408
|
+
import { existsSync as existsSync2 } from "fs";
|
|
605
409
|
import { join } from "path";
|
|
606
410
|
var fxRetryHint = () => `Fix it, then run ${retryAgentCommand("fx")}.`;
|
|
607
411
|
var readFxProfileForSetup = (filePath) => {
|
|
@@ -638,7 +442,7 @@ var fxSettingsReadRefusal = (filePath, read) => {
|
|
|
638
442
|
};
|
|
639
443
|
var recordFxQuestionRule = (receiptPath) => {
|
|
640
444
|
try {
|
|
641
|
-
if (!
|
|
445
|
+
if (!existsSync2(receiptPath)) writeJsonAtomic(receiptPath, FX_QUESTION_RULE_RECEIPT, 384);
|
|
642
446
|
return true;
|
|
643
447
|
} catch {
|
|
644
448
|
return false;
|
|
@@ -719,21 +523,182 @@ var planFxRemoval = (profilePath, settingsPath, receiptPath) => {
|
|
|
719
523
|
actions.push({ kind: "kept", label: "fx question rule", detail: FX_QUESTION_RULE_KEPT[question.outcome] });
|
|
720
524
|
}
|
|
721
525
|
}
|
|
722
|
-
if (
|
|
526
|
+
if (existsSync2(receiptPath)) actions.push({ kind: "remove-receipt", path: receiptPath });
|
|
723
527
|
return actions;
|
|
724
528
|
};
|
|
725
529
|
|
|
530
|
+
// src/cline-lifecycle.ts
|
|
531
|
+
import { randomUUID } from "crypto";
|
|
532
|
+
import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync2, renameSync, rmdirSync, rmSync, statSync, writeFileSync } from "fs";
|
|
533
|
+
import { dirname, join as join2 } from "path";
|
|
534
|
+
var CLINE_SETTINGS_LOCK_STALE_MS = 1e4;
|
|
535
|
+
var CLINE_SETTINGS_LOCK_WAIT_MS = 1e4;
|
|
536
|
+
var CLINE_SETTINGS_LOCK_POLL_MS = 25;
|
|
537
|
+
var CLINE_SETTINGS_BUSY = "stayed locked by Cline";
|
|
538
|
+
var ClineSettingsBusyError = class extends AgentConfigWriteError {
|
|
539
|
+
constructor(settingsPath) {
|
|
540
|
+
super(`${settingsPath} ${CLINE_SETTINGS_BUSY}, so it was left untouched. Close Cline, then run ${retryAgentCommand("cline")}.`);
|
|
541
|
+
this.name = "ClineSettingsBusyError";
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
var readClineSettingsFile = (settingsPath) => {
|
|
545
|
+
if (!existsSync3(settingsPath)) return { kind: "missing" };
|
|
546
|
+
try {
|
|
547
|
+
return readClineSettings(readFileSync2(settingsPath, "utf-8"));
|
|
548
|
+
} catch {
|
|
549
|
+
return { kind: "unreadable" };
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
var pause = (milliseconds) => {
|
|
553
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);
|
|
554
|
+
};
|
|
555
|
+
var lockDirectoryOf = (settingsPath) => `${settingsPath}.lock`;
|
|
556
|
+
var ownerFileOf = (directory, token) => join2(directory, `owner.${token}`);
|
|
557
|
+
var tryTakeLock = (lockDirectory, token) => {
|
|
558
|
+
const staging = `${lockDirectory}.tmp.${token}`;
|
|
559
|
+
mkdirSync(staging, { recursive: true });
|
|
560
|
+
writeFileSync(ownerFileOf(staging, token), token, { encoding: "utf-8", flag: "wx" });
|
|
561
|
+
try {
|
|
562
|
+
renameSync(staging, lockDirectory);
|
|
563
|
+
return true;
|
|
564
|
+
} catch (error) {
|
|
565
|
+
rmSync(staging, { recursive: true, force: true });
|
|
566
|
+
if (existsSync3(lockDirectory)) return false;
|
|
567
|
+
throw error;
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
var lockIsStale = (lockDirectory, now) => {
|
|
571
|
+
try {
|
|
572
|
+
return now - statSync(lockDirectory).mtimeMs > CLINE_SETTINGS_LOCK_STALE_MS;
|
|
573
|
+
} catch {
|
|
574
|
+
return false;
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
var reclaimStaleLock = (lockDirectory, token) => {
|
|
578
|
+
const setAside = `${lockDirectory}.stale.${token}`;
|
|
579
|
+
try {
|
|
580
|
+
renameSync(lockDirectory, setAside);
|
|
581
|
+
} catch {
|
|
582
|
+
return false;
|
|
583
|
+
}
|
|
584
|
+
rmSync(setAside, { recursive: true, force: true });
|
|
585
|
+
return true;
|
|
586
|
+
};
|
|
587
|
+
var releaseLock = (lockDirectory, token) => {
|
|
588
|
+
try {
|
|
589
|
+
rmSync(ownerFileOf(lockDirectory, token), { force: true });
|
|
590
|
+
rmdirSync(lockDirectory);
|
|
591
|
+
} catch {
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
};
|
|
595
|
+
var withClineSettingsLock = (settingsPath, run) => {
|
|
596
|
+
const lockDirectory = lockDirectoryOf(settingsPath);
|
|
597
|
+
const token = `${process.pid}.${Date.now()}.${randomUUID()}`;
|
|
598
|
+
mkdirSync(dirname(lockDirectory), { recursive: true });
|
|
599
|
+
const deadline = Date.now() + CLINE_SETTINGS_LOCK_WAIT_MS;
|
|
600
|
+
while (!tryTakeLock(lockDirectory, token)) {
|
|
601
|
+
if (lockIsStale(lockDirectory, Date.now()) && reclaimStaleLock(lockDirectory, token)) continue;
|
|
602
|
+
if (Date.now() >= deadline) throw new ClineSettingsBusyError(settingsPath);
|
|
603
|
+
pause(CLINE_SETTINGS_LOCK_POLL_MS);
|
|
604
|
+
}
|
|
605
|
+
try {
|
|
606
|
+
return run();
|
|
607
|
+
} finally {
|
|
608
|
+
releaseLock(lockDirectory, token);
|
|
609
|
+
}
|
|
610
|
+
};
|
|
611
|
+
var writeClineSettingsText = (settingsPath, text) => {
|
|
612
|
+
writeSetupConfigFile(settingsPath, text, KEY_FILE_MODE);
|
|
613
|
+
};
|
|
614
|
+
var writeClineSettings = (settingsPath, settings) => {
|
|
615
|
+
writeClineSettingsText(settingsPath, clineSettingsText(settings));
|
|
616
|
+
};
|
|
617
|
+
var retryHint = () => `Fix it, then run ${retryAgentCommand("cline")}.`;
|
|
618
|
+
var settingsForSetup = (settingsPath, read) => {
|
|
619
|
+
if (read.kind === "settings") return read.settings;
|
|
620
|
+
if (read.kind === "missing") return {};
|
|
621
|
+
if (read.kind === "unreadable") {
|
|
622
|
+
throw new AgentConfigError(configFailureKind("unreadable"), settingsPath, `${settingsPath} could not be read, so it was left untouched. ${retryHint()}`);
|
|
623
|
+
}
|
|
624
|
+
throw new AgentConfigError(
|
|
625
|
+
configFailureKind("unparseable"),
|
|
626
|
+
settingsPath,
|
|
627
|
+
`${settingsPath} ${CLINE_SETTINGS_REFUSALS[read.reason]}, so it was left untouched. ${retryHint()}`
|
|
628
|
+
);
|
|
629
|
+
};
|
|
630
|
+
var ClineServerNameTakenError = class extends AgentConfigError {
|
|
631
|
+
constructor(settingsPath) {
|
|
632
|
+
super(
|
|
633
|
+
"config-conflict",
|
|
634
|
+
settingsPath,
|
|
635
|
+
`${settingsPath} ${CLINE_SERVER_NAME_TAKEN}, so it was left untouched. Rename that server in Cline, then run ${retryAgentCommand("cline")}.`
|
|
636
|
+
);
|
|
637
|
+
this.name = "ClineServerNameTakenError";
|
|
638
|
+
}
|
|
639
|
+
};
|
|
640
|
+
var unclaimedSettings = (settingsPath, settings) => {
|
|
641
|
+
if (clineServerNameTakenElsewhere(settings)) throw new ClineServerNameTakenError(settingsPath);
|
|
642
|
+
return settings;
|
|
643
|
+
};
|
|
644
|
+
var configureClineServer = (settingsPath, apiKey) => withClineSettingsLock(settingsPath, () => {
|
|
645
|
+
const current = unclaimedSettings(settingsPath, settingsForSetup(settingsPath, readClineSettingsFile(settingsPath)));
|
|
646
|
+
const settings = withClinePusharyServer(current, apiKey);
|
|
647
|
+
writeClineSettings(settingsPath, settings);
|
|
648
|
+
return { otherServers: otherPusharyServerNames(settings) };
|
|
649
|
+
});
|
|
650
|
+
var carriesPusharyKey = (entry) => clineEntryAuthorization(entry) !== void 0;
|
|
651
|
+
var refreshClineKey = (settingsPath, apiKey) => !existsSync3(settingsPath) ? "not-configured" : withClineSettingsLock(settingsPath, () => {
|
|
652
|
+
const read = readClineSettingsFile(settingsPath);
|
|
653
|
+
if (read.kind !== "settings") return "not-configured";
|
|
654
|
+
const entry = clinePusharyEntryOf(read.settings);
|
|
655
|
+
if (!isClinePusharyEntry(entry)) return "not-configured";
|
|
656
|
+
if (!apiKey || clineEntryRunsCommand(entry) || !clineEntryHoldsLiteralKey(entry) || clineEntryUsesKey(entry, apiKey)) return "unchanged";
|
|
657
|
+
writeClineSettings(settingsPath, withRefreshedClineKey(read.settings, apiKey));
|
|
658
|
+
return "refreshed";
|
|
659
|
+
});
|
|
660
|
+
var inspectClineInstallation = (settingsPath, apiKey) => {
|
|
661
|
+
const read = readClineSettingsFile(settingsPath);
|
|
662
|
+
const settings = read.kind === "settings" ? read.settings : {};
|
|
663
|
+
const entry = clinePusharyEntryOf(settings);
|
|
664
|
+
return {
|
|
665
|
+
read,
|
|
666
|
+
configured: isClinePusharyEntry(entry),
|
|
667
|
+
hasKey: carriesPusharyKey(entry),
|
|
668
|
+
holdsPusharyKey: clineEntryHoldsLiteralKey(entry),
|
|
669
|
+
runsCommand: clineEntryRunsCommand(entry),
|
|
670
|
+
signedIn: clineEntrySignedIn(entry),
|
|
671
|
+
switchedOff: clineEntrySwitchedOff(entry),
|
|
672
|
+
usesCurrentKey: apiKey !== void 0 && clineEntryUsesKey(entry, apiKey),
|
|
673
|
+
nameTakenElsewhere: clineServerNameTakenElsewhere(settings),
|
|
674
|
+
otherServers: otherPusharyServerNames(settings)
|
|
675
|
+
};
|
|
676
|
+
};
|
|
677
|
+
var planClineRemoval = (settingsPath) => {
|
|
678
|
+
const read = readClineSettingsFile(settingsPath);
|
|
679
|
+
if (read.kind === "missing") return { kind: "absent" };
|
|
680
|
+
if (read.kind === "unreadable") return { kind: "kept", detail: `${settingsPath} could not be read; left untouched` };
|
|
681
|
+
if (read.kind === "refused" && !read.mentionsPushary) return { kind: "absent" };
|
|
682
|
+
if (read.kind === "refused") return { kind: "kept", detail: `${settingsPath} ${CLINE_SETTINGS_REFUSALS[read.reason]}; left untouched` };
|
|
683
|
+
const result = withoutClinePusharyServer(read.settings);
|
|
684
|
+
return result.removed ? { kind: "write", path: settingsPath, text: clineSettingsText(result.settings) } : { kind: "absent" };
|
|
685
|
+
};
|
|
686
|
+
var failedRemovalDetail = (settingsPath, error) => error instanceof ClineSettingsBusyError ? `${settingsPath} ${CLINE_SETTINGS_BUSY}; close Cline and try again` : `${settingsPath} could not be updated: ${error instanceof Error ? error.message : String(error)}`;
|
|
687
|
+
var removeFromLockedSettings = (settingsPath) => withClineSettingsLock(settingsPath, () => {
|
|
688
|
+
const plan = planClineRemoval(settingsPath);
|
|
689
|
+
if (plan.kind === "write") writeClineSettingsText(plan.path, plan.text);
|
|
690
|
+
return plan;
|
|
691
|
+
});
|
|
692
|
+
var removeClineServer = (settingsPath) => {
|
|
693
|
+
if (!existsSync3(settingsPath)) return { kind: "absent" };
|
|
694
|
+
try {
|
|
695
|
+
return removeFromLockedSettings(settingsPath);
|
|
696
|
+
} catch (error) {
|
|
697
|
+
return { kind: "failed", detail: failedRemovalDetail(settingsPath, error) };
|
|
698
|
+
}
|
|
699
|
+
};
|
|
700
|
+
|
|
726
701
|
export {
|
|
727
|
-
SHARED_AGENTS_MD_LABEL,
|
|
728
|
-
CODEX_INSTRUCTIONS_LABEL,
|
|
729
|
-
GEMINI_INSTRUCTIONS_LABEL,
|
|
730
|
-
OPENCODE_INSTRUCTIONS_LABEL,
|
|
731
|
-
renderAgentInstructions,
|
|
732
|
-
renderProjectAgentInstructions,
|
|
733
|
-
writeInstructionBlock,
|
|
734
|
-
refreshInstructionBlock,
|
|
735
|
-
removeInstructionBlock,
|
|
736
|
-
hasInstructionBlock,
|
|
737
702
|
FX_PUSHARY_TOOLS_RULE,
|
|
738
703
|
fxInstructionsBody,
|
|
739
704
|
FX_PROFILE_REFUSALS,
|
|
@@ -741,23 +706,16 @@ export {
|
|
|
741
706
|
withFxPusharyServer,
|
|
742
707
|
FX_QUESTION_TOOL,
|
|
743
708
|
fxIgnoresInstructionsFile,
|
|
744
|
-
writeSetupConfigFile,
|
|
745
|
-
writeSetupConfigJson,
|
|
746
|
-
AgentConfigError,
|
|
747
|
-
configFailureKind,
|
|
748
|
-
describedAgentFailure,
|
|
749
|
-
agentFailureFromError,
|
|
750
|
-
retryAgentCommand,
|
|
751
|
-
matchMacAccountStep,
|
|
752
|
-
describeMacAccountMismatch,
|
|
753
|
-
afterAgentFailureNote,
|
|
754
|
-
failedAgentsContext,
|
|
755
|
-
agentFailureWire,
|
|
756
709
|
readFxProfileForSetup,
|
|
757
710
|
writeFxProfile,
|
|
758
711
|
macAppFxBridge,
|
|
759
712
|
fxServerHolder,
|
|
760
713
|
configureFxSettings,
|
|
761
714
|
inspectFxInstallation,
|
|
762
|
-
planFxRemoval
|
|
715
|
+
planFxRemoval,
|
|
716
|
+
configureClineServer,
|
|
717
|
+
refreshClineKey,
|
|
718
|
+
inspectClineInstallation,
|
|
719
|
+
planClineRemoval,
|
|
720
|
+
removeClineServer
|
|
763
721
|
};
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildTranscriptRecords,
|
|
3
3
|
decodePublicKey,
|
|
4
|
+
encryptRecord,
|
|
4
5
|
generateSessionKey,
|
|
6
|
+
recordSealerFor,
|
|
5
7
|
wrapSessionKey
|
|
6
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-QSW3HAKI.js";
|
|
7
9
|
import {
|
|
8
10
|
fetchTranscriptRecipients,
|
|
9
11
|
uploadTranscriptRecords
|
|
10
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-TJUJAK5L.js";
|
|
11
13
|
|
|
12
14
|
// src/live-session.ts
|
|
13
15
|
var MAX_TRANSCRIPT_QUEUE = 100;
|
|
@@ -68,6 +70,7 @@ var LiveTranscriptRelay = class {
|
|
|
68
70
|
wrappedKey = null;
|
|
69
71
|
providerWrappedKey = null;
|
|
70
72
|
providerKeyId = null;
|
|
73
|
+
sealRecord = encryptRecord;
|
|
71
74
|
keyUploaded = false;
|
|
72
75
|
keyRejected = false;
|
|
73
76
|
flushing = null;
|
|
@@ -98,13 +101,14 @@ var LiveTranscriptRelay = class {
|
|
|
98
101
|
if (!recipients) return false;
|
|
99
102
|
this.sessionKey = generateSessionKey();
|
|
100
103
|
this.wrappedKey = wrapSessionKey(this.sessionKey, decodePublicKey(recipients.phonePublicKey));
|
|
104
|
+
this.sealRecord = recordSealerFor(recipients.phoneReadsCompressedRecords);
|
|
101
105
|
if (recipients.provider) {
|
|
102
106
|
this.providerWrappedKey = wrapSessionKey(this.sessionKey, decodePublicKey(recipients.provider.publicKey));
|
|
103
107
|
this.providerKeyId = recipients.provider.keyId;
|
|
104
108
|
}
|
|
105
109
|
}
|
|
106
110
|
const count = Math.min(this.queue.length, 50);
|
|
107
|
-
const records = buildTranscriptRecords(this.queue.slice(0, count), this.sessionKey).records;
|
|
111
|
+
const records = buildTranscriptRecords(this.queue.slice(0, count), this.sessionKey, /* @__PURE__ */ new Set(), this.sealRecord).records;
|
|
108
112
|
if (records.length === 0) {
|
|
109
113
|
this.queue.splice(0, count);
|
|
110
114
|
return true;
|