@wbern/cc-ping 1.12.0 → 1.13.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 +40 -11
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -618,14 +618,30 @@ var init_run_ping = __esm({
|
|
|
618
618
|
var schedule_exports = {};
|
|
619
619
|
__export(schedule_exports, {
|
|
620
620
|
buildHourHistogram: () => buildHourHistogram,
|
|
621
|
+
checkRecentActivity: () => checkRecentActivity,
|
|
621
622
|
findOptimalPingHour: () => findOptimalPingHour,
|
|
622
623
|
getAccountSchedule: () => getAccountSchedule,
|
|
624
|
+
isRecentlyActive: () => isRecentlyActive,
|
|
623
625
|
parseSmartSchedule: () => parseSmartSchedule,
|
|
624
626
|
readAccountSchedule: () => readAccountSchedule,
|
|
625
627
|
shouldDefer: () => shouldDefer
|
|
626
628
|
});
|
|
627
629
|
import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";
|
|
628
630
|
import { join as join6 } from "path";
|
|
631
|
+
function isRecentlyActive(historyLines, now) {
|
|
632
|
+
let latest = 0;
|
|
633
|
+
for (const line of historyLines) {
|
|
634
|
+
try {
|
|
635
|
+
const entry = JSON.parse(line);
|
|
636
|
+
if (typeof entry.timestamp === "number" && entry.timestamp > latest) {
|
|
637
|
+
latest = entry.timestamp;
|
|
638
|
+
}
|
|
639
|
+
} catch {
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
if (latest === 0) return false;
|
|
643
|
+
return now.getTime() - latest < QUOTA_WINDOW_MS2;
|
|
644
|
+
}
|
|
629
645
|
function buildHourHistogram(timestamps) {
|
|
630
646
|
const bins = new Array(24).fill(0);
|
|
631
647
|
for (const ts of timestamps) {
|
|
@@ -697,6 +713,13 @@ function readAccountSchedule(configDir, now = /* @__PURE__ */ new Date(), resetA
|
|
|
697
713
|
const lines = content.split("\n").filter((l) => l.trim());
|
|
698
714
|
return getAccountSchedule(lines, now, resetAt);
|
|
699
715
|
}
|
|
716
|
+
function checkRecentActivity(configDir, now = /* @__PURE__ */ new Date()) {
|
|
717
|
+
const historyPath = join6(configDir, "history.jsonl");
|
|
718
|
+
if (!existsSync5(historyPath)) return false;
|
|
719
|
+
const content = readFileSync5(historyPath, "utf-8");
|
|
720
|
+
const lines = content.split("\n").filter((l) => l.trim());
|
|
721
|
+
return isRecentlyActive(lines, now);
|
|
722
|
+
}
|
|
700
723
|
function parseSmartSchedule(value) {
|
|
701
724
|
const lower = value.toLowerCase();
|
|
702
725
|
if (TRUTHY.has(lower)) return true;
|
|
@@ -705,11 +728,12 @@ function parseSmartSchedule(value) {
|
|
|
705
728
|
`Invalid smart-schedule value: "${value}". Use true/false, on/off, or 1/0`
|
|
706
729
|
);
|
|
707
730
|
}
|
|
708
|
-
var QUOTA_WINDOW_HOURS, MIN_DAYS, HISTORY_WINDOW_MS, TRUTHY, FALSY;
|
|
731
|
+
var QUOTA_WINDOW_HOURS, QUOTA_WINDOW_MS2, MIN_DAYS, HISTORY_WINDOW_MS, TRUTHY, FALSY;
|
|
709
732
|
var init_schedule = __esm({
|
|
710
733
|
"src/schedule.ts"() {
|
|
711
734
|
"use strict";
|
|
712
735
|
QUOTA_WINDOW_HOURS = 5;
|
|
736
|
+
QUOTA_WINDOW_MS2 = QUOTA_WINDOW_HOURS * 60 * 60 * 1e3;
|
|
713
737
|
MIN_DAYS = 7;
|
|
714
738
|
HISTORY_WINDOW_MS = 14 * 24 * 60 * 60 * 1e3;
|
|
715
739
|
TRUTHY = /* @__PURE__ */ new Set(["true", "on", "1"]);
|
|
@@ -1109,6 +1133,7 @@ async function runDaemonWithDefaults(intervalMs, options) {
|
|
|
1109
1133
|
const { runPing: runPing2 } = await Promise.resolve().then(() => (init_run_ping(), run_ping_exports));
|
|
1110
1134
|
const { listAccounts: listAccounts2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
1111
1135
|
const { getWindowReset: getWindowReset2 } = await Promise.resolve().then(() => (init_state(), state_exports));
|
|
1136
|
+
const { checkRecentActivity: checkRecentActivity2 } = await Promise.resolve().then(() => (init_schedule(), schedule_exports));
|
|
1112
1137
|
const smartScheduleEnabled = options.smartSchedule !== false;
|
|
1113
1138
|
let shouldDeferPing;
|
|
1114
1139
|
if (smartScheduleEnabled) {
|
|
@@ -1167,7 +1192,11 @@ async function runDaemonWithDefaults(intervalMs, options) {
|
|
|
1167
1192
|
sleep: (ms) => new Promise((resolve2) => setTimeout(resolve2, ms)),
|
|
1168
1193
|
shouldStop: () => existsSync6(stopPath),
|
|
1169
1194
|
log: (msg) => console.log(msg),
|
|
1170
|
-
isWindowActive: (handle) =>
|
|
1195
|
+
isWindowActive: (handle) => {
|
|
1196
|
+
if (getWindowReset2(handle) !== null) return true;
|
|
1197
|
+
const account = listAccounts2().find((a) => a.handle === handle);
|
|
1198
|
+
return account ? checkRecentActivity2(account.configDir) : false;
|
|
1199
|
+
},
|
|
1171
1200
|
shouldDeferPing,
|
|
1172
1201
|
hasUpgraded,
|
|
1173
1202
|
updateState: (patch) => {
|
|
@@ -1458,18 +1487,18 @@ function escapeXml(str) {
|
|
|
1458
1487
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1459
1488
|
}
|
|
1460
1489
|
function parseIntervalForService(value) {
|
|
1461
|
-
if (!value) return
|
|
1490
|
+
if (!value) return QUOTA_WINDOW_MS3;
|
|
1462
1491
|
const minutes = Number(value);
|
|
1463
|
-
if (Number.isNaN(minutes) || minutes <= 0) return
|
|
1492
|
+
if (Number.isNaN(minutes) || minutes <= 0) return QUOTA_WINDOW_MS3;
|
|
1464
1493
|
return minutes * 60 * 1e3;
|
|
1465
1494
|
}
|
|
1466
|
-
var PLIST_LABEL, SYSTEMD_SERVICE,
|
|
1495
|
+
var PLIST_LABEL, SYSTEMD_SERVICE, QUOTA_WINDOW_MS3;
|
|
1467
1496
|
var init_service = __esm({
|
|
1468
1497
|
"src/service.ts"() {
|
|
1469
1498
|
"use strict";
|
|
1470
1499
|
PLIST_LABEL = "com.cc-ping.daemon";
|
|
1471
1500
|
SYSTEMD_SERVICE = "cc-ping-daemon";
|
|
1472
|
-
|
|
1501
|
+
QUOTA_WINDOW_MS3 = 5 * 60 * 60 * 1e3;
|
|
1473
1502
|
}
|
|
1474
1503
|
});
|
|
1475
1504
|
|
|
@@ -2063,7 +2092,7 @@ function getDeferredHandles() {
|
|
|
2063
2092
|
}
|
|
2064
2093
|
return deferred;
|
|
2065
2094
|
}
|
|
2066
|
-
var program = new Command().name("cc-ping").description("Ping Claude Code sessions to trigger quota windows early").version("1.
|
|
2095
|
+
var program = new Command().name("cc-ping").description("Ping Claude Code sessions to trigger quota windows early").version("1.13.0").option(
|
|
2067
2096
|
"--config <path>",
|
|
2068
2097
|
"Path to config directory (default: ~/.config/cc-ping, env: CC_PING_CONFIG)"
|
|
2069
2098
|
).hook("preAction", (thisCommand) => {
|
|
@@ -2292,7 +2321,7 @@ daemon.command("start").description("Start the daemon process").option(
|
|
|
2292
2321
|
bell: opts.bell,
|
|
2293
2322
|
notify: opts.notify,
|
|
2294
2323
|
smartSchedule,
|
|
2295
|
-
version: "1.
|
|
2324
|
+
version: "1.13.0"
|
|
2296
2325
|
});
|
|
2297
2326
|
if (!result.success) {
|
|
2298
2327
|
console.error(result.error);
|
|
@@ -2328,7 +2357,7 @@ daemon.command("stop").description("Stop the daemon process").action(async () =>
|
|
|
2328
2357
|
daemon.command("status").description("Show daemon status").option("--json", "Output as JSON", false).option("--censor", "Mask account handles in output (for screenshots)").action(async (opts) => {
|
|
2329
2358
|
const { getServiceStatus: getServiceStatus2 } = await Promise.resolve().then(() => (init_service(), service_exports));
|
|
2330
2359
|
const svc = getServiceStatus2();
|
|
2331
|
-
const status = getDaemonStatus({ currentVersion: "1.
|
|
2360
|
+
const status = getDaemonStatus({ currentVersion: "1.13.0" });
|
|
2332
2361
|
if (opts.json) {
|
|
2333
2362
|
const serviceInfo = svc.installed ? {
|
|
2334
2363
|
service: {
|
|
@@ -2389,7 +2418,7 @@ daemon.command("status").description("Show daemon status").option("--json", "Out
|
|
|
2389
2418
|
if (status.versionMismatch) {
|
|
2390
2419
|
console.log(
|
|
2391
2420
|
yellow(
|
|
2392
|
-
` Warning: daemon is running v${status.daemonVersion} but v${"1.
|
|
2421
|
+
` Warning: daemon is running v${status.daemonVersion} but v${"1.13.0"} is installed.`
|
|
2393
2422
|
)
|
|
2394
2423
|
);
|
|
2395
2424
|
console.log(
|
|
@@ -2457,7 +2486,7 @@ daemon.command("_run", { hidden: true }).option("--interval-ms <ms>", "Ping inte
|
|
|
2457
2486
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2458
2487
|
intervalMs,
|
|
2459
2488
|
configDir: resolveConfigDir2(),
|
|
2460
|
-
version: "1.
|
|
2489
|
+
version: "1.13.0"
|
|
2461
2490
|
});
|
|
2462
2491
|
}
|
|
2463
2492
|
await runDaemonWithDefaults(intervalMs, {
|