@pushary/agent-hooks 1.8.2 → 1.9.0
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 +11 -0
- package/dist/bin/pushary-bell-hook.js +23 -23
- package/dist/bin/pushary-bell.js +9 -9
- package/dist/bin/pushary-claude.js +26 -26
- package/dist/bin/pushary-clean.js +28 -28
- package/dist/bin/pushary-codex-bridge.js +18 -18
- package/dist/bin/pushary-codex-hook.js +31 -31
- package/dist/bin/pushary-codex.js +13 -13
- package/dist/bin/pushary-connect.js +13 -13
- package/dist/bin/pushary-cowork.js +5 -5
- package/dist/bin/pushary-daemon.js +43 -40
- package/dist/bin/pushary-disconnect.js +18 -18
- package/dist/bin/pushary-doctor.js +30 -30
- package/dist/bin/pushary-elicitation-hook.js +25 -25
- package/dist/bin/pushary-gemini-bridge.js +13 -13
- package/dist/bin/pushary-gemini-hook.js +28 -28
- package/dist/bin/pushary-hook.js +32 -32
- package/dist/bin/pushary-login.js +12 -12
- package/dist/bin/pushary-logout.js +7 -7
- package/dist/bin/pushary-mcp.js +9 -9
- package/dist/bin/pushary-mode.js +9 -9
- package/dist/bin/pushary-notification-hook.js +28 -28
- package/dist/bin/pushary-opencode-hook.js +27 -27
- package/dist/bin/pushary-permission-denied-hook.js +32 -32
- package/dist/bin/pushary-permission-hook.js +31 -31
- package/dist/bin/pushary-post-hook.js +28 -28
- package/dist/bin/pushary-prompt-hook.js +28 -28
- package/dist/bin/pushary-session-end-hook.js +28 -28
- package/dist/bin/pushary-session-start-hook.js +31 -31
- package/dist/bin/pushary-setup.js +53 -38
- package/dist/bin/pushary-stats.js +5 -5
- package/dist/bin/pushary-status.js +15 -15
- package/dist/bin/pushary-stop-hook.js +28 -28
- package/dist/bin/pushary-stopfailure-hook.js +28 -28
- package/dist/bin/pushary-suggestions.js +4 -4
- package/dist/bin/pushary-transcript-register.js +19 -19
- package/dist/bin/pushary-transcripts.js +7 -7
- package/dist/bin/pushary-upgrade.js +223 -147
- package/dist/bin/pushary-wait.js +9 -9
- package/dist/bin/pushary.js +6 -6
- package/dist/{chunk-NHCUXTEM.js → chunk-2V64X5RE.js} +1 -1
- package/dist/{chunk-ZJYJAD52.js → chunk-3OFHFVPX.js} +1 -1
- package/dist/{chunk-F6NTWZZC.js → chunk-42E4DE6C.js} +9 -9
- package/dist/{chunk-INSMZNS7.js → chunk-4GMZOGH4.js} +10 -7
- package/dist/{chunk-5YY3IJT4.js → chunk-4PCF34AB.js} +17 -0
- package/dist/{chunk-7U7ZWUTR.js → chunk-4ZXYWEEH.js} +1 -1
- package/dist/{chunk-DVW2MYCM.js → chunk-75CEJ4WP.js} +3 -3
- package/dist/{chunk-DXBS2EL7.js → chunk-7LLNRCOK.js} +1 -1
- package/dist/{chunk-I3XLHSOC.js → chunk-7TQQSQZ7.js} +6 -6
- package/dist/{chunk-KB2FTO4O.js → chunk-BG4QCOHQ.js} +4 -4
- package/dist/{chunk-XQZEIWAV.js → chunk-CFAD2LTH.js} +54 -6
- package/dist/{chunk-MOTNSXC3.js → chunk-CKPDSFY3.js} +5 -5
- package/dist/{chunk-I4HKMUZQ.js → chunk-CPBRXBLG.js} +3 -3
- package/dist/{chunk-ON5JW2HP.js → chunk-EG46RJRF.js} +1 -1
- package/dist/{chunk-DLEKCAQL.js → chunk-ET6QSY3H.js} +1 -1
- package/dist/{chunk-NOLPURUI.js → chunk-HHNFGWR5.js} +1 -1
- package/dist/{chunk-NNWQ5VDB.js → chunk-HNMMKFYN.js} +10 -10
- package/dist/{chunk-N6JJJTPH.js → chunk-HQWPMVR4.js} +3 -3
- package/dist/{chunk-UMMCHS6P.js → chunk-HSM5FIA3.js} +1 -1
- package/dist/{chunk-7ITOAMCD.js → chunk-IJJ3HHFT.js} +1 -1
- package/dist/{chunk-CHMOVJ2M.js → chunk-IQUBCAEK.js} +1 -1
- package/dist/{chunk-HVDMGDYV.js → chunk-JOQEPWDH.js} +2 -2
- package/dist/{chunk-W2LJ4O3A.js → chunk-JW7DKTT6.js} +2 -2
- package/dist/{chunk-CB23AO4D.js → chunk-K75TP4JY.js} +2 -2
- package/dist/{chunk-LK2S5XIV.js → chunk-K7DY2DQN.js} +6 -6
- package/dist/{chunk-HMNR7B2F.js → chunk-KETBIX7I.js} +1 -1
- package/dist/{chunk-EIGJYCOE.js → chunk-LQESQPIT.js} +5 -5
- package/dist/{chunk-T55H6YEP.js → chunk-MBNMO5IR.js} +2 -2
- package/dist/{chunk-72WOCX22.js → chunk-MBVV3RX3.js} +1 -1
- package/dist/{chunk-URNXU3FO.js → chunk-MGXXQHCM.js} +1 -1
- package/dist/{chunk-644AEX4T.js → chunk-MQJWO3AA.js} +3 -3
- package/dist/{chunk-XEGVVU5H.js → chunk-NAJ3UV4E.js} +3 -3
- package/dist/{chunk-YNCGXHM4.js → chunk-OLG6FJV2.js} +4 -4
- package/dist/{chunk-EESPY5DG.js → chunk-OXQKXZJ3.js} +2 -2
- package/dist/{chunk-64H5IZZD.js → chunk-P25O4K3J.js} +2 -2
- package/dist/{chunk-2SLCHCVN.js → chunk-P6VDRQF3.js} +3 -3
- package/dist/{chunk-UPLV5AJF.js → chunk-R76C43H7.js} +58 -6
- package/dist/{chunk-HOEB6AKG.js → chunk-RZXQFAWR.js} +1 -1
- package/dist/{chunk-35X5UDML.js → chunk-SDSKTRIV.js} +1 -1
- package/dist/{chunk-MYHG7PX2.js → chunk-TUZ7WKOF.js} +1 -1
- package/dist/{chunk-5Y2DY6X4.js → chunk-US3RDXK7.js} +2 -2
- package/dist/{chunk-4A3UQERT.js → chunk-VV4SBPCQ.js} +1 -1
- package/dist/{chunk-VFFHQC7W.js → chunk-VYNTRHB6.js} +1 -1
- package/dist/{chunk-DUA5O6X5.js → chunk-WFVNXGZ6.js} +8 -8
- package/dist/{chunk-BDMC5H5L.js → chunk-XGS2DHGF.js} +2 -2
- package/dist/{chunk-B3UVRGYP.js → chunk-XXVMUMKT.js} +5 -5
- package/dist/{chunk-S2UNQQQS.js → chunk-YFS4HYCI.js} +3 -3
- package/dist/{chunk-5DGNEUXK.js → chunk-YJZDIFON.js} +2 -2
- package/dist/{chunk-MMVCI6DT.js → chunk-ZMVLKPT7.js} +5 -5
- package/dist/{chunk-TJMAXQ5Q.js → chunk-ZRHA4PGN.js} +2 -2
- package/dist/{reapply-3UERAKQN.js → reapply-FYCVOWCW.js} +8 -8
- package/dist/src/index.js +20 -20
- package/package.json +1 -1
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
describeCodexTrustConfirmation
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-7LLNRCOK.js";
|
|
5
5
|
import {
|
|
6
6
|
ensureCodexTrustAfterReapply,
|
|
7
7
|
reapplyAllAgents
|
|
8
|
-
} from "../chunk-
|
|
9
|
-
import "../chunk-
|
|
8
|
+
} from "../chunk-XXVMUMKT.js";
|
|
9
|
+
import "../chunk-JW7DKTT6.js";
|
|
10
10
|
import {
|
|
11
11
|
waitForMachineReadiness
|
|
12
|
-
} from "../chunk-
|
|
13
|
-
import "../chunk-
|
|
12
|
+
} from "../chunk-7TQQSQZ7.js";
|
|
13
|
+
import "../chunk-MQJWO3AA.js";
|
|
14
14
|
import {
|
|
15
15
|
detectProviderLiveCapabilities,
|
|
16
16
|
expectedLaunchCapabilities,
|
|
17
17
|
hasSpawnProvider,
|
|
18
18
|
resolveControlPolicy
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-CFAD2LTH.js";
|
|
20
20
|
import "../chunk-RIVNNBEK.js";
|
|
21
21
|
import {
|
|
22
22
|
AUTO_UPDATE_DISABLE_ENV,
|
|
@@ -28,8 +28,8 @@ import {
|
|
|
28
28
|
readAutoUpdateState,
|
|
29
29
|
updateAutoUpdateState,
|
|
30
30
|
upgradeEntryFor
|
|
31
|
-
} from "../chunk-
|
|
32
|
-
import "../chunk-
|
|
31
|
+
} from "../chunk-P25O4K3J.js";
|
|
32
|
+
import "../chunk-NAJ3UV4E.js";
|
|
33
33
|
import {
|
|
34
34
|
daemonHasRemoteProof,
|
|
35
35
|
daemonServiceManagerAvailable,
|
|
@@ -40,23 +40,23 @@ import {
|
|
|
40
40
|
replaceDaemonService,
|
|
41
41
|
stopDaemonService,
|
|
42
42
|
waitForDaemonRemoteProof
|
|
43
|
-
} from "../chunk-
|
|
44
|
-
import "../chunk-
|
|
43
|
+
} from "../chunk-LQESQPIT.js";
|
|
44
|
+
import "../chunk-YFS4HYCI.js";
|
|
45
45
|
import "../chunk-XHKBHWLX.js";
|
|
46
46
|
import "../chunk-6ICPEJY5.js";
|
|
47
|
-
import "../chunk-
|
|
47
|
+
import "../chunk-VYNTRHB6.js";
|
|
48
48
|
import "../chunk-POFBE6ZY.js";
|
|
49
49
|
import {
|
|
50
50
|
exitOnHelpFlag
|
|
51
|
-
} from "../chunk-
|
|
51
|
+
} from "../chunk-K75TP4JY.js";
|
|
52
52
|
import {
|
|
53
53
|
readControlMode
|
|
54
|
-
} from "../chunk-
|
|
55
|
-
import "../chunk-
|
|
54
|
+
} from "../chunk-ZRHA4PGN.js";
|
|
55
|
+
import "../chunk-VV4SBPCQ.js";
|
|
56
56
|
import {
|
|
57
57
|
EXIT
|
|
58
58
|
} from "../chunk-KZERVKTD.js";
|
|
59
|
-
import "../chunk-
|
|
59
|
+
import "../chunk-US3RDXK7.js";
|
|
60
60
|
import {
|
|
61
61
|
LATEST_TAG,
|
|
62
62
|
autoUpdateLock,
|
|
@@ -73,86 +73,61 @@ import {
|
|
|
73
73
|
readGlobalCliInstallAt,
|
|
74
74
|
readGlobalPrefix,
|
|
75
75
|
vscodePluginDir
|
|
76
|
-
} from "../chunk-
|
|
77
|
-
import
|
|
76
|
+
} from "../chunk-R76C43H7.js";
|
|
77
|
+
import {
|
|
78
|
+
writeJsonAtomic
|
|
79
|
+
} from "../chunk-T7E75EKA.js";
|
|
78
80
|
import {
|
|
79
81
|
getApiKey
|
|
80
|
-
} from "../chunk-
|
|
82
|
+
} from "../chunk-EG46RJRF.js";
|
|
81
83
|
import {
|
|
82
84
|
NPX_LATEST_COMMAND
|
|
83
|
-
} from "../chunk-
|
|
85
|
+
} from "../chunk-SDSKTRIV.js";
|
|
84
86
|
import {
|
|
85
87
|
CANONICAL_PACKAGE,
|
|
86
88
|
LEGACY_PACKAGE,
|
|
87
89
|
commandsPackage,
|
|
90
|
+
getPackageVersion,
|
|
88
91
|
globalUpgradeEntry,
|
|
89
92
|
isNewerVersion,
|
|
90
93
|
isReleaseVersion,
|
|
91
94
|
isSameMajorVersion,
|
|
92
95
|
ownPackageRoot,
|
|
93
96
|
packageVersionAt
|
|
94
|
-
} from "../chunk-
|
|
95
|
-
|
|
96
|
-
// bin/pushary-upgrade.ts
|
|
97
|
-
import { existsSync as existsSync2 } from "fs";
|
|
98
|
-
import { homedir } from "os";
|
|
99
|
-
import { join } from "path";
|
|
97
|
+
} from "../chunk-4PCF34AB.js";
|
|
100
98
|
|
|
101
|
-
// src/
|
|
102
|
-
import {
|
|
103
|
-
import {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
import {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
var
|
|
110
|
-
var
|
|
111
|
-
var
|
|
99
|
+
// src/upgrade-lock.ts
|
|
100
|
+
import { fork } from "child_process";
|
|
101
|
+
import { createHash } from "crypto";
|
|
102
|
+
import { existsSync, mkdirSync, readFileSync, realpathSync, unlinkSync } from "fs";
|
|
103
|
+
import { createServer, Server } from "net";
|
|
104
|
+
import { basename, dirname, join } from "path";
|
|
105
|
+
var LOCK_HOST = "127.0.0.1";
|
|
106
|
+
var LOCK_PORT_START = 49152;
|
|
107
|
+
var LOCK_PORT_COUNT = 16384;
|
|
108
|
+
var INHERITED_LOCK_ENV = "PUSHARY_UPGRADE_LOCK";
|
|
109
|
+
var LOCK_READY = "pushary-upgrade-lock-ready";
|
|
110
|
+
var LOCK_HANDLE = "pushary-upgrade-lock-handle";
|
|
111
|
+
var HANDOFF_TIMEOUT_MS = 1e4;
|
|
112
112
|
var FINISH_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
113
|
-
var
|
|
114
|
-
var
|
|
115
|
-
var
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
writeSync(handle, `${JSON.stringify({ pid: process.pid, at: new Date(now).toISOString() })}
|
|
122
|
-
`);
|
|
123
|
-
} finally {
|
|
124
|
-
closeSync(handle);
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
var tryCreateLock = (lockPath, now) => {
|
|
113
|
+
var KERNEL_LOCK_FORMAT = "kernel-v1";
|
|
114
|
+
var heldLocks = /* @__PURE__ */ new Map();
|
|
115
|
+
var canonicalLockPath = (path) => {
|
|
116
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
117
|
+
return join(realpathSync(dirname(path)), basename(path));
|
|
118
|
+
};
|
|
119
|
+
var lockPort = (path) => LOCK_PORT_START + createHash("sha256").update(path).digest().readUInt32BE(0) % LOCK_PORT_COUNT;
|
|
120
|
+
var readLockRecord = (path) => {
|
|
128
121
|
try {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
};
|
|
136
|
-
var isStaleLock = (lockPath, now) => {
|
|
137
|
-
const modifiedAt = statSync(lockPath, { throwIfNoEntry: false })?.mtimeMs;
|
|
138
|
-
return modifiedAt !== void 0 && now - modifiedAt > LOCK_STALE_MS;
|
|
139
|
-
};
|
|
140
|
-
var takeOverLock = (lockPath, now) => {
|
|
141
|
-
try {
|
|
142
|
-
unlinkSync(lockPath);
|
|
122
|
+
const value = JSON.parse(readFileSync(path, "utf8"));
|
|
123
|
+
const pid = value && typeof value === "object" && "pid" in value ? value.pid : void 0;
|
|
124
|
+
return {
|
|
125
|
+
pid: typeof pid === "number" && Number.isInteger(pid) && pid > 0 ? pid : void 0,
|
|
126
|
+
installationPending: value !== null && typeof value === "object" && "installationPending" in value && value.installationPending === true,
|
|
127
|
+
usesKernelLock: value !== null && typeof value === "object" && "format" in value && value.format === KERNEL_LOCK_FORMAT
|
|
128
|
+
};
|
|
143
129
|
} catch {
|
|
144
|
-
return
|
|
145
|
-
}
|
|
146
|
-
return tryCreateLock(lockPath, now);
|
|
147
|
-
};
|
|
148
|
-
var isAbandonedLock = (evidence) => evidence.stale || evidence.holderPid !== void 0 && !evidence.holderAlive;
|
|
149
|
-
var lockHolderPid = (lockPath) => {
|
|
150
|
-
try {
|
|
151
|
-
const holder = JSON.parse(readFileSync(lockPath, "utf8"));
|
|
152
|
-
const pid = holder && typeof holder === "object" && "pid" in holder ? holder.pid : void 0;
|
|
153
|
-
return typeof pid === "number" && Number.isInteger(pid) && pid > 0 ? pid : void 0;
|
|
154
|
-
} catch {
|
|
155
|
-
return void 0;
|
|
130
|
+
return { pid: void 0, usesKernelLock: false, installationPending: false };
|
|
156
131
|
}
|
|
157
132
|
};
|
|
158
133
|
var isProcessAlive = (pid) => {
|
|
@@ -160,54 +135,138 @@ var isProcessAlive = (pid) => {
|
|
|
160
135
|
process.kill(pid, 0);
|
|
161
136
|
return true;
|
|
162
137
|
} catch (error) {
|
|
163
|
-
return error instanceof Error && "code" in error && error.code === "
|
|
138
|
+
return !(error instanceof Error && "code" in error && error.code === "ESRCH");
|
|
164
139
|
}
|
|
165
140
|
};
|
|
166
|
-
var
|
|
167
|
-
|
|
168
|
-
return {
|
|
169
|
-
holderPid,
|
|
170
|
-
holderAlive: holderPid !== void 0 && isAlive(holderPid),
|
|
171
|
-
stale: isStaleLock(lockPath, now)
|
|
172
|
-
};
|
|
141
|
+
var rejectConnection = (socket) => {
|
|
142
|
+
socket.destroy();
|
|
173
143
|
};
|
|
174
|
-
var
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
144
|
+
var inheritLock = (path) => new Promise((resolve) => {
|
|
145
|
+
const done = (claim) => {
|
|
146
|
+
clearTimeout(timer);
|
|
147
|
+
process.off("message", receive);
|
|
148
|
+
process.off("disconnect", disconnected);
|
|
149
|
+
resolve(claim);
|
|
150
|
+
};
|
|
151
|
+
const disconnected = () => done({ kind: "unavailable", reason: "Upgrade parent disconnected before transferring its lock" });
|
|
152
|
+
const receive = (message, handle) => {
|
|
153
|
+
if (message !== LOCK_HANDLE || !(handle instanceof Server)) return;
|
|
154
|
+
const address = handle.address();
|
|
155
|
+
if (address === null || typeof address === "string" || address.port !== lockPort(path) || address.address !== LOCK_HOST) {
|
|
156
|
+
handle.close();
|
|
157
|
+
done({ kind: "unavailable", reason: "Invalid inherited upgrade lock" });
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
handle.on("connection", rejectConnection);
|
|
161
|
+
heldLocks.set(path, handle);
|
|
162
|
+
done({ kind: "inherited" });
|
|
163
|
+
process.disconnect?.();
|
|
164
|
+
};
|
|
165
|
+
const timer = setTimeout(() => done({ kind: "unavailable", reason: "Upgrade lock handoff timed out" }), HANDOFF_TIMEOUT_MS);
|
|
166
|
+
process.on("message", receive);
|
|
167
|
+
process.once("disconnect", disconnected);
|
|
168
|
+
if (!process.send || !process.connected) return disconnected();
|
|
169
|
+
process.send(LOCK_READY, (error) => {
|
|
170
|
+
if (error) disconnected();
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
var claimUpgradeLock = async (request = {}) => {
|
|
174
|
+
let server;
|
|
181
175
|
try {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
176
|
+
const path = canonicalLockPath(request.lockPath ?? autoUpdateLock());
|
|
177
|
+
const inheritedPath = process.env[INHERITED_LOCK_ENV];
|
|
178
|
+
delete process.env[INHERITED_LOCK_ENV];
|
|
179
|
+
if (inheritedPath === path && !heldLocks.has(path)) return await inheritLock(path);
|
|
180
|
+
server = createServer(rejectConnection);
|
|
181
|
+
const listener = server;
|
|
182
|
+
await new Promise((resolve, reject) => {
|
|
183
|
+
listener.once("error", reject);
|
|
184
|
+
listener.listen({ host: LOCK_HOST, port: lockPort(path), exclusive: true }, resolve);
|
|
185
|
+
});
|
|
186
|
+
const record = readLockRecord(path);
|
|
187
|
+
if (record.installationPending) {
|
|
188
|
+
server.close();
|
|
189
|
+
return { kind: "unavailable", reason: `An earlier installation did not finish safely. Stop its npm processes (or restart the computer), then remove ${path} and retry the upgrade.` };
|
|
190
|
+
}
|
|
191
|
+
if (existsSync(path) && !record.usesKernelLock && (record.pid === void 0 || (request.isAlive ?? isProcessAlive)(record.pid))) {
|
|
192
|
+
server.close();
|
|
193
|
+
return { kind: "held", holderPid: record.pid };
|
|
194
|
+
}
|
|
195
|
+
writeJsonAtomic(path, { pid: process.pid, format: KERNEL_LOCK_FORMAT }, 384);
|
|
196
|
+
heldLocks.set(path, server);
|
|
197
|
+
return { kind: "acquired" };
|
|
198
|
+
} catch (error) {
|
|
199
|
+
server?.close();
|
|
200
|
+
if (error instanceof Error && "code" in error && error.code === "EADDRINUSE") {
|
|
201
|
+
return { kind: "held", holderPid: readLockRecord(request.lockPath ?? autoUpdateLock()).pid };
|
|
202
|
+
}
|
|
203
|
+
return { kind: "unavailable", reason: npmErrorMessage(error) };
|
|
185
204
|
}
|
|
186
205
|
};
|
|
187
|
-
var
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
return
|
|
191
|
-
|
|
192
|
-
var claimUpgradeLockAt = (lockPath, request) => {
|
|
193
|
-
const now = request.now ?? Date.now();
|
|
194
|
-
mkdirSync(dirname(lockPath), { recursive: true });
|
|
195
|
-
if (tryCreateLock(lockPath, now) === "acquired") return { kind: "acquired" };
|
|
196
|
-
const holder = readLockHolder(lockPath, now, request.isAlive ?? isProcessAlive);
|
|
197
|
-
const verdict = upgradeLockVerdict({ ...holder, parentPid: request.parentPid ?? process.ppid });
|
|
198
|
-
if (verdict === "inherited") return { kind: "inherited" };
|
|
199
|
-
if (verdict === "take_over" && takeOverLock(lockPath, now) === "acquired") return { kind: "acquired" };
|
|
200
|
-
return { kind: "held", holderPid: holder.holderPid };
|
|
201
|
-
};
|
|
202
|
-
var claimUpgradeLock = (request = {}) => {
|
|
206
|
+
var releaseAutoUpdateLock = (lockPath) => {
|
|
207
|
+
const path = canonicalLockPath(lockPath);
|
|
208
|
+
const server = heldLocks.get(path);
|
|
209
|
+
if (!server) return;
|
|
210
|
+
heldLocks.delete(path);
|
|
203
211
|
try {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
212
|
+
const record = readLockRecord(path);
|
|
213
|
+
if (record.pid === process.pid && !record.installationPending) unlinkSync(path);
|
|
214
|
+
} finally {
|
|
215
|
+
server.close();
|
|
207
216
|
}
|
|
208
217
|
};
|
|
218
|
+
var finishWithUpgradeLock = (request) => new Promise((resolve, reject) => {
|
|
219
|
+
const path = canonicalLockPath(request.lockPath ?? autoUpdateLock());
|
|
220
|
+
const server = heldLocks.get(path);
|
|
221
|
+
if (!server) return reject(new Error("Cannot finish an upgrade without its lock"));
|
|
222
|
+
const child = fork(request.entry, [...request.args], {
|
|
223
|
+
execArgv: [],
|
|
224
|
+
stdio: request.stdio ?? ["inherit", "inherit", "inherit", "ipc"],
|
|
225
|
+
env: { ...process.env, ...request.env, [INHERITED_LOCK_ENV]: path }
|
|
226
|
+
});
|
|
227
|
+
const timer = setTimeout(() => child.kill("SIGKILL"), FINISH_TIMEOUT_MS);
|
|
228
|
+
child.on("message", (message) => {
|
|
229
|
+
if (message === LOCK_READY) child.send(LOCK_HANDLE, server, (error) => {
|
|
230
|
+
if (error) child.kill();
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
child.once("error", (error) => {
|
|
234
|
+
clearTimeout(timer);
|
|
235
|
+
reject(error);
|
|
236
|
+
});
|
|
237
|
+
child.once("exit", (code, signal) => {
|
|
238
|
+
clearTimeout(timer);
|
|
239
|
+
if (code === 0) resolve();
|
|
240
|
+
else reject(new Error(`Upgrade finish exited with ${signal ?? code}`));
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
var installWithUpgradeLock = (request, lockPath = autoUpdateLock(), runNpm) => {
|
|
244
|
+
const path = canonicalLockPath(lockPath);
|
|
245
|
+
if (!heldLocks.has(path)) throw new Error("Cannot install an upgrade without its lock");
|
|
246
|
+
writeJsonAtomic(path, { pid: process.pid, format: KERNEL_LOCK_FORMAT, installationPending: true }, 384);
|
|
247
|
+
installPackageGlobally(request, runNpm);
|
|
248
|
+
writeJsonAtomic(path, { pid: process.pid, format: KERNEL_LOCK_FORMAT }, 384);
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
// bin/pushary-upgrade.ts
|
|
252
|
+
import { existsSync as existsSync3 } from "fs";
|
|
253
|
+
import { homedir } from "os";
|
|
254
|
+
import { join as join2 } from "path";
|
|
255
|
+
|
|
256
|
+
// src/global-upgrade.ts
|
|
257
|
+
import { existsSync as existsSync2 } from "fs";
|
|
258
|
+
|
|
259
|
+
// src/auto-update-run.ts
|
|
260
|
+
import { closeSync, mkdirSync as mkdirSync2, openSync, statSync, writeSync } from "fs";
|
|
261
|
+
import { dirname as dirname2 } from "path";
|
|
262
|
+
var FINISH_UPGRADE_FLAG = "--finish-upgrade";
|
|
263
|
+
var INSTALL_TIMEOUT_MS = 12e4;
|
|
264
|
+
var LOG_LIMIT_BYTES = 256 * 1024;
|
|
265
|
+
var UNREADABLE_INSTALLED_VERSION = "could not read the installed version";
|
|
266
|
+
var UNREACHABLE_REGISTRY = "could not read the latest version from the npm registry";
|
|
267
|
+
var MANUAL_UPGRADE_COMMAND = `${NPX_LATEST_COMMAND} upgrade`;
|
|
209
268
|
var openAutoUpdateLog = (logPath) => {
|
|
210
|
-
|
|
269
|
+
mkdirSync2(dirname2(logPath), { recursive: true });
|
|
211
270
|
const size = statSync(logPath, { throwIfNoEntry: false })?.size ?? 0;
|
|
212
271
|
return openSync(logPath, size > LOG_LIMIT_BYTES ? "w" : "a");
|
|
213
272
|
};
|
|
@@ -224,13 +283,15 @@ var appendAutoUpdateLog = (logPath, line) => {
|
|
|
224
283
|
return;
|
|
225
284
|
}
|
|
226
285
|
};
|
|
227
|
-
var finishInNewInstall = (request) => {
|
|
286
|
+
var finishInNewInstall = async (request) => {
|
|
228
287
|
const handle = openAutoUpdateLog(request.logPath);
|
|
229
288
|
try {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
289
|
+
await finishWithUpgradeLock({
|
|
290
|
+
entry: request.entry,
|
|
291
|
+
args: [FINISH_UPGRADE_FLAG],
|
|
292
|
+
lockPath: request.lockPath,
|
|
293
|
+
stdio: ["ignore", handle, handle, "ipc"],
|
|
294
|
+
env: { npm_config_prefix: request.prefix }
|
|
234
295
|
});
|
|
235
296
|
} finally {
|
|
236
297
|
closeSync(handle);
|
|
@@ -238,11 +299,11 @@ var finishInNewInstall = (request) => {
|
|
|
238
299
|
};
|
|
239
300
|
var incompleteFinishDetail = (logPath) => `installed, but refreshing the agent configs did not finish cleanly; see ${logPath}`;
|
|
240
301
|
var newMajorDetail = (latest) => `${latest} is a new major version; run ${MANUAL_UPGRADE_COMMAND}`;
|
|
241
|
-
var finishInstalledUpgrade = (context, from, to) => {
|
|
302
|
+
var finishInstalledUpgrade = async (context, from, to) => {
|
|
242
303
|
const pending = { result: "finish_pending", from, to, detail: incompleteFinishDetail(context.logPath) };
|
|
243
304
|
recordAutoUpdateCheck(context.statePath, pending, new Date(context.now()).toISOString());
|
|
244
305
|
try {
|
|
245
|
-
context.finish({ entry: upgradeEntryFor(context.location), prefix: context.location.prefix, logPath: context.logPath });
|
|
306
|
+
await context.finish({ lockPath: context.lockPath, entry: upgradeEntryFor(context.location), prefix: context.location.prefix, logPath: context.logPath });
|
|
246
307
|
return { result: "updated", from, to };
|
|
247
308
|
} catch {
|
|
248
309
|
return pending;
|
|
@@ -265,14 +326,13 @@ var checkAndInstall = async (context) => {
|
|
|
265
326
|
}
|
|
266
327
|
appendAutoUpdateLog(context.logPath, `${new Date(context.now()).toISOString()} installing ${context.location.packageName}@${latest} into ${context.location.prefix}`);
|
|
267
328
|
try {
|
|
268
|
-
|
|
329
|
+
installWithUpgradeLock({
|
|
269
330
|
packageName: context.location.packageName,
|
|
270
331
|
version: latest,
|
|
271
332
|
prefix: context.location.prefix,
|
|
272
333
|
timeoutMs: INSTALL_TIMEOUT_MS
|
|
273
|
-
}, context.runNpm);
|
|
334
|
+
}, context.lockPath, context.runNpm);
|
|
274
335
|
} catch (error) {
|
|
275
|
-
if (pendingFinish) return finishInstalledUpgrade(context, previous.from, installed);
|
|
276
336
|
return { result: "failed", from: installed, to: latest, detail: npmErrorMessage(error) };
|
|
277
337
|
}
|
|
278
338
|
return finishInstalledUpgrade(context, installed, latest);
|
|
@@ -294,9 +354,17 @@ var runAutoUpdate = async (run = {}) => {
|
|
|
294
354
|
const now = run.now ?? Date.now;
|
|
295
355
|
const lockPath = run.lockPath ?? autoUpdateLock();
|
|
296
356
|
const logPath = run.logPath ?? autoUpdateLog();
|
|
297
|
-
|
|
357
|
+
const claim = await claimUpgradeLock({ lockPath });
|
|
358
|
+
if (claim.kind === "unavailable") {
|
|
359
|
+
const at = new Date(now()).toISOString();
|
|
360
|
+
const state = recordAutoUpdateCheck(run.statePath ?? autoUpdateState(), { result: "failed", detail: claim.reason }, at);
|
|
361
|
+
appendAutoUpdateLog(logPath, `${at} ${describeAutoUpdateCheck(state)}`);
|
|
362
|
+
return { kind: "recorded", state };
|
|
363
|
+
}
|
|
364
|
+
if (claim.kind !== "acquired") return { kind: "locked" };
|
|
298
365
|
try {
|
|
299
366
|
const check = await checkAndInstall({
|
|
367
|
+
lockPath,
|
|
300
368
|
packageRoot,
|
|
301
369
|
statePath: run.statePath ?? autoUpdateState(),
|
|
302
370
|
location,
|
|
@@ -327,14 +395,12 @@ var readGlobalUpgradeSubject = (platform = process.platform) => {
|
|
|
327
395
|
const prefix = readGlobalPrefix();
|
|
328
396
|
return globalUpgradeSubject(prefix, prefix === void 0 ? { kind: "unavailable" } : readGlobalCliInstallAt(prefix, platform));
|
|
329
397
|
};
|
|
330
|
-
var finishWithThisNode = (entry) => {
|
|
331
|
-
|
|
332
|
-
};
|
|
333
|
-
var finishGlobalUpgrade = (subject, platform = process.platform, runFinish = finishWithThisNode) => {
|
|
398
|
+
var finishWithThisNode = (entry) => finishWithUpgradeLock({ entry, args: [FINISH_UPGRADE_FLAG] });
|
|
399
|
+
var finishGlobalUpgrade = async (subject, platform = process.platform, runFinish = finishWithThisNode) => {
|
|
334
400
|
const entry = globalUpgradeEntry(subject.prefix, subject.name, platform);
|
|
335
|
-
if (!
|
|
401
|
+
if (!existsSync2(entry)) return { kind: "entry_missing", entry };
|
|
336
402
|
try {
|
|
337
|
-
runFinish(entry);
|
|
403
|
+
await runFinish(entry);
|
|
338
404
|
return { kind: "finished" };
|
|
339
405
|
} catch {
|
|
340
406
|
return { kind: "failed" };
|
|
@@ -342,22 +408,30 @@ var finishGlobalUpgrade = (subject, platform = process.platform, runFinish = fin
|
|
|
342
408
|
};
|
|
343
409
|
var describeHeldUpgradeLock = (holderPid) => `Another Pushary upgrade is already running${holderPid === void 0 ? "" : ` (pid ${holderPid})`}. Try again when it has finished.`;
|
|
344
410
|
var withUpgradeLock = async (run, request = {}) => {
|
|
345
|
-
const claim = claimUpgradeLock(request);
|
|
411
|
+
const claim = await claimUpgradeLock(request);
|
|
412
|
+
if (claim.kind === "unavailable") return { kind: "refused", exitCode: EXIT.FAILED, message: `Could not lock the Pushary upgrade: ${claim.reason}` };
|
|
346
413
|
if (claim.kind === "held") return { kind: "refused", exitCode: EXIT.FAILED, message: describeHeldUpgradeLock(claim.holderPid) };
|
|
347
414
|
try {
|
|
348
415
|
await run();
|
|
349
416
|
} finally {
|
|
350
|
-
|
|
417
|
+
releaseAutoUpdateLock(request.lockPath ?? autoUpdateLock());
|
|
351
418
|
}
|
|
352
419
|
return { kind: "ran" };
|
|
353
420
|
};
|
|
421
|
+
var finishUpgradeWithLock = async (run, request) => {
|
|
422
|
+
const outcome = await withUpgradeLock(run, request);
|
|
423
|
+
if (outcome.kind === "refused") {
|
|
424
|
+
updateAutoUpdateState(request.statePath, { lastResult: "finish_pending", to: request.installedVersion, detail: outcome.message });
|
|
425
|
+
}
|
|
426
|
+
return outcome;
|
|
427
|
+
};
|
|
354
428
|
var describeUpgradeStart = (subject, latest) => `Upgrading ${subject.name} ${subject.version} -> ${latest ?? "latest"}`;
|
|
355
429
|
var upgradeInstalledPackage = async (subject, effects) => {
|
|
356
430
|
const pendingFinish = effects.hasPendingFinish(subject.version);
|
|
357
431
|
const latest = await effects.fetchLatest(subject.name);
|
|
358
432
|
const newerPublished = latest !== void 0 && isNewerVersion(latest, subject.version);
|
|
359
433
|
if (pendingFinish && !newerPublished) {
|
|
360
|
-
const finish = effects.finish(subject);
|
|
434
|
+
const finish = await effects.finish(subject);
|
|
361
435
|
if (finish.kind !== "finished") return { kind: "pending_finish_failed", finish };
|
|
362
436
|
effects.recordFinished();
|
|
363
437
|
}
|
|
@@ -368,7 +442,7 @@ var upgradeInstalledPackage = async (subject, effects) => {
|
|
|
368
442
|
} catch (error) {
|
|
369
443
|
return { kind: "install_failed", detail: npmErrorMessage(error) };
|
|
370
444
|
}
|
|
371
|
-
return { kind: "installed", finish: effects.finish(subject) };
|
|
445
|
+
return { kind: "installed", finish: await effects.finish(subject) };
|
|
372
446
|
};
|
|
373
447
|
|
|
374
448
|
// bin/pushary-upgrade.ts
|
|
@@ -378,32 +452,32 @@ var detectInstallModes = () => {
|
|
|
378
452
|
{
|
|
379
453
|
label: "Cursor plugin",
|
|
380
454
|
upgrade: "updates itself through Cursor",
|
|
381
|
-
present:
|
|
455
|
+
present: existsSync3(cursorPluginDir())
|
|
382
456
|
},
|
|
383
457
|
{
|
|
384
458
|
label: "VS Code plugin",
|
|
385
459
|
upgrade: `${NPX_LATEST_COMMAND} setup --agents vscode`,
|
|
386
|
-
present:
|
|
460
|
+
present: existsSync3(vscodePluginDir())
|
|
387
461
|
},
|
|
388
462
|
{
|
|
389
463
|
label: "Codex config",
|
|
390
464
|
upgrade: `${NPX_LATEST_COMMAND} setup --agents codex`,
|
|
391
|
-
present:
|
|
465
|
+
present: existsSync3(codexConfigToml())
|
|
392
466
|
},
|
|
393
467
|
{
|
|
394
468
|
label: "Claude Code config",
|
|
395
469
|
upgrade: `${NPX_LATEST_COMMAND} setup --agents claude_code`,
|
|
396
|
-
present:
|
|
470
|
+
present: existsSync3(claudeJson())
|
|
397
471
|
},
|
|
398
472
|
{
|
|
399
473
|
label: "Gemini config",
|
|
400
474
|
upgrade: `${NPX_LATEST_COMMAND} setup --agents gemini_cli`,
|
|
401
|
-
present:
|
|
475
|
+
present: existsSync3(geminiSettings())
|
|
402
476
|
},
|
|
403
477
|
{
|
|
404
478
|
label: "Hermes plugin (pip)",
|
|
405
479
|
upgrade: `${NPX_LATEST_COMMAND} setup --agents hermes`,
|
|
406
|
-
present:
|
|
480
|
+
present: existsSync3(join2(homedir(), ".hermes"))
|
|
407
481
|
}
|
|
408
482
|
];
|
|
409
483
|
return candidates.filter((candidate) => candidate.present).map(({ label, upgrade }) => ({ label, upgrade }));
|
|
@@ -553,7 +627,7 @@ var upgradeSubject = async (subject) => {
|
|
|
553
627
|
updateAutoUpdateState(autoUpdateState(), { lastResult: "updated", detail: void 0, announced: false });
|
|
554
628
|
},
|
|
555
629
|
announce: (line) => console.log(line),
|
|
556
|
-
install: (packageName) =>
|
|
630
|
+
install: (packageName) => installWithUpgradeLock({ packageName, version: LATEST_TAG, timeoutMs: 12e4 }),
|
|
557
631
|
finish: (installedSubject) => finishGlobalUpgrade(installedSubject)
|
|
558
632
|
});
|
|
559
633
|
reportGlobalUpgrade(outcome);
|
|
@@ -571,15 +645,17 @@ var upgradeGlobalInstall = async () => {
|
|
|
571
645
|
}
|
|
572
646
|
await upgradeSubject(subject);
|
|
573
647
|
};
|
|
574
|
-
var
|
|
575
|
-
const locked = await withUpgradeLock(run);
|
|
648
|
+
var reportUpgradeLock = (locked) => {
|
|
576
649
|
if (locked.kind === "ran") return;
|
|
577
650
|
console.error(locked.message);
|
|
578
651
|
process.exitCode = locked.exitCode;
|
|
579
652
|
};
|
|
580
653
|
var main = async () => {
|
|
581
654
|
if (process.argv.includes(FINISH_UPGRADE_FLAG)) {
|
|
582
|
-
await
|
|
655
|
+
reportUpgradeLock(await finishUpgradeWithLock(finishUpgrade, {
|
|
656
|
+
installedVersion: getPackageVersion(),
|
|
657
|
+
statePath: autoUpdateState()
|
|
658
|
+
}));
|
|
583
659
|
return;
|
|
584
660
|
}
|
|
585
661
|
const autoFlag = parseAutoUpdateFlag(process.argv.slice(2));
|
|
@@ -596,6 +672,6 @@ var main = async () => {
|
|
|
596
672
|
await runAutomaticUpdate();
|
|
597
673
|
return;
|
|
598
674
|
}
|
|
599
|
-
await
|
|
675
|
+
reportUpgradeLock(await withUpgradeLock(upgradeGlobalInstall));
|
|
600
676
|
};
|
|
601
677
|
main();
|
package/dist/bin/pushary-wait.js
CHANGED
|
@@ -4,33 +4,33 @@ import {
|
|
|
4
4
|
} from "../chunk-CVWG2N3Y.js";
|
|
5
5
|
import {
|
|
6
6
|
exitOnFailedResponse
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-2V64X5RE.js";
|
|
8
8
|
import {
|
|
9
9
|
createIo
|
|
10
10
|
} from "../chunk-U4TMAANR.js";
|
|
11
11
|
import {
|
|
12
12
|
exitOnHelpFlag
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-K75TP4JY.js";
|
|
14
14
|
import {
|
|
15
15
|
rejectUnknownFlags
|
|
16
16
|
} from "../chunk-GMXKITVA.js";
|
|
17
|
-
import "../chunk-
|
|
18
|
-
import "../chunk-
|
|
19
|
-
import "../chunk-
|
|
17
|
+
import "../chunk-75CEJ4WP.js";
|
|
18
|
+
import "../chunk-P6VDRQF3.js";
|
|
19
|
+
import "../chunk-VV4SBPCQ.js";
|
|
20
20
|
import {
|
|
21
21
|
UsageError
|
|
22
22
|
} from "../chunk-7QLSKOSU.js";
|
|
23
23
|
import {
|
|
24
24
|
EXIT
|
|
25
25
|
} from "../chunk-KZERVKTD.js";
|
|
26
|
-
import "../chunk-
|
|
26
|
+
import "../chunk-R76C43H7.js";
|
|
27
27
|
import "../chunk-T7E75EKA.js";
|
|
28
28
|
import {
|
|
29
29
|
getApiKey,
|
|
30
30
|
getBaseUrl
|
|
31
|
-
} from "../chunk-
|
|
32
|
-
import "../chunk-
|
|
33
|
-
import "../chunk-
|
|
31
|
+
} from "../chunk-EG46RJRF.js";
|
|
32
|
+
import "../chunk-SDSKTRIV.js";
|
|
33
|
+
import "../chunk-4PCF34AB.js";
|
|
34
34
|
|
|
35
35
|
// bin/pushary-wait.ts
|
|
36
36
|
exitOnHelpFlag("wait");
|
package/dist/bin/pushary.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
installNetworkDefaults
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-P6VDRQF3.js";
|
|
5
|
+
import "../chunk-VV4SBPCQ.js";
|
|
6
6
|
import "../chunk-7QLSKOSU.js";
|
|
7
7
|
import {
|
|
8
8
|
EXIT
|
|
9
9
|
} from "../chunk-KZERVKTD.js";
|
|
10
|
-
import "../chunk-
|
|
10
|
+
import "../chunk-R76C43H7.js";
|
|
11
11
|
import "../chunk-T7E75EKA.js";
|
|
12
|
-
import "../chunk-
|
|
12
|
+
import "../chunk-EG46RJRF.js";
|
|
13
13
|
import {
|
|
14
14
|
COMMANDS,
|
|
15
15
|
isCommandName,
|
|
16
16
|
renderHelp
|
|
17
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-SDSKTRIV.js";
|
|
18
18
|
import {
|
|
19
19
|
getPackageVersion
|
|
20
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-4PCF34AB.js";
|
|
21
21
|
|
|
22
22
|
// src/cli/runtime.ts
|
|
23
23
|
var supportsRuntime = (version) => {
|