@pushary/agent-hooks 0.89.4 → 0.89.5
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/dist/bin/pushary-bell-hook.js +2 -2
- package/dist/bin/pushary-bell.js +4 -4
- package/dist/bin/pushary-claude.js +1 -1
- package/dist/bin/pushary-clean.js +5 -8
- package/dist/bin/pushary-codex-bridge.js +1 -1
- package/dist/bin/pushary-connect.js +3 -3
- package/dist/bin/pushary-daemon.js +24 -29
- package/dist/bin/pushary-disconnect.js +2 -2
- package/dist/bin/pushary-doctor.js +51 -24
- package/dist/bin/pushary-hook.js +2 -2
- package/dist/bin/pushary-login.js +3 -3
- package/dist/bin/pushary-logout.js +3 -3
- package/dist/bin/pushary-mode.js +2 -2
- package/dist/bin/pushary-setup.js +85 -20
- package/dist/bin/pushary-stats.js +2 -2
- package/dist/bin/pushary-status.js +3 -3
- package/dist/bin/pushary-suggestions.js +2 -2
- package/dist/bin/pushary-upgrade.js +54 -25
- package/dist/bin/pushary-wait.js +2 -2
- package/dist/bin/pushary.js +1 -1
- package/dist/{chunk-GPNOHKFO.js → chunk-3XTFX4CL.js} +1 -0
- package/dist/{chunk-W6NPWHBJ.js → chunk-L3YUHEB6.js} +13 -1
- package/dist/{chunk-KJ57OPCC.js → chunk-LURY4WNF.js} +1 -1
- package/dist/chunk-NKHEHEUM.js +56 -0
- package/dist/{chunk-NLMSSKES.js → chunk-TRQ46MXR.js} +68 -8
- package/dist/{chunk-7IJYOBHL.js → chunk-WQGMUIDW.js} +1 -1
- package/package.json +1 -1
- package/dist/chunk-FWUEYXSD.js +0 -29
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handleBell
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-WQGMUIDW.js";
|
|
5
5
|
import {
|
|
6
6
|
readHookInput
|
|
7
7
|
} from "../chunk-6CUUA7HO.js";
|
|
8
|
-
import "../chunk-
|
|
8
|
+
import "../chunk-L3YUHEB6.js";
|
|
9
9
|
import "../chunk-BC3VCZ3E.js";
|
|
10
10
|
import "../chunk-OFRNZWC4.js";
|
|
11
11
|
import "../chunk-6MTNS63X.js";
|
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-WQGMUIDW.js";
|
|
9
9
|
import {
|
|
10
10
|
guardBinary
|
|
11
11
|
} from "../chunk-AIGDBRIJ.js";
|
|
@@ -16,14 +16,14 @@ import {
|
|
|
16
16
|
import {
|
|
17
17
|
createIo
|
|
18
18
|
} from "../chunk-5RUIFDTP.js";
|
|
19
|
-
import "../chunk-
|
|
19
|
+
import "../chunk-L3YUHEB6.js";
|
|
20
20
|
import {
|
|
21
21
|
parseFlags
|
|
22
22
|
} from "../chunk-GMXKITVA.js";
|
|
23
23
|
import {
|
|
24
24
|
exitOnHelpFlag
|
|
25
|
-
} from "../chunk-
|
|
26
|
-
import "../chunk-
|
|
25
|
+
} from "../chunk-LURY4WNF.js";
|
|
26
|
+
import "../chunk-3XTFX4CL.js";
|
|
27
27
|
import "../chunk-BC3VCZ3E.js";
|
|
28
28
|
import "../chunk-DINDL2CF.js";
|
|
29
29
|
import "../chunk-OFRNZWC4.js";
|
|
@@ -14,9 +14,8 @@ import {
|
|
|
14
14
|
import "../chunk-ATBKJNWS.js";
|
|
15
15
|
import "../chunk-AIGDBRIJ.js";
|
|
16
16
|
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
} from "../chunk-NLMSSKES.js";
|
|
17
|
+
disableDaemonService
|
|
18
|
+
} from "../chunk-TRQ46MXR.js";
|
|
20
19
|
import "../chunk-XHKBHWLX.js";
|
|
21
20
|
import {
|
|
22
21
|
execNpm
|
|
@@ -48,8 +47,8 @@ import {
|
|
|
48
47
|
} from "../chunk-GMXKITVA.js";
|
|
49
48
|
import {
|
|
50
49
|
exitOnHelpFlag
|
|
51
|
-
} from "../chunk-
|
|
52
|
-
import "../chunk-
|
|
50
|
+
} from "../chunk-LURY4WNF.js";
|
|
51
|
+
import "../chunk-3XTFX4CL.js";
|
|
53
52
|
import {
|
|
54
53
|
removeClaudeAlias
|
|
55
54
|
} from "../chunk-BC3VCZ3E.js";
|
|
@@ -148,9 +147,7 @@ var guardedDaemonRemoval = async () => {
|
|
|
148
147
|
wouldNote("stop and uninstall", "Pushary background service");
|
|
149
148
|
return true;
|
|
150
149
|
}
|
|
151
|
-
|
|
152
|
-
const detached = await stopDaemonRunning();
|
|
153
|
-
return service.kind === "ok" && detached.kind !== "unavailable";
|
|
150
|
+
return (await disableDaemonService()).kind === "ok";
|
|
154
151
|
};
|
|
155
152
|
var guardedInstructionBlockRemoval = (path) => {
|
|
156
153
|
if (!dryRun) return removeInstructionBlock(path);
|
|
@@ -16,14 +16,14 @@ import {
|
|
|
16
16
|
} from "../chunk-5RUIFDTP.js";
|
|
17
17
|
import {
|
|
18
18
|
readKeySource
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-L3YUHEB6.js";
|
|
20
20
|
import {
|
|
21
21
|
parseFlags
|
|
22
22
|
} from "../chunk-GMXKITVA.js";
|
|
23
23
|
import {
|
|
24
24
|
exitOnHelpFlag
|
|
25
|
-
} from "../chunk-
|
|
26
|
-
import "../chunk-
|
|
25
|
+
} from "../chunk-LURY4WNF.js";
|
|
26
|
+
import "../chunk-3XTFX4CL.js";
|
|
27
27
|
import "../chunk-BC3VCZ3E.js";
|
|
28
28
|
import "../chunk-DINDL2CF.js";
|
|
29
29
|
import "../chunk-BSZYIAZL.js";
|
|
@@ -13,14 +13,11 @@ import {
|
|
|
13
13
|
replaceDaemonService,
|
|
14
14
|
requestDaemonHandoff,
|
|
15
15
|
stopDaemonRunning
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-TRQ46MXR.js";
|
|
17
17
|
import {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
CODEX_RESUME_CAPABILITY,
|
|
22
|
-
geminiLiveCapabilities
|
|
23
|
-
} from "../chunk-FWUEYXSD.js";
|
|
18
|
+
detectProviderLiveCapabilities,
|
|
19
|
+
hasSpawnProvider
|
|
20
|
+
} from "../chunk-NKHEHEUM.js";
|
|
24
21
|
import {
|
|
25
22
|
findLiveProcessBySpawnId,
|
|
26
23
|
ownsLiveProcess
|
|
@@ -29,9 +26,7 @@ import {
|
|
|
29
26
|
spawnClaude
|
|
30
27
|
} from "../chunk-XHKBHWLX.js";
|
|
31
28
|
import {
|
|
32
|
-
resolveBinary
|
|
33
|
-
resolveGlobalPackageVersion,
|
|
34
|
-
resolvePackageVersionFromBinary
|
|
29
|
+
resolveBinary
|
|
35
30
|
} from "../chunk-PZA7G4CN.js";
|
|
36
31
|
import {
|
|
37
32
|
getMachineId
|
|
@@ -39,8 +34,8 @@ import {
|
|
|
39
34
|
import "../chunk-V37ZXMH3.js";
|
|
40
35
|
import {
|
|
41
36
|
exitOnHelpFlag
|
|
42
|
-
} from "../chunk-
|
|
43
|
-
import "../chunk-
|
|
37
|
+
} from "../chunk-LURY4WNF.js";
|
|
38
|
+
import "../chunk-3XTFX4CL.js";
|
|
44
39
|
import "../chunk-DINDL2CF.js";
|
|
45
40
|
import {
|
|
46
41
|
EXIT
|
|
@@ -174,8 +169,14 @@ var isAuthFailure = (err) => {
|
|
|
174
169
|
if (candidate.name !== "DrainError") return false;
|
|
175
170
|
return candidate.status === 401 || candidate.status === 403;
|
|
176
171
|
};
|
|
172
|
+
var normalizeLaunchAgent = (requestedAgent) => {
|
|
173
|
+
if (requestedAgent === void 0 || requestedAgent === "claude") return "claude";
|
|
174
|
+
if (requestedAgent === "codex" || requestedAgent === "gemini") return requestedAgent;
|
|
175
|
+
return null;
|
|
176
|
+
};
|
|
177
177
|
var providerLaunchError = (requestedAgent, binaries) => {
|
|
178
|
-
const agent = requestedAgent
|
|
178
|
+
const agent = normalizeLaunchAgent(requestedAgent);
|
|
179
|
+
if (!agent) return `Unsupported agent provider: ${requestedAgent}`;
|
|
179
180
|
if (binaries[agent]) return null;
|
|
180
181
|
return agent === "claude" ? "Claude Code is not installed on this machine" : `${agent === "codex" ? "Codex" : "Gemini"} CLI is not installed on this machine`;
|
|
181
182
|
};
|
|
@@ -200,7 +201,8 @@ var resolveSpawnDirectory = (requested, options = {}) => {
|
|
|
200
201
|
var isFlagShapedPrompt = (prompt) => prompt.trimStart().startsWith("-");
|
|
201
202
|
var buildSpawnLaunch = (req, opts) => {
|
|
202
203
|
if (isFlagShapedPrompt(req.prompt)) return null;
|
|
203
|
-
const agent = req.agent
|
|
204
|
+
const agent = normalizeLaunchAgent(req.agent);
|
|
205
|
+
if (!agent) return null;
|
|
204
206
|
const model = typeof req.model === "string" && req.model.length > 0 ? ["--model", req.model] : [];
|
|
205
207
|
if (agent === "claude") {
|
|
206
208
|
const claudeArgs = ["claude", "--remote", ...model, "-p", req.prompt];
|
|
@@ -239,12 +241,7 @@ var runSpawnDaemon = async () => {
|
|
|
239
241
|
const machineId = getMachineId();
|
|
240
242
|
const baseUrl = getBaseUrl();
|
|
241
243
|
const pusharyBin = resolveBinary("pushary") ?? "pushary";
|
|
242
|
-
const
|
|
243
|
-
const codexBin = resolveBinary("codex");
|
|
244
|
-
const geminiBin = resolveBinary("gemini");
|
|
245
|
-
const geminiCapabilities = geminiBin ? geminiLiveCapabilities(
|
|
246
|
-
resolvePackageVersionFromBinary(geminiBin, "@google/gemini-cli") ?? resolveGlobalPackageVersion("@google/gemini-cli")
|
|
247
|
-
) : [];
|
|
244
|
+
const providerCapabilities = detectProviderLiveCapabilities();
|
|
248
245
|
const siblingEntry = process.argv[1] ? join(dirname(process.argv[1]), "pushary.js") : "";
|
|
249
246
|
const codexBridgeEntry = process.argv[1] ? join(dirname(process.argv[1]), "pushary-codex-bridge.js") : "pushary-codex-bridge";
|
|
250
247
|
const geminiBridgeEntry = process.argv[1] ? join(dirname(process.argv[1]), "pushary-gemini-bridge.js") : "pushary-gemini-bridge";
|
|
@@ -294,7 +291,8 @@ var runSpawnDaemon = async () => {
|
|
|
294
291
|
}
|
|
295
292
|
const directory = resolveSpawnDirectory(req.cwd);
|
|
296
293
|
if (!directory.ok) return Promise.reject(new Error(directory.message));
|
|
297
|
-
const agent = req.agent
|
|
294
|
+
const agent = normalizeLaunchAgent(req.agent);
|
|
295
|
+
if (!agent) return Promise.reject(new Error(`Unsupported agent provider: ${req.agent}`));
|
|
298
296
|
const providerBin = resolveBinary(agent);
|
|
299
297
|
const unavailable = providerLaunchError(req.agent, {
|
|
300
298
|
claude: agent === "claude" ? providerBin ?? null : null,
|
|
@@ -542,12 +540,10 @@ var runSpawnDaemon = async () => {
|
|
|
542
540
|
const result = await sendHeartbeat(apiKey, {
|
|
543
541
|
repoKey: basename(process.cwd()),
|
|
544
542
|
capabilities: [
|
|
545
|
-
"spawn",
|
|
543
|
+
...hasSpawnProvider(providerCapabilities) ? ["spawn"] : [],
|
|
546
544
|
STOP_CAPABILITY,
|
|
547
545
|
STOP_ACK_CAPABILITY,
|
|
548
|
-
...
|
|
549
|
-
...codexBin ? [CODEX_BRIDGE_CAPABILITY, CODEX_RESUME_CAPABILITY] : [],
|
|
550
|
-
...geminiCapabilities
|
|
546
|
+
...providerCapabilities
|
|
551
547
|
]
|
|
552
548
|
});
|
|
553
549
|
if (result.kind === "ok") daemonLease.recordSuccessfulHeartbeat();
|
|
@@ -563,10 +559,9 @@ var runSpawnDaemon = async () => {
|
|
|
563
559
|
versionWatch = setInterval(() => {
|
|
564
560
|
if (daemonLease.shouldYield()) finish();
|
|
565
561
|
}, VERSION_CHECK_INTERVAL_MS);
|
|
566
|
-
stderr(
|
|
567
|
-
|
|
568
|
-
`
|
|
569
|
-
);
|
|
562
|
+
stderr(hasSpawnProvider(providerCapabilities) ? `[pushary] daemon online \u2014 this machine (${machineId}) can now be sent a new session from your phone. Ctrl-C to stop.
|
|
563
|
+
` : `[pushary] daemon online \u2014 no supported Claude, Codex, or Gemini CLI was found, so phone-start is unavailable. Ctrl-C to stop.
|
|
564
|
+
`);
|
|
570
565
|
timer = setTimeout(tick, FAST_POLL_MS);
|
|
571
566
|
const signals = daemonSignals();
|
|
572
567
|
await new Promise((resolve) => {
|
|
@@ -32,8 +32,8 @@ import {
|
|
|
32
32
|
} from "../chunk-V37ZXMH3.js";
|
|
33
33
|
import {
|
|
34
34
|
exitOnHelpFlag
|
|
35
|
-
} from "../chunk-
|
|
36
|
-
import "../chunk-
|
|
35
|
+
} from "../chunk-LURY4WNF.js";
|
|
36
|
+
import "../chunk-3XTFX4CL.js";
|
|
37
37
|
import "../chunk-DINDL2CF.js";
|
|
38
38
|
import "../chunk-KZERVKTD.js";
|
|
39
39
|
import "../chunk-L4C2JXJS.js";
|
|
@@ -31,8 +31,15 @@ import {
|
|
|
31
31
|
import "../chunk-ATBKJNWS.js";
|
|
32
32
|
import "../chunk-AIGDBRIJ.js";
|
|
33
33
|
import {
|
|
34
|
+
daemonServiceManagerAvailable,
|
|
35
|
+
hasDaemonServiceDefinition,
|
|
34
36
|
readDaemonStatus
|
|
35
|
-
} from "../chunk-
|
|
37
|
+
} from "../chunk-TRQ46MXR.js";
|
|
38
|
+
import {
|
|
39
|
+
detectProviderLiveCapabilities,
|
|
40
|
+
hasSpawnProvider,
|
|
41
|
+
resolveControlPolicy
|
|
42
|
+
} from "../chunk-NKHEHEUM.js";
|
|
36
43
|
import "../chunk-XHKBHWLX.js";
|
|
37
44
|
import {
|
|
38
45
|
execNpm
|
|
@@ -81,15 +88,16 @@ import {
|
|
|
81
88
|
} from "../chunk-5RUIFDTP.js";
|
|
82
89
|
import {
|
|
83
90
|
keyPrefix,
|
|
91
|
+
readControlMode,
|
|
84
92
|
readKeySource
|
|
85
|
-
} from "../chunk-
|
|
93
|
+
} from "../chunk-L3YUHEB6.js";
|
|
86
94
|
import {
|
|
87
95
|
parseFlags
|
|
88
96
|
} from "../chunk-GMXKITVA.js";
|
|
89
97
|
import {
|
|
90
98
|
exitOnHelpFlag
|
|
91
|
-
} from "../chunk-
|
|
92
|
-
import "../chunk-
|
|
99
|
+
} from "../chunk-LURY4WNF.js";
|
|
100
|
+
import "../chunk-3XTFX4CL.js";
|
|
93
101
|
import "../chunk-BC3VCZ3E.js";
|
|
94
102
|
import {
|
|
95
103
|
getPackageVersion
|
|
@@ -354,23 +362,6 @@ var main = async () => {
|
|
|
354
362
|
break;
|
|
355
363
|
}
|
|
356
364
|
}
|
|
357
|
-
const daemon = readDaemonStatus();
|
|
358
|
-
const daemonOk = daemon.kind === "running";
|
|
359
|
-
const daemonFailure = daemonOk ? null : `local state is ${daemon.kind}`;
|
|
360
|
-
const daemonDetail = daemonFailure ? `${daemonFailure}; run \`pushary daemon install\` to install or repair the background service` : null;
|
|
361
|
-
check(
|
|
362
|
-
daemonOk,
|
|
363
|
-
"Remote-control daemon",
|
|
364
|
-
[
|
|
365
|
-
daemonDetail,
|
|
366
|
-
daemon.kind,
|
|
367
|
-
`pid ${daemon.pid ?? "none"}`,
|
|
368
|
-
`daemon ${daemon.daemonVersion ?? "none"}`,
|
|
369
|
-
`installed ${daemon.installedVersion}`,
|
|
370
|
-
`machine ${daemon.machineId ?? "none"}`,
|
|
371
|
-
`heartbeat ${daemon.lastSuccessfulHeartbeatAt ?? "none yet"}`
|
|
372
|
-
].filter((value) => value !== null).join(" \xB7 ")
|
|
373
|
-
);
|
|
374
365
|
const CLAUDE_JSON = claudeJson();
|
|
375
366
|
const claudeInPlay = claudeWired({
|
|
376
367
|
claudeJson: readJson(CLAUDE_JSON),
|
|
@@ -438,11 +429,12 @@ var main = async () => {
|
|
|
438
429
|
codexParsed = parseTOML(codexConfig);
|
|
439
430
|
} catch {
|
|
440
431
|
}
|
|
441
|
-
|
|
432
|
+
const codexInPlay = codexWired({
|
|
442
433
|
config: codexParsed,
|
|
443
434
|
hooks: codexHooksConfig,
|
|
444
435
|
skillExists: existsSync(join(codexSkillDir(), "SKILL.md"))
|
|
445
|
-
})
|
|
436
|
+
});
|
|
437
|
+
if (codexInPlay) {
|
|
446
438
|
checking("Codex");
|
|
447
439
|
const codexMcp = codexParsed.mcp_servers?.pushary;
|
|
448
440
|
const codexTransport = !!codexMcp && (typeof codexMcp.url === "string" || typeof codexMcp.command === "string");
|
|
@@ -517,7 +509,8 @@ var main = async () => {
|
|
|
517
509
|
}
|
|
518
510
|
const geminiSettingsPath = geminiSettings();
|
|
519
511
|
const geminiSettings2 = readJson(geminiSettingsPath);
|
|
520
|
-
|
|
512
|
+
const geminiInPlay = geminiSettings2 !== null && geminiWired({ settings: geminiSettings2 });
|
|
513
|
+
if (geminiInPlay) {
|
|
521
514
|
checking("Gemini CLI");
|
|
522
515
|
const geminiServers = geminiSettings2.mcpServers ?? {};
|
|
523
516
|
const geminiPushary = geminiServers.pushary;
|
|
@@ -560,6 +553,40 @@ var main = async () => {
|
|
|
560
553
|
} else {
|
|
561
554
|
skipped("Gemini CLI", installed("gemini_cli") ? "installed, but Pushary is not set up for it" : "not installed");
|
|
562
555
|
}
|
|
556
|
+
const configuredManagedProviders = [
|
|
557
|
+
...claudeInPlay ? ["claude"] : [],
|
|
558
|
+
...codexInPlay ? ["codex"] : [],
|
|
559
|
+
...geminiInPlay ? ["gemini"] : []
|
|
560
|
+
];
|
|
561
|
+
const controlSupported = hasSpawnProvider(detectProviderLiveCapabilities(configuredManagedProviders));
|
|
562
|
+
const controlMode = readControlMode();
|
|
563
|
+
const daemon = readDaemonStatus();
|
|
564
|
+
const serviceDefined = hasDaemonServiceDefinition();
|
|
565
|
+
const managerAvailable = daemonServiceManagerAvailable();
|
|
566
|
+
const controlPolicy = resolveControlPolicy({
|
|
567
|
+
mode: controlMode,
|
|
568
|
+
providerAvailable: controlSupported,
|
|
569
|
+
managerAvailable,
|
|
570
|
+
servicePresent: serviceDefined || daemon.kind !== "absent"
|
|
571
|
+
});
|
|
572
|
+
const controlRequired = controlPolicy === "enabled";
|
|
573
|
+
const controlUnsupported = controlMode === "on" && controlPolicy !== "enabled";
|
|
574
|
+
const daemonOk = controlUnsupported ? false : controlPolicy === "disabled" ? daemon.kind === "absent" && !serviceDefined : controlPolicy === "enabled" ? daemon.kind === "running" : controlPolicy === "legacy" ? false : daemon.kind === "absent" && !serviceDefined;
|
|
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}`;
|
|
576
|
+
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
|
+
check(
|
|
578
|
+
daemonOk,
|
|
579
|
+
"Remote-control daemon",
|
|
580
|
+
[
|
|
581
|
+
daemonDetail,
|
|
582
|
+
daemon.kind,
|
|
583
|
+
`pid ${daemon.pid ?? "none"}`,
|
|
584
|
+
`daemon ${daemon.daemonVersion ?? "none"}`,
|
|
585
|
+
`installed ${daemon.installedVersion}`,
|
|
586
|
+
`machine ${daemon.machineId ?? "none"}`,
|
|
587
|
+
`heartbeat ${daemon.lastSuccessfulHeartbeatAt ?? "none yet"}`
|
|
588
|
+
].filter((value) => value !== null).join(" \xB7 ")
|
|
589
|
+
);
|
|
563
590
|
const cursorPluginDir2 = cursorPluginDir();
|
|
564
591
|
if (existsSync(cursorPluginDir2)) {
|
|
565
592
|
checking("Cursor");
|
package/dist/bin/pushary-hook.js
CHANGED
|
@@ -15,8 +15,8 @@ import "../chunk-2HYPZLYY.js";
|
|
|
15
15
|
import "../chunk-V37ZXMH3.js";
|
|
16
16
|
import {
|
|
17
17
|
exitOnHelpFlag
|
|
18
|
-
} from "../chunk-
|
|
19
|
-
import "../chunk-
|
|
18
|
+
} from "../chunk-LURY4WNF.js";
|
|
19
|
+
import "../chunk-3XTFX4CL.js";
|
|
20
20
|
import "../chunk-DINDL2CF.js";
|
|
21
21
|
import "../chunk-BSZYIAZL.js";
|
|
22
22
|
import "../chunk-SAF6HGAA.js";
|
|
@@ -13,14 +13,14 @@ import {
|
|
|
13
13
|
import {
|
|
14
14
|
readKeySource,
|
|
15
15
|
writeKey
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-L3YUHEB6.js";
|
|
17
17
|
import {
|
|
18
18
|
parseFlags
|
|
19
19
|
} from "../chunk-GMXKITVA.js";
|
|
20
20
|
import {
|
|
21
21
|
exitOnHelpFlag
|
|
22
|
-
} from "../chunk-
|
|
23
|
-
import "../chunk-
|
|
22
|
+
} from "../chunk-LURY4WNF.js";
|
|
23
|
+
import "../chunk-3XTFX4CL.js";
|
|
24
24
|
import "../chunk-BC3VCZ3E.js";
|
|
25
25
|
import {
|
|
26
26
|
getPackageVersion
|
|
@@ -11,14 +11,14 @@ import {
|
|
|
11
11
|
import {
|
|
12
12
|
clearKey,
|
|
13
13
|
readKeySource
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-L3YUHEB6.js";
|
|
15
15
|
import {
|
|
16
16
|
parseFlags
|
|
17
17
|
} from "../chunk-GMXKITVA.js";
|
|
18
18
|
import {
|
|
19
19
|
exitOnHelpFlag
|
|
20
|
-
} from "../chunk-
|
|
21
|
-
import "../chunk-
|
|
20
|
+
} from "../chunk-LURY4WNF.js";
|
|
21
|
+
import "../chunk-3XTFX4CL.js";
|
|
22
22
|
import "../chunk-BC3VCZ3E.js";
|
|
23
23
|
import "../chunk-DINDL2CF.js";
|
|
24
24
|
import "../chunk-OFRNZWC4.js";
|
package/dist/bin/pushary-mode.js
CHANGED
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
} from "../chunk-GMXKITVA.js";
|
|
12
12
|
import {
|
|
13
13
|
exitOnHelpFlag
|
|
14
|
-
} from "../chunk-
|
|
15
|
-
import "../chunk-
|
|
14
|
+
} from "../chunk-LURY4WNF.js";
|
|
15
|
+
import "../chunk-3XTFX4CL.js";
|
|
16
16
|
import "../chunk-DINDL2CF.js";
|
|
17
17
|
import "../chunk-SAF6HGAA.js";
|
|
18
18
|
import {
|
|
@@ -50,9 +50,18 @@ import {
|
|
|
50
50
|
guardedArgv
|
|
51
51
|
} from "../chunk-AIGDBRIJ.js";
|
|
52
52
|
import {
|
|
53
|
+
daemonServiceManagerAvailable,
|
|
54
|
+
disableDaemonService,
|
|
53
55
|
ensureDaemonRunning,
|
|
56
|
+
hasDaemonServiceDefinition,
|
|
57
|
+
readDaemonStatus,
|
|
54
58
|
replaceDaemonService
|
|
55
|
-
} from "../chunk-
|
|
59
|
+
} from "../chunk-TRQ46MXR.js";
|
|
60
|
+
import {
|
|
61
|
+
detectProviderLiveCapabilities,
|
|
62
|
+
hasSpawnProvider,
|
|
63
|
+
resolveControlPolicy
|
|
64
|
+
} from "../chunk-NKHEHEUM.js";
|
|
56
65
|
import "../chunk-XHKBHWLX.js";
|
|
57
66
|
import {
|
|
58
67
|
installGlobally,
|
|
@@ -108,15 +117,16 @@ import {
|
|
|
108
117
|
exportLine,
|
|
109
118
|
keyPrefix,
|
|
110
119
|
readConfigFileKey,
|
|
120
|
+
readControlMode,
|
|
111
121
|
readKeySource,
|
|
112
122
|
writeKey
|
|
113
|
-
} from "../chunk-
|
|
123
|
+
} from "../chunk-L3YUHEB6.js";
|
|
114
124
|
import {
|
|
115
125
|
parseFlags
|
|
116
126
|
} from "../chunk-GMXKITVA.js";
|
|
117
127
|
import {
|
|
118
128
|
renderCommandHelp
|
|
119
|
-
} from "../chunk-
|
|
129
|
+
} from "../chunk-3XTFX4CL.js";
|
|
120
130
|
import {
|
|
121
131
|
installClaudeAlias,
|
|
122
132
|
resolveShellRc
|
|
@@ -487,6 +497,12 @@ var parseVerifyMode = (raw) => {
|
|
|
487
497
|
if (VERIFY_MODES.includes(value)) return value;
|
|
488
498
|
throw new UsageError(`--verify must be one of: ${VERIFY_MODES.join(", ")} (got ${raw})`);
|
|
489
499
|
};
|
|
500
|
+
var CONTROL_MODES = ["auto", "on", "off"];
|
|
501
|
+
var parseControlMode = (raw) => {
|
|
502
|
+
const value = raw.trim().toLowerCase();
|
|
503
|
+
if (CONTROL_MODES.includes(value)) return value;
|
|
504
|
+
throw new UsageError(`--control must be one of: ${CONTROL_MODES.join(", ")} (got ${raw})`);
|
|
505
|
+
};
|
|
490
506
|
var effectiveVerify = (options, context) => {
|
|
491
507
|
if (options.verifyExplicit) return options.verify;
|
|
492
508
|
if (options.verify === "roundtrip") return "roundtrip";
|
|
@@ -494,8 +510,9 @@ var effectiveVerify = (options, context) => {
|
|
|
494
510
|
};
|
|
495
511
|
var SETUP_FLAGS = {
|
|
496
512
|
bools: ["key-stdin", "skip-phone", "yes", "y", "json", "dry-run", "help", "h"],
|
|
497
|
-
values: ["key", "connect", "agents", "verify"]
|
|
513
|
+
values: ["key", "connect", "agents", "verify", "control"]
|
|
498
514
|
};
|
|
515
|
+
var effectiveControlMode = (options, stored, configPresent) => options.controlExplicit ? options.control : stored ?? (configPresent ? null : options.control);
|
|
499
516
|
var isAgentChoice = (value) => AGENT_CHOICES.includes(value);
|
|
500
517
|
var parseAgentSelection = (raw, yes) => {
|
|
501
518
|
if (raw === void 0) {
|
|
@@ -532,6 +549,7 @@ var parseSetupOptions = (input2) => {
|
|
|
532
549
|
const connectRaw = flags.values.get("connect");
|
|
533
550
|
const connectMode = connectRaw === void 0 ? "app" : parseConnectMode(connectRaw);
|
|
534
551
|
const verifyRaw = flags.values.get("verify");
|
|
552
|
+
const controlRaw = flags.values.get("control");
|
|
535
553
|
const nonInteractive = yes || agentsFlag !== void 0 || flags.bools.has("json") || !input2.stdinIsTty;
|
|
536
554
|
const verify = verifyRaw !== void 0 ? parseVerifyMode(verifyRaw) : nonInteractive ? "push" : "roundtrip";
|
|
537
555
|
const key = flags.values.get("key")?.trim() || null;
|
|
@@ -567,7 +585,9 @@ var parseSetupOptions = (input2) => {
|
|
|
567
585
|
key,
|
|
568
586
|
keyStdin,
|
|
569
587
|
verify,
|
|
570
|
-
verifyExplicit: verifyRaw !== void 0
|
|
588
|
+
verifyExplicit: verifyRaw !== void 0,
|
|
589
|
+
control: controlRaw === void 0 ? "auto" : parseControlMode(controlRaw),
|
|
590
|
+
controlExplicit: controlRaw !== void 0
|
|
571
591
|
};
|
|
572
592
|
};
|
|
573
593
|
|
|
@@ -719,7 +739,9 @@ var checkForUpdates = async (current) => {
|
|
|
719
739
|
} catch {
|
|
720
740
|
}
|
|
721
741
|
};
|
|
742
|
+
var globalInstallReady = false;
|
|
722
743
|
var installGlobally2 = async () => {
|
|
744
|
+
if (globalInstallReady) return;
|
|
723
745
|
const version = getPackageVersion();
|
|
724
746
|
await spinner(`Installing pushary-hook globally (${version})`, async () => {
|
|
725
747
|
try {
|
|
@@ -728,6 +750,7 @@ var installGlobally2 = async () => {
|
|
|
728
750
|
throw new Error(npmErrorMessage(err));
|
|
729
751
|
}
|
|
730
752
|
});
|
|
753
|
+
globalInstallReady = true;
|
|
731
754
|
};
|
|
732
755
|
var _cachedSkillContent = null;
|
|
733
756
|
var fetchSkillContent = async () => {
|
|
@@ -1346,10 +1369,10 @@ ${pluginLocationSnippet(VSCODE_PLUGIN_DIR)}`
|
|
|
1346
1369
|
console.log(` ${dim("\u2022")} Fully quit and reopen VS Code to load the plugin`);
|
|
1347
1370
|
noteManual("Fully quit and reopen VS Code. A Reload Window may not pick up a new plugin location.");
|
|
1348
1371
|
};
|
|
1349
|
-
var saveApiKey = async (apiKey) => {
|
|
1372
|
+
var saveApiKey = async (apiKey, controlMode) => {
|
|
1350
1373
|
let result;
|
|
1351
1374
|
await spinner("Saving your API key", async () => {
|
|
1352
|
-
result = writeKey(apiKey);
|
|
1375
|
+
result = writeKey(apiKey, controlMode === null ? {} : { controlMode });
|
|
1353
1376
|
});
|
|
1354
1377
|
if (!result) throw new Error("Could not save the API key");
|
|
1355
1378
|
if (result.configBackupPath) {
|
|
@@ -1702,7 +1725,7 @@ var AGENT_TARGETS = {
|
|
|
1702
1725
|
],
|
|
1703
1726
|
custom: ["nothing (prints connection details only)"]
|
|
1704
1727
|
};
|
|
1705
|
-
var reportDryRun = (apiKey, agents, keyCheck) => {
|
|
1728
|
+
var reportDryRun = (apiKey, agents, keyCheck, controlMode) => {
|
|
1706
1729
|
console.log();
|
|
1707
1730
|
console.log(` ${bold("Dry run")} ${dim("\u2014 nothing below has been written")}`);
|
|
1708
1731
|
console.log();
|
|
@@ -1710,6 +1733,7 @@ var reportDryRun = (apiKey, agents, keyCheck) => {
|
|
|
1710
1733
|
apiKey ? ` ${dim("Key:")} ${dim(`${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`)} ${dim(`(${keyCheck?.kind ?? "not verified"})`)}` : ` ${dim("Key:")} ${dim("none on this machine \u2014 a real run would acquire one")}`
|
|
1711
1734
|
);
|
|
1712
1735
|
console.log(` ${dim("Key store:")} ${PUSHARY_CONFIG_FILE}`);
|
|
1736
|
+
console.log(` ${dim("Control:")} ${controlMode ?? "unchanged (legacy install)"}`);
|
|
1713
1737
|
const rc = resolveShellRc();
|
|
1714
1738
|
console.log(` ${dim("Shell rc:")} ${rc ? rc.path : dim("none for this shell; the export line would be printed instead")}`);
|
|
1715
1739
|
console.log();
|
|
@@ -1748,6 +1772,7 @@ var main = async () => {
|
|
|
1748
1772
|
`);
|
|
1749
1773
|
process.exit(EXIT.OK);
|
|
1750
1774
|
}
|
|
1775
|
+
const controlMode = effectiveControlMode(options, readControlMode(), existsSync(PUSHARY_CONFIG_FILE));
|
|
1751
1776
|
recordSetupOptions(options);
|
|
1752
1777
|
if (options.json) {
|
|
1753
1778
|
jsonMode = true;
|
|
@@ -1806,8 +1831,8 @@ var main = async () => {
|
|
|
1806
1831
|
console.log();
|
|
1807
1832
|
markStep("resolve-agents");
|
|
1808
1833
|
const plannedAgents = await resolveAgents(options);
|
|
1809
|
-
reportDryRun(null, plannedAgents, null);
|
|
1810
|
-
emitJson(options, { ok: true, dryRun: true, agents: plannedAgents, keyCheck: "skipped", key: "none" });
|
|
1834
|
+
reportDryRun(null, plannedAgents, null, controlMode);
|
|
1835
|
+
emitJson(options, { ok: true, dryRun: true, agents: plannedAgents, control: controlMode, keyCheck: "skipped", key: "none" });
|
|
1811
1836
|
process.exit(EXIT.OK);
|
|
1812
1837
|
} else if (connectMode === "app" && canShowPairingQr() && !options.skipPhone) {
|
|
1813
1838
|
console.log(` ${dim("Pairing with your Pushary app.")}`);
|
|
@@ -1894,12 +1919,12 @@ var main = async () => {
|
|
|
1894
1919
|
markStep("resolve-agents");
|
|
1895
1920
|
const agents = await resolveAgents(options);
|
|
1896
1921
|
if (options.dryRun) {
|
|
1897
|
-
reportDryRun(trimmedKey, agents, keyCheck);
|
|
1898
|
-
emitJson(options, { ok: true, dryRun: true, agents, keyCheck: keyCheck?.kind ?? "skipped" });
|
|
1922
|
+
reportDryRun(trimmedKey, agents, keyCheck, controlMode);
|
|
1923
|
+
emitJson(options, { ok: true, dryRun: true, agents, control: controlMode, keyCheck: keyCheck?.kind ?? "skipped" });
|
|
1899
1924
|
process.exit(EXIT.OK);
|
|
1900
1925
|
}
|
|
1901
1926
|
markStep("save-key");
|
|
1902
|
-
const rc = await saveApiKey(trimmedKey);
|
|
1927
|
+
const rc = await saveApiKey(trimmedKey, controlMode);
|
|
1903
1928
|
const context = { rc };
|
|
1904
1929
|
if (envKey && envKey !== trimmedKey) {
|
|
1905
1930
|
noteManual(
|
|
@@ -1909,6 +1934,7 @@ var main = async () => {
|
|
|
1909
1934
|
const failed = [];
|
|
1910
1935
|
const completed = [];
|
|
1911
1936
|
const skipped = [];
|
|
1937
|
+
let controlDisableFailure = null;
|
|
1912
1938
|
if (agents.length === 0) {
|
|
1913
1939
|
console.log(`
|
|
1914
1940
|
${check} API key saved. No agents configured.`);
|
|
@@ -1947,6 +1973,16 @@ var main = async () => {
|
|
|
1947
1973
|
await offerClaudeAlias(options);
|
|
1948
1974
|
}
|
|
1949
1975
|
}
|
|
1976
|
+
if (controlMode === "off") {
|
|
1977
|
+
markStep("control:disable");
|
|
1978
|
+
const disabled = await disableDaemonService();
|
|
1979
|
+
if (disabled.kind !== "ok") {
|
|
1980
|
+
controlDisableFailure = disabled.detail;
|
|
1981
|
+
console.log(` ${yellow("!")} Could not fully disable phone-start: ${controlDisableFailure}`);
|
|
1982
|
+
} else {
|
|
1983
|
+
console.log(` ${check} Phone-start background service disabled.`);
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1950
1986
|
markStep("connect-phone");
|
|
1951
1987
|
const skipPhone = options.skipPhone;
|
|
1952
1988
|
let phone = null;
|
|
@@ -2008,6 +2044,8 @@ var main = async () => {
|
|
|
2008
2044
|
failed,
|
|
2009
2045
|
keyCheck: "locked",
|
|
2010
2046
|
rc: rc.kind,
|
|
2047
|
+
control: controlMode,
|
|
2048
|
+
daemon: controlMode === "off" ? controlDisableFailure ? "unavailable" : "disabled" : "skipped",
|
|
2011
2049
|
exitCode: report.exitCode
|
|
2012
2050
|
});
|
|
2013
2051
|
await reportSetupOutcome({
|
|
@@ -2028,11 +2066,35 @@ var main = async () => {
|
|
|
2028
2066
|
const reachesYou = phone?.reachesYou ?? true;
|
|
2029
2067
|
markStep("closing");
|
|
2030
2068
|
const keyIsTrusted = keyFromPairing || keyCheck?.kind === "ok";
|
|
2031
|
-
const
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2069
|
+
const managedControlAgents = ["claude_code", "codex", "gemini_cli"];
|
|
2070
|
+
const configuredControlAgents = managedControlAgents.filter((agent) => agentIsWired(agent));
|
|
2071
|
+
const controlCapabilities = detectProviderLiveCapabilities(configuredControlAgents.map(
|
|
2072
|
+
(agent) => agent === "claude_code" ? "claude" : agent === "gemini_cli" ? "gemini" : agent
|
|
2073
|
+
));
|
|
2074
|
+
const providerAvailable = hasSpawnProvider(controlCapabilities);
|
|
2075
|
+
const managerAvailable = daemonServiceManagerAvailable();
|
|
2076
|
+
const servicePresent = readDaemonStatus().kind !== "absent" || hasDaemonServiceDefinition();
|
|
2077
|
+
const controlPolicy = resolveControlPolicy({
|
|
2078
|
+
mode: controlMode,
|
|
2079
|
+
providerAvailable,
|
|
2080
|
+
managerAvailable,
|
|
2081
|
+
servicePresent
|
|
2082
|
+
});
|
|
2083
|
+
if (controlMode === "on" && controlPolicy !== "enabled") {
|
|
2084
|
+
console.log(` ${yellow("!")} Phone-start was required, but this machine has no supported provider or native background-service manager.`);
|
|
2085
|
+
} else if (controlPolicy === "legacy") {
|
|
2086
|
+
console.log(` ${yellow("!")} A legacy phone-start service cannot be safely adopted in this session. Disable it with --control off or restore its provider and native service manager.`);
|
|
2087
|
+
}
|
|
2088
|
+
const daemon = keyIsTrusted && controlPolicy === "enabled" ? await (async () => {
|
|
2089
|
+
try {
|
|
2090
|
+
await installGlobally2();
|
|
2091
|
+
const service = await replaceDaemonService();
|
|
2092
|
+
return service.kind === "ok" ? ensureDaemonRunning({ spawnDaemon: () => {
|
|
2093
|
+
} }) : { kind: "unavailable", detail: service.detail };
|
|
2094
|
+
} catch (err) {
|
|
2095
|
+
return { kind: "unavailable", detail: formatError(err) };
|
|
2096
|
+
}
|
|
2097
|
+
})() : controlMode === "on" || controlPolicy === "legacy" ? { kind: "unavailable", detail: "Managed control is required but no usable provider/service-manager pair is available" } : null;
|
|
2036
2098
|
const closing = describeClosing({
|
|
2037
2099
|
agentsOk,
|
|
2038
2100
|
configuredNothing,
|
|
@@ -2040,7 +2102,7 @@ var main = async () => {
|
|
|
2040
2102
|
failed,
|
|
2041
2103
|
reachChecked,
|
|
2042
2104
|
reachesYou,
|
|
2043
|
-
daemonReady: daemon === null ? null : daemon.kind === "running" || daemon.kind === "started",
|
|
2105
|
+
daemonReady: controlDisableFailure ? false : daemon === null ? null : daemon.kind === "running" || daemon.kind === "started",
|
|
2044
2106
|
// null when the check did not run, so it changes nothing. Only an outright
|
|
2045
2107
|
// `false` is allowed to hold back "Setup complete.".
|
|
2046
2108
|
roundTripAnswered: roundTrip === null ? null : roundTrip.kind === "answered" ? true : roundTrip.kind === "unanswered" ? false : null
|
|
@@ -2085,7 +2147,10 @@ var main = async () => {
|
|
|
2085
2147
|
roundTrip: roundTrip === null ? "skipped" : roundTrip.kind,
|
|
2086
2148
|
rc: rc.kind,
|
|
2087
2149
|
rcPath: rc.path,
|
|
2088
|
-
daemon: daemon?.kind ?? "skipped",
|
|
2150
|
+
daemon: controlMode === "off" ? controlDisableFailure ? "unavailable" : "disabled" : controlPolicy === "unsupported" || controlPolicy === "preserve-absent" ? "unsupported" : daemon?.kind ?? "skipped",
|
|
2151
|
+
control: controlMode,
|
|
2152
|
+
controlPolicy,
|
|
2153
|
+
controlCapabilities,
|
|
2089
2154
|
exitCode
|
|
2090
2155
|
});
|
|
2091
2156
|
if (exitCode !== EXIT.OK) {
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
} from "../chunk-VZKXBFUA.js";
|
|
5
5
|
import {
|
|
6
6
|
exitOnHelpFlag
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-LURY4WNF.js";
|
|
8
|
+
import "../chunk-3XTFX4CL.js";
|
|
9
9
|
import "../chunk-DINDL2CF.js";
|
|
10
10
|
import "../chunk-KZERVKTD.js";
|
|
11
11
|
import {
|
|
@@ -20,14 +20,14 @@ import {
|
|
|
20
20
|
} from "../chunk-5RUIFDTP.js";
|
|
21
21
|
import {
|
|
22
22
|
readKeySource
|
|
23
|
-
} from "../chunk-
|
|
23
|
+
} from "../chunk-L3YUHEB6.js";
|
|
24
24
|
import {
|
|
25
25
|
rejectUnknownFlags
|
|
26
26
|
} from "../chunk-GMXKITVA.js";
|
|
27
27
|
import {
|
|
28
28
|
exitOnHelpFlag
|
|
29
|
-
} from "../chunk-
|
|
30
|
-
import "../chunk-
|
|
29
|
+
} from "../chunk-LURY4WNF.js";
|
|
30
|
+
import "../chunk-3XTFX4CL.js";
|
|
31
31
|
import "../chunk-BC3VCZ3E.js";
|
|
32
32
|
import "../chunk-DINDL2CF.js";
|
|
33
33
|
import "../chunk-BSZYIAZL.js";
|
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
} from "../chunk-GMXKITVA.js";
|
|
8
8
|
import {
|
|
9
9
|
exitOnHelpFlag
|
|
10
|
-
} from "../chunk-
|
|
11
|
-
import "../chunk-
|
|
10
|
+
} from "../chunk-LURY4WNF.js";
|
|
11
|
+
import "../chunk-3XTFX4CL.js";
|
|
12
12
|
import "../chunk-DINDL2CF.js";
|
|
13
13
|
import {
|
|
14
14
|
UsageError
|
|
@@ -16,9 +16,18 @@ import {
|
|
|
16
16
|
guardBinary
|
|
17
17
|
} from "../chunk-AIGDBRIJ.js";
|
|
18
18
|
import {
|
|
19
|
+
daemonServiceManagerAvailable,
|
|
20
|
+
disableDaemonService,
|
|
19
21
|
ensureDaemonRunning,
|
|
22
|
+
hasDaemonServiceDefinition,
|
|
23
|
+
readDaemonStatus,
|
|
20
24
|
replaceDaemonService
|
|
21
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-TRQ46MXR.js";
|
|
26
|
+
import {
|
|
27
|
+
detectProviderLiveCapabilities,
|
|
28
|
+
hasSpawnProvider,
|
|
29
|
+
resolveControlPolicy
|
|
30
|
+
} from "../chunk-NKHEHEUM.js";
|
|
22
31
|
import {
|
|
23
32
|
needsShell
|
|
24
33
|
} from "../chunk-XHKBHWLX.js";
|
|
@@ -44,13 +53,18 @@ import {
|
|
|
44
53
|
vscodePluginDir,
|
|
45
54
|
vscodePluginMcp
|
|
46
55
|
} from "../chunk-V37ZXMH3.js";
|
|
56
|
+
import {
|
|
57
|
+
readControlMode
|
|
58
|
+
} from "../chunk-L3YUHEB6.js";
|
|
47
59
|
import {
|
|
48
60
|
exitOnHelpFlag
|
|
49
|
-
} from "../chunk-
|
|
50
|
-
import "../chunk-
|
|
61
|
+
} from "../chunk-LURY4WNF.js";
|
|
62
|
+
import "../chunk-3XTFX4CL.js";
|
|
63
|
+
import "../chunk-BC3VCZ3E.js";
|
|
51
64
|
import {
|
|
52
65
|
isNewerVersion
|
|
53
66
|
} from "../chunk-DINDL2CF.js";
|
|
67
|
+
import "../chunk-OFRNZWC4.js";
|
|
54
68
|
import "../chunk-KZERVKTD.js";
|
|
55
69
|
import {
|
|
56
70
|
readJsonSafe
|
|
@@ -92,7 +106,7 @@ var reapplyClaudeSettings = (apiKey, paths = {}) => {
|
|
|
92
106
|
const settings = readJson(settingsPath);
|
|
93
107
|
const claudeJson2 = readJson(claudeJsonPath);
|
|
94
108
|
const configured = settings != null && hasPusharyClaudeHooks(settings) || claudeJson2 != null && hasPusharyMcp(claudeJson2);
|
|
95
|
-
if (!configured) return { reapplied: false, hooks: false, mcp: false };
|
|
109
|
+
if (!configured) return { configured: false, reapplied: false, hooks: false, mcp: false };
|
|
96
110
|
const settingsWritable = settings != null;
|
|
97
111
|
const claudeJsonWritable = claudeJson2 != null;
|
|
98
112
|
let hooks = false;
|
|
@@ -116,7 +130,7 @@ var reapplyClaudeSettings = (apiKey, paths = {}) => {
|
|
|
116
130
|
} catch {
|
|
117
131
|
}
|
|
118
132
|
}
|
|
119
|
-
return { reapplied: hooks || mcp, hooks, mcp };
|
|
133
|
+
return { configured: true, reapplied: hooks || mcp, hooks, mcp };
|
|
120
134
|
};
|
|
121
135
|
var readToml = (filePath) => {
|
|
122
136
|
try {
|
|
@@ -132,7 +146,7 @@ var reapplyCodexSettings = (apiKey, paths = {}) => {
|
|
|
132
146
|
const config = readToml(configPath);
|
|
133
147
|
const hooksConfig = readJson(hooksPath);
|
|
134
148
|
const configured = config != null && !!config.mcp_servers?.pushary || hooksConfig != null && hasCodexHooks(hooksConfig);
|
|
135
|
-
if (!configured) return { reapplied: false, hooks: false, mcp: false };
|
|
149
|
+
if (!configured) return { configured: false, reapplied: false, hooks: false, mcp: false };
|
|
136
150
|
const command = guardBinary(resolveGlobalBinary(CODEX_HOOK_BINARY) ?? CODEX_HOOK_BINARY);
|
|
137
151
|
let hooks = false;
|
|
138
152
|
let mcp = false;
|
|
@@ -155,14 +169,14 @@ var reapplyCodexSettings = (apiKey, paths = {}) => {
|
|
|
155
169
|
} catch {
|
|
156
170
|
}
|
|
157
171
|
}
|
|
158
|
-
return { reapplied: hooks || mcp, hooks, mcp };
|
|
172
|
+
return { configured: true, reapplied: hooks || mcp, hooks, mcp };
|
|
159
173
|
};
|
|
160
174
|
var reapplyGeminiSettings = (apiKey, paths = {}) => {
|
|
161
175
|
const settingsPath = paths.settingsPath ?? join(homedir(), ".gemini", "settings.json");
|
|
162
176
|
const settings = readJson(settingsPath);
|
|
163
|
-
if (settings == null) return { reapplied: false, hooks: false, mcp: false };
|
|
177
|
+
if (settings == null) return { configured: false, reapplied: false, hooks: false, mcp: false };
|
|
164
178
|
const configured = hasGeminiHooks(settings) || !!settings.mcpServers?.pushary;
|
|
165
|
-
if (!configured) return { reapplied: false, hooks: false, mcp: false };
|
|
179
|
+
if (!configured) return { configured: false, reapplied: false, hooks: false, mcp: false };
|
|
166
180
|
let hooks = false;
|
|
167
181
|
let mcp = false;
|
|
168
182
|
try {
|
|
@@ -175,20 +189,20 @@ var reapplyGeminiSettings = (apiKey, paths = {}) => {
|
|
|
175
189
|
writeJson(settingsPath, settings);
|
|
176
190
|
} catch {
|
|
177
191
|
}
|
|
178
|
-
return { reapplied: hooks || mcp, hooks, mcp };
|
|
192
|
+
return { configured: true, reapplied: hooks || mcp, hooks, mcp };
|
|
179
193
|
};
|
|
180
194
|
var reapplyPluginMcp = (mcpPath, apiKey) => {
|
|
181
|
-
if (!apiKey) return { reapplied: false, hooks: false, mcp: false };
|
|
182
195
|
const mcpConfig = readJson(mcpPath);
|
|
183
|
-
if (mcpConfig == null) return { reapplied: false, hooks: false, mcp: false };
|
|
196
|
+
if (mcpConfig == null) return { configured: false, reapplied: false, hooks: false, mcp: false };
|
|
184
197
|
const servers = mcpConfig.mcpServers;
|
|
185
|
-
if (!servers?.pushary) return { reapplied: false, hooks: false, mcp: false };
|
|
198
|
+
if (!servers?.pushary) return { configured: false, reapplied: false, hooks: false, mcp: false };
|
|
199
|
+
if (!apiKey) return { configured: true, reapplied: false, hooks: false, mcp: false };
|
|
186
200
|
try {
|
|
187
201
|
addClaudeMcpServer(mcpConfig, apiKey);
|
|
188
202
|
writeJson(mcpPath, mcpConfig);
|
|
189
|
-
return { reapplied: true, hooks: false, mcp: true };
|
|
203
|
+
return { configured: true, reapplied: true, hooks: false, mcp: true };
|
|
190
204
|
} catch {
|
|
191
|
-
return { reapplied: false, hooks: false, mcp: false };
|
|
205
|
+
return { configured: true, reapplied: false, hooks: false, mcp: false };
|
|
192
206
|
}
|
|
193
207
|
};
|
|
194
208
|
var reapplyCursorPlugin = (apiKey, paths = {}) => reapplyPluginMcp(
|
|
@@ -198,17 +212,17 @@ var reapplyCursorPlugin = (apiKey, paths = {}) => reapplyPluginMcp(
|
|
|
198
212
|
var reapplyVsCodePlugin = (apiKey, paths = {}) => reapplyPluginMcp(paths.pluginMcpPath ?? vscodePluginMcp(), apiKey);
|
|
199
213
|
var reapplyAllAgents = (apiKey) => {
|
|
200
214
|
const runners = [
|
|
201
|
-
{ label: "Claude Code", run: () => reapplyClaudeSettings(apiKey) },
|
|
202
|
-
{ label: "Codex", run: () => reapplyCodexSettings(apiKey) },
|
|
203
|
-
{ label: "Gemini CLI", run: () => reapplyGeminiSettings(apiKey) },
|
|
204
|
-
{ label: "Cursor", run: () => reapplyCursorPlugin(apiKey) },
|
|
205
|
-
{ label: "VS Code", run: () => reapplyVsCodePlugin(apiKey) }
|
|
215
|
+
{ id: "claude", label: "Claude Code", run: () => reapplyClaudeSettings(apiKey) },
|
|
216
|
+
{ id: "codex", label: "Codex", run: () => reapplyCodexSettings(apiKey) },
|
|
217
|
+
{ id: "gemini", label: "Gemini CLI", run: () => reapplyGeminiSettings(apiKey) },
|
|
218
|
+
{ id: "cursor", label: "Cursor", run: () => reapplyCursorPlugin(apiKey) },
|
|
219
|
+
{ id: "vscode", label: "VS Code", run: () => reapplyVsCodePlugin(apiKey) }
|
|
206
220
|
];
|
|
207
221
|
const done = [];
|
|
208
222
|
for (const runner of runners) {
|
|
209
223
|
try {
|
|
210
224
|
const result = runner.run();
|
|
211
|
-
if (result.
|
|
225
|
+
if (result.configured) done.push({ id: runner.id, label: runner.label, result });
|
|
212
226
|
} catch {
|
|
213
227
|
}
|
|
214
228
|
}
|
|
@@ -278,13 +292,28 @@ var finishUpgrade = async () => {
|
|
|
278
292
|
} catch {
|
|
279
293
|
apiKey = void 0;
|
|
280
294
|
}
|
|
281
|
-
const
|
|
295
|
+
const inspectedAgents = reapplyAllAgents(apiKey);
|
|
296
|
+
const refreshed = inspectedAgents.filter((agent) => agent.result.reapplied);
|
|
297
|
+
const configuredControlProviders = inspectedAgents.filter((agent) => agent.result.configured && (agent.id === "claude" || agent.id === "codex" || agent.id === "gemini")).map((agent) => agent.id);
|
|
298
|
+
const controlMode = readControlMode();
|
|
299
|
+
const daemonStatus = readDaemonStatus();
|
|
300
|
+
const serviceWasPresent = daemonStatus.kind !== "absent" || hasDaemonServiceDefinition();
|
|
301
|
+
const controlPolicy = resolveControlPolicy({
|
|
302
|
+
mode: controlMode,
|
|
303
|
+
providerAvailable: hasSpawnProvider(detectProviderLiveCapabilities(configuredControlProviders)),
|
|
304
|
+
managerAvailable: daemonServiceManagerAvailable(),
|
|
305
|
+
servicePresent: serviceWasPresent
|
|
306
|
+
});
|
|
282
307
|
let daemonReady = true;
|
|
283
|
-
if (
|
|
308
|
+
if (controlPolicy === "disabled" && serviceWasPresent) {
|
|
309
|
+
daemonReady = (await disableDaemonService()).kind === "ok";
|
|
310
|
+
} else if (apiKey && controlPolicy === "enabled") {
|
|
284
311
|
const service = await replaceDaemonService();
|
|
285
312
|
const daemon = service.kind === "ok" ? await ensureDaemonRunning({ spawnDaemon: () => {
|
|
286
313
|
} }) : null;
|
|
287
314
|
daemonReady = service.kind === "ok" && (daemon?.kind === "running" || daemon?.kind === "started");
|
|
315
|
+
} else if (controlPolicy === "legacy" || controlMode === "on" && controlPolicy === "unsupported") {
|
|
316
|
+
daemonReady = false;
|
|
288
317
|
}
|
|
289
318
|
console.log();
|
|
290
319
|
if (refreshed.length > 0) {
|
|
@@ -302,11 +331,11 @@ var finishUpgrade = async () => {
|
|
|
302
331
|
}
|
|
303
332
|
console.log();
|
|
304
333
|
if (!daemonReady) {
|
|
305
|
-
console.error("Upgrade installed, but the background service did not start. Run: pushary daemon install");
|
|
334
|
+
console.error(controlPolicy === "disabled" ? "Upgrade installed, but the disabled background service could not be fully removed. Re-run setup with --control off." : controlPolicy === "legacy" ? "Upgrade installed, but a legacy background service cannot be safely adopted in this session. Run setup with --control off, or restore its provider and native service manager." : "Upgrade installed, but the background service did not start. Run: pushary daemon install");
|
|
306
335
|
process.exitCode = 1;
|
|
307
336
|
return;
|
|
308
337
|
}
|
|
309
|
-
console.log("Done. Your hooks and background service use the new global install.");
|
|
338
|
+
console.log(controlPolicy === "disabled" ? "Done. Your hooks use the new global install; phone-start remains disabled." : controlPolicy === "unsupported" || controlPolicy === "preserve-absent" ? "Done. Your hooks use the new global install; no background service was added." : "Done. Your hooks and background service use the new global install.");
|
|
310
339
|
console.log("Verify with: pushary doctor");
|
|
311
340
|
};
|
|
312
341
|
var main = async () => {
|
package/dist/bin/pushary-wait.js
CHANGED
|
@@ -14,8 +14,8 @@ import {
|
|
|
14
14
|
} from "../chunk-GMXKITVA.js";
|
|
15
15
|
import {
|
|
16
16
|
exitOnHelpFlag
|
|
17
|
-
} from "../chunk-
|
|
18
|
-
import "../chunk-
|
|
17
|
+
} from "../chunk-LURY4WNF.js";
|
|
18
|
+
import "../chunk-3XTFX4CL.js";
|
|
19
19
|
import "../chunk-DINDL2CF.js";
|
|
20
20
|
import "../chunk-SAF6HGAA.js";
|
|
21
21
|
import {
|
package/dist/bin/pushary.js
CHANGED
|
@@ -132,6 +132,7 @@ var SETUP_OPTIONS = [
|
|
|
132
132
|
["--connect browser", "Approve in a browser tab instead. For a machine with no app"],
|
|
133
133
|
["--connect web", "Legacy browser subscribe page"],
|
|
134
134
|
["--connect none", "Skip the phone connect step, same as --skip-phone"],
|
|
135
|
+
["--control auto|on|off", "Manage phone-start automatically (default), require it, or disable its background service"],
|
|
135
136
|
["--skip-phone", "Skip the phone connect step"],
|
|
136
137
|
["--verify roundtrip", "Send a real question and wait for you to answer it (default when a human is present)"],
|
|
137
138
|
["--verify push", "Only prove a notification was delivered. Automatic when nobody is at the terminal"],
|
|
@@ -121,7 +121,12 @@ var writeKey = (apiKey, options = {}) => {
|
|
|
121
121
|
}
|
|
122
122
|
writeJsonAtomic(
|
|
123
123
|
configPath,
|
|
124
|
-
{
|
|
124
|
+
{
|
|
125
|
+
...current,
|
|
126
|
+
apiKey,
|
|
127
|
+
installSource: resolveInstallSourceFor(current),
|
|
128
|
+
...options.controlMode ? { controlMode: options.controlMode } : {}
|
|
129
|
+
},
|
|
125
130
|
KEY_FILE_MODE
|
|
126
131
|
);
|
|
127
132
|
restrictFile(configPath);
|
|
@@ -177,6 +182,12 @@ var readConfigKey = (configPath) => {
|
|
|
177
182
|
return key || null;
|
|
178
183
|
};
|
|
179
184
|
var readConfigFileKey = () => readConfigKey(configFilePath());
|
|
185
|
+
var readControlMode = () => {
|
|
186
|
+
const result = readJsonSafe(configFilePath());
|
|
187
|
+
if (result.kind !== "ok") return null;
|
|
188
|
+
const value = result.value.controlMode;
|
|
189
|
+
return value === "auto" || value === "on" || value === "off" ? value : null;
|
|
190
|
+
};
|
|
180
191
|
var readKeySource = () => {
|
|
181
192
|
const configPath = configFilePath();
|
|
182
193
|
const envKey = process.env.PUSHARY_API_KEY?.trim() || null;
|
|
@@ -194,5 +205,6 @@ export {
|
|
|
194
205
|
writeKey,
|
|
195
206
|
clearKey,
|
|
196
207
|
readConfigFileKey,
|
|
208
|
+
readControlMode,
|
|
197
209
|
readKeySource
|
|
198
210
|
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveBinary,
|
|
3
|
+
resolveGlobalPackageVersion,
|
|
4
|
+
resolvePackageVersionFromBinary
|
|
5
|
+
} from "./chunk-PZA7G4CN.js";
|
|
6
|
+
|
|
7
|
+
// src/live-capabilities.ts
|
|
8
|
+
var CLAUDE_BRIDGE_CAPABILITY = "claude-bridge";
|
|
9
|
+
var CLAUDE_RESUME_CAPABILITY = "claude-resume";
|
|
10
|
+
var CODEX_BRIDGE_CAPABILITY = "codex-bridge";
|
|
11
|
+
var CODEX_RESUME_CAPABILITY = "codex-resume";
|
|
12
|
+
var GEMINI_BRIDGE_CAPABILITY = "gemini-bridge";
|
|
13
|
+
var GEMINI_RESUME_CAPABILITY = "gemini-resume";
|
|
14
|
+
var GEMINI_BRIDGE_MIN_VERSION = [0, 40, 0];
|
|
15
|
+
var version = (raw) => {
|
|
16
|
+
const match = raw?.match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
17
|
+
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
|
|
18
|
+
};
|
|
19
|
+
var geminiLiveCapabilities = (rawVersion) => {
|
|
20
|
+
const installed = version(rawVersion);
|
|
21
|
+
if (!installed) return [];
|
|
22
|
+
for (let index = 0; index < GEMINI_BRIDGE_MIN_VERSION.length; index++) {
|
|
23
|
+
if (installed[index] > GEMINI_BRIDGE_MIN_VERSION[index]) break;
|
|
24
|
+
if (installed[index] < GEMINI_BRIDGE_MIN_VERSION[index]) return [];
|
|
25
|
+
}
|
|
26
|
+
return [GEMINI_BRIDGE_CAPABILITY, GEMINI_RESUME_CAPABILITY];
|
|
27
|
+
};
|
|
28
|
+
var providerLiveCapabilities = (probe) => [
|
|
29
|
+
...probe.claude ? [CLAUDE_BRIDGE_CAPABILITY, CLAUDE_RESUME_CAPABILITY] : [],
|
|
30
|
+
...probe.codex ? [CODEX_BRIDGE_CAPABILITY, CODEX_RESUME_CAPABILITY] : [],
|
|
31
|
+
...geminiLiveCapabilities(probe.geminiVersion)
|
|
32
|
+
];
|
|
33
|
+
var hasSpawnProvider = (capabilities) => capabilities.some(
|
|
34
|
+
(capability) => capability === CLAUDE_BRIDGE_CAPABILITY || capability === CODEX_BRIDGE_CAPABILITY || capability === GEMINI_BRIDGE_CAPABILITY
|
|
35
|
+
);
|
|
36
|
+
var resolveControlPolicy = (input) => {
|
|
37
|
+
if (input.mode === "off") return "disabled";
|
|
38
|
+
if (input.mode === null && !input.servicePresent) return "preserve-absent";
|
|
39
|
+
if (input.providerAvailable && input.managerAvailable) return "enabled";
|
|
40
|
+
return input.servicePresent ? "legacy" : "unsupported";
|
|
41
|
+
};
|
|
42
|
+
var detectProviderLiveCapabilities = (providers = ["claude", "codex", "gemini"]) => {
|
|
43
|
+
const enabled = new Set(providers);
|
|
44
|
+
const geminiBin = enabled.has("gemini") ? resolveBinary("gemini") : void 0;
|
|
45
|
+
return providerLiveCapabilities({
|
|
46
|
+
claude: enabled.has("claude") && resolveBinary("claude") !== void 0,
|
|
47
|
+
codex: enabled.has("codex") && resolveBinary("codex") !== void 0,
|
|
48
|
+
geminiVersion: geminiBin ? resolvePackageVersionFromBinary(geminiBin, "@google/gemini-cli") ?? resolveGlobalPackageVersion("@google/gemini-cli") : void 0
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export {
|
|
53
|
+
hasSpawnProvider,
|
|
54
|
+
resolveControlPolicy,
|
|
55
|
+
detectProviderLiveCapabilities
|
|
56
|
+
};
|
|
@@ -30,6 +30,31 @@ import { createHash, randomUUID } from "crypto";
|
|
|
30
30
|
import { homedir } from "os";
|
|
31
31
|
import { execFileSync } from "child_process";
|
|
32
32
|
var daemonNeedsHandoff = (status) => status.kind === "version-mismatch" || status.kind === "configuration-mismatch" || status.kind === "unresponsive" && status.processAlive === true;
|
|
33
|
+
var daemonServiceManagerAvailable = (options = {}) => {
|
|
34
|
+
const platform = options.platform ?? process.platform;
|
|
35
|
+
const run = options.run ?? ((command, args) => {
|
|
36
|
+
execFileSync(command, [...args], { stdio: "ignore", windowsHide: true });
|
|
37
|
+
});
|
|
38
|
+
try {
|
|
39
|
+
if (platform === "darwin") {
|
|
40
|
+
const uid = options.uid ?? process.getuid?.();
|
|
41
|
+
if (uid === void 0) return false;
|
|
42
|
+
run("launchctl", ["print", `gui/${uid}`]);
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
if (platform === "linux") {
|
|
46
|
+
run("systemctl", ["--user", "show-environment"]);
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
if (platform === "win32") {
|
|
50
|
+
run("sc.exe", ["query", "Schedule"]);
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
return false;
|
|
54
|
+
} catch {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
33
58
|
var statePath = (dir) => join(dir, "daemon-state.json");
|
|
34
59
|
var lockPath = (dir) => join(dir, "daemon.lock");
|
|
35
60
|
var targetPath = (dir) => join(dir, "daemon-target.json");
|
|
@@ -78,7 +103,8 @@ var buildDaemonService = (input) => {
|
|
|
78
103
|
],
|
|
79
104
|
start: [{ command: "launchctl", args: ["kickstart", "-k", target] }],
|
|
80
105
|
stop: [{ command: "launchctl", args: ["kill", "SIGTERM", target], ignoreFailure: true }],
|
|
81
|
-
uninstall: [{ command: "launchctl", args: ["bootout", domain, definitionPath], ignoreFailure: true }]
|
|
106
|
+
uninstall: [{ command: "launchctl", args: ["bootout", domain, definitionPath], ignoreFailure: true }],
|
|
107
|
+
registrationProbe: { command: "launchctl", args: ["print", target] }
|
|
82
108
|
};
|
|
83
109
|
}
|
|
84
110
|
if (input.platform === "linux") {
|
|
@@ -111,6 +137,7 @@ WantedBy=default.target
|
|
|
111
137
|
uninstall: [
|
|
112
138
|
{ command: "systemctl", args: ["--user", "disable", "--now", unit], ignoreFailure: true }
|
|
113
139
|
],
|
|
140
|
+
registrationProbe: { command: "systemctl", args: ["--user", "is-enabled", unit] },
|
|
114
141
|
reloadAfterUninstall: { command: "systemctl", args: ["--user", "daemon-reload"] }
|
|
115
142
|
};
|
|
116
143
|
}
|
|
@@ -148,7 +175,8 @@ WantedBy=default.target
|
|
|
148
175
|
],
|
|
149
176
|
start: [{ command: "schtasks.exe", args: ["/Run", "/TN", taskName] }],
|
|
150
177
|
stop: [{ command: "schtasks.exe", args: ["/End", "/TN", taskName], ignoreFailure: true }],
|
|
151
|
-
uninstall: [{ command: "schtasks.exe", args: ["/Delete", "/TN", taskName, "/F"], ignoreFailure: true }]
|
|
178
|
+
uninstall: [{ command: "schtasks.exe", args: ["/Delete", "/TN", taskName, "/F"], ignoreFailure: true }],
|
|
179
|
+
registrationProbe: { command: "schtasks.exe", args: ["/Query", "/TN", taskName] }
|
|
152
180
|
};
|
|
153
181
|
}
|
|
154
182
|
return null;
|
|
@@ -179,12 +207,6 @@ var resolveDaemonServiceDefinition = (options = {}) => {
|
|
|
179
207
|
}
|
|
180
208
|
}
|
|
181
209
|
}
|
|
182
|
-
const argvEntry = options.argvEntry ?? process.argv[1];
|
|
183
|
-
if (!daemonEntry && argvEntry) {
|
|
184
|
-
const path = platform === "win32" ? win32Path : { dirname, join };
|
|
185
|
-
const candidate = path.join(path.dirname(argvEntry), "pushary-daemon.js");
|
|
186
|
-
if (exists(candidate)) daemonEntry = candidate;
|
|
187
|
-
}
|
|
188
210
|
if (!daemonEntry || !exists(daemonEntry)) return null;
|
|
189
211
|
const homeDir = options.homeDir ?? homedir();
|
|
190
212
|
return buildDaemonService({
|
|
@@ -212,6 +234,13 @@ var applyDaemonService = (action, definition, options = {}) => {
|
|
|
212
234
|
}
|
|
213
235
|
}
|
|
214
236
|
if (action === "uninstall") {
|
|
237
|
+
let registered = false;
|
|
238
|
+
try {
|
|
239
|
+
run(definition.registrationProbe.command, definition.registrationProbe.args);
|
|
240
|
+
registered = true;
|
|
241
|
+
} catch {
|
|
242
|
+
}
|
|
243
|
+
if (registered) throw new Error("Native background service remains registered");
|
|
215
244
|
safeUnlink(definition.definitionPath);
|
|
216
245
|
const reload = definition.reloadAfterUninstall;
|
|
217
246
|
if (reload) run(reload.command, reload.args);
|
|
@@ -251,8 +280,23 @@ var manageDaemonService = (action, options = {}) => {
|
|
|
251
280
|
detail: "Could not find the globally installed daemon entry. Run Pushary setup again."
|
|
252
281
|
};
|
|
253
282
|
}
|
|
283
|
+
if (action === "uninstall" && !daemonServiceManagerAvailable(options)) {
|
|
284
|
+
return { kind: "failed", detail: "Native background-service manager is unavailable" };
|
|
285
|
+
}
|
|
254
286
|
return applyDaemonService(action, definition, { run: options.run });
|
|
255
287
|
};
|
|
288
|
+
var hasDaemonServiceDefinition = (options = {}) => {
|
|
289
|
+
const definition = buildDaemonService({
|
|
290
|
+
platform: options.platform ?? process.platform,
|
|
291
|
+
homeDir: options.homeDir ?? homedir(),
|
|
292
|
+
stateDir: options.stateDir ?? pusharyDir(),
|
|
293
|
+
execPath: options.execPath ?? process.execPath,
|
|
294
|
+
daemonEntry: options.daemonEntry ?? process.execPath,
|
|
295
|
+
pathEnv: options.pathEnv ?? process.env.PATH ?? "",
|
|
296
|
+
uid: options.uid ?? process.getuid?.()
|
|
297
|
+
});
|
|
298
|
+
return definition !== null && existsSync(definition.definitionPath);
|
|
299
|
+
};
|
|
256
300
|
var spawnDetachedDaemon = (plan, options = {}) => {
|
|
257
301
|
const spawnImpl = options.spawnImpl ?? spawnClaude;
|
|
258
302
|
const child = spawnImpl(plan.command, plan.args, {
|
|
@@ -515,6 +559,19 @@ var stopDaemonRunning = async (options = {}) => {
|
|
|
515
559
|
safeUnlink(lockPath(dir));
|
|
516
560
|
return { kind: "stopped" };
|
|
517
561
|
};
|
|
562
|
+
var disableDaemonService = async (options = {}) => {
|
|
563
|
+
const platform = options.platform ?? process.platform;
|
|
564
|
+
const supported = ["darwin", "linux", "win32"].includes(platform);
|
|
565
|
+
const managerAvailable = supported && daemonServiceManagerAvailable(options);
|
|
566
|
+
const definitionPresent = supported && hasDaemonServiceDefinition(options);
|
|
567
|
+
const service = definitionPresent && !managerAvailable ? { kind: "failed", detail: "Native background-service manager is unavailable" } : managerAvailable ? manageDaemonService("uninstall", options) : { kind: "ok" };
|
|
568
|
+
const stopped = await stopDaemonRunning(options);
|
|
569
|
+
const failures = [
|
|
570
|
+
service.kind === "ok" ? null : service.detail,
|
|
571
|
+
stopped.kind === "unavailable" ? stopped.detail : null
|
|
572
|
+
].filter((detail) => detail !== null);
|
|
573
|
+
return failures.length > 0 ? { kind: "failed", detail: failures.join("; ") } : { kind: "ok" };
|
|
574
|
+
};
|
|
518
575
|
var replaceDaemonService = async (options = {}) => {
|
|
519
576
|
const stopped = await stopDaemonRunning(options);
|
|
520
577
|
return stopped.kind === "unavailable" ? stopped : manageDaemonService("install", options);
|
|
@@ -576,13 +633,16 @@ var ensureDaemonRunning = async (options = {}) => {
|
|
|
576
633
|
};
|
|
577
634
|
|
|
578
635
|
export {
|
|
636
|
+
daemonServiceManagerAvailable,
|
|
579
637
|
DAEMON_LEASE_RENEW_INTERVAL_MS,
|
|
580
638
|
parseDaemonAction,
|
|
581
639
|
manageDaemonService,
|
|
640
|
+
hasDaemonServiceDefinition,
|
|
582
641
|
readDaemonStatus,
|
|
583
642
|
acquireDaemonLease,
|
|
584
643
|
requestDaemonHandoff,
|
|
585
644
|
stopDaemonRunning,
|
|
645
|
+
disableDaemonService,
|
|
586
646
|
replaceDaemonService,
|
|
587
647
|
ensureDaemonRunning
|
|
588
648
|
};
|
package/package.json
CHANGED
package/dist/chunk-FWUEYXSD.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
// src/live-capabilities.ts
|
|
2
|
-
var CLAUDE_BRIDGE_CAPABILITY = "claude-bridge";
|
|
3
|
-
var CLAUDE_RESUME_CAPABILITY = "claude-resume";
|
|
4
|
-
var CODEX_BRIDGE_CAPABILITY = "codex-bridge";
|
|
5
|
-
var CODEX_RESUME_CAPABILITY = "codex-resume";
|
|
6
|
-
var GEMINI_BRIDGE_CAPABILITY = "gemini-bridge";
|
|
7
|
-
var GEMINI_RESUME_CAPABILITY = "gemini-resume";
|
|
8
|
-
var GEMINI_BRIDGE_MIN_VERSION = [0, 40, 0];
|
|
9
|
-
var version = (raw) => {
|
|
10
|
-
const match = raw?.match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
11
|
-
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
|
|
12
|
-
};
|
|
13
|
-
var geminiLiveCapabilities = (rawVersion) => {
|
|
14
|
-
const installed = version(rawVersion);
|
|
15
|
-
if (!installed) return [];
|
|
16
|
-
for (let index = 0; index < GEMINI_BRIDGE_MIN_VERSION.length; index++) {
|
|
17
|
-
if (installed[index] > GEMINI_BRIDGE_MIN_VERSION[index]) break;
|
|
18
|
-
if (installed[index] < GEMINI_BRIDGE_MIN_VERSION[index]) return [];
|
|
19
|
-
}
|
|
20
|
-
return [GEMINI_BRIDGE_CAPABILITY, GEMINI_RESUME_CAPABILITY];
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export {
|
|
24
|
-
CLAUDE_BRIDGE_CAPABILITY,
|
|
25
|
-
CLAUDE_RESUME_CAPABILITY,
|
|
26
|
-
CODEX_BRIDGE_CAPABILITY,
|
|
27
|
-
CODEX_RESUME_CAPABILITY,
|
|
28
|
-
geminiLiveCapabilities
|
|
29
|
-
};
|