feat: Claude Code Monitor — lanes, pipelines and a merged workspace
Internal SmartGift build of a Claude Code monitoring dashboard. Lanes: a durable unit of parallel agent work, one per working directory, tracked across session restarts. Managed lanes are git worktrees the dashboard provisions and can reset or remove behind a three-check destroy guard and a counted preflight; adopted lanes are directories you already own and are never destroyable. Pipelines: a lane moves through pipeline stages. A stage the agent declares with evidence renders green; a stage inferred from the tool-event stream renders dashed amber and never counts as done. Detection is forward-only within a 30-minute window, and never writes the declared stage. Workspace: one page at /run with a lane grid, the selected lane's pipeline, and a full Claude console behind a disclosure.
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* @file Tests for replaceTokenUsage's compaction baseline semantics.
|
||||
*
|
||||
* The effective total for a bucket is `live + baseline`. It must behave as a
|
||||
* monotonic HIGH-WATER MARK: never decrease (so a compaction that shrinks the
|
||||
* transcript doesn't lose usage), but never inflate past the largest value ever
|
||||
* seen (so two writers hitting the same bucket with different scopes — the live
|
||||
* hook writer stores main-only tokens, importSession stores main+subagents —
|
||||
* can't ratchet the baseline upward on every downward fluctuation).
|
||||
*
|
||||
* Regression guard for the runaway that inflated one 26-day session's baseline
|
||||
* to ~11× its real usage (dashboard total $22.5k vs true ~$15.2k).
|
||||
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
||||
*/
|
||||
|
||||
const { describe, it, before, after } = require("node:test");
|
||||
const assert = require("node:assert/strict");
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const os = require("os");
|
||||
|
||||
const TEST_DB = path.join(os.tmpdir(), `dashboard-token-baseline-${Date.now()}-${process.pid}.db`);
|
||||
process.env.DASHBOARD_DB_PATH = TEST_DB;
|
||||
|
||||
const dbModule = require("../db");
|
||||
const { db, stmts } = dbModule;
|
||||
|
||||
after(() => {
|
||||
if (db) db.close();
|
||||
for (const suffix of ["", "-wal", "-shm"]) {
|
||||
try {
|
||||
fs.unlinkSync(TEST_DB + suffix);
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Write a cache_read value for a fixed bucket; return effective (live+baseline).
|
||||
function writeCacheRead(sessionId, cacheRead) {
|
||||
stmts.replaceTokenUsage.run(
|
||||
sessionId,
|
||||
"claude-opus-4-8",
|
||||
"standard",
|
||||
"global",
|
||||
"standard",
|
||||
0, // input
|
||||
0, // output
|
||||
cacheRead,
|
||||
0, // cache_write
|
||||
0, // cache_write_1h
|
||||
0, // web_search
|
||||
0, // web_fetch
|
||||
0 // code_execution
|
||||
);
|
||||
}
|
||||
function effectiveCacheRead(sessionId) {
|
||||
const r = stmts.getTokensBySession.all(sessionId).find((x) => x.model === "claude-opus-4-8");
|
||||
return r ? r.cache_read_tokens : 0;
|
||||
}
|
||||
function rawRow(sessionId) {
|
||||
return db
|
||||
.prepare(
|
||||
"SELECT cache_read_tokens, baseline_cache_read FROM token_usage WHERE session_id = ? AND model = 'claude-opus-4-8'"
|
||||
)
|
||||
.get(sessionId);
|
||||
}
|
||||
|
||||
describe("replaceTokenUsage — high-water-mark baseline", () => {
|
||||
before(() => {
|
||||
for (const id of ["hw-grow", "hw-idem", "hw-shrink", "hw-altern", "hw-recover"]) {
|
||||
try {
|
||||
stmts.insertSession.run(id, "t", "active", "/tmp", null, null);
|
||||
} catch {
|
||||
/* exists */
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("monotonic growth: effective follows the latest, no baseline", () => {
|
||||
writeCacheRead("hw-grow", 100);
|
||||
assert.equal(effectiveCacheRead("hw-grow"), 100);
|
||||
writeCacheRead("hw-grow", 300);
|
||||
assert.equal(effectiveCacheRead("hw-grow"), 300);
|
||||
assert.equal(rawRow("hw-grow").baseline_cache_read, 0);
|
||||
});
|
||||
|
||||
it("idempotent: rewriting the same value never changes effective", () => {
|
||||
writeCacheRead("hw-idem", 500);
|
||||
writeCacheRead("hw-idem", 500);
|
||||
writeCacheRead("hw-idem", 500);
|
||||
assert.equal(effectiveCacheRead("hw-idem"), 500);
|
||||
assert.equal(rawRow("hw-idem").baseline_cache_read, 0);
|
||||
});
|
||||
|
||||
it("decrease preserves the max (compaction never loses usage)", () => {
|
||||
writeCacheRead("hw-shrink", 300);
|
||||
writeCacheRead("hw-shrink", 100); // transcript shrank
|
||||
assert.equal(effectiveCacheRead("hw-shrink"), 300, "effective must not drop below the peak");
|
||||
const row = rawRow("hw-shrink");
|
||||
assert.equal(row.cache_read_tokens, 100);
|
||||
assert.equal(row.baseline_cache_read, 200); // 100 live + 200 baseline = 300
|
||||
});
|
||||
|
||||
it("writer alternation does NOT run away (the bug)", () => {
|
||||
// Two writers: 'big' (main+subagents) and 'small' (main-only) on one bucket.
|
||||
for (let i = 0; i < 20; i++) {
|
||||
writeCacheRead("hw-altern", 800); // big writer
|
||||
writeCacheRead("hw-altern", 700); // small writer
|
||||
}
|
||||
// Effective must stay pinned at the true max (800), NOT accumulate.
|
||||
assert.equal(effectiveCacheRead("hw-altern"), 800, "effective must stay at the peak, not grow");
|
||||
assert.equal(rawRow("hw-altern").baseline_cache_read, 100); // 700 + 100 = 800
|
||||
});
|
||||
|
||||
it("recovers upward: a new higher value zeroes stale baseline", () => {
|
||||
writeCacheRead("hw-recover", 300);
|
||||
writeCacheRead("hw-recover", 100); // baseline=200, eff=300
|
||||
writeCacheRead("hw-recover", 500); // new peak
|
||||
assert.equal(effectiveCacheRead("hw-recover"), 500);
|
||||
assert.equal(rawRow("hw-recover").baseline_cache_read, 0);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user