agent-dag 1.33.112 → 1.33.113
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/web/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
6
|
<title>agents-deck</title>
|
|
7
7
|
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ctext y='84' font-size='84'%3E%E2%97%89%3C/text%3E%3C/svg%3E" />
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-C-JtsHUv.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-DjZdNYsz.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-dag",
|
|
3
|
-
"version": "1.33.
|
|
3
|
+
"version": "1.33.113",
|
|
4
4
|
"description": "Live deck of Claude Code and Codex agents — watch parallel subagents fork, call tools, and return on one calm canvas. Also available as npx ccdeck and npx agent-dag.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -68,22 +68,6 @@ const FRESH_MIN_AGE_MS = 190_000;
|
|
|
68
68
|
// congestion control is deliberately holding back, and so do we.
|
|
69
69
|
const RECENT_429_MS = 3_600_000;
|
|
70
70
|
|
|
71
|
-
/**
|
|
72
|
-
* Ask claude-swap to collect, if its own schedule says anything is due.
|
|
73
|
-
*
|
|
74
|
-
* Without this the panel is only as live as whatever else is running: if the
|
|
75
|
-
* user has no `cswap watch`/`auto`/TUI open, nothing ever writes the store and
|
|
76
|
-
* the panel shows frozen numbers while looking current.
|
|
77
|
-
*
|
|
78
|
-
* `cswap list` is the safe way to ask. It runs the same on-demand pass every
|
|
79
|
-
* claude-swap surface uses, and the store — not us — decides which accounts,
|
|
80
|
-
* if any, may actually hit the network. So this cannot outrun the request
|
|
81
|
-
* budget no matter how often the panel polls: when nothing is due, it is a
|
|
82
|
-
* local read that fetches nothing.
|
|
83
|
-
*
|
|
84
|
-
* Fire-and-forget. The result lands in the store for the next poll to pick up;
|
|
85
|
-
* making the caller wait would just delay the numbers it already has.
|
|
86
|
-
*/
|
|
87
71
|
/**
|
|
88
72
|
* Whether anything is waiting to be collected.
|
|
89
73
|
*
|
|
@@ -174,6 +158,10 @@ export function nextReadAt(row, matches, fetchedAtMs, isActive, now) {
|
|
|
174
158
|
/**
|
|
175
159
|
* Keep the store moving while someone is looking at it.
|
|
176
160
|
*
|
|
161
|
+
* Without this the panel is only as live as whatever else is running: with no
|
|
162
|
+
* `cswap watch`/`auto`/TUI open, nothing ever writes the store and the panel
|
|
163
|
+
* shows frozen numbers while looking current.
|
|
164
|
+
*
|
|
177
165
|
* Two ways to ask, and the cheaper one is preferred:
|
|
178
166
|
* - something is due by claude-swap's own plan → `cswap list`, the ordinary
|
|
179
167
|
* on-demand pass every surface uses;
|
package/src/server/index.mjs
CHANGED
|
@@ -339,11 +339,14 @@ function scanTranscript(path) {
|
|
|
339
339
|
// ─── Model enrichment ────────────────────────────────────────────────────
|
|
340
340
|
// CC's hook payloads never carry the `model` field — but every hook
|
|
341
341
|
// references a `transcript_path` JSONL that contains lines like
|
|
342
|
-
// `"model":"claude-opus-4-7"`. We read the tail of that file
|
|
343
|
-
//
|
|
342
|
+
// `"model":"claude-opus-4-7"`. We re-read the tail of that file on every
|
|
343
|
+
// event for the session (throttled to MODEL_READ_THROTTLE_MS), cache the
|
|
344
|
+
// resolved root + subagent models, and (a) inject `model` into subsequent
|
|
344
345
|
// payloads for that session before broadcasting, (b) emit a synthetic
|
|
345
|
-
// `ModelObserved` event so the client backfills
|
|
346
|
-
// the model was resolved.
|
|
346
|
+
// `ModelObserved` event whenever that set CHANGES, so the client backfills
|
|
347
|
+
// agents created before the model was resolved. The cache is the emit
|
|
348
|
+
// filter, not a read filter: reading once per session meant a subagent
|
|
349
|
+
// model that only appears after the root is known was never picked up.
|
|
347
350
|
const modelBySession = new Map(); // sessionId -> { rootModel, subsSig }
|
|
348
351
|
const pendingTranscriptReads = new Set(); // sessionId currently being read
|
|
349
352
|
const modelLastReadAt = new Map(); // sessionId -> ms timestamp (re-read throttle)
|
|
@@ -489,8 +492,11 @@ function maybeResolveUsage(payload) {
|
|
|
489
492
|
// Approximation of `/context` since CC doesn't expose its breakdown via
|
|
490
493
|
// hooks. We scan the transcript JSONL for message counts (user / assistant
|
|
491
494
|
// / tool_use / tool_result / system-reminders) and walk up from cwd for
|
|
492
|
-
// any CLAUDE.md files in scope.
|
|
493
|
-
// scan
|
|
495
|
+
// any CLAUDE.md files in scope. Cumulative token totals come from
|
|
496
|
+
// UsageObserved; this scan produces the structural counts ("what does the
|
|
497
|
+
// context contain") plus the current window size — currentContextTokens, the
|
|
498
|
+
// last usage block after the most recent /clear or /compact, which is what
|
|
499
|
+
// the context donut and the modal's percentage are drawn from.
|
|
494
500
|
const lastContextReadAt = new Map();
|
|
495
501
|
const pendingContextReads = new Set();
|
|
496
502
|
const CONTEXT_READ_THROTTLE_MS = 4000;
|
|
@@ -1192,10 +1198,11 @@ function pushEvent(raw, source, opts = {}) {
|
|
|
1192
1198
|
// dead session ids before the first live event even arrives.
|
|
1193
1199
|
if (!opts.replay && raw && typeof raw === "object") touchSession(raw.session_id);
|
|
1194
1200
|
|
|
1195
|
-
// Kick off async transcript scans. Model
|
|
1196
|
-
//
|
|
1197
|
-
//
|
|
1198
|
-
//
|
|
1201
|
+
// Kick off async transcript scans. Model and usage are both re-read
|
|
1202
|
+
// periodically (throttled to 2.5s per session) so the cost columns track
|
|
1203
|
+
// running totals as the session progresses and late subagent models still
|
|
1204
|
+
// land; ModelObserved is only emitted when the resolved set changes. Both
|
|
1205
|
+
// result in synthetic events.
|
|
1199
1206
|
// Provider gates the path: Claude reads transcript_path; Codex reads its
|
|
1200
1207
|
// rollout JSONL under ~/.codex/sessions/. The Claude scanners short-circuit
|
|
1201
1208
|
// when transcript_path is absent (always the case for Codex hooks).
|
package/src/server/quota.mjs
CHANGED
|
@@ -226,15 +226,6 @@ function stripAnsi(s) {
|
|
|
226
226
|
.replace(/\x1B[()][AB012]/g, "");
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
-
/**
|
|
230
|
-
* Parse `claude --print /usage` output.
|
|
231
|
-
*
|
|
232
|
-
* Observed format (Claude Code ≥ 1.x):
|
|
233
|
-
* "Current session: 84% used · resets Jun 18, 4:09pm (Europe/Chisinau)"
|
|
234
|
-
* "Current week (all models): 85% used · resets Jun 21, 8:59am (Europe/Chisinau)"
|
|
235
|
-
* "Current week (Sonnet only): 48% used · resets Jun 21, 9am (Europe/Chisinau)"
|
|
236
|
-
* "Current week (Opus only): ..." (if present)
|
|
237
|
-
*/
|
|
238
229
|
// Parse "Jun 18, 4:09pm" (local time, no tz) into unix seconds.
|
|
239
230
|
// Claude shows times in the user's local timezone, so parsing as local is correct.
|
|
240
231
|
// `now` is injectable so the year-boundary case is testable.
|
|
@@ -263,6 +254,15 @@ export function parseResetToSec(resetStr, now = Date.now()) {
|
|
|
263
254
|
} catch { return null; }
|
|
264
255
|
}
|
|
265
256
|
|
|
257
|
+
/**
|
|
258
|
+
* Parse `claude --print /usage` output.
|
|
259
|
+
*
|
|
260
|
+
* Observed format (Claude Code ≥ 1.x):
|
|
261
|
+
* "Current session: 84% used · resets Jun 18, 4:09pm (Europe/Chisinau)"
|
|
262
|
+
* "Current week (all models): 85% used · resets Jun 21, 8:59am (Europe/Chisinau)"
|
|
263
|
+
* "Current week (Sonnet only): 48% used · resets Jun 21, 9am (Europe/Chisinau)"
|
|
264
|
+
* "Current week (Opus only): ..." (if present)
|
|
265
|
+
*/
|
|
266
266
|
function parseUsageText(raw) {
|
|
267
267
|
const text = stripAnsi(raw);
|
|
268
268
|
const result = {};
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
// So we report three distinct versions:
|
|
16
16
|
// running — captured at boot by the caller, before an upgrade can land
|
|
17
17
|
// installed — re-read from disk per call; what a restart would run
|
|
18
|
-
// latest — npm's dist-tag, fetched at most once
|
|
18
|
+
// latest — npm's dist-tag, fetched at most once an hour (CHECK_MS below,
|
|
19
|
+
// which also explains why it is not the daily cadence it was)
|
|
19
20
|
//
|
|
20
21
|
// Installing is opt-in and narrow. `npm i -g` runs only when the user asks for
|
|
21
22
|
// it by name and only where it can actually work: a global install, on a
|
|
@@ -778,9 +779,14 @@ export function lastMeaningfulLine(text) {
|
|
|
778
779
|
return lines.length ? lines[lines.length - 1].slice(0, 300) : "";
|
|
779
780
|
}
|
|
780
781
|
|
|
781
|
-
/** Full answer for GET /api/version. Never throws,
|
|
782
|
-
*
|
|
783
|
-
*
|
|
782
|
+
/** Full answer for GET /api/version. Never throws, and answers the local half
|
|
783
|
+
* even when the registry is unreachable.
|
|
784
|
+
*
|
|
785
|
+
* Network worst case is 2 x FETCH_TIMEOUT_MS, not one: the dist-tag lookup,
|
|
786
|
+
* plus — only when the tag has moved to a version this deck has not confirmed
|
|
787
|
+
* yet — the installability probe (see runCheck), each carrying its own
|
|
788
|
+
* AbortSignal timeout. That second request costs its timeout at most once per
|
|
789
|
+
* release; a deck sitting on the current release stays inside one. */
|
|
784
790
|
export async function versionReport({ running, pkgRoot, name = "agents-deck", now = Date.now(), force = false }) {
|
|
785
791
|
const installed = installedVersion(pkgRoot);
|
|
786
792
|
// Asked about the package the command installs, not about the one this build
|