mockups/issue_detail.html
Rama main · réplica de lectura del repositorio original.
<!DOCTYPE html>
<html lang="en" class="dark">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SSH host key rotation breaks existing client fingerprints · Issue #214 · mkappworks/cloudzilla</title>
<link rel="stylesheet" href="/assets/tailwind.css" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Geist+Mono:wght@400;500&family=Geist:wght@400;500;600&display=swap" rel="stylesheet" />
</head>
<body class="min-h-screen flex flex-col antialiased font-sans">
<a href="#main-content" class="skip-link">Skip to main content</a>
<div id="cz-header" data-repo-tab="issues"></div>
<main id="main-content" tabindex="-1" class="max-w-[1400px] mx-auto px-6 pt-6 pb-20 flex-1 w-full">
<div class="space-y-6">
<section aria-labelledby="issue-heading" class="border-b border-border pb-6">
<p class="font-mono text-[11px] text-muted-foreground uppercase tracking-wider mb-2">
<a href="repo.html" class="hover:underline">cloudzilla</a>
<span aria-hidden="true">·</span>
<a href="issues.html" class="hover:underline">Issues</a>
<span aria-hidden="true">·</span>
<span aria-current="page">#214</span>
</p>
<div class="mb-3">
<div id="issue-title-section" class="flex flex-wrap items-start justify-between gap-3">
<h1 id="issue-heading" class="text-2xl font-semibold tracking-tight flex items-center gap-2 flex-wrap min-w-0">
<span id="title-text">SSH host key rotation breaks existing client fingerprints</span>
<span class="text-muted-foreground font-normal" aria-label="Issue number 214">#214</span>
</h1>
<form id="title-form" hidden class="flex flex-1 items-center gap-2 min-w-0">
<input type="text" id="title-input" value="SSH host key rotation breaks existing client fingerprints" required aria-label="Issue title" class="flex-1 min-w-0 h-9 px-3 rounded-md border border-input bg-background text-lg font-medium focus:outline-hidden focus:ring-2 focus:ring-ring"/>
<button type="submit" class="h-9 px-3 text-[13px] rounded-md font-medium bg-primary text-primary-foreground hover:bg-primary/90 shrink-0">Save</button>
<button type="button" id="title-cancel" class="h-9 px-3 text-[13px] rounded-md border border-border hover:bg-muted shrink-0">Cancel</button>
</form>
<button type="button" id="title-edit" class="h-8 px-3 text-[13px] rounded-md border border-border hover:bg-muted inline-flex items-center shrink-0">Edit</button>
</div>
</div>
<div class="flex flex-wrap items-center gap-3">
<span class="inline-flex items-center gap-1.5 h-[22px] px-2 rounded-full border text-[11px] font-medium bg-success/15 text-success border-success/30">Open</span>
<span id="issue-locked-badge" hidden><span class="inline-flex items-center gap-1.5 h-[22px] px-2 rounded-full border text-[11px] font-medium bg-secondary text-secondary-foreground border-transparent">Locked</span></span>
<p class="text-[13px] text-muted-foreground">
<a href="profile.html" class="font-medium text-foreground hover:underline">yumi</a>
opened this issue
<time>May 12, 2026</time>
<span>· 2 comments</span>
</p>
</div>
</section>
<div class="grid grid-cols-1 lg:grid-cols-[1fr_280px] gap-8">
<article class="space-y-5 min-w-0">
<section id="issue-body-card" class="rounded-md border border-border bg-card overflow-hidden" aria-label="Issue description">
<header class="px-4 py-2.5 border-b border-border bg-blue-500/10 dark:bg-blue-900/40 flex items-center gap-2 text-[12.5px]">
<span class="inline-grid place-items-center rounded-full bg-muted border border-border font-medium text-muted-foreground h-6 w-6 text-[10px]" aria-hidden="true">Y</span>
<strong class="text-foreground">yumi</strong>
<span class="text-muted-foreground">opened</span>
<time class="text-muted-foreground ml-auto text-xs">May 12, 2026</time>
<button type="button" id="desc-edit" class="inline-flex items-center gap-1 h-7 px-2 rounded-md border border-border hover:bg-muted text-[12px] text-muted-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" focusable="false"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 113 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>
Edit
</button>
</header>
<div id="desc-rendered" class="px-4 py-4 prose prose-sm dark:prose-invert max-w-none">
<p>I rotated the host key on our staging Cloudzilla node yesterday. Now every existing SSH client is throwing <code>REMOTE HOST IDENTIFICATION HAS CHANGED</code> warnings — which is technically correct, but breaks unattended deploy jobs that can't accept the new key interactively.</p>
<p>Two things would help:</p>
<ul>
<li>Document the rotation procedure (include the <code>~/.ssh/known_hosts</code> remediation step).</li>
<li>Optionally support publishing the new fingerprint via an HTTPS endpoint so CI can auto-update.</li>
</ul>
</div>
<form id="desc-form" hidden class="px-4 py-4">
<div class="border border-border rounded-md bg-card overflow-hidden">
<div class="md-editor" data-md-editor>
<div class="flex items-center gap-2 border-b border-border px-3">
<div role="tablist" aria-label="Editor mode" class="flex">
<button type="button" role="tab" data-md-tab="write" aria-selected="true" class="px-3 py-2 text-[13px] border-b-2 border-foreground text-foreground font-medium -mb-px">Write</button>
<button type="button" role="tab" data-md-tab="preview" aria-selected="false" class="px-3 py-2 text-[13px] border-b-2 border-transparent text-muted-foreground hover:text-foreground -mb-px">Preview</button>
</div>
<div class="ml-auto flex items-center gap-0.5 text-muted-foreground" aria-label="Formatting">
<button type="button" data-md-action="bold" aria-label="Bold" class="h-7 w-7 grid place-items-center rounded-sm hover:bg-accent hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" focusable="false"><path d="M6 4h8a4 4 0 014 4 4 4 0 01-4 4H6zM6 12h9a4 4 0 014 4 4 4 0 01-4 4H6z"></path></svg>
</button>
<button type="button" data-md-action="italic" aria-label="Italic" class="h-7 w-7 grid place-items-center rounded-sm hover:bg-accent hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" focusable="false"><line x1="19" y1="4" x2="10" y2="4"></line><line x1="14" y1="20" x2="5" y2="20"></line><line x1="15" y1="4" x2="9" y2="20"></line></svg>
</button>
<button type="button" data-md-action="code" aria-label="Code" class="h-7 w-7 grid place-items-center rounded-sm hover:bg-accent hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" focusable="false"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg>
</button>
<button type="button" data-md-action="link" aria-label="Insert link" class="h-7 w-7 grid place-items-center rounded-sm hover:bg-accent hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 007.07 0l3-3a5 5 0 00-7.07-7.07l-1 1"></path><path d="M14 11a5 5 0 00-7.07 0l-3 3a5 5 0 007.07 7.07l1-1"></path></svg>
</button>
</div>
</div>
<div data-md-pane="write">
<label for="issue-body-textarea" class="sr-only">Issue description</label>
<textarea id="issue-body-textarea" name="body" rows="10" placeholder="Issue description" style="height:244px" class="w-full px-3 py-3 text-[13px] font-mono leading-relaxed bg-transparent resize-none focus:outline-hidden placeholder:text-muted-foreground">I rotated the host key on our staging Cloudzilla node yesterday. Now every existing SSH client is throwing `REMOTE HOST IDENTIFICATION HAS CHANGED` warnings — which is technically correct, but breaks unattended deploy jobs that can't accept the new key interactively.
Two things would help:
- Document the rotation procedure (include the `~/.ssh/known_hosts` remediation step).
- Optionally support publishing the new fingerprint via an HTTPS endpoint so CI can auto-update.</textarea>
</div>
<div data-md-pane="preview" style="height:244px" class="hidden px-4 py-3 prose prose-sm dark:prose-invert max-w-none overflow-y-auto"><p class="text-muted-foreground">Nothing to preview.</p></div>
</div>
</div>
<div class="flex justify-end gap-2 mt-3">
<button type="button" id="desc-cancel" class="h-8 px-3 text-[13px] rounded-md border border-border hover:bg-muted">Cancel</button>
<button type="submit" class="h-8 px-3 text-[13px] rounded-md font-medium bg-primary text-primary-foreground hover:bg-primary/90">Save</button>
</div>
</form>
</section>
<ol id="comments" class="space-y-4" aria-label="Issue activity">
<li class="rounded-md border border-border bg-card overflow-hidden">
<header class="px-4 py-2.5 border-b border-border bg-muted/40 flex items-center gap-2 text-[12.5px]">
<span class="inline-grid place-items-center rounded-full bg-muted border border-border font-medium text-muted-foreground h-6 w-6 text-[10px]" aria-hidden="true">M</span>
<strong class="text-foreground">malith</strong>
<span class="text-muted-foreground">commented</span>
<time class="text-muted-foreground ml-auto text-xs">May 12, 2026 at 11:00 AM</time>
</header>
<div class="px-4 py-3 prose prose-sm dark:prose-invert max-w-none">
<p>Thanks Yumi. There's a draft of the rotation runbook in <a href="wiki.html">the wiki</a> already — I'll promote it to the main SSH section today.</p>
<p>The auto-publish endpoint is a good follow-up. Worth doing as a separate issue so we can ship the docs first.</p>
</div>
</li>
<li class="rounded-md border border-border bg-card overflow-hidden">
<header class="px-4 py-2.5 border-b border-border bg-muted/40 flex items-center gap-2 text-[12.5px]">
<span class="inline-grid place-items-center rounded-full bg-muted border border-border font-medium text-muted-foreground h-6 w-6 text-[10px]" aria-hidden="true">D</span>
<strong class="text-foreground">daisy</strong>
<span class="text-muted-foreground">commented</span>
<time class="text-muted-foreground ml-auto text-xs">May 13, 2026 at 8:00 AM</time>
</header>
<div class="px-4 py-3 prose prose-sm dark:prose-invert max-w-none">
<p>+1 on splitting it. Filed <a href="issue_detail.html">#218</a> for the auto-publish endpoint.</p>
</div>
</li>
</ol>
<section aria-label="Add a comment">
<form class="rounded-md border border-border bg-card overflow-hidden" onsubmit="return false">
<header class="px-3 py-2 border-b border-border bg-background flex items-center gap-2">
<span class="inline-grid place-items-center rounded-full bg-muted border border-border font-medium text-muted-foreground h-6 w-6 text-[10px]" aria-hidden="true">M</span>
<span class="text-[13px] font-medium">Add a comment</span>
</header>
<div class="md-editor" data-md-editor>
<div class="flex items-center gap-2 border-b border-border px-3">
<div role="tablist" aria-label="Editor mode" class="flex">
<button type="button" role="tab" data-md-tab="write" aria-selected="true" class="px-3 py-2 text-[13px] border-b-2 border-foreground text-foreground font-medium -mb-px">Write</button>
<button type="button" role="tab" data-md-tab="preview" aria-selected="false" class="px-3 py-2 text-[13px] border-b-2 border-transparent text-muted-foreground hover:text-foreground -mb-px">Preview</button>
</div>
<div class="ml-auto flex items-center gap-0.5 text-muted-foreground" aria-label="Formatting">
<button type="button" data-md-action="bold" aria-label="Bold" class="h-7 w-7 grid place-items-center rounded-sm hover:bg-accent hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" focusable="false"><path d="M6 4h8a4 4 0 014 4 4 4 0 01-4 4H6zM6 12h9a4 4 0 014 4 4 4 0 01-4 4H6z"></path></svg>
</button>
<button type="button" data-md-action="italic" aria-label="Italic" class="h-7 w-7 grid place-items-center rounded-sm hover:bg-accent hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" focusable="false"><line x1="19" y1="4" x2="10" y2="4"></line><line x1="14" y1="20" x2="5" y2="20"></line><line x1="15" y1="4" x2="9" y2="20"></line></svg>
</button>
<button type="button" data-md-action="code" aria-label="Code" class="h-7 w-7 grid place-items-center rounded-sm hover:bg-accent hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" focusable="false"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg>
</button>
<button type="button" data-md-action="link" aria-label="Insert link" class="h-7 w-7 grid place-items-center rounded-sm hover:bg-accent hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 007.07 0l3-3a5 5 0 00-7.07-7.07l-1 1"></path><path d="M14 11a5 5 0 00-7.07 0l-3 3a5 5 0 007.07 7.07l1-1"></path></svg>
</button>
</div>
</div>
<div data-md-pane="write">
<label for="comment-body" class="sr-only">Add a comment…</label>
<textarea id="comment-body" name="body" rows="6" placeholder="Add a comment…" style="height:156px" class="w-full px-3 py-3 text-[13px] font-mono leading-relaxed bg-transparent resize-none focus:outline-hidden placeholder:text-muted-foreground"></textarea>
</div>
<div data-md-pane="preview" style="height:156px" class="hidden px-4 py-3 prose prose-sm dark:prose-invert max-w-none overflow-y-auto"><p class="text-muted-foreground">Nothing to preview.</p></div>
</div>
<div class="px-3 py-2 border-t border-border bg-muted/40 flex items-center gap-2">
<p class="text-[11px] text-muted-foreground font-mono flex-1">Markdown supported · drop files to attach</p>
<button type="button" id="close-issue-btn" class="inline-flex items-center gap-1.5 h-9 px-3 text-[13px] rounded-md font-medium border border-destructive/30 bg-destructive/10 text-destructive hover:bg-destructive/20">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="12" cy="12" r="9"></circle><path d="M9 12l2 2 4-4"></path></svg>
Close issue
</button>
<button type="submit" class="inline-flex items-center justify-center gap-1.5 rounded-md font-medium transition-colors h-9 px-4 text-sm bg-primary text-primary-foreground hover:bg-primary/90">
Comment
</button>
</div>
</form>
</section>
</article>
<aside class="space-y-6 text-[12.5px]" aria-label="Issue metadata">
<section data-meta>
<div class="space-y-2">
<div class="flex items-center justify-between">
<h3 class="text-[12px] font-medium text-muted-foreground">Assignees</h3>
<div class="relative">
<button type="button" data-menu-btn aria-expanded="false" aria-haspopup="menu" aria-label="Edit assignees" class="text-muted-foreground hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" focusable="false"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 113 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>
</button>
<div data-menu-panel hidden role="menu" aria-label="Assign people" class="absolute right-0 top-full mt-1.5 z-50 w-56 rounded-md border border-border bg-popover text-popover-foreground shadow-md p-1">
<div class="px-2 pt-1 pb-0.5 text-[10px] font-medium uppercase tracking-wider text-muted-foreground">Assign people</div>
<button type="button" role="menuitemcheckbox" aria-checked="true" data-key="malith" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<span class="inline-grid place-items-center rounded-full bg-muted border border-border font-medium text-muted-foreground h-6 w-6 text-[10px]" aria-hidden="true">M</span>
<span class="flex-1 truncate">malith</span>
<svg data-check width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class="shrink-0 text-success" aria-hidden="true" focusable="false"><polyline points="20 6 9 17 4 12"></polyline></svg>
</button>
<button type="button" role="menuitemcheckbox" aria-checked="false" data-key="yumi" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<span class="inline-grid place-items-center rounded-full bg-muted border border-border font-medium text-muted-foreground h-6 w-6 text-[10px]" aria-hidden="true">Y</span>
<span class="flex-1 truncate">yumi</span>
<svg data-check hidden width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class="shrink-0 text-success" aria-hidden="true" focusable="false"><polyline points="20 6 9 17 4 12"></polyline></svg>
</button>
<button type="button" role="menuitemcheckbox" aria-checked="false" data-key="daisy" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<span class="inline-grid place-items-center rounded-full bg-muted border border-border font-medium text-muted-foreground h-6 w-6 text-[10px]" aria-hidden="true">D</span>
<span class="flex-1 truncate">daisy</span>
<svg data-check hidden width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class="shrink-0 text-success" aria-hidden="true" focusable="false"><polyline points="20 6 9 17 4 12"></polyline></svg>
</button>
<div role="separator" class="my-1 h-px bg-border"></div>
<a href="settings.html" role="menuitem" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" class="shrink-0" aria-hidden="true" focusable="false"><path d="M16 21v-2a4 4 0 00-4-4H6a4 4 0 00-4 4v2"></path><circle cx="11" cy="7" r="4"></circle><line x1="19" y1="8" x2="19" y2="14"></line><line x1="22" y1="11" x2="16" y2="11"></line></svg>
Invite a collaborator
</a>
</div>
</div>
</div>
<div class="space-y-1">
<div data-entry="malith" class="flex items-center gap-2 text-[13px]">
<span class="inline-grid place-items-center rounded-full bg-muted border border-border font-medium text-muted-foreground h-6 w-6 text-[10px]" aria-hidden="true">M</span>
<a href="profile.html" class="font-medium hover:underline truncate">malith</a>
</div>
<div data-entry="yumi" hidden class="flex items-center gap-2 text-[13px]">
<span class="inline-grid place-items-center rounded-full bg-muted border border-border font-medium text-muted-foreground h-6 w-6 text-[10px]" aria-hidden="true">Y</span>
<a href="profile.html" class="font-medium hover:underline truncate">yumi</a>
</div>
<div data-entry="daisy" hidden class="flex items-center gap-2 text-[13px]">
<span class="inline-grid place-items-center rounded-full bg-muted border border-border font-medium text-muted-foreground h-6 w-6 text-[10px]" aria-hidden="true">D</span>
<a href="profile.html" class="font-medium hover:underline truncate">daisy</a>
</div>
<span data-empty hidden class="text-xs text-muted-foreground">No one assigned</span>
</div>
</div>
</section>
<section data-meta class="border-t border-border pt-6">
<div class="space-y-2">
<div class="flex items-center justify-between">
<h3 class="text-[12px] font-medium text-muted-foreground">Labels</h3>
<div class="relative">
<button type="button" data-menu-btn aria-expanded="false" aria-haspopup="menu" aria-label="Edit labels" class="text-muted-foreground hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" focusable="false"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 113 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>
</button>
<div data-menu-panel hidden role="menu" aria-label="Apply labels" class="absolute right-0 top-full mt-1.5 z-50 w-56 rounded-md border border-border bg-popover text-popover-foreground shadow-md p-1 max-h-72 overflow-y-auto">
<div class="px-2 pt-1 pb-0.5 text-[10px] font-medium uppercase tracking-wider text-muted-foreground">Apply labels</div>
<button type="button" role="menuitemcheckbox" aria-checked="true" data-key="bug" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<span class="h-2.5 w-2.5 rounded-full inline-block shrink-0" style="background-color: #ef4444"></span>
<span class="flex-1 truncate">bug</span>
<svg data-check width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class="shrink-0 text-success" aria-hidden="true" focusable="false"><polyline points="20 6 9 17 4 12"></polyline></svg>
</button>
<button type="button" role="menuitemcheckbox" aria-checked="true" data-key="security" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<span class="h-2.5 w-2.5 rounded-full inline-block shrink-0" style="background-color: #f59e0b"></span>
<span class="flex-1 truncate">security</span>
<svg data-check width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class="shrink-0 text-success" aria-hidden="true" focusable="false"><polyline points="20 6 9 17 4 12"></polyline></svg>
</button>
<button type="button" role="menuitemcheckbox" aria-checked="false" data-key="enhancement" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<span class="h-2.5 w-2.5 rounded-full inline-block shrink-0" style="background-color: #22c55e"></span>
<span class="flex-1 truncate">enhancement</span>
<svg data-check hidden width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class="shrink-0 text-success" aria-hidden="true" focusable="false"><polyline points="20 6 9 17 4 12"></polyline></svg>
</button>
<button type="button" role="menuitemcheckbox" aria-checked="false" data-key="performance" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<span class="h-2.5 w-2.5 rounded-full inline-block shrink-0" style="background-color: #3b82f6"></span>
<span class="flex-1 truncate">performance</span>
<svg data-check hidden width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class="shrink-0 text-success" aria-hidden="true" focusable="false"><polyline points="20 6 9 17 4 12"></polyline></svg>
</button>
<button type="button" role="menuitemcheckbox" aria-checked="false" data-key="documentation" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<span class="h-2.5 w-2.5 rounded-full inline-block shrink-0" style="background-color: #06b6d4"></span>
<span class="flex-1 truncate">documentation</span>
<svg data-check hidden width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class="shrink-0 text-success" aria-hidden="true" focusable="false"><polyline points="20 6 9 17 4 12"></polyline></svg>
</button>
<div role="separator" class="my-1 h-px bg-border"></div>
<a href="settings.html" role="menuitem" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" class="shrink-0" aria-hidden="true" focusable="false"><path d="M20.59 13.41l-7.17 7.17a2 2 0 01-2.83 0L2 12V2h10l8.59 8.59a2 2 0 010 2.82z"></path><line x1="7" y1="7" x2="7.01" y2="7"></line></svg>
Create a new label
</a>
</div>
</div>
</div>
<div class="flex flex-wrap gap-1">
<span data-entry="bug" class="inline-block max-w-full truncate align-middle rounded-full border px-2 py-px text-[11px] leading-4 font-medium border-(color:--label-border) bg-(color:--label-bg) text-(color:--label-fg) dark:border-(color:--label-dark-border) dark:bg-(color:--label-dark-bg) dark:text-(color:--label-dark-fg)" style="--label-bg:#f15757;--label-fg:#1f2328;--label-border:#d44d4d;--label-dark-bg:#ef44442e;--label-dark-border:#ef444466;--label-dark-fg:#f26969">bug</span>
<span data-entry="security" class="inline-block max-w-full truncate align-middle rounded-full border px-2 py-px text-[11px] leading-4 font-medium border-(color:--label-border) bg-(color:--label-bg) text-(color:--label-fg) dark:border-(color:--label-dark-border) dark:bg-(color:--label-dark-bg) dark:text-(color:--label-dark-fg)" style="--label-bg:#f59e0b;--label-fg:#1f2328;--label-border:#d88b0a;--label-dark-bg:#f59e0b2e;--label-dark-border:#f59e0b66;--label-dark-fg:#f59e0b">security</span>
<span data-entry="enhancement" hidden class="inline-block max-w-full truncate align-middle rounded-full border px-2 py-px text-[11px] leading-4 font-medium border-(color:--label-border) bg-(color:--label-bg) text-(color:--label-fg) dark:border-(color:--label-dark-border) dark:bg-(color:--label-dark-bg) dark:text-(color:--label-dark-fg)" style="--label-bg:#22c55e;--label-fg:#1f2328;--label-border:#1ead53;--label-dark-bg:#22c55e2e;--label-dark-border:#22c55e66;--label-dark-fg:#22c55e">enhancement</span>
<span data-entry="performance" hidden class="inline-block max-w-full truncate align-middle rounded-full border px-2 py-px text-[11px] leading-4 font-medium border-(color:--label-border) bg-(color:--label-bg) text-(color:--label-fg) dark:border-(color:--label-dark-border) dark:bg-(color:--label-dark-bg) dark:text-(color:--label-dark-fg)" style="--label-bg:#4588f6;--label-fg:#1f2328;--label-border:#3d78d8;--label-dark-bg:#3b82f62e;--label-dark-border:#3b82f666;--label-dark-fg:#5895f7">performance</span>
<span data-entry="documentation" hidden class="inline-block max-w-full truncate align-middle rounded-full border px-2 py-px text-[11px] leading-4 font-medium border-(color:--label-border) bg-(color:--label-bg) text-(color:--label-fg) dark:border-(color:--label-dark-border) dark:bg-(color:--label-dark-bg) dark:text-(color:--label-dark-fg)" style="--label-bg:#06b6d4;--label-fg:#1f2328;--label-border:#05a0bb;--label-dark-bg:#06b6d42e;--label-dark-border:#06b6d466;--label-dark-fg:#06b6d4">documentation</span>
<span data-empty hidden class="text-xs text-muted-foreground">None yet</span>
</div>
</div>
</section>
<section data-meta class="border-t border-border pt-6">
<div class="space-y-2">
<div class="flex items-center justify-between">
<h3 class="text-[12px] font-medium text-muted-foreground">Priority</h3>
<div class="relative">
<button type="button" data-menu-btn aria-expanded="false" aria-haspopup="menu" aria-label="Set priority" class="text-muted-foreground hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" focusable="false"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 113 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>
</button>
<div data-menu-panel hidden role="menu" aria-label="Set priority" class="absolute right-0 top-full mt-1.5 z-50 w-56 rounded-md border border-border bg-popover text-popover-foreground shadow-md p-1">
<div class="px-2 pt-1 pb-0.5 text-[10px] font-medium uppercase tracking-wider text-muted-foreground">Set priority</div>
<button type="button" role="menuitemradio" aria-checked="false" data-key="P0" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<span class="h-2 w-2 rounded-full inline-block shrink-0 bg-destructive"></span>
<span class="flex-1 truncate">P0 · Critical</span>
<svg data-check hidden width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class="shrink-0 text-success" aria-hidden="true" focusable="false"><polyline points="20 6 9 17 4 12"></polyline></svg>
</button>
<button type="button" role="menuitemradio" aria-checked="true" data-key="P1" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<span class="h-2 w-2 rounded-full inline-block shrink-0 bg-blue-500"></span>
<span class="flex-1 truncate">P1 · High</span>
<svg data-check width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class="shrink-0 text-success" aria-hidden="true" focusable="false"><polyline points="20 6 9 17 4 12"></polyline></svg>
</button>
<button type="button" role="menuitemradio" aria-checked="false" data-key="P2" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<span class="h-2 w-2 rounded-full inline-block shrink-0 bg-warning"></span>
<span class="flex-1 truncate">P2 · Medium</span>
<svg data-check hidden width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class="shrink-0 text-success" aria-hidden="true" focusable="false"><polyline points="20 6 9 17 4 12"></polyline></svg>
</button>
<button type="button" role="menuitemradio" aria-checked="false" data-key="P3" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<span class="h-2 w-2 rounded-full inline-block shrink-0 bg-muted-foreground"></span>
<span class="flex-1 truncate">P3 · Low</span>
<svg data-check hidden width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class="shrink-0 text-success" aria-hidden="true" focusable="false"><polyline points="20 6 9 17 4 12"></polyline></svg>
</button>
<div role="separator" class="my-1 h-px bg-border"></div>
<button type="button" role="menuitemradio" aria-checked="false" data-key="none" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
No priority
</button>
</div>
</div>
</div>
<span data-entry="P0" hidden class="inline-flex items-center px-2 py-0.5 rounded-full text-[11px] font-medium border bg-destructive/10 text-destructive border-destructive/30">P0</span>
<span data-entry="P1" class="inline-flex items-center px-2 py-0.5 rounded-full text-[11px] font-medium border bg-blue-500/10 text-blue-500 border-blue-500/30">P1</span>
<span data-entry="P2" hidden class="inline-flex items-center px-2 py-0.5 rounded-full text-[11px] font-medium border bg-warning/10 text-warning border-warning/30">P2</span>
<span data-entry="P3" hidden class="inline-flex items-center px-2 py-0.5 rounded-full text-[11px] font-medium border bg-muted text-muted-foreground border-border">P3</span>
<span data-empty hidden class="text-xs text-muted-foreground">No priority</span>
</div>
</section>
<section data-meta class="border-t border-border pt-6">
<div class="space-y-2">
<div class="flex items-center justify-between">
<h3 class="text-[12px] font-medium text-muted-foreground">Milestone</h3>
<div class="relative">
<button type="button" data-menu-btn aria-expanded="false" aria-haspopup="menu" aria-label="Set milestone" class="text-muted-foreground hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" focusable="false"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 113 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>
</button>
<div data-menu-panel hidden role="menu" aria-label="Set milestone" class="absolute right-0 top-full mt-1.5 z-50 w-56 rounded-md border border-border bg-popover text-popover-foreground shadow-md p-1 max-h-72 overflow-y-auto">
<div class="px-2 pt-1 pb-0.5 text-[10px] font-medium uppercase tracking-wider text-muted-foreground">Set milestone</div>
<button type="button" role="menuitemradio" aria-checked="true" data-key="m1" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<span class="h-2 w-2 rounded-full inline-block shrink-0 bg-success"></span>
<span class="flex-1 truncate">v1.0 release</span>
<svg data-check width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class="shrink-0 text-success" aria-hidden="true" focusable="false"><polyline points="20 6 9 17 4 12"></polyline></svg>
</button>
<button type="button" role="menuitemradio" aria-checked="false" data-key="m2" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<span class="h-2 w-2 rounded-full inline-block shrink-0 bg-success"></span>
<span class="flex-1 truncate">v1.1 hardening</span>
<svg data-check hidden width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class="shrink-0 text-success" aria-hidden="true" focusable="false"><polyline points="20 6 9 17 4 12"></polyline></svg>
</button>
<div role="separator" class="my-1 h-px bg-border"></div>
<button type="button" role="menuitemradio" aria-checked="false" data-key="none" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
Clear milestone
</button>
<a href="milestone_new.html" role="menuitem" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" class="shrink-0" aria-hidden="true" focusable="false"><path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"></path><line x1="4" y1="22" x2="4" y2="15"></line></svg>
New milestone
</a>
</div>
</div>
</div>
<div data-entry="m1" class="text-sm">
<a href="milestone_detail.html" class="font-medium text-foreground hover:underline">v1.0 release</a>
<div class="mt-1">
<div class="w-full bg-muted rounded-full h-1">
<div class="bg-success h-1 rounded-full" style="width: 68%"></div>
</div>
<p class="text-xs text-muted-foreground mt-0.5">34/50 closed</p>
</div>
</div>
<div data-entry="m2" hidden class="text-sm">
<a href="milestone_detail.html" class="font-medium text-foreground hover:underline">v1.1 hardening</a>
<div class="mt-1">
<div class="w-full bg-muted rounded-full h-1">
<div class="bg-success h-1 rounded-full" style="width: 22%"></div>
</div>
<p class="text-xs text-muted-foreground mt-0.5">8/36 closed</p>
</div>
</div>
<span data-empty hidden class="text-xs text-muted-foreground">No milestone</span>
</div>
</section>
<section data-meta class="border-t border-border pt-6">
<div class="space-y-2">
<div class="flex items-center justify-between">
<h3 class="text-[12px] font-medium text-muted-foreground">Linked pull requests</h3>
<div class="relative">
<button type="button" data-menu-btn aria-expanded="false" aria-haspopup="menu" aria-label="Link a pull request" class="text-muted-foreground hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"></circle><path d="M12 8v8M8 12h8"></path></svg>
</button>
<div data-menu-panel hidden role="menu" aria-label="Link a pull request" class="absolute right-0 top-full mt-1.5 z-50 w-64 rounded-md border border-border bg-popover text-popover-foreground shadow-md p-1 max-h-72 overflow-y-auto">
<div class="px-2 pt-1 pb-0.5 text-[10px] font-medium uppercase tracking-wider text-muted-foreground">Link a pull request</div>
<button type="button" role="menuitemcheckbox" aria-checked="false" data-key="350" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="shrink-0 text-success" aria-hidden="true" focusable="false"><circle cx="18" cy="18" r="3"></circle><circle cx="6" cy="6" r="3"></circle><path d="M6 21V9a9 9 0 009 9"></path></svg>
<span class="flex-1 truncate"><span class="font-mono text-muted-foreground">#350</span> Harden SSH host key handling</span>
<svg data-check hidden width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class="shrink-0 text-success" aria-hidden="true" focusable="false"><polyline points="20 6 9 17 4 12"></polyline></svg>
</button>
<button type="button" role="menuitemcheckbox" aria-checked="false" data-key="361" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="shrink-0 text-success" aria-hidden="true" focusable="false"><circle cx="18" cy="18" r="3"></circle><circle cx="6" cy="6" r="3"></circle><path d="M6 21V9a9 9 0 009 9"></path></svg>
<span class="flex-1 truncate"><span class="font-mono text-muted-foreground">#361</span> Document known_hosts remediation</span>
<svg data-check hidden width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class="shrink-0 text-success" aria-hidden="true" focusable="false"><polyline points="20 6 9 17 4 12"></polyline></svg>
</button>
<button type="button" role="menuitemcheckbox" aria-checked="false" data-key="137" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="shrink-0 text-[hsl(270_70%_70%)]" aria-hidden="true" focusable="false"><circle cx="18" cy="18" r="3"></circle><circle cx="6" cy="6" r="3"></circle><path d="M6 21V9a9 9 0 009 9"></path></svg>
<span class="flex-1 truncate"><span class="font-mono text-muted-foreground">#137</span> Flush SSH pack writes in bounded chunks</span>
<svg data-check hidden width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class="shrink-0 text-success" aria-hidden="true" focusable="false"><polyline points="20 6 9 17 4 12"></polyline></svg>
</button>
<div role="separator" class="my-1 h-px bg-border"></div>
<a href="pulls.html" role="menuitem" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="shrink-0" aria-hidden="true" focusable="false"><line x1="6" y1="3" x2="6" y2="15"></line><circle cx="18" cy="6" r="3"></circle><circle cx="6" cy="18" r="3"></circle><path d="M18 9a9 9 0 01-9 9"></path></svg>
Browse pull requests
</a>
</div>
</div>
</div>
<ul class="space-y-1.5 text-[13px]">
<li data-entry="350" hidden class="flex items-center gap-2">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="shrink-0 text-success" aria-hidden="true" focusable="false"><circle cx="18" cy="18" r="3"></circle><circle cx="6" cy="6" r="3"></circle><path d="M6 21V9a9 9 0 009 9"></path></svg>
<a href="pr.html" class="hover:underline truncate">
<span class="font-mono text-muted-foreground">#350</span>
Harden SSH host key handling
</a>
</li>
<li data-entry="361" hidden class="flex items-center gap-2">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="shrink-0 text-success" aria-hidden="true" focusable="false"><circle cx="18" cy="18" r="3"></circle><circle cx="6" cy="6" r="3"></circle><path d="M6 21V9a9 9 0 009 9"></path></svg>
<a href="pr.html" class="hover:underline truncate">
<span class="font-mono text-muted-foreground">#361</span>
Document known_hosts remediation
</a>
</li>
<li data-entry="137" hidden class="flex items-center gap-2">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="shrink-0 text-[hsl(270_70%_70%)]" aria-hidden="true" focusable="false"><circle cx="18" cy="18" r="3"></circle><circle cx="6" cy="6" r="3"></circle><path d="M6 21V9a9 9 0 009 9"></path></svg>
<a href="pr.html" class="hover:underline truncate">
<span class="font-mono text-muted-foreground">#137</span>
Flush SSH pack writes in bounded chunks
</a>
</li>
</ul>
<p data-empty class="text-xs text-muted-foreground">No linked PRs yet.</p>
</div>
</section>
<section class="border-t border-border pt-6">
<div>
<h3 class="text-[12px] font-medium text-muted-foreground mb-2">Notifications</h3>
<button type="button" id="sub-toggle" aria-pressed="true" class="w-full h-8 inline-flex items-center justify-center gap-1.5 rounded-md border text-[13px]"></button>
<p id="sub-note" class="mt-2 text-[12px] text-muted-foreground"></p>
</div>
</section>
<section class="border-t border-border pt-6">
<h3 class="text-[12px] font-medium text-muted-foreground mb-2">Maintainer</h3>
<div class="space-y-1.5">
<button type="button" id="pin-toggle" aria-pressed="false" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md border border-border text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" class="shrink-0" aria-hidden="true" focusable="false"><line x1="12" y1="17" x2="12" y2="22"></line><path d="M9 4h6l-1 7 3 3H7l3-3-1-7z"></path></svg>
<span id="pin-label">Pin issue</span>
</button>
<button type="button" id="lock-toggle" aria-pressed="false" class="flex w-full items-center gap-2 px-2.5 py-1.5 rounded-md border border-border text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" class="shrink-0" aria-hidden="true" focusable="false"><rect x="4" y="11" width="16" height="10" rx="2"></rect><path d="M8 11V7a4 4 0 018 0v4"></path></svg>
<span id="lock-label">Lock conversation</span>
</button>
</div>
</section>
</aside>
</div>
</div>
<dialog id="close-issue-dialog" class="rounded-lg border border-border bg-popover text-popover-foreground p-0 w-[480px] max-w-[calc(100vw-2rem)] max-h-[calc(100dvh-2rem)] overflow-y-auto mt-[28vh] mb-auto translate-y-[min(0px,calc(100dvh-28vh-1rem-100%))] backdrop:bg-black/60 backdrop:backdrop-blur-xs" aria-labelledby="close-issue-dialog-title">
<div class="sticky top-0 z-10 bg-popover flex flex-col gap-1 p-5 border-b border-border">
<h2 id="close-issue-dialog-title" class="text-base font-semibold leading-tight">Close this issue?</h2>
<p class="text-[13px] text-muted-foreground leading-snug">Close issue <strong class="text-foreground">#214</strong> — <strong class="text-foreground">SSH host key rotation breaks existing client fingerprints</strong>. You can reopen it later if needed.</p>
</div>
<div class="sticky bottom-0 z-10 bg-popover flex items-center justify-end gap-2 p-5 border-t border-border">
<form method="dialog" class="contents">
<button type="submit" class="inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors border border-input bg-transparent hover:bg-accent hover:text-accent-foreground h-9 px-4">Cancel</button>
</form>
<button type="button" id="close-confirm" class="inline-flex items-center justify-center rounded-md text-sm font-medium h-9 px-4 bg-destructive text-destructive-foreground hover:bg-destructive/90">Close issue</button>
</div>
</dialog>
</main>
<div id="cz-footer"></div>
<script src="shell.js"></script>
<script>
(function () {
var ON = ['border-foreground', 'text-foreground', 'font-medium'];
var OFF = ['border-transparent', 'text-muted-foreground', 'hover:text-foreground'];
function mode(ed, m) {
ed.querySelectorAll('[data-md-tab]').forEach(function (t) {
var on = t.dataset.mdTab === m;
ON.forEach(function (c) { t.classList.toggle(c, on); });
OFF.forEach(function (c) { t.classList.toggle(c, !on); });
t.setAttribute('aria-selected', String(on));
});
var ta = ed.querySelector('textarea');
var pv = ed.querySelector('[data-md-pane="preview"]');
ed.querySelector('[data-md-pane="write"]').classList.toggle('hidden', m !== 'write');
pv.classList.toggle('hidden', m !== 'preview');
if (m === 'preview') pv.textContent = ta.value.trim() || 'Nothing to preview.';
}
var PAIRS = { bold: ['**', '**'], italic: ['*', '*'], code: ['`', '`'], link: ['[', '](url)'] };
document.addEventListener('click', function (e) {
var tab = e.target.closest('[data-md-tab]');
if (tab) return mode(tab.closest('[data-md-editor]'), tab.dataset.mdTab);
var act = e.target.closest('[data-md-action]');
if (!act) return;
var ta = act.closest('[data-md-editor]').querySelector('textarea');
var p = PAIRS[act.dataset.mdAction], s = ta.selectionStart, en = ta.selectionEnd;
ta.setRangeText(p[0] + ta.value.slice(s, en) + p[1], s, en, 'end');
ta.focus();
});
})();
</script>
<script>
(function () {
function closeAll(except) {
document.querySelectorAll('[data-menu-panel]').forEach(function (p) { if (p !== except) p.hidden = true; });
document.querySelectorAll('[data-menu-btn]').forEach(function (b) {
b.setAttribute('aria-expanded', String(!!except && except.previousElementSibling === b && !except.hidden));
});
}
document.addEventListener('click', function (e) {
var btn = e.target.closest('[data-menu-btn]');
if (btn) {
var panel = btn.nextElementSibling;
var open = panel.hidden;
closeAll();
panel.hidden = !open;
btn.setAttribute('aria-expanded', String(open));
return;
}
var item = e.target.closest('[data-menu-panel] [data-key]');
if (item) {
var panel2 = item.closest('[data-menu-panel]');
var section = panel2.closest('[data-meta]');
var key = item.dataset.key;
var radio = item.getAttribute('role') === 'menuitemradio';
var on = radio ? true : item.getAttribute('aria-checked') !== 'true';
if (radio) {
panel2.querySelectorAll('[data-key]').forEach(function (it) {
var sel = it === item && key !== 'none';
it.setAttribute('aria-checked', String(sel));
var c = it.querySelector('[data-check]');
if (c) c.hidden = !sel;
});
section.querySelectorAll('[data-entry]').forEach(function (en) { en.hidden = en.dataset.entry !== key; });
} else {
item.setAttribute('aria-checked', String(on));
item.querySelector('[data-check]').hidden = !on;
var entry = section.querySelector('[data-entry="' + key + '"]');
if (entry) entry.hidden = !on;
}
var empty = section.querySelector('[data-empty]');
if (empty) empty.hidden = Array.prototype.some.call(section.querySelectorAll('[data-entry]'), function (en) { return !en.hidden; });
if (radio) closeAll();
return;
}
if (!e.target.closest('[data-menu-panel]')) closeAll();
});
document.addEventListener('keydown', function (e) { if (e.key === 'Escape') closeAll(); });
})();
</script>
<script>
(function () {
function $(id) { return document.getElementById(id); }
function swap(viewEls, formEl, on) {
viewEls.forEach(function (el) { el.hidden = on; });
formEl.hidden = !on;
}
$('title-edit').addEventListener('click', function () {
swap([$('title-text').parentElement, $('title-edit')], $('title-form'), true);
$('title-input').focus();
});
$('title-cancel').addEventListener('click', function () {
swap([$('title-text').parentElement, $('title-edit')], $('title-form'), false);
});
$('title-form').addEventListener('submit', function (e) {
e.preventDefault();
$('title-text').textContent = $('title-input').value;
swap([$('title-text').parentElement, $('title-edit')], $('title-form'), false);
});
var descEls = [$('desc-rendered'), $('desc-edit')];
$('desc-edit').addEventListener('click', function () { swap(descEls, $('desc-form'), true); });
$('desc-cancel').addEventListener('click', function () { swap(descEls, $('desc-form'), false); });
$('desc-form').addEventListener('submit', function (e) { e.preventDefault(); swap(descEls, $('desc-form'), false); });
var sub = $('sub-toggle'), note = $('sub-note');
var BELL = '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true" focusable="false"><path d="M6 8a6 6 0 0112 0c0 7 3 9 3 9H3s3-2 3-9"></path><path d="M10.3 21a1.94 1.94 0 003.4 0"></path></svg>';
var BELL_OFF = '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true" focusable="false"><path d="M13.7 21a2 2 0 01-3.4 0M18.6 13A17 17 0 0118 8M6.3 6.3A6 6 0 006 8c0 7-3 9-3 9h14M18 8a6 6 0 00-9.3-5M1 1l22 22"></path></svg>';
function renderSub() {
var on = sub.getAttribute('aria-pressed') === 'true';
sub.className = 'w-full h-8 inline-flex items-center justify-center gap-1.5 rounded-md border text-[13px] ' + (on
? 'border-border bg-accent text-foreground hover:bg-accent/70'
: 'border-border text-muted-foreground hover:bg-accent hover:text-foreground');
sub.innerHTML = on ? BELL_OFF + ' Unsubscribe' : BELL + ' Subscribe';
note.innerHTML = on ? '<span>You\u2019re receiving notifications. <em>You opened this thread.</em></span>' : '<span>You\u2019re not receiving notifications from this thread.</span>';
}
sub.addEventListener('click', function () { sub.setAttribute('aria-pressed', String(sub.getAttribute('aria-pressed') !== 'true')); renderSub(); });
renderSub();
function toggle(btn, label, on, off, after) {
btn.addEventListener('click', function () {
var v = btn.getAttribute('aria-pressed') !== 'true';
btn.setAttribute('aria-pressed', String(v));
label.textContent = v ? on : off;
if (after) after(v);
});
}
toggle($('pin-toggle'), $('pin-label'), 'Unpin issue', 'Pin issue');
toggle($('lock-toggle'), $('lock-label'), 'Unlock conversation', 'Lock conversation', function (v) { $('issue-locked-badge').hidden = !v; });
var dlg = $('close-issue-dialog'), openBtn = $('close-issue-btn');
if (dlg && openBtn) {
openBtn.addEventListener('click', function () { dlg.showModal(); });
$('close-confirm').addEventListener('click', function () { location.href = 'issue_detail_closed.html'; });
}
var reopen = $('reopen-btn');
if (reopen) reopen.addEventListener('click', function () { location.href = 'issue_detail.html'; });
})();
</script>
</body>
</html>