codiedev 0.10.0-beta.2 → 0.10.0-beta.3
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/codexLimitScan.d.ts +2 -0
- package/dist/codexLimitScan.js +15 -2
- package/dist/hook.js +3 -7
- package/dist/limitEvent.js +26 -1
- package/package.json +1 -1
package/dist/codexLimitScan.d.ts
CHANGED
|
@@ -45,6 +45,8 @@ export interface SweepArgs {
|
|
|
45
45
|
scanOptions?: ScanOptions;
|
|
46
46
|
/** How many rollouts may actually be READ in one sweep. */
|
|
47
47
|
maxScans?: number;
|
|
48
|
+
/** Stop starting new scans once this many ms have elapsed. */
|
|
49
|
+
deadlineMs?: number;
|
|
48
50
|
}
|
|
49
51
|
/**
|
|
50
52
|
* Report every Codex block this machine has not reported yet. Returns how many
|
package/dist/codexLimitScan.js
CHANGED
|
@@ -382,8 +382,20 @@ function recordCodexLimitReported(filePath, at, statePath = exports.CODEX_LIMIT_
|
|
|
382
382
|
// Candidates are listed generously and settled by one statSync each; only
|
|
383
383
|
// files that actually changed cost a read. The budget therefore bounds work
|
|
384
384
|
// without letting idle sessions bury an unreported block.
|
|
385
|
+
//
|
|
386
|
+
// The budget binds only on a COLD START, where nothing has been seen before,
|
|
387
|
+
// so it must be big enough to finish that first pass. A budget of 8 silently
|
|
388
|
+
// starved the older blocked rollouts on a real machine: 49 candidates in the
|
|
389
|
+
// window, the newest 8 all unblocked, nothing reported. A full pass over
|
|
390
|
+
// those 49 costs ~205ms — the backward scan stops at the marker rather than
|
|
391
|
+
// reading each file to its cap — so the budget can afford to cover them.
|
|
385
392
|
const DEFAULT_CANDIDATES = 200;
|
|
386
|
-
const DEFAULT_MAX_SCANS =
|
|
393
|
+
const DEFAULT_MAX_SCANS = 64;
|
|
394
|
+
// The budget bounds how MANY files are read; this bounds how LONG. A count is
|
|
395
|
+
// not enough on a slow or network-mounted disk, and this runs on the user's
|
|
396
|
+
// prompt clock. Whatever is not reached stays unrecorded, so the next prompt
|
|
397
|
+
// picks it up rather than skipping it.
|
|
398
|
+
const DEFAULT_DEADLINE_MS = 1_500;
|
|
387
399
|
/**
|
|
388
400
|
* Report every Codex block this machine has not reported yet. Returns how many
|
|
389
401
|
* events were posted. Never throws — it runs inside a hook.
|
|
@@ -407,6 +419,7 @@ async function sweepCodexLimits(args) {
|
|
|
407
419
|
const now = Date.now();
|
|
408
420
|
const touched = {};
|
|
409
421
|
let budget = args.maxScans ?? DEFAULT_MAX_SCANS;
|
|
422
|
+
const deadline = now + (args.deadlineMs ?? DEFAULT_DEADLINE_MS);
|
|
410
423
|
const pending = [];
|
|
411
424
|
for (const file of files) {
|
|
412
425
|
const print = fingerprint(file);
|
|
@@ -417,7 +430,7 @@ async function sweepCodexLimits(args) {
|
|
|
417
430
|
// it holds nothing new and does not spend the read budget.
|
|
418
431
|
if (record && record.size === print.size && record.mtime === print.mtime)
|
|
419
432
|
continue;
|
|
420
|
-
if (budget <= 0)
|
|
433
|
+
if (budget <= 0 || Date.now() >= deadline)
|
|
421
434
|
break;
|
|
422
435
|
budget -= 1;
|
|
423
436
|
const hit = scanCodexRolloutForLimit(file, args.scanOptions);
|
package/dist/hook.js
CHANGED
|
@@ -217,14 +217,10 @@ async function runCodexLimitSweep(sessionId) {
|
|
|
217
217
|
// A shorter timeout than the default: this is on the user's prompt
|
|
218
218
|
// clock, and the next prompt retries anything that does not land.
|
|
219
219
|
post: (payload) => (0, limitEventReporter_1.postLimitEvent)(config, payload, PROMPT_LIMIT_POST_TIMEOUT_MS),
|
|
220
|
-
//
|
|
221
|
-
//
|
|
222
|
-
//
|
|
223
|
-
// block is still unreported it sits at the END of its rollout, so a
|
|
224
|
-
// small scan window is enough; the Stop path keeps the larger default
|
|
225
|
-
// for a session that kept going after the window reset.
|
|
220
|
+
// Unchanged rollouts cost one statSync and do not spend the read
|
|
221
|
+
// budget, so in steady state this is nearly free. The module default
|
|
222
|
+
// covers a cold start; see DEFAULT_MAX_SCANS for why it is not small.
|
|
226
223
|
findOptions: { withinMs: 24 * 3600_000 },
|
|
227
|
-
maxScans: 8,
|
|
228
224
|
scanOptions: { maxScanBytes: 4 * 1024 * 1024 },
|
|
229
225
|
});
|
|
230
226
|
if (posted > 0) {
|
package/dist/limitEvent.js
CHANGED
|
@@ -51,11 +51,36 @@ function parseLimitEventFromTranscript(transcript) {
|
|
|
51
51
|
}
|
|
52
52
|
return found;
|
|
53
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Codex's `rate_limit_reached_type` is exactly five values (read off the 0.154
|
|
56
|
+
* binary): `rate_limit_reached`, `workspace_{owner,member}_credits_depleted`
|
|
57
|
+
* and `workspace_{owner,member}_usage_limit_reached`.
|
|
58
|
+
*
|
|
59
|
+
* The split that matters to a reader of the dashboard is "someone must act on
|
|
60
|
+
* money" vs "this dev is throttled and it will reset" — so map on what the
|
|
61
|
+
* snapshot actually asserts, not on the word "credits":
|
|
62
|
+
*
|
|
63
|
+
* - A member out of their OWN allowance is a rate limit. Real snapshots carry
|
|
64
|
+
* `spend_control_reached: null` and `individual_limit: null` — nobody
|
|
65
|
+
* configured a budget, the window is simply used up. Calling that personal
|
|
66
|
+
* spend tells a manager the dev overspent, which is not what happened.
|
|
67
|
+
*
|
|
68
|
+
* Deliberately NOT gated on `individual_limit`: it has only ever been
|
|
69
|
+
* observed null, so its populated shape and meaning are unknown, and a
|
|
70
|
+
* wrong guess reinstates the mislabel this exists to remove. The reason
|
|
71
|
+
* string is the causal signal; `individual_limit` is at best correlative.
|
|
72
|
+
* - A member whose ADMIN capped them (`usage_limit_reached`) is personal spend:
|
|
73
|
+
* there really is a cap, and someone can raise it.
|
|
74
|
+
* - Anything owner-scoped is org spend — the org's allowance or credits are
|
|
75
|
+
* gone and somebody has to act.
|
|
76
|
+
*/
|
|
54
77
|
function codexLimitKind(reason, spendControlReached) {
|
|
55
78
|
if (spendControlReached || reason.startsWith("workspace_owner_"))
|
|
56
79
|
return "org_spend";
|
|
57
|
-
if (reason
|
|
80
|
+
if (reason === "workspace_member_usage_limit_reached")
|
|
58
81
|
return "user_spend";
|
|
82
|
+
if (reason === "workspace_member_credits_depleted")
|
|
83
|
+
return "session";
|
|
59
84
|
return reason === "rate_limit_reached" ? "session" : "other";
|
|
60
85
|
}
|
|
61
86
|
function codexResetText(rateLimits) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codiedev",
|
|
3
|
-
"version": "0.10.0-beta.
|
|
3
|
+
"version": "0.10.0-beta.3",
|
|
4
4
|
"description": "Connect Claude Code, Codex, Cursor, OpenCode, or VS Code Copilot to Codiedev for team session capture and artifact collaboration — and run the governed Codie harness",
|
|
5
5
|
"bin": {
|
|
6
6
|
"codiedev": "dist/cli.js",
|