Template gallery and Start flow

Task 11074 · Queued · Coder · created · updated

## Epic requirement (verbatim) > - Purpose: allow users to launch curated task definitions (description, persona, etc.) for common scenarios > - Users should be able to browse the templates and Start any of them, favorite > - In the Templates view/ browser: modern cards with images, Most popular, Favorite, grouping by purpose, full text search > > Use best practices, minimum prose. The settled inputs are the PRD (Task 11059) §5 and §7 and the architecture (Task 11060) §4 and §6a. C1's API, C1b's assets and C2's 20 published starters are merged. ## Scope - **Shared pieces:** `ui/gallery/CardGrid.tsx` and `ui/gallery/GalleryCard.tsx`. - Grid: `repeat(auto-fill, minmax(260px, 1fr))`, one column at 448px. - Card: 16:9 `object-fit: cover`; name clamped to 2 lines at word boundaries with the full name in `title`; summary clamped to 1 line with hover for the full text; a persona · origin badge line; a favorite star; Start and Customize, each at least 44px tall. - Purpose-group placeholder when `image_url` is null. - `docs/standards/ui-style-guide.md` gains a **Gallery** archetype section pointing at these files (D12). - **`/templates` gallery:** - Sections: Favorites (if any), Most popular (top 6 by `starts_90d`, ties by name), then one per purpose group in §9 order, each with a count. - One filter chip per group, plus Clear. - Server search with a 250 ms debounce: ranked results, flat with no sections, and the "No templates match" empty state with Clear. - The favorite toggle uses PUT/DELETE. - Start and Customize are hidden when `may_start` is false (§6a). - With the switch on: **New template** (→ `/templates/new`) and **Duplicate** on global cards. - **Start dialog** (a one-shot action dialog): - Project picker over the projects where the user holds `tasks:create`, plus a persona/depth line. - On Confirm: `POST /api/tasks {template_id, …}`, then the existing `POST /start`, then navigate to the task. - If a precondition fails, show its existing message with a link to the draft task. - **Customize:** `/tasks/new?template=<id>`. - `taskPrefill.ts` learns `template`; `TaskCreateView` fetches the TemplateDetail and seeds the form with the project empty. - **A template-source attachment resolver** paints the body's `attachment:` tokens from `/api/templates/{id}/assets/{asset_id}/content`. It does NOT re-upload them. - Create sends `template_id`. - **Entry points:** - Sidebar `CORE_DESTINATIONS` gains **Templates** (owns `/templates`). - **From template** sits next to New task on `/tasks`. - The empty Tasks state shows up to 6 cards (favorites → popular → featured) plus "All templates". - **Task detail:** a "From template: <name>" line from `TaskOut.template`. It is a link while the id resolves and plain text once the template is deleted. - **Test logins (I-4):** as the operator, from the console, invite two test users into the test org: a second member with `tasks:create`, and a member without `tasks:create`. Save their logins as credentials under `org/console/`, and name the credentials (never the values) in the PR body. ## Acceptance criteria (verbatim) - **AC-6 Reachable.** Oracle: as an org member, reach `/templates` three ways: the **Templates** sidebar item, **From template** next to New task on `/tasks`, and the empty Tasks state (AC-16). Expected: each lands on the same gallery. - **AC-7 Cards.** Each card shows the image, name (up to 2 lines, never cut mid-word at desktop width), one-line summary, persona label, an origin badge (Official / Your org), the favorite toggle, Start and Customize. Oracle: compare against the card anatomy in §7. Expected: at 448px cards stack one per row with no horizontal scroll, and the buttons stay at least 44px tall. - **AC-8 Grouping and sort.** Expected: the gallery opens with sections **Favorites** (if any), **Most popular** (top 6 by D8), then one section per purpose group (§9 order), each with a count. A filter chip per group narrows to that group; "Clear" resets it. Oracle: start a template 3 times, reload, and see it move up in Most popular. - **AC-9 Start (one click).** Oracle: on a card, press Start, pick a project in the dialog, confirm. Expected: a task is created with the template's title, description, persona, depth, involvement and model. It is started (state `active` or, for an epic, its first stage queued), and the browser lands on the new task's detail. The task detail shows "From template: <name>". The template's 90-day start count goes up by 1. The dialog lists only projects the user can start tasks in. Every Start precondition (`routes/tasks/dispatch.py::start_task`) surfaces as its existing message. - **AC-10 Customize.** Oracle: press Customize. Expected: `/tasks/new` opens with every template field filled in and the project empty. Changing the description and pressing Create & Start makes a task with the edited text, linked to the template and counted once. - **AC-11 Favorite.** Oracle: toggle the star on a card, reload, and sign in as another user in the same org. Expected: the first user sees the card in Favorites; the second does not. - **AC-12 Search.** Oracle: type a word that appears only in one template's description, such as "flaky". Expected: within 1 s the grid shows only matching cards, best match first, without the section grouping. Clearing the box restores the sections. A query with no matches shows the empty state: "No templates match" and a Clear button. - **AC-13 Plan switch (gallery half).** Oracle, switch off: as an org admin, the gallery shows the global templates but no New template, no Duplicate, and no manage view. Oracle, switch on: the admin sees **New template** and **Duplicate** on global cards. - **AC-14 Isolation (UI).** Oracle: org A creates a template. Org B's members don't see it in the gallery, search or the API (404 by id). Expected: the operator sees it only when acting in org A. Turning the switch off later hides org A's templates from the gallery and from Start without deleting them. - **AC-16 Empty state.** Oracle: as a member of an org with no tasks, open `/tasks`. Expected: the empty state shows up to 6 template cards (Favorites, then Most popular, then Featured), with Start and Customize, plus "All templates" linking to `/templates`. When tasks exist, Tasks has no template cards. - **AC-19 Images (gallery view).** Oracle: view the gallery in both themes. All 20 images load, the 20 are visually distinct, and a reader can match each image to its template name. - **PRD §4 read-only viewer:** a member without `tasks:create` sees the gallery read-only, with no Start or Customize buttons. - **AC-20 Live on dev.** AC-1 through AC-19 pass on `dev.jaah.ai` after the deploy. Nothing global sits behind a flag that is off in the dev deployment. Credentials & reach: - Member flows (AC-6–10, 12, 15, 16) | Operator login acting in a tenant org with tasks:create | **verified** (`me/jaah/debug/main/operator-login`, environment `https://app.dev.jaah.ai`; `dev.jaah.ai` internal ALB timed out from runner nodes, so oracles use `app.dev.jaah.ai`) - UI ACs as the operator (AC-1–5, 17, 19, 20) | `me/jaah/debug/main/operator-login` (operator identity; switches between the operator and tenants), environment `https://app.dev.jaah.ai` | **verified**: the credential is on the roster and `credential_get` succeeded; an HTTPS GET of app.dev.jaah.ai returned 200 from this node. - Org A / org B isolation and switch on/off (AC-13, 14) | Same operator login (acts in any tenant; the admin covers the org admin) + `org/console/dev-orgb-login` as org B's own admin | **verified**: both `credential_get` calls succeeded. Note: the org B row's stored base_url names a retired host; use app.dev.jaah.ai - Second member in the same org (AC-11) and a member without `tasks:create` (PRD §4 read-only viewer) | Two test users C4 invites from the console as the operator and saves as credentials under `org/console/` (I-4, operator decision) | **deferred**: the logins don't exist yet; the operator decided the builder creates them. Created through the verified operator credential above, so no human step remains Out of scope: - N-2 No change to the task lifecycle, `start_task` preconditions, or persona prompts. Start reuses the existing create and start routes. - N-3 No fill-in inputs, `{{placeholders}}` or variables in template text (D3). - N-4 No public or community marketplace: no cross-org sharing, creator profiles, ratings, paid templates, or "Recommended for you" personalization. - N-8 No change to other sidebar items or their order beyond adding **Templates**. - N-9 Existing Tasks list behavior is unchanged when tasks exist (AC-16). - N-1 No change to Playbooks. - Do NOT touch: the manage list or editor (C3); the automation UI (C5); the API contract (C1 and C1b; report gaps). Customize must not use the `taskDuplicate` re-upload path. Done means: - Every AC above passes on app.dev.jaah.ai in a browser at desktop width AND at 448px, in light AND dark theme. Attach screenshots to the PR: the gallery (both widths, both themes), the search results, the empty state, the Start dialog and the task detail with "From template". - Fails if any card name is clipped mid-word or to one line at desktop width. - Fails if any page scrolls horizontally at 448px, or if a button is under 44px tall. - Fails if an image is stretched or broken (the placeholder must show instead). - AC-8: start one template 3 times and watch it move up in Most popular after a reload. - AC-10: after Customize → edit → Create & Start, the task has the edited text, `starts_90d` rose by exactly 1, and the body images render without being re-uploaded (check the network tab: no upload to `/attachments`). - AC-11 and the §4 viewer: use the two `org/console/` test logins this child creates. - AC-16: an org with no tasks shows at most 6 cards; an org with tasks shows none. - The ui-style-guide gains the Gallery archetype section, and the context checker is green. - Vitest covers GalleryCard (clamp, placeholder, `may_start` hiding) and the sectioning and order logic.

Activity

  • Draft
  • Ready