Skip to content
590 linesCodeBlameRaw
1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import type { AgentSession, Deployment, InboxItem, InstallRequest, Memory } from "@g1t/contracts";
5
6import {
7 type AttentionRow,
8 type CodeNeed,
9 type CodePull,
10 acceptance,
11 agentRow,
12 attention,
13 chatRow,
14 codeRow,
15 dayIn,
16 decisionsIn,
17 deploysIn,
18 duration,
19 installRequestRow,
20 landedIn,
21 limitRow,
22 notificationRow,
23 parseWindow,
24 pullOutcome,
25 rankAttention,
26 running,
27 runningDeploys,
28 runningSessions,
29 sessionOutcome,
30 sinceWords,
31 spanFor,
32 spanMonths,
33 spanSentence,
34 spanWork,
35 spendIn,
36 startHere,
37 trendLabel,
38 waitingSentence,
39} from "./home.ts";
40
41const HOUR = 3_600_000;
42const DAY = 24 * HOUR;
43// Friday 2026-10-09, 18:00 UTC; 11:00 in Los Angeles.
44const NOW = Date.parse("2026-10-09T18:00:00Z");
45const LA = "America/Los_Angeles";
46const repo = { namespace: "acme", name: "web" };
47const iso = (ms: number) => new Date(ms).toISOString();
48
49function pull(over: Partial<CodePull> = {}): CodePull {
50 return {
51 repo,
52 number: 1,
53 title: "Fix the flaky test",
54 status: "merged",
55 mergedAt: iso(NOW - HOUR),
56 createdAt: iso(NOW - 3 * HOUR),
57 updatedAt: iso(NOW - HOUR),
58 author: { username: "g1t", kind: "agent" },
59 ...over,
60 };
61}
62
63function session(over: Partial<AgentSession> = {}): AgentSession {
64 return {
65 id: "s1",
66 workspace_id: "w",
67 agent_id: "a",
68 agent_handle: "margo",
69 agent_name: "Margo",
70 agent_avatar_seed: "margo",
71 subagent: null,
72 kind: "chat",
73 parent_id: null,
74 root_id: "s1",
75 payer_agent_id: "a",
76 title: "Draft the launch notes",
77 goal: "",
78 status: "done",
79 status_note: null,
80 summary: null,
81 channel_id: "c",
82 channel_kind: "channel",
83 channel_name: "launch",
84 card_message_id: null,
85 asked_by: null,
86 asked_by_username: "bo",
87 routine_id: null,
88 steps: 3,
89 tool_calls: 2,
90 input_tokens: 0,
91 output_tokens: 0,
92 charged_micros: 400_000,
93 cap_micros: 2_000_000,
94 model: null,
95 outputs: [],
96 created_at: iso(NOW - 2 * HOUR),
97 updated_at: iso(NOW - HOUR),
98 finished_at: iso(NOW - HOUR),
99 visible: true,
100 ...over,
101 };
102}
103const need = (over: Partial<CodeNeed>): CodeNeed => ({
104 key: "pull:p1",
105 reason: "ready_to_merge",
106 repo,
107 ref: "#12",
108 title: "Add retries",
109 ask: "Waiting for you to merge it.",
110 by: { name: "g1t", agent: true },
111 for: "bo",
112 at: NOW - 2 * HOUR,
113 to: "/acme/web/pull/12",
114 facts: [{ label: "Files changed", value: "4", tone: null }],
115 ...over,
116});
117
118test("Code's needs become rows with what is at stake", () => {
119 const ready = codeRow(need({}));
120 assert.equal(ready.kind, "ready");
121 assert.equal(ready.stake?.text, "4 files to land");
122 assert.equal(ready.action.label, "Merge");
123 const deploy = codeRow(need({ key: "deploy:site", reason: "blocking", facts: [{ label: "Production", value: "Serving the build before", tone: "good" }] }));
124 assert.equal(deploy.kind, "deploy");
125 assert.equal(deploy.stake?.text, "Production on an older build");
126 assert.equal(codeRow(need({ reason: "checks_failing" })).kind, "pull_blocked");
127 assert.equal(codeRow(need({ key: "run:r1", reason: "stalled", facts: [{ label: "Cost so far", value: "$1.20", tone: null }] })).stake?.text, "$1.20 so far");
128});
129
130const row = (over: Partial<AttentionRow>): AttentionRow => ({
131 key: "k",
132 kind: "chat",
133 title: "t",
134 detail: "d",
135 stake: null,
136 action: { label: "Open", to: "/x" },
137 owner: null,
138 at: NOW,
139 from: "chat",
140 ...over,
141});
142
143test("Start here: the most pressing tier first, then what has waited longest", () => {
144 const rows = [
145 row({ key: "chat:old", kind: "chat", at: NOW - 5 * DAY, action: { label: "Reply", to: "/acme/-/chat/general" } }),
146 row({ key: "ready:new", kind: "ready", at: NOW - HOUR, action: { label: "Merge", to: "/acme/web/pull/2" } }),
147 row({ key: "ready:old", kind: "ready", at: NOW - 3 * HOUR, action: { label: "Merge", to: "/acme/web/pull/1" } }),
148 row({ key: "session:s", kind: "session_cap", at: NOW - 10 * 60_000, action: { label: "Approve more", to: "/acme/-/agents/margo/sessions/s" } }),
149 ];
150 const ranked = rankAttention(rows);
151 assert.deepEqual(ranked.map((r) => r.key), ["session:s", "ready:old", "ready:new", "chat:old"]);
152 const start = startHere(ranked);
153 assert.equal(start?.row.key, "session:s");
154 assert.match(start?.why ?? "", /spend cap/);
155 // A failed production deploy beats everything.
156 const withDeploy = rankAttention([...rows, row({ key: "deploy:site", kind: "deploy", at: NOW, action: { label: "See the build", to: "/acme/site/deployments/1" } })]);
157 assert.equal(startHere(withDeploy)?.row.key, "deploy:site");
158 // Ties in tier say so.
159 const two = startHere(rankAttention(rows.filter((r) => r.kind === "ready")));
160 assert.equal(two?.row.key, "ready:old");
161 assert.match(two?.why ?? "", /Of the 2 like it, it has waited longest/);
162 assert.equal(startHere([]), null);
163});
164
165test("the same order whatever order the rows came in", () => {
166 const rows = [row({ key: "b", kind: "review", at: NOW }), row({ key: "a", kind: "review", at: NOW, action: { label: "Review", to: "/y" } })];
167 assert.deepEqual(rankAttention(rows).map((r) => r.key), ["a", "b"]);
168 assert.deepEqual(rankAttention([...rows].reverse()).map((r) => r.key), ["a", "b"]);
169});
170
171const item = (over: Partial<InboxItem>): InboxItem => ({
172 id: "n1",
173 reason: "ci_activity",
174 severity: "error",
175 title: "Checks failed on #12",
176 body: "Add retries",
177 event: "check.failed",
178 repo: "acme/web",
179 workspace: "acme",
180 subject: "pull",
181 number: 12,
182 url: "/acme/web/pull/12",
183 actor: "g1t",
184 count: 1,
185 createdAt: iso(NOW - HOUR),
186 updatedAt: iso(NOW - HOUR),
187 readAt: null,
188 doneAt: null,
189 saved: false,
190 snoozedUntil: null,
191 ...over,
192});
193
194test("notifications: warnings and failures in this workspace; none about repositories without Code", () => {
195 assert.equal(notificationRow(item({}), "acme", true)?.kind, "notification");
196 assert.equal(notificationRow(item({}), "acme", false), null);
197 assert.equal(notificationRow(item({ repo: null, url: "/acme/-/agents/margo" }), "acme", false)?.kind, "notification");
198 assert.equal(notificationRow(item({ severity: "info" }), "acme", true), null);
199 assert.equal(notificationRow(item({ workspace: "other", repo: "other/web" }), "acme", true), null);
200 assert.equal(notificationRow(item({ readAt: iso(NOW) }), "acme", true), null);
201});
202
203test("a notification about something already listed is left out", () => {
204 const out = attention({
205 slug: "acme",
206 code: true,
207 codeNeeds: [need({})],
208 capped: [],
209 agents: [],
210 canManage: false,
211 notifications: [item({})],
212 chat: [],
213 });
214 assert.deepEqual(out.rows.map((r) => r.key), ["pull:p1"]);
215 assert.deepEqual(out.missing, []);
216});
217
218test("without Code access no Code row is asked for or shown, and a silent source is named", () => {
219 const out = attention({
220 slug: "acme",
221 code: false,
222 codeNeeds: [need({})],
223 capped: null,
224 agents: null,
225 canManage: false,
226 notifications: [item({}), item({ id: "n2", repo: null, reason: "agent", severity: "warning", url: "/acme/-/agents/margo" })],
227 chat: null,
228 });
229 assert.deepEqual(out.rows.map((r) => r.key), ["notification:n2"]);
230 assert.equal(out.rows.some((r) => r.from === "code"), false);
231 assert.deepEqual(out.missing, ["Agents", "Chat"]);
232});
233
234test("an agent out of budget is listed only for those who may raise it", () => {
235 const agent = { id: "a1", handle: "margo", display_name: "Margo", status: "out_of_budget", spent_month_micros: 52_000_000, budget: { monthly_micros: 50_000_000 }, updated_at: iso(NOW) };
236 assert.equal(agentRow(agent, "acme")?.stake?.text, "$0.00 left");
237 const base = { slug: "acme", code: true, codeNeeds: [], capped: [], notifications: [], chat: [] };
238 assert.equal(attention({ ...base, agents: [agent], canManage: false }).rows.length, 0);
239 assert.equal(attention({ ...base, agents: [agent], canManage: true }).rows[0]?.kind, "agent_budget");
240});
241
242test("chat: mentions anywhere and unread direct messages, never muted", () => {
243 const channel = { id: "c1", kind: "channel" as const, name: "general", last_message_at: iso(NOW) };
244 assert.equal(chatRow({ channel, title: "general", muted: false, unread: 4, mentions: 0 }, "acme"), null);
245 assert.equal(chatRow({ channel, title: "general", muted: false, unread: 4, mentions: 2 }, "acme")?.stake?.text, "2 mentions");
246 assert.equal(chatRow({ channel, title: "general", muted: true, unread: 4, mentions: 2 }, "acme"), null);
247 const dm = chatRow({ channel: { ...channel, kind: "dm", name: null }, title: "Bo Reed", muted: false, unread: 1, mentions: 0 }, "acme");
248 assert.equal(dm?.action.to, "/acme/-/chat/dm/c1");
249});
250
251// The span is NOW back to 3 days ago unless a test says otherwise.
252const SPAN = { from: NOW - 3 * DAY, now: NOW };
253
254test("a day is the reader's day", () => {
255 assert.equal(dayIn(NOW, LA), "2026-10-09");
256 assert.equal(dayIn(Date.parse("2026-10-10T02:00:00Z"), LA), "2026-10-09");
257 assert.equal(dayIn(Date.parse("2026-10-10T02:00:00Z"), null), "2026-10-10");
258 assert.equal(dayIn(NOW, "Not/AZone"), "2026-10-09");
259});
260
261test("since your last visit, in words, in the reader's time zone", () => {
262 // NOW is Friday 11:00 in Los Angeles.
263 assert.equal(sinceWords(NOW - 20_000, NOW, LA), "a moment ago");
264 assert.equal(sinceWords(NOW - 40 * 60_000, NOW, LA), "40 minutes ago");
265 assert.equal(sinceWords(NOW - HOUR - 60_000, NOW, LA), "an hour ago");
266 assert.equal(sinceWords(NOW - 2 * HOUR, NOW, LA), "2 hours ago");
267 // 07:00 Friday.
268 assert.equal(sinceWords(NOW - 4 * HOUR, NOW, LA), "this morning");
269 // 02:00 Friday is Thursday night.
270 assert.equal(sinceWords(NOW - 9 * HOUR, NOW, LA), "last night");
271 // 19:00 Thursday.
272 assert.equal(sinceWords(NOW - 16 * HOUR, NOW, LA), "yesterday evening");
273 // 19:00 Tuesday.
274 assert.equal(sinceWords(NOW - 2 * DAY - 16 * HOUR, NOW, LA), "Tuesday evening");
275 // 02:00 Wednesday is Tuesday night.
276 assert.equal(sinceWords(NOW - 2 * DAY - 9 * HOUR, NOW, LA), "Tuesday night");
277 assert.equal(sinceWords(NOW - 9 * DAY, NOW, LA), "Sep 30");
278});
279
280test("how long a span is", () => {
281 assert.equal(duration(30_000), "a moment");
282 assert.equal(duration(45 * 60_000), "45 minutes");
283 assert.equal(duration(HOUR), "1 hour");
284 assert.equal(duration(3 * DAY + HOUR), "3 days");
285 assert.equal(duration(15 * DAY), "2 weeks");
286});
287
288test("the span: since your last visit, capped, or a fixed window", () => {
289 assert.equal(parseWindow("24h"), "24h");
290 assert.equal(parseWindow("7d"), "7d");
291 assert.equal(parseWindow("nonsense"), "last");
292 assert.equal(parseWindow(null), "last");
293 const away = spanFor("last", NOW, NOW - 2 * DAY - 16 * HOUR, LA);
294 assert.equal(away.from, NOW - 2 * DAY - 16 * HOUR);
295 assert.equal(away.words, "Since Tuesday evening");
296 assert.equal(away.length, "2 days");
297 assert.equal(away.note, null);
298 // Never visited: the last 24 hours, and it says why.
299 const first = spanFor("last", NOW, null, LA);
300 assert.equal(first.from, NOW - DAY);
301 assert.equal(first.note, "first");
302 assert.equal(spanFor("last", NOW, undefined, LA).note, "unknown");
303 // Away a month: 14 days at most.
304 const capped = spanFor("last", NOW, NOW - 30 * DAY, LA);
305 assert.equal(capped.from, NOW - 14 * DAY);
306 assert.equal(capped.note, "capped");
307 assert.equal(capped.words, "In the last 14 days");
308 // The fixed windows ignore the last visit.
309 assert.equal(spanFor("24h", NOW, NOW - 3 * DAY, LA).from, NOW - DAY);
310 assert.deepEqual([spanFor("7d", NOW, NOW - HOUR, LA).from, spanFor("7d", NOW, NOW - HOUR, LA).words], [NOW - 7 * DAY, "In the last 7 days"]);
311});
312
313test("an agent's pull request is accepted first time when it merged in the span with no revision", () => {
314 assert.equal(pullOutcome(pull(), 0, SPAN), "accepted");
315 assert.equal(pullOutcome(pull(), 2, SPAN), "fixed");
316 assert.equal(pullOutcome(pull({ mergedAt: iso(NOW - 4 * DAY) }), 0, SPAN), null);
317 assert.equal(pullOutcome(pull({ status: "closed", mergedAt: null }), 0, SPAN), "dropped");
318 // Still open is not settled: it is under Running now.
319 assert.equal(pullOutcome(pull({ status: "open", mergedAt: null }), 1, SPAN), null);
320});
321
322test("a session counts once, at the root of its tree, when it settled in the span", () => {
323 assert.equal(sessionOutcome(session(), SPAN), "finished");
324 assert.equal(sessionOutcome(session({ parent_id: "s0" }), SPAN), null);
325 assert.equal(sessionOutcome(session({ status: "failed" }), SPAN), "dropped");
326 assert.equal(sessionOutcome(session({ status: "stopped" }), SPAN), "dropped");
327 assert.equal(sessionOutcome(session({ status: "working", finished_at: null }), SPAN), null);
328 assert.equal(sessionOutcome(session({ finished_at: iso(NOW - 4 * DAY) }), SPAN), null);
329});
330
331test("accepted first time is accepted over every agent pull request that settled", () => {
332 assert.deepEqual(acceptance(["accepted", "accepted", "fixed", "dropped", "finished"]), { value: 0.5, of: 4 });
333 assert.equal(acceptance(["finished"]), null);
334});
335
336test("the span's work: pull requests and sessions, sources, and the 7 days before", () => {
337 const work = spanWork({
338 span: SPAN,
339 slug: "acme",
340 code: {
341 pulls: [
342 pull({ number: 1 }),
343 pull({ number: 2 }),
344 pull({ number: 3, status: "open", mergedAt: null }),
345 // A person's pull request is not agent work.
346 pull({ number: 4, author: { username: "bo", kind: "user" } }),
347 // The 7 days before the span: one accepted, one fixed.
348 pull({ number: 5, mergedAt: iso(NOW - 4 * DAY), updatedAt: iso(NOW - 4 * DAY) }),
349 pull({ number: 6, mergedAt: iso(NOW - 5 * DAY), updatedAt: iso(NOW - 5 * DAY) }),
350 // Older than that: not counted.
351 pull({ number: 7, mergedAt: iso(NOW - 11 * DAY), updatedAt: iso(NOW - 11 * DAY) }),
352 ],
353 revisions: { "acme/web#2": 1, "acme/web#6": 2 },
354 complete: true,
355 },
356 sessions: { sessions: [session(), session({ id: "s2", kind: "routine", status: "working", finished_at: null }), session({ id: "s3", parent_id: "s1" })], complete: true },
357 });
358 assert.equal(work.tasks.length, 3);
359 assert.deepEqual(work.counts, { accepted: 1, fixed: 1, finished: 1, dropped: 0 });
360 assert.deepEqual(work.rate, { value: 0.5, of: 2 });
361 assert.deepEqual(work.before, { value: 0.5, of: 2 });
362 assert.deepEqual(work.sources, [
363 { source: "code", count: 2 },
364 { source: "chat", count: 1 },
365 ]);
366 assert.equal(work.code, "read");
367 assert.equal(work.partial, false);
368 assert.equal(
369 spanSentence({ words: "Since Tuesday evening" }, work, 3),
370 "Since Tuesday evening, agents finished 3 tasks and 3 changes landed. 1 needed a fix after review.",
371 );
372});
373
374test("no trend when the 7 days before could not all be read, and none without Code", () => {
375 const partial = spanWork({ span: SPAN, slug: "acme", code: { pulls: [pull()], revisions: {}, complete: false }, sessions: null });
376 assert.equal(partial.before, null);
377 assert.equal(partial.partial, true);
378 assert.equal(partial.sessions, "unavailable");
379 const member = spanWork({ span: SPAN, slug: "acme", code: "no_access", sessions: { sessions: [session()], complete: true } });
380 assert.equal(member.code, "no_access");
381 assert.equal(member.rate, null);
382 assert.equal(member.tasks.every((t) => t.source !== "code"), true);
383});
384
385test("the trend is in whole points", () => {
386 assert.equal(trendLabel({ value: 0.89 }, { value: 0.83 }), "+6 pts vs the 7 days before");
387 assert.equal(trendLabel({ value: 0.5 }, { value: 0.75 }), "−25 pts vs the 7 days before");
388 assert.equal(trendLabel({ value: 0.5 }, { value: 0.5 }), "Same as the 7 days before");
389 assert.equal(trendLabel(null, { value: 0.5 }), null);
390});
391
392test("the sentence for a quiet span, and for what needs you", () => {
393 const quiet = spanWork({ span: SPAN, slug: "acme", code: { pulls: [], revisions: {}, complete: true }, sessions: { sessions: [], complete: true } });
394 assert.equal(spanSentence({ words: "Since an hour ago" }, quiet, 0), "Since an hour ago, nothing new has settled.");
395 assert.equal(spanSentence({ words: "In the last 24 hours" }, quiet, 2), "In the last 24 hours, 2 changes landed.");
396 assert.equal(spanSentence({ words: "Since this morning" }, null, null), "Since this morning, agent work couldn't be read.");
397 assert.equal(waitingSentence(0), "Nothing needs you right now.");
398 assert.equal(waitingSentence(1), "1 thing needs you.");
399 assert.equal(waitingSentence(8), "8 things need you.");
400});
401
402test("what landed: every merge in the span, a person's or an agent's, newest first", () => {
403 const landed = landedIn(
404 [
405 pull({ number: 1, mergedAt: iso(NOW - 2 * DAY), mergedBy: "bo" }),
406 pull({ number: 2, author: { username: "bo", kind: "user" }, mergedAt: iso(NOW - HOUR) }),
407 pull({ number: 3, mergedAt: iso(NOW - 5 * DAY) }),
408 pull({ number: 4, status: "open", mergedAt: null }),
409 ],
410 SPAN,
411 );
412 assert.deepEqual(landed.map((change) => [change.number, change.agent]), [
413 [2, false],
414 [1, true],
415 ]);
416 assert.equal(landed[1]!.mergedBy, "bo");
417});
418
419const deploy = (over: Partial<Deployment>): Deployment => ({
420 id: "d1",
421 kind: "production",
422 branch: null,
423 number: null,
424 commit: "abcdef1234",
425 status: "ready",
426 url: "https://site.g1t.page",
427 error: null,
428 warnings: [],
429 buildSeconds: 40,
430 createdBy: "bo",
431 createdAt: iso(NOW - 2 * HOUR),
432 finishedAt: iso(NOW - HOUR),
433 ...over,
434});
435
436test("builds that finished in the span: live or failed, never skipped", () => {
437 const rows = deploysIn(
438 [
439 {
440 slug: "site",
441 deployments: [
442 deploy({}),
443 deploy({ id: "d2", status: "replaced", finishedAt: iso(NOW - DAY) }),
444 deploy({ id: "d3", status: "failed", finishedAt: iso(NOW - 2 * DAY) }),
445 deploy({ id: "d4", status: "skipped", finishedAt: iso(NOW - HOUR) }),
446 deploy({ id: "d5", status: "building", finishedAt: null }),
447 deploy({ id: "d6", finishedAt: iso(NOW - 5 * DAY) }),
448 ],
449 },
450 ],
451 "acme",
452 SPAN,
453 );
454 assert.deepEqual(rows.map((row) => [row.key, row.outcome]), [
455 ["deploy:site:d1", "live"],
456 ["deploy:site:d2", "live"],
457 ["deploy:site:d3", "failed"],
458 ]);
459 assert.equal(rows[0]!.to, "/acme/site/deployments/d1");
460 assert.equal(rows[0]!.commit, "abcdef1");
461});
462
463const request = (over: Partial<InstallRequest>): InstallRequest => ({
464 id: "r1",
465 listing: "integration:sentry",
466 kind: "integration",
467 name: "Sentry",
468 note: "For the error alerts",
469 requested_by: "bo",
470 requested_at: iso(NOW - 2 * DAY),
471 status: "open",
472 resolved_by: null,
473 resolved_at: null,
474 ...over,
475});
476
477const memory = (over: Partial<Memory>): Memory => ({
478 id: "m1",
479 scope: "workspace",
480 workspace: "acme",
481 repo: null,
482 text: "Use Postgres for the ledger",
483 kind: "decision",
484 source: { kind: "person" } as Memory["source"],
485 createdBy: "ada",
486 pinned: false,
487 createdAt: iso(NOW - DAY),
488 updatedAt: iso(NOW - DAY),
489 lastUsedAt: null,
490 ...over,
491});
492
493test("decisions: kept decisions in memory and requests answered, in the span", () => {
494 const rows = decisionsIn(
495 {
496 memories: [memory({}), memory({ id: "m2", kind: "fact" }), memory({ id: "m3", status: "candidate" }), memory({ id: "m4", createdAt: iso(NOW - 6 * DAY) })],
497 requests: [request({}), request({ id: "r2", status: "declined", resolved_by: "ada", resolved_at: iso(NOW - HOUR) })],
498 },
499 "acme",
500 SPAN,
501 );
502 assert.deepEqual(rows.map((row) => row.key), ["request:r2", "memory:m1"]);
503 assert.equal(rows[0]!.text, "Turned down Sentry, which bo asked for");
504});
505
506test("an open install request needs an owner; answered ones don't", () => {
507 assert.equal(installRequestRow(request({}), "acme")?.action.to, "/acme/-/marketplace/requests");
508 assert.equal(installRequestRow(request({ status: "done" }), "acme"), null);
509 const base = { slug: "acme", code: true, codeNeeds: [], capped: [], agents: [], canManage: true, notifications: [], chat: [] };
510 assert.equal(attention({ ...base, requests: [request({})] }).rows[0]?.kind, "install_request");
511 assert.equal(attention({ ...base, requests: null }).rows.length, 0);
512});
513
514test("the workspace's agent budget used up comes first, for those who may raise it", () => {
515 assert.equal(limitRow({ alert: 90, spentMicros: 1, since: NOW }, "acme"), null);
516 const limit = { alert: 100, spentMicros: 500_000_000, since: NOW - DAY };
517 assert.equal(limitRow(limit, "acme")?.action.to, "/acme/-/spend");
518 const base = { slug: "acme", code: true, codeNeeds: [need({})], capped: [], agents: [], notifications: [], chat: [], limit };
519 assert.equal(attention({ ...base, canManage: true }).start?.row.kind, "limit");
520 assert.equal(attention({ ...base, canManage: false }).rows.some((r) => r.kind === "limit"), false);
521});
522
523test("running now: live root sessions, agents' changes and builds going; a capped session is under Needs you", () => {
524 const sessions = runningSessions(
525 [
526 session({ id: "a", status: "working", finished_at: null, created_at: iso(NOW - HOUR) }),
527 session({ id: "b", status: "needs_approval", finished_at: null }),
528 session({ id: "c", status: "queued", finished_at: null, parent_id: "a" }),
529 session({ id: "d", status: "done" }),
530 session({ id: "e", status: "queued", finished_at: null, visible: false, created_at: iso(NOW - 2 * HOUR) }),
531 ],
532 "acme",
533 );
534 assert.deepEqual(sessions.map((row) => [row.key, row.status]), [
535 ["session:a", "Working"],
536 ["session:e", "Queued"],
537 ]);
538 assert.equal(sessions[1]!.title, "A session in a conversation you're not in");
539 const builds = runningDeploys(
540 [
541 { slug: "site", enabled: true, production: null, previews: 0, latest: deploy({ status: "building", finishedAt: null }) },
542 { slug: "docs", enabled: true, production: null, previews: 0, latest: deploy({}) },
543 ],
544 "acme",
545 );
546 assert.deepEqual(builds.map((row) => row.status), ["Building"]);
547 // Longest-going first within a kind.
548 assert.deepEqual(running([builds, sessions]).map((row) => row.key), ["session:e", "session:a", "deploy:site:d1"]);
549});
550
551
552test("the span's months: one, or the ones it crosses", () => {
553 assert.deepEqual(spanMonths(SPAN), ["2026-10"]);
554 assert.deepEqual(spanMonths({ from: Date.parse("2026-09-28T00:00:00Z"), now: NOW }), ["2026-09", "2026-10"]);
555 assert.deepEqual(spanMonths({ from: Date.parse("2025-12-30T00:00:00Z"), now: Date.parse("2026-01-02T00:00:00Z") }), ["2025-12", "2026-01"]);
556});
557
558test("spend in the span: the UTC days it covers across months, at price, without money in", () => {
559 const september = {
560 groups: [
561 { key: "2026-09-29", label: "", chargedMicros: 0, lines: [{ kind: "Agent runs", count: 2, chargedMicros: 1_000_000, costMicros: 0 }] },
562 { key: "2026-09-20", label: "", chargedMicros: 0, lines: [{ kind: "Agent runs", count: 9, chargedMicros: 9_000_000, costMicros: 0 }] },
563 ],
564 totals: { chargedMicros: 10_000_000, paidMicros: 0, costMicros: 0, entries: 2 },
565 };
566 const october = {
567 groups: [
568 {
569 key: "2026-10-09",
570 label: "2026-10-09",
571 chargedMicros: 0,
572 lines: [
573 { kind: "Agent runs", count: 12, chargedMicros: 3_000_000, costMicros: 2_500_000, priceMicros: 4_000_000 },
574 { kind: "Sandbox time", count: 12, chargedMicros: 600_000, costMicros: 500_000 },
575 { kind: "Payments", count: 1, chargedMicros: -50_000_000, costMicros: 0, priceMicros: 0 },
576 ],
577 },
578 ],
579 totals: { chargedMicros: 12_600_000, paidMicros: 50_000_000, costMicros: 0, entries: 4, priceMicros: 13_600_000 },
580 };
581 const spend = spendIn([september, october], { from: Date.parse("2026-09-29T15:00:00Z"), now: NOW });
582 assert.deepEqual([spend.from, spend.to], ["2026-09-29", "2026-10-09"]);
583 assert.equal(spend.totalMicros, 5_600_000);
584 assert.deepEqual(spend.lines.map((l) => [l.kind, l.micros, l.count]), [
585 ["Agent runs", 5_000_000, 14],
586 ["Sandbox time", 600_000, 12],
587 ]);
588 // The month so far is the current month's statement.
589 assert.equal(spend.monthMicros, 13_600_000);
590});