@wbern/cc-ping 1.5.0 → 1.5.1
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 +39 -16
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -701,6 +701,7 @@ __export(daemon_exports, {
|
|
|
701
701
|
daemonStopPath: () => daemonStopPath,
|
|
702
702
|
getDaemonStatus: () => getDaemonStatus,
|
|
703
703
|
isProcessRunning: () => isProcessRunning,
|
|
704
|
+
msUntilUtcHour: () => msUntilUtcHour,
|
|
704
705
|
parseInterval: () => parseInterval,
|
|
705
706
|
readDaemonState: () => readDaemonState,
|
|
706
707
|
removeDaemonState: () => removeDaemonState,
|
|
@@ -824,6 +825,12 @@ function formatUptime(ms) {
|
|
|
824
825
|
if (minutes > 0) return `${minutes}m ${seconds}s`;
|
|
825
826
|
return `${seconds}s`;
|
|
826
827
|
}
|
|
828
|
+
function msUntilUtcHour(targetHour, now) {
|
|
829
|
+
const currentMs = now.getUTCHours() * 36e5 + now.getUTCMinutes() * 6e4 + now.getUTCSeconds() * 1e3 + now.getUTCMilliseconds();
|
|
830
|
+
const targetMs = targetHour * 36e5;
|
|
831
|
+
const diff = targetMs - currentMs;
|
|
832
|
+
return diff > 0 ? diff : diff + 24 * 36e5;
|
|
833
|
+
}
|
|
827
834
|
async function daemonLoop(intervalMs, options, deps) {
|
|
828
835
|
let wakeDelayMs;
|
|
829
836
|
while (!deps.shouldStop()) {
|
|
@@ -837,23 +844,28 @@ async function daemonLoop(intervalMs, options, deps) {
|
|
|
837
844
|
if (skipped > 0) {
|
|
838
845
|
deps.log(`Skipping ${skipped} account(s) with active window`);
|
|
839
846
|
}
|
|
847
|
+
let soonestDeferHour;
|
|
840
848
|
if (deps.shouldDeferPing) {
|
|
841
849
|
const deferResults = /* @__PURE__ */ new Map();
|
|
842
850
|
for (const a of accounts) {
|
|
843
|
-
deferResults.set(
|
|
844
|
-
a.handle,
|
|
845
|
-
deps.shouldDeferPing(a.handle, a.configDir).defer
|
|
846
|
-
);
|
|
851
|
+
deferResults.set(a.handle, deps.shouldDeferPing(a.handle, a.configDir));
|
|
847
852
|
}
|
|
848
|
-
const
|
|
849
|
-
if (
|
|
850
|
-
accounts = accounts.filter((a) => !deferResults.get(a.handle));
|
|
851
|
-
deps.log(`Deferring ${
|
|
853
|
+
const deferred = [...deferResults.entries()].filter(([, r]) => r.defer);
|
|
854
|
+
if (deferred.length > 0) {
|
|
855
|
+
accounts = accounts.filter((a) => !deferResults.get(a.handle)?.defer);
|
|
856
|
+
deps.log(`Deferring ${deferred.length} account(s) (smart scheduling)`);
|
|
857
|
+
for (const [, r] of deferred) {
|
|
858
|
+
if (r.deferUntilUtcHour !== void 0 && (soonestDeferHour === void 0 || /* c8 ignore next -- production default */
|
|
859
|
+
msUntilUtcHour(r.deferUntilUtcHour, deps.now?.() ?? /* @__PURE__ */ new Date()) < /* c8 ignore next -- production default */
|
|
860
|
+
msUntilUtcHour(soonestDeferHour, deps.now?.() ?? /* @__PURE__ */ new Date()))) {
|
|
861
|
+
soonestDeferHour = r.deferUntilUtcHour;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
852
864
|
}
|
|
853
865
|
}
|
|
854
866
|
if (accounts.length === 0) {
|
|
855
867
|
deps.log(
|
|
856
|
-
allAccounts.length === 0 ? "No accounts configured, waiting..." : "All accounts have active windows, waiting..."
|
|
868
|
+
allAccounts.length === 0 ? "No accounts configured, waiting..." : soonestDeferHour !== void 0 ? "All accounts deferred (smart scheduling), waiting..." : "All accounts have active windows, waiting..."
|
|
857
869
|
);
|
|
858
870
|
} else {
|
|
859
871
|
deps.log(
|
|
@@ -882,9 +894,20 @@ async function daemonLoop(intervalMs, options, deps) {
|
|
|
882
894
|
deps.updateState?.({ lastPingAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
883
895
|
}
|
|
884
896
|
if (deps.shouldStop()) break;
|
|
885
|
-
|
|
897
|
+
let sleepMs = intervalMs;
|
|
898
|
+
if (soonestDeferHour !== void 0) {
|
|
899
|
+
const msUntilDefer = msUntilUtcHour(
|
|
900
|
+
soonestDeferHour,
|
|
901
|
+
/* c8 ignore next -- production default */
|
|
902
|
+
deps.now?.() ?? /* @__PURE__ */ new Date()
|
|
903
|
+
);
|
|
904
|
+
if (msUntilDefer > 0 && msUntilDefer < intervalMs) {
|
|
905
|
+
sleepMs = msUntilDefer;
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
deps.log(`Sleeping ${Math.round(sleepMs / 6e4)}m until next ping...`);
|
|
886
909
|
const sleepStart = Date.now();
|
|
887
|
-
await deps.sleep(
|
|
910
|
+
await deps.sleep(sleepMs);
|
|
888
911
|
const overshootMs = Date.now() - sleepStart - intervalMs;
|
|
889
912
|
if (overshootMs > 6e4) {
|
|
890
913
|
wakeDelayMs = overshootMs;
|
|
@@ -1893,7 +1916,7 @@ function suggestAccount(accounts, now = /* @__PURE__ */ new Date()) {
|
|
|
1893
1916
|
}
|
|
1894
1917
|
|
|
1895
1918
|
// src/cli.ts
|
|
1896
|
-
var program = new Command().name("cc-ping").description("Ping Claude Code sessions to trigger quota windows early").version("1.5.
|
|
1919
|
+
var program = new Command().name("cc-ping").description("Ping Claude Code sessions to trigger quota windows early").version("1.5.1").option(
|
|
1897
1920
|
"--config <path>",
|
|
1898
1921
|
"Path to config directory (default: ~/.config/cc-ping, env: CC_PING_CONFIG)"
|
|
1899
1922
|
).hook("preAction", (thisCommand) => {
|
|
@@ -2114,7 +2137,7 @@ daemon.command("start").description("Start the daemon process").option(
|
|
|
2114
2137
|
bell: opts.bell,
|
|
2115
2138
|
notify: opts.notify,
|
|
2116
2139
|
smartSchedule,
|
|
2117
|
-
version: "1.5.
|
|
2140
|
+
version: "1.5.1"
|
|
2118
2141
|
});
|
|
2119
2142
|
if (!result.success) {
|
|
2120
2143
|
console.error(result.error);
|
|
@@ -2148,7 +2171,7 @@ daemon.command("stop").description("Stop the daemon process").action(async () =>
|
|
|
2148
2171
|
daemon.command("status").description("Show daemon status").option("--json", "Output as JSON", false).action(async (opts) => {
|
|
2149
2172
|
const { getServiceStatus: getServiceStatus2 } = await Promise.resolve().then(() => (init_service(), service_exports));
|
|
2150
2173
|
const svc = getServiceStatus2();
|
|
2151
|
-
const status = getDaemonStatus({ currentVersion: "1.5.
|
|
2174
|
+
const status = getDaemonStatus({ currentVersion: "1.5.1" });
|
|
2152
2175
|
if (opts.json) {
|
|
2153
2176
|
const serviceInfo = svc.installed ? {
|
|
2154
2177
|
service: {
|
|
@@ -2202,7 +2225,7 @@ daemon.command("status").description("Show daemon status").option("--json", "Out
|
|
|
2202
2225
|
}
|
|
2203
2226
|
if (status.versionMismatch) {
|
|
2204
2227
|
console.log(
|
|
2205
|
-
` Warning: daemon is running v${status.daemonVersion} but v${"1.5.
|
|
2228
|
+
` Warning: daemon is running v${status.daemonVersion} but v${"1.5.1"} is installed.`
|
|
2206
2229
|
);
|
|
2207
2230
|
console.log(
|
|
2208
2231
|
" Restart to pick up the new version: cc-ping daemon stop && cc-ping daemon start"
|
|
@@ -2265,7 +2288,7 @@ daemon.command("_run", { hidden: true }).option("--interval-ms <ms>", "Ping inte
|
|
|
2265
2288
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2266
2289
|
intervalMs,
|
|
2267
2290
|
configDir: resolveConfigDir2(),
|
|
2268
|
-
version: "1.5.
|
|
2291
|
+
version: "1.5.1"
|
|
2269
2292
|
});
|
|
2270
2293
|
}
|
|
2271
2294
|
await runDaemonWithDefaults(intervalMs, {
|