@wbern/cc-ping 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +62 -55
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -701,6 +701,7 @@ __export(daemon_exports, {
|
|
|
701
701
|
daemonPidPath: () => daemonPidPath,
|
|
702
702
|
daemonStopPath: () => daemonStopPath,
|
|
703
703
|
getDaemonStatus: () => getDaemonStatus,
|
|
704
|
+
hasVersionChanged: () => hasVersionChanged,
|
|
704
705
|
isProcessRunning: () => isProcessRunning,
|
|
705
706
|
msUntilUtcHour: () => msUntilUtcHour,
|
|
706
707
|
parseInterval: () => parseInterval,
|
|
@@ -712,15 +713,13 @@ __export(daemon_exports, {
|
|
|
712
713
|
stopDaemon: () => stopDaemon,
|
|
713
714
|
writeDaemonState: () => writeDaemonState
|
|
714
715
|
});
|
|
715
|
-
import { execSync, spawn } from "child_process";
|
|
716
|
+
import { execFileSync, execSync, spawn } from "child_process";
|
|
716
717
|
import {
|
|
717
718
|
existsSync as existsSync6,
|
|
718
719
|
closeSync as fsCloseSync,
|
|
719
720
|
openSync as fsOpenSync,
|
|
720
721
|
mkdirSync as mkdirSync4,
|
|
721
722
|
readFileSync as readFileSync6,
|
|
722
|
-
realpathSync,
|
|
723
|
-
statSync as statSync2,
|
|
724
723
|
unlinkSync,
|
|
725
724
|
writeFileSync as writeFileSync3
|
|
726
725
|
} from "fs";
|
|
@@ -832,6 +831,14 @@ function msUntilUtcHour(targetHour, now) {
|
|
|
832
831
|
const diff = targetMs - currentMs;
|
|
833
832
|
return diff > 0 ? diff : diff + 24 * 36e5;
|
|
834
833
|
}
|
|
834
|
+
function hasVersionChanged(runningVersion, getInstalledVersion) {
|
|
835
|
+
if (!runningVersion) return false;
|
|
836
|
+
try {
|
|
837
|
+
return getInstalledVersion() !== runningVersion;
|
|
838
|
+
} catch {
|
|
839
|
+
return false;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
835
842
|
async function daemonLoop(intervalMs, options, deps) {
|
|
836
843
|
let wakeDelayMs;
|
|
837
844
|
while (!deps.shouldStop()) {
|
|
@@ -1070,15 +1077,7 @@ async function runDaemon(intervalMs, options, deps) {
|
|
|
1070
1077
|
cleanup();
|
|
1071
1078
|
}
|
|
1072
1079
|
if (exitReason === "upgrade") {
|
|
1073
|
-
|
|
1074
|
-
try {
|
|
1075
|
-
deps.restart();
|
|
1076
|
-
} catch {
|
|
1077
|
-
deps.exit(75);
|
|
1078
|
-
}
|
|
1079
|
-
} else {
|
|
1080
|
-
deps.exit(75);
|
|
1081
|
-
}
|
|
1080
|
+
deps.exit(75);
|
|
1082
1081
|
}
|
|
1083
1082
|
}
|
|
1084
1083
|
async function runDaemonWithDefaults(intervalMs, options) {
|
|
@@ -1108,8 +1107,28 @@ async function runDaemonWithDefaults(intervalMs, options) {
|
|
|
1108
1107
|
return shouldDefer2(/* @__PURE__ */ new Date(), schedule.optimalPingHour);
|
|
1109
1108
|
};
|
|
1110
1109
|
}
|
|
1111
|
-
|
|
1112
|
-
|
|
1110
|
+
let hasUpgraded;
|
|
1111
|
+
if (options.autoUpdate) {
|
|
1112
|
+
let ccPingBin = process.env.CC_PING_BIN;
|
|
1113
|
+
if (!ccPingBin) {
|
|
1114
|
+
try {
|
|
1115
|
+
ccPingBin = execSync("which cc-ping", {
|
|
1116
|
+
encoding: "utf-8",
|
|
1117
|
+
timeout: 5e3
|
|
1118
|
+
}).trim();
|
|
1119
|
+
} catch {
|
|
1120
|
+
console.log(
|
|
1121
|
+
"Auto-update: cc-ping not found in PATH, version checks disabled"
|
|
1122
|
+
);
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
if (ccPingBin) {
|
|
1126
|
+
hasUpgraded = () => hasVersionChanged(
|
|
1127
|
+
readDaemonState()?.version,
|
|
1128
|
+
() => execFileSync(ccPingBin, ["--version"], { timeout: 5e3 }).toString().trim()
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1113
1132
|
await runDaemon(intervalMs, options, {
|
|
1114
1133
|
runPing: runPing2,
|
|
1115
1134
|
listAccounts: listAccounts2,
|
|
@@ -1118,36 +1137,14 @@ async function runDaemonWithDefaults(intervalMs, options) {
|
|
|
1118
1137
|
log: (msg) => console.log(msg),
|
|
1119
1138
|
isWindowActive: (handle) => getWindowReset2(handle) !== null,
|
|
1120
1139
|
shouldDeferPing,
|
|
1121
|
-
hasUpgraded
|
|
1122
|
-
try {
|
|
1123
|
-
return statSync2(binaryPath).mtimeMs !== startMtimeMs;
|
|
1124
|
-
} catch {
|
|
1125
|
-
return false;
|
|
1126
|
-
}
|
|
1127
|
-
},
|
|
1140
|
+
hasUpgraded,
|
|
1128
1141
|
updateState: (patch) => {
|
|
1129
1142
|
const current = readDaemonState();
|
|
1130
1143
|
if (current) writeDaemonState({ ...current, ...patch });
|
|
1131
1144
|
},
|
|
1132
1145
|
onSignal: (signal, handler) => process.on(signal, handler),
|
|
1133
1146
|
removeSignal: (signal, handler) => process.removeListener(signal, handler),
|
|
1134
|
-
exit: (code) => process.exit(code)
|
|
1135
|
-
restart: () => {
|
|
1136
|
-
console.log("Restarting daemon with updated binary...");
|
|
1137
|
-
const result = startDaemon({
|
|
1138
|
-
interval: `${intervalMs / 6e4}m`,
|
|
1139
|
-
quiet: options.quiet,
|
|
1140
|
-
bell: options.bell,
|
|
1141
|
-
notify: options.notify,
|
|
1142
|
-
smartSchedule: options.smartSchedule
|
|
1143
|
-
});
|
|
1144
|
-
if (result.success) {
|
|
1145
|
-
console.log(`Daemon restarted (PID: ${result.pid})`);
|
|
1146
|
-
} else {
|
|
1147
|
-
console.log(`Failed to restart: ${result.error}`);
|
|
1148
|
-
process.exit(75);
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1147
|
+
exit: (code) => process.exit(code)
|
|
1151
1148
|
});
|
|
1152
1149
|
}
|
|
1153
1150
|
var GRACEFUL_POLL_MS, GRACEFUL_POLL_ATTEMPTS, POST_KILL_DELAY_MS;
|
|
@@ -1212,19 +1209,26 @@ function generateLaunchdPlist(options, execInfo, configDir) {
|
|
|
1212
1209
|
if (options.notify) programArgs.push("--notify");
|
|
1213
1210
|
if (options.smartSchedule === false)
|
|
1214
1211
|
programArgs.push("--smart-schedule", "off");
|
|
1212
|
+
programArgs.push("--auto-update");
|
|
1215
1213
|
const allArgs = [execInfo.executable, ...programArgs];
|
|
1216
1214
|
const argsXml = allArgs.map((a) => ` <string>${escapeXml(a)}</string>`).join("\n");
|
|
1217
1215
|
const logPath = join10(
|
|
1218
1216
|
configDir || join10(nodeHomedir(), ".config", "cc-ping"),
|
|
1219
1217
|
"daemon.log"
|
|
1220
1218
|
);
|
|
1219
|
+
const envVars = {};
|
|
1220
|
+
if (configDir) envVars.CC_PING_CONFIG = configDir;
|
|
1221
|
+
if (execInfo.args.length === 0) envVars.CC_PING_BIN = execInfo.executable;
|
|
1221
1222
|
let envSection = "";
|
|
1222
|
-
if (
|
|
1223
|
+
if (Object.keys(envVars).length > 0) {
|
|
1224
|
+
const entries = Object.entries(envVars).map(
|
|
1225
|
+
([k, v]) => ` <key>${escapeXml(k)}</key>
|
|
1226
|
+
<string>${escapeXml(v)}</string>`
|
|
1227
|
+
).join("\n");
|
|
1223
1228
|
envSection = `
|
|
1224
1229
|
<key>EnvironmentVariables</key>
|
|
1225
1230
|
<dict>
|
|
1226
|
-
|
|
1227
|
-
<string>${escapeXml(configDir)}</string>
|
|
1231
|
+
${entries}
|
|
1228
1232
|
</dict>`;
|
|
1229
1233
|
}
|
|
1230
1234
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
@@ -1266,12 +1270,14 @@ function generateSystemdUnit(options, execInfo, configDir) {
|
|
|
1266
1270
|
if (options.notify) programArgs.push("--notify");
|
|
1267
1271
|
if (options.smartSchedule === false)
|
|
1268
1272
|
programArgs.push("--smart-schedule", "off");
|
|
1273
|
+
programArgs.push("--auto-update");
|
|
1269
1274
|
const execStart = [execInfo.executable, ...programArgs].map((a) => a.includes(" ") ? `"${a}"` : a).join(" ");
|
|
1270
|
-
|
|
1271
|
-
if (configDir) {
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
+
const envPairs = [];
|
|
1276
|
+
if (configDir) envPairs.push(`CC_PING_CONFIG=${configDir}`);
|
|
1277
|
+
if (execInfo.args.length === 0)
|
|
1278
|
+
envPairs.push(`CC_PING_BIN=${execInfo.executable}`);
|
|
1279
|
+
const envLine = envPairs.map((p) => `
|
|
1280
|
+
Environment=${p}`).join("");
|
|
1275
1281
|
return `[Unit]
|
|
1276
1282
|
Description=cc-ping daemon - auto-ping Claude Code sessions
|
|
1277
1283
|
|
|
@@ -1915,7 +1921,7 @@ init_paths();
|
|
|
1915
1921
|
init_run_ping();
|
|
1916
1922
|
|
|
1917
1923
|
// src/scan.ts
|
|
1918
|
-
import { existsSync as existsSync7, readdirSync, statSync as
|
|
1924
|
+
import { existsSync as existsSync7, readdirSync, statSync as statSync2 } from "fs";
|
|
1919
1925
|
import { homedir as homedir2 } from "os";
|
|
1920
1926
|
import { join as join9 } from "path";
|
|
1921
1927
|
function scanAccounts(dir) {
|
|
@@ -1923,7 +1929,7 @@ function scanAccounts(dir) {
|
|
|
1923
1929
|
if (!existsSync7(accountsDir)) return [];
|
|
1924
1930
|
return readdirSync(accountsDir).filter((name) => {
|
|
1925
1931
|
const full = join9(accountsDir, name);
|
|
1926
|
-
return
|
|
1932
|
+
return statSync2(full).isDirectory() && !name.startsWith(".") && existsSync7(join9(full, ".claude.json"));
|
|
1927
1933
|
}).map((name) => ({
|
|
1928
1934
|
handle: name,
|
|
1929
1935
|
configDir: join9(accountsDir, name)
|
|
@@ -1995,7 +2001,7 @@ function getDeferredHandles() {
|
|
|
1995
2001
|
}
|
|
1996
2002
|
return deferred;
|
|
1997
2003
|
}
|
|
1998
|
-
var program = new Command().name("cc-ping").description("Ping Claude Code sessions to trigger quota windows early").version("1.
|
|
2004
|
+
var program = new Command().name("cc-ping").description("Ping Claude Code sessions to trigger quota windows early").version("1.9.0").option(
|
|
1999
2005
|
"--config <path>",
|
|
2000
2006
|
"Path to config directory (default: ~/.config/cc-ping, env: CC_PING_CONFIG)"
|
|
2001
2007
|
).hook("preAction", (thisCommand) => {
|
|
@@ -2222,7 +2228,7 @@ daemon.command("start").description("Start the daemon process").option(
|
|
|
2222
2228
|
bell: opts.bell,
|
|
2223
2229
|
notify: opts.notify,
|
|
2224
2230
|
smartSchedule,
|
|
2225
|
-
version: "1.
|
|
2231
|
+
version: "1.9.0"
|
|
2226
2232
|
});
|
|
2227
2233
|
if (!result.success) {
|
|
2228
2234
|
console.error(result.error);
|
|
@@ -2256,7 +2262,7 @@ daemon.command("stop").description("Stop the daemon process").action(async () =>
|
|
|
2256
2262
|
daemon.command("status").description("Show daemon status").option("--json", "Output as JSON", false).action(async (opts) => {
|
|
2257
2263
|
const { getServiceStatus: getServiceStatus2 } = await Promise.resolve().then(() => (init_service(), service_exports));
|
|
2258
2264
|
const svc = getServiceStatus2();
|
|
2259
|
-
const status = getDaemonStatus({ currentVersion: "1.
|
|
2265
|
+
const status = getDaemonStatus({ currentVersion: "1.9.0" });
|
|
2260
2266
|
if (opts.json) {
|
|
2261
2267
|
const serviceInfo = svc.installed ? {
|
|
2262
2268
|
service: {
|
|
@@ -2317,7 +2323,7 @@ daemon.command("status").description("Show daemon status").option("--json", "Out
|
|
|
2317
2323
|
if (status.versionMismatch) {
|
|
2318
2324
|
console.log(
|
|
2319
2325
|
yellow(
|
|
2320
|
-
` Warning: daemon is running v${status.daemonVersion} but v${"1.
|
|
2326
|
+
` Warning: daemon is running v${status.daemonVersion} but v${"1.9.0"} is installed.`
|
|
2321
2327
|
)
|
|
2322
2328
|
);
|
|
2323
2329
|
console.log(
|
|
@@ -2366,7 +2372,7 @@ daemon.command("uninstall").description("Remove daemon system service").action(a
|
|
|
2366
2372
|
}
|
|
2367
2373
|
console.log(`Service removed: ${result.servicePath}`);
|
|
2368
2374
|
});
|
|
2369
|
-
daemon.command("_run", { hidden: true }).option("--interval-ms <ms>", "Ping interval in milliseconds").option("-q, --quiet", "Suppress ping output", false).option("--bell", "Ring terminal bell on ping failure", false).option("--notify", "Send desktop notification on ping failure", false).option("--smart-schedule <on|off>", "Smart scheduling (default: on)").action(async (opts) => {
|
|
2375
|
+
daemon.command("_run", { hidden: true }).option("--interval-ms <ms>", "Ping interval in milliseconds").option("-q, --quiet", "Suppress ping output", false).option("--bell", "Ring terminal bell on ping failure", false).option("--notify", "Send desktop notification on ping failure", false).option("--smart-schedule <on|off>", "Smart scheduling (default: on)").option("--auto-update", "Auto-restart on upgrade (for service installs)").action(async (opts) => {
|
|
2370
2376
|
const intervalMs = Number(opts.intervalMs);
|
|
2371
2377
|
if (!intervalMs || intervalMs <= 0) {
|
|
2372
2378
|
console.error("Invalid --interval-ms");
|
|
@@ -2383,14 +2389,15 @@ daemon.command("_run", { hidden: true }).option("--interval-ms <ms>", "Ping inte
|
|
|
2383
2389
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2384
2390
|
intervalMs,
|
|
2385
2391
|
configDir: resolveConfigDir2(),
|
|
2386
|
-
version: "1.
|
|
2392
|
+
version: "1.9.0"
|
|
2387
2393
|
});
|
|
2388
2394
|
}
|
|
2389
2395
|
await runDaemonWithDefaults(intervalMs, {
|
|
2390
2396
|
quiet: opts.quiet,
|
|
2391
2397
|
bell: opts.bell,
|
|
2392
2398
|
notify: opts.notify,
|
|
2393
|
-
smartSchedule
|
|
2399
|
+
smartSchedule,
|
|
2400
|
+
autoUpdate: opts.autoUpdate
|
|
2394
2401
|
});
|
|
2395
2402
|
});
|
|
2396
2403
|
program.parse();
|