@pushary/agent-hooks 1.9.44 → 1.9.46
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 +10 -0
- package/README.md +1 -1
- package/dist/bin/pushary-bell-hook.js +25 -26
- package/dist/bin/pushary-bell.js +9 -9
- package/dist/bin/pushary-claude.js +32 -34
- package/dist/bin/pushary-clean.js +30 -31
- package/dist/bin/pushary-codex-bridge.js +22 -690
- package/dist/bin/pushary-codex-hook.js +32 -34
- package/dist/bin/pushary-codex-session.js +439 -42
- package/dist/bin/pushary-codex.js +12 -13
- package/dist/bin/pushary-connect.js +24 -25
- package/dist/bin/pushary-cowork.js +5 -5
- package/dist/bin/pushary-daemon.js +42 -43
- package/dist/bin/pushary-disconnect.js +24 -25
- package/dist/bin/pushary-doctor.js +35 -36
- package/dist/bin/pushary-elicitation-hook.js +25 -26
- package/dist/bin/pushary-gemini-bridge.js +22 -22
- package/dist/bin/pushary-gemini-hook.js +29 -31
- package/dist/bin/pushary-hook.js +30 -31
- package/dist/bin/pushary-login.js +13 -13
- package/dist/bin/pushary-logout.js +24 -25
- package/dist/bin/pushary-mcp.js +9 -9
- package/dist/bin/pushary-mode.js +12 -12
- package/dist/bin/pushary-notification-hook.js +24 -25
- package/dist/bin/pushary-opencode-hook.js +28 -30
- package/dist/bin/pushary-permission-denied-hook.js +29 -30
- package/dist/bin/pushary-permission-hook.js +28 -29
- package/dist/bin/pushary-post-hook.js +24 -25
- package/dist/bin/pushary-prompt-hook.js +24 -25
- package/dist/bin/pushary-session-end-hook.js +24 -25
- package/dist/bin/pushary-session-start-hook.js +29 -30
- package/dist/bin/pushary-setup.js +37 -38
- package/dist/bin/pushary-stats.js +5 -5
- package/dist/bin/pushary-status.js +27 -28
- package/dist/bin/pushary-stop-hook.js +24 -25
- package/dist/bin/pushary-stopfailure-hook.js +24 -25
- package/dist/bin/pushary-suggestions.js +12 -12
- package/dist/bin/pushary-transcript-register.js +17 -17
- package/dist/bin/pushary-transcripts.js +7 -7
- package/dist/bin/pushary-upgrade.js +31 -32
- package/dist/bin/pushary-wait.js +12 -12
- package/dist/bin/pushary.js +6 -6
- package/dist/{chunk-KYLY6UMN.js → chunk-2IFTZZ5K.js} +1 -1
- package/dist/{chunk-L2ZM7LXN.js → chunk-2PTJHEX4.js} +2 -2
- package/dist/{chunk-3IRC3XFG.js → chunk-2UABJ75E.js} +2 -2
- package/dist/{chunk-MRQJCIFO.js → chunk-2VNHP2OE.js} +1 -1
- package/dist/{chunk-TKTS3SIM.js → chunk-2X3PPRNC.js} +3 -3
- package/dist/{chunk-E76QCZIA.js → chunk-2ZD53EQW.js} +2 -2
- package/dist/{chunk-SI2NC6UU.js → chunk-35TUEZ5E.js} +3 -3
- package/dist/{chunk-7UM4NCUI.js → chunk-5NXD6ZHQ.js} +2 -2
- package/dist/{chunk-42CVAOC5.js → chunk-5O6GB64K.js} +2 -2
- package/dist/{chunk-OWQOMGBF.js → chunk-7XSIUY5F.js} +1 -1
- package/dist/{chunk-4WBAHVBK.js → chunk-BKJP2MQN.js} +6 -6
- package/dist/{chunk-W2TA4EVZ.js → chunk-CA6F44OF.js} +7 -7
- package/dist/{chunk-DD6IBKEJ.js → chunk-CJKEU4EZ.js} +4 -4
- package/dist/{chunk-JNU3LV47.js → chunk-EDSXF7NV.js} +25 -4
- package/dist/{chunk-75M7NFFC.js → chunk-EKDSF3IX.js} +1 -1
- package/dist/{chunk-PQAFH4DF.js → chunk-ELLN4XAF.js} +2 -2
- package/dist/{chunk-T4CKP47U.js → chunk-EP4MD6TH.js} +5 -5
- package/dist/{chunk-4JHEZ2PV.js → chunk-EW52AGOV.js} +4 -4
- package/dist/chunk-FMDGUCER.js +866 -0
- package/dist/{chunk-53UZN7JW.js → chunk-FQW7AV6U.js} +3 -3
- package/dist/{chunk-XPQDBTW4.js → chunk-FQWI6XQG.js} +1 -1
- package/dist/{chunk-MIBCRQWK.js → chunk-G227SH2O.js} +2 -2
- package/dist/{chunk-OR6KJOHE.js → chunk-GG6C4CHH.js} +2 -2
- package/dist/{chunk-2NVXFWQY.js → chunk-GQZF6DPL.js} +1 -1
- package/dist/{chunk-FI2F5KZJ.js → chunk-HTQPDODV.js} +4 -4
- package/dist/{chunk-SWDPCDLT.js → chunk-HX34VBPE.js} +4 -4
- package/dist/{chunk-OZ7MLVDM.js → chunk-I5EQ5NJD.js} +8 -8
- package/dist/{chunk-IWHDNMM3.js → chunk-JPGY5LSF.js} +5 -5
- package/dist/{chunk-S2ALW446.js → chunk-KJNWVAS6.js} +3 -3
- package/dist/{chunk-TJZUQRMH.js → chunk-LA4S2KIM.js} +3 -3
- package/dist/{chunk-RGBTKOCC.js → chunk-LEMQA4HM.js} +5 -5
- package/dist/{chunk-UC4PNLMK.js → chunk-LNO25UX4.js} +6 -6
- package/dist/{chunk-CESLE4UN.js → chunk-MBB4XJIN.js} +7 -7
- package/dist/{chunk-UJXLVH66.js → chunk-MOUUDZOZ.js} +1 -1
- package/dist/{chunk-6EV3B5CD.js → chunk-NO3ADUD4.js} +1 -1
- package/dist/{chunk-KILK6SWZ.js → chunk-NULG2ZUG.js} +4 -4
- package/dist/{chunk-CAJCCQ7N.js → chunk-NWZZTHWF.js} +1 -1
- package/dist/{chunk-FKDZU6YX.js → chunk-OI6YNNI5.js} +4 -4
- package/dist/{chunk-CEZTYTBN.js → chunk-ON2WCBIN.js} +11 -13
- package/dist/{chunk-ALY7ZBNB.js → chunk-P2FHZ65U.js} +1 -1
- package/dist/{chunk-UY5E2UUW.js → chunk-PGULTXDJ.js} +5 -5
- package/dist/{chunk-GRAPJKDK.js → chunk-PZPYL65I.js} +1 -1
- package/dist/{chunk-FYNMFSIZ.js → chunk-SEKQAYVP.js} +2 -2
- package/dist/{chunk-GBCR2FH2.js → chunk-T623UG5T.js} +3 -3
- package/dist/{chunk-OSMNLNPF.js → chunk-UCRG5QGN.js} +1 -1
- package/dist/{chunk-GOEIW2VH.js → chunk-UGXRDY3O.js} +182 -39
- package/dist/{chunk-PGHN5D4N.js → chunk-UI3WDOV3.js} +2 -2
- package/dist/{chunk-WMO2XVG4.js → chunk-ULEX43F7.js} +1 -1
- package/dist/{chunk-LEHBWBCG.js → chunk-UP2RNIHL.js} +4 -4
- package/dist/{chunk-UZVF6MP2.js → chunk-VTF7LKDB.js} +5 -5
- package/dist/{chunk-M2L7625S.js → chunk-W7MXYDGP.js} +2 -2
- package/dist/{chunk-T3KMJI4W.js → chunk-WN3MDHAM.js} +2 -2
- package/dist/{chunk-BKK3JCTD.js → chunk-WYD4PYTL.js} +12 -14
- package/dist/{chunk-TWATOPHK.js → chunk-XAMFOUXA.js} +2 -2
- package/dist/{chunk-WBD7HZEZ.js → chunk-ZGGSQTCO.js} +1 -1
- package/dist/{chunk-HV4TEKNP.js → chunk-ZYS4UHEC.js} +4 -4
- package/dist/{global-upgrade-QSSDYZCZ.js → global-upgrade-A7EADTOL.js} +6 -6
- package/dist/{paths-55DDFLY4.js → paths-UIPHTZH4.js} +2 -2
- package/dist/{reapply-MEU66ALO.js → reapply-JAT4DS6G.js} +21 -22
- package/dist/src/index.js +19 -20
- package/dist/{upgrade-lock-YLXAU4AD.js → upgrade-lock-YUSXU5I5.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-5ZSBQHCM.js +0 -161
- package/dist/chunk-SVCT5D7K.js +0 -196
|
@@ -1,36 +1,50 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
exitOnHelpFlag
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-GG6C4CHH.js";
|
|
5
5
|
import {
|
|
6
|
-
CodexNativeApprovals
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
CodexNativeApprovals,
|
|
7
|
+
answerCodexElicitation,
|
|
8
|
+
answerCodexQuestions,
|
|
9
|
+
claimOwnedQuestion,
|
|
10
|
+
closesOwnedQuestion,
|
|
11
|
+
codexQuestionOwner,
|
|
12
|
+
planCodexElicitation,
|
|
13
|
+
reportOwnedQuestion
|
|
14
|
+
} from "../chunk-FMDGUCER.js";
|
|
15
|
+
import "../chunk-ELLN4XAF.js";
|
|
9
16
|
import {
|
|
10
17
|
resolveProviderBinary
|
|
11
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-2PTJHEX4.js";
|
|
12
19
|
import "../chunk-RIVNNBEK.js";
|
|
13
|
-
import "../chunk-
|
|
14
|
-
import "../chunk-
|
|
20
|
+
import "../chunk-UI3WDOV3.js";
|
|
21
|
+
import "../chunk-EKDSF3IX.js";
|
|
22
|
+
import "../chunk-2VNHP2OE.js";
|
|
23
|
+
import "../chunk-XHKBHWLX.js";
|
|
15
24
|
import "../chunk-6ICPEJY5.js";
|
|
16
|
-
import
|
|
25
|
+
import {
|
|
26
|
+
writeDegraded
|
|
27
|
+
} from "../chunk-UGXRDY3O.js";
|
|
17
28
|
import "../chunk-POFBE6ZY.js";
|
|
18
|
-
import "../chunk-
|
|
19
|
-
import "../chunk-
|
|
20
|
-
import "../chunk-
|
|
29
|
+
import "../chunk-FQW7AV6U.js";
|
|
30
|
+
import "../chunk-2X3PPRNC.js";
|
|
31
|
+
import "../chunk-KJNWVAS6.js";
|
|
21
32
|
import {
|
|
22
33
|
getMachineId
|
|
23
|
-
} from "../chunk-
|
|
34
|
+
} from "../chunk-ULEX43F7.js";
|
|
24
35
|
import "../chunk-7QLSKOSU.js";
|
|
25
36
|
import "../chunk-KZERVKTD.js";
|
|
26
|
-
import "../chunk-
|
|
37
|
+
import "../chunk-EW52AGOV.js";
|
|
27
38
|
import "../chunk-AQFEP65J.js";
|
|
28
39
|
import {
|
|
29
40
|
getApiKey,
|
|
30
41
|
getBaseUrl
|
|
31
|
-
} from "../chunk-
|
|
32
|
-
import "../chunk-
|
|
33
|
-
import
|
|
42
|
+
} from "../chunk-7XSIUY5F.js";
|
|
43
|
+
import "../chunk-WN3MDHAM.js";
|
|
44
|
+
import {
|
|
45
|
+
CODEX_NATIVE_APPROVAL_METHODS,
|
|
46
|
+
canonicalJsonText
|
|
47
|
+
} from "../chunk-EDSXF7NV.js";
|
|
34
48
|
|
|
35
49
|
// src/codex-session-launch.ts
|
|
36
50
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -44,6 +58,95 @@ import { createServer } from "http";
|
|
|
44
58
|
import { tmpdir } from "os";
|
|
45
59
|
import { join } from "path";
|
|
46
60
|
import WebSocket, { WebSocketServer } from "ws";
|
|
61
|
+
|
|
62
|
+
// src/codex-shared-questions.ts
|
|
63
|
+
import { createHash, randomUUID } from "crypto";
|
|
64
|
+
var CodexSharedQuestions = class {
|
|
65
|
+
constructor(options) {
|
|
66
|
+
this.options = options;
|
|
67
|
+
}
|
|
68
|
+
generation = randomUUID();
|
|
69
|
+
pending = /* @__PURE__ */ new Map();
|
|
70
|
+
retired = /* @__PURE__ */ new Set();
|
|
71
|
+
tasks = /* @__PURE__ */ new Set();
|
|
72
|
+
closed = false;
|
|
73
|
+
handle(message, threadId) {
|
|
74
|
+
if (this.closed || !message.method) return;
|
|
75
|
+
const params = message.params ?? {};
|
|
76
|
+
if (message.id === void 0) {
|
|
77
|
+
for (const [id2, pending2] of this.pending) {
|
|
78
|
+
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);
|
|
79
|
+
if (closed) {
|
|
80
|
+
pending2.controller.abort();
|
|
81
|
+
this.pending.delete(id2);
|
|
82
|
+
this.retired.add(id2);
|
|
83
|
+
if (pending2.dispatch) {
|
|
84
|
+
const task2 = reportOwnedQuestion(this.options, pending2.dispatch, "request_closed").finally(() => this.tasks.delete(task2));
|
|
85
|
+
this.tasks.add(task2);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const id = message.id;
|
|
92
|
+
if (typeof id !== "string" && !(typeof id === "number" && Number.isSafeInteger(id))) return;
|
|
93
|
+
if (this.retired.has(id)) return;
|
|
94
|
+
const subjectHash = createHash("sha256").update(canonicalJsonText(params)).digest("hex");
|
|
95
|
+
const existing = this.pending.get(id);
|
|
96
|
+
if (existing) {
|
|
97
|
+
if (existing.subjectHash !== subjectHash) {
|
|
98
|
+
existing.controller.abort();
|
|
99
|
+
this.pending.delete(id);
|
|
100
|
+
this.retired.add(id);
|
|
101
|
+
}
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (this.pending.size >= 8) return;
|
|
105
|
+
const isQuestion = message.method === "item/tool/requestUserInput";
|
|
106
|
+
if (!isQuestion && message.method !== "mcpServer/elicitation/request") return;
|
|
107
|
+
const owner = isQuestion ? codexQuestionOwner(params, id, { machineId: this.options.machineId, generation: this.generation, threadId }) : null;
|
|
108
|
+
if (isQuestion ? !owner : !planCodexElicitation(params, threadId)) return;
|
|
109
|
+
const duration = params.autoResolutionMs;
|
|
110
|
+
if (duration != null && (typeof duration !== "number" || !Number.isFinite(duration) || duration < 0)) return;
|
|
111
|
+
const dispatch = owner ? { owner, correlationIds: [], deadline: typeof duration === "number" ? Date.now() + duration : null } : void 0;
|
|
112
|
+
const pending = { controller: new AbortController(), dispatch, threadId, subjectHash };
|
|
113
|
+
this.pending.set(id, pending);
|
|
114
|
+
const task = this.answer(id, params, pending).finally(() => this.tasks.delete(task));
|
|
115
|
+
this.tasks.add(task);
|
|
116
|
+
}
|
|
117
|
+
async answer(id, params, pending) {
|
|
118
|
+
const signal = AbortSignal.any([this.options.signal, pending.controller.signal]);
|
|
119
|
+
const options = { ...this.options, shared: true, signal };
|
|
120
|
+
const dispatch = pending.dispatch;
|
|
121
|
+
try {
|
|
122
|
+
const result = dispatch ? await answerCodexQuestions(options, params, signal, "request_user_input", dispatch) : await answerCodexElicitation(options, params, pending.threadId, signal);
|
|
123
|
+
if (signal.aborted || this.closed || "action" in result && result.action !== "accept") return;
|
|
124
|
+
if (dispatch) await claimOwnedQuestion(options, dispatch);
|
|
125
|
+
if (signal.aborted || this.closed || this.pending.get(id) !== pending) return;
|
|
126
|
+
if (dispatch?.deadline != null && Date.now() >= dispatch.deadline) throw new Error("Question expired");
|
|
127
|
+
this.options.reply(id, result);
|
|
128
|
+
if (dispatch) await reportOwnedQuestion(options, dispatch, "reply_queued");
|
|
129
|
+
} catch {
|
|
130
|
+
if (!signal.aborted) writeDegraded("questions", { reason: "shared_codex_question_unavailable", fallback: "native client", event: "question" });
|
|
131
|
+
} finally {
|
|
132
|
+
if (dispatch && (!dispatch.claimId || signal.aborted)) await reportOwnedQuestion(options, dispatch, "unavailable");
|
|
133
|
+
if (!dispatch?.claimId || signal.aborted) {
|
|
134
|
+
this.pending.delete(id);
|
|
135
|
+
this.retired.add(id);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async close() {
|
|
140
|
+
this.closed = true;
|
|
141
|
+
for (const pending of this.pending.values()) pending.controller.abort();
|
|
142
|
+
await Promise.allSettled(this.tasks);
|
|
143
|
+
await Promise.allSettled([...this.pending.values()].flatMap((pending) => pending.dispatch ? [reportOwnedQuestion(this.options, pending.dispatch, "unavailable")] : []));
|
|
144
|
+
this.pending.clear();
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// src/codex-shared-session.ts
|
|
149
|
+
var GROUP_HAS_NOTHING_LEFT_TO_SIGNAL = /* @__PURE__ */ new Set(["ESRCH", "EPERM"]);
|
|
47
150
|
var record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
48
151
|
var requestId = (value) => typeof value === "string" || typeof value === "number" && Number.isSafeInteger(value);
|
|
49
152
|
var MAX_MESSAGE_BYTES = 16 * 1024 * 1024;
|
|
@@ -66,14 +169,14 @@ var startCodexSharedSession = async (options) => {
|
|
|
66
169
|
detached: true
|
|
67
170
|
});
|
|
68
171
|
child.stderr.resume();
|
|
69
|
-
const exited = new Promise((
|
|
172
|
+
const exited = new Promise((resolve3) => {
|
|
70
173
|
child.once("exit", () => {
|
|
71
174
|
controller.abort(new Error("Codex app-server stopped"));
|
|
72
|
-
|
|
175
|
+
resolve3();
|
|
73
176
|
});
|
|
74
177
|
child.once("error", () => {
|
|
75
178
|
controller.abort(new Error("Could not start Codex app-server"));
|
|
76
|
-
|
|
179
|
+
resolve3();
|
|
77
180
|
});
|
|
78
181
|
});
|
|
79
182
|
let terminal = null;
|
|
@@ -84,16 +187,20 @@ var startCodexSharedSession = async (options) => {
|
|
|
84
187
|
if (signal.aborted || child.stdin.destroyed) throw new Error("Codex connection closed");
|
|
85
188
|
child.stdin.write(JSON.stringify(message) + "\n");
|
|
86
189
|
};
|
|
87
|
-
const
|
|
190
|
+
const reply = (id, result) => {
|
|
88
191
|
if (!unanswered.delete(id)) throw new Error("Native request already answered");
|
|
89
192
|
write({ id, result });
|
|
90
|
-
}
|
|
193
|
+
};
|
|
194
|
+
const approvals = new CodexNativeApprovals({ ...options, signal, shared: true, reply });
|
|
195
|
+
const questions = new CodexSharedQuestions({ ...options, signal, reply });
|
|
91
196
|
const observeNative = (message) => {
|
|
92
197
|
if (typeof message.method !== "string") return;
|
|
93
198
|
if (requestId(message.id)) unanswered.add(message.id);
|
|
94
199
|
if (!record(message.params)) return;
|
|
95
200
|
if (message.method === "serverRequest/resolved" && requestId(message.params.requestId)) unanswered.delete(message.params.requestId);
|
|
96
|
-
|
|
201
|
+
const event = { id: message.id, method: message.method, params: message.params };
|
|
202
|
+
const threadId = typeof message.params.threadId === "string" ? message.params.threadId : null;
|
|
203
|
+
if (!approvals.handle(event, threadId)) questions.handle(event, threadId);
|
|
97
204
|
};
|
|
98
205
|
child.stdout.setEncoding("utf8");
|
|
99
206
|
child.stdout.on("data", (chunk) => {
|
|
@@ -135,6 +242,7 @@ var startCodexSharedSession = async (options) => {
|
|
|
135
242
|
if (requestId(message.id) && !("method" in message)) {
|
|
136
243
|
if (!unanswered.delete(message.id)) return;
|
|
137
244
|
approvals.handle({ method: "serverRequest/resolved", params: { requestId: message.id } }, null);
|
|
245
|
+
questions.handle({ method: "serverRequest/resolved", params: { requestId: message.id } }, null);
|
|
138
246
|
}
|
|
139
247
|
write(message);
|
|
140
248
|
} catch {
|
|
@@ -148,14 +256,14 @@ var startCodexSharedSession = async (options) => {
|
|
|
148
256
|
process.kill(-child.pid, signal2);
|
|
149
257
|
return true;
|
|
150
258
|
} catch (error) {
|
|
151
|
-
if (record(error) && error.code === "
|
|
259
|
+
if (record(error) && typeof error.code === "string" && GROUP_HAS_NOTHING_LEFT_TO_SIGNAL.has(error.code)) return false;
|
|
152
260
|
throw error;
|
|
153
261
|
}
|
|
154
262
|
};
|
|
155
263
|
const stopServer = async () => {
|
|
156
264
|
signalServerGroup("SIGTERM");
|
|
157
265
|
const deadline = Date.now() + 2e3;
|
|
158
|
-
while (signalServerGroup(0) && Date.now() < deadline) await new Promise((
|
|
266
|
+
while (signalServerGroup(0) && Date.now() < deadline) await new Promise((resolve3) => setTimeout(resolve3, 25));
|
|
159
267
|
if (signalServerGroup(0)) signalServerGroup("SIGKILL");
|
|
160
268
|
await exited;
|
|
161
269
|
};
|
|
@@ -167,7 +275,7 @@ var startCodexSharedSession = async (options) => {
|
|
|
167
275
|
websocket.close();
|
|
168
276
|
http.close();
|
|
169
277
|
try {
|
|
170
|
-
await Promise.all([approvals.close(), stopServer()]);
|
|
278
|
+
await Promise.all([approvals.close(), questions.close(), stopServer()]);
|
|
171
279
|
} finally {
|
|
172
280
|
await rm(directory, { recursive: true, force: true });
|
|
173
281
|
}
|
|
@@ -178,9 +286,9 @@ var startCodexSharedSession = async (options) => {
|
|
|
178
286
|
void close();
|
|
179
287
|
}, { once: true });
|
|
180
288
|
try {
|
|
181
|
-
await new Promise((
|
|
289
|
+
await new Promise((resolve3, reject) => {
|
|
182
290
|
http.once("error", reject);
|
|
183
|
-
http.listen(socketPath,
|
|
291
|
+
http.listen(socketPath, resolve3);
|
|
184
292
|
});
|
|
185
293
|
signal.throwIfAborted();
|
|
186
294
|
return { endpoint: "unix://" + socketPath, signal, close };
|
|
@@ -200,7 +308,7 @@ var launchCodexSession = async (options) => {
|
|
|
200
308
|
if (!(await stat(options.cwd)).isDirectory()) throw new Error("Codex needs a project directory");
|
|
201
309
|
const session = await startCodexSharedSession(options);
|
|
202
310
|
try {
|
|
203
|
-
process.stderr.write("[pushary] Managed Codex session. Supported native permissions can reach Pushary; other prompts stay in this terminal.\n");
|
|
311
|
+
process.stderr.write("[pushary] Managed Codex session. Supported questions and native permissions can reach Pushary; other prompts stay in this terminal.\n");
|
|
204
312
|
const tui = spawn2(options.binary, ["--remote", session.endpoint], {
|
|
205
313
|
cwd: options.cwd,
|
|
206
314
|
env: { ...options.env ?? process.env, PUSHARY_CODEX_BRIDGE: "1" },
|
|
@@ -212,9 +320,9 @@ var launchCodexSession = async (options) => {
|
|
|
212
320
|
session.signal.addEventListener("abort", stop, { once: true });
|
|
213
321
|
if (session.signal.aborted) stop();
|
|
214
322
|
try {
|
|
215
|
-
return await new Promise((
|
|
323
|
+
return await new Promise((resolve3, reject) => {
|
|
216
324
|
tui.once("error", reject);
|
|
217
|
-
tui.once("close", (code) =>
|
|
325
|
+
tui.once("close", (code) => resolve3(code ?? 1));
|
|
218
326
|
});
|
|
219
327
|
} finally {
|
|
220
328
|
session.signal.removeEventListener("abort", stop);
|
|
@@ -224,25 +332,314 @@ var launchCodexSession = async (options) => {
|
|
|
224
332
|
}
|
|
225
333
|
};
|
|
226
334
|
|
|
335
|
+
// src/codex-desktop-launch.ts
|
|
336
|
+
import { spawn as spawn4, execFileSync } from "child_process";
|
|
337
|
+
import { existsSync } from "fs";
|
|
338
|
+
import { mkdtemp as mkdtemp2, readFile, rm as rm2, writeFile, access } from "fs/promises";
|
|
339
|
+
import { constants } from "fs";
|
|
340
|
+
import { tmpdir as tmpdir2 } from "os";
|
|
341
|
+
import { join as join2, resolve as resolve2 } from "path";
|
|
342
|
+
|
|
343
|
+
// src/codex-desktop-proxy.ts
|
|
344
|
+
import { spawn as spawn3 } from "child_process";
|
|
345
|
+
import { isAbsolute } from "path";
|
|
346
|
+
import { PassThrough, Transform } from "stream";
|
|
347
|
+
var record2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
348
|
+
var requestId2 = (value) => typeof value === "string" && value.length > 0 || typeof value === "number" && Number.isSafeInteger(value);
|
|
349
|
+
var THREAD_METHODS = ["thread/start", "thread/resume", "thread/fork", "thread/read"];
|
|
350
|
+
var MAX_MESSAGE_BYTES2 = 16 * 1024 * 1024;
|
|
351
|
+
var MAX_CONTEXTS = 1024;
|
|
352
|
+
var CodexDesktopApprovals = class {
|
|
353
|
+
threads = /* @__PURE__ */ new Map();
|
|
354
|
+
requests = /* @__PURE__ */ new Map();
|
|
355
|
+
answered = /* @__PURE__ */ new Map();
|
|
356
|
+
approvals;
|
|
357
|
+
closing;
|
|
358
|
+
constructor(options) {
|
|
359
|
+
this.approvals = new CodexNativeApprovals({ ...options, cwd: "/", shared: true, reply: (id, result) => {
|
|
360
|
+
if (this.closing || this.answered.get(id) !== false) throw new Error("Desktop already resolved this permission");
|
|
361
|
+
this.answered.set(id, true);
|
|
362
|
+
options.reply({ id, result });
|
|
363
|
+
} });
|
|
364
|
+
}
|
|
365
|
+
client(message) {
|
|
366
|
+
if (requestId2(message.id) && !("method" in message)) {
|
|
367
|
+
if (this.answered.get(message.id) === true) return false;
|
|
368
|
+
if (this.answered.has(message.id)) {
|
|
369
|
+
this.answered.set(message.id, true);
|
|
370
|
+
this.approvals.handle({ method: "serverRequest/resolved", params: { requestId: message.id } }, null);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
if (this.closing) return true;
|
|
374
|
+
if (requestId2(message.id) && typeof message.method === "string" && (THREAD_METHODS.includes(message.method) || message.method === "turn/start")) {
|
|
375
|
+
if (this.requests.size >= MAX_CONTEXTS) {
|
|
376
|
+
void this.close();
|
|
377
|
+
return true;
|
|
378
|
+
}
|
|
379
|
+
this.requests.set(message.id, message);
|
|
380
|
+
const p = message.params;
|
|
381
|
+
if (message.method === "turn/start" && record2(p) && typeof p.threadId === "string" && p.cwd != null) this.forgetThread(p.threadId);
|
|
382
|
+
}
|
|
383
|
+
return true;
|
|
384
|
+
}
|
|
385
|
+
server(message) {
|
|
386
|
+
if (this.closing) return;
|
|
387
|
+
if (requestId2(message.id) && !("method" in message)) {
|
|
388
|
+
const request = this.requests.get(message.id);
|
|
389
|
+
this.requests.delete(message.id);
|
|
390
|
+
if (request && record2(message.result)) {
|
|
391
|
+
this.rememberThread(message.result.thread);
|
|
392
|
+
const p2 = request.params;
|
|
393
|
+
if (request.method === "turn/start" && record2(p2)) this.rememberThread({ id: p2.threadId, cwd: p2.cwd });
|
|
394
|
+
}
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
if (typeof message.method !== "string" || !record2(message.params)) return;
|
|
398
|
+
const p = message.params;
|
|
399
|
+
if (message.method === "thread/started") this.rememberThread(p.thread);
|
|
400
|
+
if (message.method === "thread/closed" || message.method === "thread/archived") {
|
|
401
|
+
if (typeof p.threadId === "string") this.forgetThread(p.threadId);
|
|
402
|
+
}
|
|
403
|
+
if (message.method === "serverRequest/resolved" && requestId2(p.requestId) && this.answered.has(p.requestId)) this.answered.set(p.requestId, true);
|
|
404
|
+
const threadId = typeof p.threadId === "string" ? p.threadId : null;
|
|
405
|
+
const cwd = threadId ? this.threads.get(threadId) : void 0;
|
|
406
|
+
if (message.id !== void 0) {
|
|
407
|
+
if (!cwd || !requestId2(message.id) || !CODEX_NATIVE_APPROVAL_METHODS.some((method) => method === message.method)) return;
|
|
408
|
+
if (this.answered.has(message.id)) return;
|
|
409
|
+
if (this.answered.size >= 1e4) {
|
|
410
|
+
void this.close();
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
this.answered.set(message.id, false);
|
|
414
|
+
}
|
|
415
|
+
this.approvals.handle({ id: message.id, method: message.method, params: p }, threadId, cwd);
|
|
416
|
+
}
|
|
417
|
+
close() {
|
|
418
|
+
if (!this.closing) this.closing = this.approvals.close();
|
|
419
|
+
return this.closing;
|
|
420
|
+
}
|
|
421
|
+
forgetThread(id) {
|
|
422
|
+
this.threads.delete(id);
|
|
423
|
+
this.approvals.handle({ method: "thread/closed", params: { threadId: id } }, id);
|
|
424
|
+
}
|
|
425
|
+
rememberThread(thread) {
|
|
426
|
+
if (!record2(thread) || typeof thread.id !== "string" || typeof thread.cwd !== "string" || !isAbsolute(thread.cwd)) return;
|
|
427
|
+
if (this.threads.has(thread.id) && this.threads.get(thread.id) !== thread.cwd) this.forgetThread(thread.id);
|
|
428
|
+
if (this.threads.size >= MAX_CONTEXTS && !this.threads.has(thread.id)) return;
|
|
429
|
+
this.threads.set(thread.id, thread.cwd);
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
var codexProtocolLines = (observe, unavailable) => {
|
|
433
|
+
let buffered = Buffer.alloc(0), passthrough = false;
|
|
434
|
+
const forward = (stream, line) => {
|
|
435
|
+
try {
|
|
436
|
+
const message = JSON.parse(line.toString("utf8"));
|
|
437
|
+
if (!record2(message)) throw new Error("Unknown Codex protocol message");
|
|
438
|
+
if (observe(message)) stream.push(line);
|
|
439
|
+
} catch {
|
|
440
|
+
unavailable();
|
|
441
|
+
passthrough = true;
|
|
442
|
+
stream.push(line);
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
return new Transform({
|
|
446
|
+
transform(chunk, _encoding, callback) {
|
|
447
|
+
if (passthrough) {
|
|
448
|
+
this.push(chunk);
|
|
449
|
+
callback();
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
buffered = Buffer.concat([buffered, chunk]);
|
|
453
|
+
if (buffered.length > MAX_MESSAGE_BYTES2) {
|
|
454
|
+
unavailable();
|
|
455
|
+
passthrough = true;
|
|
456
|
+
this.push(buffered);
|
|
457
|
+
buffered = Buffer.alloc(0);
|
|
458
|
+
callback();
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
let end;
|
|
462
|
+
while ((end = buffered.indexOf(10)) >= 0) {
|
|
463
|
+
const line = buffered.subarray(0, end + 1);
|
|
464
|
+
buffered = buffered.subarray(end + 1);
|
|
465
|
+
if (passthrough || !line.toString("utf8").trim()) this.push(line);
|
|
466
|
+
else forward(this, line);
|
|
467
|
+
}
|
|
468
|
+
callback();
|
|
469
|
+
},
|
|
470
|
+
flush(callback) {
|
|
471
|
+
if (buffered.length) {
|
|
472
|
+
if (passthrough) this.push(buffered);
|
|
473
|
+
else forward(this, buffered);
|
|
474
|
+
}
|
|
475
|
+
callback();
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
};
|
|
479
|
+
var runCodexDesktopProxy = async (binary, args2, readAccount) => {
|
|
480
|
+
const stdioServer = args2[0] === "app-server" && !args2.some((arg) => arg === "--listen" || arg.startsWith("--listen="));
|
|
481
|
+
const child = spawn3(binary, [...args2], {
|
|
482
|
+
stdio: ["pipe", "pipe", "inherit"],
|
|
483
|
+
detached: true,
|
|
484
|
+
env: { ...process.env, CODEX_CLI_PATH: binary }
|
|
485
|
+
});
|
|
486
|
+
const account = stdioServer ? readAccount() : null;
|
|
487
|
+
const abort = new AbortController();
|
|
488
|
+
let approvals;
|
|
489
|
+
let timer;
|
|
490
|
+
let killTimer;
|
|
491
|
+
const unavailable = () => {
|
|
492
|
+
abort.abort();
|
|
493
|
+
clearInterval(timer);
|
|
494
|
+
void approvals?.close();
|
|
495
|
+
process.stderr.write("[pushary] Desktop forwarding unavailable; answer permissions in Codex.\n");
|
|
496
|
+
};
|
|
497
|
+
if (account && stdioServer) {
|
|
498
|
+
approvals = new CodexDesktopApprovals({ ...account, signal: abort.signal, reply: (message) => {
|
|
499
|
+
if (child.stdin.destroyed) throw new Error("Codex engine stopped");
|
|
500
|
+
child.stdin.write(JSON.stringify(message) + "\n");
|
|
501
|
+
} });
|
|
502
|
+
timer = setInterval(() => {
|
|
503
|
+
const current = readAccount();
|
|
504
|
+
if (!current || current.apiKey !== account.apiKey || current.baseUrl !== account.baseUrl || current.machineId !== account.machineId) unavailable();
|
|
505
|
+
}, 1e3);
|
|
506
|
+
}
|
|
507
|
+
const signalChild = (signal) => {
|
|
508
|
+
if (!child.pid) return;
|
|
509
|
+
try {
|
|
510
|
+
process.kill(-child.pid, signal);
|
|
511
|
+
} catch (error) {
|
|
512
|
+
if (!record2(error) || error.code !== "ESRCH") throw error;
|
|
513
|
+
}
|
|
514
|
+
};
|
|
515
|
+
const stop = () => {
|
|
516
|
+
if (killTimer) return;
|
|
517
|
+
abort.abort();
|
|
518
|
+
signalChild("SIGTERM");
|
|
519
|
+
killTimer = setTimeout(() => signalChild("SIGKILL"), 2e3);
|
|
520
|
+
};
|
|
521
|
+
const input = stdioServer ? codexProtocolLines((message) => approvals?.client(message) ?? true, unavailable) : new PassThrough();
|
|
522
|
+
const output = stdioServer ? codexProtocolLines((message) => {
|
|
523
|
+
approvals?.server(message);
|
|
524
|
+
return true;
|
|
525
|
+
}, unavailable) : new PassThrough();
|
|
526
|
+
process.stdin.pipe(input).pipe(child.stdin);
|
|
527
|
+
child.stdout.pipe(output).pipe(process.stdout, { end: false });
|
|
528
|
+
if (stdioServer) process.stdin.once("end", stop);
|
|
529
|
+
for (const stream of [process.stdin, input, child.stdin, child.stdout, output, process.stdout]) stream.on("error", stop);
|
|
530
|
+
for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) process.on(signal, stop);
|
|
531
|
+
try {
|
|
532
|
+
return await new Promise((resolve3, reject) => {
|
|
533
|
+
child.once("error", reject);
|
|
534
|
+
child.once("close", (code) => resolve3(code ?? 1));
|
|
535
|
+
});
|
|
536
|
+
} finally {
|
|
537
|
+
abort.abort();
|
|
538
|
+
clearInterval(timer);
|
|
539
|
+
clearTimeout(killTimer);
|
|
540
|
+
signalChild("SIGKILL");
|
|
541
|
+
process.stdin.unpipe(input);
|
|
542
|
+
child.stdout.unpipe(output);
|
|
543
|
+
output.unpipe(process.stdout);
|
|
544
|
+
process.stdin.pause();
|
|
545
|
+
process.stdin.off("end", stop);
|
|
546
|
+
for (const stream of [process.stdin, input, child.stdin, child.stdout, output, process.stdout]) stream.off("error", stop);
|
|
547
|
+
for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) process.off(signal, stop);
|
|
548
|
+
await approvals?.close();
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
// src/codex-desktop-launch.ts
|
|
553
|
+
var record3 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
554
|
+
var quote = (value) => "'" + value.replace(/'/g, "'\\''") + "'";
|
|
555
|
+
var TESTED_ENGINE_VERSION = "0.162.0-alpha.2";
|
|
556
|
+
var desktopEngineFromManifest = (app, manifest) => {
|
|
557
|
+
if (!record3(manifest) || manifest.layoutVersion !== 1 || manifest.entrypoint !== "bin/codex" || manifest.version !== TESTED_ENGINE_VERSION) {
|
|
558
|
+
throw new Error(`Experimental Desktop forwarding requires bundled Codex ${TESTED_ENGINE_VERSION}. Launch Codex normally for this version.`);
|
|
559
|
+
}
|
|
560
|
+
return join2(app, "Contents/Resources/codex-cli/bin/codex");
|
|
561
|
+
};
|
|
562
|
+
var writeDesktopProxy = async (entry, app, directory) => {
|
|
563
|
+
const shim = join2(directory, "codex");
|
|
564
|
+
await writeFile(shim, "#!/bin/sh\nexec " + [...entry, "--desktop-proxy", app, "--"].map(quote).join(" ") + ' "$@"\n', { mode: 448, flag: "wx" });
|
|
565
|
+
return shim;
|
|
566
|
+
};
|
|
567
|
+
var desktopEngine = async (app) => {
|
|
568
|
+
const manifest = JSON.parse(await readFile(join2(app, "Contents/Resources/codex-cli/codex-package.json"), "utf8"));
|
|
569
|
+
const engine = desktopEngineFromManifest(app, manifest);
|
|
570
|
+
await access(engine, constants.X_OK);
|
|
571
|
+
return engine;
|
|
572
|
+
};
|
|
573
|
+
var desktopExecutable = (app) => {
|
|
574
|
+
const plist = join2(app, "Contents/Info.plist");
|
|
575
|
+
const read = (key) => execFileSync("/usr/bin/plutil", ["-extract", key, "raw", plist], { encoding: "utf8" }).trim();
|
|
576
|
+
if (read("CFBundleIdentifier") !== "com.openai.codex") throw new Error("Choose the Codex Desktop application");
|
|
577
|
+
const name = read("CFBundleExecutable");
|
|
578
|
+
if (!name || name.includes("/") || name === "." || name === "..") throw new Error("Invalid Desktop executable");
|
|
579
|
+
try {
|
|
580
|
+
execFileSync("/usr/bin/pgrep", ["-x", name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")], { stdio: "ignore" });
|
|
581
|
+
} catch (error) {
|
|
582
|
+
if (record3(error) && error.status === 1) return join2(app, "Contents/MacOS", name);
|
|
583
|
+
throw error;
|
|
584
|
+
}
|
|
585
|
+
throw new Error("Codex Desktop is already running. Finish active work and quit it yourself, then retry. Pushary will not restart it.");
|
|
586
|
+
};
|
|
587
|
+
var codexDesktopCommand = async (args2, entry, readAccount) => {
|
|
588
|
+
if (args2[0] !== "--desktop" && args2[0] !== "--desktop-proxy") return null;
|
|
589
|
+
if (process.platform !== "darwin") throw new Error("Experimental Codex Desktop forwarding currently requires macOS");
|
|
590
|
+
if (args2[0] === "--desktop-proxy") {
|
|
591
|
+
if (!args2[1] || args2[2] !== "--") throw new Error("Invalid Desktop proxy invocation");
|
|
592
|
+
return runCodexDesktopProxy(await desktopEngine(args2[1]), args2.slice(3), readAccount);
|
|
593
|
+
}
|
|
594
|
+
if (args2.length > 2) throw new Error("Usage: pushary codex --desktop [path/to/Codex.app]");
|
|
595
|
+
if (!readAccount()) throw new Error("Connect Pushary before starting Desktop forwarding");
|
|
596
|
+
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");
|
|
597
|
+
await desktopEngine(app);
|
|
598
|
+
const executable = desktopExecutable(app);
|
|
599
|
+
const directory = await mkdtemp2(join2(tmpdir2(), "pushary-codex-desktop-"));
|
|
600
|
+
try {
|
|
601
|
+
const shim = await writeDesktopProxy(entry, app, directory);
|
|
602
|
+
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");
|
|
603
|
+
const child = spawn4(executable, [], { stdio: "ignore", detached: true, env: { ...process.env, CODEX_CLI_PATH: shim } });
|
|
604
|
+
return await new Promise((resolve3, reject) => {
|
|
605
|
+
child.once("error", reject);
|
|
606
|
+
child.once("close", (code) => resolve3(code ?? 1));
|
|
607
|
+
});
|
|
608
|
+
} finally {
|
|
609
|
+
await rm2(directory, { recursive: true, force: true });
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
|
|
227
613
|
// bin/pushary-codex-session.ts
|
|
228
|
-
exitOnHelpFlag("codex");
|
|
229
614
|
var args = process.argv.slice(2);
|
|
230
615
|
if (args[0] === "codex") args.shift();
|
|
616
|
+
if (args[0] !== "--desktop-proxy") exitOnHelpFlag("codex");
|
|
617
|
+
var desktopAccount = () => {
|
|
618
|
+
try {
|
|
619
|
+
return { apiKey: getApiKey(), baseUrl: getBaseUrl(), machineId: getMachineId() };
|
|
620
|
+
} catch {
|
|
621
|
+
return null;
|
|
622
|
+
}
|
|
623
|
+
};
|
|
231
624
|
{
|
|
232
625
|
const abort = new AbortController();
|
|
233
626
|
const stop = () => abort.abort();
|
|
234
|
-
for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) process.on(signal, stop);
|
|
627
|
+
if (!args[0]?.startsWith("--desktop")) for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) process.on(signal, stop);
|
|
235
628
|
try {
|
|
236
|
-
const
|
|
237
|
-
if (
|
|
238
|
-
|
|
239
|
-
binary
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
629
|
+
const desktop = await codexDesktopCommand(args, [process.execPath, ...process.execArgv, process.argv[1], "codex"], desktopAccount);
|
|
630
|
+
if (desktop !== null) process.exitCode = desktop;
|
|
631
|
+
else {
|
|
632
|
+
const binary = resolveProviderBinary("codex");
|
|
633
|
+
if (!binary) throw new Error("Install Codex first, then run pushary codex");
|
|
634
|
+
process.exitCode = await launchCodexSession({
|
|
635
|
+
binary,
|
|
636
|
+
cwd: codexSessionDirectory(args, process.cwd()),
|
|
637
|
+
apiKey: getApiKey(),
|
|
638
|
+
baseUrl: getBaseUrl(),
|
|
639
|
+
machineId: getMachineId(),
|
|
640
|
+
signal: abort.signal
|
|
641
|
+
});
|
|
642
|
+
}
|
|
246
643
|
} catch (error) {
|
|
247
644
|
process.stderr.write(`[pushary] ${error instanceof Error ? error.message : "Codex session failed"}
|
|
248
645
|
`);
|
|
@@ -1,33 +1,32 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
reportEvent
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-WYD4PYTL.js";
|
|
5
|
+
import "../chunk-NWZZTHWF.js";
|
|
6
|
+
import "../chunk-W7MXYDGP.js";
|
|
6
7
|
import {
|
|
7
8
|
askUser,
|
|
8
9
|
isDecisionStopped,
|
|
9
10
|
waitForAnswer
|
|
10
|
-
} from "../chunk-
|
|
11
|
-
import "../chunk-M2L7625S.js";
|
|
12
|
-
import "../chunk-GOEIW2VH.js";
|
|
11
|
+
} from "../chunk-UGXRDY3O.js";
|
|
13
12
|
import "../chunk-POFBE6ZY.js";
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-
|
|
13
|
+
import "../chunk-FQW7AV6U.js";
|
|
14
|
+
import "../chunk-2X3PPRNC.js";
|
|
15
|
+
import "../chunk-KJNWVAS6.js";
|
|
17
16
|
import {
|
|
18
17
|
getMachineId
|
|
19
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-ULEX43F7.js";
|
|
20
19
|
import "../chunk-7QLSKOSU.js";
|
|
21
20
|
import "../chunk-KZERVKTD.js";
|
|
22
|
-
import "../chunk-
|
|
21
|
+
import "../chunk-EW52AGOV.js";
|
|
23
22
|
import "../chunk-AQFEP65J.js";
|
|
24
23
|
import {
|
|
25
24
|
getApiKey
|
|
26
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-7XSIUY5F.js";
|
|
27
26
|
import {
|
|
28
27
|
NPX_LATEST_COMMAND
|
|
29
|
-
} from "../chunk-
|
|
30
|
-
import "../chunk-
|
|
28
|
+
} from "../chunk-WN3MDHAM.js";
|
|
29
|
+
import "../chunk-EDSXF7NV.js";
|
|
31
30
|
|
|
32
31
|
// bin/pushary-codex.ts
|
|
33
32
|
import { basename } from "path";
|