@wbern/cc-ping 1.7.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 +60 -29
- 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()) {
|
|
@@ -1100,8 +1107,28 @@ async function runDaemonWithDefaults(intervalMs, options) {
|
|
|
1100
1107
|
return shouldDefer2(/* @__PURE__ */ new Date(), schedule.optimalPingHour);
|
|
1101
1108
|
};
|
|
1102
1109
|
}
|
|
1103
|
-
|
|
1104
|
-
|
|
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
|
+
}
|
|
1105
1132
|
await runDaemon(intervalMs, options, {
|
|
1106
1133
|
runPing: runPing2,
|
|
1107
1134
|
listAccounts: listAccounts2,
|
|
@@ -1110,13 +1137,7 @@ async function runDaemonWithDefaults(intervalMs, options) {
|
|
|
1110
1137
|
log: (msg) => console.log(msg),
|
|
1111
1138
|
isWindowActive: (handle) => getWindowReset2(handle) !== null,
|
|
1112
1139
|
shouldDeferPing,
|
|
1113
|
-
hasUpgraded
|
|
1114
|
-
try {
|
|
1115
|
-
return statSync2(binaryPath).mtimeMs !== startMtimeMs;
|
|
1116
|
-
} catch {
|
|
1117
|
-
return false;
|
|
1118
|
-
}
|
|
1119
|
-
},
|
|
1140
|
+
hasUpgraded,
|
|
1120
1141
|
updateState: (patch) => {
|
|
1121
1142
|
const current = readDaemonState();
|
|
1122
1143
|
if (current) writeDaemonState({ ...current, ...patch });
|
|
@@ -1188,19 +1209,26 @@ function generateLaunchdPlist(options, execInfo, configDir) {
|
|
|
1188
1209
|
if (options.notify) programArgs.push("--notify");
|
|
1189
1210
|
if (options.smartSchedule === false)
|
|
1190
1211
|
programArgs.push("--smart-schedule", "off");
|
|
1212
|
+
programArgs.push("--auto-update");
|
|
1191
1213
|
const allArgs = [execInfo.executable, ...programArgs];
|
|
1192
1214
|
const argsXml = allArgs.map((a) => ` <string>${escapeXml(a)}</string>`).join("\n");
|
|
1193
1215
|
const logPath = join10(
|
|
1194
1216
|
configDir || join10(nodeHomedir(), ".config", "cc-ping"),
|
|
1195
1217
|
"daemon.log"
|
|
1196
1218
|
);
|
|
1219
|
+
const envVars = {};
|
|
1220
|
+
if (configDir) envVars.CC_PING_CONFIG = configDir;
|
|
1221
|
+
if (execInfo.args.length === 0) envVars.CC_PING_BIN = execInfo.executable;
|
|
1197
1222
|
let envSection = "";
|
|
1198
|
-
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");
|
|
1199
1228
|
envSection = `
|
|
1200
1229
|
<key>EnvironmentVariables</key>
|
|
1201
1230
|
<dict>
|
|
1202
|
-
|
|
1203
|
-
<string>${escapeXml(configDir)}</string>
|
|
1231
|
+
${entries}
|
|
1204
1232
|
</dict>`;
|
|
1205
1233
|
}
|
|
1206
1234
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
@@ -1242,12 +1270,14 @@ function generateSystemdUnit(options, execInfo, configDir) {
|
|
|
1242
1270
|
if (options.notify) programArgs.push("--notify");
|
|
1243
1271
|
if (options.smartSchedule === false)
|
|
1244
1272
|
programArgs.push("--smart-schedule", "off");
|
|
1273
|
+
programArgs.push("--auto-update");
|
|
1245
1274
|
const execStart = [execInfo.executable, ...programArgs].map((a) => a.includes(" ") ? `"${a}"` : a).join(" ");
|
|
1246
|
-
|
|
1247
|
-
if (configDir) {
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
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("");
|
|
1251
1281
|
return `[Unit]
|
|
1252
1282
|
Description=cc-ping daemon - auto-ping Claude Code sessions
|
|
1253
1283
|
|
|
@@ -1891,7 +1921,7 @@ init_paths();
|
|
|
1891
1921
|
init_run_ping();
|
|
1892
1922
|
|
|
1893
1923
|
// src/scan.ts
|
|
1894
|
-
import { existsSync as existsSync7, readdirSync, statSync as
|
|
1924
|
+
import { existsSync as existsSync7, readdirSync, statSync as statSync2 } from "fs";
|
|
1895
1925
|
import { homedir as homedir2 } from "os";
|
|
1896
1926
|
import { join as join9 } from "path";
|
|
1897
1927
|
function scanAccounts(dir) {
|
|
@@ -1899,7 +1929,7 @@ function scanAccounts(dir) {
|
|
|
1899
1929
|
if (!existsSync7(accountsDir)) return [];
|
|
1900
1930
|
return readdirSync(accountsDir).filter((name) => {
|
|
1901
1931
|
const full = join9(accountsDir, name);
|
|
1902
|
-
return
|
|
1932
|
+
return statSync2(full).isDirectory() && !name.startsWith(".") && existsSync7(join9(full, ".claude.json"));
|
|
1903
1933
|
}).map((name) => ({
|
|
1904
1934
|
handle: name,
|
|
1905
1935
|
configDir: join9(accountsDir, name)
|
|
@@ -1971,7 +2001,7 @@ function getDeferredHandles() {
|
|
|
1971
2001
|
}
|
|
1972
2002
|
return deferred;
|
|
1973
2003
|
}
|
|
1974
|
-
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(
|
|
1975
2005
|
"--config <path>",
|
|
1976
2006
|
"Path to config directory (default: ~/.config/cc-ping, env: CC_PING_CONFIG)"
|
|
1977
2007
|
).hook("preAction", (thisCommand) => {
|
|
@@ -2198,7 +2228,7 @@ daemon.command("start").description("Start the daemon process").option(
|
|
|
2198
2228
|
bell: opts.bell,
|
|
2199
2229
|
notify: opts.notify,
|
|
2200
2230
|
smartSchedule,
|
|
2201
|
-
version: "1.
|
|
2231
|
+
version: "1.9.0"
|
|
2202
2232
|
});
|
|
2203
2233
|
if (!result.success) {
|
|
2204
2234
|
console.error(result.error);
|
|
@@ -2232,7 +2262,7 @@ daemon.command("stop").description("Stop the daemon process").action(async () =>
|
|
|
2232
2262
|
daemon.command("status").description("Show daemon status").option("--json", "Output as JSON", false).action(async (opts) => {
|
|
2233
2263
|
const { getServiceStatus: getServiceStatus2 } = await Promise.resolve().then(() => (init_service(), service_exports));
|
|
2234
2264
|
const svc = getServiceStatus2();
|
|
2235
|
-
const status = getDaemonStatus({ currentVersion: "1.
|
|
2265
|
+
const status = getDaemonStatus({ currentVersion: "1.9.0" });
|
|
2236
2266
|
if (opts.json) {
|
|
2237
2267
|
const serviceInfo = svc.installed ? {
|
|
2238
2268
|
service: {
|
|
@@ -2293,7 +2323,7 @@ daemon.command("status").description("Show daemon status").option("--json", "Out
|
|
|
2293
2323
|
if (status.versionMismatch) {
|
|
2294
2324
|
console.log(
|
|
2295
2325
|
yellow(
|
|
2296
|
-
` 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.`
|
|
2297
2327
|
)
|
|
2298
2328
|
);
|
|
2299
2329
|
console.log(
|
|
@@ -2342,7 +2372,7 @@ daemon.command("uninstall").description("Remove daemon system service").action(a
|
|
|
2342
2372
|
}
|
|
2343
2373
|
console.log(`Service removed: ${result.servicePath}`);
|
|
2344
2374
|
});
|
|
2345
|
-
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) => {
|
|
2346
2376
|
const intervalMs = Number(opts.intervalMs);
|
|
2347
2377
|
if (!intervalMs || intervalMs <= 0) {
|
|
2348
2378
|
console.error("Invalid --interval-ms");
|
|
@@ -2359,14 +2389,15 @@ daemon.command("_run", { hidden: true }).option("--interval-ms <ms>", "Ping inte
|
|
|
2359
2389
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2360
2390
|
intervalMs,
|
|
2361
2391
|
configDir: resolveConfigDir2(),
|
|
2362
|
-
version: "1.
|
|
2392
|
+
version: "1.9.0"
|
|
2363
2393
|
});
|
|
2364
2394
|
}
|
|
2365
2395
|
await runDaemonWithDefaults(intervalMs, {
|
|
2366
2396
|
quiet: opts.quiet,
|
|
2367
2397
|
bell: opts.bell,
|
|
2368
2398
|
notify: opts.notify,
|
|
2369
|
-
smartSchedule
|
|
2399
|
+
smartSchedule,
|
|
2400
|
+
autoUpdate: opts.autoUpdate
|
|
2370
2401
|
});
|
|
2371
2402
|
});
|
|
2372
2403
|
program.parse();
|