skip to content
$registry / workers

kanban

v0.1.22

File-backed kanban board — tickets, threaded comments, agent assignment, the kanban:change and kanban:comment trigger types, and an injectable console board with agent profiles for planning and review.

worker
iiiverified
247 installs64 in 7d14 today
install
$iii trigger compose::add worker=kanban@0.1.22
binarylicense: Apache-2.0agentsboardconsole-uikanbantickets
  • macOS: arm64 · x64
  • Linux: arm64 · armv7 · x64
  • Windows: arm64 · x64

exact versions are immutable; binary and bundle artifacts are digest-pinned.

skill doc

react

how-to
skills/frontend/react.md

React

Docs https://react.dev/learn · reference https://react.dev/reference/react. Read the project's installed version's docs when the two disagree — the API surface has moved (React 19 in particular).

The mental model, in three sentences

  1. Render is pure and repeatable. Given the same props and state it produces the same JSX; it must not call functions, mutate things, or start network work.
  2. State is a snapshot per render. Setting it schedules a new render; the variable you just read is the old value for the rest of this one.
  3. Effects synchronize with external systems — sockets, DOM APIs, subscriptions, timers. They are not the place for derived data, event responses, or initialization.

Rules that catch most bugs

  • Hooks at the top level of a component or hook, unconditional. No hooks in loops, conditions, or after an early return.
  • Keys are identity. key={index} on a list that reorders or filters corrupts state. Use a stable id from the data.
  • StrictMode double-invokes render and remounts effects in dev. That is a feature: it exposes missing cleanup and non-idempotent effects. Fix the code; do not remove StrictMode.
  • Never mutate props or state. Copy, then set.
  • Do not lie about dependencies. A stale-closure bug is a missing dep or a non-memoized function. Fix the dependency, do not silence the lint rule.

State placement

  • Compute what you can; do not store it. If it is derivable from props or state, derive it during render. Mirroring creates a second source of truth that drifts.
  • Colocate, then lift. Keep state in the closest component that needs it; lift only when two siblings must agree, and lift to their closest common parent, not to the top of the app.
  • One state variable per concern. useReducer when several fields change together or the next value depends on the previous (setCount(c => c + 1) — batching means the object form is often wrong in a burst of events).
  • Reset state by changing key, not by an effect.
    is the correct "reset on entity change" and also resets every child.
  • Server data is not React state. Cache it (TanStack Query or equivalent); keeping a copy in useState guarantees stale UI and double-loading.
  • URL is state. Filters, tabs, pagination, and selection belong in search params so they survive reload, back/forward, and sharing.

Effects

useEffect(() => {
  const ac = new AbortController()
  let active = true
  void (async () => {
    const data = await fetchThing(id, { signal: ac.signal })
    if (active) setData(data)
  })()
  return () => { active = false; ac.abort() }
}, [id])
  • Every effect that starts something must clean it up. Timers, listeners, subscriptions, sockets, in-flight requests.
  • Guard against races (active flag, AbortController) whenever the dep can change mid-flight — otherwise a slow response overwrites a fast one.
  • useLayoutEffect only when you must read or write layout before paint (measuring, scroll restoration). It blocks paint; prefer useEffect.
  • Effects are the wrong tool for: responding to a click, deriving state, fetching as a general pattern when a data layer exists, or reacting to a prop you could compute from.

Refs, context, and escape hatches

  • Refs hold values that do not affect rendering (timers, DOM nodes, previous values). Do not read or write them during render — only in effects and handlers.
  • useImperativeHandle when a parent genuinely needs a handle on a child's behavior.
  • Context is for low-frequency values (theme, current user, the iii client). Split it: a context whose value object is rebuilt every render re-renders every consumer. Pair a reducer with a context and expose state and dispatch in two separate contexts.
  • useSyncExternalStore for subscribing to a store outside React (including the iii client's connection state) — it is the correct primitive, and hand-rolled subscription effects get it wrong under concurrent rendering.

Composition

  • children as a prop breaks prop-drilling without context.
  • Slots () beat boolean flags that switch internal branches into a second component.
  • Compound components (, , ) share state through context; the parent owns the invariant.
  • A component with 6+ boolean props is 2^6 configurations nobody tests. Split on the axis that actually varies.
  • Hoist state to the leaf that needs it, and keep lists virtualized when they exceed a few hundred rows.

Suspense, transitions, errors

  • + React.lazy for route-level code splitting; the fallback is a real UI state, not a spinner on a blank screen.
  • useTransition / startTransition for updates that may be expensive (tab switches, filtered lists) so typing stays responsive. useDeferredValue when a value is the slow part (a query fed to a heavy list).
  • Error boundaries are still the mechanism for render errors — a class component or react-error-boundary. An async rejection is not caught by a boundary unless you rethrow it in render or route it through the data layer.
  • use() (React 19) unwraps a promise or context in render, but only inside a Suspense boundary.

React 19 notes: refs are props (, no forwardRef), is itself usable as the provider, useActionState / useOptimistic / cover form pending and optimistic UI, and document metadata (</code>, <code class="readme-inline-code"><meta></code>) can render inline. Check the installed version before using any of these.</p> <h2 id="performance-measure-do-not-decorate" class="scroll-mt-20">Performance: measure, do not decorate</h2> <p>Order of leverage:</p> <ol> <li><strong>Do less work.</strong> Ship fewer/smaller deps, split routes, virtualize long lists, paginate.</li> <li><strong>Stop unnecessary re-renders</strong> — but only after profiling. React DevTools' Profiler shows which component re-rendered and why.</li> <li><strong>Then memoize.</strong> <code class="readme-inline-code">memo</code>, <code class="readme-inline-code">useMemo</code>, <code class="readme-inline-code">useCallback</code> cost memory and comparison time; they are net-negative on cheap components with stable inputs and net-positive on expensive subtrees fed by unstable objects.</li> <li><strong>Never memoize to fix a bug.</strong> A correct dependency array is the fix; <code class="readme-inline-code">useMemo</code> is only an optimization.</li> </ol> <ul> <li>Keep the tree shallow; a context value changing high up re-renders the world.</li> <li>Split a hot component so the state change lands low in the tree.</li> <li>Long lists: virtualize (TanStack Virtual, <code class="readme-inline-code">react-window</code>) — rendering 5000 rows is the cost, not the state.</li> <li>Avoid layout thrash: batch DOM reads and writes; never read <code class="readme-inline-code">getBoundingClientRect()</code> in the same frame as a write loop.</li> </ul> <h2 id="accessibility-is-part-of-the-component" class="scroll-mt-20">Accessibility is part of the component</h2> <p>Semantic elements before ARIA, a real <code class="readme-inline-code"><button></code> before a clickable <code class="readme-inline-code"><div></code>, labels bound to inputs, focus moved deliberately on route and dialog changes, and no interaction that only works with a mouse. It is far cheaper to build in than to retrofit.</p> <h2 id="anti-patterns-to-refuse" class="scroll-mt-20">Anti-patterns to refuse</h2> <ul> <li>Deriving state in an effect and storing it (<code class="readme-inline-code">useEffect(() => setX(a + b), [a, b])</code>).</li> <li>Syncing props to state with an effect.</li> <li>One giant context holding a mutable object.</li> <li>Fetching in an effect when a data layer exists.</li> <li><code class="readme-inline-code">useMemo</code> everywhere as a habit.</li> <li>Index keys on sortable/filterable lists.</li> <li>Suppressing the exhaustive-deps lint rule instead of fixing the dependency.</li> <li>Copying a library's internal markup instead of the library.</li> </ul> </div></div></section></div><aside class="flex flex-col gap-y-4 @4xl:sticky @4xl:top-4 @4xl:self-start @4xl:max-h-[calc(100dvh-2rem)] @4xl:overflow-y-auto"><div class="border border-rule bg-bg"><div class="bg-panel px-3.5 py-2.5 border-b border-rule"><span class="font-mono text-[11px] font-medium uppercase tracking-[0.18em] text-ink-faint">details</span></div><div class="p-4 flex flex-col gap-y-2.5"><div class="flex items-baseline justify-between font-mono text-[13px] gap-x-3"><span class="text-ink-faint shrink-0 uppercase tracking-[0.06em] text-[11px]">version</span><span class="text-ink truncate text-right lowercase tabular-nums">v0.1.22</span></div><div class="flex items-baseline justify-between font-mono text-[13px] gap-x-3"><span class="text-ink-faint shrink-0 uppercase tracking-[0.06em] text-[11px]">type</span><span class="text-ink truncate text-right lowercase ">binary</span></div><div class="flex items-baseline justify-between font-mono text-[13px] gap-x-3"><span class="text-ink-faint shrink-0 uppercase tracking-[0.06em] text-[11px]">license</span><span class="text-ink truncate text-right ">Apache-2.0</span></div><div class="flex items-baseline justify-between font-mono text-[13px] gap-x-3 min-w-0"><span class="text-ink-faint shrink-0 uppercase tracking-[0.06em] text-[11px]">repo</span><a href="https://github.com/iii-hq/workers" target="_blank" rel="noreferrer" class="inline-flex items-center gap-x-1 font-mono text-[13px] text-ink lowercase hover:text-accent transition-colors min-w-0 text-right justify-end"><span class="truncate">iii-hq/workers</span><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-external-link size-3 shrink-0" aria-hidden="true"><path d="M15 3h6v6"></path><path d="M10 14 21 3"></path><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path></svg></a></div></div></div><section id="used-in-kits" class="border border-rule bg-bg scroll-mt-20" aria-labelledby="used-in-kits-title"><div class="flex items-baseline justify-between bg-panel px-3.5 py-2.5 border-b border-rule"><span id="used-in-kits-title" class="font-mono text-[11px] font-medium uppercase tracking-[0.18em] text-ink-faint">used in <!-- -->1<!-- --> <!-- -->kit</span></div><ul class="divide-y divide-rule-2"><li><a class="group flex items-start gap-x-2.5 px-3.5 py-2.5 hover:bg-panel transition-colors" href="/kits/iii/deepwork"><svg viewBox="0 0 16 16" aria-hidden="true" focusable="false" class="size-4 shrink-0 text-type-kit mt-0.5" fill="none" stroke="currentColor" stroke-width="1.25" stroke-linejoin="miter" stroke-linecap="square"><path d="M2 5h2.9a1.9 1.9 0 1 1 3.2 0H11v2.9a1.9 1.9 0 1 1 0 3.2V14H8.1a1.6 1.6 0 0 0-3.2 0H2Z"></path></svg><span class="min-w-0 flex flex-col"><span class="font-mono text-[13px] text-ink truncate group-hover:underline underline-offset-4"><span class="text-ink-faint">iii<!-- -->/</span>deepwork</span><span class="font-mono text-[11px] uppercase tracking-[0.06em] text-ink-ghost tabular-nums">v<!-- -->0.2.1<!-- --> · <!-- -->6<!-- --> <!-- -->profiles</span></span></a></li></ul></section><div class="border border-rule bg-bg"><div class="bg-panel px-3.5 py-2.5 border-b border-rule"><span class="font-mono text-[11px] font-medium uppercase tracking-[0.18em] text-ink-faint">skills</span></div><div class="max-h-[min(60dvh,28rem)] overflow-y-auto"><section aria-labelledby="skills-tree-kanban"><div id="skills-tree-kanban" class="flex items-baseline justify-between px-3.5 py-2 bg-paper-2 border-b border-rule-2"><span class="font-mono text-[11px] font-medium uppercase tracking-[0.06em] text-ink-faint">files</span><span class="font-mono text-[11px] uppercase tracking-[0.06em] text-ink-ghost tabular-nums">27</span></div><nav aria-label="skill files" class="px-3 pt-2 pb-3"><ul class="flex flex-col gap-y-0.5"><li style="padding-left:0"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=SKILL.md&version=0.1.22">SKILL.md</a></li><li style="padding-left:0" class="min-w-0"><div class="font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase text-ink-faint select-none">agents<!-- -->/</div><ul class="flex flex-col gap-y-0.5 mt-0.5"><li style="padding-left:10px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=agents%2Fade-worker-designer.md&version=0.1.22">ade-worker-designer.md</a></li><li style="padding-left:10px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=agents%2Fbackend-engineer.md&version=0.1.22">backend-engineer.md</a></li><li style="padding-left:10px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=agents%2Ffrontend-engineer.md&version=0.1.22">frontend-engineer.md</a></li><li style="padding-left:10px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=agents%2Fproduct-manager.md&version=0.1.22">product-manager.md</a></li><li style="padding-left:10px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=agents%2Ftech-lead.md&version=0.1.22">tech-lead.md</a></li></ul></li><li style="padding-left:0" class="min-w-0"><div class="font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase text-ink-faint select-none">skills<!-- -->/</div><ul class="flex flex-col gap-y-0.5 mt-0.5"><li style="padding-left:10px" class="min-w-0"><div class="font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase text-ink-faint select-none">ade-worker-design<!-- -->/</div><ul class="flex flex-col gap-y-0.5 mt-0.5"><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Fade-worker-design&version=0.1.22">index.md</a></li><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Fade-worker-design%2Fconsole-design.md&version=0.1.22">console-design.md</a></li><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Fade-worker-design%2Fconsole-injectable-ui.md&version=0.1.22">console-injectable-ui.md</a></li><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Fade-worker-design%2Fpatterns.md&version=0.1.22">patterns.md</a></li></ul></li><li style="padding-left:10px" class="min-w-0"><div class="font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase text-ink-faint select-none">frontend<!-- -->/</div><ul class="flex flex-col gap-y-0.5 mt-0.5"><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Ffrontend&version=0.1.22">index.md</a></li><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Ffrontend%2Ffrontend-testing.md&version=0.1.22">frontend-testing.md</a></li><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Ffrontend%2Fiii-browser-sdk.md&version=0.1.22">iii-browser-sdk.md</a></li><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors bg-ink text-bg" href="/workers/kanban?tab=skills&skill=skills%2Ffrontend%2Freact.md&version=0.1.22">react.md</a></li><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Ffrontend%2Ftanstack-query.md&version=0.1.22">tanstack-query.md</a></li><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Ffrontend%2Ftanstack-router.md&version=0.1.22">tanstack-router.md</a></li><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Ffrontend%2Fvite.md&version=0.1.22">vite.md</a></li><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Ffrontend%2Fweb-accessibility.md&version=0.1.22">web-accessibility.md</a></li><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Ffrontend%2Fweb-performance.md&version=0.1.22">web-performance.md</a></li></ul></li><li style="padding-left:10px" class="min-w-0"><div class="font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase text-ink-faint select-none">iii-node<!-- -->/</div><ul class="flex flex-col gap-y-0.5 mt-0.5"><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Fiii-node&version=0.1.22">index.md</a></li><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Fiii-node%2Fconfiguration.md&version=0.1.22">configuration.md</a></li></ul></li><li style="padding-left:10px" class="min-w-0"><div class="font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase text-ink-faint select-none">tickets<!-- -->/</div><ul class="flex flex-col gap-y-0.5 mt-0.5"><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Ftickets&version=0.1.22">index.md</a></li><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Ftickets%2Facceptance-review.md&version=0.1.22">acceptance-review.md</a></li><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Ftickets%2Ffeature-planning.md&version=0.1.22">feature-planning.md</a></li><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Ftickets%2Fkanban-tickets.md&version=0.1.22">kanban-tickets.md</a></li><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Ftickets%2Fticket-orchestration.md&version=0.1.22">ticket-orchestration.md</a></li><li style="padding-left:20px"><a class="block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink" href="/workers/kanban?tab=skills&skill=skills%2Ftickets%2Fticket-worker.md&version=0.1.22">ticket-worker.md</a></li></ul></li></ul></li></ul></nav></section></div></div><div class="border border-rule bg-bg"><div class="bg-panel px-3.5 py-2.5 border-b border-rule"><span class="font-mono text-[11px] font-medium uppercase tracking-[0.18em] text-ink-faint">author</span></div><div class="p-4 flex flex-col gap-y-2.5"><div class="flex items-center gap-x-2 font-mono text-[13px]"><img src="https://iii.dev/docs/_mintlify/favicons/motiadev/AFkVbz_UcSL_5jsm/_generated/favicon/apple-touch-icon.png" alt="" class="size-5 object-cover"/><span class="text-ink lowercase">iii</span><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-badge-check size-3.5 text-accent" aria-hidden="true"><path d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z"></path><path d="m9 12 2 2 4-4"></path></svg></div></div></div></aside></div></div></div><!--$--><!--/$--></main><footer class="border-t border-rule bg-bg"><div class="flex items-center justify-between flex-wrap gap-x-6 gap-y-3 px-9 py-4.5"><div class="inline-flex items-center gap-x-4"><a aria-label="iii worker — registry home" class="inline-flex items-center gap-x-2 text-ink" href="/"><svg viewBox="0 0 1075.74 1075.69" aria-hidden="true" focusable="false" class="size-[14px]" fill="currentColor"><rect x="0" y="0.05" width="268.94" height="268.94"></rect><rect x="403.4" y="0.05" width="268.94" height="268.94"></rect><rect x="806.81" y="0.05" width="268.94" height="268.94"></rect><rect x="0" y="403.45" width="268.94" height="672.24"></rect><rect x="403.4" y="403.45" width="268.94" height="672.24"></rect><rect x="806.81" y="403.45" width="268.94" height="672.24"></rect></svg><span class="font-mono text-[13px] font-medium tracking-[-0.02em] lowercase">iii / worker</span></a><a href="https://github.com/iii-hq/iii" target="_blank" rel="noopener noreferrer" aria-label="iii-hq/iii on GitHub — 18,845 stars" class="inline-flex shrink-0 items-center gap-x-2 border border-rule px-2.5 py-1 font-mono text-[13px] text-ink-faint transition-colors hover:text-ink sm:hidden"><svg viewBox="0 0 16 16" aria-hidden="true" focusable="false" class="size-3.5 shrink-0" fill="currentColor"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8Z"></path></svg><span class="hidden sm:inline lowercase">stars</span><span class="tabular-nums text-ink" aria-hidden="true">18.8k</span></a></div><nav aria-label="footer" class="flex items-center flex-wrap gap-x-6 gap-y-2"><a href="https://iii.dev" target="_blank" rel="noreferrer" class="inline-flex items-center gap-x-1 font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors">iii.dev<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-external-link size-3 shrink-0" aria-hidden="true"><path d="M15 3h6v6"></path><path d="M10 14 21 3"></path><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path></svg></a><a href="https://iii.dev/docs" target="_blank" rel="noreferrer" class="inline-flex items-center gap-x-1 font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors">docs<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-external-link size-3 shrink-0" aria-hidden="true"><path d="M15 3h6v6"></path><path d="M10 14 21 3"></path><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path></svg></a><a class="font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors" href="/collections">collections</a><a class="font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors" href="/leaderboard">leaderboard</a><a class="font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors" href="/publish">publish</a><a class="font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors" href="/badge-preview">badge preview</a><a href="https://discord.gg/iiidev" target="_blank" rel="noreferrer" class="inline-flex items-center gap-x-1 font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors">discord<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-external-link size-3 shrink-0" aria-hidden="true"><path d="M15 3h6v6"></path><path d="M10 14 21 3"></path><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path></svg></a><a href="https://github.com/iii-hq/iii" target="_blank" rel="noreferrer" class="inline-flex items-center gap-x-1 font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors">github<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-external-link size-3 shrink-0" aria-hidden="true"><path d="M15 3h6v6"></path><path d="M10 14 21 3"></path><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path></svg></a></nav></div></footer></div></div><script src="/_next/static/chunks/0b_t-9oq5.7ee.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n3:I[20685,[\"/_next/static/chunks/0wcm0wpln.-h..js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\"],\"SiteHeader\"]\n5:I[90280,[\"/_next/static/chunks/04ylibgf-0e6d.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"/_next/static/chunks/0.vqct1a~k736.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\"],\"default\"]\n6:I[69616,[\"/_next/static/chunks/04ylibgf-0e6d.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"/_next/static/chunks/0.vqct1a~k736.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\"],\"default\"]\n7:I[46610,[\"/_next/static/chunks/0wcm0wpln.-h..js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"/_next/static/chunks/0-3vzlyvl.dxh.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\"],\"\"]\ne:I[50609,[\"/_next/static/chunks/0wcm0wpln.-h..js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"/_next/static/chunks/02eqejg_b4k2y.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\"],\"default\"]\n11:I[41074,[\"/_next/static/chunks/0wcm0wpln.-h..js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"/_next/static/chunks/0-3vzlyvl.dxh.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\"],\"default\"]\n13:I[51557,[\"/_next/static/chunks/04ylibgf-0e6d.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"/_next/static/chunks/0.vqct1a~k736.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\"],\"OutletBoundary\"]\n14:\"$Sreact.suspense\"\n17:I[51557,[\"/_next/static/chunks/04ylibgf-0e6d.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"/_next/static/chunks/0.vqct1a~k736.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\"],\"ViewportBoundary\"]\n19:I[51557,[\"/_next/static/chunks/04ylibgf-0e6d.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"/_next/static/chunks/0.vqct1a~k736.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\"],\"MetadataBoundary\"]\n:HL[\"/_next/static/chunks/05q2cs4d4qqrk.css?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"style\"]\n:HL[\"/_next/static/media/387ee14c0e0fe675-s.p.16njqniuj6huf.woff2?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n2:[\"$\",\"iframe\",null,{\"src\":\"https://www.googletagmanager.com/ns.html?id=GTM-N8DCTFB8\",\"height\":\"0\",\"width\":\"0\",\"style\":{\"display\":\"none\",\"visibility\":\"hidden\"},\"title\":\"Google Tag Manager\"}]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"workers\",\"kanban?skill=skills%2Ffrontend%2Freact.md\u0026tab=skills\u0026version=0.1.22\"],\"q\":\"?skill=skills%2Ffrontend%2Freact.md\u0026tab=skills\u0026version=0.1.22\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"workers\",{\"children\":[[\"slug\",\"kanban\",\"d\",null],{\"children\":[\"__PAGE__?{\\\"skill\\\":\\\"skills/frontend/react.md\\\",\\\"tab\\\":\\\"skills\\\",\\\"version\\\":\\\"0.1.22\\\"}\",{}]}]}]},\"$undefined\",\"$undefined\",16],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/05q2cs4d4qqrk.css?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/0wcm0wpln.-h..js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"className\":\"chivo_mono_90504305-module__244I6q__variable antialiased\",\"data-theme\":\"light\",\"suppressHydrationWarning\":true,\"children\":[\"$\",\"body\",null,{\"className\":\"bg-bg text-ink font-sans min-h-full flex flex-col\",\"children\":[[[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"\\n try {\\n var stored = localStorage.getItem('iii-theme');\\n if (stored === 'dark' || stored === 'light') {\\n document.documentElement.dataset.theme = stored;\\n } else {\\n document.documentElement.dataset.theme = 'light';\\n }\\n } catch (_) {\\n document.documentElement.dataset.theme = 'light';\\n }\\n\"}}],[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"\\n (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':\\n new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],\\n j=d.createElement(s),dl=l!='dataLayer'?'\u0026l='+l:'';j.async=true;j.src=\\n 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);\\n })(window,document,'script','dataLayer','GTM-N8DCTFB8');\\n\"}}]],[\"$\",\"noscript\",null,{\"children\":\"$2\"}],[\"$\",\"div\",null,{\"className\":\"mx-auto w-full max-w-[1200px] @container border-x border-rule min-h-screen bg-bg flex flex-col\",\"children\":[[\"$\",\"a\",null,{\"href\":\"#main-content\",\"className\":\"sr-only focus:not-sr-only focus:absolute focus:left-4 focus:top-4 focus:z-50 focus:bg-ink focus:text-bg focus:px-3 focus:py-2 focus:font-mono focus:text-[13px] lowercase\",\"children\":\"skip to content\"}],[\"$\",\"$L3\",null,{\"githubStars\":\"$L4\"}],[\"$\",\"div\",null,{\"className\":\"flex-1 overflow-x-clip flex flex-col\",\"children\":[[\"$\",\"main\",null,{\"id\":\"main-content\",\"className\":\"flex-1\",\"tabIndex\":-1,\"children\":[\"$\",\"$L5\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L6\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"div\",null,{\"className\":\"page-transition\",\"children\":[\"$\",\"div\",null,{\"className\":\"flex items-end justify-between flex-wrap gap-x-6 gap-y-4 px-9 py-12\",\"children\":[[\"$\",\"div\",null,{\"className\":\"min-w-0\",\"children\":[[\"$\",\"div\",null,{\"className\":\"font-mono text-[11px] uppercase tracking-[0.06em] text-ink-faint mb-3\",\"children\":[\"$\",\"span\",null,{\"className\":\"font-mono text-accent\",\"children\":[\"$$\",[\"$\",\"span\",null,{\"className\":\"text-ink ml-2\",\"children\":\"error\"}]]}]}],[\"$\",\"div\",null,{\"className\":\"flex items-baseline flex-wrap gap-x-3 gap-y-1\",\"children\":[[\"$\",\"h1\",null,{\"className\":\"font-mono text-[28px] font-medium tracking-[-0.01em] text-ink lowercase\",\"children\":[\"$\",\"span\",null,{\"className\":\"inline-flex items-baseline gap-x-2 tabular-nums\",\"children\":[\"404\",[\"$\",\"span\",null,{\"aria-hidden\":true,\"className\":\"blink inline-block w-[6px] h-[13px] bg-ink align-middle translate-y-[1px]\"}]]}]}],\"$undefined\",null]}],[\"$\",\"p\",null,{\"className\":\"mt-3 font-mono text-[14px] leading-[1.7] text-ink-faint max-w-[60ch] lowercase\",\"children\":\"that worker is not in the registry. it may have been renamed or never published.\"}]]}],[\"$\",\"div\",null,{\"className\":\"flex items-center gap-x-3\",\"children\":[\"$\",\"$L7\",null,{\"href\":\"/\",\"className\":\"inline-flex items-center justify-center gap-x-2 whitespace-nowrap font-mono lowercase rounded-none transition-[background-color,color,border-color,transform] duration-150 ease-out focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-accent disabled:pointer-events-none disabled:opacity-40 select-none active:scale-[0.97] motion-reduce:active:scale-100 bg-ink text-bg border border-ink hover:bg-bg hover:text-ink h-9 px-5 text-[13px]\",\"children\":\"back to registry\"}]}]]}]}],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}],\"$L8\"]}]]}]]}]}]]}],{\"children\":[\"$L9\",{\"children\":[\"$La\",{\"children\":[\"$Lb\",{},null,false,null]},null,false,\"$@c\"]},null,false,\"$@c\"]},null,false,null],\"$Ld\",false]],\"m\":\"$undefined\",\"G\":[\"$e\",[\"$Lf\"]],\"S\":false,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"8:[\"$\",\"footer\",null,{\"className\":\"border-t border-rule bg-bg\",\"children\":[\"$\",\"div\",null,{\"className\":\"flex items-center justify-between flex-wrap gap-x-6 gap-y-3 px-9 py-4.5\",\"children\":[[\"$\",\"div\",null,{\"className\":\"inline-flex items-center gap-x-4\",\"children\":[[\"$\",\"$L7\",null,{\"href\":\"/\",\"aria-label\":\"iii worker — registry home\",\"className\":\"inline-flex items-center gap-x-2 text-ink\",\"children\":[[\"$\",\"svg\",null,{\"viewBox\":\"0 0 1075.74 1075.69\",\"aria-hidden\":\"true\",\"focusable\":\"false\",\"className\":\"size-[14px]\",\"fill\":\"currentColor\",\"children\":[[\"$\",\"rect\",null,{\"x\":\"0\",\"y\":\"0.05\",\"width\":\"268.94\",\"height\":\"268.94\"}],[\"$\",\"rect\",null,{\"x\":\"403.4\",\"y\":\"0.05\",\"width\":\"268.94\",\"height\":\"268.94\"}],[\"$\",\"rect\",null,{\"x\":\"806.81\",\"y\":\"0.05\",\"width\":\"268.94\",\"height\":\"268.94\"}],[\"$\",\"rect\",null,{\"x\":\"0\",\"y\":\"403.45\",\"width\":\"268.94\",\"height\":\"672.24\"}],[\"$\",\"rect\",null,{\"x\":\"403.4\",\"y\":\"403.45\",\"width\":\"268.94\",\"height\":\"672.24\"}],[\"$\",\"rect\",null,{\"x\":\"806.81\",\"y\":\"403.45\",\"width\":\"268.94\",\"height\":\"672.24\"}]]}],[\"$\",\"span\",null,{\"className\":\"font-mono text-[13px] font-medium tracking-[-0.02em] lowercase\",\"children\":\"iii / worker\"}]]}],\"$L10\"]}],[\"$\",\"nav\",null,{\"aria-label\":\"footer\",\"className\":\"flex items-center flex-wrap gap-x-6 gap-y-2\",\"children\":[[\"$\",\"a\",\"https://iii.dev\",{\"href\":\"https://iii.dev\",\"target\":\"_blank\",\"rel\":\"noreferrer\",\"className\":\"inline-flex items-center gap-x-1 font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors\",\"children\":[\"iii.dev\",[\"$\",\"$L11\",null,{\"ref\":\"$undefined\",\"iconNode\":[[\"path\",{\"d\":\"M15 3h6v6\",\"key\":\"1q9fwt\"}],[\"path\",{\"d\":\"M10 14 21 3\",\"key\":\"gplh6r\"}],[\"path\",{\"d\":\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\",\"key\":\"a6xqqp\"}]],\"className\":\"lucide-external-link size-3 shrink-0\",\"aria-hidden\":true}]]}],[\"$\",\"a\",\"https://iii.dev/docs\",{\"href\":\"https://iii.dev/docs\",\"target\":\"_blank\",\"rel\":\"noreferrer\",\"className\":\"inline-flex items-center gap-x-1 font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors\",\"children\":[\"docs\",[\"$\",\"$L11\",null,{\"ref\":\"$undefined\",\"iconNode\":\"$8:props:children:props:children:1:props:children:0:props:children:1:props:iconNode\",\"className\":\"lucide-external-link size-3 shrink-0\",\"aria-hidden\":true}]]}],[\"$\",\"$L7\",\"/collections\",{\"href\":\"/collections\",\"className\":\"font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors\",\"children\":\"collections\"}],[\"$\",\"$L7\",\"/leaderboard\",{\"href\":\"/leaderboard\",\"className\":\"font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors\",\"children\":\"leaderboard\"}],[\"$\",\"$L7\",\"/publish\",{\"href\":\"/publish\",\"className\":\"font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors\",\"children\":\"publish\"}],[\"$\",\"$L7\",\"/badge-preview\",{\"href\":\"/badge-preview\",\"className\":\"font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors\",\"children\":\"badge preview\"}],[\"$\",\"a\",\"https://discord.gg/iiidev\",{\"href\":\"https://discord.gg/iiidev\",\"target\":\"_blank\",\"rel\":\"noreferrer\",\"className\":\"inline-flex items-center gap-x-1 font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors\",\"children\":[\"discord\",[\"$\",\"$L11\",null,{\"ref\":\"$undefined\",\"iconNode\":\"$8:props:children:props:children:1:props:children:0:props:children:1:props:iconNode\",\"className\":\"lucide-external-link size-3 shrink-0\",\"aria-hidden\":true}]]}],[\"$\",\"a\",\"https://github.com/iii-hq/iii\",{\"href\":\"https://github.com/iii-hq/iii\",\"target\":\"_blank\",\"rel\":\"noreferrer\",\"className\":\"inline-flex items-center gap-x-1 font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors\",\"children\":[\"github\",[\"$\",\"$L11\",null,{\"ref\":\"$undefined\",\"iconNode\":\"$8:props:children:props:children:1:props:children:0:props:children:1:props:iconNode\",\"className\":\"lucide-external-link size-3 shrink-0\",\"aria-hidden\":true}]]}]]}]]}]}]\n"])</script><script>self.__next_f.push([1,"9:[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L5\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L6\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}]\na:[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L5\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L6\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}]\nb:[\"$\",\"$1\",\"c\",{\"children\":[\"$L12\",[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/0-3vzlyvl.dxh.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$L13\",null,{\"children\":[\"$\",\"$14\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@15\"}]}]]}]\n16:[]\nc:\"$W16\"\nd:[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L17\",null,{\"children\":\"$L18\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L19\",null,{\"children\":[\"$\",\"$14\",null,{\"name\":\"Next.Metadata\",\"children\":\"$L1a\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}]\nf:[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/05q2cs4d4qqrk.css?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]\n18:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"4:[\"$\",\"a\",null,{\"href\":\"https://github.com/iii-hq/iii\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"aria-label\":\"iii-hq/iii on GitHub — 18,845 stars\",\"className\":\"shrink-0 items-center gap-x-2 border border-rule px-2.5 py-1 font-mono text-[13px] text-ink-faint transition-colors hover:text-ink hidden sm:inline-flex\",\"children\":[[\"$\",\"svg\",null,{\"viewBox\":\"0 0 16 16\",\"aria-hidden\":\"true\",\"focusable\":\"false\",\"className\":\"size-3.5 shrink-0\",\"fill\":\"currentColor\",\"children\":[\"$\",\"path\",null,{\"d\":\"M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8Z\"}]}],[\"$\",\"span\",null,{\"className\":\"hidden sm:inline lowercase\",\"children\":\"stars\"}],[\"$\",\"span\",null,{\"className\":\"tabular-nums text-ink\",\"aria-hidden\":true,\"children\":\"18.8k\"}]]}]\n10:[\"$\",\"a\",null,{\"href\":\"https://github.com/iii-hq/iii\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"aria-label\":\"iii-hq/iii on GitHub — 18,845 stars\",\"className\":\"inline-flex shrink-0 items-center gap-x-2 border border-rule px-2.5 py-1 font-mono text-[13px] text-ink-faint transition-colors hover:text-ink sm:hidden\",\"children\":[[\"$\",\"svg\",null,{\"viewBox\":\"0 0 16 16\",\"aria-hidden\":\"true\",\"focusable\":\"false\",\"className\":\"size-3.5 shrink-0\",\"fill\":\"currentColor\",\"children\":[\"$\",\"path\",null,{\"d\":\"M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8Z\"}]}],[\"$\",\"span\",null,{\"className\":\"hidden sm:inline lowercase\",\"children\":\"stars\"}],[\"$\",\"span\",null,{\"className\":\"tabular-nums text-ink\",\"aria-hidden\":true,\"children\":\"18.8k\"}]]}]\n"])</script><script>self.__next_f.push([1,"1b:I[18418,[\"/_next/static/chunks/04ylibgf-0e6d.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"/_next/static/chunks/0.vqct1a~k736.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\"],\"IconMark\"]\n15:null\n"])</script><script>self.__next_f.push([1,"1a:[[\"$\",\"title\",\"0\",{\"children\":\"kanban - iii worker\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"File-backed kanban board — tickets, threaded comments, agent assignment, the kanban:change and kanban:comment trigger types, and an injectable console board with agent profiles for planning and review.\"}],[\"$\",\"meta\",\"2\",{\"name\":\"robots\",\"content\":\"index, follow\"}],[\"$\",\"link\",\"3\",{\"rel\":\"canonical\",\"href\":\"https://workers.iii.dev/workers/kanban\"}],[\"$\",\"meta\",\"4\",{\"property\":\"og:title\",\"content\":\"kanban - iii worker\"}],[\"$\",\"meta\",\"5\",{\"property\":\"og:description\",\"content\":\"File-backed kanban board — tickets, threaded comments, agent assignment, the kanban:change and kanban:comment trigger types, and an injectable console board with agent profiles for planning and review.\"}],[\"$\",\"meta\",\"6\",{\"property\":\"og:url\",\"content\":\"https://workers.iii.dev/workers/kanban\"}],[\"$\",\"meta\",\"7\",{\"property\":\"og:image\",\"content\":\"https://workers.iii.dev/workers/kanban/opengraph-image?bced171a25d0f70f\"}],[\"$\",\"meta\",\"8\",{\"property\":\"og:image:type\",\"content\":\"image/png\"}],[\"$\",\"meta\",\"9\",{\"property\":\"og:image:width\",\"content\":\"1200\"}],[\"$\",\"meta\",\"10\",{\"property\":\"og:image:height\",\"content\":\"630\"}],[\"$\",\"meta\",\"11\",{\"property\":\"og:image:alt\",\"content\":\"iii worker\"}],[\"$\",\"meta\",\"12\",{\"name\":\"twitter:card\",\"content\":\"summary_large_image\"}],[\"$\",\"meta\",\"13\",{\"name\":\"twitter:title\",\"content\":\"kanban - iii worker\"}],[\"$\",\"meta\",\"14\",{\"name\":\"twitter:description\",\"content\":\"File-backed kanban board — tickets, threaded comments, agent assignment, the kanban:change and kanban:comment trigger types, and an injectable console board with agent profiles for planning and review.\"}],[\"$\",\"meta\",\"15\",{\"name\":\"twitter:image\",\"content\":\"https://workers.iii.dev/workers/kanban/opengraph-image?bced171a25d0f70f\"}],[\"$\",\"meta\",\"16\",{\"name\":\"twitter:image:alt\",\"content\":\"iii worker\"}],[\"$\",\"meta\",\"17\",{\"name\":\"twitter:image:type\",\"content\":\"image/png\"}],[\"$\",\"meta\",\"18\",{\"name\":\"twitter:image:width\",\"content\":\"1200\"}],[\"$\",\"meta\",\"19\",{\"name\":\"twitter:image:height\",\"content\":\"630\"}],[\"$\",\"link\",\"20\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.0n6vou73am7b3.ico\",\"sizes\":\"48x48\",\"type\":\"image/x-icon\"}],[\"$\",\"$L1b\",\"21\",{}]]\n"])</script><script>self.__next_f.push([1,":HL[\"https://iii.dev/docs/_mintlify/favicons/motiadev/AFkVbz_UcSL_5jsm/_generated/favicon/apple-touch-icon.png\",\"image\"]\n"])</script><script>self.__next_f.push([1,"12:[\"$\",\"div\",null,{\"className\":\"page-transition\",\"children\":[[\"$\",\"script\",null,{\"type\":\"application/ld+json\",\"dangerouslySetInnerHTML\":{\"__html\":\"{\\\"@context\\\":\\\"https://schema.org\\\",\\\"@type\\\":\\\"SoftwareApplication\\\",\\\"name\\\":\\\"kanban\\\",\\\"description\\\":\\\"File-backed kanban board — tickets, threaded comments, agent assignment, the kanban:change and kanban:comment trigger types, and an injectable console board with agent profiles for planning and review.\\\",\\\"applicationCategory\\\":\\\"DeveloperApplication\\\",\\\"softwareVersion\\\":\\\"0.1.22\\\",\\\"url\\\":\\\"https://workers.iii.dev/workers/kanban\\\",\\\"license\\\":\\\"Apache-2.0\\\",\\\"codeRepository\\\":\\\"https://github.com/iii-hq/workers\\\",\\\"author\\\":{\\\"@type\\\":\\\"Person\\\",\\\"name\\\":\\\"iii\\\"}}\"}}],[\"$\",\"div\",null,{\"className\":\"flex items-end justify-between flex-wrap gap-x-6 gap-y-4 px-9 py-12\",\"children\":[[\"$\",\"div\",null,{\"className\":\"min-w-0\",\"children\":[[\"$\",\"div\",null,{\"className\":\"font-mono text-[11px] uppercase tracking-[0.06em] text-ink-faint mb-3\",\"children\":[\"$\",\"span\",null,{\"className\":\"font-mono text-accent\",\"children\":[\"$$\",[\"$\",\"span\",null,{\"className\":\"text-ink ml-2\",\"children\":\"registry / workers\"}]]}]}],[\"$\",\"div\",null,{\"className\":\"flex items-baseline flex-wrap gap-x-3 gap-y-1\",\"children\":[[\"$\",\"h1\",null,{\"className\":\"font-mono text-[28px] font-medium tracking-[-0.01em] text-ink lowercase\",\"children\":\"kanban\"}],\"$undefined\",[\"$\",\"span\",null,{\"className\":\"font-mono text-[11px] uppercase tracking-[0.06em] text-ink-ghost tabular-nums\",\"children\":\"v0.1.22\"}]]}],[\"$\",\"p\",null,{\"className\":\"mt-3 font-mono text-[14px] leading-[1.7] text-ink-faint max-w-[60ch] lowercase\",\"children\":\"File-backed kanban board — tickets, threaded comments, agent assignment, the kanban:change and kanban:comment trigger types, and an injectable console board with agent profiles for planning and review.\"}]]}],null]}],[\"$\",\"div\",null,{\"className\":\"px-9 pb-8 flex flex-col gap-y-6\",\"children\":[null,null,[\"$\",\"div\",null,{\"className\":\"flex flex-col gap-y-5 border border-rule bg-bg p-5 @2xl:p-6\",\"children\":[[\"$\",\"div\",null,{\"className\":\"flex flex-wrap items-center gap-x-4 gap-y-2\",\"children\":[[\"$\",\"span\",null,{\"data-type-mark\":\"worker\",\"className\":\"inline-flex items-center gap-x-1.5 shrink-0\",\"children\":[[\"$\",\"svg\",null,{\"viewBox\":\"0 0 16 16\",\"aria-hidden\":\"true\",\"focusable\":\"false\",\"className\":\"size-4 shrink-0 text-type-worker\",\"fill\":\"none\",\"stroke\":\"currentColor\",\"strokeWidth\":1.25,\"strokeLinejoin\":\"miter\",\"strokeLinecap\":\"square\",\"children\":[[\"$\",\"path\",null,{\"d\":\"M8 1.6 13.6 4.8v6.4L8 14.4 2.4 11.2V4.8Z\"}],null,null]}],[\"$\",\"span\",null,{\"className\":\"font-mono text-[11px] font-medium uppercase leading-none tracking-[0.06em] text-ink-faint\",\"children\":\"worker\"}]]}],[\"$\",\"div\",null,{\"className\":\"flex items-center gap-x-2 font-mono text-[13px]\",\"children\":[[\"$\",\"img\",null,{\"src\":\"https://iii.dev/docs/_mintlify/favicons/motiadev/AFkVbz_UcSL_5jsm/_generated/favicon/apple-touch-icon.png\",\"alt\":\"\",\"className\":\"size-5 object-cover\"}],[\"$\",\"span\",null,{\"className\":\"text-ink lowercase\",\"children\":\"iii\"}],[\"$\",\"span\",null,{\"className\":\"inline-flex items-center gap-x-1 text-ink-faint\",\"children\":[[\"$\",\"$L11\",null,{\"ref\":\"$undefined\",\"iconNode\":[[\"path\",{\"d\":\"M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z\",\"key\":\"3c2336\"}],[\"path\",{\"d\":\"m9 12 2 2 4-4\",\"key\":\"dzmm74\"}]],\"className\":\"lucide-badge-check size-3.5 text-accent\",\"aria-hidden\":true}],[\"$\",\"span\",null,{\"className\":\"text-[11px] uppercase tracking-[0.06em]\",\"children\":\"verified\"}]]}]]}],[\"$\",\"span\",null,{\"className\":\"flex flex-wrap items-center gap-x-3 gap-y-1 font-mono text-[12px] text-ink-ghost tabular-nums\",\"children\":[[\"$\",\"span\",null,{\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ink\",\"children\":\"247\"}],\" installs\"]}],[[\"$\",\"span\",null,{\"aria-hidden\":true,\"className\":\"text-rule\",\"children\":\"/\"}],[\"$\",\"span\",null,{\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ink\",\"children\":\"64\"}],\" in 7d\"]}]],[[\"$\",\"span\",null,{\"aria-hidden\":true,\"className\":\"text-rule\",\"children\":\"/\"}],\"$L1c\"]]}]]}],\"$L1d\",\"$L1e\",\"$L1f\"]}],false,false]}],\"$L20\"]}]\n"])</script><script>self.__next_f.push([1,"21:I[15957,[\"/_next/static/chunks/0wcm0wpln.-h..js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"/_next/static/chunks/0-3vzlyvl.dxh.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\"],\"InstallCommand\"]\n22:I[33516,[\"/_next/static/chunks/0wcm0wpln.-h..js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"/_next/static/chunks/0-3vzlyvl.dxh.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\"],\"Image\"]\n27:I[84938,[\"/_next/static/chunks/0wcm0wpln.-h..js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\",\"/_next/static/chunks/0-3vzlyvl.dxh.js?dpl=dpl_Aek62oZSuVbHEfXvLZ3d1fURYNU1\"],\"PageTabs\"]\n1c:[\"$\",\"span\",null,{\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ink\",\"children\":\"14\"}],\" \",\"today\"]}]\n1d:[\"$\",\"$L21\",null,{\"workerName\":\"kanban\",\"version\":\"0.1.22\",\"kind\":\"worker\"}]\n"])</script><script>self.__next_f.push([1,"1e:[\"$\",\"div\",null,{\"className\":\"flex flex-col gap-y-3\",\"children\":[[\"$\",\"div\",null,{\"className\":\"flex flex-wrap items-center gap-2 font-mono text-[12px] lowercase\",\"children\":[[\"$\",\"span\",null,{\"className\":\"border border-rule px-2 py-1 text-ink\",\"children\":\"binary\"}],[\"$\",\"span\",null,{\"className\":\"border border-rule px-2 py-1 text-ink normal-case\",\"children\":[\"license: \",\"Apache-2.0\"]}],[[\"$\",\"$L7\",\"agents\",{\"href\":\"/search?tag=agents\",\"className\":\"border border-rule-2 px-2 py-1 text-ink-faint hover:text-ink hover:border-rule transition-colors\",\"children\":\"agents\"}],[\"$\",\"$L7\",\"board\",{\"href\":\"/search?tag=board\",\"className\":\"border border-rule-2 px-2 py-1 text-ink-faint hover:text-ink hover:border-rule transition-colors\",\"children\":\"board\"}],[\"$\",\"$L7\",\"console-ui\",{\"href\":\"/search?tag=console-ui\",\"className\":\"border border-rule-2 px-2 py-1 text-ink-faint hover:text-ink hover:border-rule transition-colors\",\"children\":\"console-ui\"}],[\"$\",\"$L7\",\"kanban\",{\"href\":\"/search?tag=kanban\",\"className\":\"border border-rule-2 px-2 py-1 text-ink-faint hover:text-ink hover:border-rule transition-colors\",\"children\":\"kanban\"}],[\"$\",\"$L7\",\"tickets\",{\"href\":\"/search?tag=tickets\",\"className\":\"border border-rule-2 px-2 py-1 text-ink-faint hover:text-ink hover:border-rule transition-colors\",\"children\":\"tickets\"}]]]}],[\"$\",\"ul\",null,{\"aria-label\":\"Supported platforms\",\"className\":\"flex flex-wrap items-center font-mono text-[12px] gap-x-2 gap-y-1.5 \",\"children\":[[\"$\",\"li\",\"apple\",{\"title\":\"macOS: arm64, x64\",\"className\":\"inline-flex items-center border border-rule bg-bg gap-x-2 px-2 py-1\",\"children\":[[\"$\",\"$L22\",null,{\"src\":\"/icons/apple_dark.svg\",\"alt\":\"\",\"aria-hidden\":true,\"width\":209,\"height\":256,\"className\":\"shrink-0 [filter:brightness(0)] dark:[filter:brightness(0)_invert(1)] h-4 w-auto\"}],[\"$\",\"span\",null,{\"className\":\"sr-only\",\"children\":[\"macOS\",\": \"]}],[\"$\",\"span\",null,{\"className\":\"text-ink tabular-nums\",\"children\":\"arm64 · x64\"}]]}],[\"$\",\"li\",\"linux\",{\"title\":\"Linux: arm64, armv7, x64\",\"className\":\"inline-flex items-center border border-rule bg-bg gap-x-2 px-2 py-1\",\"children\":[[\"$\",\"$L22\",null,{\"src\":\"/icons/linux.svg\",\"alt\":\"\",\"aria-hidden\":true,\"width\":256,\"height\":295,\"className\":\"shrink-0 [filter:brightness(0)] dark:[filter:brightness(0)_invert(1)] h-4 w-auto\"}],[\"$\",\"span\",null,{\"className\":\"sr-only\",\"children\":[\"Linux\",\": \"]}],[\"$\",\"span\",null,{\"className\":\"text-ink tabular-nums\",\"children\":\"arm64 · armv7 · x64\"}]]}],[\"$\",\"li\",\"windows\",{\"title\":\"Windows: arm64, x64\",\"className\":\"inline-flex items-center border border-rule bg-bg gap-x-2 px-2 py-1\",\"children\":[[\"$\",\"$L22\",null,{\"src\":\"/icons/windows.svg\",\"alt\":\"\",\"aria-hidden\":true,\"width\":88,\"height\":88,\"className\":\"shrink-0 [filter:brightness(0)] dark:[filter:brightness(0)_invert(1)] h-4 w-auto\"}],[\"$\",\"span\",null,{\"className\":\"sr-only\",\"children\":[\"Windows\",\": \"]}],[\"$\",\"span\",null,{\"className\":\"text-ink tabular-nums\",\"children\":\"arm64 · x64\"}]]}]]}],[\"$\",\"div\",null,{\"className\":\"flex flex-wrap gap-x-4 gap-y-2 font-mono text-[12px]\",\"children\":[[[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?version=0.1.22\u0026tab=api\",\"className\":\"inline-flex items-baseline gap-x-1.5 text-ink-faint hover:text-ink transition-colors\",\"children\":[[\"$\",\"span\",null,{\"className\":\"tabular-nums text-ink\",\"children\":\"30\"}],[\"$\",\"span\",null,{\"className\":\"uppercase tracking-[0.06em] text-[11px]\",\"children\":\"functions\"}]]}],[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?version=0.1.22\u0026tab=api\",\"className\":\"inline-flex items-baseline gap-x-1.5 text-ink-faint hover:text-ink transition-colors\",\"children\":[[\"$\",\"span\",null,{\"className\":\"tabular-nums text-ink\",\"children\":\"2\"}],[\"$\",\"span\",null,{\"className\":\"uppercase tracking-[0.06em] text-[11px]\",\"children\":\"triggers\"}]]}]],[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?version=0.1.22\u0026tab=skills\",\"className\":\"inline-flex items-baseline gap-x-1.5 text-ink-faint hover:text-ink transition-colors\",\"children\":[[\"$\",\"span\",null,{\"className\":\"tabular-nums text-ink\",\"children\":\"27\"}],[\"$\",\"span\",null,{\"className\":\"uppercase tracking-[0.06em] text-[11px]\",\"children\":\"skills\"}]]}],[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?version=0.1.22\u0026tab=deps\",\"className\":\"inline-flex items-baseline gap-x-1.5 text-ink-faint hover:text-ink transition-colors\",\"children\":[\"$L23\",\"$L24\"]}],\"$L25\",\"$L26\"]}]]}]\n"])</script><script>self.__next_f.push([1,"1f:[\"$\",\"div\",null,{\"className\":\"flex flex-col @2xl:flex-row @2xl:items-center gap-3 border-t border-rule-2 pt-4\",\"children\":[[\"$\",\"div\",null,{\"className\":\"flex items-center gap-x-2 min-w-0 font-mono text-[13px]\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-[11px] uppercase tracking-[0.06em] text-ink-faint shrink-0\",\"children\":\"repo\"}],[\"$\",\"a\",null,{\"href\":\"https://github.com/iii-hq/workers\",\"target\":\"_blank\",\"rel\":\"noreferrer\",\"className\":\"inline-flex items-center gap-x-1 font-mono text-[13px] text-ink lowercase hover:text-accent transition-colors min-w-0\",\"children\":[[\"$\",\"span\",null,{\"className\":\"truncate\",\"children\":\"iii-hq/workers\"}],[\"$\",\"$L11\",null,{\"ref\":\"$undefined\",\"iconNode\":\"$8:props:children:props:children:1:props:children:0:props:children:1:props:iconNode\",\"className\":\"lucide-external-link size-3 shrink-0\",\"aria-hidden\":true}]]}]]}],[\"$\",\"p\",null,{\"className\":\"font-mono text-[12px] leading-[1.5] text-ink-faint @2xl:ml-auto @2xl:max-w-[42ch] @2xl:text-right\",\"children\":\"exact versions are immutable; binary and bundle artifacts are digest-pinned.\"}]]}]\n"])</script><script>self.__next_f.push([1,"20:[\"$\",\"div\",null,{\"className\":\"px-9 pb-12 flex flex-col gap-y-6\",\"children\":[\"$\",\"div\",null,{\"className\":\"grid grid-cols-1 @4xl:grid-cols-[1fr_280px] gap-x-8 gap-y-8\",\"children\":[[\"$\",\"div\",null,{\"className\":\"min-w-0 flex flex-col gap-y-6\",\"children\":[[\"$\",\"$L27\",null,{\"slug\":\"kanban\",\"activeTab\":\"skills\",\"version\":\"0.1.22\",\"basePath\":\"/workers\",\"tabs\":\"$undefined\"}],false,false,\"$L28\",false,false,false,false]}],[\"$\",\"aside\",null,{\"className\":\"flex flex-col gap-y-4 @4xl:sticky @4xl:top-4 @4xl:self-start @4xl:max-h-[calc(100dvh-2rem)] @4xl:overflow-y-auto\",\"children\":[[\"$\",\"div\",null,{\"className\":\"border border-rule bg-bg\",\"children\":[[\"$\",\"div\",null,{\"className\":\"bg-panel px-3.5 py-2.5 border-b border-rule\",\"children\":[\"$\",\"span\",null,{\"className\":\"font-mono text-[11px] font-medium uppercase tracking-[0.18em] text-ink-faint\",\"children\":\"details\"}]}],[\"$\",\"div\",null,{\"className\":\"p-4 flex flex-col gap-y-2.5\",\"children\":[[\"$\",\"div\",null,{\"className\":\"flex items-baseline justify-between font-mono text-[13px] gap-x-3\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ink-faint shrink-0 uppercase tracking-[0.06em] text-[11px]\",\"children\":\"version\"}],[\"$\",\"span\",null,{\"className\":\"text-ink truncate text-right lowercase tabular-nums\",\"children\":\"v0.1.22\"}]]}],[\"$\",\"div\",null,{\"className\":\"flex items-baseline justify-between font-mono text-[13px] gap-x-3\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ink-faint shrink-0 uppercase tracking-[0.06em] text-[11px]\",\"children\":\"type\"}],[\"$\",\"span\",null,{\"className\":\"text-ink truncate text-right lowercase \",\"children\":\"binary\"}]]}],[\"$\",\"div\",null,{\"className\":\"flex items-baseline justify-between font-mono text-[13px] gap-x-3\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ink-faint shrink-0 uppercase tracking-[0.06em] text-[11px]\",\"children\":\"license\"}],[\"$\",\"span\",null,{\"className\":\"text-ink truncate text-right \",\"children\":\"Apache-2.0\"}]]}],null,[\"$\",\"div\",null,{\"className\":\"flex items-baseline justify-between font-mono text-[13px] gap-x-3 min-w-0\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ink-faint shrink-0 uppercase tracking-[0.06em] text-[11px]\",\"children\":\"repo\"}],[\"$\",\"a\",null,{\"href\":\"https://github.com/iii-hq/workers\",\"target\":\"_blank\",\"rel\":\"noreferrer\",\"className\":\"inline-flex items-center gap-x-1 font-mono text-[13px] text-ink lowercase hover:text-accent transition-colors min-w-0 text-right justify-end\",\"children\":[[\"$\",\"span\",null,{\"className\":\"truncate\",\"children\":\"iii-hq/workers\"}],[\"$\",\"$L11\",null,{\"ref\":\"$undefined\",\"iconNode\":\"$8:props:children:props:children:1:props:children:0:props:children:1:props:iconNode\",\"className\":\"lucide-external-link size-3 shrink-0\",\"aria-hidden\":true}]]}]]}],\"$undefined\"]}]]}],[\"$\",\"section\",null,{\"id\":\"used-in-kits\",\"className\":\"border border-rule bg-bg scroll-mt-20\",\"aria-labelledby\":\"used-in-kits-title\",\"children\":[[\"$\",\"div\",null,{\"className\":\"flex items-baseline justify-between bg-panel px-3.5 py-2.5 border-b border-rule\",\"children\":[\"$\",\"span\",null,{\"id\":\"used-in-kits-title\",\"className\":\"font-mono text-[11px] font-medium uppercase tracking-[0.18em] text-ink-faint\",\"children\":[\"used in \",1,\" \",\"kit\"]}]}],[\"$\",\"ul\",null,{\"className\":\"divide-y divide-rule-2\",\"children\":[[\"$\",\"li\",\"iii/deepwork\",{\"children\":[\"$\",\"$L7\",null,{\"href\":\"/kits/iii/deepwork\",\"className\":\"group flex items-start gap-x-2.5 px-3.5 py-2.5 hover:bg-panel transition-colors\",\"children\":[[\"$\",\"svg\",null,{\"viewBox\":\"0 0 16 16\",\"aria-hidden\":\"true\",\"focusable\":\"false\",\"className\":\"size-4 shrink-0 text-type-kit mt-0.5\",\"fill\":\"none\",\"stroke\":\"currentColor\",\"strokeWidth\":1.25,\"strokeLinejoin\":\"miter\",\"strokeLinecap\":\"square\",\"children\":[null,[\"$\",\"path\",null,{\"d\":\"M2 5h2.9a1.9 1.9 0 1 1 3.2 0H11v2.9a1.9 1.9 0 1 1 0 3.2V14H8.1a1.6 1.6 0 0 0-3.2 0H2Z\"}],null]}],[\"$\",\"span\",null,{\"className\":\"min-w-0 flex flex-col\",\"children\":[[\"$\",\"span\",null,{\"className\":\"font-mono text-[13px] text-ink truncate group-hover:underline underline-offset-4\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ink-faint\",\"children\":[\"iii\",\"/\"]}],\"deepwork\"]}],[\"$\",\"span\",null,{\"className\":\"font-mono text-[11px] uppercase tracking-[0.06em] text-ink-ghost tabular-nums\",\"children\":[\"v\",\"0.2.1\",\" · \",6,\" \",\"profiles\"]}]]}]]}]}]]}]]}],[\"$\",\"div\",null,{\"className\":\"border border-rule bg-bg\",\"children\":[\"$L29\",\"$L2a\"]}],\"$L2b\"]}]]}]}]\n"])</script><script>self.__next_f.push([1,"23:[\"$\",\"span\",null,{\"className\":\"tabular-nums text-ink\",\"children\":\"1\"}]\n24:[\"$\",\"span\",null,{\"className\":\"uppercase tracking-[0.06em] text-[11px]\",\"children\":\"deps\"}]\n25:[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?version=0.1.22\u0026tab=versions\",\"className\":\"inline-flex items-baseline gap-x-1.5 text-ink-faint hover:text-ink transition-colors\",\"children\":[[\"$\",\"span\",null,{\"className\":\"tabular-nums text-ink\",\"children\":\"v0.1.22\"}],[\"$\",\"span\",null,{\"className\":\"uppercase tracking-[0.06em] text-[11px]\",\"children\":\"version\"}]]}]\n26:[\"$\",\"$L7\",null,{\"href\":\"#used-in-kits\",\"className\":\"inline-flex items-baseline gap-x-1.5 text-ink-faint hover:text-ink transition-colors\",\"children\":[[\"$\",\"span\",null,{\"className\":\"tabular-nums text-ink\",\"children\":\"1\"}],[\"$\",\"span\",null,{\"className\":\"uppercase tracking-[0.06em] text-[11px]\",\"children\":\"kit\"}]]}]\n29:[\"$\",\"div\",null,{\"className\":\"bg-panel px-3.5 py-2.5 border-b border-rule\",\"children\":[\"$\",\"span\",null,{\"className\":\"font-mono text-[11px] font-medium uppercase tracking-[0.18em] text-ink-faint\",\"children\":\"skills\"}]}]\n"])</script><script>self.__next_f.push([1,"2a:[\"$\",\"div\",null,{\"className\":\"max-h-[min(60dvh,28rem)] overflow-y-auto\",\"children\":[[\"$\",\"section\",null,{\"aria-labelledby\":\"skills-tree-kanban\",\"children\":[[\"$\",\"div\",null,{\"id\":\"skills-tree-kanban\",\"className\":\"flex items-baseline justify-between px-3.5 py-2 bg-paper-2 border-b border-rule-2\",\"children\":[[\"$\",\"span\",null,{\"className\":\"font-mono text-[11px] font-medium uppercase tracking-[0.06em] text-ink-faint\",\"children\":\"files\"}],[\"$\",\"span\",null,{\"className\":\"font-mono text-[11px] uppercase tracking-[0.06em] text-ink-ghost tabular-nums\",\"children\":27}]]}],[\"$\",\"nav\",null,{\"aria-label\":\"skill files\",\"className\":\"px-3 pt-2 pb-3\",\"children\":[\"$\",\"ul\",null,{\"className\":\"flex flex-col gap-y-0.5\",\"children\":[[\"$\",\"li\",\"SKILL.md\",{\"style\":{\"paddingLeft\":0},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=SKILL.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"SKILL.md\"}]}],[\"$\",\"li\",\"agents\",{\"style\":{\"paddingLeft\":0},\"className\":\"min-w-0\",\"children\":[[\"$\",\"div\",null,{\"className\":\"font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase text-ink-faint select-none\",\"children\":[\"agents\",\"/\"]}],[\"$\",\"ul\",null,{\"className\":\"flex flex-col gap-y-0.5 mt-0.5\",\"children\":[[\"$\",\"li\",\"agents/ade-worker-designer.md\",{\"style\":{\"paddingLeft\":10},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=agents%2Fade-worker-designer.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"ade-worker-designer.md\"}]}],[\"$\",\"li\",\"agents/backend-engineer.md\",{\"style\":{\"paddingLeft\":10},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=agents%2Fbackend-engineer.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"backend-engineer.md\"}]}],[\"$\",\"li\",\"agents/frontend-engineer.md\",{\"style\":{\"paddingLeft\":10},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=agents%2Ffrontend-engineer.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"frontend-engineer.md\"}]}],[\"$\",\"li\",\"agents/product-manager.md\",{\"style\":{\"paddingLeft\":10},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=agents%2Fproduct-manager.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"product-manager.md\"}]}],[\"$\",\"li\",\"agents/tech-lead.md\",{\"style\":{\"paddingLeft\":10},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=agents%2Ftech-lead.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"tech-lead.md\"}]}]]}]]}],[\"$\",\"li\",\"skills\",{\"style\":{\"paddingLeft\":0},\"className\":\"min-w-0\",\"children\":[[\"$\",\"div\",null,{\"className\":\"font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase text-ink-faint select-none\",\"children\":[\"skills\",\"/\"]}],[\"$\",\"ul\",null,{\"className\":\"flex flex-col gap-y-0.5 mt-0.5\",\"children\":[[\"$\",\"li\",\"ade-worker-design\",{\"style\":{\"paddingLeft\":10},\"className\":\"min-w-0\",\"children\":[[\"$\",\"div\",null,{\"className\":\"font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase text-ink-faint select-none\",\"children\":[\"ade-worker-design\",\"/\"]}],[\"$\",\"ul\",null,{\"className\":\"flex flex-col gap-y-0.5 mt-0.5\",\"children\":[[\"$\",\"li\",\"skills/ade-worker-design\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Fade-worker-design\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"index.md\"}]}],\"$L2c\",\"$L2d\",\"$L2e\"]}]]}],\"$L2f\",\"$L30\",\"$L31\"]}]]}]]}]}]]}],null]}]\n"])</script><script>self.__next_f.push([1,"2b:[\"$\",\"div\",null,{\"className\":\"border border-rule bg-bg\",\"children\":[[\"$\",\"div\",null,{\"className\":\"bg-panel px-3.5 py-2.5 border-b border-rule\",\"children\":[\"$\",\"span\",null,{\"className\":\"font-mono text-[11px] font-medium uppercase tracking-[0.18em] text-ink-faint\",\"children\":\"author\"}]}],[\"$\",\"div\",null,{\"className\":\"p-4 flex flex-col gap-y-2.5\",\"children\":[\"$\",\"div\",null,{\"className\":\"flex items-center gap-x-2 font-mono text-[13px]\",\"children\":[[\"$\",\"img\",null,{\"src\":\"https://iii.dev/docs/_mintlify/favicons/motiadev/AFkVbz_UcSL_5jsm/_generated/favicon/apple-touch-icon.png\",\"alt\":\"\",\"className\":\"size-5 object-cover\"}],[\"$\",\"span\",null,{\"className\":\"text-ink lowercase\",\"children\":\"iii\"}],[\"$\",\"$L11\",null,{\"ref\":\"$undefined\",\"iconNode\":\"$12:props:children:2:props:children:2:props:children:0:props:children:1:props:children:2:props:children:0:props:iconNode\",\"className\":\"lucide-badge-check size-3.5 text-accent\"}]]}]}]]}]\n28:[\"$\",\"section\",null,{\"children\":[[\"$\",\"div\",null,{\"className\":\"flex items-center justify-between mb-3\",\"children\":[\"$\",\"h2\",null,{\"className\":\"font-mono text-[12px] font-medium uppercase tracking-[0.18em] text-ink-faint\",\"children\":\"skill doc\"}]}],\"$L32\"]}]\n"])</script><script>self.__next_f.push([1,"2c:[\"$\",\"li\",\"skills/ade-worker-design/console-design.md\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Fade-worker-design%2Fconsole-design.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"console-design.md\"}]}]\n2d:[\"$\",\"li\",\"skills/ade-worker-design/console-injectable-ui.md\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Fade-worker-design%2Fconsole-injectable-ui.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"console-injectable-ui.md\"}]}]\n2e:[\"$\",\"li\",\"skills/ade-worker-design/patterns.md\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Fade-worker-design%2Fpatterns.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"patterns.md\"}]}]\n"])</script><script>self.__next_f.push([1,"2f:[\"$\",\"li\",\"frontend\",{\"style\":{\"paddingLeft\":10},\"className\":\"min-w-0\",\"children\":[[\"$\",\"div\",null,{\"className\":\"font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase text-ink-faint select-none\",\"children\":[\"frontend\",\"/\"]}],[\"$\",\"ul\",null,{\"className\":\"flex flex-col gap-y-0.5 mt-0.5\",\"children\":[[\"$\",\"li\",\"skills/frontend\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Ffrontend\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"index.md\"}]}],[\"$\",\"li\",\"skills/frontend/frontend-testing.md\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Ffrontend%2Ffrontend-testing.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"frontend-testing.md\"}]}],[\"$\",\"li\",\"skills/frontend/iii-browser-sdk.md\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Ffrontend%2Fiii-browser-sdk.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"iii-browser-sdk.md\"}]}],[\"$\",\"li\",\"skills/frontend/react.md\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Ffrontend%2Freact.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors bg-ink text-bg\",\"children\":\"react.md\"}]}],[\"$\",\"li\",\"skills/frontend/tanstack-query.md\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Ffrontend%2Ftanstack-query.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"tanstack-query.md\"}]}],[\"$\",\"li\",\"skills/frontend/tanstack-router.md\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Ffrontend%2Ftanstack-router.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"tanstack-router.md\"}]}],[\"$\",\"li\",\"skills/frontend/vite.md\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Ffrontend%2Fvite.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"vite.md\"}]}],[\"$\",\"li\",\"skills/frontend/web-accessibility.md\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Ffrontend%2Fweb-accessibility.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"web-accessibility.md\"}]}],[\"$\",\"li\",\"skills/frontend/web-performance.md\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Ffrontend%2Fweb-performance.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"web-performance.md\"}]}]]}]]}]\n"])</script><script>self.__next_f.push([1,"30:[\"$\",\"li\",\"iii-node\",{\"style\":{\"paddingLeft\":10},\"className\":\"min-w-0\",\"children\":[[\"$\",\"div\",null,{\"className\":\"font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase text-ink-faint select-none\",\"children\":[\"iii-node\",\"/\"]}],[\"$\",\"ul\",null,{\"className\":\"flex flex-col gap-y-0.5 mt-0.5\",\"children\":[[\"$\",\"li\",\"skills/iii-node\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Fiii-node\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"index.md\"}]}],[\"$\",\"li\",\"skills/iii-node/configuration.md\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Fiii-node%2Fconfiguration.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"configuration.md\"}]}]]}]]}]\n"])</script><script>self.__next_f.push([1,"31:[\"$\",\"li\",\"tickets\",{\"style\":{\"paddingLeft\":10},\"className\":\"min-w-0\",\"children\":[[\"$\",\"div\",null,{\"className\":\"font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase text-ink-faint select-none\",\"children\":[\"tickets\",\"/\"]}],[\"$\",\"ul\",null,{\"className\":\"flex flex-col gap-y-0.5 mt-0.5\",\"children\":[[\"$\",\"li\",\"skills/tickets\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Ftickets\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"index.md\"}]}],[\"$\",\"li\",\"skills/tickets/acceptance-review.md\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Ftickets%2Facceptance-review.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"acceptance-review.md\"}]}],[\"$\",\"li\",\"skills/tickets/feature-planning.md\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Ftickets%2Ffeature-planning.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"feature-planning.md\"}]}],[\"$\",\"li\",\"skills/tickets/kanban-tickets.md\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Ftickets%2Fkanban-tickets.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"kanban-tickets.md\"}]}],[\"$\",\"li\",\"skills/tickets/ticket-orchestration.md\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Ftickets%2Fticket-orchestration.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"ticket-orchestration.md\"}]}],[\"$\",\"li\",\"skills/tickets/ticket-worker.md\",{\"style\":{\"paddingLeft\":20},\"children\":[\"$\",\"$L7\",null,{\"href\":\"/workers/kanban?tab=skills\u0026skill=skills%2Ftickets%2Fticket-worker.md\u0026version=0.1.22\",\"scroll\":false,\"className\":\"block font-mono text-[12px] py-0.5 px-1.5 -mx-1.5 lowercase truncate transition-colors text-ink-faint hover:text-ink\",\"children\":\"ticket-worker.md\"}]}]]}]]}]\n"])</script><script>self.__next_f.push([1,"33:T29e1,"])</script><script>self.__next_f.push([1,"\u003ch1 id=\"react\" class=\"scroll-mt-20\"\u003eReact\u003c/h1\u003e\n\u003cp\u003eDocs \u003ca href=\"https://react.dev/learn\"\u003ehttps://react.dev/learn\u003c/a\u003e · reference \u003ca href=\"https://react.dev/reference/react\"\u003ehttps://react.dev/reference/react\u003c/a\u003e. Read the\nproject\u0026#39;s installed version\u0026#39;s docs when the two disagree — the API surface has moved\n(React 19 in particular).\u003c/p\u003e\n\u003ch2 id=\"the-mental-model-in-three-sentences\" class=\"scroll-mt-20\"\u003eThe mental model, in three sentences\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003eRender is pure and repeatable.\u003c/strong\u003e Given the same props and state it produces the same JSX;\nit must not call functions, mutate things, or start network work.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eState is a snapshot per render.\u003c/strong\u003e Setting it schedules a new render; the variable you\njust read is the \u003cem\u003eold\u003c/em\u003e value for the rest of this one.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eEffects synchronize with external systems\u003c/strong\u003e — sockets, DOM APIs, subscriptions, timers.\nThey are not the place for derived data, event responses, or initialization.\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"rules-that-catch-most-bugs\" class=\"scroll-mt-20\"\u003eRules that catch most bugs\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eHooks at the top level of a component or hook, unconditional. No hooks in loops, conditions,\nor after an early \u003ccode class=\"readme-inline-code\"\u003ereturn\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eKeys are identity.\u003c/strong\u003e \u003ccode class=\"readme-inline-code\"\u003ekey={index}\u003c/code\u003e on a list that reorders or filters corrupts state.\nUse a stable id from the data.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eStrictMode double-invokes render and remounts effects in dev.\u003c/strong\u003e That is a feature: it\nexposes missing cleanup and non-idempotent effects. Fix the code; do not remove StrictMode.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eNever mutate props or state.\u003c/strong\u003e Copy, then set.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eDo not lie about dependencies.\u003c/strong\u003e A stale-closure bug is a missing dep or a non-memoized\nfunction. Fix the dependency, do not silence the lint rule.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"state-placement\" class=\"scroll-mt-20\"\u003eState placement\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eCompute what you can; do not store it.\u003c/strong\u003e If it is derivable from props or state, derive it\nduring render. Mirroring creates a second source of truth that drifts.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eColocate, then lift.\u003c/strong\u003e Keep state in the closest component that needs it; lift only when\ntwo siblings must agree, and lift to their \u003cstrong\u003eclosest common parent\u003c/strong\u003e, not to the top of\nthe app.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eOne state variable per concern.\u003c/strong\u003e \u003ccode class=\"readme-inline-code\"\u003euseReducer\u003c/code\u003e when several fields change together or the\nnext value depends on the previous (\u003ccode class=\"readme-inline-code\"\u003esetCount(c =\u003e c + 1)\u003c/code\u003e — batching means the object form\nis often wrong in a burst of events).\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eReset state by changing \u003ccode class=\"readme-inline-code\"\u003ekey\u003c/code\u003e, not by an effect.\u003c/strong\u003e \u003ccode class=\"readme-inline-code\"\u003e\u003cForm key={userId} /\u003e\u003c/code\u003e is the correct\n\u0026quot;reset on entity change\u0026quot; and also resets every child.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eServer data is not React state.\u003c/strong\u003e Cache it (TanStack Query or equivalent); keeping a copy\nin \u003ccode class=\"readme-inline-code\"\u003euseState\u003c/code\u003e guarantees stale UI and double-loading.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eURL is state.\u003c/strong\u003e Filters, tabs, pagination, and selection belong in search params so they\nsurvive reload, back/forward, and sharing.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"effects\" class=\"scroll-mt-20\"\u003eEffects\u003c/h2\u003e\n\u003cpre\u003e\u003ccode\u003euseEffect(() =\u0026gt; {\n const ac = new AbortController()\n let active = true\n void (async () =\u0026gt; {\n const data = await fetchThing(id, { signal: ac.signal })\n if (active) setData(data)\n })()\n return () =\u0026gt; { active = false; ac.abort() }\n}, [id])\u003c/code\u003e\u003c/pre\u003e\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eEvery effect that starts something must clean it up.\u003c/strong\u003e Timers, listeners, subscriptions,\nsockets, in-flight requests.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eGuard against races\u003c/strong\u003e (\u003ccode class=\"readme-inline-code\"\u003eactive\u003c/code\u003e flag, \u003ccode class=\"readme-inline-code\"\u003eAbortController\u003c/code\u003e) whenever the dep can change\nmid-flight — otherwise a slow response overwrites a fast one.\u003c/li\u003e\n\u003cli\u003e\u003ccode class=\"readme-inline-code\"\u003euseLayoutEffect\u003c/code\u003e only when you must read or write layout before paint (measuring, scroll\nrestoration). It blocks paint; prefer \u003ccode class=\"readme-inline-code\"\u003euseEffect\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eEffects are the wrong tool for:\u003c/strong\u003e responding to a click, deriving state, fetching as a\ngeneral pattern when a data layer exists, or reacting to a prop you could compute from.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"refs-context-and-escape-hatches\" class=\"scroll-mt-20\"\u003eRefs, context, and escape hatches\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eRefs hold values that do not affect rendering (timers, DOM nodes, previous values). Do not\nread or write them during render — only in effects and handlers.\u003c/li\u003e\n\u003cli\u003e\u003ccode class=\"readme-inline-code\"\u003euseImperativeHandle\u003c/code\u003e when a parent genuinely needs a handle on a child\u0026#39;s behavior.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eContext is for low-frequency values\u003c/strong\u003e (theme, current user, the iii client). Split it: a\ncontext whose value object is rebuilt every render re-renders every consumer. Pair a reducer\nwith a context and expose \u003ccode class=\"readme-inline-code\"\u003estate\u003c/code\u003e and \u003ccode class=\"readme-inline-code\"\u003edispatch\u003c/code\u003e in two separate contexts.\u003c/li\u003e\n\u003cli\u003e\u003ccode class=\"readme-inline-code\"\u003euseSyncExternalStore\u003c/code\u003e for subscribing to a store outside React (including the iii client\u0026#39;s\nconnection state) — it is the correct primitive, and hand-rolled subscription effects get it\nwrong under concurrent rendering.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"composition\" class=\"scroll-mt-20\"\u003eComposition\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode class=\"readme-inline-code\"\u003echildren\u003c/code\u003e as a prop\u003c/strong\u003e breaks prop-drilling without context.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eSlots\u003c/strong\u003e (\u003ccode class=\"readme-inline-code\"\u003e\u003cCard header={...} footer={...} /\u003e\u003c/code\u003e) beat boolean flags that switch internal\nbranches into a second component.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eCompound components\u003c/strong\u003e (\u003ccode class=\"readme-inline-code\"\u003e\u003cTabs\u003e\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003e\u003cTabs.List\u003e\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003e\u003cTabs.Panel\u003e\u003c/code\u003e) share state through\ncontext; the parent owns the invariant.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eA component with 6+ boolean props is 2^6 configurations nobody tests.\u003c/strong\u003e Split on the axis\nthat actually varies.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eHoist state to the leaf that needs it\u003c/strong\u003e, and keep lists virtualized when they exceed a few\nhundred rows.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"suspense-transitions-errors\" class=\"scroll-mt-20\"\u003eSuspense, transitions, errors\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode class=\"readme-inline-code\"\u003e\u003cSuspense fallback\u003e\u003c/code\u003e + \u003ccode class=\"readme-inline-code\"\u003eReact.lazy\u003c/code\u003e for route-level code splitting; the fallback is a real\nUI state, not a spinner on a blank screen.\u003c/li\u003e\n\u003cli\u003e\u003ccode class=\"readme-inline-code\"\u003euseTransition\u003c/code\u003e / \u003ccode class=\"readme-inline-code\"\u003estartTransition\u003c/code\u003e for updates that may be expensive (tab switches,\nfiltered lists) so typing stays responsive. \u003ccode class=\"readme-inline-code\"\u003euseDeferredValue\u003c/code\u003e when a \u003cem\u003evalue\u003c/em\u003e is the slow\npart (a query fed to a heavy list).\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eError boundaries are still the mechanism\u003c/strong\u003e for render errors — a class component or\n\u003ccode class=\"readme-inline-code\"\u003ereact-error-boundary\u003c/code\u003e. An async rejection is not caught by a boundary unless you rethrow it\nin render or route it through the data layer.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode class=\"readme-inline-code\"\u003euse()\u003c/code\u003e\u003c/strong\u003e (React 19) unwraps a promise or context in render, but only inside a Suspense\nboundary.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eReact 19 notes: refs are props (\u003ccode class=\"readme-inline-code\"\u003e\u003cinput ref={r} /\u003e\u003c/code\u003e, no \u003ccode class=\"readme-inline-code\"\u003eforwardRef\u003c/code\u003e), \u003ccode class=\"readme-inline-code\"\u003e\u003cContext\u003e\u003c/code\u003e is itself\nusable as the provider, \u003ccode class=\"readme-inline-code\"\u003euseActionState\u003c/code\u003e / \u003ccode class=\"readme-inline-code\"\u003euseOptimistic\u003c/code\u003e / \u003ccode class=\"readme-inline-code\"\u003e\u003cform action\u003e\u003c/code\u003e cover form\npending and optimistic UI, and document metadata (\u003ccode class=\"readme-inline-code\"\u003e\u003ctitle\u003e\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003e\u003cmeta\u003e\u003c/code\u003e) can render inline.\nCheck the installed version before using any of these.\u003c/p\u003e\n\u003ch2 id=\"performance-measure-do-not-decorate\" class=\"scroll-mt-20\"\u003ePerformance: measure, do not decorate\u003c/h2\u003e\n\u003cp\u003eOrder of leverage:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003eDo less work.\u003c/strong\u003e Ship fewer/smaller deps, split routes, virtualize long lists, paginate.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eStop unnecessary re-renders\u003c/strong\u003e — but only after profiling. React DevTools\u0026#39; Profiler shows\nwhich component re-rendered and why.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eThen memoize.\u003c/strong\u003e \u003ccode class=\"readme-inline-code\"\u003ememo\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003euseMemo\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003euseCallback\u003c/code\u003e cost memory and comparison time; they are\nnet-negative on cheap components with stable inputs and net-positive on expensive subtrees\nfed by unstable objects.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eNever memoize to fix a bug.\u003c/strong\u003e A correct dependency array is the fix; \u003ccode class=\"readme-inline-code\"\u003euseMemo\u003c/code\u003e is only an\noptimization.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cul\u003e\n\u003cli\u003eKeep the tree shallow; a context value changing high up re-renders the world.\u003c/li\u003e\n\u003cli\u003eSplit a hot component so the state change lands low in the tree.\u003c/li\u003e\n\u003cli\u003eLong lists: virtualize (TanStack Virtual, \u003ccode class=\"readme-inline-code\"\u003ereact-window\u003c/code\u003e) — rendering 5000 rows is the cost,\nnot the state.\u003c/li\u003e\n\u003cli\u003eAvoid layout thrash: batch DOM reads and writes; never read \u003ccode class=\"readme-inline-code\"\u003egetBoundingClientRect()\u003c/code\u003e in the\nsame frame as a write loop.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"accessibility-is-part-of-the-component\" class=\"scroll-mt-20\"\u003eAccessibility is part of the component\u003c/h2\u003e\n\u003cp\u003eSemantic elements before ARIA, a real \u003ccode class=\"readme-inline-code\"\u003e\u003cbutton\u003e\u003c/code\u003e before a clickable \u003ccode class=\"readme-inline-code\"\u003e\u003cdiv\u003e\u003c/code\u003e, labels bound to\ninputs, focus moved deliberately on route and dialog changes, and no interaction that only\nworks with a mouse. It is far cheaper to build in than to retrofit.\u003c/p\u003e\n\u003ch2 id=\"anti-patterns-to-refuse\" class=\"scroll-mt-20\"\u003eAnti-patterns to refuse\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eDeriving state in an effect and storing it (\u003ccode class=\"readme-inline-code\"\u003euseEffect(() =\u003e setX(a + b), [a, b])\u003c/code\u003e).\u003c/li\u003e\n\u003cli\u003eSyncing props to state with an effect.\u003c/li\u003e\n\u003cli\u003eOne giant context holding a mutable object.\u003c/li\u003e\n\u003cli\u003eFetching in an effect when a data layer exists.\u003c/li\u003e\n\u003cli\u003e\u003ccode class=\"readme-inline-code\"\u003euseMemo\u003c/code\u003e everywhere as a habit.\u003c/li\u003e\n\u003cli\u003eIndex keys on sortable/filterable lists.\u003c/li\u003e\n\u003cli\u003eSuppressing the exhaustive-deps lint rule instead of fixing the dependency.\u003c/li\u003e\n\u003cli\u003eCopying a library\u0026#39;s internal markup instead of the library.\u003c/li\u003e\n\u003c/ul\u003e\n"])</script><script>self.__next_f.push([1,"32:[\"$\",\"div\",null,{\"className\":\"border border-rule bg-bg\",\"children\":[[\"$\",\"div\",null,{\"className\":\"bg-panel px-3.5 py-2.5 border-b border-rule flex flex-col gap-y-1\",\"children\":[[\"$\",\"div\",null,{\"className\":\"flex items-center gap-x-2 min-w-0\",\"children\":[[\"$\",\"h3\",null,{\"className\":\"font-mono text-[16px] font-semibold tracking-[-0.01em] text-ink truncate min-w-0\",\"children\":\"react\"}],[\"$\",\"span\",null,{\"className\":\"inline-flex items-center border border-rule-2 px-1.5 pt-0.5 pb-0.4 font-mono text-[11px] uppercase tracking-[0.1em] font-medium bg-bg text-ink-faint leading-1.1\",\"children\":\"how-to\"}]]}],[\"$\",\"div\",null,{\"className\":\"font-mono text-[11px] uppercase tracking-[0.06em] text-ink-ghost truncate\",\"children\":\"skills/frontend/react.md\"}]]}],[\"$\",\"div\",null,{\"className\":\"px-7 py-6 readme-prose font-mono\",\"dangerouslySetInnerHTML\":{\"__html\":\"$33\"}}]]}]\n"])</script></body></html>