ccdeck 3.36.3 → 3.36.5
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/README.md +7 -7
- package/dist/web/assets/{BrowserWatchModal-BJKk2x-P.js → BrowserWatchModal-LYnUxuAL.js} +1 -1
- package/dist/web/assets/{UsageHistoryModal-ClT1-0hN.js → UsageHistoryModal-B0qdsys5.js} +1 -1
- package/dist/web/assets/{index-Dj4JHRcG.js → index-B18vwZ9I.js} +29 -29
- package/dist/web/assets/index-BkXTN4dZ.css +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/release-notes.json +3 -1
- package/src/server/deck-prefs.mjs +2 -2
- package/src/server/output-watch.mjs +14 -1
- package/src/server/reports-routes.mjs +4 -3
- package/src/server/reports.mjs +12 -9
- package/src/server/session-tracking.mjs +9 -1
- package/dist/web/assets/index-1U-Iz_x2.css +0 -1
package/dist/web/index.html
CHANGED
|
@@ -64,8 +64,8 @@
|
|
|
64
64
|
stored === "light" || (stored !== "dark" && light) ? "light" : "dark");
|
|
65
65
|
})();
|
|
66
66
|
</script>
|
|
67
|
-
<script type="module" crossorigin src="/assets/index-
|
|
68
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
67
|
+
<script type="module" crossorigin src="/assets/index-B18vwZ9I.js"></script>
|
|
68
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BkXTN4dZ.css">
|
|
69
69
|
</head>
|
|
70
70
|
<body>
|
|
71
71
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccdeck",
|
|
3
|
-
"version": "3.36.
|
|
3
|
+
"version": "3.36.5",
|
|
4
4
|
"description": "Local dashboard for Claude Code and Codex CLI sessions: which Claude Code session needs input, every tool call and Claude Code subagent live, token cost and quota, several Claude accounts. Run npx ccdeck.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/release-notes.json
CHANGED
|
@@ -80,8 +80,8 @@ export const DEFAULTS = Object.freeze({
|
|
|
80
80
|
// the server can read it with no page open.
|
|
81
81
|
autoUpdate: true,
|
|
82
82
|
// USAGE REPORTS (#1853), ON unless somebody turns them off — the owner's
|
|
83
|
-
// decision, 2026-09-30: nobody is asked
|
|
84
|
-
//
|
|
83
|
+
// decision, 2026-09-30: nobody is asked and the README says what is sent; the
|
|
84
|
+
// page has no switch since 2026-10-01. See reports.mjs for what is sent, and
|
|
85
85
|
// reportsVetoed for the launch-time veto that wins over this.
|
|
86
86
|
reports: true,
|
|
87
87
|
// What reports.mjs keeps between runs, and the page never sees
|
|
@@ -147,6 +147,19 @@ export function createOutputWatch(io = {}) {
|
|
|
147
147
|
function clear() { seen.clear(); }
|
|
148
148
|
function size() { return seen.size; }
|
|
149
149
|
|
|
150
|
+
/** How many distinct projects the live sessions sit in, read off the paths
|
|
151
|
+
* already held — no new state. Claude keeps one transcript folder per project
|
|
152
|
+
* under ~/.claude/projects, so distinct folders are distinct projects. Only
|
|
153
|
+
* the count is ever read; no path or project name leaves. */
|
|
154
|
+
function projectCount() {
|
|
155
|
+
const projects = new Set();
|
|
156
|
+
for (const { path } of seen.values()) {
|
|
157
|
+
const cut = Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\"));
|
|
158
|
+
projects.add(cut > 0 ? path.slice(0, cut) : path);
|
|
159
|
+
}
|
|
160
|
+
return projects.size;
|
|
161
|
+
}
|
|
162
|
+
|
|
150
163
|
/**
|
|
151
164
|
* One tick. Stats each named session's file, reads only what is new, and
|
|
152
165
|
* answers with EVERY block that landed in it, oldest first — see blocksIn
|
|
@@ -270,5 +283,5 @@ export function createOutputWatch(io = {}) {
|
|
|
270
283
|
}
|
|
271
284
|
}
|
|
272
285
|
|
|
273
|
-
return { note, forget, clear, size, poll };
|
|
286
|
+
return { note, forget, clear, size, projectCount, poll };
|
|
274
287
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// The page's
|
|
2
|
-
//
|
|
1
|
+
// The page's ways into reports.mjs (#1853): an error the page caught and the
|
|
2
|
+
// feedback dialog. (The switch in Appearance went on 2026-10-01; its route stays.) The page never
|
|
3
3
|
// talks to api.ccdeck.dev itself — this server does, which is also why the
|
|
4
4
|
// install id never has to reach the page.
|
|
5
5
|
|
|
@@ -19,7 +19,8 @@ async function readJson(req, res, limit) {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
/** `POST /api/reports` `{ on }`:
|
|
22
|
+
/** `POST /api/reports` `{ on }`: sets `prefs.reports`. No page control calls it since the owner
|
|
23
|
+
* removed Appearance's switch (2026-10-01); kept so a deck can still be switched off over the API. */
|
|
23
24
|
export async function handleReportsWrite(req, res, { report = reporter } = {}) {
|
|
24
25
|
const body = await readJson(req, res, 1_000);
|
|
25
26
|
if (typeof body?.on !== "boolean") return send(res, 400, { ok: false, reason: "bad_request" });
|
package/src/server/reports.mjs
CHANGED
|
@@ -40,8 +40,9 @@
|
|
|
40
40
|
// so it stops entirely the moment reports are switched off or vetoed.
|
|
41
41
|
//
|
|
42
42
|
// NOBODY IS ASKED, AND NOTHING IS HIDDEN. The owner chose on-by-default
|
|
43
|
-
// (2026-09-30): the README says what is sent,
|
|
44
|
-
//
|
|
43
|
+
// (2026-09-30): the README says what is sent, and AGENTS_DECK_NO_REPORTS=1 keeps it
|
|
44
|
+
// off from the first start. The deck has no switch for it since the owner removed
|
|
45
|
+
// Appearance's on 2026-10-01.
|
|
45
46
|
//
|
|
46
47
|
// SWITCHING IT OFF DELETES WHAT WAS SENT. The id is forgotten here and the API
|
|
47
48
|
// is asked to drop every event and error it holds for it; if that request
|
|
@@ -533,17 +534,19 @@ export function createReporter({
|
|
|
533
534
|
// the CLI probe into a fast path like `--version` that imports it for nothing.
|
|
534
535
|
|
|
535
536
|
/** The coarse counts the "active" report carries, read from the state the deck
|
|
536
|
-
* already keeps — the LRU of tracked sessions
|
|
537
|
-
* signatures
|
|
538
|
-
*
|
|
539
|
-
*
|
|
540
|
-
*
|
|
537
|
+
* already keeps — the LRU of tracked sessions, the per-session subagent
|
|
538
|
+
* signatures, and the folders those sessions' transcripts sit in. Never new
|
|
539
|
+
* tracking, and never anything but a number: no session id, project name or
|
|
540
|
+
* path, only how many. `projects` is the distinct transcript folders among the
|
|
541
|
+
* live sessions, so it counts Claude projects; a Codex-only deck sends no
|
|
542
|
+
* transcript path and so reports no projects. */
|
|
541
543
|
async function deckUsage() {
|
|
542
544
|
const out = {};
|
|
543
545
|
try {
|
|
544
|
-
const { trackedSessionCount } = await import("./session-tracking.mjs");
|
|
546
|
+
const { trackedSessionCount, trackedProjectCount } = await import("./session-tracking.mjs");
|
|
545
547
|
out.sessions = trackedSessionCount();
|
|
546
|
-
|
|
548
|
+
out.projects = trackedProjectCount();
|
|
549
|
+
} catch { /* counts unavailable: omitted */ }
|
|
547
550
|
try {
|
|
548
551
|
const { trackedSubagentCount } = await import("./session-enrichment.mjs");
|
|
549
552
|
out.subagents = trackedSubagentCount();
|
|
@@ -156,6 +156,14 @@ function trackedSessionCount() {
|
|
|
156
156
|
return sessionTouchedAt.size;
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
+
/** How many distinct projects those live sessions sit in — the same live set,
|
|
160
|
+
* counted by the folder each session's transcript is in. Reused, not new state:
|
|
161
|
+
* the watch already holds every live session's transcript path. Never a project
|
|
162
|
+
* name or path — only the count. */
|
|
163
|
+
function trackedProjectCount() {
|
|
164
|
+
return outputWatch.projectCount();
|
|
165
|
+
}
|
|
166
|
+
|
|
159
167
|
function touchSession(sid) {
|
|
160
168
|
if (!sid || typeof sid !== "string") return;
|
|
161
169
|
// Re-insert so the Map's own insertion order *is* the LRU order and eviction
|
|
@@ -248,4 +256,4 @@ async function handleForget(req, res) {
|
|
|
248
256
|
// What index.mjs calls besides HARD_TRACKED_SESSIONS. Listed rather than
|
|
249
257
|
// marked at each declaration, so the declarations read as they did where they
|
|
250
258
|
// came from.
|
|
251
|
-
export { handleForget, outputWatch, startOutputWatch, touchSession, trackedSessionCount };
|
|
259
|
+
export { handleForget, outputWatch, startOutputWatch, touchSession, trackedProjectCount, trackedSessionCount };
|