vectiscode 0.1.0 → 0.1.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/checks.js CHANGED
@@ -1,4 +1,4 @@
1
- import { limitDeltas, openWindows } from "./codex.js";
1
+ import { limitDeltas, severalAccounts } from "./codex.js";
2
2
  import { costParts, readPrice } from "./prices.js";
3
3
  const WEEK = 10_080;
4
4
  const LONG = 150_000;
@@ -34,7 +34,7 @@ export function analyze(claude, codex, since, now = Date.now()) {
34
34
  report.codex = {
35
35
  turns: codex.requests.length,
36
36
  chats: codex.sessions.size,
37
- openWeekly: openWindows(codex.limits, WEEK, now),
37
+ severalAccounts: severalAccounts(codex.limits, WEEK),
38
38
  limits: [...latest.values()].map((s) => ({
39
39
  limit: s.limit,
40
40
  windowMinutes: s.windowMinutes,
package/dist/codex.js CHANGED
@@ -3,7 +3,9 @@ import { jsonlFiles, readLines } from "./files.js";
3
3
  import { projectName, sessionFor } from "./model.js";
4
4
  const NEEDLES = ['"session_meta"', '"turn_context"', '"token_count"'];
5
5
  const keep = (line) => NEEDLES.some((n) => line.includes(n));
6
- const JITTER = 3 * 3_600_000;
6
+ // Readings of one window disagree on its reset time by about a minute. Windows of two accounts that
7
+ // started close together can be only 17 minutes apart, so the tolerance stays small.
8
+ const JITTER = 5 * 60_000;
7
9
  /** Reads Codex's logs: <root>/sessions/YYYY/MM/DD/rollout-*.jsonl. */
8
10
  export async function readCodex(root, since) {
9
11
  const requests = [];
@@ -81,8 +83,8 @@ export async function readCodex(root, since) {
81
83
  }
82
84
  /**
83
85
  * How many percentage points of a limit window each turn used. A window is known by its reset time: people who
84
- * switch between ChatGPT accounts have several running at once, and parallel chats report the same window with
85
- * reset times up to an hour apart, sometimes with an older, lower reading. So each window counts up from its peak.
86
+ * switch between ChatGPT accounts have several running at once, and parallel chats sometimes report an older,
87
+ * lower reading of the same window. So each window counts up from its peak.
86
88
  */
87
89
  export function limitDeltas(limits, windowMinutes, since) {
88
90
  const deltas = new Map();
@@ -103,12 +105,17 @@ export function limitDeltas(limits, windowMinutes, since) {
103
105
  }
104
106
  return deltas;
105
107
  }
106
- /** How many different windows of this length were still open at `now`. */
107
- export function openWindows(limits, windowMinutes, now) {
108
- const open = [];
108
+ /** Whether readings of two windows alternate in time, which only happens with more than one account. */
109
+ export function severalAccounts(limits, windowMinutes) {
110
+ const spans = [];
109
111
  for (const s of limits) {
110
- if (s.windowMinutes === windowMinutes && s.limit === "codex" && s.resetsAt > now && !open.some((r) => Math.abs(r - s.resetsAt) <= JITTER))
111
- open.push(s.resetsAt);
112
+ if (s.windowMinutes !== windowMinutes || s.limit !== "codex")
113
+ continue;
114
+ const w = spans.find((x) => Math.abs(x.resetsAt - s.resetsAt) <= JITTER);
115
+ if (w)
116
+ w.last = s.time;
117
+ else
118
+ spans.push({ resetsAt: s.resetsAt, first: s.time, last: s.time });
112
119
  }
113
- return open.length;
120
+ return spans.some((a) => spans.some((b) => a !== b && a.first < b.first && b.first < a.last));
114
121
  }
package/dist/report.js CHANGED
@@ -24,8 +24,8 @@ export function render(report, days) {
24
24
  const text = limits.map((l) => `${l.limit === "codex" ? "" : `${l.limit} `}${windowName(l.windowMinutes)} ${l.used}%${l.used ? ` used, resets ${when(l.resetsAt)}` : ""}`);
25
25
  if (text.length)
26
26
  out.push(row("", `latest reading: ${text.join(" · ")}`));
27
- if (x.openWeekly > 1)
28
- out.push(row("", dim(`Readings came from ${x.openWeekly} different weekly windows, usually a sign of more than one ChatGPT account. The reading above is the latest one.`)));
27
+ if (x.severalAccounts)
28
+ out.push(row("", dim("You use more than one ChatGPT account. The reading above is from the one used last; each account's chats are counted against its own limit.")));
29
29
  if (x.topChats.length)
30
30
  out.push(row("", `biggest chats: ${x.topChats.map((s) => `${s.project} (${day(s.start)}) ${Math.round(s.points)}%`).join(", ")} of a weekly limit`));
31
31
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vectiscode",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Find out why your Claude Code and Codex limits drain, and what to change. Runs locally on your own logs.",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -15,7 +15,7 @@
15
15
  "type": "git",
16
16
  "url": "git+https://github.com/vectiscode/vectiscode-cli.git"
17
17
  },
18
- "homepage": "https://github.com/vectiscode/vectiscode-cli#readme",
18
+ "homepage": "https://vectiscode.com",
19
19
  "bugs": "https://github.com/vectiscode/vectiscode-cli/issues",
20
20
  "type": "module",
21
21
  "bin": {