@pushary/agent-hooks 0.89.7 → 0.89.9
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 +30 -0
- package/dist/bin/pushary-bell-hook.js +3 -3
- package/dist/bin/pushary-bell.js +3 -3
- package/dist/bin/pushary-claude.js +5 -5
- package/dist/bin/pushary-clean.js +13 -10
- package/dist/bin/pushary-codex-bridge.js +3 -3
- package/dist/bin/pushary-codex-hook.js +3 -3
- package/dist/bin/pushary-codex.js +3 -3
- package/dist/bin/pushary-connect.js +2 -2
- package/dist/bin/pushary-daemon.js +49 -14
- package/dist/bin/pushary-doctor.js +29 -8
- package/dist/bin/pushary-elicitation-hook.js +2 -2
- package/dist/bin/pushary-gemini-bridge.js +3 -3
- package/dist/bin/pushary-gemini-hook.js +3 -3
- package/dist/bin/pushary-hook.js +4 -4
- package/dist/bin/pushary-login.js +2 -2
- package/dist/bin/pushary-logout.js +2 -2
- package/dist/bin/pushary-notification-hook.js +3 -3
- package/dist/bin/pushary-opencode-hook.js +3 -3
- package/dist/bin/pushary-permission-denied-hook.js +4 -4
- package/dist/bin/pushary-permission-hook.js +4 -4
- package/dist/bin/pushary-post-hook.js +3 -3
- package/dist/bin/pushary-prompt-hook.js +3 -3
- package/dist/bin/pushary-session-end-hook.js +3 -3
- package/dist/bin/pushary-session-start-hook.js +3 -3
- package/dist/bin/pushary-setup.js +20 -7
- package/dist/bin/pushary-status.js +4 -4
- package/dist/bin/pushary-stop-hook.js +3 -3
- package/dist/bin/pushary-stopfailure-hook.js +3 -3
- package/dist/bin/pushary-upgrade.js +16 -8
- package/dist/{chunk-BPKMGE7L.js → chunk-4XZCDSNG.js} +1 -1
- package/dist/{chunk-ZH7TWAYK.js → chunk-543KNJKC.js} +390 -37
- package/dist/{chunk-2M66JVZM.js → chunk-DKDDLF5P.js} +1 -1
- package/dist/{chunk-2MEJBUOI.js → chunk-EA3E74P2.js} +1 -1
- package/dist/{chunk-5YUVKPTS.js → chunk-EJT2ER6G.js} +2 -2
- package/dist/{chunk-WQGMUIDW.js → chunk-FX5QSMPY.js} +1 -1
- package/dist/{chunk-42TTFZLV.js → chunk-TF247BET.js} +1 -1
- package/dist/{chunk-TESGYWEM.js → chunk-U5TQCQ25.js} +32 -1
- package/dist/{chunk-L3YUHEB6.js → chunk-V6N4Q223.js} +1 -1
- package/dist/{chunk-6MTNS63X.js → chunk-XX2V4QS5.js} +12 -1
- package/dist/src/index.js +4 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.89.9
|
|
4
|
+
|
|
5
|
+
### Setup proves managed control reaches the server
|
|
6
|
+
|
|
7
|
+
The background daemon now records successful heartbeats separately from
|
|
8
|
+
successful control-queue responses. Setup and upgrade wait for both before
|
|
9
|
+
reporting managed control ready, and doctor reports either missing proof.
|
|
10
|
+
|
|
11
|
+
An authenticated, once-per-minute challenge round trip gives the server the
|
|
12
|
+
same readiness evidence without launching an agent or changing queued work.
|
|
13
|
+
Machine status exposes that observation additively so current clients keep
|
|
14
|
+
their existing fields while newer CLIs can verify capabilities end to end.
|
|
15
|
+
|
|
16
|
+
## 0.89.8
|
|
17
|
+
|
|
18
|
+
### Daemon upgrades keep a recoverable service
|
|
19
|
+
|
|
20
|
+
Background-service replacement now records the previous definition and native
|
|
21
|
+
running state in an owner-only transaction receipt before changing launchd,
|
|
22
|
+
systemd or Task Scheduler. A failed or interrupted replacement restores that
|
|
23
|
+
service before another upgrade is attempted, and verifies whether it should be
|
|
24
|
+
running or stopped.
|
|
25
|
+
|
|
26
|
+
Native probe errors are not treated as proof that a service disappeared, and
|
|
27
|
+
rollback preserves an administratively disabled service instead of enabling it.
|
|
28
|
+
|
|
29
|
+
`pushary clean` now proves the background service was removed before changing
|
|
30
|
+
agent configuration or local state. If removal cannot be proven, clean stops
|
|
31
|
+
with the existing installation intact so it can be repaired and retried.
|
|
32
|
+
|
|
3
33
|
## 0.89.7
|
|
4
34
|
|
|
5
35
|
### clean no longer uninstalls the macOS app along with the CLI
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handleBell
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-FX5QSMPY.js";
|
|
5
5
|
import {
|
|
6
6
|
readHookInput
|
|
7
7
|
} from "../chunk-6CUUA7HO.js";
|
|
8
|
-
import "../chunk-
|
|
8
|
+
import "../chunk-V6N4Q223.js";
|
|
9
9
|
import "../chunk-BC3VCZ3E.js";
|
|
10
10
|
import "../chunk-OFRNZWC4.js";
|
|
11
|
-
import "../chunk-
|
|
11
|
+
import "../chunk-XX2V4QS5.js";
|
|
12
12
|
import "../chunk-2UMNXADU.js";
|
|
13
13
|
import "../chunk-L4C2JXJS.js";
|
|
14
14
|
|
package/dist/bin/pushary-bell.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
liveAgentCount,
|
|
6
6
|
ring,
|
|
7
7
|
upgradeThreshold
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-FX5QSMPY.js";
|
|
9
9
|
import {
|
|
10
10
|
guardBinary
|
|
11
11
|
} from "../chunk-AIGDBRIJ.js";
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
import {
|
|
17
17
|
createIo
|
|
18
18
|
} from "../chunk-5RUIFDTP.js";
|
|
19
|
-
import "../chunk-
|
|
19
|
+
import "../chunk-V6N4Q223.js";
|
|
20
20
|
import {
|
|
21
21
|
parseFlags
|
|
22
22
|
} from "../chunk-GMXKITVA.js";
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
import {
|
|
35
35
|
readJsonSafe,
|
|
36
36
|
writeJsonAtomic
|
|
37
|
-
} from "../chunk-
|
|
37
|
+
} from "../chunk-XX2V4QS5.js";
|
|
38
38
|
import "../chunk-2UMNXADU.js";
|
|
39
39
|
import "../chunk-L4C2JXJS.js";
|
|
40
40
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ensureDaemonRunning
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-543KNJKC.js";
|
|
5
5
|
import {
|
|
6
6
|
buildTranscriptRecords,
|
|
7
7
|
decodePublicKey,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import {
|
|
14
14
|
startProcessOwnership,
|
|
15
15
|
withSpawnProcessOwnership
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-TF247BET.js";
|
|
17
17
|
import {
|
|
18
18
|
needsShell,
|
|
19
19
|
spawnClaude
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
getPolicy,
|
|
28
28
|
repoKeyFor,
|
|
29
29
|
reportEvent
|
|
30
|
-
} from "../chunk-
|
|
30
|
+
} from "../chunk-4XZCDSNG.js";
|
|
31
31
|
import {
|
|
32
32
|
DEFAULT_SESSION,
|
|
33
33
|
askUser,
|
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
} from "../chunk-KOPUTJQC.js";
|
|
47
47
|
import {
|
|
48
48
|
getMachineId
|
|
49
|
-
} from "../chunk-
|
|
49
|
+
} from "../chunk-DKDDLF5P.js";
|
|
50
50
|
import "../chunk-GMI5QZLG.js";
|
|
51
51
|
import "../chunk-DINDL2CF.js";
|
|
52
52
|
import "../chunk-BSZYIAZL.js";
|
|
@@ -54,7 +54,7 @@ import "../chunk-SAF6HGAA.js";
|
|
|
54
54
|
import "../chunk-OFRNZWC4.js";
|
|
55
55
|
import "../chunk-7QLSKOSU.js";
|
|
56
56
|
import "../chunk-KZERVKTD.js";
|
|
57
|
-
import "../chunk-
|
|
57
|
+
import "../chunk-XX2V4QS5.js";
|
|
58
58
|
import {
|
|
59
59
|
getApiKey,
|
|
60
60
|
getBaseUrl
|
|
@@ -24,13 +24,13 @@ import "../chunk-ATBKJNWS.js";
|
|
|
24
24
|
import "../chunk-AIGDBRIJ.js";
|
|
25
25
|
import {
|
|
26
26
|
disableDaemonService
|
|
27
|
-
} from "../chunk-
|
|
27
|
+
} from "../chunk-543KNJKC.js";
|
|
28
28
|
import "../chunk-XHKBHWLX.js";
|
|
29
29
|
import {
|
|
30
30
|
execNpm
|
|
31
31
|
} from "../chunk-PZA7G4CN.js";
|
|
32
32
|
import "../chunk-KOPUTJQC.js";
|
|
33
|
-
import "../chunk-
|
|
33
|
+
import "../chunk-DKDDLF5P.js";
|
|
34
34
|
import {
|
|
35
35
|
claudeJson,
|
|
36
36
|
claudeSettings,
|
|
@@ -66,7 +66,7 @@ import "../chunk-7QLSKOSU.js";
|
|
|
66
66
|
import {
|
|
67
67
|
EXIT
|
|
68
68
|
} from "../chunk-KZERVKTD.js";
|
|
69
|
-
import "../chunk-
|
|
69
|
+
import "../chunk-XX2V4QS5.js";
|
|
70
70
|
import "../chunk-2UMNXADU.js";
|
|
71
71
|
import {
|
|
72
72
|
CURSOR_GATE_EVENTS,
|
|
@@ -177,7 +177,7 @@ var guardedDaemonRemoval = async () => {
|
|
|
177
177
|
wouldNote("stop and uninstall", "Pushary background service");
|
|
178
178
|
return true;
|
|
179
179
|
}
|
|
180
|
-
return (await disableDaemonService()).kind === "ok";
|
|
180
|
+
return (await disableDaemonService({ requireAbsenceProof: true })).kind === "ok";
|
|
181
181
|
};
|
|
182
182
|
var guardedInstructionBlockRemoval = (path) => {
|
|
183
183
|
if (!dryRun) return removeInstructionBlock(path);
|
|
@@ -290,6 +290,15 @@ var main = async () => {
|
|
|
290
290
|
console.log(` ${dim("The Mac app is installed, so its wiring and the state it owns are left alone.")}`);
|
|
291
291
|
console.log();
|
|
292
292
|
}
|
|
293
|
+
const daemonRemoved = await guardedDaemonRemoval();
|
|
294
|
+
if (!daemonRemoved) {
|
|
295
|
+
console.log(` ${cross} Background service ${dim("(could not stop or uninstall)")}`);
|
|
296
|
+
console.log(` ${yellow(bold("Clean stopped before changing provider configuration or local state."))}`);
|
|
297
|
+
console.log(` ${dim("Fix the background service, then re-run")} npx @pushary/agent-hooks@latest clean`);
|
|
298
|
+
console.log();
|
|
299
|
+
process.exit(EXIT.FAILED);
|
|
300
|
+
}
|
|
301
|
+
console.log(` ${check} Background service ${dim(did("uninstalled"))}`);
|
|
293
302
|
cleanSettingsFile(CLAUDE_SETTINGS, "Claude Code settings");
|
|
294
303
|
cleanSettingsFile(CLAUDE_SETTINGS_LOCAL, "Claude Code settings.local");
|
|
295
304
|
const claudeJson2 = keepShared ? null : readJson(CLAUDE_JSON);
|
|
@@ -521,12 +530,6 @@ var main = async () => {
|
|
|
521
530
|
} else {
|
|
522
531
|
console.log(` ${skip} claude alias ${dim("(not set)")}`);
|
|
523
532
|
}
|
|
524
|
-
if (await guardedDaemonRemoval()) {
|
|
525
|
-
console.log(` ${check} Background service ${dim(did("uninstalled"))}`);
|
|
526
|
-
} else {
|
|
527
|
-
incompleteClean = true;
|
|
528
|
-
console.log(` ${cross} Background service ${dim("(could not stop or uninstall)")}`);
|
|
529
|
-
}
|
|
530
533
|
if (existsSync(PUSHARY_DIR)) {
|
|
531
534
|
let removed = 0;
|
|
532
535
|
const kept = [];
|
|
@@ -11,7 +11,7 @@ import "../chunk-PMHTCDEO.js";
|
|
|
11
11
|
import {
|
|
12
12
|
startProcessOwnership,
|
|
13
13
|
withSpawnProcessOwnership
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-TF247BET.js";
|
|
15
15
|
import {
|
|
16
16
|
spawnClaude
|
|
17
17
|
} from "../chunk-XHKBHWLX.js";
|
|
@@ -20,9 +20,9 @@ import {
|
|
|
20
20
|
} from "../chunk-PZA7G4CN.js";
|
|
21
21
|
import {
|
|
22
22
|
getMachineId
|
|
23
|
-
} from "../chunk-
|
|
23
|
+
} from "../chunk-DKDDLF5P.js";
|
|
24
24
|
import "../chunk-GMI5QZLG.js";
|
|
25
|
-
import "../chunk-
|
|
25
|
+
import "../chunk-XX2V4QS5.js";
|
|
26
26
|
import {
|
|
27
27
|
getApiKey,
|
|
28
28
|
getBaseUrl
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
toCodexWire,
|
|
32
32
|
toPolicyLookup,
|
|
33
33
|
toPolicyLookups
|
|
34
|
-
} from "../chunk-
|
|
34
|
+
} from "../chunk-4XZCDSNG.js";
|
|
35
35
|
import {
|
|
36
36
|
DEFAULT_SESSION,
|
|
37
37
|
askUser,
|
|
@@ -49,7 +49,7 @@ import {
|
|
|
49
49
|
} from "../chunk-KOPUTJQC.js";
|
|
50
50
|
import {
|
|
51
51
|
getMachineId
|
|
52
|
-
} from "../chunk-
|
|
52
|
+
} from "../chunk-DKDDLF5P.js";
|
|
53
53
|
import {
|
|
54
54
|
canonicalJson
|
|
55
55
|
} from "../chunk-GMI5QZLG.js";
|
|
@@ -58,7 +58,7 @@ import "../chunk-SAF6HGAA.js";
|
|
|
58
58
|
import "../chunk-OFRNZWC4.js";
|
|
59
59
|
import "../chunk-7QLSKOSU.js";
|
|
60
60
|
import "../chunk-KZERVKTD.js";
|
|
61
|
-
import "../chunk-
|
|
61
|
+
import "../chunk-XX2V4QS5.js";
|
|
62
62
|
import {
|
|
63
63
|
getApiKey
|
|
64
64
|
} from "../chunk-2UMNXADU.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
reportEvent
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-4XZCDSNG.js";
|
|
5
5
|
import {
|
|
6
6
|
askUser,
|
|
7
7
|
waitForAnswer
|
|
@@ -9,14 +9,14 @@ import {
|
|
|
9
9
|
import "../chunk-KOPUTJQC.js";
|
|
10
10
|
import {
|
|
11
11
|
getMachineId
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-DKDDLF5P.js";
|
|
13
13
|
import "../chunk-GMI5QZLG.js";
|
|
14
14
|
import "../chunk-BSZYIAZL.js";
|
|
15
15
|
import "../chunk-SAF6HGAA.js";
|
|
16
16
|
import "../chunk-OFRNZWC4.js";
|
|
17
17
|
import "../chunk-7QLSKOSU.js";
|
|
18
18
|
import "../chunk-KZERVKTD.js";
|
|
19
|
-
import "../chunk-
|
|
19
|
+
import "../chunk-XX2V4QS5.js";
|
|
20
20
|
import {
|
|
21
21
|
getApiKey
|
|
22
22
|
} from "../chunk-2UMNXADU.js";
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
} from "../chunk-5RUIFDTP.js";
|
|
17
17
|
import {
|
|
18
18
|
readKeySource
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-V6N4Q223.js";
|
|
20
20
|
import {
|
|
21
21
|
parseFlags
|
|
22
22
|
} from "../chunk-GMXKITVA.js";
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
import {
|
|
36
36
|
EXIT
|
|
37
37
|
} from "../chunk-KZERVKTD.js";
|
|
38
|
-
import "../chunk-
|
|
38
|
+
import "../chunk-XX2V4QS5.js";
|
|
39
39
|
import "../chunk-2UMNXADU.js";
|
|
40
40
|
import "../chunk-L4C2JXJS.js";
|
|
41
41
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
inspectConfiguredManagedProviders
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-EA3E74P2.js";
|
|
5
5
|
import "../chunk-J2JZJZKB.js";
|
|
6
|
+
import "../chunk-BAE45YLP.js";
|
|
6
7
|
import {
|
|
7
8
|
HEARTBEAT_INTERVAL_MS,
|
|
8
9
|
sendHeartbeat
|
|
9
|
-
} from "../chunk-
|
|
10
|
-
import "../chunk-BAE45YLP.js";
|
|
10
|
+
} from "../chunk-U5TQCQ25.js";
|
|
11
11
|
import "../chunk-VA7VUNRD.js";
|
|
12
12
|
import "../chunk-ATBKJNWS.js";
|
|
13
13
|
import "../chunk-AIGDBRIJ.js";
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
replaceDaemonService,
|
|
24
24
|
requestDaemonHandoff,
|
|
25
25
|
stopDaemonRunning
|
|
26
|
-
} from "../chunk-
|
|
26
|
+
} from "../chunk-543KNJKC.js";
|
|
27
27
|
import {
|
|
28
28
|
detectProviderLiveCapabilities,
|
|
29
29
|
hasSpawnProvider,
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
import {
|
|
33
33
|
findLiveProcessBySpawnId,
|
|
34
34
|
ownsLiveProcess
|
|
35
|
-
} from "../chunk-
|
|
35
|
+
} from "../chunk-TF247BET.js";
|
|
36
36
|
import {
|
|
37
37
|
spawnClaude
|
|
38
38
|
} from "../chunk-XHKBHWLX.js";
|
|
@@ -41,11 +41,11 @@ import {
|
|
|
41
41
|
} from "../chunk-PZA7G4CN.js";
|
|
42
42
|
import {
|
|
43
43
|
getMachineId
|
|
44
|
-
} from "../chunk-
|
|
44
|
+
} from "../chunk-DKDDLF5P.js";
|
|
45
45
|
import "../chunk-GMI5QZLG.js";
|
|
46
46
|
import {
|
|
47
47
|
readControlMode
|
|
48
|
-
} from "../chunk-
|
|
48
|
+
} from "../chunk-V6N4Q223.js";
|
|
49
49
|
import {
|
|
50
50
|
exitOnHelpFlag
|
|
51
51
|
} from "../chunk-LURY4WNF.js";
|
|
@@ -56,7 +56,7 @@ import "../chunk-OFRNZWC4.js";
|
|
|
56
56
|
import {
|
|
57
57
|
EXIT
|
|
58
58
|
} from "../chunk-KZERVKTD.js";
|
|
59
|
-
import "../chunk-
|
|
59
|
+
import "../chunk-XX2V4QS5.js";
|
|
60
60
|
import {
|
|
61
61
|
getApiKey,
|
|
62
62
|
getBaseUrl
|
|
@@ -116,8 +116,15 @@ var STOP_PROTOCOL_VERSION = 2;
|
|
|
116
116
|
var MAX_SPAWNS_PER_WINDOW = 5;
|
|
117
117
|
var SPAWN_WINDOW_MS = 6e4;
|
|
118
118
|
var VERSION_CHECK_INTERVAL_MS = 2e3;
|
|
119
|
+
var CONTROL_PROBE_INTERVAL_MS = 6e4;
|
|
119
120
|
var MAX_TRACKED_PROCESSES = 100;
|
|
120
121
|
var MAX_COMPLETED_STOPS = 20;
|
|
122
|
+
var controlProbeDue = (lastProbeAt, at = Date.now()) => lastProbeAt === 0 || at - lastProbeAt >= CONTROL_PROBE_INTERVAL_MS;
|
|
123
|
+
var parseControlProbe = (value) => {
|
|
124
|
+
if (typeof value !== "object" || value === null) return null;
|
|
125
|
+
const id = value.id;
|
|
126
|
+
return typeof id === "string" && id.length > 0 && id.length <= 128 ? id : null;
|
|
127
|
+
};
|
|
121
128
|
var daemonSignals = (platform = process.platform) => platform === "win32" ? ["SIGINT", "SIGTERM"] : ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
122
129
|
var parseSpawnClaim = (value) => {
|
|
123
130
|
if (typeof value !== "object" || value === null) return null;
|
|
@@ -294,6 +301,7 @@ var runSpawnDaemon = async () => {
|
|
|
294
301
|
let stopped = false;
|
|
295
302
|
let idleTicks = 0;
|
|
296
303
|
let errorStreak = 0;
|
|
304
|
+
let lastControlProbeAt = 0;
|
|
297
305
|
const spawnTimestamps = [];
|
|
298
306
|
const launchedProcesses = /* @__PURE__ */ new Map();
|
|
299
307
|
const completedStops = /* @__PURE__ */ new Map();
|
|
@@ -432,18 +440,41 @@ var runSpawnDaemon = async () => {
|
|
|
432
440
|
});
|
|
433
441
|
}
|
|
434
442
|
};
|
|
443
|
+
const acknowledgeControlProbe = async (probeId) => {
|
|
444
|
+
const response = await fetch(`${baseUrl}${DRAIN_PATH}`, {
|
|
445
|
+
method: "POST",
|
|
446
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` },
|
|
447
|
+
body: JSON.stringify({ machineId, controlProbeAck: probeId }),
|
|
448
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
449
|
+
}).catch(() => null);
|
|
450
|
+
return response?.ok === true;
|
|
451
|
+
};
|
|
435
452
|
const drain = async (signal) => {
|
|
453
|
+
const controlProbe = controlProbeDue(lastControlProbeAt);
|
|
454
|
+
if (controlProbe) lastControlProbeAt = Date.now();
|
|
436
455
|
const res = await fetch(`${baseUrl}${DRAIN_PATH}`, {
|
|
437
456
|
method: "POST",
|
|
438
457
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` },
|
|
439
|
-
body: JSON.stringify({
|
|
458
|
+
body: JSON.stringify({
|
|
459
|
+
machineId,
|
|
460
|
+
spawnProtocol: SPAWN_PROTOCOL_VERSION,
|
|
461
|
+
stopProtocol: STOP_PROTOCOL_VERSION,
|
|
462
|
+
controlProbe
|
|
463
|
+
}),
|
|
440
464
|
signal
|
|
441
465
|
});
|
|
442
466
|
if (!res.ok) throw new DrainError(res.status);
|
|
443
467
|
const data = await res.json();
|
|
444
468
|
const response = typeof data === "object" && data !== null ? data : {};
|
|
445
469
|
await Promise.all(parseStopRequests(response.stops).map(runStop));
|
|
446
|
-
|
|
470
|
+
const controlProbeId = parseControlProbe(response.controlProbe);
|
|
471
|
+
return {
|
|
472
|
+
request: parseSpawnClaim(response.spawn),
|
|
473
|
+
controlProbeId,
|
|
474
|
+
// Released servers ignore the request field and omit the response field.
|
|
475
|
+
// Their successful authenticated drain remains the strongest proof they expose.
|
|
476
|
+
legacyControlProof: controlProbe && !Object.hasOwn(response, "controlProbe")
|
|
477
|
+
};
|
|
447
478
|
};
|
|
448
479
|
const acknowledge = async (body) => {
|
|
449
480
|
if (!body) return;
|
|
@@ -507,18 +538,22 @@ var runSpawnDaemon = async () => {
|
|
|
507
538
|
inflight = controller;
|
|
508
539
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
509
540
|
try {
|
|
510
|
-
const
|
|
541
|
+
const drained = await drain(controller.signal);
|
|
511
542
|
if (!daemonLease.isOwner()) {
|
|
512
543
|
finish();
|
|
513
544
|
return;
|
|
514
545
|
}
|
|
515
546
|
errorStreak = 0;
|
|
516
|
-
if (
|
|
547
|
+
if (drained.request) {
|
|
517
548
|
idleTicks = 0;
|
|
518
|
-
await launchClaim(
|
|
549
|
+
await launchClaim(drained.request);
|
|
519
550
|
} else {
|
|
520
551
|
idleTicks++;
|
|
521
552
|
}
|
|
553
|
+
const controlProved = drained.legacyControlProof || drained.controlProbeId !== null && await acknowledgeControlProbe(drained.controlProbeId);
|
|
554
|
+
if (controlProved) {
|
|
555
|
+
daemonLease.recordSuccessfulControl();
|
|
556
|
+
}
|
|
522
557
|
} catch (err) {
|
|
523
558
|
if (isAuthFailure(err)) {
|
|
524
559
|
const status = err.status;
|
|
@@ -582,7 +617,7 @@ var runSpawnDaemon = async () => {
|
|
|
582
617
|
stderr(hasSpawnProvider(providerCapabilities) ? `[pushary] daemon online \u2014 this machine (${machineId}) can now be sent a new session from your phone. Ctrl-C to stop.
|
|
583
618
|
` : `[pushary] daemon online \u2014 no supported Claude, Codex, or Gemini CLI was found, so phone-start is unavailable. Ctrl-C to stop.
|
|
584
619
|
`);
|
|
585
|
-
timer = setTimeout(tick,
|
|
620
|
+
timer = setTimeout(tick, 0);
|
|
586
621
|
const signals = daemonSignals();
|
|
587
622
|
await new Promise((resolve) => {
|
|
588
623
|
const onSignal = () => finish();
|
|
@@ -8,6 +8,9 @@ import {
|
|
|
8
8
|
geminiWired,
|
|
9
9
|
pusharyHookExecutable
|
|
10
10
|
} from "../chunk-BAE45YLP.js";
|
|
11
|
+
import {
|
|
12
|
+
readMachineReadiness
|
|
13
|
+
} from "../chunk-U5TQCQ25.js";
|
|
11
14
|
import {
|
|
12
15
|
agentProbes,
|
|
13
16
|
detectAgent,
|
|
@@ -31,10 +34,11 @@ import {
|
|
|
31
34
|
import "../chunk-ATBKJNWS.js";
|
|
32
35
|
import "../chunk-AIGDBRIJ.js";
|
|
33
36
|
import {
|
|
37
|
+
daemonHasRemoteProof,
|
|
34
38
|
daemonServiceManagerAvailable,
|
|
35
39
|
hasDaemonServiceDefinition,
|
|
36
40
|
readDaemonStatus
|
|
37
|
-
} from "../chunk-
|
|
41
|
+
} from "../chunk-543KNJKC.js";
|
|
38
42
|
import {
|
|
39
43
|
detectProviderLiveCapabilities,
|
|
40
44
|
hasSpawnProvider,
|
|
@@ -50,7 +54,7 @@ import {
|
|
|
50
54
|
import "../chunk-KOPUTJQC.js";
|
|
51
55
|
import {
|
|
52
56
|
getMachineId
|
|
53
|
-
} from "../chunk-
|
|
57
|
+
} from "../chunk-DKDDLF5P.js";
|
|
54
58
|
import {
|
|
55
59
|
claudeJson,
|
|
56
60
|
claudeSettings,
|
|
@@ -90,7 +94,7 @@ import {
|
|
|
90
94
|
keyPrefix,
|
|
91
95
|
readControlMode,
|
|
92
96
|
readKeySource
|
|
93
|
-
} from "../chunk-
|
|
97
|
+
} from "../chunk-V6N4Q223.js";
|
|
94
98
|
import {
|
|
95
99
|
parseFlags
|
|
96
100
|
} from "../chunk-GMXKITVA.js";
|
|
@@ -114,7 +118,7 @@ import {
|
|
|
114
118
|
import {
|
|
115
119
|
EXIT
|
|
116
120
|
} from "../chunk-KZERVKTD.js";
|
|
117
|
-
import "../chunk-
|
|
121
|
+
import "../chunk-XX2V4QS5.js";
|
|
118
122
|
import {
|
|
119
123
|
getBaseUrl
|
|
120
124
|
} from "../chunk-2UMNXADU.js";
|
|
@@ -558,7 +562,8 @@ var main = async () => {
|
|
|
558
562
|
...codexInPlay ? ["codex"] : [],
|
|
559
563
|
...geminiInPlay ? ["gemini"] : []
|
|
560
564
|
];
|
|
561
|
-
const
|
|
565
|
+
const controlCapabilities = detectProviderLiveCapabilities(configuredManagedProviders);
|
|
566
|
+
const controlSupported = hasSpawnProvider(controlCapabilities);
|
|
562
567
|
const controlMode = readControlMode();
|
|
563
568
|
const daemon = readDaemonStatus();
|
|
564
569
|
const serviceDefined = hasDaemonServiceDefinition();
|
|
@@ -571,8 +576,8 @@ var main = async () => {
|
|
|
571
576
|
});
|
|
572
577
|
const controlRequired = controlPolicy === "enabled";
|
|
573
578
|
const controlUnsupported = controlMode === "on" && controlPolicy !== "enabled";
|
|
574
|
-
const daemonOk = controlUnsupported ? false : controlPolicy === "disabled" ? daemon.kind === "absent" && !serviceDefined : controlPolicy === "enabled" ? daemon
|
|
575
|
-
const daemonFailure = daemonOk ? null : controlUnsupported ? "control is required but no usable provider/service-manager pair is available" : controlPolicy === "disabled" ? `control is disabled but ${serviceDefined ? "the service definition remains" : `local state is ${daemon.kind}`}` : controlPolicy === "legacy" ? "a legacy service exists without a usable provider/service-manager pair" : `local state is ${daemon.kind}`;
|
|
579
|
+
const daemonOk = controlUnsupported ? false : controlPolicy === "disabled" ? daemon.kind === "absent" && !serviceDefined : controlPolicy === "enabled" ? daemonHasRemoteProof(daemon) : controlPolicy === "legacy" ? false : daemon.kind === "absent" && !serviceDefined;
|
|
580
|
+
const daemonFailure = daemonOk ? null : controlUnsupported ? "control is required but no usable provider/service-manager pair is available" : controlPolicy === "enabled" && daemon.kind === "running" ? "the daemon has not completed an authenticated heartbeat and control poll" : controlPolicy === "disabled" ? `control is disabled but ${serviceDefined ? "the service definition remains" : `local state is ${daemon.kind}`}` : controlPolicy === "legacy" ? "a legacy service exists without a usable provider/service-manager pair" : `local state is ${daemon.kind}`;
|
|
576
581
|
const daemonDetail = daemonFailure ? controlUnsupported ? `${daemonFailure}; re-run setup with \`--control off\`, or restore both requirements` : controlPolicy === "disabled" ? `${daemonFailure}; re-run setup with \`--control off\`` : controlPolicy === "legacy" ? `${daemonFailure}; run setup with \`--control off\`, or restore both requirements` : `${daemonFailure}; run \`pushary daemon install\` to install or repair the background service` : controlPolicy === "disabled" ? "disabled by setup" : controlPolicy === "preserve-absent" ? "legacy absence preserved" : !controlRequired && daemon.kind === "absent" ? "managed control is unsupported on this provider or operating-system session" : null;
|
|
577
582
|
check(
|
|
578
583
|
daemonOk,
|
|
@@ -584,9 +589,25 @@ var main = async () => {
|
|
|
584
589
|
`daemon ${daemon.daemonVersion ?? "none"}`,
|
|
585
590
|
`installed ${daemon.installedVersion}`,
|
|
586
591
|
`machine ${daemon.machineId ?? "none"}`,
|
|
587
|
-
`heartbeat ${daemon.lastSuccessfulHeartbeatAt ?? "none yet"}
|
|
592
|
+
`heartbeat ${daemon.lastSuccessfulHeartbeatAt ?? "none yet"}`,
|
|
593
|
+
`control ${daemon.lastSuccessfulControlAt ?? "none yet"}`
|
|
588
594
|
].filter((value) => value !== null).join(" \xB7 ")
|
|
589
595
|
);
|
|
596
|
+
if (controlPolicy === "enabled" && apiKey && daemon.machineId) {
|
|
597
|
+
const serverProof = await readMachineReadiness(apiKey, ["spawn", ...controlCapabilities], {
|
|
598
|
+
machineId: daemon.machineId
|
|
599
|
+
});
|
|
600
|
+
if (serverProof.kind === "unsupported") {
|
|
601
|
+
console.log(` ${warn} Remote-control server proof unavailable ${dim(`(${serverProof.detail})`)}`);
|
|
602
|
+
} else {
|
|
603
|
+
check(
|
|
604
|
+
serverProof.kind === "ready",
|
|
605
|
+
"Remote-control server proof",
|
|
606
|
+
serverProof.kind === "ready" ? "heartbeat \xB7 capabilities \xB7 control queue" : serverProof.detail,
|
|
607
|
+
serverProof.kind === "failed" ? "unreachable" : void 0
|
|
608
|
+
);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
590
611
|
const cursorPluginDir2 = cursorPluginDir();
|
|
591
612
|
if (existsSync(cursorPluginDir2)) {
|
|
592
613
|
checking("Cursor");
|
|
@@ -14,13 +14,13 @@ import {
|
|
|
14
14
|
} from "../chunk-GKAKAOKC.js";
|
|
15
15
|
import {
|
|
16
16
|
getMachineId
|
|
17
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-DKDDLF5P.js";
|
|
18
18
|
import "../chunk-GMI5QZLG.js";
|
|
19
19
|
import "../chunk-BSZYIAZL.js";
|
|
20
20
|
import "../chunk-SAF6HGAA.js";
|
|
21
21
|
import "../chunk-7QLSKOSU.js";
|
|
22
22
|
import "../chunk-KZERVKTD.js";
|
|
23
|
-
import "../chunk-
|
|
23
|
+
import "../chunk-XX2V4QS5.js";
|
|
24
24
|
import {
|
|
25
25
|
getApiKey
|
|
26
26
|
} from "../chunk-2UMNXADU.js";
|
|
@@ -10,7 +10,7 @@ import "../chunk-PMHTCDEO.js";
|
|
|
10
10
|
import {
|
|
11
11
|
startProcessOwnership,
|
|
12
12
|
withSpawnProcessOwnership
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-TF247BET.js";
|
|
14
14
|
import {
|
|
15
15
|
spawnClaude
|
|
16
16
|
} from "../chunk-XHKBHWLX.js";
|
|
@@ -19,9 +19,9 @@ import {
|
|
|
19
19
|
} from "../chunk-PZA7G4CN.js";
|
|
20
20
|
import {
|
|
21
21
|
getMachineId
|
|
22
|
-
} from "../chunk-
|
|
22
|
+
} from "../chunk-DKDDLF5P.js";
|
|
23
23
|
import "../chunk-GMI5QZLG.js";
|
|
24
|
-
import "../chunk-
|
|
24
|
+
import "../chunk-XX2V4QS5.js";
|
|
25
25
|
import {
|
|
26
26
|
getApiKey,
|
|
27
27
|
getBaseUrl
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
readLastUserPrompt,
|
|
22
22
|
repoKeyFor,
|
|
23
23
|
reportEvent
|
|
24
|
-
} from "../chunk-
|
|
24
|
+
} from "../chunk-4XZCDSNG.js";
|
|
25
25
|
import {
|
|
26
26
|
DEFAULT_SESSION,
|
|
27
27
|
askUser,
|
|
@@ -39,14 +39,14 @@ import {
|
|
|
39
39
|
} from "../chunk-KOPUTJQC.js";
|
|
40
40
|
import {
|
|
41
41
|
getMachineId
|
|
42
|
-
} from "../chunk-
|
|
42
|
+
} from "../chunk-DKDDLF5P.js";
|
|
43
43
|
import "../chunk-GMI5QZLG.js";
|
|
44
44
|
import "../chunk-BSZYIAZL.js";
|
|
45
45
|
import "../chunk-SAF6HGAA.js";
|
|
46
46
|
import "../chunk-OFRNZWC4.js";
|
|
47
47
|
import "../chunk-7QLSKOSU.js";
|
|
48
48
|
import "../chunk-KZERVKTD.js";
|
|
49
|
-
import "../chunk-
|
|
49
|
+
import "../chunk-XX2V4QS5.js";
|
|
50
50
|
import {
|
|
51
51
|
getApiKey
|
|
52
52
|
} from "../chunk-2UMNXADU.js";
|
package/dist/bin/pushary-hook.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handlePreToolUse
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-EJT2ER6G.js";
|
|
5
5
|
import "../chunk-ATBKJNWS.js";
|
|
6
6
|
import "../chunk-VZKXBFUA.js";
|
|
7
7
|
import {
|
|
8
8
|
readHookInput
|
|
9
9
|
} from "../chunk-6CUUA7HO.js";
|
|
10
10
|
import "../chunk-YHG74UFF.js";
|
|
11
|
-
import "../chunk-
|
|
11
|
+
import "../chunk-4XZCDSNG.js";
|
|
12
12
|
import "../chunk-GKAKAOKC.js";
|
|
13
13
|
import "../chunk-KOPUTJQC.js";
|
|
14
|
-
import "../chunk-
|
|
14
|
+
import "../chunk-DKDDLF5P.js";
|
|
15
15
|
import "../chunk-GMI5QZLG.js";
|
|
16
16
|
import {
|
|
17
17
|
exitOnHelpFlag
|
|
@@ -23,7 +23,7 @@ import "../chunk-SAF6HGAA.js";
|
|
|
23
23
|
import "../chunk-OFRNZWC4.js";
|
|
24
24
|
import "../chunk-7QLSKOSU.js";
|
|
25
25
|
import "../chunk-KZERVKTD.js";
|
|
26
|
-
import "../chunk-
|
|
26
|
+
import "../chunk-XX2V4QS5.js";
|
|
27
27
|
import "../chunk-2UMNXADU.js";
|
|
28
28
|
import "../chunk-L4C2JXJS.js";
|
|
29
29
|
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import {
|
|
14
14
|
readKeySource,
|
|
15
15
|
writeKey
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-V6N4Q223.js";
|
|
17
17
|
import {
|
|
18
18
|
parseFlags
|
|
19
19
|
} from "../chunk-GMXKITVA.js";
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
import {
|
|
34
34
|
EXIT
|
|
35
35
|
} from "../chunk-KZERVKTD.js";
|
|
36
|
-
import "../chunk-
|
|
36
|
+
import "../chunk-XX2V4QS5.js";
|
|
37
37
|
import "../chunk-2UMNXADU.js";
|
|
38
38
|
import {
|
|
39
39
|
isValidApiKey
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import {
|
|
12
12
|
clearKey,
|
|
13
13
|
readKeySource
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-V6N4Q223.js";
|
|
15
15
|
import {
|
|
16
16
|
parseFlags
|
|
17
17
|
} from "../chunk-GMXKITVA.js";
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
import {
|
|
29
29
|
EXIT
|
|
30
30
|
} from "../chunk-KZERVKTD.js";
|
|
31
|
-
import "../chunk-
|
|
31
|
+
import "../chunk-XX2V4QS5.js";
|
|
32
32
|
import {
|
|
33
33
|
getBaseUrl
|
|
34
34
|
} from "../chunk-2UMNXADU.js";
|