pushary 1.9.50 → 1.9.51
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/README.md +0 -1
- package/dist/api-PPNFRSJC.js +55 -0
- package/dist/bin/pushary-bell-hook.js +28 -25
- package/dist/bin/pushary-bell.js +13 -11
- package/dist/bin/pushary-claude.js +36 -32
- package/dist/bin/pushary-clean.js +68 -42
- package/dist/bin/pushary-codex-bridge.js +23 -20
- package/dist/bin/pushary-codex-hook.js +35 -31
- package/dist/bin/pushary-codex-session.js +17 -616
- package/dist/bin/pushary-codex.js +15 -12
- package/dist/bin/pushary-connect.js +31 -28
- package/dist/bin/pushary-cowork.js +7 -6
- package/dist/bin/pushary-daemon.js +55 -52
- package/dist/bin/pushary-disconnect.js +29 -26
- package/dist/bin/pushary-doctor.js +57 -52
- package/dist/bin/pushary-elicitation-hook.js +28 -25
- package/dist/bin/pushary-gemini-bridge.js +17 -15
- package/dist/bin/pushary-gemini-hook.js +32 -28
- package/dist/bin/pushary-hook.js +34 -31
- package/dist/bin/pushary-login.js +19 -16
- package/dist/bin/pushary-logout.js +30 -27
- package/dist/bin/pushary-mcp.js +11 -9
- package/dist/bin/pushary-mode.js +16 -14
- package/dist/bin/pushary-notification-hook.js +27 -24
- package/dist/bin/pushary-opencode-hook.js +31 -27
- package/dist/bin/pushary-permission-denied-hook.js +32 -29
- package/dist/bin/pushary-permission-hook.js +31 -28
- package/dist/bin/pushary-post-hook.js +27 -24
- package/dist/bin/pushary-prompt-hook.js +27 -24
- package/dist/bin/pushary-session-end-hook.js +27 -24
- package/dist/bin/pushary-session-start-hook.js +32 -29
- package/dist/bin/pushary-setup.js +133 -81
- package/dist/bin/pushary-stats.js +8 -7
- package/dist/bin/pushary-status.js +35 -32
- package/dist/bin/pushary-stop-hook.js +27 -24
- package/dist/bin/pushary-stopfailure-hook.js +27 -24
- package/dist/bin/pushary-suggestions.js +16 -14
- package/dist/bin/pushary-transcript-register.js +19 -17
- package/dist/bin/pushary-transcripts.js +10 -9
- package/dist/bin/pushary-upgrade.js +46 -42
- package/dist/bin/pushary-wait.js +16 -14
- package/dist/bin/pushary.js +10 -8
- package/dist/{chunk-IF2UPWD2.js → chunk-26MUPAKS.js} +1 -1
- package/dist/{chunk-AWMMABVB.js → chunk-2QPHUCXU.js} +49 -135
- package/dist/{chunk-WEY5ZHDB.js → chunk-2YSCVT6Q.js} +5 -5
- package/dist/chunk-36NGFHE4.js +72 -0
- package/dist/{chunk-25SYEAW4.js → chunk-3ICRY72Q.js} +3 -3
- package/dist/{chunk-LZYJMSOY.js → chunk-3OLEGCMU.js} +3 -3
- package/dist/{chunk-B7LV6W7U.js → chunk-3RPN7AAT.js} +1 -1
- package/dist/{chunk-VCZN7NAB.js → chunk-3YAOJEHG.js} +7 -5
- package/dist/{chunk-TGCIFEDE.js → chunk-43NXSBNZ.js} +13 -11
- package/dist/{chunk-Y74IJ2IO.js → chunk-4JM2CK2A.js} +4 -4
- package/dist/{chunk-KEAIIVW3.js → chunk-4QQEUJL4.js} +2 -2
- package/dist/{chunk-XNZB274I.js → chunk-5463UUO2.js} +1 -1
- package/dist/{chunk-ZMYLVFXC.js → chunk-5CRQCIHR.js} +14 -9
- package/dist/{chunk-KIO2MZQC.js → chunk-6QPRQVQM.js} +5 -3
- package/dist/{chunk-4PCJ6DYK.js → chunk-6SWMKF5E.js} +2 -2
- package/dist/{chunk-Y7WD72J7.js → chunk-7CLLWDCP.js} +1 -1
- package/dist/{chunk-TYTIDEBW.js → chunk-7DBTOPOT.js} +5 -5
- package/dist/chunk-7YAVKENV.js +271 -0
- package/dist/{chunk-34AQAQKW.js → chunk-AA2K3H7Y.js} +4 -4
- package/dist/{chunk-DH4BWFU7.js → chunk-AZHTI5JX.js} +5 -5
- package/dist/{chunk-PA54A437.js → chunk-BUXDR6US.js} +1 -1
- package/dist/{chunk-VUS6QGND.js → chunk-CQ5JGRML.js} +5 -1
- package/dist/{chunk-YVO4HIHX.js → chunk-DT5CACWZ.js} +12 -10
- package/dist/{chunk-LLRYP5TR.js → chunk-DT5Y55FI.js} +5 -5
- package/dist/{chunk-ZTTCYHOM.js → chunk-DUMZORSL.js} +8 -6
- package/dist/{chunk-XTVEW2NG.js → chunk-EGKD4S5H.js} +1 -1
- package/dist/{chunk-FPKQGWAF.js → chunk-EJCPHLY2.js} +2 -2
- package/dist/{chunk-YTYXFA5M.js → chunk-FI73DGNB.js} +1 -1
- package/dist/{chunk-JGNYCRB2.js → chunk-FV34HT35.js} +1 -1
- package/dist/{chunk-KK2DIUVV.js → chunk-GCN73COS.js} +1 -1
- package/dist/{chunk-SE4JFMLW.js → chunk-GTSI6NG6.js} +8 -6
- package/dist/chunk-JBT3ZSJS.js +92 -0
- package/dist/chunk-JZDRR7BL.js +427 -0
- package/dist/{chunk-KBGKWB5T.js → chunk-K3BIMGP4.js} +4 -2
- package/dist/{chunk-LY3OJFBW.js → chunk-KQBXPGXO.js} +2 -1
- package/dist/{chunk-OR5F63C2.js → chunk-LF3TLC7B.js} +2 -168
- package/dist/{chunk-GTGXQ7FJ.js → chunk-LXRQLDGW.js} +11 -11
- package/dist/{chunk-ZOKMGBPR.js → chunk-MC4VY5LK.js} +16 -5
- package/dist/{chunk-OW4DNSQ6.js → chunk-NSY2V7XU.js} +1 -1
- package/dist/{chunk-X3RCIOIH.js → chunk-ONCWYACA.js} +1 -1
- package/dist/{chunk-EP6S6VY3.js → chunk-PMJEN6CX.js} +6 -6
- package/dist/{chunk-K73CBZKW.js → chunk-PTNSIGLB.js} +4 -4
- package/dist/chunk-PVDSN6TB.js +729 -0
- package/dist/chunk-QTOLNRET.js +169 -0
- package/dist/{chunk-APASKZ2I.js → chunk-RLADRNPV.js} +5 -3
- package/dist/{chunk-BOVSUH4N.js → chunk-S6RNS4UL.js} +2 -2
- package/dist/{chunk-34RXPM5U.js → chunk-SRXBOMSR.js} +3 -3
- package/dist/{chunk-HXRH7ZCK.js → chunk-TQ6AGJVH.js} +2 -2
- package/dist/{chunk-SALUTWPX.js → chunk-UKX5WIB5.js} +4 -4
- package/dist/{chunk-ABMEBN2R.js → chunk-UR7XX2DV.js} +6 -4
- package/dist/{chunk-BXK6ZJVJ.js → chunk-UVT6B6XN.js} +2 -2
- package/dist/{chunk-5Q2FRMPC.js → chunk-VD2OAF7Q.js} +4 -4
- package/dist/{chunk-XH3F66VD.js → chunk-VYBH6D4X.js} +3 -3
- package/dist/{chunk-UCF3EZZL.js → chunk-VZRCM362.js} +13 -13
- package/dist/{chunk-7RMSB4A2.js → chunk-W26Q2DTD.js} +14 -12
- package/dist/{chunk-GBKSCDEK.js → chunk-WVSM3G4C.js} +17 -4
- package/dist/{chunk-GDDXGBTM.js → chunk-X5GHIFST.js} +2 -2
- package/dist/chunk-XCEN33UP.js +7 -0
- package/dist/{chunk-UHVD7BSV.js → chunk-XQHPHJHR.js} +6 -6
- package/dist/{chunk-OZLGTMIY.js → chunk-XSUJ2PQY.js} +2 -2
- package/dist/{chunk-ZYYQJSIO.js → chunk-YQDZ7ZIL.js} +44 -462
- package/dist/{chunk-PXUNPXOX.js → chunk-ZOP3I2GQ.js} +3 -3
- package/dist/{chunk-WLT6J3SB.js → chunk-ZXGDBCIH.js} +2 -2
- package/dist/codex-app-cards-switch-ZQRT7MXB.js +52 -0
- package/dist/codex-desktop-launch-X7UKQ4VR.js +27 -0
- package/dist/codex-session-launch-IX33LOQZ.js +331 -0
- package/dist/config-HX6ZNOIL.js +14 -0
- package/dist/{global-upgrade-AIUSS2YH.js → global-upgrade-DGP2E2NE.js} +8 -6
- package/dist/identity-YISWVJ2A.js +15 -0
- package/dist/live-capabilities-44KFBOD4.js +53 -0
- package/dist/{paths-RO34TYNM.js → paths-VLGX4GJA.js} +4 -2
- package/dist/{reapply-KTNPP4XE.js → reapply-35F3WDTB.js} +24 -21
- package/dist/src/index.d.ts +3 -3
- package/dist/src/index.js +22 -19
- package/dist/{upgrade-lock-5UAGXIW7.js → upgrade-lock-LMO3DSSU.js} +5 -3
- package/dist/usage-ZC6BKIE3.js +10 -0
- package/package.json +1 -1
|
@@ -1,638 +1,39 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import {
|
|
6
|
-
CodexNativeApprovals,
|
|
7
|
-
answerCodexElicitation,
|
|
8
|
-
answerCodexQuestions,
|
|
9
|
-
claimOwnedQuestion,
|
|
10
|
-
closesOwnedQuestion,
|
|
11
|
-
codexQuestionOwner,
|
|
12
|
-
isCodexQuestionLeftWithTheLocalClient,
|
|
13
|
-
planCodexElicitation,
|
|
14
|
-
reportOwnedQuestion
|
|
15
|
-
} from "../chunk-SE4JFMLW.js";
|
|
16
|
-
import "../chunk-BXK6ZJVJ.js";
|
|
17
|
-
import {
|
|
18
|
-
resolveProviderBinary
|
|
19
|
-
} from "../chunk-GBKSCDEK.js";
|
|
20
|
-
import "../chunk-RIVNNBEK.js";
|
|
21
|
-
import "../chunk-FPKQGWAF.js";
|
|
22
|
-
import "../chunk-XNZB274I.js";
|
|
23
|
-
import "../chunk-KK2DIUVV.js";
|
|
24
|
-
import "../chunk-XHKBHWLX.js";
|
|
25
|
-
import "../chunk-6ICPEJY5.js";
|
|
26
|
-
import {
|
|
27
|
-
writeDegraded
|
|
28
|
-
} from "../chunk-AWMMABVB.js";
|
|
29
|
-
import "../chunk-POFBE6ZY.js";
|
|
30
|
-
import "../chunk-LZYJMSOY.js";
|
|
31
|
-
import "../chunk-34RXPM5U.js";
|
|
32
|
-
import "../chunk-ABMEBN2R.js";
|
|
33
|
-
import {
|
|
34
|
-
getMachineId
|
|
35
|
-
} from "../chunk-LY3OJFBW.js";
|
|
36
|
-
import "../chunk-7QLSKOSU.js";
|
|
37
|
-
import "../chunk-KZERVKTD.js";
|
|
38
|
-
import "../chunk-ZYYQJSIO.js";
|
|
39
|
-
import "../chunk-AQFEP65J.js";
|
|
40
|
-
import {
|
|
41
|
-
getApiKey,
|
|
42
|
-
getBaseUrl
|
|
43
|
-
} from "../chunk-VUS6QGND.js";
|
|
44
|
-
import "../chunk-ZOKMGBPR.js";
|
|
45
|
-
import {
|
|
46
|
-
CODEX_NATIVE_APPROVAL_METHODS,
|
|
47
|
-
canonicalJsonText
|
|
48
|
-
} from "../chunk-OR5F63C2.js";
|
|
49
|
-
|
|
50
|
-
// src/codex-session-launch.ts
|
|
51
|
-
import { spawn as spawn2 } from "child_process";
|
|
52
|
-
import { stat } from "fs/promises";
|
|
53
|
-
import { resolve } from "path";
|
|
54
|
-
|
|
55
|
-
// src/codex-shared-session.ts
|
|
56
|
-
import { spawn } from "child_process";
|
|
57
|
-
import { mkdtemp, rm } from "fs/promises";
|
|
58
|
-
import { createServer } from "http";
|
|
59
|
-
import { tmpdir } from "os";
|
|
60
|
-
import { join } from "path";
|
|
61
|
-
import WebSocket, { WebSocketServer } from "ws";
|
|
62
|
-
|
|
63
|
-
// src/codex-shared-questions.ts
|
|
64
|
-
import { createHash, randomUUID } from "crypto";
|
|
65
|
-
var CodexSharedQuestions = class {
|
|
66
|
-
constructor(options) {
|
|
67
|
-
this.options = options;
|
|
68
|
-
}
|
|
69
|
-
generation = randomUUID();
|
|
70
|
-
pending = /* @__PURE__ */ new Map();
|
|
71
|
-
retired = /* @__PURE__ */ new Set();
|
|
72
|
-
tasks = /* @__PURE__ */ new Set();
|
|
73
|
-
closed = false;
|
|
74
|
-
handle(message, threadId) {
|
|
75
|
-
if (this.closed || !message.method) return;
|
|
76
|
-
const params = message.params ?? {};
|
|
77
|
-
if (message.id === void 0) {
|
|
78
|
-
for (const [id2, pending2] of this.pending) {
|
|
79
|
-
const closed = pending2.dispatch ? closesOwnedQuestion(pending2.dispatch.owner, message.method, params) : message.method === "serverRequest/resolved" && params.requestId === id2 || params.threadId === pending2.threadId && ["thread/closed", "thread/archived", "turn/completed"].includes(message.method);
|
|
80
|
-
if (closed) {
|
|
81
|
-
pending2.controller.abort();
|
|
82
|
-
this.pending.delete(id2);
|
|
83
|
-
this.retired.add(id2);
|
|
84
|
-
if (pending2.dispatch) {
|
|
85
|
-
const task2 = reportOwnedQuestion(this.options, pending2.dispatch, "request_closed").finally(() => this.tasks.delete(task2));
|
|
86
|
-
this.tasks.add(task2);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
const id = message.id;
|
|
93
|
-
if (typeof id !== "string" && !(typeof id === "number" && Number.isSafeInteger(id))) return;
|
|
94
|
-
if (this.retired.has(id)) return;
|
|
95
|
-
const subjectHash = createHash("sha256").update(canonicalJsonText(params)).digest("hex");
|
|
96
|
-
const existing = this.pending.get(id);
|
|
97
|
-
if (existing) {
|
|
98
|
-
if (existing.subjectHash !== subjectHash) {
|
|
99
|
-
existing.controller.abort();
|
|
100
|
-
this.pending.delete(id);
|
|
101
|
-
this.retired.add(id);
|
|
102
|
-
}
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
if (this.pending.size >= 8) return;
|
|
106
|
-
const isQuestion = message.method === "item/tool/requestUserInput";
|
|
107
|
-
if (!isQuestion && message.method !== "mcpServer/elicitation/request") return;
|
|
108
|
-
const owner = isQuestion ? codexQuestionOwner(params, id, { machineId: this.options.machineId, generation: this.generation, threadId }) : null;
|
|
109
|
-
if (isQuestion ? !owner : !planCodexElicitation(params, threadId)) return;
|
|
110
|
-
const duration = params.autoResolutionMs;
|
|
111
|
-
if (duration != null && (typeof duration !== "number" || !Number.isFinite(duration) || duration < 0)) return;
|
|
112
|
-
const dispatch = owner ? { owner, correlationIds: [], deadline: typeof duration === "number" ? Date.now() + duration : null } : void 0;
|
|
113
|
-
const pending = { controller: new AbortController(), dispatch, threadId, subjectHash };
|
|
114
|
-
this.pending.set(id, pending);
|
|
115
|
-
const task = this.answer(id, params, pending).finally(() => this.tasks.delete(task));
|
|
116
|
-
this.tasks.add(task);
|
|
117
|
-
}
|
|
118
|
-
async answer(id, params, pending) {
|
|
119
|
-
const signal = AbortSignal.any([this.options.signal, pending.controller.signal]);
|
|
120
|
-
const options = { ...this.options, shared: true, signal };
|
|
121
|
-
const dispatch = pending.dispatch;
|
|
122
|
-
try {
|
|
123
|
-
const result = dispatch ? await answerCodexQuestions(options, params, signal, "request_user_input", dispatch) : await answerCodexElicitation(options, params, pending.threadId, signal);
|
|
124
|
-
if (signal.aborted || this.closed || "action" in result && result.action !== "accept") return;
|
|
125
|
-
if (dispatch) await claimOwnedQuestion(options, dispatch);
|
|
126
|
-
if (signal.aborted || this.closed || this.pending.get(id) !== pending) return;
|
|
127
|
-
if (dispatch?.deadline != null && Date.now() >= dispatch.deadline) throw new Error("Question expired");
|
|
128
|
-
this.options.reply(id, result);
|
|
129
|
-
if (dispatch) await reportOwnedQuestion(options, dispatch, "reply_queued");
|
|
130
|
-
} catch (error) {
|
|
131
|
-
if (!signal.aborted && !isCodexQuestionLeftWithTheLocalClient(error)) writeDegraded("questions", { reason: "shared_codex_question_unavailable", fallback: "native client", event: "question" });
|
|
132
|
-
} finally {
|
|
133
|
-
if (dispatch && (!dispatch.claimId || signal.aborted)) await reportOwnedQuestion(options, dispatch, "unavailable");
|
|
134
|
-
if (!dispatch?.claimId || signal.aborted) {
|
|
135
|
-
this.pending.delete(id);
|
|
136
|
-
this.retired.add(id);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
async close() {
|
|
141
|
-
this.closed = true;
|
|
142
|
-
for (const pending of this.pending.values()) pending.controller.abort();
|
|
143
|
-
await Promise.allSettled(this.tasks);
|
|
144
|
-
await Promise.allSettled([...this.pending.values()].flatMap((pending) => pending.dispatch ? [reportOwnedQuestion(this.options, pending.dispatch, "unavailable")] : []));
|
|
145
|
-
this.pending.clear();
|
|
146
|
-
}
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
// src/process-group.ts
|
|
150
|
-
var GROUP_HAS_NOTHING_LEFT_TO_SIGNAL = /* @__PURE__ */ new Set(["ESRCH", "EPERM"]);
|
|
151
|
-
var processGroupHasNothingLeftToSignal = (error) => error !== null && typeof error === "object" && "code" in error && typeof error.code === "string" && GROUP_HAS_NOTHING_LEFT_TO_SIGNAL.has(error.code);
|
|
152
|
-
|
|
153
|
-
// src/codex-shared-session.ts
|
|
154
|
-
var record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
155
|
-
var requestId = (value) => typeof value === "string" || typeof value === "number" && Number.isSafeInteger(value);
|
|
156
|
-
var MAX_MESSAGE_BYTES = 16 * 1024 * 1024;
|
|
157
|
-
var startCodexSharedSession = async (options) => {
|
|
158
|
-
if (process.platform === "win32") throw new Error("Managed Codex sessions currently require macOS or Linux");
|
|
159
|
-
options.signal.throwIfAborted();
|
|
160
|
-
const directory = await mkdtemp(join(tmpdir(), "pushary-codex-"));
|
|
161
|
-
const socketPath = join(directory, "terminal.sock");
|
|
162
|
-
const controller = new AbortController();
|
|
163
|
-
const signal = AbortSignal.any([controller.signal, options.signal]);
|
|
164
|
-
const http = createServer((_request, response) => {
|
|
165
|
-
response.writeHead(404);
|
|
166
|
-
response.end();
|
|
167
|
-
});
|
|
168
|
-
const websocket = new WebSocketServer({ server: http, maxPayload: MAX_MESSAGE_BYTES, perMessageDeflate: false });
|
|
169
|
-
const child = spawn(options.binary, ["app-server"], {
|
|
170
|
-
cwd: options.cwd,
|
|
171
|
-
env: { ...options.env ?? process.env, PUSHARY_CODEX_BRIDGE: "1" },
|
|
172
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
173
|
-
detached: true
|
|
174
|
-
});
|
|
175
|
-
child.stderr.resume();
|
|
176
|
-
const exited = new Promise((resolve3) => {
|
|
177
|
-
child.once("exit", () => {
|
|
178
|
-
controller.abort(new Error("Codex app-server stopped"));
|
|
179
|
-
resolve3();
|
|
180
|
-
});
|
|
181
|
-
child.once("error", () => {
|
|
182
|
-
controller.abort(new Error("Could not start Codex app-server"));
|
|
183
|
-
resolve3();
|
|
184
|
-
});
|
|
185
|
-
});
|
|
186
|
-
let terminal = null;
|
|
187
|
-
let closing = null;
|
|
188
|
-
let buffered = "";
|
|
189
|
-
const unanswered = /* @__PURE__ */ new Set();
|
|
190
|
-
const write = (message) => {
|
|
191
|
-
if (signal.aborted || child.stdin.destroyed) throw new Error("Codex connection closed");
|
|
192
|
-
child.stdin.write(JSON.stringify(message) + "\n");
|
|
193
|
-
};
|
|
194
|
-
const reply = (id, result) => {
|
|
195
|
-
if (!unanswered.delete(id)) throw new Error("Native request already answered");
|
|
196
|
-
write({ id, result });
|
|
197
|
-
};
|
|
198
|
-
const approvals = new CodexNativeApprovals({ ...options, signal, shared: true, reply });
|
|
199
|
-
const questions = new CodexSharedQuestions({ ...options, signal, reply });
|
|
200
|
-
const observeNative = (message) => {
|
|
201
|
-
if (typeof message.method !== "string") return;
|
|
202
|
-
if (requestId(message.id)) unanswered.add(message.id);
|
|
203
|
-
if (!record(message.params)) return;
|
|
204
|
-
if (message.method === "serverRequest/resolved" && requestId(message.params.requestId)) unanswered.delete(message.params.requestId);
|
|
205
|
-
const event = { id: message.id, method: message.method, params: message.params };
|
|
206
|
-
const threadId = typeof message.params.threadId === "string" ? message.params.threadId : null;
|
|
207
|
-
if (!approvals.handle(event, threadId)) questions.handle(event, threadId);
|
|
208
|
-
};
|
|
209
|
-
child.stdout.setEncoding("utf8");
|
|
210
|
-
child.stdout.on("data", (chunk) => {
|
|
211
|
-
buffered += chunk;
|
|
212
|
-
let end;
|
|
213
|
-
while ((end = buffered.indexOf("\n")) >= 0) {
|
|
214
|
-
const line = buffered.slice(0, end);
|
|
215
|
-
buffered = buffered.slice(end + 1);
|
|
216
|
-
if (!line.trim()) continue;
|
|
217
|
-
if (Buffer.byteLength(line) > MAX_MESSAGE_BYTES) {
|
|
218
|
-
controller.abort();
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
try {
|
|
222
|
-
const message = JSON.parse(line);
|
|
223
|
-
if (!record(message)) throw new Error("Invalid Codex message");
|
|
224
|
-
observeNative(message);
|
|
225
|
-
if (terminal?.readyState === WebSocket.OPEN) terminal.send(line);
|
|
226
|
-
} catch {
|
|
227
|
-
controller.abort();
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
if (Buffer.byteLength(buffered) > MAX_MESSAGE_BYTES) controller.abort();
|
|
232
|
-
});
|
|
233
|
-
child.stdin.on("error", () => controller.abort());
|
|
234
|
-
websocket.on("connection", (client) => {
|
|
235
|
-
if (terminal || signal.aborted) {
|
|
236
|
-
client.close();
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
terminal = client;
|
|
240
|
-
client.on("error", () => controller.abort());
|
|
241
|
-
client.on("close", () => controller.abort());
|
|
242
|
-
client.on("message", (bytes) => {
|
|
243
|
-
try {
|
|
244
|
-
const message = JSON.parse(bytes.toString());
|
|
245
|
-
if (!record(message)) throw new Error("Invalid terminal message");
|
|
246
|
-
if (requestId(message.id) && !("method" in message)) {
|
|
247
|
-
if (!unanswered.delete(message.id)) return;
|
|
248
|
-
approvals.handle({ method: "serverRequest/resolved", params: { requestId: message.id } }, null);
|
|
249
|
-
questions.handle({ method: "serverRequest/resolved", params: { requestId: message.id } }, null);
|
|
250
|
-
}
|
|
251
|
-
write(message);
|
|
252
|
-
} catch {
|
|
253
|
-
controller.abort();
|
|
254
|
-
}
|
|
255
|
-
});
|
|
256
|
-
});
|
|
257
|
-
const signalServerGroup = (signal2) => {
|
|
258
|
-
if (!child.pid) return false;
|
|
259
|
-
try {
|
|
260
|
-
process.kill(-child.pid, signal2);
|
|
261
|
-
return true;
|
|
262
|
-
} catch (error) {
|
|
263
|
-
if (processGroupHasNothingLeftToSignal(error)) return false;
|
|
264
|
-
throw error;
|
|
265
|
-
}
|
|
266
|
-
};
|
|
267
|
-
const stopServer = async () => {
|
|
268
|
-
signalServerGroup("SIGTERM");
|
|
269
|
-
const deadline = Date.now() + 2e3;
|
|
270
|
-
while (signalServerGroup(0) && Date.now() < deadline) await new Promise((resolve3) => setTimeout(resolve3, 25));
|
|
271
|
-
if (signalServerGroup(0)) signalServerGroup("SIGKILL");
|
|
272
|
-
await exited;
|
|
273
|
-
};
|
|
274
|
-
const close = () => {
|
|
275
|
-
if (closing) return closing;
|
|
276
|
-
closing = Promise.resolve().then(async () => {
|
|
277
|
-
controller.abort();
|
|
278
|
-
terminal?.terminate();
|
|
279
|
-
websocket.close();
|
|
280
|
-
http.close();
|
|
281
|
-
try {
|
|
282
|
-
await Promise.all([approvals.close(), questions.close(), stopServer()]);
|
|
283
|
-
} finally {
|
|
284
|
-
await rm(directory, { recursive: true, force: true });
|
|
285
|
-
}
|
|
286
|
-
});
|
|
287
|
-
return closing;
|
|
288
|
-
};
|
|
289
|
-
signal.addEventListener("abort", () => {
|
|
290
|
-
void close();
|
|
291
|
-
}, { once: true });
|
|
292
|
-
try {
|
|
293
|
-
await new Promise((resolve3, reject) => {
|
|
294
|
-
http.once("error", reject);
|
|
295
|
-
http.listen(socketPath, resolve3);
|
|
296
|
-
});
|
|
297
|
-
signal.throwIfAborted();
|
|
298
|
-
return { endpoint: "unix://" + socketPath, signal, close };
|
|
299
|
-
} catch (error) {
|
|
300
|
-
await close();
|
|
301
|
-
throw error;
|
|
302
|
-
}
|
|
303
|
-
};
|
|
304
|
-
|
|
305
|
-
// src/codex-session-launch.ts
|
|
306
|
-
var codexSessionDirectory = (args2, cwd) => {
|
|
307
|
-
if (args2.length === 0) return cwd;
|
|
308
|
-
if (args2.length === 2 && args2[0] === "--cwd" && args2[1]) return resolve(cwd, args2[1]);
|
|
309
|
-
throw new Error("Usage: pushary codex [--cwd <directory>]");
|
|
310
|
-
};
|
|
311
|
-
var launchCodexSession = async (options) => {
|
|
312
|
-
if (!(await stat(options.cwd)).isDirectory()) throw new Error("Codex needs a project directory");
|
|
313
|
-
const session = await startCodexSharedSession(options);
|
|
314
|
-
try {
|
|
315
|
-
process.stderr.write("[pushary] Managed Codex session. Supported questions and native permissions can reach Pushary; other prompts stay in this terminal.\n");
|
|
316
|
-
const tui = spawn2(options.binary, ["--remote", session.endpoint], {
|
|
317
|
-
cwd: options.cwd,
|
|
318
|
-
env: { ...options.env ?? process.env, PUSHARY_CODEX_BRIDGE: "1" },
|
|
319
|
-
stdio: "inherit"
|
|
320
|
-
});
|
|
321
|
-
const stop = () => {
|
|
322
|
-
tui.kill("SIGTERM");
|
|
323
|
-
};
|
|
324
|
-
session.signal.addEventListener("abort", stop, { once: true });
|
|
325
|
-
if (session.signal.aborted) stop();
|
|
326
|
-
try {
|
|
327
|
-
return await new Promise((resolve3, reject) => {
|
|
328
|
-
tui.once("error", reject);
|
|
329
|
-
tui.once("close", (code) => resolve3(code ?? 1));
|
|
330
|
-
});
|
|
331
|
-
} finally {
|
|
332
|
-
session.signal.removeEventListener("abort", stop);
|
|
333
|
-
}
|
|
334
|
-
} finally {
|
|
335
|
-
await session.close();
|
|
336
|
-
}
|
|
337
|
-
};
|
|
338
|
-
|
|
339
|
-
// src/codex-desktop-launch.ts
|
|
340
|
-
import { spawn as spawn4, execFileSync } from "child_process";
|
|
341
|
-
import { existsSync } from "fs";
|
|
342
|
-
import { mkdtemp as mkdtemp2, readFile, rm as rm2, writeFile, access } from "fs/promises";
|
|
343
|
-
import { constants } from "fs";
|
|
344
|
-
import { tmpdir as tmpdir2 } from "os";
|
|
345
|
-
import { join as join2, resolve as resolve2 } from "path";
|
|
346
|
-
|
|
347
|
-
// src/codex-desktop-proxy.ts
|
|
348
|
-
import { spawn as spawn3 } from "child_process";
|
|
349
|
-
import { isAbsolute } from "path";
|
|
350
|
-
import { PassThrough, Transform } from "stream";
|
|
351
|
-
var record2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
352
|
-
var requestId2 = (value) => typeof value === "string" && value.length > 0 || typeof value === "number" && Number.isSafeInteger(value);
|
|
353
|
-
var THREAD_METHODS = ["thread/start", "thread/resume", "thread/fork", "thread/read"];
|
|
354
|
-
var MAX_MESSAGE_BYTES2 = 16 * 1024 * 1024;
|
|
355
|
-
var MAX_CONTEXTS = 1024;
|
|
356
|
-
var CodexDesktopApprovals = class {
|
|
357
|
-
threads = /* @__PURE__ */ new Map();
|
|
358
|
-
requests = /* @__PURE__ */ new Map();
|
|
359
|
-
answered = /* @__PURE__ */ new Map();
|
|
360
|
-
approvals;
|
|
361
|
-
closing;
|
|
362
|
-
constructor(options) {
|
|
363
|
-
this.approvals = new CodexNativeApprovals({ ...options, cwd: "/", shared: true, reply: (id, result) => {
|
|
364
|
-
if (this.closing || this.answered.get(id) !== false) throw new Error("Desktop already resolved this permission");
|
|
365
|
-
this.answered.set(id, true);
|
|
366
|
-
options.reply({ id, result });
|
|
367
|
-
} });
|
|
368
|
-
}
|
|
369
|
-
client(message) {
|
|
370
|
-
if (requestId2(message.id) && !("method" in message)) {
|
|
371
|
-
if (this.answered.get(message.id) === true) return false;
|
|
372
|
-
if (this.answered.has(message.id)) {
|
|
373
|
-
this.answered.set(message.id, true);
|
|
374
|
-
this.approvals.handle({ method: "serverRequest/resolved", params: { requestId: message.id } }, null);
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
if (this.closing) return true;
|
|
378
|
-
if (requestId2(message.id) && typeof message.method === "string" && (THREAD_METHODS.includes(message.method) || message.method === "turn/start")) {
|
|
379
|
-
if (this.requests.size >= MAX_CONTEXTS) {
|
|
380
|
-
void this.close();
|
|
381
|
-
return true;
|
|
382
|
-
}
|
|
383
|
-
this.requests.set(message.id, message);
|
|
384
|
-
const p = message.params;
|
|
385
|
-
if (message.method === "turn/start" && record2(p) && typeof p.threadId === "string" && p.cwd != null) this.forgetThread(p.threadId);
|
|
386
|
-
}
|
|
387
|
-
return true;
|
|
388
|
-
}
|
|
389
|
-
server(message) {
|
|
390
|
-
if (this.closing) return;
|
|
391
|
-
if (requestId2(message.id) && !("method" in message)) {
|
|
392
|
-
const request = this.requests.get(message.id);
|
|
393
|
-
this.requests.delete(message.id);
|
|
394
|
-
if (request && record2(message.result)) {
|
|
395
|
-
this.rememberThread(message.result.thread);
|
|
396
|
-
const p2 = request.params;
|
|
397
|
-
if (request.method === "turn/start" && record2(p2)) this.rememberThread({ id: p2.threadId, cwd: p2.cwd });
|
|
398
|
-
}
|
|
399
|
-
return;
|
|
400
|
-
}
|
|
401
|
-
if (typeof message.method !== "string" || !record2(message.params)) return;
|
|
402
|
-
const p = message.params;
|
|
403
|
-
if (message.method === "thread/started") this.rememberThread(p.thread);
|
|
404
|
-
if (message.method === "thread/closed" || message.method === "thread/archived") {
|
|
405
|
-
if (typeof p.threadId === "string") this.forgetThread(p.threadId);
|
|
406
|
-
}
|
|
407
|
-
if (message.method === "serverRequest/resolved" && requestId2(p.requestId) && this.answered.has(p.requestId)) this.answered.set(p.requestId, true);
|
|
408
|
-
const threadId = typeof p.threadId === "string" ? p.threadId : null;
|
|
409
|
-
const cwd = threadId ? this.threads.get(threadId) : void 0;
|
|
410
|
-
if (message.id !== void 0) {
|
|
411
|
-
if (!cwd || !requestId2(message.id) || !CODEX_NATIVE_APPROVAL_METHODS.some((method) => method === message.method)) return;
|
|
412
|
-
if (this.answered.has(message.id)) return;
|
|
413
|
-
if (this.answered.size >= 1e4) {
|
|
414
|
-
void this.close();
|
|
415
|
-
return;
|
|
416
|
-
}
|
|
417
|
-
this.answered.set(message.id, false);
|
|
418
|
-
}
|
|
419
|
-
this.approvals.handle({ id: message.id, method: message.method, params: p }, threadId, cwd);
|
|
420
|
-
}
|
|
421
|
-
close() {
|
|
422
|
-
if (!this.closing) this.closing = this.approvals.close();
|
|
423
|
-
return this.closing;
|
|
424
|
-
}
|
|
425
|
-
forgetThread(id) {
|
|
426
|
-
this.threads.delete(id);
|
|
427
|
-
this.approvals.handle({ method: "thread/closed", params: { threadId: id } }, id);
|
|
428
|
-
}
|
|
429
|
-
rememberThread(thread) {
|
|
430
|
-
if (!record2(thread) || typeof thread.id !== "string" || typeof thread.cwd !== "string" || !isAbsolute(thread.cwd)) return;
|
|
431
|
-
if (this.threads.has(thread.id) && this.threads.get(thread.id) !== thread.cwd) this.forgetThread(thread.id);
|
|
432
|
-
if (this.threads.size >= MAX_CONTEXTS && !this.threads.has(thread.id)) return;
|
|
433
|
-
this.threads.set(thread.id, thread.cwd);
|
|
434
|
-
}
|
|
435
|
-
};
|
|
436
|
-
var codexProtocolLines = (observe, unavailable) => {
|
|
437
|
-
let buffered = Buffer.alloc(0), passthrough = false;
|
|
438
|
-
const forward = (stream, line) => {
|
|
439
|
-
try {
|
|
440
|
-
const message = JSON.parse(line.toString("utf8"));
|
|
441
|
-
if (!record2(message)) throw new Error("Unknown Codex protocol message");
|
|
442
|
-
if (observe(message)) stream.push(line);
|
|
443
|
-
} catch {
|
|
444
|
-
unavailable();
|
|
445
|
-
passthrough = true;
|
|
446
|
-
stream.push(line);
|
|
447
|
-
}
|
|
448
|
-
};
|
|
449
|
-
return new Transform({
|
|
450
|
-
transform(chunk, _encoding, callback) {
|
|
451
|
-
if (passthrough) {
|
|
452
|
-
this.push(chunk);
|
|
453
|
-
callback();
|
|
454
|
-
return;
|
|
455
|
-
}
|
|
456
|
-
buffered = Buffer.concat([buffered, chunk]);
|
|
457
|
-
if (buffered.length > MAX_MESSAGE_BYTES2) {
|
|
458
|
-
unavailable();
|
|
459
|
-
passthrough = true;
|
|
460
|
-
this.push(buffered);
|
|
461
|
-
buffered = Buffer.alloc(0);
|
|
462
|
-
callback();
|
|
463
|
-
return;
|
|
464
|
-
}
|
|
465
|
-
let end;
|
|
466
|
-
while ((end = buffered.indexOf(10)) >= 0) {
|
|
467
|
-
const line = buffered.subarray(0, end + 1);
|
|
468
|
-
buffered = buffered.subarray(end + 1);
|
|
469
|
-
if (passthrough || !line.toString("utf8").trim()) this.push(line);
|
|
470
|
-
else forward(this, line);
|
|
471
|
-
}
|
|
472
|
-
callback();
|
|
473
|
-
},
|
|
474
|
-
flush(callback) {
|
|
475
|
-
if (buffered.length) {
|
|
476
|
-
if (passthrough) this.push(buffered);
|
|
477
|
-
else forward(this, buffered);
|
|
478
|
-
}
|
|
479
|
-
callback();
|
|
480
|
-
}
|
|
481
|
-
});
|
|
482
|
-
};
|
|
483
|
-
var runCodexDesktopProxy = async (binary, args2, readAccount) => {
|
|
484
|
-
const stdioServer = args2[0] === "app-server" && !args2.some((arg) => arg === "--listen" || arg.startsWith("--listen="));
|
|
485
|
-
const child = spawn3(binary, [...args2], {
|
|
486
|
-
stdio: ["pipe", "pipe", "inherit"],
|
|
487
|
-
detached: true,
|
|
488
|
-
env: { ...process.env, CODEX_CLI_PATH: binary }
|
|
489
|
-
});
|
|
490
|
-
const account = stdioServer ? readAccount() : null;
|
|
491
|
-
const abort = new AbortController();
|
|
492
|
-
let approvals;
|
|
493
|
-
let timer;
|
|
494
|
-
let killTimer;
|
|
495
|
-
const unavailable = () => {
|
|
496
|
-
abort.abort();
|
|
497
|
-
clearInterval(timer);
|
|
498
|
-
void approvals?.close();
|
|
499
|
-
process.stderr.write("[pushary] Desktop forwarding unavailable; answer permissions in Codex.\n");
|
|
500
|
-
};
|
|
501
|
-
if (account && stdioServer) {
|
|
502
|
-
approvals = new CodexDesktopApprovals({ ...account, signal: abort.signal, reply: (message) => {
|
|
503
|
-
if (child.stdin.destroyed) throw new Error("Codex engine stopped");
|
|
504
|
-
child.stdin.write(JSON.stringify(message) + "\n");
|
|
505
|
-
} });
|
|
506
|
-
timer = setInterval(() => {
|
|
507
|
-
const current = readAccount();
|
|
508
|
-
if (!current || current.apiKey !== account.apiKey || current.baseUrl !== account.baseUrl || current.machineId !== account.machineId) unavailable();
|
|
509
|
-
}, 1e3);
|
|
510
|
-
}
|
|
511
|
-
const signalChild = (signal) => {
|
|
512
|
-
if (!child.pid) return;
|
|
513
|
-
try {
|
|
514
|
-
process.kill(-child.pid, signal);
|
|
515
|
-
} catch (error) {
|
|
516
|
-
if (!processGroupHasNothingLeftToSignal(error)) throw error;
|
|
517
|
-
}
|
|
518
|
-
};
|
|
519
|
-
const stop = () => {
|
|
520
|
-
if (killTimer) return;
|
|
521
|
-
abort.abort();
|
|
522
|
-
signalChild("SIGTERM");
|
|
523
|
-
killTimer = setTimeout(() => signalChild("SIGKILL"), 2e3);
|
|
524
|
-
};
|
|
525
|
-
const input = stdioServer ? codexProtocolLines((message) => approvals?.client(message) ?? true, unavailable) : new PassThrough();
|
|
526
|
-
const output = stdioServer ? codexProtocolLines((message) => {
|
|
527
|
-
approvals?.server(message);
|
|
528
|
-
return true;
|
|
529
|
-
}, unavailable) : new PassThrough();
|
|
530
|
-
process.stdin.pipe(input).pipe(child.stdin);
|
|
531
|
-
child.stdout.pipe(output).pipe(process.stdout, { end: false });
|
|
532
|
-
if (stdioServer) process.stdin.once("end", stop);
|
|
533
|
-
for (const stream of [process.stdin, input, child.stdin, child.stdout, output, process.stdout]) stream.on("error", stop);
|
|
534
|
-
for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) process.on(signal, stop);
|
|
535
|
-
try {
|
|
536
|
-
return await new Promise((resolve3, reject) => {
|
|
537
|
-
child.once("error", reject);
|
|
538
|
-
child.once("close", (code) => resolve3(code ?? 1));
|
|
539
|
-
});
|
|
540
|
-
} finally {
|
|
541
|
-
abort.abort();
|
|
542
|
-
clearInterval(timer);
|
|
543
|
-
clearTimeout(killTimer);
|
|
544
|
-
signalChild("SIGKILL");
|
|
545
|
-
process.stdin.unpipe(input);
|
|
546
|
-
child.stdout.unpipe(output);
|
|
547
|
-
output.unpipe(process.stdout);
|
|
548
|
-
process.stdin.pause();
|
|
549
|
-
process.stdin.off("end", stop);
|
|
550
|
-
for (const stream of [process.stdin, input, child.stdin, child.stdout, output, process.stdout]) stream.off("error", stop);
|
|
551
|
-
for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) process.off(signal, stop);
|
|
552
|
-
await approvals?.close();
|
|
553
|
-
}
|
|
554
|
-
};
|
|
555
|
-
|
|
556
|
-
// src/codex-desktop-launch.ts
|
|
557
|
-
var record3 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
558
|
-
var quote = (value) => "'" + value.replace(/'/g, "'\\''") + "'";
|
|
559
|
-
var TESTED_ENGINE_VERSION = "0.162.0-alpha.2";
|
|
560
|
-
var desktopEngineFromManifest = (app, manifest) => {
|
|
561
|
-
if (!record3(manifest) || manifest.layoutVersion !== 1 || manifest.entrypoint !== "bin/codex" || manifest.version !== TESTED_ENGINE_VERSION) {
|
|
562
|
-
throw new Error(`Experimental Desktop forwarding requires bundled Codex ${TESTED_ENGINE_VERSION}. Launch Codex normally for this version.`);
|
|
563
|
-
}
|
|
564
|
-
return join2(app, "Contents/Resources/codex-cli/bin/codex");
|
|
565
|
-
};
|
|
566
|
-
var writeDesktopProxy = async (entry, app, directory) => {
|
|
567
|
-
const shim = join2(directory, "codex");
|
|
568
|
-
await writeFile(shim, "#!/bin/sh\nexec " + [...entry, "--desktop-proxy", app, "--"].map(quote).join(" ") + ' "$@"\n', { mode: 448, flag: "wx" });
|
|
569
|
-
return shim;
|
|
570
|
-
};
|
|
571
|
-
var desktopEngine = async (app) => {
|
|
572
|
-
const manifest = JSON.parse(await readFile(join2(app, "Contents/Resources/codex-cli/codex-package.json"), "utf8"));
|
|
573
|
-
const engine = desktopEngineFromManifest(app, manifest);
|
|
574
|
-
await access(engine, constants.X_OK);
|
|
575
|
-
return engine;
|
|
576
|
-
};
|
|
577
|
-
var desktopExecutable = (app) => {
|
|
578
|
-
const plist = join2(app, "Contents/Info.plist");
|
|
579
|
-
const read = (key) => execFileSync("/usr/bin/plutil", ["-extract", key, "raw", plist], { encoding: "utf8" }).trim();
|
|
580
|
-
if (read("CFBundleIdentifier") !== "com.openai.codex") throw new Error("Choose the Codex Desktop application");
|
|
581
|
-
const name = read("CFBundleExecutable");
|
|
582
|
-
if (!name || name.includes("/") || name === "." || name === "..") throw new Error("Invalid Desktop executable");
|
|
583
|
-
try {
|
|
584
|
-
execFileSync("/usr/bin/pgrep", ["-x", name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")], { stdio: "ignore" });
|
|
585
|
-
} catch (error) {
|
|
586
|
-
if (record3(error) && error.status === 1) return join2(app, "Contents/MacOS", name);
|
|
587
|
-
throw error;
|
|
588
|
-
}
|
|
589
|
-
throw new Error("Codex Desktop is already running. Finish active work and quit it yourself, then retry. Pushary will not restart it.");
|
|
590
|
-
};
|
|
591
|
-
var codexDesktopCommand = async (args2, entry, readAccount) => {
|
|
592
|
-
if (args2[0] !== "--desktop" && args2[0] !== "--desktop-proxy") return null;
|
|
593
|
-
if (process.platform !== "darwin") throw new Error("Experimental Codex Desktop forwarding currently requires macOS");
|
|
594
|
-
if (args2[0] === "--desktop-proxy") {
|
|
595
|
-
if (!args2[1] || args2[2] !== "--") throw new Error("Invalid Desktop proxy invocation");
|
|
596
|
-
return runCodexDesktopProxy(await desktopEngine(args2[1]), args2.slice(3), readAccount);
|
|
597
|
-
}
|
|
598
|
-
if (args2.length > 2) throw new Error("Usage: pushary codex --desktop [path/to/Codex.app]");
|
|
599
|
-
if (!readAccount()) throw new Error("Connect Pushary before starting Desktop forwarding");
|
|
600
|
-
const app = resolve2(args2[1] ?? ["/Applications/ChatGPT.app", "/Applications/Codex.app"].find((candidate) => existsSync(join2(candidate, "Contents/Resources/codex-cli/codex-package.json"))) ?? "/Applications/Codex.app");
|
|
601
|
-
await desktopEngine(app);
|
|
602
|
-
const executable = desktopExecutable(app);
|
|
603
|
-
const directory = await mkdtemp2(join2(tmpdir2(), "pushary-codex-desktop-"));
|
|
604
|
-
try {
|
|
605
|
-
const shim = await writeDesktopProxy(entry, app, directory);
|
|
606
|
-
process.stderr.write("[pushary] Experimental Desktop launch. Supported approvals can reach Pushary; other prompts stay in Codex. Quit and open Codex normally to disable.\n");
|
|
607
|
-
const child = spawn4(executable, [], { stdio: "ignore", detached: true, env: { ...process.env, CODEX_CLI_PATH: shim } });
|
|
608
|
-
return await new Promise((resolve3, reject) => {
|
|
609
|
-
child.once("error", reject);
|
|
610
|
-
child.once("close", (code) => resolve3(code ?? 1));
|
|
611
|
-
});
|
|
612
|
-
} finally {
|
|
613
|
-
await rm2(directory, { recursive: true, force: true });
|
|
614
|
-
}
|
|
615
|
-
};
|
|
3
|
+
letCodexRunWithoutPushary
|
|
4
|
+
} from "../chunk-36NGFHE4.js";
|
|
616
5
|
|
|
617
6
|
// bin/pushary-codex-session.ts
|
|
618
7
|
var args = process.argv.slice(2);
|
|
619
8
|
if (args[0] === "codex") args.shift();
|
|
620
|
-
|
|
621
|
-
|
|
9
|
+
var appBehindTheProxy = args[0] === "--desktop-proxy" && args[2] === "--" ? args[1] : void 0;
|
|
10
|
+
if (args[0] !== "--desktop-proxy") (await import("../usage-ZC6BKIE3.js")).exitOnHelpFlag("codex");
|
|
11
|
+
var desktopAccount = async () => {
|
|
622
12
|
try {
|
|
13
|
+
const [{ getApiKey, getBaseUrl }, { getMachineId }] = await Promise.all([import("../config-HX6ZNOIL.js"), import("../identity-YISWVJ2A.js")]);
|
|
623
14
|
return { apiKey: getApiKey(), baseUrl: getBaseUrl(), machineId: getMachineId() };
|
|
624
15
|
} catch {
|
|
625
16
|
return null;
|
|
626
17
|
}
|
|
627
18
|
};
|
|
628
|
-
|
|
19
|
+
var desktopLaunch = await import("../codex-desktop-launch-X7UKQ4VR.js").catch(() => null);
|
|
20
|
+
if (desktopLaunch === null && appBehindTheProxy !== void 0) {
|
|
21
|
+
process.exitCode = await letCodexRunWithoutPushary(appBehindTheProxy, args.slice(3));
|
|
22
|
+
} else {
|
|
629
23
|
const abort = new AbortController();
|
|
630
24
|
const stop = () => abort.abort();
|
|
631
25
|
if (!args[0]?.startsWith("--desktop")) for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) process.on(signal, stop);
|
|
632
26
|
try {
|
|
27
|
+
const { codexDesktopCommand } = desktopLaunch ?? await import("../codex-desktop-launch-X7UKQ4VR.js");
|
|
633
28
|
const desktop = await codexDesktopCommand(args, [process.execPath, ...process.execArgv, process.argv[1], "codex"], desktopAccount);
|
|
634
29
|
if (desktop !== null) process.exitCode = desktop;
|
|
635
30
|
else {
|
|
31
|
+
const [{ getApiKey, getBaseUrl }, { getMachineId }, { resolveProviderBinary }, { codexSessionDirectory, launchCodexSession }] = await Promise.all([
|
|
32
|
+
import("../config-HX6ZNOIL.js"),
|
|
33
|
+
import("../identity-YISWVJ2A.js"),
|
|
34
|
+
import("../live-capabilities-44KFBOD4.js"),
|
|
35
|
+
import("../codex-session-launch-IX33LOQZ.js")
|
|
36
|
+
]);
|
|
636
37
|
const binary = resolveProviderBinary("codex");
|
|
637
38
|
if (!binary) throw new Error("Install Codex first, then run pushary codex");
|
|
638
39
|
process.exitCode = await launchCodexSession({
|