@pushary/agent-hooks 1.4.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/bin/pushary-bell-hook.js +18 -18
- package/dist/bin/pushary-bell.js +6 -6
- package/dist/bin/pushary-claude.js +18 -18
- package/dist/bin/pushary-clean.js +154 -137
- package/dist/bin/pushary-codex-bridge.js +10 -10
- package/dist/bin/pushary-codex-hook.js +22 -22
- package/dist/bin/pushary-codex.js +6 -6
- package/dist/bin/pushary-connect.js +6 -6
- package/dist/bin/pushary-cowork.js +3 -3
- package/dist/bin/pushary-daemon.js +22 -22
- package/dist/bin/pushary-disconnect.js +10 -10
- package/dist/bin/pushary-doctor.js +20 -20
- package/dist/bin/pushary-elicitation-hook.js +17 -17
- package/dist/bin/pushary-gemini-bridge.js +9 -9
- package/dist/bin/pushary-gemini-hook.js +19 -19
- package/dist/bin/pushary-hook.js +23 -23
- package/dist/bin/pushary-login.js +7 -7
- package/dist/bin/pushary-logout.js +4 -4
- package/dist/bin/pushary-mode.js +3 -3
- package/dist/bin/pushary-notification-hook.js +20 -20
- package/dist/bin/pushary-opencode-hook.js +19 -19
- package/dist/bin/pushary-permission-denied-hook.js +24 -24
- package/dist/bin/pushary-permission-hook.js +23 -23
- package/dist/bin/pushary-post-hook.js +20 -20
- package/dist/bin/pushary-prompt-hook.js +20 -20
- package/dist/bin/pushary-session-end-hook.js +20 -20
- package/dist/bin/pushary-session-start-hook.js +22 -22
- package/dist/bin/pushary-setup.js +26 -26
- package/dist/bin/pushary-stats.js +2 -2
- package/dist/bin/pushary-status.js +10 -10
- package/dist/bin/pushary-stop-hook.js +20 -20
- package/dist/bin/pushary-stopfailure-hook.js +20 -20
- package/dist/bin/pushary-transcript-register.js +16 -16
- package/dist/bin/pushary-transcripts.js +4 -4
- package/dist/bin/pushary-upgrade.js +14 -14
- package/dist/bin/pushary-wait.js +3 -3
- package/dist/{chunk-S3CLZSV3.js → chunk-2GMI6JH6.js} +5 -5
- package/dist/{chunk-NBCTKC4Z.js → chunk-37VLIYLI.js} +4 -4
- package/dist/{chunk-RGZY77CD.js → chunk-3BPB2HYZ.js} +3 -3
- package/dist/{chunk-RQM5SMMR.js → chunk-3T52B2OF.js} +1 -1
- package/dist/{chunk-O5L2OJBB.js → chunk-3UA6FPRC.js} +3 -3
- package/dist/{chunk-2TOTCUJC.js → chunk-43JKGLZZ.js} +2 -2
- package/dist/{chunk-ZIGGEKZW.js → chunk-4FN6VV56.js} +2 -2
- package/dist/{chunk-JCWCTBYH.js → chunk-ALFT7H5B.js} +3 -3
- package/dist/{chunk-VENQSVKA.js → chunk-BZBUPZC6.js} +1 -1
- package/dist/{chunk-S3EUZZJB.js → chunk-CRNAXFQ6.js} +1 -1
- package/dist/{chunk-GS5EI2YL.js → chunk-D7ERHWYB.js} +1 -1
- package/dist/{chunk-A7XIL2WD.js → chunk-ED5TA2FJ.js} +3 -3
- package/dist/{chunk-7IEB2GV4.js → chunk-FVKFDTN6.js} +1 -0
- package/dist/{chunk-43Z3RLS5.js → chunk-GOFDGTEI.js} +6 -6
- package/dist/{chunk-XJWMPQ6X.js → chunk-HK3IXIQJ.js} +1 -1
- package/dist/{chunk-HGN6VZTY.js → chunk-HQLAZWJJ.js} +5 -5
- package/dist/{chunk-UIN3RD2U.js → chunk-I6HRQOMT.js} +4 -4
- package/dist/{chunk-7PQZYCEP.js → chunk-JOVWYVSR.js} +1 -1
- package/dist/{chunk-P4JVVJ2D.js → chunk-K6I5M2ME.js} +1 -1
- package/dist/{chunk-UTYTPDWN.js → chunk-KEMEBTCJ.js} +4 -4
- package/dist/{chunk-GLPWCQ6V.js → chunk-KI36MAT6.js} +2 -2
- package/dist/{chunk-IF46POXX.js → chunk-LNGYW6G4.js} +4 -4
- package/dist/{chunk-SGZ3IAWF.js → chunk-LUT2EZLG.js} +1 -1
- package/dist/{chunk-YYRZPEMA.js → chunk-LYXX5NSB.js} +1 -1
- package/dist/{chunk-BYAXXBNO.js → chunk-MN3XOVRK.js} +1 -1
- package/dist/{chunk-GIXLZFEY.js → chunk-PHHGHHOW.js} +1 -1
- package/dist/{chunk-D4TNSUDY.js → chunk-QBS6LGEK.js} +1 -1
- package/dist/{chunk-5MSBI6NP.js → chunk-R3AMKNIW.js} +1 -1
- package/dist/{chunk-U4FB623J.js → chunk-S3EP4B35.js} +2 -2
- package/dist/{chunk-UCGQEAKZ.js → chunk-SAF6NNXY.js} +1 -1
- package/dist/{chunk-H25UB3CG.js → chunk-SKXLIVFM.js} +1 -1
- package/dist/{chunk-5F5QQMCA.js → chunk-SWFF5U2N.js} +1 -1
- package/dist/{chunk-O6RN46OS.js → chunk-TF4IOINR.js} +3 -3
- package/dist/{chunk-NYHNLMQO.js → chunk-TI3ZWXZG.js} +1 -1
- package/dist/{chunk-ESLLVHDY.js → chunk-TNS3YLFE.js} +6 -6
- package/dist/{chunk-Q4UAMWXK.js → chunk-VYUDGQM7.js} +1 -1
- package/dist/{chunk-KZIXHLPQ.js → chunk-WEO5JCB4.js} +1 -1
- package/dist/{chunk-5IBVIMWT.js → chunk-WIOXWUUH.js} +3 -3
- package/dist/{reapply-B3S2LRMT.js → reapply-BAWDJTG7.js} +8 -8
- package/dist/src/index.js +12 -12
- package/package.json +1 -1
|
@@ -7,14 +7,14 @@ import {
|
|
|
7
7
|
createGuards,
|
|
8
8
|
resolveHermesPython,
|
|
9
9
|
runHermesPythonScript
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-37VLIYLI.js";
|
|
11
11
|
import "../chunk-P32LPT2L.js";
|
|
12
12
|
import {
|
|
13
13
|
removeInstructionBlock,
|
|
14
14
|
shortenHome,
|
|
15
15
|
unregisterPluginLocation,
|
|
16
16
|
vscodeSettingsTargets
|
|
17
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-3UA6FPRC.js";
|
|
18
18
|
import {
|
|
19
19
|
OPENCODE_PLUGIN_SIBLING,
|
|
20
20
|
OPENCODE_PLUGIN_SIBLING_CONTENTS,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
openCodePluginDir,
|
|
25
25
|
openCodePluginFile,
|
|
26
26
|
removeOpenCodeMcpServer
|
|
27
|
-
} from "../chunk-
|
|
27
|
+
} from "../chunk-VYUDGQM7.js";
|
|
28
28
|
import {
|
|
29
29
|
compatibleConfigFile,
|
|
30
30
|
compatibleInstructionsFile,
|
|
@@ -32,40 +32,40 @@ import {
|
|
|
32
32
|
compatiblePermissionRuleFile,
|
|
33
33
|
removeCompatibleHooks,
|
|
34
34
|
removeCompatibleMcpServer
|
|
35
|
-
} from "../chunk-
|
|
35
|
+
} from "../chunk-HQLAZWJJ.js";
|
|
36
36
|
import {
|
|
37
37
|
isClaudeMcpSnapshot,
|
|
38
38
|
removeClaudeMcpServers,
|
|
39
39
|
removePusharySettings,
|
|
40
40
|
removePusharyToolPermissions,
|
|
41
41
|
restoreClaudeMcpServer
|
|
42
|
-
} from "../chunk-
|
|
42
|
+
} from "../chunk-WIOXWUUH.js";
|
|
43
43
|
import {
|
|
44
44
|
hookOwnerOf,
|
|
45
45
|
isHookTakeoverReceipt,
|
|
46
46
|
restoreHookTakeover,
|
|
47
47
|
restoreMcpServer
|
|
48
|
-
} from "../chunk-
|
|
49
|
-
import "../chunk-
|
|
48
|
+
} from "../chunk-KEMEBTCJ.js";
|
|
49
|
+
import "../chunk-R3AMKNIW.js";
|
|
50
50
|
import {
|
|
51
51
|
liveBridgeProbe,
|
|
52
52
|
resolveBridgeStub
|
|
53
|
-
} from "../chunk-
|
|
53
|
+
} from "../chunk-LYXX5NSB.js";
|
|
54
54
|
import {
|
|
55
55
|
pusharyHookExecutable
|
|
56
|
-
} from "../chunk-
|
|
56
|
+
} from "../chunk-TF4IOINR.js";
|
|
57
57
|
import {
|
|
58
58
|
disableDaemonService
|
|
59
|
-
} from "../chunk-
|
|
59
|
+
} from "../chunk-3BPB2HYZ.js";
|
|
60
60
|
import {
|
|
61
61
|
removeGeminiSettings
|
|
62
|
-
} from "../chunk-
|
|
63
|
-
import "../chunk-
|
|
62
|
+
} from "../chunk-ED5TA2FJ.js";
|
|
63
|
+
import "../chunk-JOVWYVSR.js";
|
|
64
64
|
import "../chunk-XHKBHWLX.js";
|
|
65
|
-
import "../chunk-
|
|
66
|
-
import "../chunk-
|
|
65
|
+
import "../chunk-LNGYW6G4.js";
|
|
66
|
+
import "../chunk-WEO5JCB4.js";
|
|
67
67
|
import "../chunk-LGXUGYUH.js";
|
|
68
|
-
import "../chunk-
|
|
68
|
+
import "../chunk-3T52B2OF.js";
|
|
69
69
|
import {
|
|
70
70
|
bridgeAgentKey,
|
|
71
71
|
claudeJson,
|
|
@@ -94,7 +94,7 @@ import {
|
|
|
94
94
|
restoreCodexHookTrust,
|
|
95
95
|
vscodePluginDir,
|
|
96
96
|
vscodePluginMcp
|
|
97
|
-
} from "../chunk-
|
|
97
|
+
} from "../chunk-SAF6NNXY.js";
|
|
98
98
|
import {
|
|
99
99
|
exitOnHelpFlag
|
|
100
100
|
} from "../chunk-TWWLVOPB.js";
|
|
@@ -107,14 +107,14 @@ import {
|
|
|
107
107
|
CANDIDATE_RCS,
|
|
108
108
|
isDisabledExport,
|
|
109
109
|
removeClaudeAlias
|
|
110
|
-
} from "../chunk-
|
|
110
|
+
} from "../chunk-TI3ZWXZG.js";
|
|
111
111
|
import "../chunk-EYRGBYZG.js";
|
|
112
112
|
import "../chunk-SAF6HGAA.js";
|
|
113
113
|
import "../chunk-7QLSKOSU.js";
|
|
114
114
|
import {
|
|
115
115
|
EXIT
|
|
116
116
|
} from "../chunk-KZERVKTD.js";
|
|
117
|
-
import "../chunk-
|
|
117
|
+
import "../chunk-K6I5M2ME.js";
|
|
118
118
|
import "../chunk-T7E75EKA.js";
|
|
119
119
|
import "../chunk-2UMNXADU.js";
|
|
120
120
|
import {
|
|
@@ -123,18 +123,19 @@ import {
|
|
|
123
123
|
HOOK_LOCATOR_BINARY,
|
|
124
124
|
SUPPORT_DISCORD,
|
|
125
125
|
SUPPORT_EMAIL,
|
|
126
|
-
isValidApiKey
|
|
127
|
-
|
|
126
|
+
isValidApiKey,
|
|
127
|
+
redactSecrets
|
|
128
|
+
} from "../chunk-FVKFDTN6.js";
|
|
128
129
|
|
|
129
130
|
// bin/pushary-clean.ts
|
|
130
|
-
import { existsSync as
|
|
131
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4, copyFileSync, readdirSync as readdirSync3 } from "fs";
|
|
131
132
|
import { dirname, join as join5 } from "path";
|
|
132
133
|
import { homedir as homedir5, tmpdir } from "os";
|
|
133
134
|
import { confirm } from "@inquirer/prompts";
|
|
134
135
|
import { parse as parseTOML, stringify as stringifyTOML } from "smol-toml";
|
|
135
136
|
|
|
136
137
|
// src/cli/mac-leftovers.ts
|
|
137
|
-
import { execSync } from "child_process";
|
|
138
|
+
import { execSync, execFileSync } from "child_process";
|
|
138
139
|
import { existsSync } from "fs";
|
|
139
140
|
import { homedir } from "os";
|
|
140
141
|
import { join } from "path";
|
|
@@ -209,21 +210,16 @@ var pusharyKeychainServices = (dump) => {
|
|
|
209
210
|
return [...found];
|
|
210
211
|
};
|
|
211
212
|
var storedPusharyKeychainServices = () => {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
return stored.includes(MAC_KEYCHAIN_SERVICE) ? stored : [MAC_KEYCHAIN_SERVICE, ...stored];
|
|
221
|
-
} catch {
|
|
222
|
-
return [MAC_KEYCHAIN_SERVICE];
|
|
223
|
-
}
|
|
213
|
+
const dump = execFileSync("security", ["dump-keychain"], {
|
|
214
|
+
encoding: "utf-8",
|
|
215
|
+
timeout: 3e4,
|
|
216
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
217
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
218
|
+
});
|
|
219
|
+
const stored = pusharyKeychainServices(dump);
|
|
220
|
+
return stored.includes(MAC_KEYCHAIN_SERVICE) ? stored : [MAC_KEYCHAIN_SERVICE, ...stored];
|
|
224
221
|
};
|
|
225
222
|
var MAC_APP_BUNDLE_ID = "com.pushary.app";
|
|
226
|
-
var QUIT_MAC_APP = `osascript -e 'tell application id "${MAC_APP_BUNDLE_ID}" to quit'`;
|
|
227
223
|
var runningMacAppPIDs = () => {
|
|
228
224
|
if (process.platform !== "darwin") return [];
|
|
229
225
|
try {
|
|
@@ -245,8 +241,83 @@ var waitForMacAppExit = (attempts = 20, everyMs = 250) => {
|
|
|
245
241
|
return runningMacAppPIDs().length === 0;
|
|
246
242
|
};
|
|
247
243
|
|
|
244
|
+
// src/cli/clean-mac.ts
|
|
245
|
+
import { existsSync as existsSync2 } from "fs";
|
|
246
|
+
var removeDeveloperLeftovers = (guards2, domains, bundles) => {
|
|
247
|
+
let removed = 0;
|
|
248
|
+
for (const domain of domains) {
|
|
249
|
+
try {
|
|
250
|
+
guards2.execFile("defaults", ["delete", domain], { stdio: "ignore", timeout: 1e4 }, `delete preferences ${domain}`);
|
|
251
|
+
removed++;
|
|
252
|
+
} catch {
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
for (const bundle of bundles) {
|
|
257
|
+
try {
|
|
258
|
+
guards2.execFile(LSREGISTER, ["-u", bundle], { stdio: "ignore", timeout: 2e4 }, `unregister ${bundle}`);
|
|
259
|
+
removed++;
|
|
260
|
+
} catch {
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return removed;
|
|
265
|
+
};
|
|
266
|
+
var removeMacAppState = (guards2, readServices, home) => {
|
|
267
|
+
let removed = 0;
|
|
268
|
+
let failed = 0;
|
|
269
|
+
let services;
|
|
270
|
+
try {
|
|
271
|
+
services = readServices();
|
|
272
|
+
} catch {
|
|
273
|
+
return { removed, failed: 1 };
|
|
274
|
+
}
|
|
275
|
+
for (const service of services) {
|
|
276
|
+
for (const account of MAC_KEYCHAIN_ACCOUNTS) {
|
|
277
|
+
try {
|
|
278
|
+
guards2.execFile(
|
|
279
|
+
"security",
|
|
280
|
+
["delete-generic-password", "-s", service, "-a", account],
|
|
281
|
+
{ stdio: "ignore" },
|
|
282
|
+
`remove keychain item ${service} (${account})`
|
|
283
|
+
);
|
|
284
|
+
removed++;
|
|
285
|
+
} catch (error) {
|
|
286
|
+
if (!(error instanceof Error && "status" in error && error.status === 44)) failed++;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
for (const domain of MAC_DEFAULTS_DOMAINS) {
|
|
291
|
+
try {
|
|
292
|
+
guards2.execFile("defaults", ["delete", domain], { stdio: "ignore", timeout: 1e4 }, `delete preferences ${domain}`);
|
|
293
|
+
removed++;
|
|
294
|
+
} catch {
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
for (const path of macLibraryState(home)) {
|
|
299
|
+
if (!existsSync2(path)) continue;
|
|
300
|
+
guards2.remove(path, { force: true });
|
|
301
|
+
removed++;
|
|
302
|
+
}
|
|
303
|
+
return { removed, failed };
|
|
304
|
+
};
|
|
305
|
+
var quitMacApp = (guards2, state) => {
|
|
306
|
+
if (state.platform !== "darwin" || state.running().length === 0) return "not-running";
|
|
307
|
+
try {
|
|
308
|
+
guards2.execFile(
|
|
309
|
+
"osascript",
|
|
310
|
+
["-e", `tell application id "${MAC_APP_BUNDLE_ID}" to quit`],
|
|
311
|
+
{ stdio: "ignore", timeout: 3e4 },
|
|
312
|
+
"quit Pushary"
|
|
313
|
+
);
|
|
314
|
+
} catch {
|
|
315
|
+
}
|
|
316
|
+
return state.dryRun || state.waitForExit() ? "quit" : "running";
|
|
317
|
+
};
|
|
318
|
+
|
|
248
319
|
// src/cli/editor-extension.ts
|
|
249
|
-
import { existsSync as
|
|
320
|
+
import { existsSync as existsSync3, readFileSync, readdirSync } from "fs";
|
|
250
321
|
import { homedir as homedir2 } from "os";
|
|
251
322
|
import { join as join2 } from "path";
|
|
252
323
|
var EDITOR_EXTENSION_ID = "pushary.pushary";
|
|
@@ -273,13 +344,13 @@ var recordWithoutUs = (directory) => {
|
|
|
273
344
|
return void 0;
|
|
274
345
|
}
|
|
275
346
|
};
|
|
276
|
-
var editorExtensionRemovals = (home = homedir2()) => EDITOR_EXTENSION_DIRS.map((relative) => join2(home, relative)).filter(
|
|
347
|
+
var editorExtensionRemovals = (home = homedir2()) => EDITOR_EXTENSION_DIRS.map((relative) => join2(home, relative)).filter(existsSync3).map((directory) => {
|
|
277
348
|
const folders = readdirSync(directory).filter((name) => name.startsWith(`${EDITOR_EXTENSION_ID}-`)).map((name) => join2(directory, name));
|
|
278
349
|
return { directory, folders, record: recordWithoutUs(directory) };
|
|
279
350
|
}).filter((removal) => removal.folders.length > 0 || removal.record !== void 0);
|
|
280
351
|
|
|
281
352
|
// src/cli/skills-store.ts
|
|
282
|
-
import { existsSync as
|
|
353
|
+
import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
|
|
283
354
|
import { homedir as homedir3 } from "os";
|
|
284
355
|
import { join as join3 } from "path";
|
|
285
356
|
var SKILLS_STORE_DIR = ".agents";
|
|
@@ -287,9 +358,12 @@ var LOCK_FILE = ".skill-lock.json";
|
|
|
287
358
|
var lockWithoutUs = (path) => {
|
|
288
359
|
try {
|
|
289
360
|
const lock = JSON.parse(readFileSync2(path, "utf-8"));
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
361
|
+
if (!lock || typeof lock !== "object" || Array.isArray(lock) || !("skills" in lock)) return void 0;
|
|
362
|
+
const entries = lock.skills;
|
|
363
|
+
if (!entries || typeof entries !== "object" || Array.isArray(entries) || !(PUSHARY_SKILL_NAME in entries)) return void 0;
|
|
364
|
+
const entry = entries[PUSHARY_SKILL_NAME];
|
|
365
|
+
if (!entry || typeof entry !== "object" || !("source" in entry) || entry.source !== PUSHARY_SKILL_SOURCE) return void 0;
|
|
366
|
+
const { [PUSHARY_SKILL_NAME]: _ours, ...skills } = entries;
|
|
293
367
|
return { path, contents: `${JSON.stringify({ ...lock, skills }, null, 2)}
|
|
294
368
|
` };
|
|
295
369
|
} catch {
|
|
@@ -299,22 +373,23 @@ var lockWithoutUs = (path) => {
|
|
|
299
373
|
var skillsStoreRemoval = (home = homedir3()) => {
|
|
300
374
|
const store = join3(home, SKILLS_STORE_DIR);
|
|
301
375
|
const skillDir = join3(store, "skills", PUSHARY_SKILL_NAME);
|
|
376
|
+
const lock = lockWithoutUs(join3(store, LOCK_FILE));
|
|
302
377
|
return {
|
|
303
|
-
skillDir:
|
|
304
|
-
lock
|
|
378
|
+
skillDir: lock && existsSync4(skillDir) ? skillDir : void 0,
|
|
379
|
+
lock
|
|
305
380
|
};
|
|
306
381
|
};
|
|
307
382
|
|
|
308
383
|
// src/cli/claude-backups.ts
|
|
309
|
-
import { existsSync as
|
|
384
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3, readdirSync as readdirSync2 } from "fs";
|
|
310
385
|
import { homedir as homedir4 } from "os";
|
|
311
386
|
import { join as join4 } from "path";
|
|
312
387
|
var BACKUP_PREFIX = ".claude.json.backup";
|
|
313
388
|
var claudeJsonBackups = (home = homedir4()) => {
|
|
314
389
|
const rollingDir = join4(home, ".claude", "backups");
|
|
315
390
|
const legacy = join4(home, BACKUP_PREFIX);
|
|
316
|
-
const rolling =
|
|
317
|
-
return
|
|
391
|
+
const rolling = existsSync5(rollingDir) ? readdirSync2(rollingDir).filter((name) => name.startsWith(BACKUP_PREFIX)).sort().map((name) => join4(rollingDir, name)) : [];
|
|
392
|
+
return existsSync5(legacy) ? [...rolling, legacy] : rolling;
|
|
318
393
|
};
|
|
319
394
|
var parsed = (path) => {
|
|
320
395
|
try {
|
|
@@ -414,69 +489,6 @@ var wouldNote = (action, path) => {
|
|
|
414
489
|
var guards = createGuards(() => dryRun, wouldNote);
|
|
415
490
|
var guardedWrite = (path, contents) => guards.write(path, contents);
|
|
416
491
|
var guardedRemove = (path, options) => guards.remove(path, options);
|
|
417
|
-
var guardedExec = (command, options, describe) => guards.exec(command, options ?? {}, describe);
|
|
418
|
-
var removeDeveloperLeftovers = () => {
|
|
419
|
-
if (process.platform !== "darwin") return 0;
|
|
420
|
-
let removed = 0;
|
|
421
|
-
for (const domain of leakedTestDefaultsDomains()) {
|
|
422
|
-
const command = `defaults delete ${JSON.stringify(domain)}`;
|
|
423
|
-
try {
|
|
424
|
-
guardedExec(command, { stdio: "ignore", timeout: 1e4 }, command);
|
|
425
|
-
removed++;
|
|
426
|
-
} catch {
|
|
427
|
-
continue;
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
for (const bundle of registeredPusharyBundles()) {
|
|
431
|
-
const command = `${LSREGISTER} -u ${JSON.stringify(bundle)}`;
|
|
432
|
-
try {
|
|
433
|
-
guardedExec(command, { stdio: "ignore", timeout: 2e4 }, command);
|
|
434
|
-
removed++;
|
|
435
|
-
} catch {
|
|
436
|
-
continue;
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
return removed;
|
|
440
|
-
};
|
|
441
|
-
var removeMacAppState = () => {
|
|
442
|
-
if (process.platform !== "darwin") return 0;
|
|
443
|
-
let removed = 0;
|
|
444
|
-
for (const service of storedPusharyKeychainServices()) {
|
|
445
|
-
for (const account of MAC_KEYCHAIN_ACCOUNTS) {
|
|
446
|
-
const command = `security delete-generic-password -s ${JSON.stringify(service)} -a ${account}`;
|
|
447
|
-
try {
|
|
448
|
-
guardedExec(command, { stdio: "ignore", timeout: 1e4 }, command);
|
|
449
|
-
removed++;
|
|
450
|
-
} catch {
|
|
451
|
-
continue;
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
for (const domain of MAC_DEFAULTS_DOMAINS) {
|
|
456
|
-
const command = `defaults delete ${JSON.stringify(domain)}`;
|
|
457
|
-
try {
|
|
458
|
-
guardedExec(command, { stdio: "ignore", timeout: 1e4 }, command);
|
|
459
|
-
removed++;
|
|
460
|
-
} catch {
|
|
461
|
-
continue;
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
for (const path of macLibraryState(homedir5())) {
|
|
465
|
-
if (!existsSync5(path)) continue;
|
|
466
|
-
guardedRemove(path, { force: true });
|
|
467
|
-
removed++;
|
|
468
|
-
}
|
|
469
|
-
return removed;
|
|
470
|
-
};
|
|
471
|
-
var quitMacApp = () => {
|
|
472
|
-
if (process.platform !== "darwin") return "not-running";
|
|
473
|
-
if (runningMacAppPIDs().length === 0) return "not-running";
|
|
474
|
-
try {
|
|
475
|
-
guardedExec(QUIT_MAC_APP, { stdio: "ignore", timeout: 3e4 }, QUIT_MAC_APP);
|
|
476
|
-
} catch {
|
|
477
|
-
}
|
|
478
|
-
return dryRun || waitForMacAppExit() ? "quit" : "running";
|
|
479
|
-
};
|
|
480
492
|
var CURSOR_PLUGIN_STAGING = ".pushary-staging-";
|
|
481
493
|
var cursorPluginLeftovers = () => {
|
|
482
494
|
const parent = dirname(CURSOR_PLUGIN_DIR);
|
|
@@ -496,14 +508,14 @@ var guardedDaemonRemoval = async () => {
|
|
|
496
508
|
};
|
|
497
509
|
var guardedInstructionBlockRemoval = (path) => {
|
|
498
510
|
if (!dryRun) return removeInstructionBlock(path);
|
|
499
|
-
if (!
|
|
511
|
+
if (!existsSync6(path)) return false;
|
|
500
512
|
const hasBlock = readFileSync4(path, "utf-8").includes("pushary");
|
|
501
513
|
if (hasBlock) wouldNote("rewrite", path);
|
|
502
514
|
return hasBlock;
|
|
503
515
|
};
|
|
504
516
|
var guardedAliasRemoval = () => {
|
|
505
517
|
if (!dryRun) return removeClaudeAlias();
|
|
506
|
-
const shells = CANDIDATE_RCS.map((name) => join5(homedir5(), name)).filter((path) =>
|
|
518
|
+
const shells = CANDIDATE_RCS.map((name) => join5(homedir5(), name)).filter((path) => existsSync6(path) && readFileSync4(path, "utf-8").includes("pushary claude"));
|
|
507
519
|
for (const path of shells) wouldNote("rewrite", path);
|
|
508
520
|
return shells;
|
|
509
521
|
};
|
|
@@ -511,7 +523,7 @@ var writeJson = (path, data) => {
|
|
|
511
523
|
guardedWrite(path, JSON.stringify(data, null, 2) + "\n");
|
|
512
524
|
};
|
|
513
525
|
var removeCursorUserHook = (scope) => {
|
|
514
|
-
if (!
|
|
526
|
+
if (!existsSync6(CURSOR_USER_HOOKS)) return "absent";
|
|
515
527
|
let parsed2;
|
|
516
528
|
try {
|
|
517
529
|
parsed2 = JSON.parse(readFileSync4(CURSOR_USER_HOOKS, "utf-8"));
|
|
@@ -585,11 +597,11 @@ var restoreTakeoverReceipts = () => {
|
|
|
585
597
|
];
|
|
586
598
|
for (const [agent, hookFile, mcpFile, mcpKey, mcpFormat] of targets) {
|
|
587
599
|
const receiptPath = hookTakeoverReceipt(agent);
|
|
588
|
-
if (!
|
|
600
|
+
if (!existsSync6(receiptPath)) continue;
|
|
589
601
|
try {
|
|
590
602
|
const receipt = readJson(receiptPath);
|
|
591
603
|
if (!isHookTakeoverReceipt(receipt) || receipt.agent !== agent) throw new Error("invalid receipt");
|
|
592
|
-
const document =
|
|
604
|
+
const document = existsSync6(hookFile) ? JSON.parse(readFileSync4(hookFile, "utf-8")) : {};
|
|
593
605
|
if (!document || typeof document !== "object" || Array.isArray(document)) throw new Error("invalid hooks file");
|
|
594
606
|
const appAlreadyOwns = hookOwnerOf(document) === "app";
|
|
595
607
|
const cliPositions = agent === "codex" ? codexHookPositions(document) : {};
|
|
@@ -600,7 +612,7 @@ var restoreTakeoverReceipts = () => {
|
|
|
600
612
|
if (mcpFile === hookFile) {
|
|
601
613
|
mcpDocument = document;
|
|
602
614
|
} else {
|
|
603
|
-
const raw =
|
|
615
|
+
const raw = existsSync6(mcpFile) ? readFileSync4(mcpFile, "utf-8") : "";
|
|
604
616
|
mcpDocument = raw.trim() ? mcpFormat === "toml" ? parseTOML(raw) : JSON.parse(raw) : {};
|
|
605
617
|
}
|
|
606
618
|
mcpChanged = restoreMcpServer(mcpDocument, mcpKey, receipt.mcpServer);
|
|
@@ -610,7 +622,7 @@ var restoreTakeoverReceipts = () => {
|
|
|
610
622
|
if (!appAlreadyOwns && agent === "codex") {
|
|
611
623
|
if (!mcpDocument) {
|
|
612
624
|
const configPath = codexConfigToml();
|
|
613
|
-
const raw =
|
|
625
|
+
const raw = existsSync6(configPath) ? readFileSync4(configPath, "utf-8") : "";
|
|
614
626
|
mcpDocument = raw.trim() ? parseTOML(raw) : {};
|
|
615
627
|
}
|
|
616
628
|
codexConfig = mcpDocument;
|
|
@@ -679,18 +691,19 @@ var main = async () => {
|
|
|
679
691
|
console.log(` ${dim("Removing the Mac app's wiring and state as well.")}`);
|
|
680
692
|
}
|
|
681
693
|
if (everything) {
|
|
682
|
-
const quit = quitMacApp();
|
|
694
|
+
const quit = quitMacApp(guards, { platform: process.platform, dryRun, running: runningMacAppPIDs, waitForExit: waitForMacAppExit });
|
|
683
695
|
if (quit === "quit") {
|
|
684
696
|
console.log(` ${check} Pushary ${dim(did("quit"))} ${dim("(running, and its watcher puts back what this removes)")}`);
|
|
685
697
|
} else if (quit === "running") {
|
|
686
698
|
incompleteClean = true;
|
|
687
699
|
console.log(` ${cross} Pushary ${dim("would not quit, and it puts back what this removes")}`);
|
|
688
700
|
console.log(` ${dim("Quit it from the notch menu, then re-run.")}`);
|
|
701
|
+
process.exit(EXIT.FAILED);
|
|
689
702
|
}
|
|
690
703
|
}
|
|
691
704
|
if (presence !== "absent") console.log();
|
|
692
705
|
const restoredByTakeover = new Set(
|
|
693
|
-
["claude_code", "codex", "gemini_cli"].filter((agent) =>
|
|
706
|
+
["claude_code", "codex", "gemini_cli"].filter((agent) => existsSync6(hookTakeoverReceipt(agent)))
|
|
694
707
|
);
|
|
695
708
|
if (keepShared) restoreTakeoverReceipts();
|
|
696
709
|
const sharedMcpKeys = {
|
|
@@ -718,7 +731,7 @@ var main = async () => {
|
|
|
718
731
|
const claudeHadPusharyEntry = claudeHasPusharyEntry();
|
|
719
732
|
const rawReceipt = readJson(CLAUDE_MCP_RECEIPT);
|
|
720
733
|
const receipt = isClaudeMcpSnapshot(rawReceipt) ? rawReceipt : null;
|
|
721
|
-
const receiptUnreadable =
|
|
734
|
+
const receiptUnreadable = existsSync6(CLAUDE_MCP_RECEIPT) && !receipt;
|
|
722
735
|
if (keepClaudeMcp) {
|
|
723
736
|
console.log(` ${skip} Claude Code MCP servers ${dim("(kept: the Mac app uses it)")}`);
|
|
724
737
|
} else if (claudeJson2) {
|
|
@@ -733,7 +746,7 @@ var main = async () => {
|
|
|
733
746
|
if (receipt && !keepShared) incompleteClean = true;
|
|
734
747
|
console.log(` ${skip} Claude Code MCP servers ${dim(receipt ? "(changed after setup; left unchanged)" : "(no pushary entries)")}`);
|
|
735
748
|
}
|
|
736
|
-
} else if (
|
|
749
|
+
} else if (existsSync6(CLAUDE_MCP_RECEIPT)) {
|
|
737
750
|
incompleteClean = true;
|
|
738
751
|
console.log(` ${skip} Claude Code MCP servers ${dim("(config missing; setup receipt kept for retry)")}`);
|
|
739
752
|
} else {
|
|
@@ -777,7 +790,7 @@ var main = async () => {
|
|
|
777
790
|
}
|
|
778
791
|
if (cursorGate === "failed") {
|
|
779
792
|
console.log(` ${skip} Cursor plugin ${dim("(kept: removing it now would block matched commands)")}`);
|
|
780
|
-
} else if (
|
|
793
|
+
} else if (existsSync6(CURSOR_PLUGIN_DIR)) {
|
|
781
794
|
guardedRemove(CURSOR_PLUGIN_DIR);
|
|
782
795
|
console.log(` ${check} Cursor plugin ${dim("(removed from ~/.cursor/plugins/local)")}`);
|
|
783
796
|
} else {
|
|
@@ -793,9 +806,9 @@ var main = async () => {
|
|
|
793
806
|
if (keepShared) {
|
|
794
807
|
console.log(` ${skip} VS Code plugin ${dim("(kept: the Mac app writes the same plugin directory)")}`);
|
|
795
808
|
}
|
|
796
|
-
for (const settingsPath of keepShared ? [] : vscodeSettingsTargets(
|
|
809
|
+
for (const settingsPath of keepShared ? [] : vscodeSettingsTargets(existsSync6)) {
|
|
797
810
|
const label = `VS Code plugin ${dim(`(${shortenHome(settingsPath)})`)}`;
|
|
798
|
-
if (!
|
|
811
|
+
if (!existsSync6(settingsPath)) {
|
|
799
812
|
console.log(` ${skip} ${label} ${dim("(no settings.json)")}`);
|
|
800
813
|
continue;
|
|
801
814
|
}
|
|
@@ -809,7 +822,7 @@ var main = async () => {
|
|
|
809
822
|
console.log(` ${skip} ${label} ${dim("(no pushary entry)")}`);
|
|
810
823
|
}
|
|
811
824
|
}
|
|
812
|
-
if (!keepShared &&
|
|
825
|
+
if (!keepShared && existsSync6(VSCODE_PLUGIN_DIR)) {
|
|
813
826
|
guardedRemove(VSCODE_PLUGIN_DIR);
|
|
814
827
|
console.log(` ${check} VS Code plugin files ${dim(did("removed"))}`);
|
|
815
828
|
}
|
|
@@ -828,7 +841,7 @@ var main = async () => {
|
|
|
828
841
|
}
|
|
829
842
|
if (keepShared) {
|
|
830
843
|
console.log(` ${skip} Skill directory ${dim("(kept: the Mac app uses it)")}`);
|
|
831
|
-
} else if (
|
|
844
|
+
} else if (existsSync6(SKILL_DIR)) {
|
|
832
845
|
guardedRemove(SKILL_DIR);
|
|
833
846
|
console.log(` ${check} Skill directory ${dim(did("removed"))}`);
|
|
834
847
|
} else {
|
|
@@ -888,7 +901,7 @@ var main = async () => {
|
|
|
888
901
|
const codexSkillDir2 = codexSkillDir();
|
|
889
902
|
if (keepShared) {
|
|
890
903
|
console.log(` ${skip} Codex skill directory ${dim("(kept: the Mac app uses it)")}`);
|
|
891
|
-
} else if (
|
|
904
|
+
} else if (existsSync6(codexSkillDir2)) {
|
|
892
905
|
guardedRemove(codexSkillDir2);
|
|
893
906
|
console.log(` ${check} Codex skill directory ${dim(did("removed"))}`);
|
|
894
907
|
} else {
|
|
@@ -944,7 +957,7 @@ var main = async () => {
|
|
|
944
957
|
console.log(` ${skip} Gemini GEMINI.md ${dim("(no pushary block)")}`);
|
|
945
958
|
}
|
|
946
959
|
const openCodePlugin = openCodePluginFile();
|
|
947
|
-
const openCodePluginContents =
|
|
960
|
+
const openCodePluginContents = existsSync6(openCodePlugin) ? readFileSync4(openCodePlugin, "utf-8") : null;
|
|
948
961
|
if (openCodePluginContents === null) {
|
|
949
962
|
console.log(` ${skip} OpenCode plugin ${dim("(not installed)")}`);
|
|
950
963
|
} else if (!isOpenCodePluginOurs(openCodePluginContents)) {
|
|
@@ -962,7 +975,7 @@ var main = async () => {
|
|
|
962
975
|
return [];
|
|
963
976
|
}
|
|
964
977
|
})();
|
|
965
|
-
const siblingIsOurs =
|
|
978
|
+
const siblingIsOurs = existsSync6(sibling) && readFileSync4(sibling, "utf-8") === OPENCODE_PLUGIN_SIBLING_CONTENTS;
|
|
966
979
|
if (siblingIsOurs && !hasForeignPlugins(remaining)) {
|
|
967
980
|
guardedRemove(sibling, { force: true });
|
|
968
981
|
console.log(` ${check} OpenCode plugin sibling ${dim(did("removed"))}`);
|
|
@@ -990,14 +1003,14 @@ var main = async () => {
|
|
|
990
1003
|
} else {
|
|
991
1004
|
console.log(` ${check} Hermes config ${dim("(setup-owned changes restored)")}`);
|
|
992
1005
|
try {
|
|
993
|
-
|
|
1006
|
+
guards.execFile(hermesPython, ["-m", "pip", "uninstall", "-y", HERMES_PIP_PACKAGE], { stdio: "pipe", timeout: 6e4 }, `pip uninstall ${HERMES_PIP_PACKAGE}`);
|
|
994
1007
|
console.log(` ${check} Hermes plugin ${dim("(pip uninstalled)")}`);
|
|
995
1008
|
} catch {
|
|
996
1009
|
incompleteClean = true;
|
|
997
1010
|
console.log(` ${skip} Hermes plugin ${dim("(could not uninstall; setup receipt kept for retry)")}`);
|
|
998
1011
|
}
|
|
999
1012
|
}
|
|
1000
|
-
} else if (
|
|
1013
|
+
} else if (existsSync6(HERMES_CONFIG_RECEIPT)) {
|
|
1001
1014
|
incompleteClean = true;
|
|
1002
1015
|
console.log(` ${skip} Hermes ${dim("(runtime not found; setup receipt kept for retry)")}`);
|
|
1003
1016
|
} else {
|
|
@@ -1025,10 +1038,10 @@ var main = async () => {
|
|
|
1025
1038
|
if ((line.match(/pk_[A-Za-z0-9_]+\.[A-Za-z0-9_]+/g) ?? []).some(isValidApiKey)) {
|
|
1026
1039
|
incompleteClean = true;
|
|
1027
1040
|
console.log(` ${cross} ${name} ${dim("still sets PUSHARY_API_KEY, in a form this command will not rewrite:")}`);
|
|
1028
|
-
console.log(` ${dim(line.trim())}`);
|
|
1041
|
+
console.log(` ${dim(redactSecrets(line.trim()))}`);
|
|
1029
1042
|
console.log(` ${dim("Remove it yourself. A setup run would sign this machine in as that account.")}`);
|
|
1030
1043
|
} else {
|
|
1031
|
-
console.log(` ${skip} ${name} ${dim(`left a line referencing PUSHARY_API_KEY: ${line.trim()}`)}`);
|
|
1044
|
+
console.log(` ${skip} ${name} ${dim(`left a line referencing PUSHARY_API_KEY: ${redactSecrets(line.trim())}`)}`);
|
|
1032
1045
|
}
|
|
1033
1046
|
}
|
|
1034
1047
|
}
|
|
@@ -1041,7 +1054,7 @@ var main = async () => {
|
|
|
1041
1054
|
} else {
|
|
1042
1055
|
console.log(` ${skip} claude alias ${dim("(not set)")}`);
|
|
1043
1056
|
}
|
|
1044
|
-
if (
|
|
1057
|
+
if (existsSync6(PUSHARY_DIR)) {
|
|
1045
1058
|
let removed = 0;
|
|
1046
1059
|
const kept = [];
|
|
1047
1060
|
for (const entry of readdirSync3(PUSHARY_DIR)) {
|
|
@@ -1084,14 +1097,18 @@ var main = async () => {
|
|
|
1084
1097
|
if (store.skillDir || store.lock) {
|
|
1085
1098
|
console.log(` ${check} skills.sh registration ${dim(did("removed"))} ${dim("(~/.agents)")}`);
|
|
1086
1099
|
}
|
|
1087
|
-
const leftovers = removeDeveloperLeftovers();
|
|
1100
|
+
const leftovers = process.platform === "darwin" ? removeDeveloperLeftovers(guards, leakedTestDefaultsDomains(), registeredPusharyBundles()) : 0;
|
|
1088
1101
|
if (leftovers > 0) {
|
|
1089
1102
|
console.log(` ${check} Developer leftovers ${dim(did("removed"))} ${dim(`(${leftovers} leaked test preferences and stale app registrations)`)}`);
|
|
1090
1103
|
}
|
|
1091
|
-
const removed = removeMacAppState();
|
|
1104
|
+
const { removed, failed } = process.platform === "darwin" ? removeMacAppState(guards, storedPusharyKeychainServices, homedir5()) : { removed: 0, failed: 0 };
|
|
1105
|
+
if (failed > 0) {
|
|
1106
|
+
incompleteClean = true;
|
|
1107
|
+
console.log(` ${cross} Mac keychain ${dim(`(${failed} operations failed; unlock your keychain and re-run)`)}`);
|
|
1108
|
+
}
|
|
1092
1109
|
if (removed > 0) {
|
|
1093
1110
|
console.log(` ${check} Mac app state ${dim(did("removed"))} ${dim(`(${removed} keychain items, preferences and caches)`)}`);
|
|
1094
|
-
} else {
|
|
1111
|
+
} else if (failed === 0) {
|
|
1095
1112
|
console.log(` ${skip} Mac app state ${dim("(nothing of ours in the keychain, preferences or caches)")}`);
|
|
1096
1113
|
}
|
|
1097
1114
|
}
|
|
@@ -1112,7 +1129,7 @@ var main = async () => {
|
|
|
1112
1129
|
console.log(` ${dim("Still stuck? Send this output to")} ${SUPPORT_EMAIL} ${dim("or")} ${SUPPORT_DISCORD}`);
|
|
1113
1130
|
} else if (everything) {
|
|
1114
1131
|
console.log(` ${green(bold("Clean complete. Nothing of ours is left in any agent config."))}`);
|
|
1115
|
-
const bundle = installedPusharyBundles().find(
|
|
1132
|
+
const bundle = installedPusharyBundles().find(existsSync6);
|
|
1116
1133
|
if (bundle) {
|
|
1117
1134
|
console.log(` ${dim("The app itself is still installed. Drag")} ${bundle} ${dim("to the Trash to finish.")}`);
|
|
1118
1135
|
}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "../chunk-
|
|
2
|
+
import "../chunk-KI36MAT6.js";
|
|
3
3
|
import {
|
|
4
4
|
LiveTranscriptRelay,
|
|
5
5
|
liveSessionSleep,
|
|
6
6
|
postLiveSession,
|
|
7
7
|
postLiveSessionUntilAccepted,
|
|
8
8
|
startLiveSessionHeartbeat
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-SKXLIVFM.js";
|
|
10
10
|
import {
|
|
11
11
|
SESSION_IDLE_TIMEOUT_MS,
|
|
12
12
|
describeIdleWindow,
|
|
13
13
|
idleDeadlinePassed,
|
|
14
14
|
startProcessOwnership,
|
|
15
15
|
withSpawnProcessOwnership
|
|
16
|
-
} from "../chunk-
|
|
17
|
-
import "../chunk-
|
|
16
|
+
} from "../chunk-PHHGHHOW.js";
|
|
17
|
+
import "../chunk-CRNAXFQ6.js";
|
|
18
18
|
import "../chunk-EQRS3SGM.js";
|
|
19
19
|
import {
|
|
20
20
|
transcriptsEnabled
|
|
21
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-MN3XOVRK.js";
|
|
22
22
|
import {
|
|
23
23
|
spawnClaude
|
|
24
24
|
} from "../chunk-XHKBHWLX.js";
|
|
@@ -28,18 +28,18 @@ import {
|
|
|
28
28
|
} from "../chunk-LGXUGYUH.js";
|
|
29
29
|
import {
|
|
30
30
|
getMachineId
|
|
31
|
-
} from "../chunk-
|
|
31
|
+
} from "../chunk-3T52B2OF.js";
|
|
32
32
|
import {
|
|
33
33
|
resolveBinary
|
|
34
|
-
} from "../chunk-
|
|
35
|
-
import "../chunk-
|
|
34
|
+
} from "../chunk-SAF6NNXY.js";
|
|
35
|
+
import "../chunk-TI3ZWXZG.js";
|
|
36
36
|
import {
|
|
37
37
|
callMcpTool
|
|
38
38
|
} from "../chunk-EYRGBYZG.js";
|
|
39
39
|
import "../chunk-SAF6HGAA.js";
|
|
40
40
|
import "../chunk-7QLSKOSU.js";
|
|
41
41
|
import "../chunk-KZERVKTD.js";
|
|
42
|
-
import "../chunk-
|
|
42
|
+
import "../chunk-K6I5M2ME.js";
|
|
43
43
|
import "../chunk-T7E75EKA.js";
|
|
44
44
|
import {
|
|
45
45
|
getApiKey,
|
|
@@ -48,7 +48,7 @@ import {
|
|
|
48
48
|
import {
|
|
49
49
|
parseAgentQuestion,
|
|
50
50
|
parseAgentQuestionAnswers
|
|
51
|
-
} from "../chunk-
|
|
51
|
+
} from "../chunk-FVKFDTN6.js";
|
|
52
52
|
|
|
53
53
|
// bin/pushary-codex-bridge.ts
|
|
54
54
|
import { existsSync } from "fs";
|