Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -485,16 +485,13 @@ started.
`fctl open my-app#12 --claude` opens the desktop app, or claude.ai when it
is not installed.

To try the new session view, choose **Try the new view** in a session's ⋯
menu, press `v` on its page, or turn on **New session view** in **Settings →
Appearance**; your browser keeps the choice, and the same places switch
back. It opens with the session at a glance: its turns, the agent's time,
its steps, what it changed and its pull requests, and its turns as a
ribbon, each a click from its start. It reads a session in turns: each
message opens a card, what the agent did about it hangs from the card on a
thread, and each turn ends with how long it took, its steps and the files
it edited, each of which opens its diff; the ⋯ at a turn's end copies it as
Markdown, or a link that opens the session at that turn. The agent's plan
The session page opens with the session at a glance: its turns, the
agent's time, its steps, what it changed and its pull requests, and its
turns as a ribbon, each a click from its start. It reads a session in
turns: each message opens a card, what the agent did about it hangs from
the card on a thread, and each turn ends with how long it took, its steps
and the files it edited, each of which opens its diff; the ⋯ at a turn's
end copies it as Markdown, or a link that opens the session at that turn. The agent's plan
(its to-do list) stays beside the transcript, its steps checked off as the
agent goes. Above the message box, a line says what the agent does now and
for how long, led by the step of its plan it is at, with how far it got;
Expand Down
6 changes: 3 additions & 3 deletions docs/llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -203,13 +203,13 @@ Each recipe says who does what: some steps take a person with a role in the proj
## Web app

- **Agent Floor** (`/`): the task box (project, model, effort, GitHub access, files; ⌘Enter starts, **Schedule** turns the task into a schedule), sessions **Working now** and **Recently** (choosing one of your workspaces above them lists only its sessions and moves the task box to its first project where you can start sessions, in your sidebar order), plan usage, invitations. ⌘K searches sessions, projects, workspaces and what sessions said.
- **Keyboard shortcuts** (on a computer; ⌘ is Ctrl on Linux and Windows): `?` or ⌘/ lists them all, those of the page first, with a filter (also in ⌘K and the menu under your name); `n`, or ⌘⇧O from a text box, opens the Agent Floor's task box over any page, with the same draft, in the page's project (on the Agent Floor or a project's Sessions tab, it goes to the page's own box); `g` then `f`, `n`, `p` or `s` go to the Agent Floor, the next session in Needs you, the pull requests and Settings; ⌘K, ⌘B (fold the sidebar); on a session's page `r` goes to the message box, `c` opens the changes, `d` shows or hides the details, `v` switches between the classic and the new view, and in the new view `j`/`k` go from turn to turn. Esc leaves a task box or the message box, for the single keys. Keys are the characters your layout types: `?` and `/` work with the Shift they take on Swedish or German keyboards, letters where each layout has them.
- **Keyboard shortcuts** (on a computer; ⌘ is Ctrl on Linux and Windows): `?` or ⌘/ lists them all, those of the page first, with a filter (also in ⌘K and the menu under your name); `n`, or ⌘⇧O from a text box, opens the Agent Floor's task box over any page, with the same draft, in the page's project (on the Agent Floor or a project's Sessions tab, it goes to the page's own box); `g` then `f`, `n`, `p` or `s` go to the Agent Floor, the next session in Needs you, the pull requests and Settings; ⌘K, ⌘B (fold the sidebar); on a session's page `r` goes to the message box, `c` opens the changes, `d` shows or hides the details, and `j`/`k` go from turn to turn. Esc leaves a task box or the message box, for the single keys. Keys are the characters your layout types: `?` and `/` work with the Shift they take on Swedish or German keyboards, letters where each layout has them.
- **Sidebar**: the Agent Floor; **Needs you** (what your sessions and those you follow wait on you for, most pressing first: an agent's question, a failure, failed checks, a pull request its agent finished, a reply it waits for unless its pull requests are all merged or closed and nobody wrote to it since, a pause; its count shows in the tab's title and on the installed app's icon); **Pull requests** (`/pulls`, with how many are ready for review); then your workspaces and their projects in your order, each project with its icon, and under each, on every page, its sessions that haven't ended and, for an hour, those that stopped or failed; hovering one whose agent waits for a message, stopped or failed shows a button that hides it from the sidebar in that browser until its agent works again (a run starts, it asks something or it ends another turn). The project a page is about shows its own pull requests too. Drag its edge to make it wider (a double click puts it back); ⌘B (Ctrl+B; ⌘\ too), or dragging its edge most of the way to the left, folds it into a rail of icons, and dragging the rail's edge to the right opens it again.
- **Pull requests** (`/pulls`): the pull requests agents opened, each once with its sessions, archived sessions' too; open ones sorted by what each needs next (waiting for your answer, with the agent's question and its answers to click, then ready for review, checks failing, agents at work, merge queue, drafts), merged and closed ones by day; each with its checks, fctl's review and its size; a filter whose matches each tab counts, a workspace or project, Mine (on until you turn it off, which the browser keeps; the sidebar's counts follow it); opened again from the sidebar, it shows the tab and the filter it had; `j`/`k`, Enter, `o` for GitHub, `c` to copy its link, `/` to filter, the arrows between tabs.
- **Session page** (`/s/<id>`, `r`, `c` and `d` for the message box, the changes and the details): the live transcript (tool calls fold into lines, edits show highlighted; the images the agent read show small under them for 7 days), the composer to message the agent (with its owner's lists for the model and effort level it works at from its next step: a new model, which reads the conversation again without Claude's prompt cache, asks first), Interrupt, Stop and Resume, Share, the follow bell, Changes (the files the branch changed; a file opens every file's diff, highlighted, one after the other at that file, with the list of files beside them marking the one in view: `j`/`k` or the arrow keys in the list go from file to file, `n`/`p` from change to change, ⌘F finds in all the diffs (Enter and Shift+Enter, ⌘G, Alt+C/W/R for case, whole words and regular expressions), `s` lays them out side by side, `w` wraps lines; as the agent changes the files, its changes come in where the reader looks while the lines in view stay put, and a button goes to those out of sight), pull requests with checks, context and usage, retrospectives (the transcript shows each with a line for each part, which opens to all it says, and marks what an update changed), ⌘F to find in the transcript, Open in Claude. A new view people can switch to (`v`, the ⋯ menu, or Settings → Appearance; the browser keeps it) reads the session in turns: a cover with the session at a glance (turns, the agent's time, steps, changes, pull requests, a ribbon of the turns), then each message opens a card, the agent's work hangs from it on a thread, and each turn ends with its time, steps and the files it edited (each opens its diff), and copies as Markdown or a link to it (`/s/<id>?turn=<seq>`); the agent's plan (its TodoWrite list) stays in the details; a line above the message box says what the agent does now and where it is in its plan, or that it's the reader's turn, and while the agent waits for its background tasks, names them in a list that goes to the call that started each (whose line says it runs in the background, then how long it ran); a bar under the header says which turn the reader is in and lists them all (the details list the newest six and the one the reader is in, the earlier ones a click away), a button goes back to the newest work or up to what came while the reader was away, and the conversation alone shows without the agent's work.
- **Session page** (`/s/<id>`, `r`, `c` and `d` for the message box, the changes and the details, `j`/`k` from turn to turn): the live transcript (tool calls fold into lines, edits show highlighted; the images the agent read show small under them for 7 days), the composer to message the agent (with its owner's lists for the model and effort level it works at from its next step: a new model, which reads the conversation again without Claude's prompt cache, asks first), Interrupt, Stop and Resume, Share, the follow bell, Changes (the files the branch changed; a file opens every file's diff, highlighted, one after the other at that file, with the list of files beside them marking the one in view: `j`/`k` or the arrow keys in the list go from file to file, `n`/`p` from change to change, ⌘F finds in all the diffs (Enter and Shift+Enter, ⌘G, Alt+C/W/R for case, whole words and regular expressions), `s` lays them out side by side, `w` wraps lines; as the agent changes the files, its changes come in where the reader looks while the lines in view stay put, and a button goes to those out of sight), pull requests with checks, context and usage, retrospectives (the transcript shows each with a line for each part, which opens to all it says, and marks what an update changed), ⌘F to find in the transcript, Open in Claude. The page reads the session in turns: a cover with the session at a glance (turns, the agent's time, steps, changes, pull requests, a ribbon of the turns), then each message opens a card, the agent's work hangs from it on a thread, and each turn ends with its time, steps and the files it edited (each opens its diff), and copies as Markdown or a link to it (`/s/<id>?turn=<seq>`); the agent's plan (its TodoWrite list) stays in the details; a line above the message box says what the agent does now and where it is in its plan, or that it's the reader's turn, and while the agent waits for its background tasks, names them in a list that goes to the call that started each (whose line says it runs in the background, then how long it ran); a bar under the header says which turn the reader is in and lists them all (the details list the newest six and the one the reader is in, the earlier ones a click away), a button goes back to the newest work or up to what came while the reader was away, and the conversation alone shows without the agent's work.
- **Project page** (`/p/<slug>`): Sessions, Tickets, Schedules, Reviews, Memory, Retrospectives, Repositories and Members tabs; maintainers and owners also see Settings (agents, sandbox, GitHub, follow-ups…) and Secrets.
- **Workspace page** (`/w/<slug>`): Projects, People, Runners (with the command and token that add one, the runners that wait for your approval, and the enrollment tokens: every one for admins, members' own for members), GitHub, Linear, Settings (its name, address, avatar image, and the color its avatar shows without one: yellow, pink, blue, ink or one of its own, as `fctl workspaces set --color '#2a9d8f'` sets it), and the Audit log for admins.
- **Settings** (`/settings`, a page each, `?tab=`): Profile (`profile`: name and picture; without one, your Gravatar unless you turn it off), Email addresses (`emails`, with commit emails), Workspaces (`workspaces`: which Claude connection, leaving), Claude (`claude`), Linear (`linear`, your Linear account), Notifications (`notifications`), Appearance (`appearance`: dark or light, a 12- or 24-hour clock, the new session view), Security (`security`: password and Google, passkeys, two-factor sign-in, devices), Access tokens (`tokens`) and Your data (`data`: one export a week, unless admins chose another wait, and deleting your account). Without `?tab=`, a phone lists the pages and a wider screen opens Profile beside them. **Admin** (`/admin`, instance admins): people, access (allowlist), early access, workspaces, GitHub, runners, settings (with reserved addresses, Gravatar for everyone, and how often people can export their data), audit.
- **Settings** (`/settings`, a page each, `?tab=`): Profile (`profile`: name and picture; without one, your Gravatar unless you turn it off), Email addresses (`emails`, with commit emails), Workspaces (`workspaces`: which Claude connection, leaving), Claude (`claude`), Linear (`linear`, your Linear account), Notifications (`notifications`), Appearance (`appearance`: dark or light, a 12- or 24-hour clock), Security (`security`: password and Google, passkeys, two-factor sign-in, devices), Access tokens (`tokens`) and Your data (`data`: one export a week, unless admins chose another wait, and deleting your account). Without `?tab=`, a phone lists the pages and a wider screen opens Profile beside them. **Admin** (`/admin`, instance admins): people, access (allowlist), early access, workspaces, GitHub, runners, settings (with reserved addresses, Gravatar for everyone, and how often people can export their data), audit.
- Notifications are Web Push to browsers where people turned them on (on iPhone and iPad, fctl added to the Home Screen): a followed session waits for a reply, pauses on a usage limit, or fails.

## Docs
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/session/glance.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// The session at a glance, on the new session page's cover (routes/session-next.tsx): how many
// The session at a glance, on the session page's cover (routes/session.tsx): how many
// turns it took, the agent's time, its steps and what it changed, in figures that roll as they
// move; its pull requests and how each stands; and its turns as a ribbon, each as wide as the
// work in it, colored by how it went, that goes to the turn it is.
Expand Down
18 changes: 7 additions & 11 deletions web/src/components/session/lines.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,16 @@
// with their icons bare.

import { ChevronRight, CircleAlert } from "lucide-react";
import { Component, type ComponentType, createContext, type ReactNode, useContext } from "react";
import { Spinner } from "@/components/ui";
import { Component, type ReactNode } from "react";
import { DotWave } from "@/components/ui";
import { cn } from "@/lib/cn";

/**
* What says a step of the agent's work is under way (a call that runs, one that streams in, the
* sandbox's setup): the spinner, unless the page has its own (the new session page's dots).
* What says a step of the agent's work is under way (a call that runs, the sandbox's setup): the
* session page's dots.
*/
export const BusyMark = createContext<ComponentType<{ className?: string }>>(Spinner);

/** The page's sign that a step is under way ([`BusyMark`]). */
export function Busy({ className }: { className?: string }) {
const Mark = useContext(BusyMark);
return <Mark className={className} />;
return <DotWave className={className} />;
}

export function Milestone({
Expand Down Expand Up @@ -51,8 +47,8 @@ export function Milestone({
}

/**
* An icon in the rail, without a tile. It says it is one (`data-rail`), for the new session page,
* whose thread runs down behind the rail's icons.
* An icon in the rail, without a tile. It says it is one (`data-rail`), for the thread that runs
* down behind the rail's icons.
*/
export function RailIcon({ children, className }: { children: ReactNode; className?: string }) {
return (
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/session/now-line.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Above the new session page's message box (routes/session-next.tsx): what the agent is doing at
// Above the session page's message box (routes/session.tsx): what the agent is doing at
// this moment, as it changes, and for how long, each new step rolling in from below as the last
// rolls away above; while it waits for work it left in the background, what that is, in a list the
// line opens into; and beside it, the way back to the newest work, with how much came since the
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/session/plan.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// The agent's plan in the new session page (routes/session-next.tsx): beside the transcript, its
// The agent's plan on the session page (routes/session.tsx): beside the transcript, its
// steps as the agent last wrote them, the one it is at marked and those it finished checked off as
// it does, with how far it got; and above the message box, a ring that fills as it goes.

Expand Down
5 changes: 0 additions & 5 deletions web/src/components/session/thinking.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,8 @@
import { useId, useState } from "react";
import { ThoughtIcon } from "@/components/ui";
import { cn } from "@/lib/cn";
import { num } from "@/lib/format";
import { OpenLine, RailIcon, Thread } from "./lines";

/** What a thought that streams in says, with how far it got once Claude Code says: "Thinking · 1.2K tokens". */
export const thinkingNow = (tokens?: number) =>
tokens ? `Thinking · ${num(tokens)} ${tokens === 1 ? "token" : "tokens"}` : "Thinking";

export function Thinking({
text,
open: shown,
Expand Down
Loading
Loading