@pushary/agent-hooks 0.61.0 → 0.62.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 +48 -0
- package/dist/bin/pushary-claude.js +4 -4
- package/dist/bin/pushary-clean.js +62 -32
- package/dist/bin/pushary-codex-hook.js +4 -4
- package/dist/bin/pushary-codex.js +3 -3
- package/dist/bin/pushary-connect.js +6 -6
- package/dist/bin/pushary-daemon.js +37 -5
- package/dist/bin/pushary-doctor.js +113 -34
- package/dist/bin/pushary-gemini-hook.js +4 -4
- package/dist/bin/pushary-hook.js +5 -5
- package/dist/bin/pushary-login.js +4 -4
- package/dist/bin/pushary-logout.js +51 -9
- package/dist/bin/pushary-mode.js +4 -4
- package/dist/bin/pushary-notification-hook.js +2 -2
- package/dist/bin/pushary-permission-denied-hook.js +3 -3
- package/dist/bin/pushary-permission-hook.js +3 -3
- package/dist/bin/pushary-post-hook.js +2 -2
- package/dist/bin/pushary-prompt-hook.js +2 -2
- package/dist/bin/pushary-session-end-hook.js +2 -2
- package/dist/bin/pushary-session-start-hook.js +2 -2
- package/dist/bin/pushary-setup.js +92 -152
- package/dist/bin/pushary-stats.js +2 -2
- package/dist/bin/pushary-status.js +5 -5
- package/dist/bin/pushary-stop-hook.js +2 -2
- package/dist/bin/pushary-stopfailure-hook.js +2 -2
- package/dist/bin/pushary-suggestions.js +2 -2
- package/dist/bin/pushary-upgrade.js +176 -11
- package/dist/bin/pushary-wait.js +4 -4
- package/dist/bin/pushary.js +1 -1
- package/dist/{chunk-B26DNXCA.js → chunk-247C4RE5.js} +1 -0
- package/dist/{chunk-GX64YGU3.js → chunk-3O27ZSRE.js} +25 -0
- package/dist/{chunk-HI4AGGE6.js → chunk-5SO3CEGJ.js} +4 -4
- package/dist/chunk-E2U35RLD.js +108 -0
- package/dist/chunk-ER657KRJ.js +168 -0
- package/dist/{chunk-HUJQSP4F.js → chunk-IIZZYUWK.js} +1 -1
- package/dist/chunk-N7XJ4L2W.js +79 -0
- package/dist/{chunk-R6C4USIV.js → chunk-ONVEYEVR.js} +2 -2
- package/dist/{chunk-SML23YOT.js → chunk-SP7OZXCQ.js} +10 -2
- package/dist/chunk-UXXRRXUS.js +93 -0
- package/dist/{chunk-UKNAAVEE.js → chunk-YJ7YZRVV.js} +1 -1
- package/dist/src/index.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-S4TFBJ5O.js +0 -339
- package/dist/{chunk-VFBYRR2N.js → chunk-HIIBSYFJ.js} +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.62.0
|
|
4
|
+
|
|
5
|
+
### `pushary clean` could leave your API key on disk
|
|
6
|
+
|
|
7
|
+
If `CODEX_HOME` was set, `clean` looked for Codex's `config.toml` in `~/.codex`
|
|
8
|
+
and never found the real one. It printed `Codex config (not found)`, exited `0`,
|
|
9
|
+
and left the key in the file. A user who ran `clean` to remove their key was told
|
|
10
|
+
it had worked.
|
|
11
|
+
|
|
12
|
+
The same fault ran through the rest of the Codex path. With `CODEX_HOME` set:
|
|
13
|
+
|
|
14
|
+
- `setup` wrote the MCP server, the trust hashes and the notify entry to
|
|
15
|
+
`~/.codex/config.toml` while writing `hooks.json`, `AGENTS.md` and the skill to
|
|
16
|
+
the real `CODEX_HOME`, splitting the install across two directories
|
|
17
|
+
- `setup --dry-run` named the relocated path, so the preview and the real run
|
|
18
|
+
disagreed about where the key would land
|
|
19
|
+
- `doctor` read the relocated config and reported the key missing
|
|
20
|
+
- `logout` treated an exported-but-empty `CODEX_HOME` as a path relative to the
|
|
21
|
+
current directory
|
|
22
|
+
|
|
23
|
+
If you use `CODEX_HOME`, run `pushary clean --dry-run` to see what is still
|
|
24
|
+
there, and check `$CODEX_HOME/config.toml` for a key you thought was gone.
|
|
25
|
+
|
|
26
|
+
### New
|
|
27
|
+
|
|
28
|
+
- `pushary clean --dry-run` lists everything it would remove and changes nothing
|
|
29
|
+
- `pushary doctor --bundle` writes a redacted diagnostics file for a support
|
|
30
|
+
thread. Keys, your home directory and the machine name are stripped.
|
|
31
|
+
- `pushary logout --revoke` kills the key server-side as well as locally, so it
|
|
32
|
+
stops working everywhere rather than only on this machine
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- `pushary upgrade` now refreshes Codex, Gemini CLI and Cursor, not only Claude
|
|
37
|
+
Code, and names the agents it actually touched. It matters most for Codex,
|
|
38
|
+
whose hooks are trusted by hash: a refreshed hook command without a refreshed
|
|
39
|
+
trust entry is a hook Codex silently declines to run.
|
|
40
|
+
- `pushary upgrade` with no global install now names the install modes it can
|
|
41
|
+
see and the command that updates each, instead of one generic line and exit 0
|
|
42
|
+
- `pushary daemon` stops on a rejected key or a closed plan and exits `4`
|
|
43
|
+
(`UNAUTHENTICATED`). It used to treat that like a network blip, back off to a
|
|
44
|
+
two-minute poll and sit there under an `online` banner, so a revoked key left a
|
|
45
|
+
daemon that looked healthy and would never launch anything again.
|
|
46
|
+
- Ctrl-C during app pairing now cancels the pairing on the server, so a QR still
|
|
47
|
+
on your screen stops being claimable immediately instead of staying live for
|
|
48
|
+
the rest of its five minutes
|
|
49
|
+
- `setup` prints the command surface when it finishes
|
|
50
|
+
|
|
3
51
|
## 0.61.0
|
|
4
52
|
|
|
5
53
|
The largest release since the CLI shipped. Setup no longer asks you to paste an
|
|
@@ -17,14 +17,14 @@ import {
|
|
|
17
17
|
reportEvent,
|
|
18
18
|
resolvePolicy,
|
|
19
19
|
waitForAnswer
|
|
20
|
-
} from "../chunk-
|
|
21
|
-
import {
|
|
22
|
-
getMachineId
|
|
23
|
-
} from "../chunk-RN3NOEJF.js";
|
|
20
|
+
} from "../chunk-HIIBSYFJ.js";
|
|
24
21
|
import "../chunk-HNTKTK5B.js";
|
|
25
22
|
import {
|
|
26
23
|
redactSecrets
|
|
27
24
|
} from "../chunk-DQAN3JQP.js";
|
|
25
|
+
import {
|
|
26
|
+
getMachineId
|
|
27
|
+
} from "../chunk-RN3NOEJF.js";
|
|
28
28
|
import {
|
|
29
29
|
getApiKey,
|
|
30
30
|
getBaseUrl
|
|
@@ -4,10 +4,18 @@ import {
|
|
|
4
4
|
removePusharySettings
|
|
5
5
|
} from "../chunk-CAJZAFVS.js";
|
|
6
6
|
import {
|
|
7
|
-
removeCodexHooks,
|
|
8
|
-
removeGeminiSettings,
|
|
9
7
|
removeInstructionBlock
|
|
10
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-N7XJ4L2W.js";
|
|
9
|
+
import {
|
|
10
|
+
removeGeminiSettings
|
|
11
|
+
} from "../chunk-E2U35RLD.js";
|
|
12
|
+
import {
|
|
13
|
+
codexAgentsMd,
|
|
14
|
+
codexConfigToml,
|
|
15
|
+
codexHooksJson,
|
|
16
|
+
codexSkillDir,
|
|
17
|
+
removeCodexHooks
|
|
18
|
+
} from "../chunk-ER657KRJ.js";
|
|
11
19
|
import {
|
|
12
20
|
removeClaudeAlias
|
|
13
21
|
} from "../chunk-BC3VCZ3E.js";
|
|
@@ -16,8 +24,8 @@ import {
|
|
|
16
24
|
} from "../chunk-MUEW424A.js";
|
|
17
25
|
import {
|
|
18
26
|
exitOnHelpFlag
|
|
19
|
-
} from "../chunk-
|
|
20
|
-
import "../chunk-
|
|
27
|
+
} from "../chunk-IIZZYUWK.js";
|
|
28
|
+
import "../chunk-SP7OZXCQ.js";
|
|
21
29
|
import "../chunk-DQAN3JQP.js";
|
|
22
30
|
|
|
23
31
|
// bin/pushary-clean.ts
|
|
@@ -66,8 +74,25 @@ var readJson = (path) => {
|
|
|
66
74
|
return null;
|
|
67
75
|
}
|
|
68
76
|
};
|
|
77
|
+
var dryRun = false;
|
|
78
|
+
var did = (past) => dryRun ? `(would ${past === "cleaned" ? "clean" : past === "removed" ? "remove" : past === "uninstalled" ? "uninstall" : past})` : `(${past})`;
|
|
79
|
+
var wouldNote = (action, path) => {
|
|
80
|
+
console.log(` ${dim("would")} ${action} ${path}`);
|
|
81
|
+
};
|
|
82
|
+
var guardedWrite = (path, contents) => {
|
|
83
|
+
if (dryRun) return wouldNote("rewrite", path);
|
|
84
|
+
writeFileSync(path, contents, "utf-8");
|
|
85
|
+
};
|
|
86
|
+
var guardedRemove = (path, options = {}) => {
|
|
87
|
+
if (dryRun) return wouldNote("remove ", path);
|
|
88
|
+
rmSync(path, { recursive: true, force: options.force });
|
|
89
|
+
};
|
|
90
|
+
var guardedExec = (command, options, describe) => {
|
|
91
|
+
if (dryRun) return wouldNote("run ", describe);
|
|
92
|
+
execSync(command, options);
|
|
93
|
+
};
|
|
69
94
|
var writeJson = (path, data) => {
|
|
70
|
-
|
|
95
|
+
guardedWrite(path, JSON.stringify(data, null, 2) + "\n");
|
|
71
96
|
};
|
|
72
97
|
var cleanSettingsFile = (path, label) => {
|
|
73
98
|
const data = readJson(path);
|
|
@@ -78,7 +103,7 @@ var cleanSettingsFile = (path, label) => {
|
|
|
78
103
|
const changed = removePusharySettings(data);
|
|
79
104
|
if (changed) {
|
|
80
105
|
writeJson(path, data);
|
|
81
|
-
console.log(` ${check} ${label} ${dim("
|
|
106
|
+
console.log(` ${check} ${label} ${dim(did("cleaned"))}`);
|
|
82
107
|
} else {
|
|
83
108
|
console.log(` ${skip} ${label} ${dim("(no pushary entries)")}`);
|
|
84
109
|
}
|
|
@@ -88,7 +113,12 @@ var main = async () => {
|
|
|
88
113
|
console.log(` ${bold("Pushary Clean")}`);
|
|
89
114
|
console.log(` ${dim("Removes all Pushary configuration")}`);
|
|
90
115
|
console.log();
|
|
91
|
-
|
|
116
|
+
dryRun = process.argv.includes("--dry-run");
|
|
117
|
+
if (dryRun) {
|
|
118
|
+
console.log(` ${bold("Dry run")} ${dim("- nothing will be changed")}`);
|
|
119
|
+
console.log();
|
|
120
|
+
}
|
|
121
|
+
const assumeYes = dryRun || process.argv.includes("--yes") || process.argv.includes("-y");
|
|
92
122
|
if (!assumeYes && !process.stdin.isTTY) {
|
|
93
123
|
console.log(` ${yellow("!")} Non-interactive shell. Re-run with --yes to confirm removal.`);
|
|
94
124
|
process.exit(1);
|
|
@@ -118,7 +148,7 @@ var main = async () => {
|
|
|
118
148
|
if (mcpServers?.pushary) {
|
|
119
149
|
delete mcpServers.pushary;
|
|
120
150
|
writeJson(CURSOR_MCP, cursorData);
|
|
121
|
-
console.log(` ${check} Cursor MCP config ${dim("
|
|
151
|
+
console.log(` ${check} Cursor MCP config ${dim(did("cleaned"))}`);
|
|
122
152
|
} else {
|
|
123
153
|
console.log(` ${skip} Cursor MCP config ${dim("(no pushary entries)")}`);
|
|
124
154
|
}
|
|
@@ -126,7 +156,7 @@ var main = async () => {
|
|
|
126
156
|
console.log(` ${skip} Cursor MCP config ${dim("(not found)")}`);
|
|
127
157
|
}
|
|
128
158
|
if (existsSync(CURSOR_PLUGIN_DIR)) {
|
|
129
|
-
|
|
159
|
+
guardedRemove(CURSOR_PLUGIN_DIR);
|
|
130
160
|
console.log(` ${check} Cursor plugin ${dim("(removed from ~/.cursor/plugins/local)")}`);
|
|
131
161
|
} else {
|
|
132
162
|
console.log(` ${skip} Cursor plugin ${dim("(not installed)")}`);
|
|
@@ -149,12 +179,12 @@ var main = async () => {
|
|
|
149
179
|
console.log(` ${skip} Cursor gate ${dim("(no hooks.json)")}`);
|
|
150
180
|
}
|
|
151
181
|
if (existsSync(SKILL_DIR)) {
|
|
152
|
-
|
|
153
|
-
console.log(` ${check} Skill directory ${dim("
|
|
182
|
+
guardedRemove(SKILL_DIR);
|
|
183
|
+
console.log(` ${check} Skill directory ${dim(did("removed"))}`);
|
|
154
184
|
} else {
|
|
155
185
|
console.log(` ${skip} Skill directory ${dim("(not found)")}`);
|
|
156
186
|
}
|
|
157
|
-
const codexConfig =
|
|
187
|
+
const codexConfig = codexConfigToml();
|
|
158
188
|
try {
|
|
159
189
|
const config = readFileSync(codexConfig, "utf-8");
|
|
160
190
|
const hadPushary = config.includes("pushary");
|
|
@@ -168,19 +198,19 @@ var main = async () => {
|
|
|
168
198
|
parsed.notify = parsed.notify.filter((n) => typeof n !== "string" || !n.includes("pushary-codex"));
|
|
169
199
|
if (parsed.notify.length === 0) delete parsed.notify;
|
|
170
200
|
}
|
|
171
|
-
|
|
172
|
-
console.log(` ${check} Codex config ${dim("
|
|
201
|
+
guardedWrite(codexConfig, stringifyTOML(parsed));
|
|
202
|
+
console.log(` ${check} Codex config ${dim(did("cleaned"))}`);
|
|
173
203
|
} else {
|
|
174
204
|
console.log(` ${skip} Codex config ${dim("(no pushary entries)")}`);
|
|
175
205
|
}
|
|
176
206
|
} catch {
|
|
177
207
|
console.log(` ${skip} Codex config ${dim("(not found)")}`);
|
|
178
208
|
}
|
|
179
|
-
const
|
|
180
|
-
const codexHooksData = readJson(
|
|
209
|
+
const codexHooksJson2 = codexHooksJson();
|
|
210
|
+
const codexHooksData = readJson(codexHooksJson2);
|
|
181
211
|
if (codexHooksData) {
|
|
182
212
|
if (removeCodexHooks(codexHooksData)) {
|
|
183
|
-
writeJson(
|
|
213
|
+
writeJson(codexHooksJson2, codexHooksData);
|
|
184
214
|
console.log(` ${check} Codex hooks ${dim("(removed from ~/.codex/hooks.json)")}`);
|
|
185
215
|
} else {
|
|
186
216
|
console.log(` ${skip} Codex hooks ${dim("(no pushary entries)")}`);
|
|
@@ -188,16 +218,16 @@ var main = async () => {
|
|
|
188
218
|
} else {
|
|
189
219
|
console.log(` ${skip} Codex hooks ${dim("(not found)")}`);
|
|
190
220
|
}
|
|
191
|
-
const
|
|
192
|
-
if (removeInstructionBlock(
|
|
221
|
+
const codexAgentsMd2 = codexAgentsMd();
|
|
222
|
+
if (removeInstructionBlock(codexAgentsMd2)) {
|
|
193
223
|
console.log(` ${check} Codex AGENTS.md ${dim("(removed Pushary block)")}`);
|
|
194
224
|
} else {
|
|
195
225
|
console.log(` ${skip} Codex AGENTS.md ${dim("(no pushary block)")}`);
|
|
196
226
|
}
|
|
197
|
-
const
|
|
198
|
-
if (existsSync(
|
|
199
|
-
|
|
200
|
-
console.log(` ${check} Codex skill directory ${dim("
|
|
227
|
+
const codexSkillDir2 = codexSkillDir();
|
|
228
|
+
if (existsSync(codexSkillDir2)) {
|
|
229
|
+
guardedRemove(codexSkillDir2);
|
|
230
|
+
console.log(` ${check} Codex skill directory ${dim(did("removed"))}`);
|
|
201
231
|
} else {
|
|
202
232
|
console.log(` ${skip} Codex skill directory ${dim("(not found)")}`);
|
|
203
233
|
}
|
|
@@ -206,7 +236,7 @@ var main = async () => {
|
|
|
206
236
|
if (geminiSettings) {
|
|
207
237
|
if (removeGeminiSettings(geminiSettings)) {
|
|
208
238
|
writeJson(geminiSettingsPath, geminiSettings);
|
|
209
|
-
console.log(` ${check} Gemini CLI settings ${dim("
|
|
239
|
+
console.log(` ${check} Gemini CLI settings ${dim(did("cleaned"))}`);
|
|
210
240
|
} else {
|
|
211
241
|
console.log(` ${skip} Gemini CLI settings ${dim("(no pushary entries)")}`);
|
|
212
242
|
}
|
|
@@ -223,13 +253,13 @@ var main = async () => {
|
|
|
223
253
|
if (hermesPython) {
|
|
224
254
|
const snippet = 'from hermes_cli.config import load_config, save_config; c = load_config(); p = c.get("plugins") if isinstance(c.get("plugins"), dict) else {}; e = p.get("enabled") if isinstance(p.get("enabled"), list) else []; p["enabled"] = [x for x in e if x != "pushary"]; c["plugins"] = p; a = c.get("agent") if isinstance(c.get("agent"), dict) else {}; d = a.get("disabled_toolsets") if isinstance(a.get("disabled_toolsets"), list) else []; a["disabled_toolsets"] = [x for x in d if x != "clarify"]; c["agent"] = a; save_config(c)';
|
|
225
255
|
try {
|
|
226
|
-
|
|
256
|
+
guardedExec(`"${hermesPython}" -c '${snippet}'`, { stdio: "pipe", timeout: 15e3 }, "hermes plugin config update");
|
|
227
257
|
console.log(` ${check} Hermes config ${dim("(plugin disabled, clarify toolset restored)")}`);
|
|
228
258
|
} catch {
|
|
229
259
|
console.log(` ${skip} Hermes config ${dim("(could not update config.yaml)")}`);
|
|
230
260
|
}
|
|
231
261
|
try {
|
|
232
|
-
|
|
262
|
+
guardedExec(`"${hermesPython}" -m pip uninstall -y hermes-plugin-pushary`, { stdio: "pipe", timeout: 6e4 }, "pip uninstall hermes-plugin-pushary");
|
|
233
263
|
console.log(` ${check} Hermes plugin ${dim("(pip uninstalled)")}`);
|
|
234
264
|
} catch {
|
|
235
265
|
console.log(` ${skip} Hermes plugin ${dim("(not installed)")}`);
|
|
@@ -247,8 +277,8 @@ var main = async () => {
|
|
|
247
277
|
const cleaned = lines.filter((l) => !isOurExport(l)).join("\n");
|
|
248
278
|
if (cleaned !== content) {
|
|
249
279
|
const backup = `${shellFile}.pushary-backup-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`;
|
|
250
|
-
copyFileSync(shellFile, backup);
|
|
251
|
-
|
|
280
|
+
if (!dryRun) copyFileSync(shellFile, backup);
|
|
281
|
+
guardedWrite(shellFile, cleaned);
|
|
252
282
|
console.log(` ${check} ${shellFile.split("/").pop()} ${dim(`(removed the export, backup at ${backup})`)}`);
|
|
253
283
|
}
|
|
254
284
|
for (const line of declined) {
|
|
@@ -265,7 +295,7 @@ var main = async () => {
|
|
|
265
295
|
console.log(` ${skip} claude alias ${dim("(not set)")}`);
|
|
266
296
|
}
|
|
267
297
|
if (existsSync(PUSHARY_DIR)) {
|
|
268
|
-
|
|
298
|
+
guardedRemove(PUSHARY_DIR);
|
|
269
299
|
console.log(` ${check} Local state ${dim("(~/.pushary removed: stored API key, ledger)")}`);
|
|
270
300
|
} else {
|
|
271
301
|
console.log(` ${skip} Local state ${dim("(~/.pushary not found)")}`);
|
|
@@ -275,7 +305,7 @@ var main = async () => {
|
|
|
275
305
|
for (const f of readdirSync(tmpdir())) {
|
|
276
306
|
if (!f.startsWith("pushary-")) continue;
|
|
277
307
|
try {
|
|
278
|
-
|
|
308
|
+
guardedRemove(join(tmpdir(), f), { force: true });
|
|
279
309
|
swept++;
|
|
280
310
|
} catch {
|
|
281
311
|
}
|
|
@@ -285,7 +315,7 @@ var main = async () => {
|
|
|
285
315
|
}
|
|
286
316
|
try {
|
|
287
317
|
execNpm("uninstall -g --no-workspaces @pushary/agent-hooks", { stdio: "ignore", timeout: 3e4 });
|
|
288
|
-
console.log(` ${check} Global package ${dim("
|
|
318
|
+
console.log(` ${check} Global package ${dim(did("uninstalled"))}`);
|
|
289
319
|
} catch {
|
|
290
320
|
console.log(` ${skip} Global package ${dim("(not installed)")}`);
|
|
291
321
|
}
|
|
@@ -31,10 +31,7 @@ import {
|
|
|
31
31
|
toCodexWire,
|
|
32
32
|
toPolicyLookup,
|
|
33
33
|
waitForAnswer
|
|
34
|
-
} from "../chunk-
|
|
35
|
-
import {
|
|
36
|
-
getMachineId
|
|
37
|
-
} from "../chunk-RN3NOEJF.js";
|
|
34
|
+
} from "../chunk-HIIBSYFJ.js";
|
|
38
35
|
import {
|
|
39
36
|
isGatingMoment,
|
|
40
37
|
recordKeylessMoment
|
|
@@ -46,6 +43,9 @@ import {
|
|
|
46
43
|
hookWaitClamped,
|
|
47
44
|
hookWaitDeadline
|
|
48
45
|
} from "../chunk-DQAN3JQP.js";
|
|
46
|
+
import {
|
|
47
|
+
getMachineId
|
|
48
|
+
} from "../chunk-RN3NOEJF.js";
|
|
49
49
|
import {
|
|
50
50
|
getApiKey
|
|
51
51
|
} from "../chunk-2UMNXADU.js";
|
|
@@ -3,12 +3,12 @@ import {
|
|
|
3
3
|
askUser,
|
|
4
4
|
reportEvent,
|
|
5
5
|
waitForAnswer
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-HIIBSYFJ.js";
|
|
7
|
+
import "../chunk-HNTKTK5B.js";
|
|
8
|
+
import "../chunk-DQAN3JQP.js";
|
|
7
9
|
import {
|
|
8
10
|
getMachineId
|
|
9
11
|
} from "../chunk-RN3NOEJF.js";
|
|
10
|
-
import "../chunk-HNTKTK5B.js";
|
|
11
|
-
import "../chunk-DQAN3JQP.js";
|
|
12
12
|
import {
|
|
13
13
|
getApiKey
|
|
14
14
|
} from "../chunk-2UMNXADU.js";
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
printKeyCheck
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-ONVEYEVR.js";
|
|
5
5
|
import {
|
|
6
6
|
confirmAppConnection,
|
|
7
7
|
connectDevice,
|
|
8
8
|
printConnectInstructions
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-3O27ZSRE.js";
|
|
10
10
|
import "../chunk-3EGEA4KH.js";
|
|
11
11
|
import {
|
|
12
12
|
parseFlags
|
|
13
13
|
} from "../chunk-N4DA4CJB.js";
|
|
14
14
|
import {
|
|
15
15
|
readKeySource
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-247C4RE5.js";
|
|
17
17
|
import {
|
|
18
18
|
checkApiKey
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-YJ7YZRVV.js";
|
|
20
20
|
import {
|
|
21
21
|
createIo
|
|
22
22
|
} from "../chunk-TX7KBKT7.js";
|
|
@@ -26,10 +26,10 @@ import {
|
|
|
26
26
|
import "../chunk-BC3VCZ3E.js";
|
|
27
27
|
import {
|
|
28
28
|
exitOnHelpFlag
|
|
29
|
-
} from "../chunk-
|
|
29
|
+
} from "../chunk-IIZZYUWK.js";
|
|
30
30
|
import {
|
|
31
31
|
EXIT
|
|
32
|
-
} from "../chunk-
|
|
32
|
+
} from "../chunk-SP7OZXCQ.js";
|
|
33
33
|
import "../chunk-HNTKTK5B.js";
|
|
34
34
|
import "../chunk-DQAN3JQP.js";
|
|
35
35
|
import "../chunk-2UMNXADU.js";
|
|
@@ -7,8 +7,10 @@ import {
|
|
|
7
7
|
} from "../chunk-MUEW424A.js";
|
|
8
8
|
import {
|
|
9
9
|
exitOnHelpFlag
|
|
10
|
-
} from "../chunk-
|
|
11
|
-
import
|
|
10
|
+
} from "../chunk-IIZZYUWK.js";
|
|
11
|
+
import {
|
|
12
|
+
EXIT
|
|
13
|
+
} from "../chunk-SP7OZXCQ.js";
|
|
12
14
|
import {
|
|
13
15
|
getMachineId
|
|
14
16
|
} from "../chunk-RN3NOEJF.js";
|
|
@@ -30,6 +32,19 @@ var MAX_ERROR_STREAK = 6;
|
|
|
30
32
|
var REQUEST_TIMEOUT_MS = 1e4;
|
|
31
33
|
var MAX_SPAWNS_PER_WINDOW = 5;
|
|
32
34
|
var SPAWN_WINDOW_MS = 6e4;
|
|
35
|
+
var DrainError = class extends Error {
|
|
36
|
+
constructor(status) {
|
|
37
|
+
super(`drain ${status}`);
|
|
38
|
+
this.status = status;
|
|
39
|
+
this.name = "DrainError";
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
var isAuthFailure = (err) => {
|
|
43
|
+
if (typeof err !== "object" || err === null) return false;
|
|
44
|
+
const candidate = err;
|
|
45
|
+
if (candidate.name !== "DrainError") return false;
|
|
46
|
+
return candidate.status === 401 || candidate.status === 403;
|
|
47
|
+
};
|
|
33
48
|
var NATIVE_AGENT_BINARIES = { codex: "codex", gemini: "gemini" };
|
|
34
49
|
var buildSpawnLaunch = (req, opts) => {
|
|
35
50
|
const agent = req.agent === "codex" || req.agent === "gemini" ? req.agent : "claude";
|
|
@@ -68,6 +83,9 @@ var runSpawnDaemon = async () => {
|
|
|
68
83
|
const spawnTimestamps = [];
|
|
69
84
|
let timer;
|
|
70
85
|
let inflight;
|
|
86
|
+
let fatalCode = null;
|
|
87
|
+
let finish = () => {
|
|
88
|
+
};
|
|
71
89
|
const launch = (req) => {
|
|
72
90
|
spawnTimestamps.push(Date.now());
|
|
73
91
|
const cwd = req.cwd && existsSync(req.cwd) ? req.cwd : process.cwd();
|
|
@@ -98,7 +116,7 @@ var runSpawnDaemon = async () => {
|
|
|
98
116
|
body: JSON.stringify({ machineId }),
|
|
99
117
|
signal
|
|
100
118
|
});
|
|
101
|
-
if (!res.ok) throw new
|
|
119
|
+
if (!res.ok) throw new DrainError(res.status);
|
|
102
120
|
const data = await res.json();
|
|
103
121
|
const spawn2 = data.spawn;
|
|
104
122
|
return spawn2 && typeof spawn2.prompt === "string" && typeof spawn2.id === "string" ? spawn2 : null;
|
|
@@ -126,7 +144,16 @@ var runSpawnDaemon = async () => {
|
|
|
126
144
|
} else {
|
|
127
145
|
idleTicks++;
|
|
128
146
|
}
|
|
129
|
-
} catch {
|
|
147
|
+
} catch (err) {
|
|
148
|
+
if (isAuthFailure(err)) {
|
|
149
|
+
const status = err.status;
|
|
150
|
+
fatalCode = EXIT.UNAUTHENTICATED;
|
|
151
|
+
stderr(
|
|
152
|
+
status === 401 ? "[pushary] daemon stopping: this machine's key was rejected. Run `pushary login` to sign in again.\n" : "[pushary] daemon stopping: this workspace has no active plan, so the queue is closed. Pick one at pushary.com/dashboard/settings?tab=billing\n"
|
|
153
|
+
);
|
|
154
|
+
finish();
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
130
157
|
errorStreak = Math.min(errorStreak + 1, MAX_ERROR_STREAK);
|
|
131
158
|
} finally {
|
|
132
159
|
clearTimeout(timeout);
|
|
@@ -152,8 +179,13 @@ var runSpawnDaemon = async () => {
|
|
|
152
179
|
resolve();
|
|
153
180
|
};
|
|
154
181
|
for (const signal of signals) process.on(signal, onSignal);
|
|
182
|
+
finish = () => {
|
|
183
|
+
teardown();
|
|
184
|
+
for (const signal of signals) process.off(signal, onSignal);
|
|
185
|
+
resolve();
|
|
186
|
+
};
|
|
155
187
|
});
|
|
156
|
-
return 0;
|
|
188
|
+
return fatalCode ?? 0;
|
|
157
189
|
};
|
|
158
190
|
|
|
159
191
|
// bin/pushary-daemon.ts
|