route-makeover

star 243

Scan an entire SvelteKit project's routes and generate a full design-makeover epic — a dependency-wired task tree that runs the impeccable treatment (critique → audit → findings-driven fixes → polish → re-critique) against every high-value route, gated behind a shared design-system foundation phase. Use when the user wants to redesign/overhaul the whole app's UI, give all routes the impeccable treatment, plan a design firm's work across the app, or turn a route sweep into actionable tasks. Pairs with the impeccable skill and jat:tasktree.

joewinke By joewinke schedule Updated 6/13/2026

name: route-makeover description: Scan an entire SvelteKit project's routes and generate a full design-makeover epic — a dependency-wired task tree that runs the impeccable treatment (critique → audit → findings-driven fixes → polish → re-critique) against every high-value route, gated behind a shared design-system foundation phase. Use when the user wants to redesign/overhaul the whole app's UI, give all routes the impeccable treatment, plan a design firm's work across the app, or turn a route sweep into actionable tasks. Pairs with the impeccable skill and jat:tasktree. version: 1.0.0 user-invocable: true argument-hint: "[--tiers 1-4] [--root src/routes]"

Turn a whole SvelteKit app into a structured design makeover: scan every route → cluster + tier them → write a PRD → materialize an impeccable-treatment epic (epic + foundation tasks + one task per route cluster, fully dependency-wired).

This skill orchestrates two others: the impeccable design skill (the per-route treatment) and jat:tasktree (the epic/task materialization). It does not redesign routes itself — it produces the plan and the tasks that do.

When to use

The user wants the whole app (or a tier of it) redesigned, not a single screen. Signals: "give all our routes the design treatment", "full design makeover", "plan the redesign across the app", "turn our routes into a design epic", "hand the design firm a task tree".

For a single page/feature, use $impeccable craft/shape/critique directly instead.

Preflight (gates — pass before generating anything)

Gate Check If fail
SvelteKit src/routes/ (or --root) exists Ask for the routes root; abort if not a SvelteKit app.
impeccable The impeccable skill is reachable (vendored at .agents/skills/impeccable/ or installed) Tell the user the makeover depends on it; stop.
Context A real design-authority exists: PRODUCT.md/DESIGN.md, or the project's own equivalent (a design-system doc + its token/state-color/component sources). If none, run $impeccable teach/document (or hand-author from the existing token/component files), then resume. Becomes F1 regardless — but you need enough now to set register + archetype.
Tasks jt CLI available (run bare jt for usage — note jt create has no --help, it would make a junk task). Tell the user tasks can't be created; offer to emit the PRD only.

Procedure

1. Scan

Run the bundled scanner from the project root:

node .agents/skills/route-makeover/scripts/scan-routes.mjs --plan docs/route-plan.json

It writes docs/ROUTES.md (the inventory) and docs/route-plan.json (structured clusters with a proposed tier ∈ 1–4 and register ∈ brand|product per cluster). Read the plan JSON in full. Counts and tier distribution are in .counts.

Flags: --root <dir> (non-default routes path), --out <md> (inventory path), --no-md (skip the inventory), --plan <path> (JSON output; omit → stdout).

2. Plan with judgment

First name the project archetype — it decides register, tier meaning, and guardrails, and the scanner cannot infer it:

  • Brand / marketing SaaS (landing + app; a JST-template project): the scanner's brand first-impression + money-path tiers apply; register is a brand/product mix; use the JST-style guardrails (white-label token-only, multi-theme proof, test on the real deployment).
  • Internal tool / dashboard / admin / dev-tooling (e.g. the JAT IDE itself): there are no marketing/brand/checkout surfaces — register is essentially all product, and the scanner's brand/money tiers are meaningless. It will dump almost everything into one tier-4 "Other" bucket and mislabel entry/search pages as fake tier-1 "brand". Throw out its tiers and re-tier by operator value: T1 daily-drivers → T2 frequent tools → T3 regular tools → T4 secondary. Guardrails come from the project's own design system, not a white-label token policy (see reference/treatment.md → "Adapting guardrails per archetype").

Then apply judgment to the clusters themselves — the scanner's clustering is a proposal, not the answer:

  • Re-cluster; don't trust the buckets. For dashboard/internal apps the scanner emits one giant "Other" cluster — decompose it by functional domain (the screens an operator thinks of together) and by shared-component leverage (routes rendering the same core components redesign together). Ground this in what each route actually is — a quick read of each +page.svelte (purpose, LOC, primary components) beats guessing; an Explore/general-purpose agent can characterize all routes in one fan-out.
  • Merge clusters that share a flow; split any cluster too big for one 2–8h session. Size each so one agent can hold its diagnose→fix loop in context.
  • Confirm register per cluster against the archetype + any PRODUCT.md register field; override per surface (a marketing hero inside a product app is still brand).
  • Drop redirect-only / stub / deprecated / already-perfect routes — they have no design surface (the scanner may still list them; e.g. /-redirect, legacy /old → /new, catch-all 404).

Then confirm scope with the user via AskUserQuestion (skip only if they already specified): which tiers to materialize now (1–4 full, 1–2 first, or 1 pilot), and confirm the one-task-per-cluster granularity (the right default — keeps the diagnose→fix loop in one agent's context; the per-command alternative fragments it).

3. Write the PRD

Using reference/treatment.md (the treatment sequence, register policy, guardrails, DoD, foundation phase, and PRD template), write the PRD to docs/prds/<slug>-design-treatment.mdor match the project's existing PRD location/naming convention if it has one (e.g. the JAT IDE keeps PRDs at ide/docs/prd-*.md). Fill the template from the plan + scope answers. The per-cluster task list is the (judgment-adjusted) clusters, ordered by tier. Always include the 3 foundation tasks (F1/F2/F3).

Adapt the guardrails, DoD, and foundation sections to the archetype — see reference/treatment.md → "Adapting guardrails per archetype". JST defaults (token-only/no-oklch-literals, multi-theme white-label proof, jatui reuse, test on the real deployment) are for brand SaaS; an internal tool swaps in its own design system as the authority and tests on its own dev server. State the swap explicitly in the PRD so cluster agents don't apply the wrong policy.

4. Materialize the epic (tasktree)

Follow jat:tasktree. The mechanics below are battle-tested — jt's task-tree behavior has sharp edges that silently corrupt the tree:

⚠️ jt gotchas:

  • jt create has no --helpjt create --help makes a junk task titled "--help". Run bare jt for usage.
  • Epic children get DOTTED ids <epic>.N (e.g. jat-65q2g.4). jt create --parent E … prints Created jat-65q2g.4: <title>. Capture the id by parsing that line — not by grepping jat-[a-z0-9]+, which stops at the dot and hands you the parent every time. jt create --json dumps the whole object with no clean top-level id line, so the plain-output parse is easier.
  • jt delete <id> with the un-dotted epic id deletes the epic (orphaning its .N children under a dead prefix). Always delete the full dotted id, and re-jt show the epic after any delete.
  • On postgres-backed projects, --parent sets the parent pointer but does not wire epic←child dependency edges — wire every edge manually.

Recipe (capture ids to a temp file — shell state does not persist across separate tool calls; sleep between creates to dodge create-flake):

idof(){ sed -n 's/^Created \([^:]*\):.*/\1/p' | head -1; }   # robust: handles dotted child ids
# 1. Epic
E=$(jt create "Epic: Design makeover — <project> routes" --type epic --priority 1 \
      --labels "design,impeccable,frontend" --description "…PRD path + 'stays open, blocked by all children'…" 2>&1 | idof)
echo "E=$E" > /tmp/makeover-ids.env
# 2. Children: F1,F2,F3 (P0) then one per cluster (tier 1–3 → P1, tier 4 → P2). Each --parent "$E".
#    --description embeds: routes + register + condensed treatment footer (sequence + guardrails + DoD
#    from reference/treatment.md; point to the PRD for the canonical version).
out=$(jt create "F1 — …" --type task --priority 0 --parent "$E" --description "…" 2>&1)
echo "F1=$(printf '%s' "$out" | idof)" >> /tmp/makeover-ids.env       # …repeat for F2,F3,C1…Cn (sleep ~0.4)
# 3. Wire ALL deps manually  (jt dep add A B  ==  "A depends on B"):
source /tmp/makeover-ids.env
for c in $F1 $F2 $F3 $C1 … $Cn; do jt dep add "$E" "$c"; done          # epic blocked by EVERY child
jt dep add "$F2" "$F1"; jt dep add "$F3" "$F1"                         # F2,F3 → F1
for c in $C1 … $Cn; do jt dep add "$c" "$F2"; jt dep add "$c" "$F3"; done  # each cluster → F2,F3

Do not close the epic. It stays open + blocked by all children; it becomes the cross-cluster consistency/UAT verification task when they complete.

5. Verify + report

source /tmp/makeover-ids.env
jt show "$E" --json     # depends_on must list EVERY child (count == number of children)
jt show "$F1" --json    # depends_on == [] (F1 is the only ready task)
jt show "$C1" --json    # depends_on == [F2, F3]

Verify gating from each task's depends_on (entries look like {id,type:"blocks",…}), not from jt ready:

⚠️ On postgres, jt ready returns all open tasks (dependency filtering is SQLite-only), so it cannot confirm "only F1 is ready". Trust jt show --jsondepends_on instead. (Reads can lag the cache briefly; re-check if a freshly-wired edge is missing.)

Print the tasktree banner: total tasks, P0/P1/P2 counts, the F1 → {F2,F3} → clusters dependency graph, and the execution strategy (F1 solo → F2+F3 parallel → fan out by tier). Tell the user to start at E.1 (/jat:start E.1).

Notes

  • One task per cluster, full sequence embedded is the default and the best-product choice. Resist one-task-per-command: critique emits the fix commands the same session runs, and splitting loses that context across sessions.
  • Foundation gates routes because shared-system work — tokens, the component primitives, the app shells — propagates to every route. Never let per-route polish run before F2/F3.
  • Shared primitives carry the foundation. On component-heavy apps a handful of primitives (cards, tables, badges, the skeleton/loading family) render across many routes, so F2 fixing them improves a dozen routes at once — per-cluster tasks then become mostly layout/IA/state work, not rebuilds. Lean on this when sizing clusters, and enumerate those primitives explicitly in F2.
  • $impeccable may be vendored as individual skills. Some projects (e.g. the JAT IDE) install the family as standalone /critique, /audit, /polish, /typeset, … with no $impeccable umbrella — invoke each directly. Check what's actually installed before writing commands into task descriptions.
  • The scanner excludes API endpoints, cron, webhooks, feeds/manifests/health, and component demo galleries — those have no design surface. It does not detect redirect/stub +page.sveltes (e.g. a goto() redirect) — you must drop those in step 2.
  • Re-running the scanner is safe and idempotent; regenerate docs/ROUTES.md after routes change.
Install via CLI
npx skills add https://github.com/joewinke/jat --skill route-makeover
Repository Details
star Stars 243
call_split Forks 26
navigation Branch main
article Path SKILL.md
More from Creator