{# One project row. Rendered by the dashboard grid loop AND by GET /api/projects/{name}/row for reactive insertion (no full-page reload). `idx` is the row's position for the search/cap visibility gate (0 from the fragment route, so a freshly created project is always shown). The `:style` below reorders rows VISUALLY for a non-name sort via CSS `order` — it does NOT change DOM/tab order (focus + screen-reader order stay A–Z), the deliberate trade for an opt-in cosmetic sort. Don't turn this into a DOM reorder (the anti-pattern the Active zone avoids). #}
{# DES-07: responsive name cap — clamp scales the truncation width with the viewport (narrow phone → ~10rem, wide desktop → 28rem) instead of a fixed 16rem; min-width:0 lets text-truncate shrink inside the flex row. #} {{ p.name }} {% if p.is_git_repo %}Git{% endif %} {% if p.has_claude_md %}CLAUDE.md{% endif %} {# FE-578: surface a launch precondition INSIDE the popover; Run stays ENABLED (disabling it would hide the spawn picker / trust confirm that resolve it). On open we coerce a non-git+worktree default to a valid mode; the note below the Spawn picker explains it. #} {# Dismissing the popover (outside-click / Escape) also clears any pending trust/bypass gate (#686) so a hidden gate never lingers — reopening starts a fresh launch. mopen is reset too so More options collapses on reopen. #}
How do you want to drive it?

Connectable from claude.ai / Desktop — converse with it, and Stop it here when done.

{# Option text + effect tooltip both come from the canonical permission_labels map (#685) — never a hand-maintained copy. bypassPermissions is offered only where the per-project ceiling allows it and only for the Desktop/bridge launch (the typed-confirm footgun guard); the "(Desktop only)" caveat is a contextual hint appended here, not baked into the canonical label. #} {# Plain-language effect of the SELECTED mode, inline (not just title=) so it's visible on touch — the riskiest per-launch choice shouldn't hide in a tooltip. #}

{# "More options" — a single disclosure (#686) holding the ADVANCED choices for the Desktop/bridge launch: the Mode selector (Server Mode / Interactive Session) AND Spawn. Mode is an advanced choice, tucked away by default; the safe Desktop default works with this closed. Only the Desktop launch exposes these (browser/background ignore spawn + resume mode). #}
{% if pty_supported %} {# Mode (Server Mode / Interactive Session) — the advanced launch-shape choice, tucked inside More options. Drives whether Spawn applies (standard) or the single-session note shows (pty). #}
{% endif %} {# Spawn only applies to the standard (multi-session) bridge — it maps to `claude remote-control --spawn`. pty is a single interactive session run under the keeper with no `--spawn`, so it ignores these; hide them in pty mode rather than offer no-op choices. #}
{# #578: surface (don't disable) — a non-git dir can't worktree, so note it here and coerceSpawnMode() falls back to same-dir on open. x-text (auto-escaped, never x-html); no d-* class on this x-show el. #}

{% if pty_supported %} {# Keep d-flex OFF this x-show element — `.d-flex{display:flex!important}` overrides x-show's inline display:none and would pin this hint visible even in standard mode (same bug as the live-tail banners). Flex goes on the inner wrapper. #}

Runs as one session in the project directory.

{% endif %}
{# Trust-on-start + bypassPermissions gates fold INSIDE the popover (#686) — no separate below-the-row alerts. Both are hidden until the Run button routes a Desktop launch into start(), which opens the matching gate; resolving or cancelling either one dismisses the popover (via the launch-pop-close event). #} {# When a gate opens INSIDE the popover the Run button hides, so move focus into the gate's first control (WCAG 2.4.3 / 4.1.3) — else focus is orphaned on and a keyboard/SR user gets no signal a confirm now blocks launch. x-effect re-runs when confirmTrust[name] flips; $nextTick waits for x-show. #}

Trust the files in {{ p.name }}? Launching a session here lets it run tools and execute any code in CLAUDE.md / .claude in this directory.

bypassPermissions lets sessions in {{ p.name }} run tools without asking. Type the project name to confirm.

{# Primary Run action. Hidden while a trust/bypass gate is showing INSIDE the popover so the gate's own confirm button is the single next step (no competing primary). On a clean launch (no gate pending) launchRun() returns true and the popover closes; when it opens a gate it returns false and the popover stays. #} {# Semantic end-of-popover sentinel: a stable structural boundary for tests (so they don't couple to template whitespace/nesting). Renders nothing. #}
Readiness checks for {{ p.name }} before launch
{# The trust-on-start + bypassPermissions confirm gates moved INSIDE the launch popover (#686) — they no longer render as separate below-the-row alerts. The `data-test="inline-error"` hook is load-bearing: three `.alert-danger.mb-0` blocks now share this row (the in-popover bypass-confirm, this transient-action error, and the spawn-failure detail below), so a bare `.alert-danger.mb-0` selector is ambiguous — tests must target this stable hook. #}