pushary 1.9.52 → 1.9.54

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.
@@ -55,7 +55,7 @@ import {
55
55
  } from "../chunk-EUW7JL2K.js";
56
56
  import {
57
57
  codexEngineBehindLauncher
58
- } from "../chunk-DMJFW4KL.js";
58
+ } from "../chunk-T5L5NWT3.js";
59
59
  import "../chunk-XCEN33UP.js";
60
60
  import {
61
61
  CURSOR_PLUGIN_BACKUP_INFIX,
@@ -244,7 +244,7 @@ import {
244
244
  CODEX_ENGINE_ENTRYPOINT,
245
245
  CODEX_ENGINE_MANIFEST,
246
246
  codexEngineInside
247
- } from "../chunk-36NGFHE4.js";
247
+ } from "../chunk-E46NE7FB.js";
248
248
  import {
249
249
  reportEvent
250
250
  } from "../chunk-U2L42GVI.js";
@@ -4,6 +4,7 @@ import { rmSync } from "fs";
4
4
  import { join } from "path";
5
5
  var CODEX_APP_LAUNCH_VARIABLE = "CODEX_CLI_PATH";
6
6
  var CODEX_ENGINE_PENDING_VARIABLE = "PUSHARY_CODEX_ENGINE_PENDING";
7
+ var CODEX_APP_LAUNCH_AT_LOGIN_VERB = "codex-app-launch-at-login";
7
8
  var CODEX_ENGINE_DIRECTORY = "Contents/Resources/codex-cli";
8
9
  var CODEX_ENGINE_ENTRYPOINT = "bin/codex";
9
10
  var CODEX_ENGINE_MANIFEST = "codex-package.json";
@@ -60,6 +61,7 @@ var letCodexRunWithoutPushary = (app, engineArgs) => {
60
61
  export {
61
62
  CODEX_APP_LAUNCH_VARIABLE,
62
63
  CODEX_ENGINE_PENDING_VARIABLE,
64
+ CODEX_APP_LAUNCH_AT_LOGIN_VERB,
63
65
  CODEX_ENGINE_DIRECTORY,
64
66
  CODEX_ENGINE_ENTRYPOINT,
65
67
  CODEX_ENGINE_MANIFEST,
@@ -12,7 +12,7 @@ import {
12
12
  launcherIsGone,
13
13
  launcherWaitingOnThisProcess,
14
14
  tellTheLauncherTheEngineStarted
15
- } from "./chunk-36NGFHE4.js";
15
+ } from "./chunk-E46NE7FB.js";
16
16
 
17
17
  // src/codex-desktop-launch.ts
18
18
  import { spawn as spawn2, execFileSync } from "child_process";
@@ -670,7 +670,8 @@ var engineWhateverTheLayout = async (app) => {
670
670
  return { engine, layoutIsKnown: false };
671
671
  }
672
672
  };
673
- var installedCodexApp = (chosen) => resolve(chosen ?? INSTALLED_CODEX_APPS.find((candidate) => existsSync(join(candidate, CODEX_ENGINE_DIRECTORY, CODEX_ENGINE_MANIFEST))) ?? INSTALLED_CODEX_APPS[1]);
673
+ var codexAppOnThisMac = () => INSTALLED_CODEX_APPS.find((candidate) => existsSync(join(candidate, CODEX_ENGINE_DIRECTORY, CODEX_ENGINE_MANIFEST))) ?? null;
674
+ var installedCodexApp = (chosen) => resolve(chosen ?? codexAppOnThisMac() ?? INSTALLED_CODEX_APPS[1]);
674
675
  var desktopExecutable = (app) => {
675
676
  const plist = join(app, "Contents/Info.plist");
676
677
  const read = (key) => execFileSync("/usr/bin/plutil", ["-extract", key, "raw", plist], { encoding: "utf8" }).trim();
@@ -694,7 +695,7 @@ var codexDesktopCommand = async (args, entry, readAccount) => {
694
695
  return runCodexDesktopProxy(engine2, args.slice(3), readAccount, { watchesForCards: layoutIsKnown });
695
696
  }
696
697
  if (args[0] === APP_CARDS_FLAG) {
697
- const { codexAppCardsCommandOnThisMac } = await import("./codex-app-cards-switch-OUQ3DUWF.js");
698
+ const { codexAppCardsCommandOnThisMac } = await import("./codex-app-cards-switch-P4RVJNRV.js");
698
699
  return codexAppCardsCommandOnThisMac(args.slice(1), entry, readAccount);
699
700
  }
700
701
  if (args.length > 2) throw new Error("Usage: pushary codex --desktop [path/to/Codex.app]");
@@ -719,11 +720,13 @@ var codexDesktopCommand = async (args, entry, readAccount) => {
719
720
  export {
720
721
  shellQuoted,
721
722
  desktopEngineFromManifest,
723
+ everyProgramFileIsThere,
722
724
  desktopProxyScript,
723
725
  codexPassThroughScript,
724
726
  codexEngineBehindLauncher,
725
727
  writeDesktopProxy,
726
728
  desktopEngine,
729
+ codexAppOnThisMac,
727
730
  installedCodexApp,
728
731
  codexDesktopCommand
729
732
  };
@@ -0,0 +1,525 @@
1
+ import {
2
+ codexAppOnThisMac,
3
+ codexPassThroughScript,
4
+ desktopEngine,
5
+ desktopProxyScript,
6
+ everyProgramFileIsThere,
7
+ installedCodexApp,
8
+ shellQuoted
9
+ } from "./chunk-T5L5NWT3.js";
10
+ import {
11
+ writeHuman
12
+ } from "./chunk-QCGNGEGE.js";
13
+ import {
14
+ xml
15
+ } from "./chunk-BL3WAGIK.js";
16
+ import {
17
+ CODEX_APP_LAUNCH_AT_LOGIN_VERB,
18
+ CODEX_APP_LAUNCH_VARIABLE
19
+ } from "./chunk-E46NE7FB.js";
20
+ import {
21
+ writeFileAtomic
22
+ } from "./chunk-AQFEP65J.js";
23
+
24
+ // src/codex-app-cards-switch.ts
25
+ import { execFileSync as execFileSync2 } from "child_process";
26
+ import { existsSync as existsSync2, mkdirSync, readFileSync, rmSync } from "fs";
27
+ import { homedir as homedir2 } from "os";
28
+ import { join as join2 } from "path";
29
+
30
+ // src/cli/mac-leftovers.ts
31
+ import { execSync, execFileSync } from "child_process";
32
+ import { existsSync, readdirSync } from "fs";
33
+ import { homedir } from "os";
34
+ import { isAbsolute, join } from "path";
35
+ var MAC_APP_BUNDLE = "/Applications/Pushary.app";
36
+ var MAC_APP_BUNDLE_ID = "com.pushary.app";
37
+ var installedPusharyBundles = (home = homedir()) => [MAC_APP_BUNDLE, join(home, "Applications", "Pushary.app")];
38
+ var LSREGISTER = "/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister";
39
+ var TEST_DEFAULTS_PREFIXES = [
40
+ "com.pushary.mac.tests.",
41
+ "com.pushary.tests.",
42
+ "pushary.tests.",
43
+ "pushary.quiet-mode-test.",
44
+ "pushary.drafts.test.",
45
+ "pushary-optin-",
46
+ "pushary-completion-test-",
47
+ "pushary-updates-only-"
48
+ ];
49
+ var UUID = "[0-9A-Fa-f]{8}(?:-[0-9A-Fa-f]{4}){3}-[0-9A-Fa-f]{12}";
50
+ var UNPREFIXED_TEST_DEFAULTS_DOMAIN = new RegExp(`^(?:owner-mode|fx-model)-${UUID}$`);
51
+ var DEVELOPER_BUILD_DEFAULTS_DOMAIN = "PusharyMac";
52
+ var isDeveloperDefaultsDomain = (domain) => domain === DEVELOPER_BUILD_DEFAULTS_DOMAIN || UNPREFIXED_TEST_DEFAULTS_DOMAIN.test(domain) || TEST_DEFAULTS_PREFIXES.some((prefix) => domain.startsWith(prefix));
53
+ var PREFERENCES_FILE_EXTENSION = ".plist";
54
+ var preferencesDirectory = (home) => join(home, "Library", "Preferences");
55
+ var preferencesFile = (home, domain) => join(preferencesDirectory(home), `${domain}${PREFERENCES_FILE_EXTENSION}`);
56
+ var namesIn = (directory) => {
57
+ try {
58
+ return readdirSync(directory);
59
+ } catch {
60
+ return [];
61
+ }
62
+ };
63
+ var developerDefaults = (home = homedir()) => namesIn(preferencesDirectory(home)).filter((name) => name.endsWith(PREFERENCES_FILE_EXTENSION)).map((name) => name.slice(0, -PREFERENCES_FILE_EXTENSION.length)).filter(isDeveloperDefaultsDomain).map((domain) => ({ domain, file: preferencesFile(home, domain) }));
64
+ var BUNDLE_NAME = "Pushary.app";
65
+ var DUMP_RECORD_SEPARATOR = /^-{20,}$/m;
66
+ var DUMP_PATH_LINES = /^[ \t]*path:[ \t]+(.+?)(?: \(0x[0-9a-f]+\))?[ \t]*$/gm;
67
+ var DUMP_IDENTIFIER_LINES = /^[ \t]*identifier:[ \t]+(\S+)/gm;
68
+ var capturedIn = (text, lines) => [...text.matchAll(lines)].flatMap((match) => match[1] === void 0 ? [] : [match[1]]);
69
+ var appCopyNamedByRecord = (record) => {
70
+ const paths = capturedIn(record, DUMP_PATH_LINES);
71
+ const identifiers = capturedIn(record, DUMP_IDENTIFIER_LINES);
72
+ const namesOneAppCopy = paths.length === 1 && identifiers.length === 1 && identifiers[0] === MAC_APP_BUNDLE_ID;
73
+ return namesOneAppCopy ? paths : [];
74
+ };
75
+ var isAtOrInside = (path, bundle) => path === bundle || path.startsWith(`${bundle}/`);
76
+ var isUnderBundleNamedPushary = (path) => path.split("/").includes(BUNDLE_NAME);
77
+ var bundlesInLaunchServicesDump = (dump) => {
78
+ const appCopies = dump.split(DUMP_RECORD_SEPARATOR).flatMap(appCopyNamedByRecord);
79
+ const isOurs = (path) => isUnderBundleNamedPushary(path) || appCopies.some((copy) => isAtOrInside(path, copy));
80
+ return [...new Set(capturedIn(dump, DUMP_PATH_LINES).filter(isOurs))];
81
+ };
82
+ var outsideInstalledBundles = (registered, installed) => registered.filter((path) => !installed.some((bundle) => isAtOrInside(path, bundle)));
83
+ var registeredPusharyBundles = (installed = installedPusharyBundles()) => {
84
+ if (!existsSync(LSREGISTER)) return [];
85
+ try {
86
+ const dump = execSync(`${LSREGISTER} -dump`, {
87
+ encoding: "utf-8",
88
+ timeout: 6e4,
89
+ maxBuffer: 256 * 1024 * 1024
90
+ });
91
+ return outsideInstalledBundles(bundlesInLaunchServicesDump(dump), installed);
92
+ } catch {
93
+ return [];
94
+ }
95
+ };
96
+ var MAC_KEYCHAIN_SERVICE = "com.pushary.app.mac";
97
+ var MAC_KEYCHAIN_ACCOUNTS = [
98
+ "pushary.site-api-key",
99
+ "pushary.site-id",
100
+ "pushary.partner-enrollments",
101
+ "pushary.partner-device-key",
102
+ "clerk.device-token",
103
+ "clerk.session-id",
104
+ "clerkDeviceToken",
105
+ "cachedClient",
106
+ "cachedClientServerDate",
107
+ "cachedEnvironment"
108
+ ];
109
+ var MAC_DEFAULTS_DOMAINS = ["com.pushary.app", "pushary-bridge", "pushary.render"];
110
+ var PRESENCE_PROBE_TIMEOUT_MS = 1e4;
111
+ var commandSucceeds = (file, args) => {
112
+ try {
113
+ execFileSync(file, args, { stdio: "ignore", timeout: PRESENCE_PROBE_TIMEOUT_MS });
114
+ return true;
115
+ } catch {
116
+ return false;
117
+ }
118
+ };
119
+ var KEYCHAIN_ITEM_NOT_FOUND = 44;
120
+ var keychainItemMayExist = (service, account) => {
121
+ try {
122
+ execFileSync("security", ["find-generic-password", "-s", service, "-a", account], { stdio: "ignore" });
123
+ return true;
124
+ } catch (error) {
125
+ return !(error instanceof Error && "status" in error && error.status === KEYCHAIN_ITEM_NOT_FOUND);
126
+ }
127
+ };
128
+ var liveMacStatePresence = {
129
+ keychainItem: keychainItemMayExist,
130
+ defaultsDomain: (domain) => commandSucceeds("defaults", ["read", domain])
131
+ };
132
+ var macLibraryState = (home = homedir()) => [
133
+ join(home, "Library", "Application Support", "Pushary"),
134
+ join(home, "Library", "Caches", "com.pushary.app"),
135
+ join(home, "Library", "Caches", "com.pushary.app.sparkle"),
136
+ join(home, "Library", "Saved Application State", "com.pushary.app.savedState"),
137
+ join(home, "Library", "Caches", "pushary-bridge"),
138
+ join(home, "Library", "HTTPStorages", "com.pushary.app"),
139
+ join(home, "Library", "HTTPStorages", "com.pushary.app.binarycookies"),
140
+ join(home, "Library", "HTTPStorages", "pushary-bridge"),
141
+ ...MAC_DEFAULTS_DOMAINS.map((domain) => preferencesFile(home, domain))
142
+ ];
143
+ var USER_CACHE_ENTRIES = [MAC_APP_BUNDLE_ID, "pushary-bridge", "PusharyBridge"];
144
+ var macUserCacheState = (reportedUserCacheDirectory) => {
145
+ const directory = reportedUserCacheDirectory.trim();
146
+ return isAbsolute(directory) ? USER_CACHE_ENTRIES.map((entry) => join(directory, entry)) : [];
147
+ };
148
+ var UNKNOWN_USER_CACHE_DIRECTORY = "";
149
+ var reportedDarwinUserCacheDirectory = () => {
150
+ try {
151
+ return execFileSync("getconf", ["DARWIN_USER_CACHE_DIR"], {
152
+ encoding: "utf-8",
153
+ timeout: PRESENCE_PROBE_TIMEOUT_MS,
154
+ stdio: ["ignore", "pipe", "ignore"]
155
+ });
156
+ } catch {
157
+ return UNKNOWN_USER_CACHE_DIRECTORY;
158
+ }
159
+ };
160
+ var CRASH_REPORTER_ENTRY = new RegExp(`^(?:Pushary|PusharyMac|pushary-bridge)_${UUID}\\.plist$`);
161
+ var crashReporterEntries = (home = homedir()) => {
162
+ const directory = join(home, "Library", "Application Support", "CrashReporter");
163
+ return namesIn(directory).filter((name) => CRASH_REPORTER_ENTRY.test(name)).map((name) => join(directory, name));
164
+ };
165
+ var storedMacAppState = (home = homedir()) => [
166
+ ...macLibraryState(home),
167
+ ...macUserCacheState(reportedDarwinUserCacheDirectory()),
168
+ ...crashReporterEntries(home)
169
+ ];
170
+ var DUMP_SERVICE_LINE = /^\s*"svce"<blob>="(.+)"\s*$/;
171
+ var pusharyKeychainServices = (dump) => {
172
+ const found = /* @__PURE__ */ new Set();
173
+ for (const line of dump.split("\n")) {
174
+ const service = DUMP_SERVICE_LINE.exec(line)?.[1];
175
+ if (service?.startsWith(MAC_KEYCHAIN_SERVICE)) found.add(service);
176
+ }
177
+ return [...found];
178
+ };
179
+ var storedPusharyKeychainServices = () => {
180
+ const dump = execFileSync("security", ["dump-keychain"], {
181
+ encoding: "utf-8",
182
+ timeout: 3e4,
183
+ maxBuffer: 64 * 1024 * 1024,
184
+ stdio: ["ignore", "pipe", "ignore"]
185
+ });
186
+ const stored = pusharyKeychainServices(dump);
187
+ return stored.includes(MAC_KEYCHAIN_SERVICE) ? stored : [MAC_KEYCHAIN_SERVICE, ...stored];
188
+ };
189
+ var runningMacAppPIDs = () => {
190
+ if (process.platform !== "darwin") return [];
191
+ try {
192
+ return execSync('pgrep -f "Pushary.app/Contents/MacOS/Pushary"', {
193
+ encoding: "utf-8",
194
+ timeout: 1e4,
195
+ stdio: ["ignore", "pipe", "ignore"]
196
+ }).split("\n").map((line) => Number(line.trim())).filter((pid) => Number.isInteger(pid) && pid > 0);
197
+ } catch {
198
+ return [];
199
+ }
200
+ };
201
+ var waitForMacAppExit = (attempts = 20, everyMs = 250) => {
202
+ const idle = new Int32Array(new SharedArrayBuffer(4));
203
+ for (let attempt = 0; attempt < attempts; attempt++) {
204
+ if (runningMacAppPIDs().length === 0) return true;
205
+ Atomics.wait(idle, 0, 0, everyMs);
206
+ }
207
+ return runningMacAppPIDs().length === 0;
208
+ };
209
+
210
+ // src/codex-app-cards-switch.ts
211
+ var CODEX_APP_CARDS_LOGIN_ITEM = "com.pushary.codex-app-cards";
212
+ var CODEX_APP_CARDS_DIRECTORY = "codex-app";
213
+ var LAUNCHCTL = "/bin/launchctl";
214
+ var LAUNCHER_NAME = "codex";
215
+ var RECEIPT_NAME = "turned-on.json";
216
+ var TURNED_OFF_NAME = "turned-off";
217
+ var PRIVATE_DIRECTORY_MODE = 448;
218
+ var PRIVATE_PROGRAM_MODE = 448;
219
+ var PRIVATE_FILE_MODE = 384;
220
+ var LOGIN_ITEM_DIRECTORY_MODE = 493;
221
+ var LOGIN_ITEM_MODE = 420;
222
+ var MAC_APP_HELPER = "/Contents/Helpers/pushary-native-transcripts";
223
+ var TEMPORARY_NPX_FOLDER = "/_npx/";
224
+ var codexAppCardsPaths = (homeDir, uid) => {
225
+ const launcherDirectory = join2(homeDir, ".pushary", CODEX_APP_CARDS_DIRECTORY);
226
+ const loginItemDirectory = join2(homeDir, "Library", "LaunchAgents");
227
+ return {
228
+ launcherDirectory,
229
+ launcherPath: join2(launcherDirectory, LAUNCHER_NAME),
230
+ receiptPath: join2(launcherDirectory, RECEIPT_NAME),
231
+ turnedOffPath: join2(launcherDirectory, TURNED_OFF_NAME),
232
+ loginItemDirectory,
233
+ loginItemPath: join2(loginItemDirectory, `${CODEX_APP_CARDS_LOGIN_ITEM}.plist`),
234
+ loginItemTarget: `gui/${uid}/${CODEX_APP_CARDS_LOGIN_ITEM}`
235
+ };
236
+ };
237
+ var codexAppCardsLoginScript = (launcherPath, engine, entry) => [
238
+ `if [ -x ${shellQuoted(launcherPath)} ] && [ -x ${shellQuoted(engine)} ] && ${everyProgramFileIsThere(entry)}`,
239
+ `&& [ -z "$(${LAUNCHCTL} getenv ${CODEX_APP_LAUNCH_VARIABLE})" ];`,
240
+ `then ${LAUNCHCTL} setenv ${CODEX_APP_LAUNCH_VARIABLE} ${shellQuoted(launcherPath)}; fi`
241
+ ].join(" ");
242
+ var isTheMacAppsHelper = (entry) => entry.length > 0 && entry[0].endsWith(MAC_APP_HELPER);
243
+ var loginItemProgram = (launcherPath, engine, entry) => isTheMacAppsHelper(entry) ? [entry[0], CODEX_APP_LAUNCH_AT_LOGIN_VERB] : ["/bin/sh", "-c", codexAppCardsLoginScript(launcherPath, engine, entry)];
244
+ var LISTED_UNDER_THE_MAC_APP = ` <key>AssociatedBundleIdentifiers</key>
245
+ <array>
246
+ <string>${MAC_APP_BUNDLE_ID}</string>
247
+ </array>
248
+ `;
249
+ var propertyListString = (value) => ` <string>${xml(value)}</string>`;
250
+ var codexAppCardsLoginItem = (launcherPath, engine, entry) => `<?xml version="1.0" encoding="UTF-8"?>
251
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
252
+ <plist version="1.0">
253
+ <dict>
254
+ <key>Label</key>
255
+ <string>${CODEX_APP_CARDS_LOGIN_ITEM}</string>
256
+ ${isTheMacAppsHelper(entry) ? LISTED_UNDER_THE_MAC_APP : ""} <key>ProgramArguments</key>
257
+ <array>
258
+ ${loginItemProgram(launcherPath, engine, entry).map(propertyListString).join("\n")}
259
+ </array>
260
+ <key>RunAtLoad</key>
261
+ <true/>
262
+ </dict>
263
+ </plist>
264
+ `;
265
+ var isAString = (value) => typeof value === "string";
266
+ var codexAppCardsReceiptFrom = (contents) => {
267
+ if (contents === null) return null;
268
+ let parsed;
269
+ try {
270
+ parsed = JSON.parse(contents);
271
+ } catch {
272
+ return null;
273
+ }
274
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return null;
275
+ const { entry, app, engine } = parsed;
276
+ return Array.isArray(entry) && entry.length > 0 && entry.every(isAString) && isAString(app) && isAString(engine) ? { entry, app, engine } : null;
277
+ };
278
+ var codexAppCardsInstallation = (input) => {
279
+ const paths = codexAppCardsPaths(input.homeDir, input.uid);
280
+ return {
281
+ paths,
282
+ launcherScript: desktopProxyScript(input.entry, input.app, input.engine, { turnsItselfOffWithoutTheEngine: true }),
283
+ loginItem: codexAppCardsLoginItem(paths.launcherPath, input.engine, input.entry),
284
+ receipt: { entry: input.entry, app: input.app, engine: input.engine }
285
+ };
286
+ };
287
+ var isAbsolutePath = (value) => value.startsWith("/");
288
+ var whatTheLauncherCannotRun = (receipt, machine) => {
289
+ if (receipt === null) return null;
290
+ if (!machine.exists(receipt.engine)) return { kind: "on_but_the_codex_engine_moved", engine: receipt.engine };
291
+ const missing = receipt.entry.filter(isAbsolutePath).find((path) => !machine.exists(path));
292
+ return missing === void 0 ? null : { kind: "on_but_pushary_is_missing", missing };
293
+ };
294
+ var codexAppCardsStatus = (paths, machine) => {
295
+ const value = machine.launchVariable();
296
+ if (value.length > 0 && value !== paths.launcherPath) return { kind: "another_program_owns_the_launch", value };
297
+ const launcherIsThere = machine.exists(paths.launcherPath);
298
+ const setForThisLogin = value === paths.launcherPath && launcherIsThere;
299
+ const setAtEveryLogin = launcherIsThere && machine.exists(paths.loginItemPath);
300
+ if (!setForThisLogin && !setAtEveryLogin) return { kind: "off" };
301
+ const cannotRun = whatTheLauncherCannotRun(codexAppCardsReceiptFrom(machine.readFile(paths.receiptPath)), machine);
302
+ if (cannotRun) return cannotRun;
303
+ if (setForThisLogin && setAtEveryLogin) return { kind: "on" };
304
+ return setForThisLogin ? { kind: "on_until_logout" } : { kind: "on_after_next_login" };
305
+ };
306
+ var turnCodexAppCardsOn = (installation, machine) => {
307
+ const { paths } = installation;
308
+ const value = machine.launchVariable();
309
+ if (value.length > 0 && value !== paths.launcherPath) return { kind: "another_program_owns_the_launch", value };
310
+ machine.makeDirectory(paths.launcherDirectory, PRIVATE_DIRECTORY_MODE);
311
+ machine.writeFile(paths.launcherPath, installation.launcherScript, PRIVATE_PROGRAM_MODE);
312
+ machine.writeFile(paths.receiptPath, `${JSON.stringify(installation.receipt, null, 2)}
313
+ `, PRIVATE_FILE_MODE);
314
+ if (machine.exists(paths.turnedOffPath)) machine.remove(paths.turnedOffPath);
315
+ machine.makeDirectory(paths.loginItemDirectory, LOGIN_ITEM_DIRECTORY_MODE);
316
+ machine.writeFile(paths.loginItemPath, installation.loginItem, LOGIN_ITEM_MODE);
317
+ machine.setLaunchVariable(paths.launcherPath);
318
+ return { kind: "on" };
319
+ };
320
+ var setCodexAppLaunchAtLogin = (paths, machine) => {
321
+ const isTurnedOn = machine.exists(paths.launcherPath) && machine.exists(paths.loginItemPath);
322
+ const cannotRun = whatTheLauncherCannotRun(codexAppCardsReceiptFrom(machine.readFile(paths.receiptPath)), machine);
323
+ if (!isTurnedOn || cannotRun !== null || machine.launchVariable().length > 0) return "left_as_it_is";
324
+ machine.setLaunchVariable(paths.launcherPath);
325
+ return "set";
326
+ };
327
+ var leaveOnlyThePathToTheEngine = (paths, machine) => {
328
+ const receipt = codexAppCardsReceiptFrom(machine.readFile(paths.receiptPath));
329
+ const launcher = machine.readFile(paths.launcherPath);
330
+ if (receipt === null || launcher === null) return;
331
+ const onlyThePathToTheEngine = codexPassThroughScript(receipt.engine);
332
+ if (launcher !== onlyThePathToTheEngine) machine.writeFile(paths.launcherPath, onlyThePathToTheEngine, PRIVATE_PROGRAM_MODE);
333
+ };
334
+ var turnCodexAppCardsOff = (paths, machine) => {
335
+ const value = machine.launchVariable();
336
+ const ours = value === paths.launcherPath;
337
+ const loginItemIsThere = machine.exists(paths.loginItemPath);
338
+ leaveOnlyThePathToTheEngine(paths, machine);
339
+ if (ours) machine.unsetLaunchVariable();
340
+ if (loginItemIsThere) {
341
+ machine.unloadLoginItem(paths.loginItemTarget);
342
+ machine.remove(paths.loginItemPath);
343
+ }
344
+ return { wasOn: ours || loginItemIsThere, launchLeftToAnotherProgram: value.length > 0 && !ours ? value : null };
345
+ };
346
+ var rememberCodexAppCardsWereTurnedOff = (paths, machine) => {
347
+ if (machine.exists(paths.turnedOffPath)) return;
348
+ machine.makeDirectory(paths.launcherDirectory, PRIVATE_DIRECTORY_MODE);
349
+ machine.writeFile(paths.turnedOffPath, "", PRIVATE_FILE_MODE);
350
+ };
351
+ var turnedOnByTheMacApp = (receipt) => receipt !== null && isTheMacAppsHelper(receipt.entry);
352
+ var codexAppCardsReport = (paths, machine) => ({
353
+ status: codexAppCardsStatus(paths, machine),
354
+ codexApp: machine.codexApp(),
355
+ turnedOnByTheMacApp: turnedOnByTheMacApp(codexAppCardsReceiptFrom(machine.readFile(paths.receiptPath))),
356
+ turnedOffOnPurpose: machine.exists(paths.turnedOffPath)
357
+ });
358
+ var isKeptOnForTheMacApp = (request, paths, machine) => request.keepWhatTheMacAppTurnedOn && turnedOnByTheMacApp(codexAppCardsReceiptFrom(machine.readFile(paths.receiptPath))) && codexAppCardsStatus(paths, machine).kind !== "off";
359
+ var isKeptOffForTheMacApp = (request, paths, machine) => request.keepWhatTheMacAppTurnedOn && machine.exists(paths.turnedOffPath);
360
+ var codexAppCardsFolderStays = (request, machine) => {
361
+ const paths = codexAppCardsPaths(request.homeDir, request.uid);
362
+ return isKeptOnForTheMacApp(request, paths, machine) || isKeptOffForTheMacApp(request, paths, machine);
363
+ };
364
+ var nothingIsTurnedOn = (paths, machine) => !machine.exists(paths.launcherPath) && !machine.exists(paths.loginItemPath) && machine.launchVariable() !== paths.launcherPath;
365
+ var removeCodexAppCards = (request, machine) => {
366
+ const paths = codexAppCardsPaths(request.homeDir, request.uid);
367
+ const keepsTheOff = isKeptOffForTheMacApp(request, paths, machine);
368
+ if (nothingIsTurnedOn(paths, machine)) {
369
+ if (!request.dryRun && !keepsTheOff && machine.exists(paths.launcherDirectory)) machine.remove(paths.launcherDirectory);
370
+ return "absent";
371
+ }
372
+ if (isKeptOnForTheMacApp(request, paths, machine)) return "kept_for_the_mac_app";
373
+ if (request.dryRun) return "removed";
374
+ turnCodexAppCardsOff(paths, machine);
375
+ machine.remove(paths.launcherDirectory);
376
+ if (keepsTheOff) rememberCodexAppCardsWereTurnedOff(paths, machine);
377
+ return "removed";
378
+ };
379
+ var launchctl = (args) => execFileSync2(LAUNCHCTL, [...args], { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
380
+ var launchctlIgnoringFailure = (args) => {
381
+ try {
382
+ return launchctl(args);
383
+ } catch {
384
+ return "";
385
+ }
386
+ };
387
+ var fileContents = (path) => {
388
+ try {
389
+ return readFileSync(path, "utf8");
390
+ } catch {
391
+ return null;
392
+ }
393
+ };
394
+ var thisMacsCodexAppCardsMachine = () => ({
395
+ codexApp: codexAppOnThisMac,
396
+ launchVariable: () => launchctlIgnoringFailure(["getenv", CODEX_APP_LAUNCH_VARIABLE]).trim(),
397
+ setLaunchVariable: (value) => {
398
+ launchctl(["setenv", CODEX_APP_LAUNCH_VARIABLE, value]);
399
+ },
400
+ unsetLaunchVariable: () => {
401
+ launchctl(["unsetenv", CODEX_APP_LAUNCH_VARIABLE]);
402
+ },
403
+ unloadLoginItem: (target) => {
404
+ launchctlIgnoringFailure(["bootout", target]);
405
+ },
406
+ exists: existsSync2,
407
+ readFile: fileContents,
408
+ makeDirectory: (path, mode) => {
409
+ mkdirSync(path, { recursive: true, mode });
410
+ },
411
+ writeFile: (path, contents, mode) => {
412
+ writeFileAtomic(path, contents, mode);
413
+ },
414
+ remove: (path) => {
415
+ rmSync(path, { recursive: true, force: true });
416
+ }
417
+ });
418
+ var removeCodexAppCardsFromThisMac = (request) => removeCodexAppCards(request, thisMacsCodexAppCardsMachine());
419
+ var codexAppCardsFolderStaysOnThisMac = (request) => codexAppCardsFolderStays(request, thisMacsCodexAppCardsMachine());
420
+ var setCodexAppLaunchAtLoginOnThisMac = () => {
421
+ const uid = process.getuid?.();
422
+ if (uid === void 0) return;
423
+ setCodexAppLaunchAtLogin(codexAppCardsPaths(homedir2(), uid), thisMacsCodexAppCardsMachine());
424
+ };
425
+ var USAGE = "Usage: pushary codex --app-cards on [path/to/Codex.app] | off | status [--json]";
426
+ var AS_JSON = "--json";
427
+ var TAKES_EFFECT_AFTER_REOPENING = "Quit Codex and open it again.";
428
+ var TURN_THEM_ON_AGAIN = "Run the same command with on to repair it.";
429
+ var runsFromATemporaryFolder = (entry) => entry.some((part) => part.includes(TEMPORARY_NPX_FOLDER));
430
+ var ownedByAnotherProgram = (value) => `Another program already starts the Codex app through ${value}. Pushary did not change it.`;
431
+ var codexAppCardsStatusLine = (status) => {
432
+ switch (status.kind) {
433
+ case "on":
434
+ return "Codex app cards are on.";
435
+ case "off":
436
+ return "Codex app cards are off.";
437
+ case "on_until_logout":
438
+ return "Codex app cards are on until you log out. Turn them on again to keep them on.";
439
+ case "on_after_next_login":
440
+ return "Codex app cards start the next time you log in. Turn them on again to start now.";
441
+ case "on_but_pushary_is_missing":
442
+ return `Codex app cards are on, but no card can reach Pushary: ${status.missing} is gone. Codex itself works. ${TURN_THEM_ON_AGAIN}`;
443
+ case "on_but_the_codex_engine_moved":
444
+ return `Codex app cards are on, but the Codex engine is no longer at ${status.engine}. ${TURN_THEM_ON_AGAIN}`;
445
+ case "another_program_owns_the_launch":
446
+ return ownedByAnotherProgram(status.value);
447
+ }
448
+ };
449
+ var codexAppCardsCommand = async (args, entry, readAccount, machine, say) => {
450
+ const [action, chosenApp, ...rest] = args;
451
+ const uid = process.getuid?.();
452
+ if (uid === void 0) throw new Error("Codex app cards need macOS");
453
+ const paths = codexAppCardsPaths(homedir2(), uid);
454
+ if (action === "status" && chosenApp === AS_JSON && rest.length === 0) {
455
+ say(JSON.stringify(codexAppCardsReport(paths, machine)));
456
+ return 0;
457
+ }
458
+ if (action === "status" && chosenApp === void 0) {
459
+ say(codexAppCardsStatusLine(codexAppCardsStatus(paths, machine)));
460
+ return 0;
461
+ }
462
+ if (action === "off" && chosenApp === void 0) {
463
+ const turnedOff = turnCodexAppCardsOff(paths, machine);
464
+ if (!isTheMacAppsHelper(entry)) rememberCodexAppCardsWereTurnedOff(paths, machine);
465
+ say(turnedOff.wasOn ? `Codex app cards are off. ${TAKES_EFFECT_AFTER_REOPENING}` : "Codex app cards were already off.");
466
+ if (turnedOff.launchLeftToAnotherProgram) say(ownedByAnotherProgram(turnedOff.launchLeftToAnotherProgram));
467
+ return 0;
468
+ }
469
+ if (action !== "on" || rest.length > 0 || chosenApp?.startsWith("--")) throw new Error(USAGE);
470
+ if (!await readAccount()) throw new Error("Connect Pushary before turning Codex app cards on");
471
+ const app = installedCodexApp(chosenApp);
472
+ const engine = await desktopEngine(app);
473
+ const turnedOn = turnCodexAppCardsOn(codexAppCardsInstallation({ homeDir: homedir2(), uid, entry, app, engine }), machine);
474
+ if (turnedOn.kind === "another_program_owns_the_launch") {
475
+ say(ownedByAnotherProgram(turnedOn.value));
476
+ return 1;
477
+ }
478
+ say(`Codex app cards are on. ${TAKES_EFFECT_AFTER_REOPENING}`);
479
+ say("From then on, when Codex asks to use an app on this Mac, the question also reaches Pushary. Everything else in Codex stays as it is.");
480
+ say("Turn them off by running the same command with off.");
481
+ if (runsFromATemporaryFolder(entry)) say("This copy of Pushary runs from a temporary npx folder. If that folder is cleared, the cards stop reaching Pushary and Codex keeps working. Install Pushary with npm install -g pushary and turn them on again to make it last.");
482
+ return 0;
483
+ };
484
+ var sayToThePerson = (line) => {
485
+ writeHuman(`${line}
486
+ `);
487
+ };
488
+ var codexAppCardsCommandOnThisMac = (args, entry, readAccount) => codexAppCardsCommand(args, entry, readAccount, thisMacsCodexAppCardsMachine(), sayToThePerson);
489
+
490
+ export {
491
+ MAC_APP_BUNDLE_ID,
492
+ installedPusharyBundles,
493
+ LSREGISTER,
494
+ developerDefaults,
495
+ registeredPusharyBundles,
496
+ MAC_KEYCHAIN_ACCOUNTS,
497
+ MAC_DEFAULTS_DOMAINS,
498
+ liveMacStatePresence,
499
+ storedMacAppState,
500
+ storedPusharyKeychainServices,
501
+ runningMacAppPIDs,
502
+ waitForMacAppExit,
503
+ CODEX_APP_CARDS_LOGIN_ITEM,
504
+ CODEX_APP_CARDS_DIRECTORY,
505
+ codexAppCardsPaths,
506
+ codexAppCardsLoginScript,
507
+ codexAppCardsLoginItem,
508
+ codexAppCardsReceiptFrom,
509
+ codexAppCardsInstallation,
510
+ codexAppCardsStatus,
511
+ turnCodexAppCardsOn,
512
+ setCodexAppLaunchAtLogin,
513
+ turnCodexAppCardsOff,
514
+ rememberCodexAppCardsWereTurnedOff,
515
+ codexAppCardsReport,
516
+ codexAppCardsFolderStays,
517
+ removeCodexAppCards,
518
+ removeCodexAppCardsFromThisMac,
519
+ codexAppCardsFolderStaysOnThisMac,
520
+ setCodexAppLaunchAtLoginOnThisMac,
521
+ runsFromATemporaryFolder,
522
+ codexAppCardsStatusLine,
523
+ codexAppCardsCommand,
524
+ codexAppCardsCommandOnThisMac
525
+ };
@@ -3,26 +3,32 @@ import {
3
3
  CODEX_APP_CARDS_LOGIN_ITEM,
4
4
  codexAppCardsCommand,
5
5
  codexAppCardsCommandOnThisMac,
6
+ codexAppCardsFolderStays,
7
+ codexAppCardsFolderStaysOnThisMac,
6
8
  codexAppCardsInstallation,
7
9
  codexAppCardsLoginItem,
8
10
  codexAppCardsLoginScript,
9
11
  codexAppCardsPaths,
10
12
  codexAppCardsReceiptFrom,
13
+ codexAppCardsReport,
11
14
  codexAppCardsStatus,
12
15
  codexAppCardsStatusLine,
16
+ rememberCodexAppCardsWereTurnedOff,
13
17
  removeCodexAppCards,
14
18
  removeCodexAppCardsFromThisMac,
15
19
  runsFromATemporaryFolder,
20
+ setCodexAppLaunchAtLogin,
21
+ setCodexAppLaunchAtLoginOnThisMac,
16
22
  turnCodexAppCardsOff,
17
23
  turnCodexAppCardsOn
18
- } from "./chunk-OHSHDQZF.js";
19
- import "./chunk-DMJFW4KL.js";
24
+ } from "./chunk-ZWOWEXCV.js";
25
+ import "./chunk-T5L5NWT3.js";
20
26
  import "./chunk-XCEN33UP.js";
21
27
  import "./chunk-QCGNGEGE.js";
22
28
  import "./chunk-BL3WAGIK.js";
23
29
  import "./chunk-XHKBHWLX.js";
24
30
  import "./chunk-VYBH6D4X.js";
25
- import "./chunk-36NGFHE4.js";
31
+ import "./chunk-E46NE7FB.js";
26
32
  import "./chunk-T6RIKJUO.js";
27
33
  import "./chunk-4QQEUJL4.js";
28
34
  import "./chunk-OML4YFBN.js";
@@ -37,16 +43,22 @@ export {
37
43
  CODEX_APP_CARDS_LOGIN_ITEM,
38
44
  codexAppCardsCommand,
39
45
  codexAppCardsCommandOnThisMac,
46
+ codexAppCardsFolderStays,
47
+ codexAppCardsFolderStaysOnThisMac,
40
48
  codexAppCardsInstallation,
41
49
  codexAppCardsLoginItem,
42
50
  codexAppCardsLoginScript,
43
51
  codexAppCardsPaths,
44
52
  codexAppCardsReceiptFrom,
53
+ codexAppCardsReport,
45
54
  codexAppCardsStatus,
46
55
  codexAppCardsStatusLine,
56
+ rememberCodexAppCardsWereTurnedOff,
47
57
  removeCodexAppCards,
48
58
  removeCodexAppCardsFromThisMac,
49
59
  runsFromATemporaryFolder,
60
+ setCodexAppLaunchAtLogin,
61
+ setCodexAppLaunchAtLoginOnThisMac,
50
62
  turnCodexAppCardsOff,
51
63
  turnCodexAppCardsOn
52
64
  };