@pushary/agent-hooks 0.83.2 → 0.84.1
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 +94 -0
- package/dist/bin/pushary-bell-hook.js +5 -5
- package/dist/bin/pushary-bell.js +15 -14
- package/dist/bin/pushary-claude.js +93 -143
- package/dist/bin/pushary-clean.js +13 -12
- package/dist/bin/pushary-codex-bridge.d.ts +1 -0
- package/dist/bin/pushary-codex-bridge.js +349 -0
- package/dist/bin/pushary-codex-hook.js +18 -14
- package/dist/bin/pushary-codex.js +7 -7
- package/dist/bin/pushary-connect.js +13 -12
- package/dist/bin/pushary-daemon.js +331 -41
- package/dist/bin/pushary-doctor.js +48 -25
- package/dist/bin/pushary-gemini-bridge.d.ts +1 -0
- package/dist/bin/pushary-gemini-bridge.js +299 -0
- package/dist/bin/pushary-gemini-hook.js +28 -21
- package/dist/bin/pushary-hook.js +14 -13
- package/dist/bin/pushary-login.js +15 -14
- package/dist/bin/pushary-logout.js +12 -11
- package/dist/bin/pushary-mode.js +10 -9
- package/dist/bin/pushary-notification-hook.js +5 -5
- package/dist/bin/pushary-permission-denied-hook.js +9 -9
- package/dist/bin/pushary-permission-hook.js +9 -9
- package/dist/bin/pushary-post-hook.js +5 -5
- package/dist/bin/pushary-prompt-hook.js +5 -5
- package/dist/bin/pushary-session-end-hook.js +5 -5
- package/dist/bin/pushary-session-start-hook.js +5 -5
- package/dist/bin/pushary-setup.js +42 -36
- package/dist/bin/pushary-stats.js +6 -5
- package/dist/bin/pushary-status.js +17 -16
- package/dist/bin/pushary-stop-hook.js +5 -5
- package/dist/bin/pushary-stopfailure-hook.js +5 -5
- package/dist/bin/pushary-suggestions.js +7 -6
- package/dist/bin/pushary-upgrade.js +18 -17
- package/dist/bin/pushary-wait.js +10 -9
- package/dist/bin/pushary.js +8 -6
- package/dist/{chunk-SAA3VBDK.js → chunk-437T77TY.js} +3 -3
- package/dist/{chunk-U27BZWFT.js → chunk-6LC4WSCL.js} +1 -1
- package/dist/{chunk-7WWZPII5.js → chunk-7PZPJSWI.js} +1 -1
- package/dist/{chunk-4QQOKEOS.js → chunk-BLDDXHHA.js} +6 -6
- package/dist/{chunk-7PO2VEA4.js → chunk-CCCJ6BPW.js} +40 -34
- package/dist/chunk-CCH775Y6.js +343 -0
- package/dist/chunk-DINDL2CF.js +45 -0
- package/dist/{chunk-TXF4QZSQ.js → chunk-DOXSWT4Q.js} +1 -1
- package/dist/chunk-ERYKGH4J.js +140 -0
- package/dist/{chunk-QR6MVVQ7.js → chunk-F52SIIDG.js} +4 -4
- package/dist/{chunk-26D2YMDU.js → chunk-FBGBJXVC.js} +1 -1
- package/dist/chunk-GCKAWHFP.js +124 -0
- package/dist/{chunk-QF7WTF2C.js → chunk-HZNOAJGB.js} +2 -2
- package/dist/chunk-ILB6UOAF.js +192 -0
- package/dist/{chunk-RRZZ7TFJ.js → chunk-J4KFVOCQ.js} +4 -2
- package/dist/{chunk-WDRRULBH.js → chunk-K7CSRGKZ.js} +4 -4
- package/dist/{chunk-ZUKH2NPJ.js → chunk-MGJBC6DD.js} +1 -44
- package/dist/{chunk-GQLB2GBJ.js → chunk-MHBC2XUP.js} +1 -1
- package/dist/{chunk-YWRJGYUH.js → chunk-MQMPG5X4.js} +28 -2
- package/dist/{chunk-3AGM3TDM.js → chunk-NJ7JT26G.js} +1 -1
- package/dist/chunk-NRGRUOAR.js +25 -0
- package/dist/{chunk-EHLTWCDZ.js → chunk-SEAHGHCE.js} +1 -1
- package/dist/{chunk-NDC3TBHI.js → chunk-UKSQWTBH.js} +1 -1
- package/dist/{chunk-UVAC2KHH.js → chunk-UXWEE3QI.js} +1 -1
- package/dist/{chunk-MUEW424A.js → chunk-VT4IVERX.js} +50 -3
- package/dist/{chunk-DHAZ6SOT.js → chunk-YR5TSPXB.js} +81 -25
- package/dist/src/index.d.ts +6 -3
- package/dist/src/index.js +9 -9
- package/package.json +3 -1
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import "../chunk-NRGRUOAR.js";
|
|
3
|
+
import {
|
|
4
|
+
LiveTranscriptRelay,
|
|
5
|
+
liveSessionSleep,
|
|
6
|
+
postLiveSession,
|
|
7
|
+
postLiveSessionUntilAccepted,
|
|
8
|
+
startLiveSessionHeartbeat
|
|
9
|
+
} from "../chunk-ERYKGH4J.js";
|
|
10
|
+
import "../chunk-GCKAWHFP.js";
|
|
11
|
+
import {
|
|
12
|
+
startProcessOwnership,
|
|
13
|
+
withSpawnProcessOwnership
|
|
14
|
+
} from "../chunk-ILB6UOAF.js";
|
|
15
|
+
import {
|
|
16
|
+
spawnClaude
|
|
17
|
+
} from "../chunk-XHKBHWLX.js";
|
|
18
|
+
import {
|
|
19
|
+
resolveBinary
|
|
20
|
+
} from "../chunk-VT4IVERX.js";
|
|
21
|
+
import "../chunk-SEAHGHCE.js";
|
|
22
|
+
import {
|
|
23
|
+
getMachineId
|
|
24
|
+
} from "../chunk-RN3NOEJF.js";
|
|
25
|
+
import "../chunk-6MTNS63X.js";
|
|
26
|
+
import {
|
|
27
|
+
getApiKey,
|
|
28
|
+
getBaseUrl
|
|
29
|
+
} from "../chunk-2UMNXADU.js";
|
|
30
|
+
import "../chunk-MQMPG5X4.js";
|
|
31
|
+
|
|
32
|
+
// bin/pushary-codex-bridge.ts
|
|
33
|
+
import { existsSync } from "fs";
|
|
34
|
+
|
|
35
|
+
// src/codex-bridge.ts
|
|
36
|
+
import { spawn } from "child_process";
|
|
37
|
+
import { basename } from "path";
|
|
38
|
+
var MAX_RPC_LINE = 1024 * 1024;
|
|
39
|
+
var MAX_PENDING_RPC = 8;
|
|
40
|
+
var MAX_TRANSCRIPT_TEXT = 32 * 1024;
|
|
41
|
+
var MAX_MESSAGE_BUFFERS = 16;
|
|
42
|
+
var JsonRpcClient = class {
|
|
43
|
+
child;
|
|
44
|
+
pending = /* @__PURE__ */ new Map();
|
|
45
|
+
notifications = /* @__PURE__ */ new Set();
|
|
46
|
+
nextId = 1;
|
|
47
|
+
buffer = "";
|
|
48
|
+
closed = false;
|
|
49
|
+
constructor(command, cwd, timeoutMs) {
|
|
50
|
+
const options = { cwd, env: process.env, stdio: ["pipe", "pipe", "pipe"] };
|
|
51
|
+
this.child = process.platform === "win32" ? spawnClaude(command.command, command.args ?? [], options) : spawn(command.command, command.args ?? [], options);
|
|
52
|
+
this.child.stdout?.setEncoding("utf8");
|
|
53
|
+
this.child.stdout?.on("data", (chunk) => this.read(String(chunk)));
|
|
54
|
+
this.child.stderr?.resume();
|
|
55
|
+
this.child.once("error", (error) => this.fail(error));
|
|
56
|
+
this.child.once("exit", () => this.fail(new Error("Codex app-server exited")));
|
|
57
|
+
this.timeoutMs = timeoutMs;
|
|
58
|
+
}
|
|
59
|
+
timeoutMs;
|
|
60
|
+
get isClosed() {
|
|
61
|
+
return this.closed;
|
|
62
|
+
}
|
|
63
|
+
onNotification(listener) {
|
|
64
|
+
this.notifications.add(listener);
|
|
65
|
+
return () => this.notifications.delete(listener);
|
|
66
|
+
}
|
|
67
|
+
notify(method) {
|
|
68
|
+
this.write({ method });
|
|
69
|
+
}
|
|
70
|
+
request(method, params) {
|
|
71
|
+
if (this.closed) return Promise.reject(new Error("Codex app-server is closed"));
|
|
72
|
+
if (this.pending.size >= MAX_PENDING_RPC) return Promise.reject(new Error("Codex app-server request limit reached"));
|
|
73
|
+
const id = this.nextId++;
|
|
74
|
+
return new Promise((resolve, reject) => {
|
|
75
|
+
const timer = setTimeout(() => {
|
|
76
|
+
this.pending.delete(id);
|
|
77
|
+
reject(new Error(`${method} timed out`));
|
|
78
|
+
}, this.timeoutMs);
|
|
79
|
+
this.pending.set(id, { resolve, reject, timer });
|
|
80
|
+
this.write({ id, method, params });
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
async close() {
|
|
84
|
+
if (this.closed) return;
|
|
85
|
+
this.closed = true;
|
|
86
|
+
this.child.stdin?.end();
|
|
87
|
+
if (this.child.exitCode != null) return;
|
|
88
|
+
await Promise.race([
|
|
89
|
+
new Promise((resolve) => this.child.once("exit", () => resolve())),
|
|
90
|
+
new Promise((resolve) => setTimeout(resolve, 1e3))
|
|
91
|
+
]);
|
|
92
|
+
if (this.child.exitCode == null) this.child.kill();
|
|
93
|
+
this.rejectPending(new Error("Codex app-server closed"));
|
|
94
|
+
}
|
|
95
|
+
write(value) {
|
|
96
|
+
this.child.stdin?.write(`${JSON.stringify(value)}
|
|
97
|
+
`);
|
|
98
|
+
}
|
|
99
|
+
read(chunk) {
|
|
100
|
+
this.buffer += chunk;
|
|
101
|
+
if (this.buffer.length > MAX_RPC_LINE && !this.buffer.includes("\n")) {
|
|
102
|
+
this.fail(new Error("Codex app-server sent an oversized message"));
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
let newline = this.buffer.indexOf("\n");
|
|
106
|
+
while (newline >= 0) {
|
|
107
|
+
const line = this.buffer.slice(0, newline);
|
|
108
|
+
this.buffer = this.buffer.slice(newline + 1);
|
|
109
|
+
if (line.length > MAX_RPC_LINE) {
|
|
110
|
+
this.fail(new Error("Codex app-server sent an oversized message"));
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
this.handle(line);
|
|
114
|
+
newline = this.buffer.indexOf("\n");
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
handle(line) {
|
|
118
|
+
let message;
|
|
119
|
+
try {
|
|
120
|
+
message = JSON.parse(line);
|
|
121
|
+
} catch {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (typeof message.id === "number" && message.method) {
|
|
125
|
+
const result = message.method === "item/commandExecution/requestApproval" || message.method === "item/fileChange/requestApproval" ? { decision: "decline" } : message.method === "applyPatchApproval" || message.method === "execCommandApproval" ? { decision: { denied: { rejection: "No interactive Codex client is attached" } } } : message.method === "item/tool/requestUserInput" ? { answers: {} } : null;
|
|
126
|
+
this.write(result ? { id: message.id, result } : { id: message.id, error: { code: -32601, message: "Unsupported server request" } });
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (typeof message.id === "number") {
|
|
130
|
+
const pending = this.pending.get(message.id);
|
|
131
|
+
if (!pending) return;
|
|
132
|
+
this.pending.delete(message.id);
|
|
133
|
+
clearTimeout(pending.timer);
|
|
134
|
+
if (message.error) pending.reject(new Error(message.error.message ?? "Codex app-server request failed"));
|
|
135
|
+
else pending.resolve(message.result);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (message.method) {
|
|
139
|
+
for (const listener of this.notifications) listener(message);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
fail(error) {
|
|
143
|
+
if (this.closed) return;
|
|
144
|
+
this.closed = true;
|
|
145
|
+
this.rejectPending(error);
|
|
146
|
+
if (this.child.exitCode == null) this.child.kill();
|
|
147
|
+
}
|
|
148
|
+
rejectPending(error) {
|
|
149
|
+
for (const pending of this.pending.values()) {
|
|
150
|
+
clearTimeout(pending.timer);
|
|
151
|
+
pending.reject(error);
|
|
152
|
+
}
|
|
153
|
+
this.pending.clear();
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
var object = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
157
|
+
var string = (value) => typeof value === "string" && value.length > 0 ? value : null;
|
|
158
|
+
var input = (text) => [{ type: "text", text, text_elements: [] }];
|
|
159
|
+
var rpcThreadId = (result) => string(object(object(result)?.thread)?.id);
|
|
160
|
+
var rpcTurnId = (result) => {
|
|
161
|
+
const response = object(result);
|
|
162
|
+
return string(object(response?.turn)?.id) ?? string(response?.turnId);
|
|
163
|
+
};
|
|
164
|
+
var runCodexBridge = async (options) => {
|
|
165
|
+
const timeoutMs = options.requestTimeoutMs ?? 1e4;
|
|
166
|
+
const rpc = new JsonRpcClient(options.appServer, options.cwd, timeoutMs);
|
|
167
|
+
let threadId = options.resumeThreadId ?? null;
|
|
168
|
+
let activeTurnId = null;
|
|
169
|
+
let relay = null;
|
|
170
|
+
let linked = false;
|
|
171
|
+
let stopHeartbeat = () => {
|
|
172
|
+
};
|
|
173
|
+
let ownership = null;
|
|
174
|
+
const messages = /* @__PURE__ */ new Map();
|
|
175
|
+
const reportBody = (event, action) => ({
|
|
176
|
+
event,
|
|
177
|
+
action,
|
|
178
|
+
agentType: "codex",
|
|
179
|
+
agentName: `Codex - ${basename(options.cwd)}`,
|
|
180
|
+
sessionId: threadId,
|
|
181
|
+
codexThreadId: threadId,
|
|
182
|
+
spawnId: options.spawnId,
|
|
183
|
+
machineId: options.machineId,
|
|
184
|
+
pid: process.pid,
|
|
185
|
+
cwd: options.cwd
|
|
186
|
+
});
|
|
187
|
+
const report = (event, action) => postLiveSession(options, "/api/agent/event", reportBody(event, action));
|
|
188
|
+
const removeNotification = rpc.onNotification((message) => {
|
|
189
|
+
const params = message.params ?? {};
|
|
190
|
+
if (message.method === "turn/started") activeTurnId = string(object(params.turn)?.id);
|
|
191
|
+
if (message.method === "turn/completed") {
|
|
192
|
+
activeTurnId = null;
|
|
193
|
+
void report("stop", "Turn completed").catch(() => {
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
if (message.method === "item/agentMessage/delta") {
|
|
197
|
+
const itemId = string(params.itemId);
|
|
198
|
+
const delta = string(params.delta);
|
|
199
|
+
if (!itemId || !delta) return;
|
|
200
|
+
if (!messages.has(itemId) && messages.size === MAX_MESSAGE_BUFFERS) {
|
|
201
|
+
const oldest = messages.keys().next().value;
|
|
202
|
+
if (typeof oldest === "string") messages.delete(oldest);
|
|
203
|
+
}
|
|
204
|
+
messages.set(itemId, `${messages.get(itemId) ?? ""}${delta}`.slice(0, MAX_TRANSCRIPT_TEXT));
|
|
205
|
+
}
|
|
206
|
+
if (message.method === "item/completed") {
|
|
207
|
+
const itemId = string(object(params.item)?.id);
|
|
208
|
+
const text = itemId ? messages.get(itemId) : null;
|
|
209
|
+
if (!itemId || !text) return;
|
|
210
|
+
messages.delete(itemId);
|
|
211
|
+
relay?.add({ type: "assistant", uuid: itemId, message: { role: "assistant", content: text } });
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
try {
|
|
215
|
+
await rpc.request("initialize", {
|
|
216
|
+
clientInfo: { name: "pushary", title: "Pushary", version: "1" },
|
|
217
|
+
capabilities: { experimentalApi: false, requestAttestation: false }
|
|
218
|
+
});
|
|
219
|
+
rpc.notify("initialized");
|
|
220
|
+
const thread = options.resumeThreadId ? await rpc.request("thread/resume", { threadId: options.resumeThreadId, cwd: options.cwd, excludeTurns: true }) : await rpc.request("thread/start", { cwd: options.cwd, model: options.model ?? null });
|
|
221
|
+
threadId = rpcThreadId(thread);
|
|
222
|
+
if (!threadId) throw new Error("Codex app-server did not return a thread id");
|
|
223
|
+
ownership = startProcessOwnership({ sessionId: threadId, pid: process.pid, spawnId: options.spawnId });
|
|
224
|
+
await ownership.ready;
|
|
225
|
+
relay = options.transcripts === false ? null : new LiveTranscriptRelay(options, threadId);
|
|
226
|
+
await postLiveSessionUntilAccepted(
|
|
227
|
+
options,
|
|
228
|
+
"/api/agent/event",
|
|
229
|
+
reportBody("session_start", options.resumeThreadId ? "Session resumed" : "Session started")
|
|
230
|
+
);
|
|
231
|
+
linked = true;
|
|
232
|
+
stopHeartbeat = startLiveSessionHeartbeat(options, reportBody("heartbeat", "Session online"));
|
|
233
|
+
const startTurn = async (text, commandId) => {
|
|
234
|
+
relay?.add({ type: "user", uuid: commandId, message: { role: "user", content: text } });
|
|
235
|
+
const result = activeTurnId ? await rpc.request("turn/steer", {
|
|
236
|
+
threadId,
|
|
237
|
+
expectedTurnId: activeTurnId,
|
|
238
|
+
input: input(text),
|
|
239
|
+
clientUserMessageId: commandId
|
|
240
|
+
}) : await rpc.request("turn/start", {
|
|
241
|
+
threadId,
|
|
242
|
+
input: input(text),
|
|
243
|
+
cwd: options.cwd,
|
|
244
|
+
model: options.model ?? null,
|
|
245
|
+
clientUserMessageId: commandId
|
|
246
|
+
});
|
|
247
|
+
activeTurnId = rpcTurnId(result) ?? activeTurnId;
|
|
248
|
+
};
|
|
249
|
+
if (options.prompt) await startTurn(options.prompt, `spawn-${options.spawnId}`);
|
|
250
|
+
let pendingAck = null;
|
|
251
|
+
while (!options.signal.aborted && !rpc.isClosed) {
|
|
252
|
+
try {
|
|
253
|
+
if (pendingAck) {
|
|
254
|
+
const acknowledged = await postLiveSession(options, "/api/agent/command/ack", pendingAck);
|
|
255
|
+
if (acknowledged.ok) pendingAck = null;
|
|
256
|
+
}
|
|
257
|
+
if (pendingAck) {
|
|
258
|
+
await liveSessionSleep(options.pollIntervalMs ?? 2e3, options.signal);
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
const response = await postLiveSession(options, "/api/agent/command/drain", { sessionId: threadId, ackMode: true });
|
|
262
|
+
if (response.ok) {
|
|
263
|
+
const command = object((await response.json()).command);
|
|
264
|
+
const commandId = string(command?.id);
|
|
265
|
+
const text = string(command?.text);
|
|
266
|
+
if (commandId && text) {
|
|
267
|
+
try {
|
|
268
|
+
await startTurn(text, commandId);
|
|
269
|
+
pendingAck = { commandId, state: "delivered" };
|
|
270
|
+
} catch {
|
|
271
|
+
pendingAck = {
|
|
272
|
+
commandId,
|
|
273
|
+
state: "failed",
|
|
274
|
+
failureCode: "codex_rejected"
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
} catch {
|
|
280
|
+
}
|
|
281
|
+
await relay?.flush();
|
|
282
|
+
await liveSessionSleep(options.pollIntervalMs ?? 2e3, options.signal);
|
|
283
|
+
}
|
|
284
|
+
if (rpc.isClosed && !options.signal.aborted) throw new Error("Codex app-server exited");
|
|
285
|
+
if (activeTurnId) {
|
|
286
|
+
await rpc.request("turn/interrupt", { threadId, turnId: activeTurnId }).catch(() => null);
|
|
287
|
+
}
|
|
288
|
+
await relay?.flush();
|
|
289
|
+
await report("session_closed", "Session stopped").catch(() => null);
|
|
290
|
+
return "stopped";
|
|
291
|
+
} catch (error) {
|
|
292
|
+
if (!linked && options.claimId) {
|
|
293
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
294
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
295
|
+
const acknowledged = await postLiveSession(options, "/api/agent/spawn/ack", {
|
|
296
|
+
spawnId: options.spawnId,
|
|
297
|
+
claimId: options.claimId,
|
|
298
|
+
machineId: options.machineId,
|
|
299
|
+
state: "failed",
|
|
300
|
+
failure: {
|
|
301
|
+
code: "bridge_failed",
|
|
302
|
+
message: message.slice(0, 240),
|
|
303
|
+
retryable: false
|
|
304
|
+
}
|
|
305
|
+
}).catch(() => null);
|
|
306
|
+
if (acknowledged?.ok) break;
|
|
307
|
+
await liveSessionSleep(200 * (attempt + 1), options.signal);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
await report("error", "Live bridge failed").catch(() => null);
|
|
311
|
+
return "failed";
|
|
312
|
+
} finally {
|
|
313
|
+
stopHeartbeat();
|
|
314
|
+
ownership?.stop();
|
|
315
|
+
removeNotification();
|
|
316
|
+
await rpc.close();
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
// bin/pushary-codex-bridge.ts
|
|
321
|
+
var spawnId = process.env.PUSHARY_SPAWN_ID?.trim();
|
|
322
|
+
var requestedCwd = process.env.PUSHARY_BRIDGE_CWD?.trim();
|
|
323
|
+
if (!spawnId || !requestedCwd || !existsSync(requestedCwd)) {
|
|
324
|
+
process.stderr.write("[pushary] Codex bridge received an invalid launch request\n");
|
|
325
|
+
process.exit(1);
|
|
326
|
+
}
|
|
327
|
+
var abort = new AbortController();
|
|
328
|
+
var signals = process.platform === "win32" ? ["SIGINT", "SIGTERM"] : ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
329
|
+
var stop = () => abort.abort();
|
|
330
|
+
for (const signal of signals) process.on(signal, stop);
|
|
331
|
+
var outcome = await withSpawnProcessOwnership(spawnId, () => runCodexBridge({
|
|
332
|
+
apiKey: getApiKey(),
|
|
333
|
+
baseUrl: getBaseUrl(),
|
|
334
|
+
machineId: getMachineId(),
|
|
335
|
+
spawnId,
|
|
336
|
+
claimId: process.env.PUSHARY_SPAWN_CLAIM_ID?.trim() || void 0,
|
|
337
|
+
cwd: requestedCwd,
|
|
338
|
+
prompt: process.env.PUSHARY_BRIDGE_PROMPT?.trim() || void 0,
|
|
339
|
+
model: process.env.PUSHARY_BRIDGE_MODEL?.trim() || void 0,
|
|
340
|
+
resumeThreadId: process.env.PUSHARY_BRIDGE_RESUME_SESSION_ID?.trim() || void 0,
|
|
341
|
+
appServer: {
|
|
342
|
+
command: process.env.PUSHARY_CODEX_COMMAND?.trim() || resolveBinary("codex") || "codex",
|
|
343
|
+
args: ["app-server", "--stdio"]
|
|
344
|
+
},
|
|
345
|
+
signal: abort.signal,
|
|
346
|
+
transcripts: process.env.PUSHARY_TRANSCRIPTS === "1"
|
|
347
|
+
}));
|
|
348
|
+
for (const signal of signals) process.off(signal, stop);
|
|
349
|
+
process.exit(outcome === "stopped" ? 0 : 1);
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
import {
|
|
3
3
|
isGatingMoment,
|
|
4
4
|
recordKeylessMoment
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-NJ7JT26G.js";
|
|
6
6
|
import {
|
|
7
7
|
KILL_REASON,
|
|
8
8
|
denyReasonFrom,
|
|
9
9
|
isDeferAnswer,
|
|
10
10
|
resolveGate
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-BLDDXHHA.js";
|
|
12
12
|
import {
|
|
13
13
|
CODEX_AGENT,
|
|
14
14
|
DEFAULT_SESSION,
|
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
handleStop,
|
|
29
29
|
handleUserPrompt,
|
|
30
30
|
permissionTimeoutDecision,
|
|
31
|
+
policyRequestFor,
|
|
31
32
|
preToolUseTimeoutDecision,
|
|
32
33
|
readLastPrompt,
|
|
33
34
|
repoKeyFor,
|
|
@@ -39,24 +40,24 @@ import {
|
|
|
39
40
|
toPolicyLookup,
|
|
40
41
|
toPolicyLookups,
|
|
41
42
|
waitForAnswer
|
|
42
|
-
} from "../chunk-
|
|
43
|
+
} from "../chunk-CCCJ6BPW.js";
|
|
44
|
+
import {
|
|
45
|
+
getMachineId
|
|
46
|
+
} from "../chunk-RN3NOEJF.js";
|
|
43
47
|
import "../chunk-BSZYIAZL.js";
|
|
44
48
|
import "../chunk-SAF6HGAA.js";
|
|
45
|
-
import "../chunk-
|
|
49
|
+
import "../chunk-437T77TY.js";
|
|
46
50
|
import "../chunk-7QLSKOSU.js";
|
|
51
|
+
import "../chunk-KZERVKTD.js";
|
|
52
|
+
import {
|
|
53
|
+
getApiKey
|
|
54
|
+
} from "../chunk-2UMNXADU.js";
|
|
47
55
|
import {
|
|
48
56
|
DECISION_LINE_MAX,
|
|
49
57
|
effectiveWaitSeconds,
|
|
50
58
|
hookWaitClamped,
|
|
51
59
|
hookWaitDeadline
|
|
52
|
-
} from "../chunk-
|
|
53
|
-
import {
|
|
54
|
-
getMachineId
|
|
55
|
-
} from "../chunk-RN3NOEJF.js";
|
|
56
|
-
import {
|
|
57
|
-
getApiKey
|
|
58
|
-
} from "../chunk-2UMNXADU.js";
|
|
59
|
-
import "../chunk-KZERVKTD.js";
|
|
60
|
+
} from "../chunk-MQMPG5X4.js";
|
|
60
61
|
|
|
61
62
|
// bin/pushary-codex-hook.ts
|
|
62
63
|
import { basename, join } from "path";
|
|
@@ -143,6 +144,7 @@ var pushQuestion = async (apiKey, input, lookup, waitSeconds, mode) => {
|
|
|
143
144
|
action: description.slice(0, DECISION_LINE_MAX),
|
|
144
145
|
blocker: deriveBlocker(mode),
|
|
145
146
|
actionBody: deriveActionBody(input.tool_name ?? "", input.tool_input ?? {}),
|
|
147
|
+
repoKey: repoKeyFor(input.cwd),
|
|
146
148
|
// Codex has always sent this; it is what claimNotify and markApproved already
|
|
147
149
|
// key on locally. Passing it through lets the server collapse a retried create
|
|
148
150
|
// the same way, instead of putting the same approval on the phone twice.
|
|
@@ -177,9 +179,10 @@ var notifyApprovalNeeded = async (apiKey, input, lookup) => {
|
|
|
177
179
|
};
|
|
178
180
|
var codexGate = async (apiKey, input) => {
|
|
179
181
|
const modeState = await fetchModeState(apiKey, input.session_id);
|
|
182
|
+
const policyRequest = policyRequestFor("codex");
|
|
180
183
|
const lookup = toPolicyLookup(input.tool_name ?? "", input.tool_input ?? {}, input.cwd);
|
|
181
184
|
const lookups = toPolicyLookups(input.tool_name ?? "", input.tool_input ?? {}, input.cwd);
|
|
182
|
-
const config = await getPolicy(apiKey, modeState.policyVersion,
|
|
185
|
+
const config = await getPolicy(apiKey, modeState.policyVersion, policyRequest.agent, policyRequest.repoAware, input.session_id);
|
|
183
186
|
const verdict = resolveGate({
|
|
184
187
|
modeState,
|
|
185
188
|
config,
|
|
@@ -189,7 +192,8 @@ var codexGate = async (apiKey, input) => {
|
|
|
189
192
|
// session. A multi-file patch contributes one path per file.
|
|
190
193
|
scopePaths: modeState.scope ? lookups.inputs.map((entry) => scopePathFor(lookups.tool, entry, input.cwd)).filter((path) => typeof path === "string") : [],
|
|
191
194
|
cwd: input.cwd,
|
|
192
|
-
repoKey: repoKeyFor(input.cwd)
|
|
195
|
+
repoKey: repoKeyFor(input.cwd),
|
|
196
|
+
sessionId: input.session_id
|
|
193
197
|
});
|
|
194
198
|
return { verdict, lookup };
|
|
195
199
|
};
|
|
@@ -3,19 +3,19 @@ import {
|
|
|
3
3
|
askUser,
|
|
4
4
|
reportEvent,
|
|
5
5
|
waitForAnswer
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import "../chunk-BSZYIAZL.js";
|
|
8
|
-
import "../chunk-SAF6HGAA.js";
|
|
9
|
-
import "../chunk-SAA3VBDK.js";
|
|
10
|
-
import "../chunk-7QLSKOSU.js";
|
|
11
|
-
import "../chunk-YWRJGYUH.js";
|
|
6
|
+
} from "../chunk-CCCJ6BPW.js";
|
|
12
7
|
import {
|
|
13
8
|
getMachineId
|
|
14
9
|
} from "../chunk-RN3NOEJF.js";
|
|
10
|
+
import "../chunk-BSZYIAZL.js";
|
|
11
|
+
import "../chunk-SAF6HGAA.js";
|
|
12
|
+
import "../chunk-437T77TY.js";
|
|
13
|
+
import "../chunk-7QLSKOSU.js";
|
|
14
|
+
import "../chunk-KZERVKTD.js";
|
|
15
15
|
import {
|
|
16
16
|
getApiKey
|
|
17
17
|
} from "../chunk-2UMNXADU.js";
|
|
18
|
-
import "../chunk-
|
|
18
|
+
import "../chunk-MQMPG5X4.js";
|
|
19
19
|
|
|
20
20
|
// bin/pushary-codex.ts
|
|
21
21
|
import { basename } from "path";
|
|
@@ -3,40 +3,41 @@ import {
|
|
|
3
3
|
confirmAppConnection,
|
|
4
4
|
connectDevice,
|
|
5
5
|
printConnectInstructions
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-6LC4WSCL.js";
|
|
7
7
|
import "../chunk-3EGEA4KH.js";
|
|
8
8
|
import {
|
|
9
9
|
printKeyCheck
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-FBGBJXVC.js";
|
|
11
11
|
import {
|
|
12
12
|
checkApiKey
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-F52SIIDG.js";
|
|
14
14
|
import {
|
|
15
15
|
createIo
|
|
16
16
|
} from "../chunk-5RUIFDTP.js";
|
|
17
17
|
import {
|
|
18
18
|
readKeySource
|
|
19
|
-
} from "../chunk-
|
|
20
|
-
import "../chunk-6MTNS63X.js";
|
|
19
|
+
} from "../chunk-K7CSRGKZ.js";
|
|
21
20
|
import {
|
|
22
21
|
parseFlags
|
|
23
22
|
} from "../chunk-GMXKITVA.js";
|
|
23
|
+
import {
|
|
24
|
+
exitOnHelpFlag
|
|
25
|
+
} from "../chunk-J4KFVOCQ.js";
|
|
26
|
+
import "../chunk-MGJBC6DD.js";
|
|
24
27
|
import "../chunk-BC3VCZ3E.js";
|
|
28
|
+
import "../chunk-DINDL2CF.js";
|
|
29
|
+
import "../chunk-6MTNS63X.js";
|
|
25
30
|
import "../chunk-BSZYIAZL.js";
|
|
26
31
|
import "../chunk-SAF6HGAA.js";
|
|
27
|
-
import "../chunk-
|
|
32
|
+
import "../chunk-437T77TY.js";
|
|
28
33
|
import {
|
|
29
34
|
UsageError
|
|
30
35
|
} from "../chunk-7QLSKOSU.js";
|
|
31
|
-
import "../chunk-YWRJGYUH.js";
|
|
32
|
-
import {
|
|
33
|
-
exitOnHelpFlag
|
|
34
|
-
} from "../chunk-RRZZ7TFJ.js";
|
|
35
|
-
import "../chunk-ZUKH2NPJ.js";
|
|
36
|
-
import "../chunk-2UMNXADU.js";
|
|
37
36
|
import {
|
|
38
37
|
EXIT
|
|
39
38
|
} from "../chunk-KZERVKTD.js";
|
|
39
|
+
import "../chunk-2UMNXADU.js";
|
|
40
|
+
import "../chunk-MQMPG5X4.js";
|
|
40
41
|
|
|
41
42
|
// bin/pushary-connect.ts
|
|
42
43
|
exitOnHelpFlag("connect");
|