Something went wrong. Try again.
Where attention appears to go across agent threads: collector, web explorer, and native iOS client
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286import { expect, test } from "bun:test";import { calendar, shiftDay, validDay, duration } from "../shared/dates.mjs";import { estimate, summarize } from "../shared/model.mjs";import { repositoryReference, repositoryLinks, linkedItems, rankRepositories, contextFacts } from "../shared/repos.mjs";
const event = (at, thread = "a") => ({ at, thread, kind: "message" });
test("day boundaries follow each zone, including DST days", () => { for (const [zone, cases] of [ ["America/Chicago", [["2026-03-08", 23], ["2026-11-01", 25], ["2026-09-29", 24]]], ["America/Vancouver", [["2026-03-08", 23], ["2026-11-01", 24], ["2026-10-02", 24]]], ["America/Los_Angeles", [["2026-03-08", 23], ["2026-11-01", 25]]], ["Europe/London", [["2026-03-29", 23], ["2026-10-25", 25]]], ["Asia/Kolkata", [["2026-09-29", 24]]], ["UTC", [["2026-09-29", 24]]], ]) { const cal = calendar(zone, "en-US"); for (const [day, hours] of cases) { const [start, end] = cal.bounds(day); expect((end - start) / 3600).toBe(hours); expect(cal.dateKey(start)).toBe(day); expect(cal.dateKey(end - 1)).toBe(day); expect(cal.dateKey(end)).toBe(shiftDay(day, 1)); } } const chicago = calendar("America/Chicago", "en-US"); expect(chicago.bounds("2026-09-29", 7)[0]).toBe(chicago.bounds("2026-09-23")[0]); expect(validDay("2026-02-30")).toBe(false); expect(validDay("2026-09-29")).toBe(true);});
test("the same instant lands on different days in different zones", () => { const at = Date.parse("2026-10-02T05:30:00Z") / 1000; expect(calendar("America/Chicago", "en-US").dateKey(at)).toBe("2026-10-02"); expect(calendar("America/Vancouver", "en-US").dateKey(at)).toBe("2026-10-01"); expect(calendar("America/Vancouver", "en-US").time(at)).toBe("10:30 PM");});
test("day labels do not depend on the device zone", () => { const cal = calendar("Pacific/Kiritimati", "en-US"); expect(cal.longDate("2026-09-29")).toBe("September 29"); expect(cal.weekdayShort("2026-09-29")).toBe("Tue"); expect(cal.title("2026-09-29")).toBe("Tuesday, Sep 29"); expect(cal.dayNumber("2026-09-09")).toBe(9);});
test("durations are compact", () => { expect(duration(42)).toBe("42s"); expect(duration(600)).toBe("10m"); expect(duration(3 * 3600 + 5 * 60)).toBe("3h 5m");});
test("isolated signals, long gaps and thread switches add no duration", () => { const result = estimate([event(0), event(60), event(90, "b"), event(120), event(1000)], 300); expect(result.spans).toEqual([{ thread: "a", start: 0, end: 60 }]); expect(result.switches.length).toBe(2); expect(estimate([event(1)], 300).spans.length).toBe(0);});
test("global inference prevents filters bridging over another thread", () => { const global = estimate([event(0), event(10, "b"), event(20)], 300); expect(global.spans.filter((s) => s.thread === "a").length).toBe(0);});
test("threshold changes estimates without inventing signal counts", () => { const events = [event(0), event(180), event(800)]; expect(estimate(events, 60).spans.length).toBe(0); expect(estimate(events, 300).spans.length).toBe(1); expect(estimate(events, 900).spans.length).toBe(2);});
test("worktrees share repository group and duration is never double counted", () => { const events = [event(0), event(20), event(30, "b"), event(50, "b")]; const threads = { a: { title: "one", project: "checkout", project_key: "p1", repo: "host.dev/org/repo", provider: "Codex" }, b: { title: "two", project: "worktree", project_key: "p2", repo: "host.dev/org/repo", provider: "Codex" }, }; const groups = summarize(events, estimate(events, 300).spans, threads, "project"); expect(groups.length).toBe(1); expect(groups[0].count).toBe(4); expect(groups[0].seconds).toBe(40); expect(groups[0].threads.size).toBe(2);});
test("remote breadcrumbs only link recorded safe repository addresses", () => { expect(repositoryReference("tangled.org/zzstoatzz.io/pub-search")).toEqual({ href: "https://tangled.org/zzstoatzz.io/pub-search", label: "zzstoatzz.io/pub-search", host: "tangled.org", }); expect(repositoryReference("github.com/org/repo").href).toBe("https://github.com/org/repo"); expect(repositoryReference("tangled.org/did:plc:abc", "bot").label).toBe("bot"); for (const repo of ["", "local-folder", "[redacted]", "javascript:alert(1)", "name:password@example.com/repo", "example.com/repo?token=secret", "//example.com/repo"]) expect(repositoryReference(repo)).toBe(null);});
test("repository rails dedupe, rank named repos first, and link github items", () => { const contexts = [ { repo: "github.com/org/alpha", project: "alpha" }, { repo: "github.com/org/beta", project: "beta" }, { repo: "github.com/org/alpha", project: "alpha" }, { repo: "not a repo", project: "x" }, ]; expect(repositoryLinks(contexts).map((l) => l.label)).toEqual(["org/alpha", "org/beta"]); expect(rankRepositories("Beta release notes", contexts).map((c) => c.repo)[0]).toBe("github.com/org/beta"); expect(linkedItems({ repo: "github.com/org/alpha", linked_pr: 12, linked_issue: 3 })).toEqual([ { label: "PR #12 ↗", href: "https://github.com/org/alpha/pull/12" }, { label: "Issue #3 ↗", href: "https://github.com/org/alpha/issues/3" }, ]); expect(linkedItems({ repo: "tangled.org/org/alpha", linked_pr: 12 })).toEqual([]); expect(contextFacts({ host: "mac", workspace_status: "in-review", worktree: "wt", branch: "b" })).toEqual([ "Workspace in review", "Worktree: wt", "Branch: b", ]);});
test("did-addressed repositories group under their project name", () => { const threads = { a: { title: "t", project: "bot", project_key: "k", repo: "tangled.org/did:plc:abc", provider: "Codex" } }; expect(summarize([event(0)], [], threads, "project")[0].label).toBe("bot");});
import { inline } from "../shared/text.mjs";import { cleanTitle } from "../shared/sessions.mjs";
test("transcript text links, code and bold become tokens; other schemes stay text", () => { expect(inline("Live in [Atlas](https://pub-search.waow.tech/atlas). Run `bun test` **now**.")).toEqual([ { kind: "text", text: "Live in " }, { kind: "link", text: "Atlas", href: "https://pub-search.waow.tech/atlas" }, { kind: "text", text: ". Run " }, { kind: "code", text: "bun test" }, { kind: "text", text: " " }, { kind: "bold", text: "now" }, { kind: "text", text: "." }, ]); expect(inline("see https://example.com/a?b=1.")).toEqual([ { kind: "text", text: "see " }, { kind: "link", text: "example.com/a?b=1", href: "https://example.com/a?b=1" }, { kind: "text", text: "." }, ]); expect(inline("[x](javascript:alert(1))")).toEqual([{ kind: "text", text: "[x](javascript:alert(1))" }]);});
test("titles drop harness markup but keep real angle-bracket text", () => { expect(cleanTitle("<local-command-caveat>The command below was run")).toBe("The command below was run"); expect(cleanTitle("compare a < b and b > c")).toBe("compare a < b and b > c");});
test("the default Orca status is quiet; moved statuses and archives show", () => { expect(contextFacts({ host: "Orca", workspace_status: "in-progress" })).toEqual([]); expect(contextFacts({ host: "Orca", workspace_status: "in-review" })).toEqual(["Workspace in review"]); expect(contextFacts({ host: "Orca", workspace_status: "in-progress", worktree_archived: true })).toEqual(["Archived workspace"]);});
import { find, highlight, snippet } from "../shared/find.mjs";
test("find ranks exact, prefix and all-word title matches above field matches, with reasons", () => { const entries = [ { key: "a", title: "Deploy notes", fields: [{ label: "Branch", text: "main" }] }, { key: "b", title: "Notes site", fields: [] }, { key: "c", title: "Fix the thing", fields: [{ label: "Branch", text: "notes-deploy-fix" }] }, { key: "d", title: "notes", fields: [] }, { key: "e", title: "Unrelated", fields: [{ label: "Summary", text: "nothing here" }] }, ]; const results = find(entries, "notes"); expect(results.map((r) => r.entry.key)).toEqual(["d", "b", "a", "c"]); expect(results[3].reason?.label).toBe("Branch"); expect(results[3].reason?.parts.find((p) => p.hit)?.text).toBe("notes"); expect(results[0].reason).toBe(null); expect(find(entries, "deploy fix").map((r) => r.entry.key)).toEqual(["c"]); expect(find(entries, "").length).toBe(5);});
test("highlights are case-insensitive and snippets center on the match", () => { expect(highlight("Deploy Notes now", ["notes"])).toEqual([ { text: "Deploy ", hit: false }, { text: "Notes", hit: true }, { text: " now", hit: false }, ]); const long = "a ".repeat(80) + "the needle is here " + "b ".repeat(80); const parts = snippet(long, ["needle"]); const joined = parts.map((p) => p.text).join(""); expect(joined.startsWith("…") && joined.endsWith("…")).toBe(true); expect(parts.some((p) => p.hit && p.text === "needle")).toBe(true); expect(joined.length).toBeLessThanOrEqual(76);});
test("a title match hidden by truncation gets its own reason line", () => { const long = { key: "l", title: "I wrote HANDOFF.md at the root of my-prefect-server and pushed it, then checked heavypad", fields: [] }; const [result] = find([long], "heavypad"); expect(result.reason?.label).toBe("Title"); expect(result.reason?.parts.some((p) => p.hit && p.text.toLowerCase() === "heavypad")).toBe(true); const [short] = find([{ key: "s", title: "Check HeavyPad RTX VRAM", fields: [] }], "heavypad"); expect(short.reason).toBe(null);});
import { activeFilterCount, defaultFilters, filterSessions } from "../shared/sessions.mjs";
test("subagents are hidden by default and count as a filter when included", () => { const base = { id: "x", provider: "Claude", title: "t", display_title: "", project: "p", cwd: "", model: "", branch: "", repo: "", repo_source: "", host: "", worktree: "", workspace_status: "", archived: false, updated: 1, status: "quiet", repositories: [] }; const sessions = [{ ...base, id: "a", subagent: false }, { ...base, id: "b", subagent: true }]; const opts = { query: "", provider: "All", filters: defaultFilters }; expect(filterSessions(sessions, opts, 2).map((s) => s.id)).toEqual(["a"]); expect(activeFilterCount(defaultFilters)).toBe(0); const withSub = { ...defaultFilters, subagents: true }; expect(filterSessions(sessions, { ...opts, filters: withSub }, 2).map((s) => s.id)).toEqual(["a", "b"]); expect(activeFilterCount(withSub)).toBe(1);});
import { computeTimeline, estimator } from "../shared/timeline.mjs";
test("today's track reaches the present and marks now; past days do not", () => { const cal = calendar("UTC", "en-US"); const day = "2026-09-30"; const nine = Date.parse(`${day}T09:10:00Z`) / 1000; const data = { at: nine, since: 0, coverage: "", errors: [], threads: { a: { title: "A", project: "p", project_key: "k", repo: "", provider: "Codex" } }, events: [{ thread: "a", at: nine, kind: "message" }] }; const state = { day, period: 1, project: "", search: "", threadFilter: null, gap: 5, group: "project" }; const later = Date.parse(`${day}T14:30:00Z`) / 1000; const today = computeTimeline(data, state, cal, estimator(), later).track; expect(today.now).toBe(later); expect(today.high).toBe(Date.parse(`${day}T15:00:00Z`) / 1000); const past = computeTimeline(data, state, cal, estimator(), later + 86400).track; expect(past.now).toBe(null); expect(past.high).toBe(Date.parse(`${day}T10:00:00Z`) / 1000);});
import { blocks } from "../shared/markdown.mjs";import { turns } from "../shared/sessions.mjs";
test("markdown blocks: tables, lists, headings, code, and paragraphs", () => { const text = "**Argon is cheaper.** Comparison:\n\n| Benchmark | Argon | Astra |\n|---|---:|---:|\n| DeepSWE | **77.9%** | 74.1% |\n| Other | 1 | 2 |\n\n## Prices\n- one\n- two\n1. first\n\n```\ncode here\n```\ntrailing words"; expect(blocks(text).map((b) => b.kind)).toEqual(["paragraph", "table", "heading", "list", "list", "code", "paragraph"]); const table = blocks(text)[1]; expect(table.kind === "table" && table.header).toEqual(["Benchmark", "Argon", "Astra"]); expect(table.kind === "table" && table.align).toEqual(["left", "right", "right"]); expect(table.kind === "table" && table.rows.length).toBe(2); expect(blocks("a | b is not a table")).toEqual([{ kind: "paragraph", text: "a | b is not a table" }]);});
test("turns group a voice session into readable cards, newest first", () => { const events = [ { at: 1, label: "Turn started", text: "" }, { at: 2, label: "You", text: "How do those benchmarks", voice: true }, { at: 3, label: "You", text: "compare to Astra?", voice: true }, { at: 4, label: "Assistant", text: "I'll check." }, { at: 5, label: "Tool", text: "exec" }, { at: 6, label: "Tool", text: "exec" }, { at: 7, label: "Assistant", text: "Argon is cheaper.", cut: true }, { at: 8, label: "Turn ended", text: "" }, { at: 9, label: "You", text: "<task-notification> done" }, { at: 10, label: "You", text: "what about Fable?" }, { at: 11, label: "Assistant", text: "Fable costs more." }, ]; const result = turns(events); expect(result.length).toBe(2); expect(result[1].items.map((i) => i.kind)).toEqual(["you", "reply", "tools", "reply"]); expect(result[1].items[0]).toEqual({ kind: "you", text: "How do those benchmarks compare to Astra?", voice: true }); expect(result[1].tools).toBe(2); expect(result[1].items[3]).toEqual({ kind: "reply", text: "Argon is cheaper.", cut: true }); expect(result[0].items.map((i) => i.kind)).toEqual(["note", "you", "reply"]); expect([result[1].start, result[1].end]).toEqual([1, 8]);});
test("claude-style sessions without turn markers split on your words after a reply", () => { const result = turns([ { at: 1, label: "You", text: "one" }, { at: 2, label: "Assistant", text: "a" }, { at: 3, label: "You", text: "two" }, { at: 4, label: "Tool", text: "Bash" }, { at: 5, label: "Assistant", text: "b" }, ]); expect(result.map((t) => t.items[0].kind === "you" && t.items[0].text)).toEqual(["two", "one"]);});
test("spoken words before a turn-started marker stay in that turn", () => { const result = turns([ { at: 1, label: "Assistant", text: "earlier" }, { at: 2, label: "Turn ended", text: "" }, { at: 3, label: "You", text: "what is the price", voice: true }, { at: 4, label: "Turn started", text: "" }, { at: 5, label: "Assistant", text: "answered" }, ]); expect(result.length).toBe(2); expect(result[0].items.map((i) => i.kind)).toEqual(["you", "reply"]);});