diff --git a/docs/diag/a.mdx b/docs/diag/a.mdx
new file mode 100644
index 00000000..bbf89d16
--- /dev/null
+++ b/docs/diag/a.mdx
@@ -0,0 +1,159 @@
+---
+title: "diag a"
+mode: "custom"
+---
+
+{/* Mirrors CLIAgent::accent_rgb / icon_path: a solid brand disc with the
+ agent's own mark masked in white on top, as tab_strip.rs avatar_disc draws it. */}
+export const AGENTS = {
+ claude: { name: "Claude Code", c: "#D97757" },
+ codex: { name: "Codex", c: "#000000", edge: true },
+ gemini: { name: "Gemini", c: "#4285F4" },
+ cursor: { name: "Cursor", c: "#9AA0A6" },
+ opencode: { name: "OpenCode", c: "#6E56CF" },
+ copilot: { name: "Copilot", c: "#8957E5" },
+};
+
+export const GROUPS = [
+ { name: "atlas-api", meta: "main", items: [
+ { a: "claude", t: "Spin up a staging instance", s: "working" },
+ { a: "codex", t: "Inspect CLI error logs", s: "working" },
+ ] },
+ { name: "northwind", meta: "", items: [
+ { a: "cursor", t: "Refactor session auth", b: "feat/session-auth", s: "waiting" },
+ { a: "gemini", t: "Fix pricing fetch timeout", b: "fix/pricing-fetch-timeout", s: "working" },
+ ] },
+ { name: "orbit", meta: "main · +104 −12", items: [
+ { shell: true, t: "~/code/orbit", on: true },
+ { a: "claude", t: "Optimize route planner" },
+ ] },
+ { name: "lumen-web", meta: "main · +259 −191", items: [
+ { a: "copilot", t: "Backtest search ranking" },
+ ] },
+];
+
+export const Glyph = ({ a, shell }) => shell
+ ? {">_"}
+ :
+
+ ;
+
+export const Row = ({ it }) => (
+
+
+
+ {it.t}
+ {it.b ? {it.b} : null}
+
+ {it.s ?
: null}
+
+);
+
+export const Group = ({ g }) => (
+
+
{g.name} {g.meta}
+ {g.items.map((it) =>
|
)}
+
+);
+
+export const Search = () => (
+
+
+
+
+);
+
+export const Check = () => (
+
+);
+
+export const Cross = () => (
+
+);
+
+export const State = ({ s }) => (
+ {s === "ok" ? : s === "fail" ? : }
+);
+
+export const CHECKS = [["lint", "ok", "18s"], ["typecheck", "ok", "41s"], ["test (py3.12)", "run", "2m"], ["build image", "ok", "1m 12s"]];
+export const PRS = [
+ ["Add export endpoints", "#214 · Merged 1d ago", "ok"],
+ ["Refactor session auth", "#228 · feat/session-auth · Draft", "run"],
+ ["Fix pricing fetch timeout", "#229 · 1 check failing", "fail"],
+];
+
+export const Inspector = () => (
+
+ Info Files Changes PR
+
+
+
#231 · Open 12m ago
+
Handle empty daily summaries
+
fix/report-daily-summary → main
+
Squash and merge Waiting on 1 check
+
+
+
Checks 3 of 4 passed
+ {CHECKS.map(([n, s, t]) => (
+
{n} {t}
+ ))}
+
+
+
Reviews
+
M mara Approved
+
J jonas Requested
+
+
+
Pull requests
+ {PRS.map(([t, m, s]) => (
+
+ ))}
+
+
+
+);
+
+{/* The hero demo. Five chapters after the promo storyboard
+ (videos/tty7-promo/STORYBOARD.md), each a pure function of the seconds t
+ since it began, so any frame can be drawn directly and a click can jump
+ to any chapter. */}
+
+export const CHAPTERS = [
+ { key: "agents", label: "Every agent", d: 7.5 },
+ { key: "cli", label: "Agents drive it", d: 9.5 },
+ { key: "prompt", label: "Editor prompt", d: 7.5 },
+ { key: "search", label: "⌘P everything", d: 8 },
+ { key: "persist", label: "Quit, keep running", d: 7.5 },
+];
+
+export const typed = (s, t, t0, cps = 22) => (t < t0 ? "" : s.slice(0, Math.floor((t - t0) * cps)));
+export const typingDone = (s, t, t0, cps = 22) => t >= t0 + s.length / cps;
+export const hl = (s, q) => {
+ const i = q ? s.toLowerCase().indexOf(q) : -1;
+ return i < 0 ? s : <>{s.slice(0, i)}{s.slice(i, i + q.length)} {s.slice(i + q.length)}>;
+};
+
+export const P = ({ br = "main", caret, children }) => (
+
+ → orbit {br} ●
+ {children}{caret ? : null}
+
+);
+
+export const O = ({ c = "", children }) => {children}
;
+
+{/* Sidebar for a frame: the base groups plus whatever the chapter changed. */}
+export const sidebar = (ch, t) => {
+ const g = GROUPS.map((x) => ({ ...x, items: x.items.map((it) => ({ ...it })) }));
+ const find = (title) => g.flatMap((x) => x.items).find((it) => it.t === title);
+ if (ch === 0) find("Refactor session auth").s = t < 3.1 ? "working" : "waiting";
+ if (ch === 1 && t >= 3.2) find("~/code/orbit").s = t < 6.4 ? "working" : "done";
+ if ((ch === 3 && t >= 4.1) || ch === 4) {
+ find("~/code/orbit").on = false;
+ g[0].items.unshift({ a: "claude", t: "Handle empty daily summaries", s: ch === 4 && t >= 5.2 ? "done" : "working", on: true });
+ }
+ return g;
+};
+
+
+ok-a
diff --git a/docs/diag/b.mdx b/docs/diag/b.mdx
new file mode 100644
index 00000000..7277d204
--- /dev/null
+++ b/docs/diag/b.mdx
@@ -0,0 +1,160 @@
+---
+title: "diag b"
+mode: "custom"
+---
+
+{/* Mirrors CLIAgent::accent_rgb / icon_path: a solid brand disc with the
+ agent's own mark masked in white on top, as tab_strip.rs avatar_disc draws it. */}
+export const AGENTS = {
+ claude: { name: "Claude Code", c: "#D97757" },
+ codex: { name: "Codex", c: "#000000", edge: true },
+ gemini: { name: "Gemini", c: "#4285F4" },
+ cursor: { name: "Cursor", c: "#9AA0A6" },
+ opencode: { name: "OpenCode", c: "#6E56CF" },
+ copilot: { name: "Copilot", c: "#8957E5" },
+};
+
+export const GROUPS = [
+ { name: "atlas-api", meta: "main", items: [
+ { a: "claude", t: "Spin up a staging instance", s: "working" },
+ { a: "codex", t: "Inspect CLI error logs", s: "working" },
+ ] },
+ { name: "northwind", meta: "", items: [
+ { a: "cursor", t: "Refactor session auth", b: "feat/session-auth", s: "waiting" },
+ { a: "gemini", t: "Fix pricing fetch timeout", b: "fix/pricing-fetch-timeout", s: "working" },
+ ] },
+ { name: "orbit", meta: "main · +104 −12", items: [
+ { shell: true, t: "~/code/orbit", on: true },
+ { a: "claude", t: "Optimize route planner" },
+ ] },
+ { name: "lumen-web", meta: "main · +259 −191", items: [
+ { a: "copilot", t: "Backtest search ranking" },
+ ] },
+];
+
+export const Glyph = ({ a, shell }) => shell
+ ? {">_"}
+ :
+
+ ;
+
+export const Row = ({ it }) => (
+
+
+
+ {it.t}
+ {it.b ? {it.b} : null}
+
+ {it.s ?
: null}
+
+);
+
+export const Group = ({ g }) => (
+
+
{g.name} {g.meta}
+ {g.items.map((it) =>
|
)}
+
+);
+
+export const Search = () => (
+
+
+
+
+);
+
+export const Check = () => (
+
+);
+
+export const Cross = () => (
+
+);
+
+export const State = ({ s }) => (
+ {s === "ok" ? : s === "fail" ? : }
+);
+
+export const CHECKS = [["lint", "ok", "18s"], ["typecheck", "ok", "41s"], ["test (py3.12)", "run", "2m"], ["build image", "ok", "1m 12s"]];
+export const PRS = [
+ ["Add export endpoints", "#214 · Merged 1d ago", "ok"],
+ ["Refactor session auth", "#228 · feat/session-auth · Draft", "run"],
+ ["Fix pricing fetch timeout", "#229 · 1 check failing", "fail"],
+];
+
+export const Inspector = () => (
+
+ Info Files Changes PR
+
+
+
#231 · Open 12m ago
+
Handle empty daily summaries
+
fix/report-daily-summary → main
+
Squash and merge Waiting on 1 check
+
+
+
Checks 3 of 4 passed
+ {CHECKS.map(([n, s, t]) => (
+
{n} {t}
+ ))}
+
+
+
Reviews
+
M mara Approved
+
J jonas Requested
+
+
+
Pull requests
+ {PRS.map(([t, m, s]) => (
+
+ ))}
+
+
+
+);
+
+{/* The hero demo. Five chapters after the promo storyboard
+ (videos/tty7-promo/STORYBOARD.md), each a pure function of the seconds t
+ since it began, so any frame can be drawn directly and a click can jump
+ to any chapter. */}
+
+export const CHAPTERS = [
+ { key: "agents", label: "Every agent", d: 7.5 },
+ { key: "cli", label: "Agents drive it", d: 9.5 },
+ { key: "prompt", label: "Editor prompt", d: 7.5 },
+ { key: "search", label: "⌘P everything", d: 8 },
+ { key: "persist", label: "Quit, keep running", d: 7.5 },
+];
+
+export const typed = (s, t, t0, cps = 22) => (t < t0 ? "" : s.slice(0, Math.floor((t - t0) * cps)));
+export const typingDone = (s, t, t0, cps = 22) => t >= t0 + s.length / cps;
+export const hl = (s, q) => {
+ const i = q ? s.toLowerCase().indexOf(q) : -1;
+ return i < 0 ? s : <>{s.slice(0, i)}{s.slice(i, i + q.length)} {s.slice(i + q.length)}>;
+};
+
+export const P = ({ br = "main", caret, children }) => (
+
+ → orbit {br} ●
+ {children}{caret ? : null}
+
+);
+
+export const O = ({ c = "", children }) => {children}
;
+
+{/* Sidebar for a frame: the base groups plus whatever the chapter changed. */}
+export const sidebar = (ch, t) => {
+ const g = GROUPS.map((x) => ({ ...x, items: x.items.map((it) => ({ ...it })) }));
+ const find = (title) => g.flatMap((x) => x.items).find((it) => it.t === title);
+ if (ch === 0) find("Refactor session auth").s = t < 3.1 ? "working" : "waiting";
+ // A split stays in the same tab; the tab picks up the agent's status.
+ if (ch === 1 && t >= 3.2) find("~/code/orbit").s = t < 6.4 ? "working" : "done";
+ if ((ch === 3 && t >= 4.1) || ch === 4) {
+ find("~/code/orbit").on = false;
+ g[0].items.unshift({ a: "claude", t: "Handle empty daily summaries", s: ch === 4 && t >= 5.2 ? "done" : "working", on: true });
+ }
+ return g;
+};
+
+
+ok-b
diff --git a/docs/diag/c.mdx b/docs/diag/c.mdx
new file mode 100644
index 00000000..409a1803
--- /dev/null
+++ b/docs/diag/c.mdx
@@ -0,0 +1,160 @@
+---
+title: "diag c"
+mode: "custom"
+---
+
+{/* Mirrors CLIAgent::accent_rgb / icon_path: a solid brand disc with the
+ agent's own mark masked in white on top, as tab_strip.rs avatar_disc draws it. */}
+export const AGENTS = {
+ claude: { name: "Claude Code", c: "#D97757" },
+ codex: { name: "Codex", c: "#000000", edge: true },
+ gemini: { name: "Gemini", c: "#4285F4" },
+ cursor: { name: "Cursor", c: "#9AA0A6" },
+ opencode: { name: "OpenCode", c: "#6E56CF" },
+ copilot: { name: "Copilot", c: "#8957E5" },
+};
+
+export const GROUPS = [
+ { name: "atlas-api", meta: "main", items: [
+ { a: "claude", t: "Spin up a staging instance", s: "working" },
+ { a: "codex", t: "Inspect CLI error logs", s: "working" },
+ ] },
+ { name: "northwind", meta: "", items: [
+ { a: "cursor", t: "Refactor session auth", b: "feat/session-auth", s: "waiting" },
+ { a: "gemini", t: "Fix pricing fetch timeout", b: "fix/pricing-fetch-timeout", s: "working" },
+ ] },
+ { name: "orbit", meta: "main · +104 −12", items: [
+ { shell: true, t: "~/code/orbit", on: true },
+ { a: "claude", t: "Optimize route planner" },
+ ] },
+ { name: "lumen-web", meta: "main · +259 −191", items: [
+ { a: "copilot", t: "Backtest search ranking" },
+ ] },
+];
+
+export const Glyph = ({ a, shell }) => shell
+ ? {">_"}
+ :
+
+ ;
+
+export const Row = ({ it }) => (
+
+
+
+ {it.t}
+ {it.b ? {it.b} : null}
+
+ {it.s ?
: null}
+
+);
+
+export const Group = ({ g }) => (
+
+
{g.name} {g.meta}
+ {g.items.map((it) =>
|
)}
+
+);
+
+export const Search = () => (
+
+
+
+
+);
+
+export const Check = () => (
+
+);
+
+export const Cross = () => (
+
+);
+
+export const State = ({ s }) => (
+ {s === "ok" ? : s === "fail" ? : }
+);
+
+export const CHECKS = [["lint", "ok", "18s"], ["typecheck", "ok", "41s"], ["test (py3.12)", "run", "2m"], ["build image", "ok", "1m 12s"]];
+export const PRS = [
+ ["Add export endpoints", "#214 · Merged 1d ago", "ok"],
+ ["Refactor session auth", "#228 · feat/session-auth · Draft", "run"],
+ ["Fix pricing fetch timeout", "#229 · 1 check failing", "fail"],
+];
+
+export const Inspector = () => (
+
+ Info Files Changes PR
+
+
+
#231 · Open 12m ago
+
Handle empty daily summaries
+
fix/report-daily-summary → main
+
Squash and merge Waiting on 1 check
+
+
+
Checks 3 of 4 passed
+ {CHECKS.map(([n, s, t]) => (
+
{n} {t}
+ ))}
+
+
+
Reviews
+
M mara Approved
+
J jonas Requested
+
+
+
Pull requests
+ {PRS.map(([t, m, s]) => (
+
+ ))}
+
+
+
+);
+
+{/* The hero demo. Five chapters after the promo storyboard
+ (videos/tty7-promo/STORYBOARD.md), each a pure function of the seconds t
+ since it began, so any frame can be drawn directly and a click can jump
+ to any chapter. */}
+
+export const CHAPTERS = [
+ { key: "agents", label: "Every agent", d: 7.5 },
+ { key: "cli", label: "Agents drive it", d: 9.5 },
+ { key: "prompt", label: "Editor prompt", d: 7.5 },
+ { key: "search", label: "⌘P everything", d: 8 },
+ { key: "persist", label: "Quit, keep running", d: 7.5 },
+];
+
+export const typed = (s, t, t0, cps = 22) => (t < t0 ? "" : s.slice(0, Math.floor((t - t0) * cps)));
+export const typingDone = (s, t, t0, cps = 22) => t >= t0 + s.length / cps;
+export const hl = (s, q) => {
+ const i = q ? s.toLowerCase().indexOf(q) : -1;
+ return i < 0 ? s : <>{s.slice(0, i)}{s.slice(i, i + q.length)} {s.slice(i + q.length)}>;
+};
+
+export const P = ({ br = "main", caret, children }) => (
+
+ → orbit {br} ●
+ {children}{caret ? : null}
+
+);
+
+export const O = ({ c = "", children }) => {children}
;
+
+{/* Sidebar for a frame: the base groups plus whatever the chapter changed. */}
+export const sidebar = (ch, t) => {
+ const g = GROUPS.map((x) => ({ ...x, items: x.items.map((it) => ({ ...it })) }));
+ const find = (title) => g.flatMap((x) => x.items).find((it) => it.t === title);
+ if (ch === 0) find("Refactor session auth").s = t < 3.1 ? "working" : "waiting";
+ // A split stays in the same tab; the tab picks up the agent status.
+ if (ch === 1 && t >= 3.2) find("~/code/orbit").s = t < 6.4 ? "working" : "done";
+ if ((ch === 3 && t >= 4.1) || ch === 4) {
+ find("~/code/orbit").on = false;
+ g[0].items.unshift({ a: "claude", t: "Handle empty daily summaries", s: ch === 4 && t >= 5.2 ? "done" : "working", on: true });
+ }
+ return g;
+};
+
+
+ok-c
diff --git a/docs/diag/d.mdx b/docs/diag/d.mdx
new file mode 100644
index 00000000..5bb4ae2b
--- /dev/null
+++ b/docs/diag/d.mdx
@@ -0,0 +1,181 @@
+---
+title: "diag d"
+mode: "custom"
+---
+
+{/* Mirrors CLIAgent::accent_rgb / icon_path: a solid brand disc with the
+ agent's own mark masked in white on top, as tab_strip.rs avatar_disc draws it. */}
+export const AGENTS = {
+ claude: { name: "Claude Code", c: "#D97757" },
+ codex: { name: "Codex", c: "#000000", edge: true },
+ gemini: { name: "Gemini", c: "#4285F4" },
+ cursor: { name: "Cursor", c: "#9AA0A6" },
+ opencode: { name: "OpenCode", c: "#6E56CF" },
+ copilot: { name: "Copilot", c: "#8957E5" },
+};
+
+export const GROUPS = [
+ { name: "atlas-api", meta: "main", items: [
+ { a: "claude", t: "Spin up a staging instance", s: "working" },
+ { a: "codex", t: "Inspect CLI error logs", s: "working" },
+ ] },
+ { name: "northwind", meta: "", items: [
+ { a: "cursor", t: "Refactor session auth", b: "feat/session-auth", s: "waiting" },
+ { a: "gemini", t: "Fix pricing fetch timeout", b: "fix/pricing-fetch-timeout", s: "working" },
+ ] },
+ { name: "orbit", meta: "main · +104 −12", items: [
+ { shell: true, t: "~/code/orbit", on: true },
+ { a: "claude", t: "Optimize route planner" },
+ ] },
+ { name: "lumen-web", meta: "main · +259 −191", items: [
+ { a: "copilot", t: "Backtest search ranking" },
+ ] },
+];
+
+export const Glyph = ({ a, shell }) => shell
+ ? {">_"}
+ :
+
+ ;
+
+export const Row = ({ it }) => (
+
+
+
+ {it.t}
+ {it.b ? {it.b} : null}
+
+ {it.s ?
: null}
+
+);
+
+export const Group = ({ g }) => (
+
+
{g.name} {g.meta}
+ {g.items.map((it) =>
|
)}
+
+);
+
+export const Search = () => (
+
+
+
+
+);
+
+export const Check = () => (
+
+);
+
+export const Cross = () => (
+
+);
+
+export const State = ({ s }) => (
+ {s === "ok" ? : s === "fail" ? : }
+);
+
+export const CHECKS = [["lint", "ok", "18s"], ["typecheck", "ok", "41s"], ["test (py3.12)", "run", "2m"], ["build image", "ok", "1m 12s"]];
+export const PRS = [
+ ["Add export endpoints", "#214 · Merged 1d ago", "ok"],
+ ["Refactor session auth", "#228 · feat/session-auth · Draft", "run"],
+ ["Fix pricing fetch timeout", "#229 · 1 check failing", "fail"],
+];
+
+export const Inspector = () => (
+
+ Info Files Changes PR
+
+
+
#231 · Open 12m ago
+
Handle empty daily summaries
+
fix/report-daily-summary → main
+
Squash and merge Waiting on 1 check
+
+
+
Checks 3 of 4 passed
+ {CHECKS.map(([n, s, t]) => (
+
{n} {t}
+ ))}
+
+
+
Reviews
+
M mara Approved
+
J jonas Requested
+
+
+
Pull requests
+ {PRS.map(([t, m, s]) => (
+
+ ))}
+
+
+
+);
+
+{/* The hero demo. Five chapters after the promo storyboard
+ (videos/tty7-promo/STORYBOARD.md), each a pure function of the seconds t
+ since it began, so any frame can be drawn directly and a click can jump
+ to any chapter. */}
+
+export const CHAPTERS = [
+ { key: "agents", label: "Every agent", d: 7.5 },
+ { key: "cli", label: "Agents drive it", d: 9.5 },
+ { key: "prompt", label: "Editor prompt", d: 7.5 },
+ { key: "search", label: "⌘P everything", d: 8 },
+ { key: "persist", label: "Quit, keep running", d: 7.5 },
+];
+
+export const typed = (s, t, t0, cps = 22) => (t < t0 ? "" : s.slice(0, Math.floor((t - t0) * cps)));
+export const typingDone = (s, t, t0, cps = 22) => t >= t0 + s.length / cps;
+export const hl = (s, q) => {
+ const i = q ? s.toLowerCase().indexOf(q) : -1;
+ return i < 0 ? s : <>{s.slice(0, i)}{s.slice(i, i + q.length)} {s.slice(i + q.length)}>;
+};
+
+export const P = ({ br = "main", caret, children }) => (
+
+ → orbit {br} ●
+ {children}{caret ? : null}
+
+);
+
+export const O = ({ c = "", children }) => {children}
;
+
+
+export const AgentsTable = ({ cursor }) => (
+ <>
+ {"PANE AGENT STATUS MESSAGE"}
+ {AGENT_ROWS.map(([p, a, s, m]) => {
+ const st = a === "cursor" ? cursor : s;
+ return {p.padEnd(6)}{a.padEnd(9)}{st.padEnd(9)} {m} ;
+ })}
+ >
+);
+
+{/* Pane ids spell their "%" as \u0025: the hosted Mintlify build percent-decodes
+ the page before parsing it, so a literal "%22" turned into a quote and broke the page. */}
+export const AGENT_ROWS = [
+ ["\u002512", "claude", "working", "Spin up a staging instance"],
+ ["\u002514", "codex", "working", "Inspect CLI error logs"],
+ ["\u002521", "cursor", "working", "Refactor session auth"],
+ ["\u002522", "gemini", "working", "Fix pricing fetch timeout"],
+ ["\u002531", "claude", "done", "Optimize route planner"],
+];
+
+export const TermAgents = ({ t }) => {
+ const c1 = "tty7 agents", c2 = "tty7 wait \u002521 --until waiting";
+ return (
+
+
{typed(c1, t, 0.4, 18)}
+ {t >= 1.3 ?
: null}
+ {t >= 1.5 ?
{typed(c2, t, 1.7, 26)}
: null}
+ {t >= 3.1 ?
{"\u002521 "}waiting : null}
+ {t >= 3.1 ?
: null}
+
+ );
+};
+
+
+
+ok-d
diff --git a/docs/diag/e.mdx b/docs/diag/e.mdx
new file mode 100644
index 00000000..0e03ba09
--- /dev/null
+++ b/docs/diag/e.mdx
@@ -0,0 +1,595 @@
+---
+title: "diag e"
+description: "A terminal workbench: persistent sessions, remote work, agents."
+mode: "custom"
+---
+
+{/* Mirrors CLIAgent::accent_rgb / icon_path: a solid brand disc with the
+ agent own mark masked in white on top, as tab_strip.rs avatar_disc draws it. */}
+export const AGENTS = {
+ claude: { name: "Claude Code", c: "#D97757" },
+ codex: { name: "Codex", c: "#000000", edge: true },
+ gemini: { name: "Gemini", c: "#4285F4" },
+ cursor: { name: "Cursor", c: "#9AA0A6" },
+ opencode: { name: "OpenCode", c: "#6E56CF" },
+ copilot: { name: "Copilot", c: "#8957E5" },
+};
+
+export const GROUPS = [
+ { name: "atlas-api", meta: "main", items: [
+ { a: "claude", t: "Spin up a staging instance", s: "working" },
+ { a: "codex", t: "Inspect CLI error logs", s: "working" },
+ ] },
+ { name: "northwind", meta: "", items: [
+ { a: "cursor", t: "Refactor session auth", b: "feat/session-auth", s: "waiting" },
+ { a: "gemini", t: "Fix pricing fetch timeout", b: "fix/pricing-fetch-timeout", s: "working" },
+ ] },
+ { name: "orbit", meta: "main · +104 −12", items: [
+ { shell: true, t: "~/code/orbit", on: true },
+ { a: "claude", t: "Optimize route planner" },
+ ] },
+ { name: "lumen-web", meta: "main · +259 −191", items: [
+ { a: "copilot", t: "Backtest search ranking" },
+ ] },
+];
+
+export const Glyph = ({ a, shell }) => shell
+ ? {">_"}
+ :
+
+ ;
+
+export const Row = ({ it }) => (
+
+
+
+ {it.t}
+ {it.b ? {it.b} : null}
+
+ {it.s ?
: null}
+
+);
+
+export const Group = ({ g }) => (
+
+
{g.name} {g.meta}
+ {g.items.map((it) =>
|
)}
+
+);
+
+export const Search = () => (
+
+
+
+
+);
+
+export const Check = () => (
+
+);
+
+export const Cross = () => (
+
+);
+
+export const State = ({ s }) => (
+ {s === "ok" ? : s === "fail" ? : }
+);
+
+export const CHECKS = [["lint", "ok", "18s"], ["typecheck", "ok", "41s"], ["test (py3.12)", "run", "2m"], ["build image", "ok", "1m 12s"]];
+export const PRS = [
+ ["Add export endpoints", "#214 · Merged 1d ago", "ok"],
+ ["Refactor session auth", "#228 · feat/session-auth · Draft", "run"],
+ ["Fix pricing fetch timeout", "#229 · 1 check failing", "fail"],
+];
+
+export const Inspector = () => (
+
+ Info Files Changes PR
+
+
+
#231 · Open 12m ago
+
Handle empty daily summaries
+
fix/report-daily-summary → main
+
Squash and merge Waiting on 1 check
+
+
+
Checks 3 of 4 passed
+ {CHECKS.map(([n, s, t]) => (
+
{n} {t}
+ ))}
+
+
+
Reviews
+
M mara Approved
+
J jonas Requested
+
+
+
Pull requests
+ {PRS.map(([t, m, s]) => (
+
+ ))}
+
+
+
+);
+
+{/* The hero demo. Five chapters after the promo storyboard
+ (videos/tty7-promo/STORYBOARD.md), each a pure function of the seconds t
+ since it began, so any frame can be drawn directly and a click can jump
+ to any chapter. */}
+
+export const CHAPTERS = [
+ { key: "agents", label: "Every agent", d: 7.5 },
+ { key: "cli", label: "Agents drive it", d: 9.5 },
+ { key: "prompt", label: "Editor prompt", d: 7.5 },
+ { key: "search", label: "⌘P everything", d: 8 },
+ { key: "persist", label: "Quit, keep running", d: 7.5 },
+];
+
+export const typed = (s, t, t0, cps = 22) => (t < t0 ? "" : s.slice(0, Math.floor((t - t0) * cps)));
+export const typingDone = (s, t, t0, cps = 22) => t >= t0 + s.length / cps;
+export const hl = (s, q) => {
+ const i = q ? s.toLowerCase().indexOf(q) : -1;
+ return i < 0 ? s : <>{s.slice(0, i)}{s.slice(i, i + q.length)} {s.slice(i + q.length)}>;
+};
+
+export const P = ({ br = "main", caret, children }) => (
+
+ → orbit {br} ●
+ {children}{caret ? : null}
+
+);
+
+export const O = ({ c = "", children }) => {children}
;
+
+{/* Sidebar for a frame: the base groups plus whatever the chapter changed. */}
+export const sidebar = (ch, t) => {
+ const g = GROUPS.map((x) => ({ ...x, items: x.items.map((it) => ({ ...it })) }));
+ const find = (title) => g.flatMap((x) => x.items).find((it) => it.t === title);
+ if (ch === 0) find("Refactor session auth").s = t < 3.1 ? "working" : "waiting";
+ /* A split stays in the same tab; the tab picks up the agent status. */
+ if (ch === 1 && t >= 3.2) find("~/code/orbit").s = t < 6.4 ? "working" : "done";
+ if ((ch === 3 && t >= 4.1) || ch === 4) {
+ find("~/code/orbit").on = false;
+ g[0].items.unshift({ a: "claude", t: "Handle empty daily summaries", s: ch === 4 && t >= 5.2 ? "done" : "working", on: true });
+ }
+ return g;
+};
+
+export const AgentsTable = ({ cursor }) => (
+ <>
+ {"PANE AGENT STATUS MESSAGE"}
+ {AGENT_ROWS.map(([p, a, s, m]) => {
+ const st = a === "cursor" ? cursor : s;
+ return {p.padEnd(6)}{a.padEnd(9)}{st.padEnd(9)} {m} ;
+ })}
+ >
+);
+
+{/* Pane ids spell their "%" as \u0025: the hosted Mintlify build percent-decodes
+ the page before parsing it, so a literal "%22" turned into a quote and broke the page. */}
+export const AGENT_ROWS = [
+ ["\u002512", "claude", "working", "Spin up a staging instance"],
+ ["\u002514", "codex", "working", "Inspect CLI error logs"],
+ ["\u002521", "cursor", "working", "Refactor session auth"],
+ ["\u002522", "gemini", "working", "Fix pricing fetch timeout"],
+ ["\u002531", "claude", "done", "Optimize route planner"],
+];
+
+export const TermAgents = ({ t }) => {
+ const c1 = "tty7 agents", c2 = "tty7 wait \u002521 --until waiting";
+ return (
+
+
{typed(c1, t, 0.4, 18)}
+ {t >= 1.3 ?
: null}
+ {t >= 1.5 ?
{typed(c2, t, 1.7, 26)}
: null}
+ {t >= 3.1 ?
{"\u002521 "}waiting : null}
+ {t >= 3.1 ?
: null}
+
+ );
+};
+
+export const TermCli = ({ t }) => {
+ const a = "tty7 split --h", b = "tty7 send \u002512 'claude \"fix flaky test\"' --enter";
+ const c = "tty7 wait \u002512 --until done", d = "tty7 capture \u002512 --tail 1";
+ const split = t >= 1.3;
+ return (
+
+
+
{typed(a, t, 0.4, 18)}
+ {t >= 1.3 ?
{"\u002512"} : null}
+ {t >= 1.5 ?
{typed(b, t, 1.6, 30)}
: null}
+ {t >= 3.3 ?
= 3.3 && t < 6.4 && typingDone(c, t, 3.5, 26)}>{typed(c, t, 3.5, 26)}
: null}
+ {t >= 6.5 ?
{typed(d, t, 6.6, 26)}
: null}
+ {t >= 7.7 ?
✓ Patched warmup() race · 214 passed : null}
+ {t >= 7.7 ?
: null}
+
+ {split ? (
+
+
{t >= 3.2 ? "claude \"fix flaky test\"" : ""}
+ {t >= 3.7 ?
✻ Reading cache_test.rs : null}
+ {t >= 4.6 ?
✻ Running cargo test ×20 : null}
+ {t >= 5.6 ?
✓ Found race in warmup() : null}
+ {t >= 6.3 ?
✓ Patched warmup() race · 214 passed : null}
+
+ ) : null}
+
+ );
+};
+
+export const COMPLETIONS = [
+ ["checkout", "Switch branches or restore working tree files"],
+ ["cherry-pick", "Apply the changes introduced by existing commits"],
+ ["cherry", "Find commits yet to be applied upstream"],
+];
+
+export const TermPrompt = ({ t }) => {
+ const menu = t >= 1.8 && t < 3.6;
+ const sel = t < 2.4 ? 0 : t < 3.0 ? 1 : 0;
+ const accepted = t >= 4.5, ran = t >= 5.3;
+ let line;
+ if (t < 3.6) line = <>{typed("git ch", t, 0.4, 12)}{!menu && t >= 1.0 ? eckout -b fix/pricing : null}>;
+ else if (!accepted) line = <>{"git checkout "}{t >= 3.8 ? -b fix/pricing : null}>;
+ else line = <>git checkout -b fix/pricing >;
+ return (
+
+
cargo test --quiet
+
test result: ok. 214 passed; 0 failed
+
+
{line}
+ {menu ? (
+
+ {COMPLETIONS.map(([n, d], i) => (
+
{n} {d}
+ ))}
+
+ ) : null}
+
+ {ran ?
{"Switched to a new branch 'fix/pricing'"} : null}
+ {ran ?
: null}
+
+ );
+};
+
+export const PAL = {
+ Terminals: [["claude", "Spin up a staging instance", "atlas-api"], ["codex", "Inspect CLI error logs", "atlas-api"], ["cursor", "Refactor session auth", "northwind · feat/session-auth"]],
+ Actions: [["Split Right", "⌘D"], ["Zoom Pane", "⇧⌘↩"], ["New Worktree Tab…", ""]],
+ Sessions: [["claude", "Handle empty daily summaries", "atlas-api · 12m ago"], ["codex", "Add export endpoints", "atlas-api · Yesterday"], ["claude", "Summarize benchmark results", "research · Last week"]],
+};
+
+export const Palette = ({ t }) => {
+ const q = typed("summ", t, 2.2, 7).toLowerCase();
+ const m = (s) => !q || s.toLowerCase().includes(q);
+ const groups = [
+ ["Terminals", PAL.Terminals.filter((x) => m(x[1]))],
+ ["Actions", PAL.Actions.filter((x) => m(x[0]))],
+ ["Sessions", PAL.Sessions.filter((x) => m(x[1]))],
+ ].filter(([, xs]) => xs.length);
+ if (q) groups.sort((x, y) => (x[0] === "Sessions" ? -1 : y[0] === "Sessions" ? 1 : 0));
+ let i = 0;
+ return (
+
+
+
+ {q ? {q} : Search tabs, sessions, hosts and actions }
+
+
{["All", "Actions", "Terminals", "Sessions", "Hosts"].map((s) => {s} )}
+
+ {groups.map(([name, xs]) => (
+
+
{name}
+ {xs.map((x) => {
+ const sel = i++ === 0;
+ return name === "Actions" ? (
+
{"›"} {hl(x[0], q)} {x[1]}
+ ) : (
+
{hl(x[1], q)} {x[2]}
+ );
+ })}
+
+ ))}
+
+
+ );
+};
+
+export const TermResumed = ({ t, t0, extra }) => (
+
+
{t >= t0 ? "claude --resume 3f9c2a" : ""}
+ {t >= t0 + 0.5 ?
✻ Resuming “Handle empty daily summaries” : null}
+ {t >= t0 + 1.2 ?
Read report_service.py · 3 edits pending : null}
+ {t >= t0 + 1.9 ?
✻ Running pytest tests/test_report_service.py : null}
+ {extra}
+
+);
+
+export const TermSearch = ({ t }) => (t < 4.1
+ ? (
+
+ )
+ : );
+
+export const TermPersist = ({ t }) => (
+
+ {t >= 4.6 ? ✓ 18 passed · empty summaries return EMPTY_SUMMARY : null}
+ {t >= 5.2 ? ⏺ Done. 3 files changed, +41 −6 : null}
+ >} />
+);
+
+export const PERSIST_PANES = [["claude", "Handle empty daily summaries"], ["claude", "Spin up a staging instance"], ["codex", "Inspect CLI error logs"], ["gemini", "Fix pricing fetch timeout"]];
+
+export const Frame = ({ ch, t }) => {
+ const k = CHAPTERS[ch].key;
+ const groups = sidebar(ch, t);
+ const title = (k === "search" && t >= 4.1) || k === "persist" ? "Handle empty daily summaries" : "~/code/orbit";
+ const gone = k === "persist" && t >= 0.9 && t < 3.7;
+ const palOpen = k === "search" && t >= 0.7 && t < 4.0;
+ const toast = k === "agents" && t >= 3.2 && t < 6.9;
+ return (
+
+
+
+
+
+
+ {groups.map((g) => )}
+
+
+
+
= 0.35 && t < 0.7 ? " is-press" : "")}>{title} ⌘P
+
+ {k === "agents" ? : k === "cli" ? : k === "prompt" ? : k === "search" ? : }
+
+
+ {palOpen ?
: null}
+ {palOpen ?
: null}
+ {toast ? (
+
+
+
Cursor needs your permission… northwind · Refactor session auth
+
+ ) : null}
+
+ {k === "persist" && t >= 1.1 && t < 3.8 ? (
+
+
Window closed. The server kept going.
+ {PERSIST_PANES.map(([a, s]) => (
+
{s}
+ ))}
+
+ ) : null}
+
+ );
+};
+
+export const Demo = () => {
+ const [st, setSt] = useState({ ch: 0, t: 0 });
+ /* Mintlify documents useState and useEffect in MDX, so the mutable clock
+ and the element handle live in state rather than refs. No // comments in
+ this file: the hosted build fails to parse a page that has them. */
+ const [c0] = useState(() => ({ ch: 0, start: 0, visible: true, last: 0, paused: 0 }));
+ const [el, setEl] = useState(null);
+ useEffect(() => {
+ const c = c0;
+ c.start = performance.now();
+ let raf = 0;
+ const tick = (now) => {
+ raf = requestAnimationFrame(tick);
+ if (!c.visible || document.hidden) { c.start = now - c.paused; return; }
+ let t = (now - c.start) / 1000;
+ if (t >= CHAPTERS[c.ch].d) { c.ch = (c.ch + 1) % CHAPTERS.length; c.start = now; t = 0; }
+ c.paused = now - c.start;
+ if (now - c.last < 33) return;
+ c.last = now;
+ setSt({ ch: c.ch, t });
+ };
+ c.paused = 0;
+ raf = requestAnimationFrame(tick);
+ const io = new IntersectionObserver(([e]) => { c.visible = e.isIntersecting; }, { threshold: 0.05 });
+ if (el) io.observe(el);
+ return () => { cancelAnimationFrame(raf); io.disconnect(); };
+ }, [el]);
+ const go = (i) => {
+ const c = c0;
+ c.ch = i; c.start = performance.now(); c.paused = 0;
+ setSt({ ch: i, t: 0 });
+ };
+ const cur = CHAPTERS[st.ch];
+ return (
+
+
+
+ {CHAPTERS.map((c, i) => (
+ go(i)}>
+
+ {c.label}
+
+ ))}
+
+
{cur.label}
+
+ );
+};
+
+export const Ico = ({ d }) => (
+
+);
+
+export const FEATURES = [
+ { t: "Sessions that outlive the app", href: "/getting-started/concepts",
+ d: "M12 3v8M6.3 6.3a8 8 0 1 0 11.4 0",
+ p: "A background server owns your shells, not the window. Quit tty7 and your builds keep building. No tmux to learn or configure." },
+ { t: "Editor-grade input", href: "/terminal/prompt",
+ d: "M5 6h14a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2zM7 10h.01M11 10h.01M15 10h.01M8 14h8",
+ p: "Ghost suggestions from your history, tab completion that explains each flag, syntax highlighting, click-to-place caret, real multi-line editing." },
+ { t: "Agent-aware", href: "/agents/overview",
+ d: "M8 8h8a3 3 0 0 1 3 3v5a3 3 0 0 1-3 3H8a3 3 0 0 1-3-3v-5a3 3 0 0 1 3-3zM12 4v4M9.5 13h.01M14.5 13h.01",
+ p: "26 coding CLIs recognised on sight. Per-pane status dots, a notification when one needs you, and session resume after a reboot." },
+ { t: "Remote work that feels local", href: "/remote/workspaces",
+ d: "M5 4h14a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2zM5 13h14a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2zM7 7.5h.01M7 16.5h.01",
+ p: "A native Rust SSH stack with profiles, SFTP, and port forwarding — plus remote workspaces where files, repos, and panes stay on the far machine." },
+ { t: "Git where you are looking", href: "/git/source-control",
+ d: "M6 3a2 2 0 1 0 0 4 2 2 0 0 0 0-4zM6 17a2 2 0 1 0 0 4 2 2 0 0 0 0-4zM18 5a2 2 0 1 0 0 4 2 2 0 0 0 0-4zM6 7v10M18 9v1a4 4 0 0 1-4 4H6",
+ p: "Branch and diff counts on every sidebar row, a source control panel, a diff overlay, GitHub issues and pull requests, and worktrees in one dialog." },
+ { t: "Scriptable", href: "/cli/overview",
+ d: "M5 4h14a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2zM7 9l3 3-3 3M13 15h4",
+ p: "A bundled tty7 CLI that opens panes, sends keys, reads screens, and blocks until an agent needs you — so scripts and agents can drive the workbench." },
+];
+
+export const Features = () => (
+
+);
+
+export const Tick = () => (
+
+);
+
+export const AgentPanel = () => (
+
+ {GROUPS.slice(0, 2).map((g) =>
)}
+
+
+
Cursor needs your permission… northwind · Refactor session auth
+
⌘1
+
+
+);
+
+export const Bench = ({ title, hint, big, unit, rows, max }) => (
+
+
{title} {hint}
+
{big}{unit}
+
+ {rows.map(([n, v]) => (
+
+ {n}
+
+ {v} {unit}
+
+ ))}
+
+
+);
+
+export const STEPS = [
+ { t: "Install it", p: "Native builds for macOS, Windows, and Linux. No runtime to install first.", href: "/getting-started/installation", l: "Installation" },
+ { t: "Set it up", p: "Five minutes of settings that pay for themselves: shell, font, theme, keys.", href: "/getting-started/first-launch", l: "First launch" },
+ { t: "Learn the three words", p: "Workspace, tab, pane — and the server underneath them that keeps it all alive.", href: "/getting-started/concepts", l: "Core concepts" },
+];
+
+export const Home = () => (
+
+
+
+
Open source · written in Rust
+
A terminal you can leave running.
+
Close the window, reboot, walk to a different laptop — the shells you started are still there, and so are the coding agents you left working in them.
+
+
macOS · Windows · Linux
+
+
+
+
+
+
+
What makes it different
+
A workbench, not just a window.
+
Everything you reach for between commands — sessions, hosts, branches, agents — sits next to the terminal instead of in another app.
+
+
+
+
+
+
+
+
Coding agents
+
Run five agents. Watch none of them.
+
tty7 never wraps your agents — it recognises them by the command in the pane and keeps track from the outside.
+
+ Status on every tab. Working, waiting, done — a dot per pane, grouped by repository.
+ Told when you're needed. A notification the moment an agent blocks on you, and another when a turn finishes.
+ Back after a reboot. Agent sessions resume where they were, in the pane they were in.
+
+
+ {["claude", "codex", "gemini", "cursor", "opencode", "copilot"].map((a) => (
+
{AGENTS[a].name}
+ ))}
+
+20 more
+
+
+
+
+
+
+
+
+
Performance
+
Roughly twice as fast where it counts.
+
The PTY is read at device speed and parsed off the render path, so drawing never throttles reading — and a flood never drops the frame rate.
+
+
+
+
+
Apple M1 Pro, macOS 26.3.1, 155×40 grid, five-run averages. Reproduce it with one command →
+
+
+
+
+
+
Start here
+
Up and running in three steps.
+
+
+
+
+
+
+ Your shells will still be there.
+ Free and open source. Native on macOS, Windows, and Linux.
+
+
+
+
+
+);
+
+
diff --git a/docs/index.mdx b/docs/index.mdx
index 6b4467b2..50d6889e 100644
--- a/docs/index.mdx
+++ b/docs/index.mdx
@@ -148,7 +148,7 @@ export const sidebar = (ch, t) => {
const g = GROUPS.map((x) => ({ ...x, items: x.items.map((it) => ({ ...it })) }));
const find = (title) => g.flatMap((x) => x.items).find((it) => it.t === title);
if (ch === 0) find("Refactor session auth").s = t < 3.1 ? "working" : "waiting";
- // A split stays in the same tab; the tab picks up the agent's status.
+ /* A split stays in the same tab; the tab picks up the agent's status. */
if (ch === 1 && t >= 3.2) find("~/code/orbit").s = t < 6.4 ? "working" : "done";
if ((ch === 3 && t >= 4.1) || ch === 4) {
find("~/code/orbit").on = false;
@@ -374,8 +374,9 @@ export const Frame = ({ ch, t }) => {
export const Demo = () => {
const [st, setSt] = useState({ ch: 0, t: 0 });
- // Mintlify documents useState and useEffect in MDX, so the mutable clock
- // and the element handle live in state rather than refs.
+ /* Mintlify documents useState and useEffect in MDX, so the mutable clock
+ and the element handle live in state rather than refs. No // comments in
+ this file: the hosted build fails to parse a page that has them. */
const [c0] = useState(() => ({ ch: 0, start: 0, visible: true, last: 0, paused: 0 }));
const [el, setEl] = useState(null);
useEffect(() => {