From 1a2710f7c8294ed3a0a39206b2e1bc5aaa8db02c Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Fri, 16 Oct 2026 09:13:28 -0700 Subject: [PATCH] Pick project and model when creating a task --- TODO.md | 3 --- docs/operations.md | 2 +- web/dist/switcher.js | 19 ++++++++++++------- web/dist/switcher.js.map | 2 +- web/src/switcher.ts | 26 +++++++++++++++++++------- 5 files changed, 33 insertions(+), 19 deletions(-) diff --git a/TODO.md b/TODO.md index af3fc1e..c40a2a9 100644 --- a/TODO.md +++ b/TODO.md @@ -4,9 +4,6 @@ # M2 — Seeing the work -- Pick project and model when creating a task - The switcher's task creation lets a `proj:` prefix narrow to project rows instead of always using the focused or first project, and the "New task in X" row shows the model that will run. - # M3 — Second vendor and review # M4 — Merging and history diff --git a/docs/operations.md b/docs/operations.md index 8ff2a21..cab4e32 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -137,7 +137,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.`, one JSON object with `composer` (keyed by `message:` 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 session state and open inbox item count (the Project tab's task list shows the same state), and **merge held** on a task with `merge_queued_at`, 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. Picking a task points the right pane at it on the Inbox tab when it has open inbox items, otherwise on the Transcript tab (see "Lead agent"). +The task switcher (⌘K, or the project ▸ task picker centred in the right pane's top row) lists active tasks with their session state and open inbox item count (the Project tab's task list shows the same state), and **merge held** on a task with `merge_queued_at`, 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 (see "Lead agent"). **Task colours.** Each task has a colour, `tasks.color` (`color` in the API), an index into the palette of `--task-0` … `--task-N` custom properties at the top of `web/style.css`, one set for light and one for dark, all at least 4.5:1 against the backgrounds so they work as text. `CreateTask` assigns it in the same transaction as the task's row: of the `store.TaskColors` colours, one no active task holds, and among those the one given out longest ago (the lowest `max(rowid)` of tasks with that colour, never-used first), so a new task doesn't take the colour of one just closed. Active tasks have distinct colours until more than `TaskColors` are active at once. `TaskColors` must match the number of palette entries. An element styled with `taskStyle(id)` (`web/src/taskcolor.ts`) sets `--task` for itself and its children from the task's `color`; `--task` defaults to the accent, which is also what a task the page doesn't know gets. The right pane sets it for the selected task, which tints the picker's row, colours the task picker's text, the selected tab's underline, the composer's border and the running border and scanner. Everywhere a task is named it shows in its colour: task titles in the switcher, the Project tab and the Status tab (`.task-name`), and task links (`a.task-link`), including any Markdown link to `#/task/` or `#/task//`. The lead's guidance tells it to link every task it names that way, using `#/task//inbox` when it points the human at the task's inbox, and clicking one points the right pane at the task, selecting the named tab if there is one. diff --git a/web/dist/switcher.js b/web/dist/switcher.js index 438159f..2da9f8b 100644 --- a/web/dist/switcher.js +++ b/web/dist/switcher.js @@ -2,7 +2,7 @@ import { post } from "./api.js"; import { errorText, h, replace, showAlert } from "./dom.js"; import { focusLead } from "./panes.js"; import { activeTasks, focusedProject, focusProject, focusTab, focusTask, lastVisits, onEach, state, taskState } from "./state.js"; -import { confirmMerge } from "./task.js"; +import { confirmMerge, models } from "./task.js"; import { taskStyle } from "./taskcolor.js"; export function bindShortcuts() { addEventListener("keydown", (e) => { @@ -50,6 +50,7 @@ const shortcuts = [ [ ["↑ ↓", "Move the highlight"], ["Enter", "Pick the highlighted row"], + ["name: title", "Create the task in the project whose name starts with name"], ], ], [ @@ -117,12 +118,16 @@ export function openSwitcher() { } }; const render = () => { - const title = input.value.trim(); + const typed = input.value.trim(); + const prefix = /^([^:\s]+):\s*(.*)$/.exec(typed); + const named = prefix ? state.projects.filter((p) => p.name.toLowerCase().startsWith(prefix[1].toLowerCase())) : []; + const targets = named.length > 0 ? named : undefined; + const title = targets ? prefix[2] : typed; const q = title.toLowerCase(); const inbox = (taskId) => state.inbox.filter((item) => item.task_id === taskId).length; const visits = lastVisits(); const matches = activeTasks() - .filter(({ project, task }) => `${project.name} ${task.title}`.toLowerCase().includes(q)) + .filter(({ project, task }) => targets ? targets.some((p) => p.id === project.id) && task.title.toLowerCase().includes(q) : `${project.name} ${task.title}`.toLowerCase().includes(q)) .map((m) => ({ ...m, count: inbox(m.task.id), visited: visits[m.task.id] ?? 0 })) .sort((a, b) => Number(b.count > 0) - Number(a.count > 0) || a.visited - b.visited); rows = matches.map(({ project, task, count }) => { @@ -130,7 +135,7 @@ export function openSwitcher() { const el = h("li", { style: taskStyle(task.id) }, h("span", { class: `dot ${ts ?? "none"}`, title: ts ?? "no session" }), h("span", { class: "task-title" }, h("span", { class: "project-name" }, project.name), " ", h("span", { class: "task-name" }, task.title)), count > 0 && h("span", { class: "badge", title: "inbox items" }, count), task.merge_queued_at !== undefined && h("span", { class: "task-state warn", title: "Waiting for the merge in progress in this project to finish" }, "merge held"), h("span", { class: "task-state" }, ts ?? "no agent")); return { el, pick: () => go(task.id) }; }); - for (const p of state.projects.filter((p) => `${p.name} project`.toLowerCase().includes(q))) { + for (const p of (targets ?? state.projects).filter((p) => `${p.name} project`.toLowerCase().includes(q))) { const el = h("li", {}, h("span", { class: "dot none" }), h("span", { class: "task-title" }, h("span", { class: "project-name" }, p.name)), h("span", { class: "task-state" }, "project")); rows.push({ el, @@ -140,9 +145,9 @@ export function openSwitcher() { }, }); } - const project = focusedProject() ?? state.projects[0]; - if (title && project) { - const el = h("li", { class: "new-task" }, h("span", { class: "task-title" }, "New task in ", h("span", { class: "project-name" }, project.name), ": ", title)); + const fallback = focusedProject() ?? state.projects[0]; + for (const project of title ? (targets ?? (fallback ? [fallback] : [])) : []) { + const el = h("li", { class: "new-task" }, h("span", { class: "task-title" }, "New task in ", h("span", { class: "project-name" }, project.name), ": ", title), h("span", { class: "task-state", title: "Model for the first message" }, models[0])); rows.push({ el, pick: () => void create(project.id, title) }); } selected = Math.min(selected, Math.max(rows.length - 1, 0)); diff --git a/web/dist/switcher.js.map b/web/dist/switcher.js.map index 1f08a4b..b64cf4a 100644 --- a/web/dist/switcher.js.map +++ b/web/dist/switcher.js.map @@ -1 +1 @@ -{"version":3,"file":"switcher.js","sourceRoot":"","sources":["../src/switcher.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"switcher.js","sourceRoot":"","sources":["../src/switcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAClI,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,UAAU,aAAa;IAC3B,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;QAChC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC,aAAa,CAAC,cAAc,CAAC,EAAE,CAAC;YACxE,OAAO;QACT,CAAC;QACD,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YAClB,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,YAAY,EAAE,CAAC;QACjB,CAAC;aAAM,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YACzB,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,QAAQ,CAAC,SAAS,CAAC,CAAC;QACtB,CAAC;aAAM,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YACzB,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,SAAS,EAAE,CAAC;QACd,CAAC;aAAM,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YACzB,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;gBACzB,KAAK,YAAY,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YACzB,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,aAAa,EAAE,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,SAAS,GAAmC;IAChD;QACE,UAAU;QACV;YACE,CAAC,IAAI,EAAE,4BAA4B,CAAC;YACpC,CAAC,IAAI,EAAE,sBAAsB,CAAC;YAC9B,CAAC,IAAI,EAAE,oCAAoC,CAAC;YAC5C,CAAC,IAAI,EAAE,6BAA6B,CAAC;YACrC,CAAC,IAAI,EAAE,sBAAsB,CAAC;YAC9B,CAAC,KAAK,EAAE,gCAAgC,CAAC;SAC1C;KACF;IACD;QACE,eAAe;QACf;YACE,CAAC,KAAK,EAAE,oBAAoB,CAAC;YAC7B,CAAC,OAAO,EAAE,0BAA0B,CAAC;YACrC,CAAC,aAAa,EAAE,4DAA4D,CAAC;SAC9E;KACF;IACD;QACE,4BAA4B;QAC5B;YACE,CAAC,OAAO,EAAE,MAAM,CAAC;YACjB,CAAC,aAAa,EAAE,UAAU,CAAC;YAC3B,CAAC,eAAe,EAAE,yBAAyB,CAAC;SAC7C;KACF;IACD;QACE,SAAS;QACT,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;KACvB;IACD;QACE,UAAU;QACV,CAAC,CAAC,QAAQ,EAAE,gCAAgC,CAAC,CAAC;KAC/C;CACF,CAAC;AAEF,SAAS,aAAa;IACpB,KAAK,SAAS,CAAC;QACb,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,oBAAoB,CAAC;QAC3D,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,CACjC,CAAC,CACC,SAAS,EACT,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAC5B,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,EAClB,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CACrG,CACF;QACD,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,2BAA2B,CAAC;KACvD,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,IAAI,QAAQ,CAAC,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC;QACxC,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,8CAA8C,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/G,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;IAC1D,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACzD,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,IAAI,GAA4C,EAAE,CAAC;IAEvD,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IAChF,MAAM,QAAQ,GAAG,CAAC,CAAgB,EAAE,EAAE;QACpC,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QACD,CAAC,CAAC,cAAc,EAAE,CAAC;QACnB,CAAC,CAAC,eAAe,EAAE,CAAC;QACpB,KAAK,EAAE,CAAC;IACV,CAAC,CAAC;IACF,gBAAgB,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,GAAG,EAAE;QACjB,IAAI,EAAE,CAAC;QACP,mBAAmB,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5D,QAAQ,CAAC,MAAM,EAAE,CAAC;QAClB,GAAG,CAAC,MAAM,EAAE,CAAC;IACf,CAAC,CAAC;IAEF,MAAM,EAAE,GAAG,CAAC,MAAc,EAAE,EAAE;QAC5B,KAAK,EAAE,CAAC;QACR,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IAClG,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,KAAK,EAAE,SAAiB,EAAE,KAAa,EAAE,EAAE;QACxD,KAAK,EAAE,CAAC;QACR,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,iCAAiC,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YACrG,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QACjC,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,GAAG,EAAE;QAClB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACpH,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QACrD,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,MAAO,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QAC5C,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,CAAC,MAAc,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;QAC/F,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,WAAW,EAAE;aAC1B,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAC5B,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CACvJ;aACA,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;aAChF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;QACtF,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;YAC9C,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YAC3B,MAAM,EAAE,GAAG,CAAC,CACV,IAAI,EACJ,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAC7B,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,YAAY,EAAE,CAAC,EACtE,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAC1I,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,KAAK,CAAC,EACvE,IAAI,CAAC,eAAe,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,6DAA6D,EAAE,EAAE,YAAY,CAAC,EACjK,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,EAAE,IAAI,UAAU,CAAC,CACrD,CAAC;YACF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;QACzC,CAAC,CAAC,CAAC;QACH,KAAK,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACzG,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC;YAC1L,IAAI,CAAC,IAAI,CAAC;gBACR,EAAE;gBACF,IAAI,EAAE,GAAG,EAAE;oBACT,KAAK,EAAE,CAAC;oBACR,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACrB,CAAC;aACF,CAAC,CAAC;QACL,CAAC;QACD,MAAM,QAAQ,GAAG,cAAc,EAAE,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACvD,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAC7E,MAAM,EAAE,GAAG,CAAC,CACV,IAAI,EACJ,EAAE,KAAK,EAAE,UAAU,EAAE,EACrB,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,EACnH,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,6BAA6B,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CACpF,CAAC;YACF,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QAChE,CAAC;QACD,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5D,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;YACtB,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,KAAK,QAAQ,CAAC,CAAC;YACpD,GAAG,CAAC,EAAE,CAAC,WAAW,GAAG,CAAC,CAAC,EAAE,EAAE;gBACzB,CAAC,CAAC,cAAc,EAAE,CAAC;gBACnB,GAAG,CAAC,IAAI,EAAE,CAAC;YACb,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,8CAA8C,CAAC,CAAC,CAAC;IAChJ,CAAC,CAAC;IAEF,KAAK,CAAC,OAAO,GAAG,GAAG,EAAE;QACnB,QAAQ,GAAG,CAAC,CAAC;QACb,MAAM,EAAE,CAAC;IACX,CAAC,CAAC;IACF,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,EAAE;QACtB,IAAI,CAAC,CAAC,GAAG,KAAK,WAAW,EAAE,CAAC;YAC1B,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACnD,MAAM,EAAE,CAAC;QACX,CAAC;aAAM,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YAC/B,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YACrC,MAAM,EAAE,CAAC;QACX,CAAC;aAAM,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;YAC7B,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC;QACzB,CAAC;IACH,CAAC,CAAC;IACF,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAC;IAEzB,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,cAAc,CAAE,CAAC,qBAAqB,EAAE,CAAC;IAC/E,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC;IACzC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,QAAQ,CAAC,eAAe,CAAC,WAAW,CAAC;IACtD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,GAAG,GAAG,CAAC,WAAW,GAAG,CAAC,CAAC;IAClE,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,GAAG,GAAG,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IACpF,MAAM,EAAE,CAAC;IACT,KAAK,CAAC,KAAK,EAAE,CAAC;AAChB,CAAC"} \ No newline at end of file diff --git a/web/src/switcher.ts b/web/src/switcher.ts index 98ede1a..27de437 100644 --- a/web/src/switcher.ts +++ b/web/src/switcher.ts @@ -2,7 +2,7 @@ import { post } from "./api.js"; import { errorText, h, replace, showAlert } from "./dom.js"; import { focusLead } from "./panes.js"; import { activeTasks, focusedProject, focusProject, focusTab, focusTask, lastVisits, onEach, state, taskState } from "./state.js"; -import { confirmMerge } from "./task.js"; +import { confirmMerge, models } from "./task.js"; import { taskStyle } from "./taskcolor.js"; export function bindShortcuts(): void { @@ -48,6 +48,7 @@ const shortcuts: [string, [string, string][]][] = [ [ ["↑ ↓", "Move the highlight"], ["Enter", "Pick the highlighted row"], + ["name: title", "Create the task in the project whose name starts with name"], ], ], [ @@ -128,12 +129,18 @@ export function openSwitcher(): void { }; const render = () => { - const title = input.value.trim(); + const typed = input.value.trim(); + const prefix = /^([^:\s]+):\s*(.*)$/.exec(typed); + const named = prefix ? state.projects.filter((p) => p.name.toLowerCase().startsWith(prefix[1]!.toLowerCase())) : []; + const targets = named.length > 0 ? named : undefined; + const title = targets ? prefix![2]! : typed; const q = title.toLowerCase(); const inbox = (taskId: string) => state.inbox.filter((item) => item.task_id === taskId).length; const visits = lastVisits(); const matches = activeTasks() - .filter(({ project, task }) => `${project.name} ${task.title}`.toLowerCase().includes(q)) + .filter(({ project, task }) => + targets ? targets.some((p) => p.id === project.id) && task.title.toLowerCase().includes(q) : `${project.name} ${task.title}`.toLowerCase().includes(q), + ) .map((m) => ({ ...m, count: inbox(m.task.id), visited: visits[m.task.id] ?? 0 })) .sort((a, b) => Number(b.count > 0) - Number(a.count > 0) || a.visited - b.visited); rows = matches.map(({ project, task, count }) => { @@ -149,7 +156,7 @@ export function openSwitcher(): void { ); return { el, pick: () => go(task.id) }; }); - for (const p of state.projects.filter((p) => `${p.name} project`.toLowerCase().includes(q))) { + for (const p of (targets ?? state.projects).filter((p) => `${p.name} project`.toLowerCase().includes(q))) { const el = h("li", {}, h("span", { class: "dot none" }), h("span", { class: "task-title" }, h("span", { class: "project-name" }, p.name)), h("span", { class: "task-state" }, "project")); rows.push({ el, @@ -159,9 +166,14 @@ export function openSwitcher(): void { }, }); } - const project = focusedProject() ?? state.projects[0]; - if (title && project) { - const el = h("li", { class: "new-task" }, h("span", { class: "task-title" }, "New task in ", h("span", { class: "project-name" }, project.name), ": ", title)); + const fallback = focusedProject() ?? state.projects[0]; + for (const project of title ? (targets ?? (fallback ? [fallback] : [])) : []) { + const el = h( + "li", + { class: "new-task" }, + h("span", { class: "task-title" }, "New task in ", h("span", { class: "project-name" }, project.name), ": ", title), + h("span", { class: "task-state", title: "Model for the first message" }, models[0]), + ); rows.push({ el, pick: () => void create(project.id, title) }); } selected = Math.min(selected, Math.max(rows.length - 1, 0));