swap picker
This commit is contained in:
+1
-1
@@ -182,7 +182,7 @@ Messages byre itself sends an agent (actor `byre`: the restart notice, Sync and
|
||||
|
||||
**Drafts.** Unsent composer text (task and lead) and unsent inbox answers (checked choices and Other/Reply text) are kept in memory by `web/src/drafts.ts` and mirrored to the browser's localStorage under `byre.drafts.<login>`, one JSON object with `composer` (keyed by `message:<task id>` or `message:lead`, each `{text, images}`), `checked` and `texts` (both keyed by inbox item id). Writes are debounced and flushed at once when a composer or answer box loses focus, when the transcript view is disposed, and on `pagehide`. A composer draft is cleared only once its send succeeds, and an inbox answer only once its response is accepted; each send in flight is tracked on its own and the stored draft holds the text of every unconfirmed send (oldest first, then the composer's current text, separated by blank lines) and counts its images, so a reload mid-send brings back everything not yet confirmed. A failed send's text goes back into the composer ahead of whatever is there now (text typed since, or earlier failures), separated by a blank line, rather than replacing it. Drafts for tasks that are no longer active and for inbox items no longer open are pruned whenever the task list or inbox reloads. A storage read that throws or holds malformed JSON (or entries of the wrong shape) is ignored, and a write that throws is logged; drafts then live only in memory. Pending images are not stored, only their count: after a reload the composer shows how many need re-attaching, until dismissed or the next successful send.
|
||||
|
||||
The task switcher (⌘K, or the project ▸ task picker centred in the right pane's top row) lists active tasks with their task state and open inbox item count (the Project tab shows the same state), live while it is open. Tasks with inbox items come first; within each group, the task least recently visited in this browser comes first (never-visited tasks before all others, ties in the server's order: projects by name, tasks newest first). Visit times are kept in the browser's localStorage under `byre.visits`, stamped when a task is selected and again when it is left. After the tasks come the projects, one row each; picking one points the right pane at the project with no task, on the Project tab. Typing filters both and adds a last row that creates a task with the typed text as its title, in the right pane's project (the first project when there is none); Enter picks the highlighted row. Text before a first colon that starts at least one project's name (ignoring case, no spaces) picks those projects instead: `by: fix` lists only their tasks whose titles contain "fix", their project rows that match, and one row per project creating the task titled "fix" there. When no project name starts with it, the whole text is the title, so "Fix: login" stays as typed. A create row shows `models[0]` from `web/src/task.ts`, the model the composer offers first for the new task's first message; the task itself starts with no session. Picking a task points the right pane at it on the Inbox tab when it has open inbox items, otherwise on the Transcript tab, scrolled to its latest summary when that is unread (see below and "Lead agent").
|
||||
The task switcher (⌘K, or the project ▸ task picker centred in the right pane's top row) lists active tasks with their task state and open inbox item count (the Project tab shows the same state), live while it is open. Tasks with inbox items come first; within each group, the task least recently visited in this browser comes first (never-visited tasks before all others, the right pane's own task after all others, ties in the server's order: projects by name, tasks newest first), so ⌘K Enter repeated cycles through the tasks. Visit times are kept in the browser's localStorage under `byre.visits`, stamped when a task is selected and again when it is left. After the tasks come the projects, one row each; picking one points the right pane at the project with no task, on the Project tab. Typing filters both and adds a last row that creates a task with the typed text as its title, in the right pane's project (the first project when there is none); Enter picks the highlighted row. Text before a first colon that starts at least one project's name (ignoring case, no spaces) picks those projects instead: `by: fix` lists only their tasks whose titles contain "fix", their project rows that match, and one row per project creating the task titled "fix" there. When no project name starts with it, the whole text is the title, so "Fix: login" stays as typed. A create row shows `models[0]` from `web/src/task.ts`, the model the composer offers first for the new task's first message; the task itself starts with no session. Picking a task points the right pane at it on the Inbox tab when it has open inbox items, otherwise on the Transcript tab, scrolled to its latest summary when that is unread (see below and "Lead agent").
|
||||
|
||||
**Task state.** The switcher and the Project tab show one label per task in place of its raw session state, the first that applies (`taskState` in `web/src/state.ts`), with a dot and a tooltip saying why: **Needs your answer** (an open `question` inbox item), **Merging** (`merging` or `merging_into_parent`), **Merge held** (`merge_queued_at`), **Error** (an open `session_error` or `rate_limited` inbox item), **Working** (the task's `state` is `running`, `review_pending`, `reviewing` or `discarding`; see "Task state in the store"), **Idle** (anything else, including no session). The Project tab, in its task list and TODO items, draws a spinner in place of the dot for **Working** and **Merging**. The label follows the tasks and inbox state the page already holds, so it needs no extra fetch.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user