# Trace: Integrate Plugin Inline Under Reviewers Section

Agent: opencode | Model: GPT-5.3 Codex | Project: explorer-chrome-extension

---

## User

Put this plugin inline under the reviewers and follow the same style and spacing as github [Image 1]

Also, remove mentions of "Open Source Explorer" just at the bottom of it say in light Powered by the Open Source Explorer but very subtle

REmove all the borders etc so it looks like a part of the github page 

## Assistant

## Assistant

### Tool: glob

**Args:**
```json
{
  "pattern": "*"
}
```

## Assistant

**Result** (success):
```
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/opencode
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/index
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/manifest.json
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/background.js
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/config
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/README.md
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/refs/heads/main
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/logs/refs/remotes/origin/HEAD
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/logs/refs/heads/main
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/logs/HEAD
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/HEAD
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/packed-refs
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/refs/remotes/origin/HEAD
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/objects/pack/pack-2e6748d550d0dcb237f1086fb3508d457c4f2339.rev
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/objects/pack/pack-2e6748d550d0dcb237f1086fb3508d457c4f2339.pack
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/objects/pack/pack-2e6748d550d0dcb237f1086fb3508d457c4f2339.idx
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/hooks/push-to-checkout.sample
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/hooks/update.sample
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/hooks/pre-push.sample
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/hooks/pre-applypatch.sample
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/hooks/pre-merge-commit.sample
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/hooks/post-update.sample
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/hooks/prepare-commit-msg.sample
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/hooks/pre-receive.sample
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/hooks/fsmonitor-watchman.sample
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/hooks/applypatch-msg.sample
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/hooks/pre-commit.sample
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/hooks/sendemail-validate.sample
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/hooks/pre-rebase.sample
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/hooks/commit-msg.sample
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/description
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/.git/info/exclude
```

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js"
}
```

## Assistant

**Result** (success):
```
<file>
00001| (() => {
00002|   const STORAGE_KEY = "md_expert_pr_config";
00003|   const STYLE_ID = "md-expert-pr-style";
00004|   const PANEL_ID = "md-expert-pr-panel";
00005|   const BADGE_ID = "md-expert-pr-badge";
00006| 
00007|   const DEFAULT_CONFIG = {
00008|     apiKey: "",
00009|     settingsOpen: false
00010|   };
00011| 
00012|   const state = {
00013|     config: loadConfig(),
00014|     currentResult: null,
00015|     listCache: new Map()
00016|   };
00017| 
00018|   function loadConfig() {
00019|     const raw = window.localStorage.getItem(STORAGE_KEY);
00020|     if (!raw) return { ...DEFAULT_CONFIG };
00021|     try {
00022|       const parsed = JSON.parse(raw);
00023|       return { ...DEFAULT_CONFIG, ...parsed };
00024|     } catch (error) {
00025|       return { ...DEFAULT_CONFIG };
00026|     }
00027|   }
00028| 
00029|   function saveConfig(nextConfig) {
00030|     state.config = { ...DEFAULT_CONFIG, ...nextConfig };
00031|     window.localStorage.setItem(STORAGE_KEY, JSON.stringify(state.config));
00032|   }
00033| 
00034|   function isPullDetailPage() {
00035|     return /\/pull\/(\d+)(\/|$)/.test(window.location.pathname);
00036|   }
00037| 
00038|   function isPullListPage() {
00039|     return /\/pulls(\/|$)/.test(window.location.pathname);
00040|   }
00041| 
00042|   function canUseBackground() {
00043|     return typeof chrome !== "undefined" && chrome.runtime && chrome.runtime.sendMessage;
00044|   }
00045| 
00046|   function fetchViaBackground(url, apiKey) {
00047|     if (!canUseBackground()) return Promise.resolve(null);
00048|     return new Promise((resolve) => {
00049|       chrome.runtime.sendMessage(
00050|         { type: "md-expert-pr-check", url, apiKey },
00051|         (response) => {
00052|           if (chrome.runtime.lastError) {
00053|             resolve(null);
00054|             return;
00055|           }
00056|           resolve(response);
00057|         }
00058|       );
00059|     });
00060|   }
00061| 
00062|   function ensureStyles() {
00063|     if (document.getElementById(STYLE_ID)) return;
00064|     const style = document.createElement("style");
00065|     style.id = STYLE_ID;
00066|     style.textContent = `
00067|       #${PANEL_ID} {
00068|         position: fixed;
00069|         right: 16px;
00070|         bottom: 16px;
00071|         z-index: 999999;
00072|         font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
00073|         color: #1f2328;
00074|       }
00075|       #${PANEL_ID} .md-pr-panel {
00076|         width: 440px;
00077|         background: #ffffff;
00078|         border: 1px solid #d0d7de;
00079|         border-radius: 12px;
00080|         box-shadow: 0 1px 3px rgba(27, 31, 36, 0.12);
00081|         padding: 12px 12px 10px;
00082|         font-size: 14px;
00083|       }
00084|       #${PANEL_ID} .md-pr-header {
00085|         display: flex;
00086|         justify-content: flex-end;
00087|         align-items: center;
00088|         gap: 8px;
00089|         font-weight: 600;
00090|         font-size: 13px;
00091|       }
00092|       #${PANEL_ID} .md-pr-gear {
00093|         border: none;
00094|         background: #f6f8fa;
00095|         border-radius: 6px;
00096|         width: 28px;
00097|         height: 28px;
00098|         display: inline-flex;
00099|         align-items: center;
00100|         justify-content: center;
00101|         cursor: pointer;
00102|         border: 1px solid #d0d7de;
00103|         color: #57606a;
00104|       }
00105|       #${PANEL_ID} .md-pr-body {
00106|         margin-top: 10px;
00107|       }
00108|       #${PANEL_ID} .md-pr-settings {
00109|         display: none;
00110|         margin-top: 10px;
00111|         border-top: 1px dashed #d0d7de;
00112|         padding-top: 10px;
00113|       }
00114|       #${PANEL_ID} .md-pr-settings.md-pr-open {
00115|         display: block;
00116|       }
00117|       #${PANEL_ID} label {
00118|         display: block;
00119|         margin-bottom: 6px;
00120|         font-weight: 600;
00121|         font-size: 12px;
00122|         color: #57606a;
00123|       }
00124|       #${PANEL_ID} input[type="text"],
00125|       #${PANEL_ID} input[type="password"] {
00126|         width: 100%;
00127|         border: 1px solid #d0d7de;
00128|         border-radius: 6px;
00129|         padding: 6px 8px;
00130|         font-size: 14px;
00131|         background: #ffffff;
00132|         margin-bottom: 8px;
00133|       }
00134|       #${PANEL_ID} .md-pr-status {
00135|         margin-top: 8px;
00136|         color: #57606a;
00137|       }
00138|       #${PANEL_ID} .md-pr-warning {
00139|         color: #cf222e;
00140|         font-weight: 600;
00141|       }
00142|       #${PANEL_ID} .md-pr-success {
00143|         color: #1a7f37;
00144|         font-weight: 600;
00145|       }
00146|       #${PANEL_ID} .md-pr-details {
00147|         margin-top: 6px;
00148|         color: #24292f;
00149|       }
00150|       #${PANEL_ID} .md-pr-summary {
00151|         margin-top: 6px;
00152|         font-size: 18px;
00153|         color: #24292f;
00154|         font-weight: 600;
00155|       }
00156|       #${PANEL_ID} .md-pr-card {
00157|         border: 1px solid #d0d7de;
00158|         border-radius: 10px;
00159|         padding: 12px;
00160|       }
00161|       #${PANEL_ID} .md-pr-card-header {
00162|         display: flex;
00163|         gap: 12px;
00164|         align-items: center;
00165|       }
00166|       #${PANEL_ID} .md-pr-avatar {
00167|         width: 56px;
00168|         height: 56px;
00169|         border-radius: 50%;
00170|         background: #f6f8fa;
00171|         border: 1px solid #d0d7de;
00172|         overflow: hidden;
00173|         display: inline-flex;
00174|         align-items: center;
00175|         justify-content: center;
00176|         font-weight: 600;
00177|         color: #57606a;
00178|       }
00179|       #${PANEL_ID} .md-pr-avatar img {
00180|         width: 100%;
00181|         height: 100%;
00182|         object-fit: cover;
00183|       }
00184|       #${PANEL_ID} .md-pr-name {
00185|         font-size: 18px;
00186|         font-weight: 700;
00187|         color: #1a7f37;
00188|       }
00189|       #${PANEL_ID} .md-pr-meta {
00190|         margin-top: 6px;
00191|         color: #57606a;
00192|         font-size: 14px;
00193|       }
00194|       #${PANEL_ID} .md-pr-links {
00195|         margin-top: 6px;
00196|         display: flex;
00197|         gap: 12px;
00198|         font-size: 14px;
00199|       }
00200|       #${PANEL_ID} .md-pr-link {
00201|         color: #0969da;
00202|         font-weight: 600;
00203|       }
00204|       #${PANEL_ID} .md-pr-stats {
00205|         margin-top: 12px;
00206|         border: 1px solid #d0d7de;
00207|         border-radius: 8px;
00208|         overflow: hidden;
00209|       }
00210|       #${PANEL_ID} .md-pr-stat-row {
00211|         display: flex;
00212|         justify-content: space-between;
00213|         align-items: center;
00214|         padding: 8px 10px;
00215|         border-bottom: 1px solid #d0d7de;
00216|         font-size: 14px;
00217|       }
00218|       #${PANEL_ID} .md-pr-stat-row:last-child {
00219|         border-bottom: none;
00220|       }
00221|       #${PANEL_ID} .md-pr-stat-label {
00222|         color: #57606a;
00223|         text-transform: uppercase;
00224|         letter-spacing: 0.04em;
00225|         font-weight: 600;
00226|         font-size: 11px;
00227|       }
00228|       #${PANEL_ID} .md-pr-stat-value {
00229|         font-weight: 700;
00230|         color: #24292f;
00231|       }
00232|       #${PANEL_ID} .md-pr-section {
00233|         margin-top: 12px;
00234|       }
00235|       #${PANEL_ID} .md-pr-section-title {
00236|         font-size: 13px;
00237|         font-weight: 600;
00238|         color: #57606a;
00239|         text-transform: uppercase;
00240|         letter-spacing: 0.04em;
00241|         margin-bottom: 6px;
00242|       }
00243|       #${PANEL_ID} .md-pr-ecosystems {
00244|         display: flex;
00245|         flex-wrap: wrap;
00246|         gap: 6px;
00247|       }
00248|       #${PANEL_ID} .md-pr-ecosystem-pill {
00249|         display: inline-flex;
00250|         align-items: center;
00251|         background: #f6f8fa;
00252|         border: 1px solid #d0d7de;
00253|         border-radius: 999px;
00254|         padding: 2px 8px;
00255|         font-size: 13px;
00256|         color: #57606a;
00257|         text-decoration: none;
00258|       }
00259|       #${PANEL_ID} .md-pr-project-list {
00260|         display: flex;
00261|         flex-direction: column;
00262|         gap: 6px;
00263|       }
00264|       #${PANEL_ID} .md-pr-project-item {
00265|         display: flex;
00266|         justify-content: space-between;
00267|         gap: 8px;
00268|         font-size: 14px;
00269|         color: #24292f;
00270|       }
00271|       #${PANEL_ID} .md-pr-project-meta {
00272|         color: #57606a;
00273|         font-size: 13px;
00274|       }
00275|       .md-pr-list-indicator {
00276|         display: inline-flex;
00277|         align-items: center;
00278|         justify-content: center;
00279|         width: 8px;
00280|         height: 8px;
00281|         border-radius: 999px;
00282|         margin-left: 6px;
00283|         border: 1px solid #d0d7de;
00284|       }
00285|       .md-pr-list-indicator.md-pr-list-expert {
00286|         background: #2da44e;
00287|         border-color: #2da44e;
00288|       }
00289|       .md-pr-list-indicator.md-pr-list-missing {
00290|         background: #afb8c1;
00291|       }
00292|       #${PANEL_ID} .md-pr-section {
00293|         margin-top: 8px;
00294|       }
00295|       #${PANEL_ID} .md-pr-section-title {
00296|         font-size: 11px;
00297|         font-weight: 600;
00298|         text-transform: uppercase;
00299|         letter-spacing: 0.04em;
00300|         color: #6b7280;
00301|         margin-bottom: 4px;
00302|       }
00303|       #${PANEL_ID} .md-pr-stats {
00304|         display: grid;
00305|         grid-template-columns: repeat(3, minmax(0, 1fr));
00306|         gap: 6px;
00307|       }
00308|       #${PANEL_ID} .md-pr-stat {
00309|         background: #ffffff;
00310|         border: 1px solid #e5e7eb;
00311|         border-radius: 8px;
00312|         padding: 6px;
00313|         text-align: center;
00314|       }
00315|       #${PANEL_ID} .md-pr-stat-label {
00316|         font-size: 10px;
00317|         text-transform: uppercase;
00318|         letter-spacing: 0.05em;
00319|         color: #6b7280;
00320|       }
00321|       #${PANEL_ID} .md-pr-stat-value {
00322|         font-size: 13px;
00323|         font-weight: 600;
00324|         color: #111827;
00325|       }
00326|       #${PANEL_ID} .md-pr-pill {
00327|         display: inline-flex;
00328|         align-items: center;
00329|         padding: 2px 6px;
00330|         border-radius: 999px;
00331|         background: #eef2ff;
00332|         color: #3730a3;
00333|         font-size: 11px;
00334|         margin-right: 4px;
00335|         margin-bottom: 4px;
00336|       }
00337|       #${PANEL_ID} .md-pr-link {
00338|         color: #0a3069;
00339|         font-weight: 600;
00340|       }
00341|       #${BADGE_ID} {
00342|         display: inline-flex;
00343|         align-items: center;
00344|         gap: 6px;
00345|         margin-left: 8px;
00346|         padding: 2px 8px;
00347|         border-radius: 999px;
00348|         font-size: 11px;
00349|         font-weight: 600;
00350|       }
00351|       #${BADGE_ID}.md-pr-badge-error {
00352|         background: #ffe4e8;
00353|         color: #9f1239;
00354|       }
00355|       #${BADGE_ID}.md-pr-badge-success {
00356|         background: #dcfce7;
00357|         color: #166534;
00358|       }
00359|     `;
00360|     document.head.appendChild(style);
00361|   }
00362| 
00363|   function ensurePanel() {
00364|     const existing = document.getElementById(PANEL_ID);
00365|     if (!isPullDetailPage()) {
00366|       if (existing) existing.remove();
00367|       removeBadge();
00368|       return;
00369|     }
00370| 
00371|     ensureStyles();
00372| 
00373|     if (existing) {
00374|       updatePanel(existing);
00375|       return;
00376|     }
00377| 
00378|     const wrapper = document.createElement("div");
00379|     wrapper.id = PANEL_ID;
00380|     wrapper.innerHTML = `
00381|       <div class="md-pr-panel">
00382|         <div class="md-pr-header">
00383|           <span></span>
00384|           <button class="md-pr-gear" type="button" aria-label="Settings">
00385|             <span aria-hidden="true">⚙</span>
00386|           </button>
00387|         </div>
00388|         <div class="md-pr-body">
00389|           <div class="md-pr-summary"></div>
00390|           <div class="md-pr-status"></div>
00391|           <div class="md-pr-details"></div>
00392|         </div>
00393|         <div class="md-pr-settings ${state.config.settingsOpen ? "md-pr-open" : ""}">
00394|           <label>API key</label>
00395|           <input type="password" data-config="apiKey" />
00396|           <div class="md-pr-status"></div>
00397|         </div>
00398|       </div>
00399|     `;
00400| 
00401|     wrapper.querySelector(".md-pr-gear").addEventListener("click", () => {
00402|       const settings = wrapper.querySelector(".md-pr-settings");
00403|       const open = settings.classList.toggle("md-pr-open");
00404|       saveConfig({ ...state.config, settingsOpen: open });
00405|     });
00406| 
00407|     wrapper.querySelectorAll("[data-config]").forEach((input) => {
00408|       const key = input.getAttribute("data-config");
00409|       input.value = state.config[key] ?? "";
00410|       input.addEventListener("change", () => {
00411|         if (key === "apiKey") {
00412|           state.listCache.clear();
00413|         }
00414|         saveConfig({ ...state.config, [key]: input.value });
00415|         applyCheck();
00416|         applyListIndicators();
00417|       });
00418|     });
00419| 
00420|     document.body.appendChild(wrapper);
00421|     updatePanel(wrapper);
00422|   }
00423| 
00424|   function updatePanel(wrapper) {
00425|     const summary = wrapper.querySelector(".md-pr-summary");
00426|     const statusBlocks = wrapper.querySelectorAll(".md-pr-status");
00427|     const details = wrapper.querySelector(".md-pr-details");
00428|     const result = state.currentResult;
00429| 
00430|     statusBlocks.forEach((status) => {
00431|       status.textContent = "";
00432|       status.innerHTML = "";
00433|     });
00434| 
00435|     if (!result) {
00436|       statusBlocks.forEach((status) => {
00437|         status.textContent = "Checking PR author...";
00438|       });
00439|       summary.textContent = "";
00440|       details.textContent = "";
00441|       return;
00442|     }
00443| 
00444|     if (result.state === "missing-key") {
00445|       statusBlocks.forEach((status) => {
00446|         status.innerHTML = `<span class="md-pr-warning">API key required</span>`;
00447|       });
00448|       summary.textContent = "";
00449|       details.textContent = "";
00450|       return;
00451|     }
00452| 
00453|     if (result.state === "error") {
00454|       statusBlocks.forEach((status) => {
00455|         status.innerHTML = `<span class="md-pr-warning">${result.message}</span>`;
00456|       });
00457|       summary.textContent = "";
00458|       details.textContent = "";
00459|       return;
00460|     }
00461| 
00462|     if (result.state === "not-expert") {
00463|       statusBlocks.forEach((status) => {
00464|         status.innerHTML = "";
00465|       });
00466|       summary.innerHTML = `No profile found on the Open Source Explorer. <a class="md-pr-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Explore</a>`;
00467|       details.innerHTML = "";
00468|       return;
00469|     }
00470| 
00471|     if (result.state === "expert") {
00472|       statusBlocks.forEach((status) => {
00473|         status.innerHTML = "";
00474|       });
00475|       const info = result.expert && result.expert.expert ? result.expert.expert : result.expert;
00476|       summary.textContent = buildSummary(info, result.username);
00477|       details.innerHTML = renderExpertDetails(info, result.username);
00478|     }
00479|   }
00480| 
00481|   function buildSummary(info, username) {
00482|     if (!info) return `This PR was opened by ${username}.`;
00483|     const name = info.name || username;
00484|     const downloadsRaw = Number(info.total_downloads || 0);
00485|     const downloads = downloadsRaw > 0 ? formatCompactNumber(downloadsRaw) : null;
00486|     const stars = formatCompactNumber(info.total_stars);
00487|     const downloadText = downloads ? `${downloads} total downloads` : "";
00488|     const starsText = stars ? `${stars} stars on repos` : "";
00489|     const stats = [downloadText, starsText].filter(Boolean).join(", ");
00490|     if (!stats) return `This PR was opened by ${name} (${username}).`;
00491|     return `This PR was opened by ${name} (${username}). They have received ${stats}.`;
00492|   }
00493| 
00494|   function formatCompactNumber(value) {
00495|     if (value === null || value === undefined) return null;
00496|     const num = Number(value);
00497|     if (Number.isNaN(num)) return null;
00498|     return new Intl.NumberFormat("en", {
00499|       notation: "compact",
00500|       maximumFractionDigits: 1
00501|     }).format(num);
00502|   }
00503| 
00504|   function renderExpertDetails(info, username) {
00505|     const profileUrl = `https://explore.market.dev/experts/${encodeURIComponent(username)}`;
00506|     if (!info) {
00507|       return `Expert profile: <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Open</a>`;
00508|     }
00509| 
00510|     const name = info.name || username;
00511|     const avatarUrl = info.avatar_url || info.avatar || null;
00512|     const location = info.location || info.display_location || "";
00513| 
00514|     const stats = [
00515|       { label: "Projects", value: formatCompactNumber(info.projects_count) },
00516|       { label: "Downloads", value: formatCompactNumber(info.total_downloads) },
00517|       { label: "Stars", value: formatCompactNumber(info.total_stars) }
00518|     ].filter((stat) => stat.value !== null);
00519| 
00520|     const projects = Array.isArray(info.projects) ? info.projects : [];
00521|     const sortedProjects = [...projects].sort((a, b) => {
00522|       const starsA = Number(a.total_stars || a.stars || 0);
00523|       const starsB = Number(b.total_stars || b.stars || 0);
00524|       if (starsB !== starsA) return starsB - starsA;
00525|       const downloadsA = Number(a.total_downloads || a.downloads || 0);
00526|       const downloadsB = Number(b.total_downloads || b.downloads || 0);
00527|       return downloadsB - downloadsA;
00528|     });
00529|     const maintainerItems = sortedProjects.slice(0, 10).map((project) => {
00530|       const role = project.role || project.project_experts?.[0]?.role;
00531|       const name = project.name || project.slug || "";
00532|       if (!name) return null;
00533|       const stars = formatCompactNumber(project.total_stars || project.stars);
00534|       const downloads = formatCompactNumber(project.total_downloads || project.downloads);
00535|       const metaParts = [stars ? `${stars} stars` : null, downloads ? `${downloads} downloads` : null]
00536|         .filter(Boolean)
00537|         .join(" · ");
00538|       const label = role ? `${role} of ${name}` : name;
00539|       const projectSlug = project.slug || project.name || "";
00540|       const projectUrl =
00541|         project.github_url ||
00542|         project.repo_url ||
00543|         project.url ||
00544|         (projectSlug ? `https://explore.market.dev/projects/${encodeURIComponent(projectSlug)}` : null);
00545|       return { label, meta: metaParts, url: projectUrl };
00546|     }).filter(Boolean);
00547| 
00548|     const ecosystems =
00549|       (Array.isArray(info.ecosystems) && info.ecosystems) ||
00550|       (Array.isArray(info.ecosystem_names) && info.ecosystem_names) ||
00551|       [];
00552| 
00553|     const ecosystemNames = ecosystems
00554|       .map((eco) => (typeof eco === "string" ? eco : eco.name))
00555|       .filter(Boolean)
00556|       .slice(0, 8)
00557|       .map((name) => ({
00558|         name,
00559|         url: `https://explore.market.dev/ecosystems/${encodeURIComponent(name)}`
00560|       }));
00561| 
00562|     return `
00563|       <div class="md-pr-card">
00564|         <div class="md-pr-card-header">
00565|           <div class="md-pr-avatar">
00566|             ${avatarUrl ? `<img src="${avatarUrl}" alt="${name}" />` : name.slice(0, 1).toUpperCase()}
00567|           </div>
00568|           <div>
00569|             <div class="md-pr-name">${name}</div>
00570|             <div class="md-pr-meta">@${username}${location ? ` · ${location}` : ""}</div>
00571|             <div class="md-pr-links">
00572|               <a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">GitHub</a>
00573|               <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Market.dev</a>
00574|             </div>
00575|           </div>
00576|         </div>
00577|         ${stats.length ? `
00578|           <div class="md-pr-stats">
00579|             ${stats
00580|               .map(
00581|                 (stat) => `
00582|                   <div class="md-pr-stat-row">
00583|                     <span class="md-pr-stat-label">${stat.label}</span>
00584|                     <span class="md-pr-stat-value">${stat.value}</span>
00585|                   </div>
00586|                 `
00587|               )
00588|               .join("")}
00589|           </div>
00590|         ` : ""}
00591|         ${ecosystemNames.length ? `
00592|           <div class="md-pr-section">
00593|             <div class="md-pr-section-title">Ecosystems</div>
00594|             <div class="md-pr-ecosystems">
00595|               ${ecosystemNames
00596|                 .map((eco) => `<a class="md-pr-ecosystem-pill" href="${eco.url}" target="_blank" rel="noopener noreferrer">${eco.name}</a>`)
00597|                 .join("")}
00598|             </div>
00599|           </div>
00600|         ` : ""}
00601|         ${maintainerItems.length ? `
00602|           <div class="md-pr-section">
00603|             <div class="md-pr-section-title">Projects</div>
00604|             <div class="md-pr-project-list">
00605|               ${maintainerItems
00606|                 .map(
00607|                   (item) => `
00608|                     <div class="md-pr-project-item">
00609|                       ${item.url ? `<a class="md-pr-link" href="${item.url}" target="_blank" rel="noopener noreferrer">${item.label}</a>` : `<span>${item.label}</span>`}
00610|                       ${item.meta ? `<span class="md-pr-project-meta">${item.meta}</span>` : ""}
00611|                     </div>
00612|                   `
00613|                 )
00614|                 .join("")}
00615|             </div>
00616|           </div>
00617|         ` : ""}
00618|       </div>
00619|     `;
00620|   }
00621| 
00622|   function findPrAuthor() {
00623|     const selectors = [
00624|       ".gh-header-meta .author",
00625|       ".js-discussion .timeline-comment-header .author",
00626|       ".js-discussion .author",
00627|       ".timeline-comment-header .author",
00628|       "a.author"
00629|     ];
00630|     for (const selector of selectors) {
00631|       const el = document.querySelector(selector);
00632|       if (el && el.textContent.trim()) return el.textContent.trim();
00633|     }
00634|     return null;
00635|   }
00636| 
00637|   function removeBadge() {
00638|     const existing = document.getElementById(BADGE_ID);
00639|     if (existing) existing.remove();
00640|   }
00641| 
00642|   function updateBadge(result) {
00643|     const header = document.querySelector(".gh-header-title") || document.querySelector(".gh-header-meta");
00644|     if (!header) return;
00645| 
00646|     removeBadge();
00647|     if (!result || result.state === "error" || result.state === "missing-key") return;
00648| 
00649|     const badge = document.createElement("span");
00650|     badge.id = BADGE_ID;
00651| 
00652|     if (result.state === "not-expert") {
00653|       badge.className = "md-pr-badge-error";
00654|       badge.textContent = "No Profile";
00655|       header.appendChild(badge);
00656|     }
00657|   }
00658| 
00659|   async function fetchExpert(username) {
00660|     const apiKey = String(state.config.apiKey || "").trim();
00661|     if (!apiKey) return { state: "missing-key" };
00662| 
00663|     const url = `https://explore.market.dev/api/v1/experts/${encodeURIComponent(username)}`;
00664| 
00665|     try {
00666|       const backgroundResponse = await fetchViaBackground(url, apiKey);
00667|       let responseStatus = 0;
00668|       let responseData = null;
00669| 
00670|       if (backgroundResponse) {
00671|         responseStatus = backgroundResponse.status || 0;
00672|         responseData = backgroundResponse.data || null;
00673|       } else {
00674|         const response = await fetch(url, {
00675|           headers: {
00676|             Authorization: `Bearer ${apiKey}`,
00677|             Accept: "application/json"
00678|           }
00679|         });
00680|         responseStatus = response.status;
00681|         const text = await response.text();
00682|         try {
00683|           responseData = text ? JSON.parse(text) : null;
00684|         } catch (error) {
00685|           responseData = null;
00686|         }
00687|       }
00688| 
00689|       if (responseStatus === 200) return { state: "expert", expert: responseData };
00690|       if (responseStatus === 404) return { state: "not-expert" };
00691|       if (responseStatus === 401) return { state: "error", message: "Auth failed" };
00692|       return { state: "error", message: "API request failed" };
00693|     } catch (error) {
00694|       return { state: "error", message: "API request failed" };
00695|     }
00696|   }
00697| 
00698|   async function fetchExpertStatus(username) {
00699|     if (state.listCache.has(username)) {
00700|       return state.listCache.get(username);
00701|     }
00702| 
00703|     const apiKey = String(state.config.apiKey || "").trim();
00704|     if (!apiKey) return null;
00705| 
00706|     const url = `https://explore.market.dev/api/v1/experts/${encodeURIComponent(username)}`;
00707|     try {
00708|       const backgroundResponse = await fetchViaBackground(url, apiKey);
00709|       const status = backgroundResponse ? backgroundResponse.status : null;
00710|       if (status === 200 || status === 404) {
00711|         const value = status === 200 ? "expert" : "missing";
00712|         state.listCache.set(username, value);
00713|         return value;
00714|       }
00715|       return null;
00716|     } catch (error) {
00717|       return null;
00718|     }
00719|   }
00720| 
00721|   async function applyListIndicators() {
00722|     if (!isPullListPage()) return;
00723| 
00724|     const rows = document.querySelectorAll("div.js-issue-row");
00725|     rows.forEach((row) => {
00726|       const author = row.getAttribute("data-author");
00727|       if (!author) return;
00728|       const authorLink = row.querySelector("a[data-hovercard-type='user']") || row.querySelector("a.author");
00729|       if (!authorLink) return;
00730|       if (authorLink.parentElement?.querySelector(".md-pr-list-indicator")) return;
00731| 
00732|       fetchExpertStatus(author).then((status) => {
00733|         if (!status) return;
00734|         if (authorLink.parentElement?.querySelector(".md-pr-list-indicator")) return;
00735|         const indicator = document.createElement("span");
00736|         indicator.className = `md-pr-list-indicator ${status === "expert" ? "md-pr-list-expert" : "md-pr-list-missing"}`;
00737|         indicator.title = status === "expert" ? "Expert profile found" : "No expert profile";
00738|         authorLink.insertAdjacentElement("afterend", indicator);
00739|       });
00740|     });
00741|   }
00742| 
00743|   async function applyCheck() {
00744|     ensurePanel();
00745|     if (!isPullDetailPage()) return;
00746| 
00747|     const username = findPrAuthor();
00748|     if (!username) {
00749|       state.currentResult = { state: "error", message: "PR author not found" };
00750|       updateBadge(state.currentResult);
00751|       const panel = document.getElementById(PANEL_ID);
00752|       if (panel) updatePanel(panel);
00753|       return;
00754|     }
00755| 
00756|     state.currentResult = null;
00757|     const panel = document.getElementById(PANEL_ID);
00758|     if (panel) updatePanel(panel);
00759| 
00760|     const result = await fetchExpert(username);
00761|     state.currentResult = { ...result, username };
00762|     updateBadge(state.currentResult);
00763|     if (panel) updatePanel(panel);
00764|   }
00765| 
00766|   function init() {
00767|     applyCheck();
00768|     applyListIndicators();
00769|   }
00770| 
00771|   document.addEventListener("pjax:end", init);
00772|   document.addEventListener("turbo:load", init);
00773|   if (document.readyState === "loading") {
00774|     document.addEventListener("DOMContentLoaded", init);
00775|   } else {
00776|     init();
00777|   }
00778| })();
00779| 

(End of file - total 779 lines)
</file>
```

## Assistant

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension",
  "pattern": "Open Source Explorer"
}
```

## Assistant

**Result** (success):
```
Found 2 matches
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js:
  Line 423:       summary.innerHTML = `No profile found on the Open Source Explorer. <a class="md-pr-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Explore</a>`;

/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js:
  Line 466:       summary.innerHTML = `No profile found on the Open Source Explorer. <a class="md-pr-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Explore</a>`;
```

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "limit": 260,
  "offset": 1
}
```

## Assistant

**Result** (success):
```
<file>
00002|   if (window.__mdExpertPrBookmarklet) return;
00003|   window.__mdExpertPrBookmarklet = true;
00004| 
00005|   const STORAGE_KEY = "md_expert_pr_config";
00006|   const STYLE_ID = "md-expert-pr-style";
00007|   const PANEL_ID = "md-expert-pr-panel";
00008|   const BADGE_ID = "md-expert-pr-badge";
00009| 
00010|   const DEFAULT_CONFIG = {
00011|     apiKey: "",
00012|     settingsOpen: false
00013|   };
00014| 
00015|   const state = {
00016|     config: loadConfig(),
00017|     currentResult: null
00018|   };
00019| 
00020|   function loadConfig() {
00021|     const raw = window.localStorage.getItem(STORAGE_KEY);
00022|     if (!raw) return { ...DEFAULT_CONFIG };
00023|     try {
00024|       const parsed = JSON.parse(raw);
00025|       return { ...DEFAULT_CONFIG, ...parsed };
00026|     } catch (error) {
00027|       return { ...DEFAULT_CONFIG };
00028|     }
00029|   }
00030| 
00031|   function saveConfig(nextConfig) {
00032|     state.config = { ...DEFAULT_CONFIG, ...nextConfig };
00033|     window.localStorage.setItem(STORAGE_KEY, JSON.stringify(state.config));
00034|   }
00035| 
00036|   function isPullDetailPage() {
00037|     return /\/pull\/(\d+)(\/|$)/.test(window.location.pathname);
00038|   }
00039| 
00040|   function ensureStyles() {
00041|     if (document.getElementById(STYLE_ID)) return;
00042|     const style = document.createElement("style");
00043|     style.id = STYLE_ID;
00044|     style.textContent = `
00045|       #${PANEL_ID} {
00046|         position: fixed;
00047|         right: 16px;
00048|         bottom: 16px;
00049|         z-index: 999999;
00050|         font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
00051|         color: #1f2328;
00052|       }
00053|       #${PANEL_ID} .md-pr-panel {
00054|         width: 440px;
00055|         background: #ffffff;
00056|         border: 1px solid #d0d7de;
00057|         border-radius: 12px;
00058|         box-shadow: 0 1px 3px rgba(27, 31, 36, 0.12);
00059|         padding: 12px 12px 10px;
00060|         font-size: 14px;
00061|       }
00062|       #${PANEL_ID} .md-pr-header {
00063|         display: flex;
00064|         justify-content: flex-end;
00065|         align-items: center;
00066|         gap: 8px;
00067|         font-weight: 600;
00068|         font-size: 13px;
00069|       }
00070|       #${PANEL_ID} .md-pr-gear {
00071|         border: none;
00072|         background: #f6f8fa;
00073|         border-radius: 6px;
00074|         width: 28px;
00075|         height: 28px;
00076|         display: inline-flex;
00077|         align-items: center;
00078|         justify-content: center;
00079|         cursor: pointer;
00080|         border: 1px solid #d0d7de;
00081|         color: #57606a;
00082|       }
00083|       #${PANEL_ID} .md-pr-body {
00084|         margin-top: 10px;
00085|       }
00086|       #${PANEL_ID} .md-pr-settings {
00087|         display: none;
00088|         margin-top: 10px;
00089|         border-top: 1px dashed #d0d7de;
00090|         padding-top: 10px;
00091|       }
00092|       #${PANEL_ID} .md-pr-settings.md-pr-open {
00093|         display: block;
00094|       }
00095|       #${PANEL_ID} label {
00096|         display: block;
00097|         margin-bottom: 6px;
00098|         font-weight: 600;
00099|         font-size: 12px;
00100|         color: #57606a;
00101|       }
00102|       #${PANEL_ID} input[type="text"],
00103|       #${PANEL_ID} input[type="password"] {
00104|         width: 100%;
00105|         border: 1px solid #d0d7de;
00106|         border-radius: 6px;
00107|         padding: 6px 8px;
00108|         font-size: 14px;
00109|         background: #ffffff;
00110|         margin-bottom: 8px;
00111|       }
00112|       #${PANEL_ID} .md-pr-status {
00113|         margin-top: 8px;
00114|         color: #57606a;
00115|       }
00116|       #${PANEL_ID} .md-pr-warning {
00117|         color: #cf222e;
00118|         font-weight: 600;
00119|       }
00120|       #${PANEL_ID} .md-pr-success {
00121|         color: #1a7f37;
00122|         font-weight: 600;
00123|       }
00124|       #${PANEL_ID} .md-pr-details {
00125|         margin-top: 6px;
00126|         color: #24292f;
00127|       }
00128|       #${PANEL_ID} .md-pr-summary {
00129|         margin-top: 6px;
00130|         font-size: 18px;
00131|         color: #24292f;
00132|         font-weight: 600;
00133|       }
00134|       #${PANEL_ID} .md-pr-card {
00135|         border: 1px solid #d0d7de;
00136|         border-radius: 10px;
00137|         padding: 12px;
00138|       }
00139|       #${PANEL_ID} .md-pr-card-header {
00140|         display: flex;
00141|         gap: 12px;
00142|         align-items: center;
00143|       }
00144|       #${PANEL_ID} .md-pr-avatar {
00145|         width: 56px;
00146|         height: 56px;
00147|         border-radius: 50%;
00148|         background: #f6f8fa;
00149|         border: 1px solid #d0d7de;
00150|         overflow: hidden;
00151|         display: inline-flex;
00152|         align-items: center;
00153|         justify-content: center;
00154|         font-weight: 600;
00155|         color: #57606a;
00156|       }
00157|       #${PANEL_ID} .md-pr-avatar img {
00158|         width: 100%;
00159|         height: 100%;
00160|         object-fit: cover;
00161|       }
00162|       #${PANEL_ID} .md-pr-name {
00163|         font-size: 18px;
00164|         font-weight: 700;
00165|         color: #1a7f37;
00166|       }
00167|       #${PANEL_ID} .md-pr-meta {
00168|         margin-top: 6px;
00169|         color: #57606a;
00170|         font-size: 14px;
00171|       }
00172|       #${PANEL_ID} .md-pr-links {
00173|         margin-top: 6px;
00174|         display: flex;
00175|         gap: 12px;
00176|         font-size: 14px;
00177|       }
00178|       #${PANEL_ID} .md-pr-link {
00179|         color: #0969da;
00180|         font-weight: 600;
00181|       }
00182|       #${PANEL_ID} .md-pr-stats {
00183|         margin-top: 12px;
00184|         border: 1px solid #d0d7de;
00185|         border-radius: 8px;
00186|         overflow: hidden;
00187|       }
00188|       #${PANEL_ID} .md-pr-stat-row {
00189|         display: flex;
00190|         justify-content: space-between;
00191|         align-items: center;
00192|         padding: 8px 10px;
00193|         border-bottom: 1px solid #d0d7de;
00194|         font-size: 14px;
00195|       }
00196|       #${PANEL_ID} .md-pr-stat-row:last-child {
00197|         border-bottom: none;
00198|       }
00199|       #${PANEL_ID} .md-pr-stat-label {
00200|         color: #57606a;
00201|         text-transform: uppercase;
00202|         letter-spacing: 0.04em;
00203|         font-weight: 600;
00204|         font-size: 11px;
00205|       }
00206|       #${PANEL_ID} .md-pr-stat-value {
00207|         font-weight: 700;
00208|         color: #24292f;
00209|       }
00210|       #${PANEL_ID} .md-pr-section {
00211|         margin-top: 12px;
00212|       }
00213|       #${PANEL_ID} .md-pr-section-title {
00214|         font-size: 13px;
00215|         font-weight: 600;
00216|         color: #57606a;
00217|         text-transform: uppercase;
00218|         letter-spacing: 0.04em;
00219|         margin-bottom: 6px;
00220|       }
00221|       #${PANEL_ID} .md-pr-ecosystems {
00222|         display: flex;
00223|         flex-wrap: wrap;
00224|         gap: 6px;
00225|       }
00226|       #${PANEL_ID} .md-pr-ecosystem-pill {
00227|         display: inline-flex;
00228|         align-items: center;
00229|         background: #f6f8fa;
00230|         border: 1px solid #d0d7de;
00231|         border-radius: 999px;
00232|         padding: 2px 8px;
00233|         font-size: 13px;
00234|         color: #57606a;
00235|         text-decoration: none;
00236|       }
00237|       #${PANEL_ID} .md-pr-project-list {
00238|         display: flex;
00239|         flex-direction: column;
00240|         gap: 6px;
00241|       }
00242|       #${PANEL_ID} .md-pr-project-item {
00243|         display: flex;
00244|         justify-content: space-between;
00245|         gap: 8px;
00246|         font-size: 14px;
00247|         color: #24292f;
00248|       }
00249|       #${PANEL_ID} .md-pr-project-meta {
00250|         color: #57606a;
00251|         font-size: 13px;
00252|       }
00253|       #${PANEL_ID} .md-pr-section {
00254|         margin-top: 8px;
00255|       }
00256|       #${PANEL_ID} .md-pr-section-title {
00257|         font-size: 11px;
00258|         font-weight: 600;
00259|         text-transform: uppercase;
00260|         letter-spacing: 0.04em;
00261|         color: #6b7280;

(File has more lines. Use 'offset' parameter to read beyond line 261)
</file>
```

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "limit": 400,
  "offset": 260
}
```

## Assistant

**Result** (success):
```
<file>
00261|         color: #6b7280;
00262|         margin-bottom: 4px;
00263|       }
00264|       #${PANEL_ID} .md-pr-stats {
00265|         display: grid;
00266|         grid-template-columns: repeat(3, minmax(0, 1fr));
00267|         gap: 6px;
00268|       }
00269|       #${PANEL_ID} .md-pr-stat {
00270|         background: #ffffff;
00271|         border: 1px solid #e5e7eb;
00272|         border-radius: 8px;
00273|         padding: 6px;
00274|         text-align: center;
00275|       }
00276|       #${PANEL_ID} .md-pr-stat-label {
00277|         font-size: 10px;
00278|         text-transform: uppercase;
00279|         letter-spacing: 0.05em;
00280|         color: #6b7280;
00281|       }
00282|       #${PANEL_ID} .md-pr-stat-value {
00283|         font-size: 13px;
00284|         font-weight: 600;
00285|         color: #111827;
00286|       }
00287|       #${PANEL_ID} .md-pr-pill {
00288|         display: inline-flex;
00289|         align-items: center;
00290|         padding: 2px 6px;
00291|         border-radius: 999px;
00292|         background: #eef2ff;
00293|         color: #3730a3;
00294|         font-size: 11px;
00295|         margin-right: 4px;
00296|         margin-bottom: 4px;
00297|       }
00298|       #${PANEL_ID} .md-pr-link {
00299|         color: #0a3069;
00300|         font-weight: 600;
00301|       }
00302|       #${BADGE_ID} {
00303|         display: inline-flex;
00304|         align-items: center;
00305|         gap: 6px;
00306|         margin-left: 8px;
00307|         padding: 2px 8px;
00308|         border-radius: 999px;
00309|         font-size: 11px;
00310|         font-weight: 600;
00311|       }
00312|       #${BADGE_ID}.md-pr-badge-error {
00313|         background: #ffe4e8;
00314|         color: #9f1239;
00315|       }
00316|       #${BADGE_ID}.md-pr-badge-success {
00317|         background: #dcfce7;
00318|         color: #166534;
00319|       }
00320|     `;
00321|     document.head.appendChild(style);
00322|   }
00323| 
00324|   function ensurePanel() {
00325|     const existing = document.getElementById(PANEL_ID);
00326|     if (!isPullDetailPage()) {
00327|       if (existing) existing.remove();
00328|       removeBadge();
00329|       return;
00330|     }
00331| 
00332|     ensureStyles();
00333| 
00334|     if (existing) {
00335|       updatePanel(existing);
00336|       return;
00337|     }
00338| 
00339|     const wrapper = document.createElement("div");
00340|     wrapper.id = PANEL_ID;
00341|     wrapper.innerHTML = `
00342|       <div class="md-pr-panel">
00343|         <div class="md-pr-header">
00344|           <span></span>
00345|           <button class="md-pr-gear" type="button" aria-label="Settings">
00346|             <span aria-hidden="true">⚙</span>
00347|           </button>
00348|         </div>
00349|         <div class="md-pr-body">
00350|           <div class="md-pr-summary"></div>
00351|           <div class="md-pr-status"></div>
00352|           <div class="md-pr-details"></div>
00353|         </div>
00354|         <div class="md-pr-settings ${state.config.settingsOpen ? "md-pr-open" : ""}">
00355|           <label>API key</label>
00356|           <input type="password" data-config="apiKey" />
00357|           <div class="md-pr-status"></div>
00358|         </div>
00359|       </div>
00360|     `;
00361| 
00362|     wrapper.querySelector(".md-pr-gear").addEventListener("click", () => {
00363|       const settings = wrapper.querySelector(".md-pr-settings");
00364|       const open = settings.classList.toggle("md-pr-open");
00365|       saveConfig({ ...state.config, settingsOpen: open });
00366|     });
00367| 
00368|     wrapper.querySelectorAll("[data-config]").forEach((input) => {
00369|       const key = input.getAttribute("data-config");
00370|       input.value = state.config[key] ?? "";
00371|       input.addEventListener("change", () => {
00372|         saveConfig({ ...state.config, [key]: input.value });
00373|         applyCheck();
00374|       });
00375|     });
00376| 
00377|     document.body.appendChild(wrapper);
00378|     updatePanel(wrapper);
00379|   }
00380| 
00381|   function updatePanel(wrapper) {
00382|     const summary = wrapper.querySelector(".md-pr-summary");
00383|     const statusBlocks = wrapper.querySelectorAll(".md-pr-status");
00384|     const details = wrapper.querySelector(".md-pr-details");
00385|     const result = state.currentResult;
00386| 
00387|     statusBlocks.forEach((status) => {
00388|       status.textContent = "";
00389|       status.innerHTML = "";
00390|     });
00391| 
00392|     if (!result) {
00393|       statusBlocks.forEach((status) => {
00394|         status.textContent = "Checking PR author...";
00395|       });
00396|       summary.textContent = "";
00397|       details.textContent = "";
00398|       return;
00399|     }
00400| 
00401|     if (result.state === "missing-key") {
00402|       statusBlocks.forEach((status) => {
00403|         status.innerHTML = `<span class="md-pr-warning">API key required</span>`;
00404|       });
00405|       summary.textContent = "";
00406|       details.textContent = "";
00407|       return;
00408|     }
00409| 
00410|     if (result.state === "error") {
00411|       statusBlocks.forEach((status) => {
00412|         status.innerHTML = `<span class="md-pr-warning">${result.message}</span>`;
00413|       });
00414|       summary.textContent = "";
00415|       details.textContent = "";
00416|       return;
00417|     }
00418| 
00419|     if (result.state === "not-expert") {
00420|       statusBlocks.forEach((status) => {
00421|         status.innerHTML = "";
00422|       });
00423|       summary.innerHTML = `No profile found on the Open Source Explorer. <a class="md-pr-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Explore</a>`;
00424|       details.innerHTML = "";
00425|       return;
00426|     }
00427| 
00428|     if (result.state === "expert") {
00429|       statusBlocks.forEach((status) => {
00430|         status.innerHTML = "";
00431|       });
00432|       const info = result.expert && result.expert.expert ? result.expert.expert : result.expert;
00433|       summary.textContent = buildSummary(info, result.username);
00434|       details.innerHTML = renderExpertDetails(info, result.username);
00435|     }
00436|   }
00437| 
00438|   function buildSummary(info, username) {
00439|     if (!info) return `This PR was opened by ${username}.`;
00440|     const name = info.name || username;
00441|     const downloadsRaw = Number(info.total_downloads || 0);
00442|     const downloads = downloadsRaw > 0 ? formatCompactNumber(downloadsRaw) : null;
00443|     const stars = formatCompactNumber(info.total_stars);
00444|     const downloadText = downloads ? `${downloads} total downloads` : "";
00445|     const starsText = stars ? `${stars} stars on repos` : "";
00446|     const stats = [downloadText, starsText].filter(Boolean).join(", ");
00447|     if (!stats) return `This PR was opened by ${name} (${username}).`;
00448|     return `This PR was opened by ${name} (${username}). They have received ${stats}.`;
00449|   }
00450| 
00451|   function formatCompactNumber(value) {
00452|     if (value === null || value === undefined) return null;
00453|     const num = Number(value);
00454|     if (Number.isNaN(num)) return null;
00455|     return new Intl.NumberFormat("en", {
00456|       notation: "compact",
00457|       maximumFractionDigits: 1
00458|     }).format(num);
00459|   }
00460| 
00461|   function renderExpertDetails(info, username) {
00462|     const profileUrl = `https://explore.market.dev/experts/${encodeURIComponent(username)}`;
00463|     if (!info) {
00464|       return `Expert profile: <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Open</a>`;
00465|     }
00466| 
00467|     const name = info.name || username;
00468|     const avatarUrl = info.avatar_url || info.avatar || null;
00469|     const location = info.location || info.display_location || "";
00470| 
00471|     const stats = [
00472|       { label: "Projects", value: formatCompactNumber(info.projects_count) },
00473|       { label: "Downloads", value: formatCompactNumber(info.total_downloads) },
00474|       { label: "Stars", value: formatCompactNumber(info.total_stars) }
00475|     ].filter((stat) => stat.value !== null);
00476| 
00477|     const projects = Array.isArray(info.projects) ? info.projects : [];
00478|     const sortedProjects = [...projects].sort((a, b) => {
00479|       const starsA = Number(a.total_stars || a.stars || 0);
00480|       const starsB = Number(b.total_stars || b.stars || 0);
00481|       if (starsB !== starsA) return starsB - starsA;
00482|       const downloadsA = Number(a.total_downloads || a.downloads || 0);
00483|       const downloadsB = Number(b.total_downloads || b.downloads || 0);
00484|       return downloadsB - downloadsA;
00485|     });
00486|     const maintainerItems = sortedProjects.slice(0, 10).map((project) => {
00487|       const role = project.role || project.project_experts?.[0]?.role;
00488|       const name = project.name || project.slug || "";
00489|       if (!name) return null;
00490|       const stars = formatCompactNumber(project.total_stars || project.stars);
00491|       const downloads = formatCompactNumber(project.total_downloads || project.downloads);
00492|       const metaParts = [stars ? `${stars} stars` : null, downloads ? `${downloads} downloads` : null]
00493|         .filter(Boolean)
00494|         .join(" · ");
00495|       const label = role ? `${role} of ${name}` : name;
00496|       const projectSlug = project.slug || project.name || "";
00497|       const projectUrl =
00498|         project.github_url ||
00499|         project.repo_url ||
00500|         project.url ||
00501|         (projectSlug ? `https://explore.market.dev/projects/${encodeURIComponent(projectSlug)}` : null);
00502|       return { label, meta: metaParts, url: projectUrl };
00503|     }).filter(Boolean);
00504| 
00505|     const ecosystems =
00506|       (Array.isArray(info.ecosystems) && info.ecosystems) ||
00507|       (Array.isArray(info.ecosystem_names) && info.ecosystem_names) ||
00508|       [];
00509| 
00510|     const ecosystemNames = ecosystems
00511|       .map((eco) => (typeof eco === "string" ? eco : eco.name))
00512|       .filter(Boolean)
00513|       .slice(0, 8)
00514|       .map((name) => ({
00515|         name,
00516|         url: `https://explore.market.dev/ecosystems/${encodeURIComponent(name)}`
00517|       }));
00518| 
00519|     return `
00520|       <div class="md-pr-card">
00521|         <div class="md-pr-card-header">
00522|           <div class="md-pr-avatar">
00523|             ${avatarUrl ? `<img src="${avatarUrl}" alt="${name}" />` : name.slice(0, 1).toUpperCase()}
00524|           </div>
00525|           <div>
00526|             <div class="md-pr-name">${name}</div>
00527|             <div class="md-pr-meta">@${username}${location ? ` · ${location}` : ""}</div>
00528|             <div class="md-pr-links">
00529|               <a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">GitHub</a>
00530|               <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Explore</a>
00531|             </div>
00532|           </div>
00533|         </div>
00534|         ${stats.length ? `
00535|           <div class="md-pr-stats">
00536|             ${stats
00537|               .map(
00538|                 (stat) => `
00539|                   <div class="md-pr-stat-row">
00540|                     <span class="md-pr-stat-label">${stat.label}</span>
00541|                     <span class="md-pr-stat-value">${stat.value}</span>
00542|                   </div>
00543|                 `
00544|               )
00545|               .join("")}
00546|           </div>
00547|         ` : ""}
00548|         ${ecosystemNames.length ? `
00549|           <div class="md-pr-section">
00550|             <div class="md-pr-section-title">Ecosystems</div>
00551|             <div class="md-pr-ecosystems">
00552|               ${ecosystemNames
00553|                 .map((eco) => `<a class="md-pr-ecosystem-pill" href="${eco.url}" target="_blank" rel="noopener noreferrer">${eco.name}</a>`)
00554|                 .join("")}
00555|             </div>
00556|           </div>
00557|         ` : ""}
00558|         ${maintainerItems.length ? `
00559|           <div class="md-pr-section">
00560|             <div class="md-pr-section-title">Projects</div>
00561|             <div class="md-pr-project-list">
00562|               ${maintainerItems
00563|                 .map(
00564|                   (item) => `
00565|                     <div class="md-pr-project-item">
00566|                       ${item.url ? `<a class="md-pr-link" href="${item.url}" target="_blank" rel="noopener noreferrer">${item.label}</a>` : `<span>${item.label}</span>`}
00567|                       ${item.meta ? `<span class="md-pr-project-meta">${item.meta}</span>` : ""}
00568|                     </div>
00569|                   `
00570|                 )
00571|                 .join("")}
00572|             </div>
00573|           </div>
00574|         ` : ""}
00575|       </div>
00576|     `;
00577|   }
00578| 
00579|   function findPrAuthor() {
00580|     const selectors = [
00581|       ".gh-header-meta .author",
00582|       ".js-discussion .timeline-comment-header .author",
00583|       ".js-discussion .author",
00584|       ".timeline-comment-header .author",
00585|       "a.author"
00586|     ];
00587|     for (const selector of selectors) {
00588|       const el = document.querySelector(selector);
00589|       if (el && el.textContent.trim()) return el.textContent.trim();
00590|     }
00591|     return null;
00592|   }
00593| 
00594|   function removeBadge() {
00595|     const existing = document.getElementById(BADGE_ID);
00596|     if (existing) existing.remove();
00597|   }
00598| 
00599|   function updateBadge(result) {
00600|     const header = document.querySelector(".gh-header-title") || document.querySelector(".gh-header-meta");
00601|     if (!header) return;
00602| 
00603|     removeBadge();
00604|     if (!result || result.state === "error" || result.state === "missing-key") return;
00605| 
00606|     const badge = document.createElement("span");
00607|     badge.id = BADGE_ID;
00608| 
00609|     if (result.state === "not-expert") {
00610|       badge.className = "md-pr-badge-error";
00611|       badge.textContent = "No Profile";
00612|       header.appendChild(badge);
00613|     }
00614|   }
00615| 
00616|   async function fetchExpert(username) {
00617|     const apiKey = String(state.config.apiKey || "").trim();
00618|     if (!apiKey) return { state: "missing-key" };
00619| 
00620|     const url = `https://explore.market.dev/api/v1/experts/${encodeURIComponent(username)}`;
00621| 
00622|     try {
00623|       const response = await fetch(url, {
00624|         headers: {
00625|           Authorization: `Bearer ${apiKey}`,
00626|           Accept: "application/json"
00627|         }
00628|       });
00629|       const text = await response.text();
00630|       let data = null;
00631|       try {
00632|         data = text ? JSON.parse(text) : null;
00633|       } catch (error) {
00634|         data = null;
00635|       }
00636| 
00637|       if (response.status === 200) return { state: "expert", expert: data };
00638|       if (response.status === 404) return { state: "not-expert" };
00639|       if (response.status === 401) return { state: "error", message: "Auth failed" };
00640|       return { state: "error", message: "API request failed" };
00641|     } catch (error) {
00642|       return { state: "error", message: "API request failed" };
00643|     }
00644|   }
00645| 
00646|   async function applyCheck() {
00647|     ensurePanel();
00648|     if (!isPullDetailPage()) return;
00649| 
00650|     const username = findPrAuthor();
00651|     if (!username) {
00652|       state.currentResult = { state: "error", message: "PR author not found" };
00653|       updateBadge(state.currentResult);
00654|       const panel = document.getElementById(PANEL_ID);
00655|       if (panel) updatePanel(panel);
00656|       return;
00657|     }
00658| 
00659|     state.currentResult = null;
00660|     const panel = document.getElementById(PANEL_ID);

(File has more lines. Use 'offset' parameter to read beyond line 660)
</file>
```

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "limit": 120,
  "offset": 660
}
```

## Assistant

**Result** (success):
```
<file>
00661|     if (panel) updatePanel(panel);
00662| 
00663|     const result = await fetchExpert(username);
00664|     state.currentResult = { ...result, username };
00665|     updateBadge(state.currentResult);
00666|     if (panel) updatePanel(panel);
00667|   }
00668| 
00669|   function init() {
00670|     applyCheck();
00671|   }
00672| 
00673|   if (document.readyState === "loading") {
00674|     document.addEventListener("DOMContentLoaded", init);
00675|   } else {
00676|     init();
00677|   }
00678| })();
00679|       #${PANEL_ID} .md-pr-summary {
00680|         margin-top: 6px;
00681|         font-size: 13px;
00682|         color: #111827;
00683|         font-weight: 600;
00684|       }
00685| 

(End of file - total 685 lines)
</file>
```

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "limit": 60,
  "offset": 640
}
```

## Assistant

**Result** (success):
```
<file>
00641|     } catch (error) {
00642|       return { state: "error", message: "API request failed" };
00643|     }
00644|   }
00645| 
00646|   async function applyCheck() {
00647|     ensurePanel();
00648|     if (!isPullDetailPage()) return;
00649| 
00650|     const username = findPrAuthor();
00651|     if (!username) {
00652|       state.currentResult = { state: "error", message: "PR author not found" };
00653|       updateBadge(state.currentResult);
00654|       const panel = document.getElementById(PANEL_ID);
00655|       if (panel) updatePanel(panel);
00656|       return;
00657|     }
00658| 
00659|     state.currentResult = null;
00660|     const panel = document.getElementById(PANEL_ID);
00661|     if (panel) updatePanel(panel);
00662| 
00663|     const result = await fetchExpert(username);
00664|     state.currentResult = { ...result, username };
00665|     updateBadge(state.currentResult);
00666|     if (panel) updatePanel(panel);
00667|   }
00668| 
00669|   function init() {
00670|     applyCheck();
00671|   }
00672| 
00673|   if (document.readyState === "loading") {
00674|     document.addEventListener("DOMContentLoaded", init);
00675|   } else {
00676|     init();
00677|   }
00678| })();
00679|       #${PANEL_ID} .md-pr-summary {
00680|         margin-top: 6px;
00681|         font-size: 13px;
00682|         color: #111827;
00683|         font-weight: 600;
00684|       }
00685| 

(End of file - total 685 lines)
</file>
```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git status --short",
  "description": "Show working tree short status"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/manifest.json"
}
```

## Assistant

**Result** (success):
```
<file>
00001| {
00002|   "manifest_version": 3,
00003|   "name": "Market.dev Expert Filter",
00004|   "version": "0.1.0",
00005|   "description": "Hide GitHub content from non-experts using the Market.dev experts API.",
00006|   "host_permissions": [
00007|     "https://github.com/*",
00008|     "https://*.github.com/*",
00009|     "https://*.market.dev/*"
00010|   ],
00011|   "background": {
00012|     "service_worker": "background.js"
00013|   },
00014|   "content_scripts": [
00015|     {
00016|       "matches": ["https://github.com/*"],
00017|       "js": ["content.js"]
00018|     }
00019|   ]
00020| }
00021| 

(End of file - total 21 lines)
</file>
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n   function ensureStyles() {\n     if (document.getElementById(STYLE_ID)) return;\n     const style = document.createElement(\"style\");\n     style.id = STYLE_ID;\n     style.textContent = `\n       #${PANEL_ID} {\n-        position: fixed;\n-        right: 16px;\n-        bottom: 16px;\n-        z-index: 999999;\n-        font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Noto Sans\", Helvetica, Arial, sans-serif;\n-        color: #1f2328;\n+        color: var(--fgColor-default, #24292f);\n+      }\n+      #${PANEL_ID}.discussion-sidebar-item {\n+        margin-top: 0;\n       }\n       #${PANEL_ID} .md-pr-panel {\n-        width: 440px;\n-        background: #ffffff;\n-        border: 1px solid #d0d7de;\n-        border-radius: 12px;\n-        box-shadow: 0 1px 3px rgba(27, 31, 36, 0.12);\n-        padding: 12px 12px 10px;\n-        font-size: 14px;\n+        font-size: 12px;\n+        line-height: 1.5;\n       }\n       #${PANEL_ID} .md-pr-header {\n         display: flex;\n-        justify-content: flex-end;\n+        justify-content: space-between;\n         align-items: center;\n-        gap: 8px;\n-        font-weight: 600;\n-        font-size: 13px;\n+        margin-bottom: 6px;\n+      }\n+      #${PANEL_ID} .md-pr-heading {\n+        margin: 0;\n       }\n       #${PANEL_ID} .md-pr-gear {\n         border: none;\n-        background: #f6f8fa;\n-        border-radius: 6px;\n-        width: 28px;\n-        height: 28px;\n+        background: transparent;\n+        color: var(--fgColor-muted, #57606a);\n+        width: 20px;\n+        height: 20px;\n+        padding: 0;\n         display: inline-flex;\n         align-items: center;\n         justify-content: center;\n         cursor: pointer;\n-        border: 1px solid #d0d7de;\n-        color: #57606a;\n       }\n-      #${PANEL_ID} .md-pr-body {\n-        margin-top: 10px;\n+      #${PANEL_ID} .md-pr-gear:hover {\n+        color: var(--fgColor-default, #24292f);\n       }\n       #${PANEL_ID} .md-pr-settings {\n         display: none;\n-        margin-top: 10px;\n-        border-top: 1px dashed #d0d7de;\n-        padding-top: 10px;\n+        margin-top: 8px;\n       }\n       #${PANEL_ID} .md-pr-settings.md-pr-open {\n         display: block;\n       }\n-      #${PANEL_ID} label {\n+      #${PANEL_ID} .md-pr-settings label {\n         display: block;\n-        margin-bottom: 6px;\n-        font-weight: 600;\n+        margin-bottom: 4px;\n         font-size: 12px;\n-        color: #57606a;\n+        color: var(--fgColor-muted, #57606a);\n       }\n-      #${PANEL_ID} input[type=\"text\"],\n-      #${PANEL_ID} input[type=\"password\"] {\n+      #${PANEL_ID} .md-pr-settings input[type=\"password\"] {\n         width: 100%;\n-        border: 1px solid #d0d7de;\n+        border: 1px solid var(--borderColor-default, #d0d7de);\n         border-radius: 6px;\n-        padding: 6px 8px;\n-        font-size: 14px;\n-        background: #ffffff;\n-        margin-bottom: 8px;\n+        padding: 5px 8px;\n+        font-size: 12px;\n+        color: var(--fgColor-default, #24292f);\n+        background: var(--bgColor-default, #ffffff);\n       }\n       #${PANEL_ID} .md-pr-status {\n-        margin-top: 8px;\n-        color: #57606a;\n+        color: var(--fgColor-muted, #57606a);\n       }\n       #${PANEL_ID} .md-pr-warning {\n-        color: #cf222e;\n-        font-weight: 600;\n-      }\n-      #${PANEL_ID} .md-pr-success {\n-        color: #1a7f37;\n-        font-weight: 600;\n+        color: var(--fgColor-danger, #cf222e);\n       }\n       #${PANEL_ID} .md-pr-details {\n-        margin-top: 6px;\n-        color: #24292f;\n+        color: var(--fgColor-muted, #57606a);\n       }\n       #${PANEL_ID} .md-pr-summary {\n-        margin-top: 6px;\n-        font-size: 18px;\n-        color: #24292f;\n-        font-weight: 600;\n-      }\n-      #${PANEL_ID} .md-pr-card {\n-        border: 1px solid #d0d7de;\n-        border-radius: 10px;\n-        padding: 12px;\n+        margin-bottom: 8px;\n+        color: var(--fgColor-default, #24292f);\n       }\n       #${PANEL_ID} .md-pr-card-header {\n         display: flex;\n-        gap: 12px;\n-        align-items: center;\n+        gap: 8px;\n+        align-items: flex-start;\n       }\n       #${PANEL_ID} .md-pr-avatar {\n-        width: 56px;\n-        height: 56px;\n+        width: 32px;\n+        height: 32px;\n         border-radius: 50%;\n-        background: #f6f8fa;\n-        border: 1px solid #d0d7de;\n         overflow: hidden;\n+        background: var(--bgColor-muted, #f6f8fa);\n         display: inline-flex;\n         align-items: center;\n         justify-content: center;\n         font-weight: 600;\n-        color: #57606a;\n+        color: var(--fgColor-muted, #57606a);\n+        flex-shrink: 0;\n       }\n       #${PANEL_ID} .md-pr-avatar img {\n         width: 100%;\n@@\n       }\n       #${PANEL_ID} .md-pr-name {\n-        font-size: 18px;\n-        font-weight: 700;\n-        color: #1a7f37;\n+        font-size: 13px;\n+        font-weight: 600;\n+        color: var(--fgColor-default, #24292f);\n       }\n       #${PANEL_ID} .md-pr-meta {\n-        margin-top: 6px;\n-        color: #57606a;\n-        font-size: 14px;\n+        color: var(--fgColor-muted, #57606a);\n       }\n       #${PANEL_ID} .md-pr-links {\n-        margin-top: 6px;\n+        margin-top: 2px;\n         display: flex;\n-        gap: 12px;\n-        font-size: 14px;\n+        gap: 8px;\n       }\n       #${PANEL_ID} .md-pr-link {\n-        color: #0969da;\n-        font-weight: 600;\n+        color: var(--fgColor-accent, #0969da);\n+        text-decoration: none;\n+      }\n+      #${PANEL_ID} .md-pr-link:hover {\n+        text-decoration: underline;\n       }\n       #${PANEL_ID} .md-pr-stats {\n-        margin-top: 12px;\n-        border: 1px solid #d0d7de;\n-        border-radius: 8px;\n-        overflow: hidden;\n+        margin-top: 8px;\n       }\n-      #${PANEL_ID} .md-pr-stat-row {\n-        display: flex;\n-        justify-content: space-between;\n-        align-items: center;\n-        padding: 8px 10px;\n-        border-bottom: 1px solid #d0d7de;\n-        font-size: 14px;\n-      }\n-      #${PANEL_ID} .md-pr-stat-row:last-child {\n-        border-bottom: none;\n+      #${PANEL_ID} .md-pr-stat-item {\n+        color: var(--fgColor-default, #24292f);\n       }\n       #${PANEL_ID} .md-pr-stat-label {\n-        color: #57606a;\n-        text-transform: uppercase;\n-        letter-spacing: 0.04em;\n-        font-weight: 600;\n-        font-size: 11px;\n+        color: var(--fgColor-muted, #57606a);\n       }\n-      #${PANEL_ID} .md-pr-stat-value {\n-        font-weight: 700;\n-        color: #24292f;\n+      #${PANEL_ID} .md-pr-stat-sep {\n+        margin: 0 4px;\n+        color: var(--fgColor-muted, #57606a);\n       }\n       #${PANEL_ID} .md-pr-section {\n-        margin-top: 12px;\n+        margin-top: 8px;\n       }\n       #${PANEL_ID} .md-pr-section-title {\n-        font-size: 13px;\n+        margin-bottom: 2px;\n         font-weight: 600;\n-        color: #57606a;\n-        text-transform: uppercase;\n-        letter-spacing: 0.04em;\n-        margin-bottom: 6px;\n+        color: var(--fgColor-muted, #57606a);\n       }\n       #${PANEL_ID} .md-pr-ecosystems {\n         display: flex;\n         flex-wrap: wrap;\n-        gap: 6px;\n+        gap: 8px;\n       }\n       #${PANEL_ID} .md-pr-ecosystem-pill {\n-        display: inline-flex;\n-        align-items: center;\n-        background: #f6f8fa;\n-        border: 1px solid #d0d7de;\n-        border-radius: 999px;\n-        padding: 2px 8px;\n-        font-size: 13px;\n-        color: #57606a;\n+        color: var(--fgColor-accent, #0969da);\n         text-decoration: none;\n       }\n+      #${PANEL_ID} .md-pr-ecosystem-pill:hover {\n+        text-decoration: underline;\n+      }\n       #${PANEL_ID} .md-pr-project-list {\n         display: flex;\n         flex-direction: column;\n-        gap: 6px;\n+        gap: 2px;\n       }\n       #${PANEL_ID} .md-pr-project-item {\n         display: flex;\n+        align-items: baseline;\n         justify-content: space-between;\n         gap: 8px;\n-        font-size: 14px;\n-        color: #24292f;\n       }\n       #${PANEL_ID} .md-pr-project-meta {\n-        color: #57606a;\n-        font-size: 13px;\n-      }\n-      .md-pr-list-indicator {\n-        display: inline-flex;\n-        align-items: center;\n-        justify-content: center;\n-        width: 8px;\n-        height: 8px;\n-        border-radius: 999px;\n-        margin-left: 6px;\n-        border: 1px solid #d0d7de;\n-      }\n-      .md-pr-list-indicator.md-pr-list-expert {\n-        background: #2da44e;\n-        border-color: #2da44e;\n-      }\n-      .md-pr-list-indicator.md-pr-list-missing {\n-        background: #afb8c1;\n-      }\n-      #${PANEL_ID} .md-pr-section {\n-        margin-top: 8px;\n-      }\n-      #${PANEL_ID} .md-pr-section-title {\n-        font-size: 11px;\n-        font-weight: 600;\n-        text-transform: uppercase;\n-        letter-spacing: 0.04em;\n-        color: #6b7280;\n-        margin-bottom: 4px;\n-      }\n-      #${PANEL_ID} .md-pr-stats {\n-        display: grid;\n-        grid-template-columns: repeat(3, minmax(0, 1fr));\n-        gap: 6px;\n-      }\n-      #${PANEL_ID} .md-pr-stat {\n-        background: #ffffff;\n-        border: 1px solid #e5e7eb;\n-        border-radius: 8px;\n-        padding: 6px;\n-        text-align: center;\n-      }\n-      #${PANEL_ID} .md-pr-stat-label {\n-        font-size: 10px;\n-        text-transform: uppercase;\n-        letter-spacing: 0.05em;\n-        color: #6b7280;\n-      }\n-      #${PANEL_ID} .md-pr-stat-value {\n-        font-size: 13px;\n-        font-weight: 600;\n-        color: #111827;\n-      }\n-      #${PANEL_ID} .md-pr-pill {\n-        display: inline-flex;\n-        align-items: center;\n-        padding: 2px 6px;\n-        border-radius: 999px;\n-        background: #eef2ff;\n-        color: #3730a3;\n-        font-size: 11px;\n-        margin-right: 4px;\n-        margin-bottom: 4px;\n-      }\n-      #${PANEL_ID} .md-pr-link {\n-        color: #0a3069;\n-        font-weight: 600;\n+        color: var(--fgColor-muted, #57606a);\n+        flex-shrink: 0;\n+      }\n+      #${PANEL_ID} .md-pr-powered {\n+        margin-top: 8px;\n+        font-size: 11px;\n+        color: var(--fgColor-muted, #57606a);\n+        opacity: 0.65;\n+      }\n+      .md-pr-list-indicator {\n+        display: inline-flex;\n+        align-items: center;\n+        justify-content: center;\n+        width: 8px;\n+        height: 8px;\n+        border-radius: 999px;\n+        margin-left: 6px;\n+        border: 1px solid #d0d7de;\n+      }\n+      .md-pr-list-indicator.md-pr-list-expert {\n+        background: #2da44e;\n+        border-color: #2da44e;\n+      }\n+      .md-pr-list-indicator.md-pr-list-missing {\n+        background: #afb8c1;\n       }\n       #${BADGE_ID} {\n         display: inline-flex;\n@@\n     `;\n     document.head.appendChild(style);\n   }\n+\n+  function findSidebar() {\n+    return document.querySelector(\".discussion-sidebar\");\n+  }\n+\n+  function findReviewersSection(sidebar) {\n+    if (!sidebar) return null;\n+    const byClass = sidebar.querySelector(\".discussion-sidebar-item.sidebar-reviewers\");\n+    if (byClass) return byClass;\n+\n+    const headings = sidebar.querySelectorAll(\".discussion-sidebar-heading, h3\");\n+    for (const heading of headings) {\n+      if (heading.textContent.trim().toLowerCase() !== \"reviewers\") continue;\n+      const item = heading.closest(\".discussion-sidebar-item\");\n+      if (item) return item;\n+    }\n+\n+    return null;\n+  }\n+\n+  function mountPanel(wrapper) {\n+    const sidebar = findSidebar();\n+    if (!sidebar) return false;\n+\n+    const reviewersSection = findReviewersSection(sidebar);\n+    if (reviewersSection) {\n+      if (reviewersSection.nextElementSibling !== wrapper) {\n+        reviewersSection.insertAdjacentElement(\"afterend\", wrapper);\n+      }\n+      return true;\n+    }\n+\n+    if (wrapper.parentElement !== sidebar) {\n+      sidebar.appendChild(wrapper);\n+    }\n+    return true;\n+  }\n \n   function ensurePanel() {\n     const existing = document.getElementById(PANEL_ID);\n     if (!isPullDetailPage()) {\n       if (existing) existing.remove();\n@@\n \n     ensureStyles();\n \n     if (existing) {\n+      mountPanel(existing);\n       updatePanel(existing);\n       return;\n     }\n \n     const wrapper = document.createElement(\"div\");\n     wrapper.id = PANEL_ID;\n+    wrapper.className = \"discussion-sidebar-item\";\n     wrapper.innerHTML = `\n       <div class=\"md-pr-panel\">\n         <div class=\"md-pr-header\">\n-          <span></span>\n+          <h3 class=\"discussion-sidebar-heading md-pr-heading\">Contributor insights</h3>\n           <button class=\"md-pr-gear\" type=\"button\" aria-label=\"Settings\">\n             <span aria-hidden=\"true\">⚙</span>\n           </button>\n         </div>\n         <div class=\"md-pr-body\">\n@@\n-        <div class=\"md-pr-settings ${state.config.settingsOpen ? \"md-pr-open\" : \"\"}\">\n-          <label>API key</label>\n-          <input type=\"password\" data-config=\"apiKey\" />\n+        <div class=\"md-pr-settings ${state.config.settingsOpen ? \"md-pr-open\" : \"\"}\">\n+          <label for=\"${PANEL_ID}-api-key\">API key</label>\n+          <input id=\"${PANEL_ID}-api-key\" type=\"password\" data-config=\"apiKey\" />\n           <div class=\"md-pr-status\"></div>\n         </div>\n+        <div class=\"md-pr-powered\">Powered by the Open Source Explorer</div>\n       </div>\n     `;\n@@\n     wrapper.querySelectorAll(\"[data-config]\").forEach((input) => {\n       const key = input.getAttribute(\"data-config\");\n       input.value = state.config[key] ?? \"\";\n@@\n         applyListIndicators();\n       });\n     });\n \n-    document.body.appendChild(wrapper);\n+    if (!mountPanel(wrapper)) {\n+      return;\n+    }\n+\n     updatePanel(wrapper);\n   }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n     if (result.state === \"not-expert\") {\n       statusBlocks.forEach((status) => {\n         status.innerHTML = \"\";\n       });\n-      summary.innerHTML = `No profile found on the Open Source Explorer. <a class=\"md-pr-link\" href=\"https://explore.market.dev\" target=\"_blank\" rel=\"noopener noreferrer\">Explore</a>`;\n-      details.innerHTML = \"\";\n+      summary.textContent = \"No contributor profile found yet.\";\n+      details.innerHTML = `<a class=\"md-pr-link\" href=\"https://explore.market.dev\" target=\"_blank\" rel=\"noopener noreferrer\">Browse directory</a>`;\n       return;\n     }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 220,
  "offset": 470
}
```

## Assistant

**Result** (success):
```
<file>
00471| 
00472|     const projects = Array.isArray(info.projects) ? info.projects : [];
00473|     const sortedProjects = [...projects].sort((a, b) => {
00474|       const starsA = Number(a.total_stars || a.stars || 0);
00475|       const starsB = Number(b.total_stars || b.stars || 0);
00476|       if (starsB !== starsA) return starsB - starsA;
00477|       const downloadsA = Number(a.total_downloads || a.downloads || 0);
00478|       const downloadsB = Number(b.total_downloads || b.downloads || 0);
00479|       return downloadsB - downloadsA;
00480|     });
00481|     const maintainerItems = sortedProjects.slice(0, 10).map((project) => {
00482|       const role = project.role || project.project_experts?.[0]?.role;
00483|       const name = project.name || project.slug || "";
00484|       if (!name) return null;
00485|       const stars = formatCompactNumber(project.total_stars || project.stars);
00486|       const downloads = formatCompactNumber(project.total_downloads || project.downloads);
00487|       const metaParts = [stars ? `${stars} stars` : null, downloads ? `${downloads} downloads` : null]
00488|         .filter(Boolean)
00489|         .join(" · ");
00490|       const label = role ? `${role} of ${name}` : name;
00491|       const projectSlug = project.slug || project.name || "";
00492|       const projectUrl =
00493|         project.github_url ||
00494|         project.repo_url ||
00495|         project.url ||
00496|         (projectSlug ? `https://explore.market.dev/projects/${encodeURIComponent(projectSlug)}` : null);
00497|       return { label, meta: metaParts, url: projectUrl };
00498|     }).filter(Boolean);
00499| 
00500|     const ecosystems =
00501|       (Array.isArray(info.ecosystems) && info.ecosystems) ||
00502|       (Array.isArray(info.ecosystem_names) && info.ecosystem_names) ||
00503|       [];
00504| 
00505|     const ecosystemNames = ecosystems
00506|       .map((eco) => (typeof eco === "string" ? eco : eco.name))
00507|       .filter(Boolean)
00508|       .slice(0, 8)
00509|       .map((name) => ({
00510|         name,
00511|         url: `https://explore.market.dev/ecosystems/${encodeURIComponent(name)}`
00512|       }));
00513| 
00514|     return `
00515|       <div class="md-pr-card">
00516|         <div class="md-pr-card-header">
00517|           <div class="md-pr-avatar">
00518|             ${avatarUrl ? `<img src="${avatarUrl}" alt="${name}" />` : name.slice(0, 1).toUpperCase()}
00519|           </div>
00520|           <div>
00521|             <div class="md-pr-name">${name}</div>
00522|             <div class="md-pr-meta">@${username}${location ? ` · ${location}` : ""}</div>
00523|             <div class="md-pr-links">
00524|               <a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">GitHub</a>
00525|               <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Market.dev</a>
00526|             </div>
00527|           </div>
00528|         </div>
00529|         ${stats.length ? `
00530|           <div class="md-pr-stats">
00531|             ${stats
00532|               .map(
00533|                 (stat) => `
00534|                   <div class="md-pr-stat-row">
00535|                     <span class="md-pr-stat-label">${stat.label}</span>
00536|                     <span class="md-pr-stat-value">${stat.value}</span>
00537|                   </div>
00538|                 `
00539|               )
00540|               .join("")}
00541|           </div>
00542|         ` : ""}
00543|         ${ecosystemNames.length ? `
00544|           <div class="md-pr-section">
00545|             <div class="md-pr-section-title">Ecosystems</div>
00546|             <div class="md-pr-ecosystems">
00547|               ${ecosystemNames
00548|                 .map((eco) => `<a class="md-pr-ecosystem-pill" href="${eco.url}" target="_blank" rel="noopener noreferrer">${eco.name}</a>`)
00549|                 .join("")}
00550|             </div>
00551|           </div>
00552|         ` : ""}
00553|         ${maintainerItems.length ? `
00554|           <div class="md-pr-section">
00555|             <div class="md-pr-section-title">Projects</div>
00556|             <div class="md-pr-project-list">
00557|               ${maintainerItems
00558|                 .map(
00559|                   (item) => `
00560|                     <div class="md-pr-project-item">
00561|                       ${item.url ? `<a class="md-pr-link" href="${item.url}" target="_blank" rel="noopener noreferrer">${item.label}</a>` : `<span>${item.label}</span>`}
00562|                       ${item.meta ? `<span class="md-pr-project-meta">${item.meta}</span>` : ""}
00563|                     </div>
00564|                   `
00565|                 )
00566|                 .join("")}
00567|             </div>
00568|           </div>
00569|         ` : ""}
00570|       </div>
00571|     `;
00572|   }
00573| 
00574|   function findPrAuthor() {
00575|     const selectors = [
00576|       ".gh-header-meta .author",
00577|       ".js-discussion .timeline-comment-header .author",
00578|       ".js-discussion .author",
00579|       ".timeline-comment-header .author",
00580|       "a.author"
00581|     ];
00582|     for (const selector of selectors) {
00583|       const el = document.querySelector(selector);
00584|       if (el && el.textContent.trim()) return el.textContent.trim();
00585|     }
00586|     return null;
00587|   }
00588| 
00589|   function removeBadge() {
00590|     const existing = document.getElementById(BADGE_ID);
00591|     if (existing) existing.remove();
00592|   }
00593| 
00594|   function updateBadge(result) {
00595|     const header = document.querySelector(".gh-header-title") || document.querySelector(".gh-header-meta");
00596|     if (!header) return;
00597| 
00598|     removeBadge();
00599|     if (!result || result.state === "error" || result.state === "missing-key") return;
00600| 
00601|     const badge = document.createElement("span");
00602|     badge.id = BADGE_ID;
00603| 
00604|     if (result.state === "not-expert") {
00605|       badge.className = "md-pr-badge-error";
00606|       badge.textContent = "No Profile";
00607|       header.appendChild(badge);
00608|     }
00609|   }
00610| 
00611|   async function fetchExpert(username) {
00612|     const apiKey = String(state.config.apiKey || "").trim();
00613|     if (!apiKey) return { state: "missing-key" };
00614| 
00615|     const url = `https://explore.market.dev/api/v1/experts/${encodeURIComponent(username)}`;
00616| 
00617|     try {
00618|       const backgroundResponse = await fetchViaBackground(url, apiKey);
00619|       let responseStatus = 0;
00620|       let responseData = null;
00621| 
00622|       if (backgroundResponse) {
00623|         responseStatus = backgroundResponse.status || 0;
00624|         responseData = backgroundResponse.data || null;
00625|       } else {
00626|         const response = await fetch(url, {
00627|           headers: {
00628|             Authorization: `Bearer ${apiKey}`,
00629|             Accept: "application/json"
00630|           }
00631|         });
00632|         responseStatus = response.status;
00633|         const text = await response.text();
00634|         try {
00635|           responseData = text ? JSON.parse(text) : null;
00636|         } catch (error) {
00637|           responseData = null;
00638|         }
00639|       }
00640| 
00641|       if (responseStatus === 200) return { state: "expert", expert: responseData };
00642|       if (responseStatus === 404) return { state: "not-expert" };
00643|       if (responseStatus === 401) return { state: "error", message: "Auth failed" };
00644|       return { state: "error", message: "API request failed" };
00645|     } catch (error) {
00646|       return { state: "error", message: "API request failed" };
00647|     }
00648|   }
00649| 
00650|   async function fetchExpertStatus(username) {
00651|     if (state.listCache.has(username)) {
00652|       return state.listCache.get(username);
00653|     }
00654| 
00655|     const apiKey = String(state.config.apiKey || "").trim();
00656|     if (!apiKey) return null;
00657| 
00658|     const url = `https://explore.market.dev/api/v1/experts/${encodeURIComponent(username)}`;
00659|     try {
00660|       const backgroundResponse = await fetchViaBackground(url, apiKey);
00661|       const status = backgroundResponse ? backgroundResponse.status : null;
00662|       if (status === 200 || status === 404) {
00663|         const value = status === 200 ? "expert" : "missing";
00664|         state.listCache.set(username, value);
00665|         return value;
00666|       }
00667|       return null;
00668|     } catch (error) {
00669|       return null;
00670|     }
00671|   }
00672| 
00673|   async function applyListIndicators() {
00674|     if (!isPullListPage()) return;
00675| 
00676|     const rows = document.querySelectorAll("div.js-issue-row");
00677|     rows.forEach((row) => {
00678|       const author = row.getAttribute("data-author");
00679|       if (!author) return;
00680|       const authorLink = row.querySelector("a[data-hovercard-type='user']") || row.querySelector("a.author");
00681|       if (!authorLink) return;
00682|       if (authorLink.parentElement?.querySelector(".md-pr-list-indicator")) return;
00683| 
00684|       fetchExpertStatus(author).then((status) => {
00685|         if (!status) return;
00686|         if (authorLink.parentElement?.querySelector(".md-pr-list-indicator")) return;
00687|         const indicator = document.createElement("span");
00688|         indicator.className = `md-pr-list-indicator ${status === "expert" ? "md-pr-list-expert" : "md-pr-list-missing"}`;
00689|         indicator.title = status === "expert" ? "Expert profile found" : "No expert profile";
00690|         authorLink.insertAdjacentElement("afterend", indicator);

(File has more lines. Use 'offset' parameter to read beyond line 690)
</file>
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n-    return `\n-      <div class=\"md-pr-card\">\n-        <div class=\"md-pr-card-header\">\n-          <div class=\"md-pr-avatar\">\n-            ${avatarUrl ? `<img src=\"${avatarUrl}\" alt=\"${name}\" />` : name.slice(0, 1).toUpperCase()}\n-          </div>\n-          <div>\n-            <div class=\"md-pr-name\">${name}</div>\n-            <div class=\"md-pr-meta\">@${username}${location ? ` · ${location}` : \"\"}</div>\n-            <div class=\"md-pr-links\">\n-              <a class=\"md-pr-link\" href=\"https://github.com/${encodeURIComponent(username)}\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub</a>\n-              <a class=\"md-pr-link\" href=\"${profileUrl}\" target=\"_blank\" rel=\"noopener noreferrer\">Market.dev</a>\n-            </div>\n-          </div>\n-        </div>\n-        ${stats.length ? `\n-          <div class=\"md-pr-stats\">\n-            ${stats\n-              .map(\n-                (stat) => `\n-                  <div class=\"md-pr-stat-row\">\n-                    <span class=\"md-pr-stat-label\">${stat.label}</span>\n-                    <span class=\"md-pr-stat-value\">${stat.value}</span>\n-                  </div>\n-                `\n-              )\n-              .join(\"\")}\n-          </div>\n-        ` : \"\"}\n-        ${ecosystemNames.length ? `\n-          <div class=\"md-pr-section\">\n-            <div class=\"md-pr-section-title\">Ecosystems</div>\n-            <div class=\"md-pr-ecosystems\">\n-              ${ecosystemNames\n-                .map((eco) => `<a class=\"md-pr-ecosystem-pill\" href=\"${eco.url}\" target=\"_blank\" rel=\"noopener noreferrer\">${eco.name}</a>`)\n-                .join(\"\")}\n-            </div>\n-          </div>\n-        ` : \"\"}\n-        ${maintainerItems.length ? `\n-          <div class=\"md-pr-section\">\n-            <div class=\"md-pr-section-title\">Projects</div>\n-            <div class=\"md-pr-project-list\">\n-              ${maintainerItems\n-                .map(\n-                  (item) => `\n-                    <div class=\"md-pr-project-item\">\n-                      ${item.url ? `<a class=\"md-pr-link\" href=\"${item.url}\" target=\"_blank\" rel=\"noopener noreferrer\">${item.label}</a>` : `<span>${item.label}</span>`}\n-                      ${item.meta ? `<span class=\"md-pr-project-meta\">${item.meta}</span>` : \"\"}\n-                    </div>\n-                  `\n-                )\n-                .join(\"\")}\n-            </div>\n-          </div>\n-        ` : \"\"}\n-      </div>\n-    `;\n+    return `\n+      <div class=\"md-pr-card\">\n+        <div class=\"md-pr-card-header\">\n+          <div class=\"md-pr-avatar\">\n+            ${avatarUrl ? `<img src=\"${avatarUrl}\" alt=\"${name}\" />` : name.slice(0, 1).toUpperCase()}\n+          </div>\n+          <div>\n+            <div class=\"md-pr-name\"><a class=\"md-pr-link\" href=\"https://github.com/${encodeURIComponent(username)}\" target=\"_blank\" rel=\"noopener noreferrer\">${name}</a></div>\n+            <div class=\"md-pr-meta\">@${username}${location ? ` · ${location}` : \"\"}</div>\n+            <div class=\"md-pr-links\">\n+              <a class=\"md-pr-link\" href=\"https://github.com/${encodeURIComponent(username)}\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub</a>\n+              <a class=\"md-pr-link\" href=\"${profileUrl}\" target=\"_blank\" rel=\"noopener noreferrer\">Market.dev</a>\n+            </div>\n+          </div>\n+        </div>\n+        ${stats.length ? `\n+          <div class=\"md-pr-stats\">\n+            ${stats\n+              .map(\n+                (stat) => `<span class=\"md-pr-stat-item\"><span class=\"md-pr-stat-label\">${stat.label}:</span> ${stat.value}</span>`\n+              )\n+              .join('<span class=\"md-pr-stat-sep\">·</span>')}\n+          </div>\n+        ` : \"\"}\n+        ${ecosystemNames.length ? `\n+          <div class=\"md-pr-section\">\n+            <div class=\"md-pr-section-title\">Ecosystems</div>\n+            <div class=\"md-pr-ecosystems\">\n+              ${ecosystemNames\n+                .map((eco) => `<a class=\"md-pr-ecosystem-pill\" href=\"${eco.url}\" target=\"_blank\" rel=\"noopener noreferrer\">${eco.name}</a>`)\n+                .join(\"\")}\n+            </div>\n+          </div>\n+        ` : \"\"}\n+        ${maintainerItems.length ? `\n+          <div class=\"md-pr-section\">\n+            <div class=\"md-pr-section-title\">Projects</div>\n+            <div class=\"md-pr-project-list\">\n+              ${maintainerItems\n+                .map(\n+                  (item) => `\n+                    <div class=\"md-pr-project-item\">\n+                      ${item.url ? `<a class=\"md-pr-link\" href=\"${item.url}\" target=\"_blank\" rel=\"noopener noreferrer\">${item.label}</a>` : `<span>${item.label}</span>`}\n+                      ${item.meta ? `<span class=\"md-pr-project-meta\">${item.meta}</span>` : \"\"}\n+                    </div>\n+                  `\n+                )\n+                .join(\"\")}\n+            </div>\n+          </div>\n+        ` : \"\"}\n+      </div>\n+    `;\n   }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "pattern": "Open Source Explorer"
}
```

## Assistant

**Result** (success):
```
Found 1 matches
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js:
  Line 346:         <div class="md-pr-powered">Powered by the Open Source Explorer</div>
```

## Assistant

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "pattern": "md-pr-success"
}
```

## Assistant

**Result** (success):
```
No files found
```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check content.js",
  "description": "Check content script syntax"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "pattern": "md-pr-stat-row|md-pr-stat-value|md-pr-pill|md-pr-success"
}
```

## Assistant

**Result** (success):
```
No files found
```

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 380,
  "offset": 50
}
```

## Assistant

**Result** (success):
```
<file>
00051|         (response) => {
00052|           if (chrome.runtime.lastError) {
00053|             resolve(null);
00054|             return;
00055|           }
00056|           resolve(response);
00057|         }
00058|       );
00059|     });
00060|   }
00061| 
00062|   function ensureStyles() {
00063|     if (document.getElementById(STYLE_ID)) return;
00064|     const style = document.createElement("style");
00065|     style.id = STYLE_ID;
00066|     style.textContent = `
00067|       #${PANEL_ID} {
00068|         color: var(--fgColor-default, #24292f);
00069|       }
00070|       #${PANEL_ID}.discussion-sidebar-item {
00071|         margin-top: 0;
00072|       }
00073|       #${PANEL_ID} .md-pr-panel {
00074|         font-size: 12px;
00075|         line-height: 1.5;
00076|       }
00077|       #${PANEL_ID} .md-pr-header {
00078|         display: flex;
00079|         justify-content: space-between;
00080|         align-items: center;
00081|         margin-bottom: 6px;
00082|       }
00083|       #${PANEL_ID} .md-pr-heading {
00084|         margin: 0;
00085|       }
00086|       #${PANEL_ID} .md-pr-gear {
00087|         border: none;
00088|         background: transparent;
00089|         color: var(--fgColor-muted, #57606a);
00090|         width: 20px;
00091|         height: 20px;
00092|         padding: 0;
00093|         display: inline-flex;
00094|         align-items: center;
00095|         justify-content: center;
00096|         cursor: pointer;
00097|       }
00098|       #${PANEL_ID} .md-pr-gear:hover {
00099|         color: var(--fgColor-default, #24292f);
00100|       }
00101|       #${PANEL_ID} .md-pr-settings {
00102|         display: none;
00103|         margin-top: 8px;
00104|       }
00105|       #${PANEL_ID} .md-pr-settings.md-pr-open {
00106|         display: block;
00107|       }
00108|       #${PANEL_ID} .md-pr-settings label {
00109|         display: block;
00110|         margin-bottom: 4px;
00111|         font-size: 12px;
00112|         color: var(--fgColor-muted, #57606a);
00113|       }
00114|       #${PANEL_ID} .md-pr-settings input[type="password"] {
00115|         width: 100%;
00116|         border: 1px solid var(--borderColor-default, #d0d7de);
00117|         border-radius: 6px;
00118|         padding: 5px 8px;
00119|         font-size: 12px;
00120|         color: var(--fgColor-default, #24292f);
00121|         background: var(--bgColor-default, #ffffff);
00122|       }
00123|       #${PANEL_ID} .md-pr-status {
00124|         color: var(--fgColor-muted, #57606a);
00125|       }
00126|       #${PANEL_ID} .md-pr-warning {
00127|         color: var(--fgColor-danger, #cf222e);
00128|       }
00129|       #${PANEL_ID} .md-pr-details {
00130|         color: var(--fgColor-muted, #57606a);
00131|       }
00132|       #${PANEL_ID} .md-pr-summary {
00133|         margin-bottom: 8px;
00134|         color: var(--fgColor-default, #24292f);
00135|       }
00136|       #${PANEL_ID} .md-pr-card-header {
00137|         display: flex;
00138|         gap: 8px;
00139|         align-items: flex-start;
00140|       }
00141|       #${PANEL_ID} .md-pr-avatar {
00142|         width: 32px;
00143|         height: 32px;
00144|         border-radius: 50%;
00145|         overflow: hidden;
00146|         background: var(--bgColor-muted, #f6f8fa);
00147|         display: inline-flex;
00148|         align-items: center;
00149|         justify-content: center;
00150|         font-weight: 600;
00151|         color: var(--fgColor-muted, #57606a);
00152|         flex-shrink: 0;
00153|       }
00154|       #${PANEL_ID} .md-pr-avatar img {
00155|         width: 100%;
00156|         height: 100%;
00157|         object-fit: cover;
00158|       }
00159|       #${PANEL_ID} .md-pr-name {
00160|         font-size: 13px;
00161|         font-weight: 600;
00162|         color: var(--fgColor-default, #24292f);
00163|       }
00164|       #${PANEL_ID} .md-pr-meta {
00165|         color: var(--fgColor-muted, #57606a);
00166|       }
00167|       #${PANEL_ID} .md-pr-links {
00168|         margin-top: 2px;
00169|         display: flex;
00170|         gap: 8px;
00171|       }
00172|       #${PANEL_ID} .md-pr-link {
00173|         color: var(--fgColor-accent, #0969da);
00174|         text-decoration: none;
00175|       }
00176|       #${PANEL_ID} .md-pr-link:hover {
00177|         text-decoration: underline;
00178|       }
00179|       #${PANEL_ID} .md-pr-stats {
00180|         margin-top: 8px;
00181|       }
00182|       #${PANEL_ID} .md-pr-stat-item {
00183|         color: var(--fgColor-default, #24292f);
00184|       }
00185|       #${PANEL_ID} .md-pr-stat-label {
00186|         color: var(--fgColor-muted, #57606a);
00187|       }
00188|       #${PANEL_ID} .md-pr-stat-sep {
00189|         margin: 0 4px;
00190|         color: var(--fgColor-muted, #57606a);
00191|       }
00192|       #${PANEL_ID} .md-pr-section {
00193|         margin-top: 8px;
00194|       }
00195|       #${PANEL_ID} .md-pr-section-title {
00196|         margin-bottom: 2px;
00197|         font-weight: 600;
00198|         color: var(--fgColor-muted, #57606a);
00199|       }
00200|       #${PANEL_ID} .md-pr-ecosystems {
00201|         display: flex;
00202|         flex-wrap: wrap;
00203|         gap: 8px;
00204|       }
00205|       #${PANEL_ID} .md-pr-ecosystem-pill {
00206|         color: var(--fgColor-accent, #0969da);
00207|         text-decoration: none;
00208|       }
00209|       #${PANEL_ID} .md-pr-ecosystem-pill:hover {
00210|         text-decoration: underline;
00211|       }
00212|       #${PANEL_ID} .md-pr-project-list {
00213|         display: flex;
00214|         flex-direction: column;
00215|         gap: 2px;
00216|       }
00217|       #${PANEL_ID} .md-pr-project-item {
00218|         display: flex;
00219|         align-items: baseline;
00220|         justify-content: space-between;
00221|         gap: 8px;
00222|       }
00223|       #${PANEL_ID} .md-pr-project-meta {
00224|         color: var(--fgColor-muted, #57606a);
00225|         flex-shrink: 0;
00226|       }
00227|       #${PANEL_ID} .md-pr-powered {
00228|         margin-top: 8px;
00229|         font-size: 11px;
00230|         color: var(--fgColor-muted, #57606a);
00231|         opacity: 0.65;
00232|       }
00233|       .md-pr-list-indicator {
00234|         display: inline-flex;
00235|         align-items: center;
00236|         justify-content: center;
00237|         width: 8px;
00238|         height: 8px;
00239|         border-radius: 999px;
00240|         margin-left: 6px;
00241|         border: 1px solid #d0d7de;
00242|       }
00243|       .md-pr-list-indicator.md-pr-list-expert {
00244|         background: #2da44e;
00245|         border-color: #2da44e;
00246|       }
00247|       .md-pr-list-indicator.md-pr-list-missing {
00248|         background: #afb8c1;
00249|       }
00250|       #${BADGE_ID} {
00251|         display: inline-flex;
00252|         align-items: center;
00253|         gap: 6px;
00254|         margin-left: 8px;
00255|         padding: 2px 8px;
00256|         border-radius: 999px;
00257|         font-size: 11px;
00258|         font-weight: 600;
00259|       }
00260|       #${BADGE_ID}.md-pr-badge-error {
00261|         background: #ffe4e8;
00262|         color: #9f1239;
00263|       }
00264|       #${BADGE_ID}.md-pr-badge-success {
00265|         background: #dcfce7;
00266|         color: #166534;
00267|       }
00268|     `;
00269|     document.head.appendChild(style);
00270|   }
00271| 
00272|   function findSidebar() {
00273|     return document.querySelector(".discussion-sidebar");
00274|   }
00275| 
00276|   function findReviewersSection(sidebar) {
00277|     if (!sidebar) return null;
00278|     const byClass = sidebar.querySelector(".discussion-sidebar-item.sidebar-reviewers");
00279|     if (byClass) return byClass;
00280| 
00281|     const headings = sidebar.querySelectorAll(".discussion-sidebar-heading, h3");
00282|     for (const heading of headings) {
00283|       if (heading.textContent.trim().toLowerCase() !== "reviewers") continue;
00284|       const item = heading.closest(".discussion-sidebar-item");
00285|       if (item) return item;
00286|     }
00287| 
00288|     return null;
00289|   }
00290| 
00291|   function mountPanel(wrapper) {
00292|     const sidebar = findSidebar();
00293|     if (!sidebar) return false;
00294| 
00295|     const reviewersSection = findReviewersSection(sidebar);
00296|     if (reviewersSection) {
00297|       if (reviewersSection.nextElementSibling !== wrapper) {
00298|         reviewersSection.insertAdjacentElement("afterend", wrapper);
00299|       }
00300|       return true;
00301|     }
00302| 
00303|     if (wrapper.parentElement !== sidebar) {
00304|       sidebar.appendChild(wrapper);
00305|     }
00306|     return true;
00307|   }
00308| 
00309|   function ensurePanel() {
00310|     const existing = document.getElementById(PANEL_ID);
00311|     if (!isPullDetailPage()) {
00312|       if (existing) existing.remove();
00313|       removeBadge();
00314|       return;
00315|     }
00316| 
00317|     ensureStyles();
00318| 
00319|     if (existing) {
00320|       mountPanel(existing);
00321|       updatePanel(existing);
00322|       return;
00323|     }
00324| 
00325|     const wrapper = document.createElement("div");
00326|     wrapper.id = PANEL_ID;
00327|     wrapper.className = "discussion-sidebar-item";
00328|     wrapper.innerHTML = `
00329|       <div class="md-pr-panel">
00330|         <div class="md-pr-header">
00331|           <h3 class="discussion-sidebar-heading md-pr-heading">Contributor insights</h3>
00332|           <button class="md-pr-gear" type="button" aria-label="Settings">
00333|             <span aria-hidden="true">⚙</span>
00334|           </button>
00335|         </div>
00336|         <div class="md-pr-body">
00337|           <div class="md-pr-summary"></div>
00338|           <div class="md-pr-status"></div>
00339|           <div class="md-pr-details"></div>
00340|         </div>
00341|         <div class="md-pr-settings ${state.config.settingsOpen ? "md-pr-open" : ""}">
00342|           <label for="${PANEL_ID}-api-key">API key</label>
00343|           <input id="${PANEL_ID}-api-key" type="password" data-config="apiKey" />
00344|           <div class="md-pr-status"></div>
00345|         </div>
00346|         <div class="md-pr-powered">Powered by the Open Source Explorer</div>
00347|       </div>
00348|     `;
00349| 
00350|     wrapper.querySelector(".md-pr-gear").addEventListener("click", () => {
00351|       const settings = wrapper.querySelector(".md-pr-settings");
00352|       const open = settings.classList.toggle("md-pr-open");
00353|       saveConfig({ ...state.config, settingsOpen: open });
00354|     });
00355| 
00356|     wrapper.querySelectorAll("[data-config]").forEach((input) => {
00357|       const key = input.getAttribute("data-config");
00358|       input.value = state.config[key] ?? "";
00359|       input.addEventListener("change", () => {
00360|         if (key === "apiKey") {
00361|           state.listCache.clear();
00362|         }
00363|         saveConfig({ ...state.config, [key]: input.value });
00364|         applyCheck();
00365|         applyListIndicators();
00366|       });
00367|     });
00368| 
00369|     if (!mountPanel(wrapper)) {
00370|       return;
00371|     }
00372| 
00373|     updatePanel(wrapper);
00374|   }
00375| 
00376|   function updatePanel(wrapper) {
00377|     const summary = wrapper.querySelector(".md-pr-summary");
00378|     const statusBlocks = wrapper.querySelectorAll(".md-pr-status");
00379|     const details = wrapper.querySelector(".md-pr-details");
00380|     const result = state.currentResult;
00381| 
00382|     statusBlocks.forEach((status) => {
00383|       status.textContent = "";
00384|       status.innerHTML = "";
00385|     });
00386| 
00387|     if (!result) {
00388|       statusBlocks.forEach((status) => {
00389|         status.textContent = "Checking PR author...";
00390|       });
00391|       summary.textContent = "";
00392|       details.textContent = "";
00393|       return;
00394|     }
00395| 
00396|     if (result.state === "missing-key") {
00397|       statusBlocks.forEach((status) => {
00398|         status.innerHTML = `<span class="md-pr-warning">API key required</span>`;
00399|       });
00400|       summary.textContent = "";
00401|       details.textContent = "";
00402|       return;
00403|     }
00404| 
00405|     if (result.state === "error") {
00406|       statusBlocks.forEach((status) => {
00407|         status.innerHTML = `<span class="md-pr-warning">${result.message}</span>`;
00408|       });
00409|       summary.textContent = "";
00410|       details.textContent = "";
00411|       return;
00412|     }
00413| 
00414|     if (result.state === "not-expert") {
00415|       statusBlocks.forEach((status) => {
00416|         status.innerHTML = "";
00417|       });
00418|       summary.textContent = "No contributor profile found yet.";
00419|       details.innerHTML = `<a class="md-pr-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Browse directory</a>`;
00420|       return;
00421|     }
00422| 
00423|     if (result.state === "expert") {
00424|       statusBlocks.forEach((status) => {
00425|         status.innerHTML = "";
00426|       });
00427|       const info = result.expert && result.expert.expert ? result.expert.expert : result.expert;
00428|       summary.textContent = buildSummary(info, result.username);
00429|       details.innerHTML = renderExpertDetails(info, result.username);
00430|     }

(File has more lines. Use 'offset' parameter to read beyond line 430)
</file>
```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git diff -- content.js",
  "description": "Show changes in content script"
}
```

## Assistant

**Result** (success):
```
diff --git a/content.js b/content.js
index 6c186a7..f2a3e03 100644
--- a/content.js
+++ b/content.js
@@ -65,116 +65,91 @@
     style.id = STYLE_ID;
     style.textContent = `
       #${PANEL_ID} {
-        position: fixed;
-        right: 16px;
-        bottom: 16px;
-        z-index: 999999;
-        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
-        color: #1f2328;
+        color: var(--fgColor-default, #24292f);
+      }
+      #${PANEL_ID}.discussion-sidebar-item {
+        margin-top: 0;
       }
       #${PANEL_ID} .md-pr-panel {
-        width: 440px;
-        background: #ffffff;
-        border: 1px solid #d0d7de;
-        border-radius: 12px;
-        box-shadow: 0 1px 3px rgba(27, 31, 36, 0.12);
-        padding: 12px 12px 10px;
-        font-size: 14px;
+        font-size: 12px;
+        line-height: 1.5;
       }
       #${PANEL_ID} .md-pr-header {
         display: flex;
-        justify-content: flex-end;
+        justify-content: space-between;
         align-items: center;
-        gap: 8px;
-        font-weight: 600;
-        font-size: 13px;
+        margin-bottom: 6px;
+      }
+      #${PANEL_ID} .md-pr-heading {
+        margin: 0;
       }
       #${PANEL_ID} .md-pr-gear {
         border: none;
-        background: #f6f8fa;
-        border-radius: 6px;
-        width: 28px;
-        height: 28px;
+        background: transparent;
+        color: var(--fgColor-muted, #57606a);
+        width: 20px;
+        height: 20px;
+        padding: 0;
         display: inline-flex;
         align-items: center;
         justify-content: center;
         cursor: pointer;
-        border: 1px solid #d0d7de;
-        color: #57606a;
       }
-      #${PANEL_ID} .md-pr-body {
-        margin-top: 10px;
+      #${PANEL_ID} .md-pr-gear:hover {
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-settings {
         display: none;
-        margin-top: 10px;
-        border-top: 1px dashed #d0d7de;
-        padding-top: 10px;
+        margin-top: 8px;
       }
       #${PANEL_ID} .md-pr-settings.md-pr-open {
         display: block;
       }
-      #${PANEL_ID} label {
+      #${PANEL_ID} .md-pr-settings label {
         display: block;
-        margin-bottom: 6px;
-        font-weight: 600;
+        margin-bottom: 4px;
         font-size: 12px;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
       }
-      #${PANEL_ID} input[type="text"],
-      #${PANEL_ID} input[type="password"] {
+      #${PANEL_ID} .md-pr-settings input[type="password"] {
         width: 100%;
-        border: 1px solid #d0d7de;
+        border: 1px solid var(--borderColor-default, #d0d7de);
         border-radius: 6px;
-        padding: 6px 8px;
-        font-size: 14px;
-        background: #ffffff;
-        margin-bottom: 8px;
+        padding: 5px 8px;
+        font-size: 12px;
+        color: var(--fgColor-default, #24292f);
+        background: var(--bgColor-default, #ffffff);
       }
       #${PANEL_ID} .md-pr-status {
-        margin-top: 8px;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-warning {
-        color: #cf222e;
-        font-weight: 600;
-      }
-      #${PANEL_ID} .md-pr-success {
-        color: #1a7f37;
-        font-weight: 600;
+        color: var(--fgColor-danger, #cf222e);
       }
       #${PANEL_ID} .md-pr-details {
-        margin-top: 6px;
-        color: #24292f;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-summary {
-        margin-top: 6px;
-        font-size: 18px;
-        color: #24292f;
-        font-weight: 600;
-      }
-      #${PANEL_ID} .md-pr-card {
-        border: 1px solid #d0d7de;
-        border-radius: 10px;
-        padding: 12px;
+        margin-bottom: 8px;
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-card-header {
         display: flex;
-        gap: 12px;
-        align-items: center;
+        gap: 8px;
+        align-items: flex-start;
       }
       #${PANEL_ID} .md-pr-avatar {
-        width: 56px;
-        height: 56px;
+        width: 32px;
+        height: 32px;
         border-radius: 50%;
-        background: #f6f8fa;
-        border: 1px solid #d0d7de;
         overflow: hidden;
+        background: var(--bgColor-muted, #f6f8fa);
         display: inline-flex;
         align-items: center;
         justify-content: center;
         font-weight: 600;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
+        flex-shrink: 0;
       }
       #${PANEL_ID} .md-pr-avatar img {
         width: 100%;
@@ -182,95 +157,78 @@
         object-fit: cover;
       }
       #${PANEL_ID} .md-pr-name {
-        font-size: 18px;
-        font-weight: 700;
-        color: #1a7f37;
+        font-size: 13px;
+        font-weight: 600;
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-meta {
-        margin-top: 6px;
-        color: #57606a;
-        font-size: 14px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-links {
-        margin-top: 6px;
+        margin-top: 2px;
         display: flex;
-        gap: 12px;
-        font-size: 14px;
+        gap: 8px;
       }
       #${PANEL_ID} .md-pr-link {
-        color: #0969da;
-        font-weight: 600;
+        color: var(--fgColor-accent, #0969da);
+        text-decoration: none;
       }
-      #${PANEL_ID} .md-pr-stats {
-        margin-top: 12px;
-        border: 1px solid #d0d7de;
-        border-radius: 8px;
-        overflow: hidden;
+      #${PANEL_ID} .md-pr-link:hover {
+        text-decoration: underline;
       }
-      #${PANEL_ID} .md-pr-stat-row {
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        padding: 8px 10px;
-        border-bottom: 1px solid #d0d7de;
-        font-size: 14px;
+      #${PANEL_ID} .md-pr-stats {
+        margin-top: 8px;
       }
-      #${PANEL_ID} .md-pr-stat-row:last-child {
-        border-bottom: none;
+      #${PANEL_ID} .md-pr-stat-item {
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-stat-label {
-        color: #57606a;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        font-weight: 600;
-        font-size: 11px;
+        color: var(--fgColor-muted, #57606a);
       }
-      #${PANEL_ID} .md-pr-stat-value {
-        font-weight: 700;
-        color: #24292f;
+      #${PANEL_ID} .md-pr-stat-sep {
+        margin: 0 4px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-section {
-        margin-top: 12px;
+        margin-top: 8px;
       }
       #${PANEL_ID} .md-pr-section-title {
-        font-size: 13px;
+        margin-bottom: 2px;
         font-weight: 600;
-        color: #57606a;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        margin-bottom: 6px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-ecosystems {
         display: flex;
         flex-wrap: wrap;
-        gap: 6px;
+        gap: 8px;
       }
       #${PANEL_ID} .md-pr-ecosystem-pill {
-        display: inline-flex;
-        align-items: center;
-        background: #f6f8fa;
-        border: 1px solid #d0d7de;
-        border-radius: 999px;
-        padding: 2px 8px;
-        font-size: 13px;
-        color: #57606a;
+        color: var(--fgColor-accent, #0969da);
         text-decoration: none;
       }
+      #${PANEL_ID} .md-pr-ecosystem-pill:hover {
+        text-decoration: underline;
+      }
       #${PANEL_ID} .md-pr-project-list {
         display: flex;
         flex-direction: column;
-        gap: 6px;
+        gap: 2px;
       }
       #${PANEL_ID} .md-pr-project-item {
         display: flex;
+        align-items: baseline;
         justify-content: space-between;
         gap: 8px;
-        font-size: 14px;
-        color: #24292f;
       }
       #${PANEL_ID} .md-pr-project-meta {
-        color: #57606a;
-        font-size: 13px;
+        color: var(--fgColor-muted, #57606a);
+        flex-shrink: 0;
+      }
+      #${PANEL_ID} .md-pr-powered {
+        margin-top: 8px;
+        font-size: 11px;
+        color: var(--fgColor-muted, #57606a);
+        opacity: 0.65;
       }
       .md-pr-list-indicator {
         display: inline-flex;
@@ -289,55 +247,6 @@
       .md-pr-list-indicator.md-pr-list-missing {
         background: #afb8c1;
       }
-      #${PANEL_ID} .md-pr-section {
-        margin-top: 8px;
-      }
-      #${PANEL_ID} .md-pr-section-title {
-        font-size: 11px;
-        font-weight: 600;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        color: #6b7280;
-        margin-bottom: 4px;
-      }
-      #${PANEL_ID} .md-pr-stats {
-        display: grid;
-        grid-template-columns: repeat(3, minmax(0, 1fr));
-        gap: 6px;
-      }
-      #${PANEL_ID} .md-pr-stat {
-        background: #ffffff;
-        border: 1px solid #e5e7eb;
-        border-radius: 8px;
-        padding: 6px;
-        text-align: center;
-      }
-      #${PANEL_ID} .md-pr-stat-label {
-        font-size: 10px;
-        text-transform: uppercase;
-        letter-spacing: 0.05em;
-        color: #6b7280;
-      }
-      #${PANEL_ID} .md-pr-stat-value {
-        font-size: 13px;
-        font-weight: 600;
-        color: #111827;
-      }
-      #${PANEL_ID} .md-pr-pill {
-        display: inline-flex;
-        align-items: center;
-        padding: 2px 6px;
-        border-radius: 999px;
-        background: #eef2ff;
-        color: #3730a3;
-        font-size: 11px;
-        margin-right: 4px;
-        margin-bottom: 4px;
-      }
-      #${PANEL_ID} .md-pr-link {
-        color: #0a3069;
-        font-weight: 600;
-      }
       #${BADGE_ID} {
         display: inline-flex;
         align-items: center;
@@ -360,6 +269,43 @@
     document.head.appendChild(style);
   }
 
+  function findSidebar() {
+    return document.querySelector(".discussion-sidebar");
+  }
+
+  function findReviewersSection(sidebar) {
+    if (!sidebar) return null;
+    const byClass = sidebar.querySelector(".discussion-sidebar-item.sidebar-reviewers");
+    if (byClass) return byClass;
+
+    const headings = sidebar.querySelectorAll(".discussion-sidebar-heading, h3");
+    for (const heading of headings) {
+      if (heading.textContent.trim().toLowerCase() !== "reviewers") continue;
+      const item = heading.closest(".discussion-sidebar-item");
+      if (item) return item;
+    }
+
+    return null;
+  }
+
+  function mountPanel(wrapper) {
+    const sidebar = findSidebar();
+    if (!sidebar) return false;
+
+    const reviewersSection = findReviewersSection(sidebar);
+    if (reviewersSection) {
+      if (reviewersSection.nextElementSibling !== wrapper) {
+        reviewersSection.insertAdjacentElement("afterend", wrapper);
+      }
+      return true;
+    }
+
+    if (wrapper.parentElement !== sidebar) {
+      sidebar.appendChild(wrapper);
+    }
+    return true;
+  }
+
   function ensurePanel() {
     const existing = document.getElementById(PANEL_ID);
     if (!isPullDetailPage()) {
@@ -371,16 +317,18 @@
     ensureStyles();
 
     if (existing) {
+      mountPanel(existing);
       updatePanel(existing);
       return;
     }
 
     const wrapper = document.createElement("div");
     wrapper.id = PANEL_ID;
+    wrapper.className = "discussion-sidebar-item";
     wrapper.innerHTML = `
       <div class="md-pr-panel">
         <div class="md-pr-header">
-          <span></span>
+          <h3 class="discussion-sidebar-heading md-pr-heading">Contributor insights</h3>
           <button class="md-pr-gear" type="button" aria-label="Settings">
             <span aria-hidden="true">⚙</span>
           </button>
@@ -391,10 +339,11 @@
           <div class="md-pr-details"></div>
         </div>
         <div class="md-pr-settings ${state.config.settingsOpen ? "md-pr-open" : ""}">
-          <label>API key</label>
-          <input type="password" data-config="apiKey" />
+          <label for="${PANEL_ID}-api-key">API key</label>
+          <input id="${PANEL_ID}-api-key" type="password" data-config="apiKey" />
           <div class="md-pr-status"></div>
         </div>
+        <div class="md-pr-powered">Powered by the Open Source Explorer</div>
       </div>
     `;
 
@@ -417,7 +366,10 @@
       });
     });
 
-    document.body.appendChild(wrapper);
+    if (!mountPanel(wrapper)) {
+      return;
+    }
+
     updatePanel(wrapper);
   }
 
@@ -463,8 +415,8 @@
       statusBlocks.forEach((status) => {
         status.innerHTML = "";
       });
-      summary.innerHTML = `No profile found on the Open Source Explorer. <a class="md-pr-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Explore</a>`;
-      details.innerHTML = "";
+      summary.textContent = "No contributor profile found yet.";
+      details.innerHTML = `<a class="md-pr-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Browse directory</a>`;
       return;
     }
 
@@ -566,7 +518,7 @@
             ${avatarUrl ? `<img src="${avatarUrl}" alt="${name}" />` : name.slice(0, 1).toUpperCase()}
           </div>
           <div>
-            <div class="md-pr-name">${name}</div>
+            <div class="md-pr-name"><a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">${name}</a></div>
             <div class="md-pr-meta">@${username}${location ? ` · ${location}` : ""}</div>
             <div class="md-pr-links">
               <a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">GitHub</a>
@@ -578,14 +530,9 @@
           <div class="md-pr-stats">
             ${stats
               .map(
-                (stat) => `
-                  <div class="md-pr-stat-row">
-                    <span class="md-pr-stat-label">${stat.label}</span>
-                    <span class="md-pr-stat-value">${stat.value}</span>
-                  </div>
-                `
+                (stat) => `<span class="md-pr-stat-item"><span class="md-pr-stat-label">${stat.label}:</span> ${stat.value}</span>`
               )
-              .join("")}
+              .join('<span class="md-pr-stat-sep">·</span>')}
           </div>
         ` : ""}
         ${ecosystemNames.length ? `

```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git status --short",
  "description": "Check modified files"
}
```

## Assistant

**Result** (success):
```
 M content.js

```

## Assistant

## Assistant

Done — I moved the panel into GitHub’s PR sidebar and restyled it to blend in as a native section under Reviewers.

- The plugin now mounts directly in `.discussion-sidebar`, positioned immediately after the Reviewers block instead of floating in the viewport (`content.js:272`, `content.js:309`).
- I removed the custom “card” look (fixed position, large borders, shadow, boxed stats) and switched to subtle GitHub-like spacing/typography (`content.js:62`).
- The section now reads as an inline sidebar item with lightweight controls and no extra visual chrome (`content.js:325`).
- I removed the in-body Open Source Explorer mentions; the only remaining mention is the subtle footer text: “Powered by the Open Source Explorer” (`content.js:346`).
- “Not found” copy is now neutral and simple: “No contributor profile found yet.” with a low-key directory link (`content.js:414`).
- I also ran a syntax check: `node --check content.js` (passes).

If you want, next I can:
1. Tighten it even further to look *exactly* like an existing GitHub sidebar item (matching heading size/line-height one-to-one).
2. Apply the same visual changes to `bookmarklet.js` too so both extension + bookmarklet UIs are consistent.

## User

yes exactly, i don't want that popup style anymore

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "limit": 30,
  "offset": 0
}
```

## Assistant

**Result** (success):
```
<file>
00001| (() => {
00002|   if (window.__mdExpertPrBookmarklet) return;
00003|   window.__mdExpertPrBookmarklet = true;
00004| 
00005|   const STORAGE_KEY = "md_expert_pr_config";
00006|   const STYLE_ID = "md-expert-pr-style";
00007|   const PANEL_ID = "md-expert-pr-panel";
00008|   const BADGE_ID = "md-expert-pr-badge";
00009| 
00010|   const DEFAULT_CONFIG = {
00011|     apiKey: "",
00012|     settingsOpen: false
00013|   };
00014| 
00015|   const state = {
00016|     config: loadConfig(),
00017|     currentResult: null
00018|   };
00019| 
00020|   function loadConfig() {
00021|     const raw = window.localStorage.getItem(STORAGE_KEY);
00022|     if (!raw) return { ...DEFAULT_CONFIG };
00023|     try {
00024|       const parsed = JSON.parse(raw);
00025|       return { ...DEFAULT_CONFIG, ...parsed };
00026|     } catch (error) {
00027|       return { ...DEFAULT_CONFIG };
00028|     }
00029|   }
00030| 

(File has more lines. Use 'offset' parameter to read beyond line 30)
</file>
```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check bookmarklet.js",
  "description": "Check bookmarklet syntax"
}
```

## Assistant

**Result** (success):
```
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js:678
})();
    ^

SyntaxError: Private field '#$' must be declared in an enclosing class
    at wrapSafe (node:internal/modules/cjs/loader:1740:18)
    at checkSyntax (node:internal/main/check_syntax:76:3)

Node.js v25.6.0

```

## Assistant

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "pattern": "function ensureStyles|function ensurePanel|function updatePanel|function renderExpertDetails|\\)\\(\\);"
}
```

## Assistant

**Result** (success):
```
Found 5 matches
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js:
  Line 40:   function ensureStyles() {
  Line 324:   function ensurePanel() {
  Line 381:   function updatePanel(wrapper) {
  Line 461:   function renderExpertDetails(info, username) {
  Line 678: })();
```

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "limit": 360,
  "offset": 36
}
```

## Assistant

**Result** (success):
```
<file>
00037|     return /\/pull\/(\d+)(\/|$)/.test(window.location.pathname);
00038|   }
00039| 
00040|   function ensureStyles() {
00041|     if (document.getElementById(STYLE_ID)) return;
00042|     const style = document.createElement("style");
00043|     style.id = STYLE_ID;
00044|     style.textContent = `
00045|       #${PANEL_ID} {
00046|         position: fixed;
00047|         right: 16px;
00048|         bottom: 16px;
00049|         z-index: 999999;
00050|         font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
00051|         color: #1f2328;
00052|       }
00053|       #${PANEL_ID} .md-pr-panel {
00054|         width: 440px;
00055|         background: #ffffff;
00056|         border: 1px solid #d0d7de;
00057|         border-radius: 12px;
00058|         box-shadow: 0 1px 3px rgba(27, 31, 36, 0.12);
00059|         padding: 12px 12px 10px;
00060|         font-size: 14px;
00061|       }
00062|       #${PANEL_ID} .md-pr-header {
00063|         display: flex;
00064|         justify-content: flex-end;
00065|         align-items: center;
00066|         gap: 8px;
00067|         font-weight: 600;
00068|         font-size: 13px;
00069|       }
00070|       #${PANEL_ID} .md-pr-gear {
00071|         border: none;
00072|         background: #f6f8fa;
00073|         border-radius: 6px;
00074|         width: 28px;
00075|         height: 28px;
00076|         display: inline-flex;
00077|         align-items: center;
00078|         justify-content: center;
00079|         cursor: pointer;
00080|         border: 1px solid #d0d7de;
00081|         color: #57606a;
00082|       }
00083|       #${PANEL_ID} .md-pr-body {
00084|         margin-top: 10px;
00085|       }
00086|       #${PANEL_ID} .md-pr-settings {
00087|         display: none;
00088|         margin-top: 10px;
00089|         border-top: 1px dashed #d0d7de;
00090|         padding-top: 10px;
00091|       }
00092|       #${PANEL_ID} .md-pr-settings.md-pr-open {
00093|         display: block;
00094|       }
00095|       #${PANEL_ID} label {
00096|         display: block;
00097|         margin-bottom: 6px;
00098|         font-weight: 600;
00099|         font-size: 12px;
00100|         color: #57606a;
00101|       }
00102|       #${PANEL_ID} input[type="text"],
00103|       #${PANEL_ID} input[type="password"] {
00104|         width: 100%;
00105|         border: 1px solid #d0d7de;
00106|         border-radius: 6px;
00107|         padding: 6px 8px;
00108|         font-size: 14px;
00109|         background: #ffffff;
00110|         margin-bottom: 8px;
00111|       }
00112|       #${PANEL_ID} .md-pr-status {
00113|         margin-top: 8px;
00114|         color: #57606a;
00115|       }
00116|       #${PANEL_ID} .md-pr-warning {
00117|         color: #cf222e;
00118|         font-weight: 600;
00119|       }
00120|       #${PANEL_ID} .md-pr-success {
00121|         color: #1a7f37;
00122|         font-weight: 600;
00123|       }
00124|       #${PANEL_ID} .md-pr-details {
00125|         margin-top: 6px;
00126|         color: #24292f;
00127|       }
00128|       #${PANEL_ID} .md-pr-summary {
00129|         margin-top: 6px;
00130|         font-size: 18px;
00131|         color: #24292f;
00132|         font-weight: 600;
00133|       }
00134|       #${PANEL_ID} .md-pr-card {
00135|         border: 1px solid #d0d7de;
00136|         border-radius: 10px;
00137|         padding: 12px;
00138|       }
00139|       #${PANEL_ID} .md-pr-card-header {
00140|         display: flex;
00141|         gap: 12px;
00142|         align-items: center;
00143|       }
00144|       #${PANEL_ID} .md-pr-avatar {
00145|         width: 56px;
00146|         height: 56px;
00147|         border-radius: 50%;
00148|         background: #f6f8fa;
00149|         border: 1px solid #d0d7de;
00150|         overflow: hidden;
00151|         display: inline-flex;
00152|         align-items: center;
00153|         justify-content: center;
00154|         font-weight: 600;
00155|         color: #57606a;
00156|       }
00157|       #${PANEL_ID} .md-pr-avatar img {
00158|         width: 100%;
00159|         height: 100%;
00160|         object-fit: cover;
00161|       }
00162|       #${PANEL_ID} .md-pr-name {
00163|         font-size: 18px;
00164|         font-weight: 700;
00165|         color: #1a7f37;
00166|       }
00167|       #${PANEL_ID} .md-pr-meta {
00168|         margin-top: 6px;
00169|         color: #57606a;
00170|         font-size: 14px;
00171|       }
00172|       #${PANEL_ID} .md-pr-links {
00173|         margin-top: 6px;
00174|         display: flex;
00175|         gap: 12px;
00176|         font-size: 14px;
00177|       }
00178|       #${PANEL_ID} .md-pr-link {
00179|         color: #0969da;
00180|         font-weight: 600;
00181|       }
00182|       #${PANEL_ID} .md-pr-stats {
00183|         margin-top: 12px;
00184|         border: 1px solid #d0d7de;
00185|         border-radius: 8px;
00186|         overflow: hidden;
00187|       }
00188|       #${PANEL_ID} .md-pr-stat-row {
00189|         display: flex;
00190|         justify-content: space-between;
00191|         align-items: center;
00192|         padding: 8px 10px;
00193|         border-bottom: 1px solid #d0d7de;
00194|         font-size: 14px;
00195|       }
00196|       #${PANEL_ID} .md-pr-stat-row:last-child {
00197|         border-bottom: none;
00198|       }
00199|       #${PANEL_ID} .md-pr-stat-label {
00200|         color: #57606a;
00201|         text-transform: uppercase;
00202|         letter-spacing: 0.04em;
00203|         font-weight: 600;
00204|         font-size: 11px;
00205|       }
00206|       #${PANEL_ID} .md-pr-stat-value {
00207|         font-weight: 700;
00208|         color: #24292f;
00209|       }
00210|       #${PANEL_ID} .md-pr-section {
00211|         margin-top: 12px;
00212|       }
00213|       #${PANEL_ID} .md-pr-section-title {
00214|         font-size: 13px;
00215|         font-weight: 600;
00216|         color: #57606a;
00217|         text-transform: uppercase;
00218|         letter-spacing: 0.04em;
00219|         margin-bottom: 6px;
00220|       }
00221|       #${PANEL_ID} .md-pr-ecosystems {
00222|         display: flex;
00223|         flex-wrap: wrap;
00224|         gap: 6px;
00225|       }
00226|       #${PANEL_ID} .md-pr-ecosystem-pill {
00227|         display: inline-flex;
00228|         align-items: center;
00229|         background: #f6f8fa;
00230|         border: 1px solid #d0d7de;
00231|         border-radius: 999px;
00232|         padding: 2px 8px;
00233|         font-size: 13px;
00234|         color: #57606a;
00235|         text-decoration: none;
00236|       }
00237|       #${PANEL_ID} .md-pr-project-list {
00238|         display: flex;
00239|         flex-direction: column;
00240|         gap: 6px;
00241|       }
00242|       #${PANEL_ID} .md-pr-project-item {
00243|         display: flex;
00244|         justify-content: space-between;
00245|         gap: 8px;
00246|         font-size: 14px;
00247|         color: #24292f;
00248|       }
00249|       #${PANEL_ID} .md-pr-project-meta {
00250|         color: #57606a;
00251|         font-size: 13px;
00252|       }
00253|       #${PANEL_ID} .md-pr-section {
00254|         margin-top: 8px;
00255|       }
00256|       #${PANEL_ID} .md-pr-section-title {
00257|         font-size: 11px;
00258|         font-weight: 600;
00259|         text-transform: uppercase;
00260|         letter-spacing: 0.04em;
00261|         color: #6b7280;
00262|         margin-bottom: 4px;
00263|       }
00264|       #${PANEL_ID} .md-pr-stats {
00265|         display: grid;
00266|         grid-template-columns: repeat(3, minmax(0, 1fr));
00267|         gap: 6px;
00268|       }
00269|       #${PANEL_ID} .md-pr-stat {
00270|         background: #ffffff;
00271|         border: 1px solid #e5e7eb;
00272|         border-radius: 8px;
00273|         padding: 6px;
00274|         text-align: center;
00275|       }
00276|       #${PANEL_ID} .md-pr-stat-label {
00277|         font-size: 10px;
00278|         text-transform: uppercase;
00279|         letter-spacing: 0.05em;
00280|         color: #6b7280;
00281|       }
00282|       #${PANEL_ID} .md-pr-stat-value {
00283|         font-size: 13px;
00284|         font-weight: 600;
00285|         color: #111827;
00286|       }
00287|       #${PANEL_ID} .md-pr-pill {
00288|         display: inline-flex;
00289|         align-items: center;
00290|         padding: 2px 6px;
00291|         border-radius: 999px;
00292|         background: #eef2ff;
00293|         color: #3730a3;
00294|         font-size: 11px;
00295|         margin-right: 4px;
00296|         margin-bottom: 4px;
00297|       }
00298|       #${PANEL_ID} .md-pr-link {
00299|         color: #0a3069;
00300|         font-weight: 600;
00301|       }
00302|       #${BADGE_ID} {
00303|         display: inline-flex;
00304|         align-items: center;
00305|         gap: 6px;
00306|         margin-left: 8px;
00307|         padding: 2px 8px;
00308|         border-radius: 999px;
00309|         font-size: 11px;
00310|         font-weight: 600;
00311|       }
00312|       #${BADGE_ID}.md-pr-badge-error {
00313|         background: #ffe4e8;
00314|         color: #9f1239;
00315|       }
00316|       #${BADGE_ID}.md-pr-badge-success {
00317|         background: #dcfce7;
00318|         color: #166534;
00319|       }
00320|     `;
00321|     document.head.appendChild(style);
00322|   }
00323| 
00324|   function ensurePanel() {
00325|     const existing = document.getElementById(PANEL_ID);
00326|     if (!isPullDetailPage()) {
00327|       if (existing) existing.remove();
00328|       removeBadge();
00329|       return;
00330|     }
00331| 
00332|     ensureStyles();
00333| 
00334|     if (existing) {
00335|       updatePanel(existing);
00336|       return;
00337|     }
00338| 
00339|     const wrapper = document.createElement("div");
00340|     wrapper.id = PANEL_ID;
00341|     wrapper.innerHTML = `
00342|       <div class="md-pr-panel">
00343|         <div class="md-pr-header">
00344|           <span></span>
00345|           <button class="md-pr-gear" type="button" aria-label="Settings">
00346|             <span aria-hidden="true">⚙</span>
00347|           </button>
00348|         </div>
00349|         <div class="md-pr-body">
00350|           <div class="md-pr-summary"></div>
00351|           <div class="md-pr-status"></div>
00352|           <div class="md-pr-details"></div>
00353|         </div>
00354|         <div class="md-pr-settings ${state.config.settingsOpen ? "md-pr-open" : ""}">
00355|           <label>API key</label>
00356|           <input type="password" data-config="apiKey" />
00357|           <div class="md-pr-status"></div>
00358|         </div>
00359|       </div>
00360|     `;
00361| 
00362|     wrapper.querySelector(".md-pr-gear").addEventListener("click", () => {
00363|       const settings = wrapper.querySelector(".md-pr-settings");
00364|       const open = settings.classList.toggle("md-pr-open");
00365|       saveConfig({ ...state.config, settingsOpen: open });
00366|     });
00367| 
00368|     wrapper.querySelectorAll("[data-config]").forEach((input) => {
00369|       const key = input.getAttribute("data-config");
00370|       input.value = state.config[key] ?? "";
00371|       input.addEventListener("change", () => {
00372|         saveConfig({ ...state.config, [key]: input.value });
00373|         applyCheck();
00374|       });
00375|     });
00376| 
00377|     document.body.appendChild(wrapper);
00378|     updatePanel(wrapper);
00379|   }
00380| 
00381|   function updatePanel(wrapper) {
00382|     const summary = wrapper.querySelector(".md-pr-summary");
00383|     const statusBlocks = wrapper.querySelectorAll(".md-pr-status");
00384|     const details = wrapper.querySelector(".md-pr-details");
00385|     const result = state.currentResult;
00386| 
00387|     statusBlocks.forEach((status) => {
00388|       status.textContent = "";
00389|       status.innerHTML = "";
00390|     });
00391| 
00392|     if (!result) {
00393|       statusBlocks.forEach((status) => {
00394|         status.textContent = "Checking PR author...";
00395|       });
00396|       summary.textContent = "";

(File has more lines. Use 'offset' parameter to read beyond line 396)
</file>
```

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "limit": 320,
  "offset": 396
}
```

## Assistant

**Result** (success):
```
<file>
00397|       details.textContent = "";
00398|       return;
00399|     }
00400| 
00401|     if (result.state === "missing-key") {
00402|       statusBlocks.forEach((status) => {
00403|         status.innerHTML = `<span class="md-pr-warning">API key required</span>`;
00404|       });
00405|       summary.textContent = "";
00406|       details.textContent = "";
00407|       return;
00408|     }
00409| 
00410|     if (result.state === "error") {
00411|       statusBlocks.forEach((status) => {
00412|         status.innerHTML = `<span class="md-pr-warning">${result.message}</span>`;
00413|       });
00414|       summary.textContent = "";
00415|       details.textContent = "";
00416|       return;
00417|     }
00418| 
00419|     if (result.state === "not-expert") {
00420|       statusBlocks.forEach((status) => {
00421|         status.innerHTML = "";
00422|       });
00423|       summary.innerHTML = `No profile found on the Open Source Explorer. <a class="md-pr-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Explore</a>`;
00424|       details.innerHTML = "";
00425|       return;
00426|     }
00427| 
00428|     if (result.state === "expert") {
00429|       statusBlocks.forEach((status) => {
00430|         status.innerHTML = "";
00431|       });
00432|       const info = result.expert && result.expert.expert ? result.expert.expert : result.expert;
00433|       summary.textContent = buildSummary(info, result.username);
00434|       details.innerHTML = renderExpertDetails(info, result.username);
00435|     }
00436|   }
00437| 
00438|   function buildSummary(info, username) {
00439|     if (!info) return `This PR was opened by ${username}.`;
00440|     const name = info.name || username;
00441|     const downloadsRaw = Number(info.total_downloads || 0);
00442|     const downloads = downloadsRaw > 0 ? formatCompactNumber(downloadsRaw) : null;
00443|     const stars = formatCompactNumber(info.total_stars);
00444|     const downloadText = downloads ? `${downloads} total downloads` : "";
00445|     const starsText = stars ? `${stars} stars on repos` : "";
00446|     const stats = [downloadText, starsText].filter(Boolean).join(", ");
00447|     if (!stats) return `This PR was opened by ${name} (${username}).`;
00448|     return `This PR was opened by ${name} (${username}). They have received ${stats}.`;
00449|   }
00450| 
00451|   function formatCompactNumber(value) {
00452|     if (value === null || value === undefined) return null;
00453|     const num = Number(value);
00454|     if (Number.isNaN(num)) return null;
00455|     return new Intl.NumberFormat("en", {
00456|       notation: "compact",
00457|       maximumFractionDigits: 1
00458|     }).format(num);
00459|   }
00460| 
00461|   function renderExpertDetails(info, username) {
00462|     const profileUrl = `https://explore.market.dev/experts/${encodeURIComponent(username)}`;
00463|     if (!info) {
00464|       return `Expert profile: <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Open</a>`;
00465|     }
00466| 
00467|     const name = info.name || username;
00468|     const avatarUrl = info.avatar_url || info.avatar || null;
00469|     const location = info.location || info.display_location || "";
00470| 
00471|     const stats = [
00472|       { label: "Projects", value: formatCompactNumber(info.projects_count) },
00473|       { label: "Downloads", value: formatCompactNumber(info.total_downloads) },
00474|       { label: "Stars", value: formatCompactNumber(info.total_stars) }
00475|     ].filter((stat) => stat.value !== null);
00476| 
00477|     const projects = Array.isArray(info.projects) ? info.projects : [];
00478|     const sortedProjects = [...projects].sort((a, b) => {
00479|       const starsA = Number(a.total_stars || a.stars || 0);
00480|       const starsB = Number(b.total_stars || b.stars || 0);
00481|       if (starsB !== starsA) return starsB - starsA;
00482|       const downloadsA = Number(a.total_downloads || a.downloads || 0);
00483|       const downloadsB = Number(b.total_downloads || b.downloads || 0);
00484|       return downloadsB - downloadsA;
00485|     });
00486|     const maintainerItems = sortedProjects.slice(0, 10).map((project) => {
00487|       const role = project.role || project.project_experts?.[0]?.role;
00488|       const name = project.name || project.slug || "";
00489|       if (!name) return null;
00490|       const stars = formatCompactNumber(project.total_stars || project.stars);
00491|       const downloads = formatCompactNumber(project.total_downloads || project.downloads);
00492|       const metaParts = [stars ? `${stars} stars` : null, downloads ? `${downloads} downloads` : null]
00493|         .filter(Boolean)
00494|         .join(" · ");
00495|       const label = role ? `${role} of ${name}` : name;
00496|       const projectSlug = project.slug || project.name || "";
00497|       const projectUrl =
00498|         project.github_url ||
00499|         project.repo_url ||
00500|         project.url ||
00501|         (projectSlug ? `https://explore.market.dev/projects/${encodeURIComponent(projectSlug)}` : null);
00502|       return { label, meta: metaParts, url: projectUrl };
00503|     }).filter(Boolean);
00504| 
00505|     const ecosystems =
00506|       (Array.isArray(info.ecosystems) && info.ecosystems) ||
00507|       (Array.isArray(info.ecosystem_names) && info.ecosystem_names) ||
00508|       [];
00509| 
00510|     const ecosystemNames = ecosystems
00511|       .map((eco) => (typeof eco === "string" ? eco : eco.name))
00512|       .filter(Boolean)
00513|       .slice(0, 8)
00514|       .map((name) => ({
00515|         name,
00516|         url: `https://explore.market.dev/ecosystems/${encodeURIComponent(name)}`
00517|       }));
00518| 
00519|     return `
00520|       <div class="md-pr-card">
00521|         <div class="md-pr-card-header">
00522|           <div class="md-pr-avatar">
00523|             ${avatarUrl ? `<img src="${avatarUrl}" alt="${name}" />` : name.slice(0, 1).toUpperCase()}
00524|           </div>
00525|           <div>
00526|             <div class="md-pr-name">${name}</div>
00527|             <div class="md-pr-meta">@${username}${location ? ` · ${location}` : ""}</div>
00528|             <div class="md-pr-links">
00529|               <a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">GitHub</a>
00530|               <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Explore</a>
00531|             </div>
00532|           </div>
00533|         </div>
00534|         ${stats.length ? `
00535|           <div class="md-pr-stats">
00536|             ${stats
00537|               .map(
00538|                 (stat) => `
00539|                   <div class="md-pr-stat-row">
00540|                     <span class="md-pr-stat-label">${stat.label}</span>
00541|                     <span class="md-pr-stat-value">${stat.value}</span>
00542|                   </div>
00543|                 `
00544|               )
00545|               .join("")}
00546|           </div>
00547|         ` : ""}
00548|         ${ecosystemNames.length ? `
00549|           <div class="md-pr-section">
00550|             <div class="md-pr-section-title">Ecosystems</div>
00551|             <div class="md-pr-ecosystems">
00552|               ${ecosystemNames
00553|                 .map((eco) => `<a class="md-pr-ecosystem-pill" href="${eco.url}" target="_blank" rel="noopener noreferrer">${eco.name}</a>`)
00554|                 .join("")}
00555|             </div>
00556|           </div>
00557|         ` : ""}
00558|         ${maintainerItems.length ? `
00559|           <div class="md-pr-section">
00560|             <div class="md-pr-section-title">Projects</div>
00561|             <div class="md-pr-project-list">
00562|               ${maintainerItems
00563|                 .map(
00564|                   (item) => `
00565|                     <div class="md-pr-project-item">
00566|                       ${item.url ? `<a class="md-pr-link" href="${item.url}" target="_blank" rel="noopener noreferrer">${item.label}</a>` : `<span>${item.label}</span>`}
00567|                       ${item.meta ? `<span class="md-pr-project-meta">${item.meta}</span>` : ""}
00568|                     </div>
00569|                   `
00570|                 )
00571|                 .join("")}
00572|             </div>
00573|           </div>
00574|         ` : ""}
00575|       </div>
00576|     `;
00577|   }
00578| 
00579|   function findPrAuthor() {
00580|     const selectors = [
00581|       ".gh-header-meta .author",
00582|       ".js-discussion .timeline-comment-header .author",
00583|       ".js-discussion .author",
00584|       ".timeline-comment-header .author",
00585|       "a.author"
00586|     ];
00587|     for (const selector of selectors) {
00588|       const el = document.querySelector(selector);
00589|       if (el && el.textContent.trim()) return el.textContent.trim();
00590|     }
00591|     return null;
00592|   }
00593| 
00594|   function removeBadge() {
00595|     const existing = document.getElementById(BADGE_ID);
00596|     if (existing) existing.remove();
00597|   }
00598| 
00599|   function updateBadge(result) {
00600|     const header = document.querySelector(".gh-header-title") || document.querySelector(".gh-header-meta");
00601|     if (!header) return;
00602| 
00603|     removeBadge();
00604|     if (!result || result.state === "error" || result.state === "missing-key") return;
00605| 
00606|     const badge = document.createElement("span");
00607|     badge.id = BADGE_ID;
00608| 
00609|     if (result.state === "not-expert") {
00610|       badge.className = "md-pr-badge-error";
00611|       badge.textContent = "No Profile";
00612|       header.appendChild(badge);
00613|     }
00614|   }
00615| 
00616|   async function fetchExpert(username) {
00617|     const apiKey = String(state.config.apiKey || "").trim();
00618|     if (!apiKey) return { state: "missing-key" };
00619| 
00620|     const url = `https://explore.market.dev/api/v1/experts/${encodeURIComponent(username)}`;
00621| 
00622|     try {
00623|       const response = await fetch(url, {
00624|         headers: {
00625|           Authorization: `Bearer ${apiKey}`,
00626|           Accept: "application/json"
00627|         }
00628|       });
00629|       const text = await response.text();
00630|       let data = null;
00631|       try {
00632|         data = text ? JSON.parse(text) : null;
00633|       } catch (error) {
00634|         data = null;
00635|       }
00636| 
00637|       if (response.status === 200) return { state: "expert", expert: data };
00638|       if (response.status === 404) return { state: "not-expert" };
00639|       if (response.status === 401) return { state: "error", message: "Auth failed" };
00640|       return { state: "error", message: "API request failed" };
00641|     } catch (error) {
00642|       return { state: "error", message: "API request failed" };
00643|     }
00644|   }
00645| 
00646|   async function applyCheck() {
00647|     ensurePanel();
00648|     if (!isPullDetailPage()) return;
00649| 
00650|     const username = findPrAuthor();
00651|     if (!username) {
00652|       state.currentResult = { state: "error", message: "PR author not found" };
00653|       updateBadge(state.currentResult);
00654|       const panel = document.getElementById(PANEL_ID);
00655|       if (panel) updatePanel(panel);
00656|       return;
00657|     }
00658| 
00659|     state.currentResult = null;
00660|     const panel = document.getElementById(PANEL_ID);
00661|     if (panel) updatePanel(panel);
00662| 
00663|     const result = await fetchExpert(username);
00664|     state.currentResult = { ...result, username };
00665|     updateBadge(state.currentResult);
00666|     if (panel) updatePanel(panel);
00667|   }
00668| 
00669|   function init() {
00670|     applyCheck();
00671|   }
00672| 
00673|   if (document.readyState === "loading") {
00674|     document.addEventListener("DOMContentLoaded", init);
00675|   } else {
00676|     init();
00677|   }
00678| })();
00679|       #${PANEL_ID} .md-pr-summary {
00680|         margin-top: 6px;
00681|         font-size: 13px;
00682|         color: #111827;
00683|         font-weight: 600;
00684|       }
00685| 

(End of file - total 685 lines)
</file>
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js\n@@\n   function ensureStyles() {\n     if (document.getElementById(STYLE_ID)) return;\n     const style = document.createElement(\"style\");\n     style.id = STYLE_ID;\n     style.textContent = `\n       #${PANEL_ID} {\n-        position: fixed;\n-        right: 16px;\n-        bottom: 16px;\n-        z-index: 999999;\n-        font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Noto Sans\", Helvetica, Arial, sans-serif;\n-        color: #1f2328;\n+        color: var(--fgColor-default, #24292f);\n+      }\n+      #${PANEL_ID}.discussion-sidebar-item {\n+        margin-top: 0;\n       }\n       #${PANEL_ID} .md-pr-panel {\n-        width: 440px;\n-        background: #ffffff;\n-        border: 1px solid #d0d7de;\n-        border-radius: 12px;\n-        box-shadow: 0 1px 3px rgba(27, 31, 36, 0.12);\n-        padding: 12px 12px 10px;\n-        font-size: 14px;\n+        font-size: 12px;\n+        line-height: 1.5;\n       }\n       #${PANEL_ID} .md-pr-header {\n         display: flex;\n-        justify-content: flex-end;\n+        justify-content: space-between;\n         align-items: center;\n-        gap: 8px;\n-        font-weight: 600;\n-        font-size: 13px;\n+        margin-bottom: 6px;\n+      }\n+      #${PANEL_ID} .md-pr-heading {\n+        margin: 0;\n       }\n       #${PANEL_ID} .md-pr-gear {\n         border: none;\n-        background: #f6f8fa;\n-        border-radius: 6px;\n-        width: 28px;\n-        height: 28px;\n+        background: transparent;\n+        color: var(--fgColor-muted, #57606a);\n+        width: 20px;\n+        height: 20px;\n+        padding: 0;\n         display: inline-flex;\n         align-items: center;\n         justify-content: center;\n         cursor: pointer;\n-        border: 1px solid #d0d7de;\n-        color: #57606a;\n       }\n-      #${PANEL_ID} .md-pr-body {\n-        margin-top: 10px;\n+      #${PANEL_ID} .md-pr-gear:hover {\n+        color: var(--fgColor-default, #24292f);\n       }\n       #${PANEL_ID} .md-pr-settings {\n         display: none;\n-        margin-top: 10px;\n-        border-top: 1px dashed #d0d7de;\n-        padding-top: 10px;\n+        margin-top: 8px;\n       }\n       #${PANEL_ID} .md-pr-settings.md-pr-open {\n         display: block;\n       }\n-      #${PANEL_ID} label {\n+      #${PANEL_ID} .md-pr-settings label {\n         display: block;\n-        margin-bottom: 6px;\n-        font-weight: 600;\n+        margin-bottom: 4px;\n         font-size: 12px;\n-        color: #57606a;\n+        color: var(--fgColor-muted, #57606a);\n       }\n-      #${PANEL_ID} input[type=\"text\"],\n-      #${PANEL_ID} input[type=\"password\"] {\n+      #${PANEL_ID} .md-pr-settings input[type=\"password\"] {\n         width: 100%;\n-        border: 1px solid #d0d7de;\n+        border: 1px solid var(--borderColor-default, #d0d7de);\n         border-radius: 6px;\n-        padding: 6px 8px;\n-        font-size: 14px;\n-        background: #ffffff;\n-        margin-bottom: 8px;\n+        padding: 5px 8px;\n+        font-size: 12px;\n+        color: var(--fgColor-default, #24292f);\n+        background: var(--bgColor-default, #ffffff);\n       }\n       #${PANEL_ID} .md-pr-status {\n-        margin-top: 8px;\n-        color: #57606a;\n+        color: var(--fgColor-muted, #57606a);\n       }\n       #${PANEL_ID} .md-pr-warning {\n-        color: #cf222e;\n-        font-weight: 600;\n-      }\n-      #${PANEL_ID} .md-pr-success {\n-        color: #1a7f37;\n-        font-weight: 600;\n+        color: var(--fgColor-danger, #cf222e);\n       }\n       #${PANEL_ID} .md-pr-details {\n-        margin-top: 6px;\n-        color: #24292f;\n+        color: var(--fgColor-muted, #57606a);\n       }\n       #${PANEL_ID} .md-pr-summary {\n-        margin-top: 6px;\n-        font-size: 18px;\n-        color: #24292f;\n-        font-weight: 600;\n-      }\n-      #${PANEL_ID} .md-pr-card {\n-        border: 1px solid #d0d7de;\n-        border-radius: 10px;\n-        padding: 12px;\n+        margin-bottom: 8px;\n+        color: var(--fgColor-default, #24292f);\n       }\n       #${PANEL_ID} .md-pr-card-header {\n         display: flex;\n-        gap: 12px;\n-        align-items: center;\n+        gap: 8px;\n+        align-items: flex-start;\n       }\n       #${PANEL_ID} .md-pr-avatar {\n-        width: 56px;\n-        height: 56px;\n+        width: 32px;\n+        height: 32px;\n         border-radius: 50%;\n-        background: #f6f8fa;\n-        border: 1px solid #d0d7de;\n         overflow: hidden;\n+        background: var(--bgColor-muted, #f6f8fa);\n         display: inline-flex;\n         align-items: center;\n         justify-content: center;\n         font-weight: 600;\n-        color: #57606a;\n+        color: var(--fgColor-muted, #57606a);\n+        flex-shrink: 0;\n       }\n       #${PANEL_ID} .md-pr-avatar img {\n         width: 100%;\n@@\n         object-fit: cover;\n       }\n       #${PANEL_ID} .md-pr-name {\n-        font-size: 18px;\n-        font-weight: 700;\n-        color: #1a7f37;\n+        font-size: 13px;\n+        font-weight: 600;\n+        color: var(--fgColor-default, #24292f);\n       }\n       #${PANEL_ID} .md-pr-meta {\n-        margin-top: 6px;\n-        color: #57606a;\n-        font-size: 14px;\n+        color: var(--fgColor-muted, #57606a);\n       }\n       #${PANEL_ID} .md-pr-links {\n-        margin-top: 6px;\n+        margin-top: 2px;\n         display: flex;\n-        gap: 12px;\n-        font-size: 14px;\n+        gap: 8px;\n       }\n       #${PANEL_ID} .md-pr-link {\n-        color: #0969da;\n-        font-weight: 600;\n+        color: var(--fgColor-accent, #0969da);\n+        text-decoration: none;\n+      }\n+      #${PANEL_ID} .md-pr-link:hover {\n+        text-decoration: underline;\n       }\n       #${PANEL_ID} .md-pr-stats {\n-        margin-top: 12px;\n-        border: 1px solid #d0d7de;\n-        border-radius: 8px;\n-        overflow: hidden;\n-      }\n-      #${PANEL_ID} .md-pr-stat-row {\n-        display: flex;\n-        justify-content: space-between;\n-        align-items: center;\n-        padding: 8px 10px;\n-        border-bottom: 1px solid #d0d7de;\n-        font-size: 14px;\n-      }\n-      #${PANEL_ID} .md-pr-stat-row:last-child {\n-        border-bottom: none;\n+        margin-top: 8px;\n+      }\n+      #${PANEL_ID} .md-pr-stat-item {\n+        color: var(--fgColor-default, #24292f);\n       }\n       #${PANEL_ID} .md-pr-stat-label {\n-        color: #57606a;\n-        text-transform: uppercase;\n-        letter-spacing: 0.04em;\n-        font-weight: 600;\n-        font-size: 11px;\n-      }\n-      #${PANEL_ID} .md-pr-stat-value {\n-        font-weight: 700;\n-        color: #24292f;\n+        color: var(--fgColor-muted, #57606a);\n+      }\n+      #${PANEL_ID} .md-pr-stat-sep {\n+        margin: 0 4px;\n+        color: var(--fgColor-muted, #57606a);\n       }\n       #${PANEL_ID} .md-pr-section {\n-        margin-top: 12px;\n+        margin-top: 8px;\n       }\n       #${PANEL_ID} .md-pr-section-title {\n-        font-size: 13px;\n+        margin-bottom: 2px;\n         font-weight: 600;\n-        color: #57606a;\n-        text-transform: uppercase;\n-        letter-spacing: 0.04em;\n-        margin-bottom: 6px;\n+        color: var(--fgColor-muted, #57606a);\n       }\n       #${PANEL_ID} .md-pr-ecosystems {\n         display: flex;\n         flex-wrap: wrap;\n-        gap: 6px;\n+        gap: 8px;\n       }\n       #${PANEL_ID} .md-pr-ecosystem-pill {\n-        display: inline-flex;\n-        align-items: center;\n-        background: #f6f8fa;\n-        border: 1px solid #d0d7de;\n-        border-radius: 999px;\n-        padding: 2px 8px;\n-        font-size: 13px;\n-        color: #57606a;\n+        color: var(--fgColor-accent, #0969da);\n         text-decoration: none;\n       }\n+      #${PANEL_ID} .md-pr-ecosystem-pill:hover {\n+        text-decoration: underline;\n+      }\n       #${PANEL_ID} .md-pr-project-list {\n         display: flex;\n         flex-direction: column;\n-        gap: 6px;\n+        gap: 2px;\n       }\n       #${PANEL_ID} .md-pr-project-item {\n         display: flex;\n+        align-items: baseline;\n         justify-content: space-between;\n         gap: 8px;\n-        font-size: 14px;\n-        color: #24292f;\n       }\n       #${PANEL_ID} .md-pr-project-meta {\n-        color: #57606a;\n-        font-size: 13px;\n-      }\n-      #${PANEL_ID} .md-pr-section {\n-        margin-top: 8px;\n-      }\n-      #${PANEL_ID} .md-pr-section-title {\n-        font-size: 11px;\n-        font-weight: 600;\n-        text-transform: uppercase;\n-        letter-spacing: 0.04em;\n-        color: #6b7280;\n-        margin-bottom: 4px;\n-      }\n-      #${PANEL_ID} .md-pr-stats {\n-        display: grid;\n-        grid-template-columns: repeat(3, minmax(0, 1fr));\n-        gap: 6px;\n-      }\n-      #${PANEL_ID} .md-pr-stat {\n-        background: #ffffff;\n-        border: 1px solid #e5e7eb;\n-        border-radius: 8px;\n-        padding: 6px;\n-        text-align: center;\n-      }\n-      #${PANEL_ID} .md-pr-stat-label {\n-        font-size: 10px;\n-        text-transform: uppercase;\n-        letter-spacing: 0.05em;\n-        color: #6b7280;\n-      }\n-      #${PANEL_ID} .md-pr-stat-value {\n-        font-size: 13px;\n-        font-weight: 600;\n-        color: #111827;\n-      }\n-      #${PANEL_ID} .md-pr-pill {\n-        display: inline-flex;\n-        align-items: center;\n-        padding: 2px 6px;\n-        border-radius: 999px;\n-        background: #eef2ff;\n-        color: #3730a3;\n-        font-size: 11px;\n-        margin-right: 4px;\n-        margin-bottom: 4px;\n-      }\n-      #${PANEL_ID} .md-pr-link {\n-        color: #0a3069;\n-        font-weight: 600;\n+        color: var(--fgColor-muted, #57606a);\n+        flex-shrink: 0;\n+      }\n+      #${PANEL_ID} .md-pr-powered {\n+        margin-top: 8px;\n+        font-size: 11px;\n+        color: var(--fgColor-muted, #57606a);\n+        opacity: 0.65;\n       }\n       #${BADGE_ID} {\n         display: inline-flex;\n@@\n     `;\n     document.head.appendChild(style);\n   }\n+\n+  function findSidebar() {\n+    return document.querySelector(\".discussion-sidebar\");\n+  }\n+\n+  function findReviewersSection(sidebar) {\n+    if (!sidebar) return null;\n+    const byClass = sidebar.querySelector(\".discussion-sidebar-item.sidebar-reviewers\");\n+    if (byClass) return byClass;\n+\n+    const headings = sidebar.querySelectorAll(\".discussion-sidebar-heading, h3\");\n+    for (const heading of headings) {\n+      if (heading.textContent.trim().toLowerCase() !== \"reviewers\") continue;\n+      const item = heading.closest(\".discussion-sidebar-item\");\n+      if (item) return item;\n+    }\n+\n+    return null;\n+  }\n+\n+  function mountPanel(wrapper) {\n+    const sidebar = findSidebar();\n+    if (!sidebar) return false;\n+\n+    const reviewersSection = findReviewersSection(sidebar);\n+    if (reviewersSection) {\n+      if (reviewersSection.nextElementSibling !== wrapper) {\n+        reviewersSection.insertAdjacentElement(\"afterend\", wrapper);\n+      }\n+      return true;\n+    }\n+\n+    if (wrapper.parentElement !== sidebar) {\n+      sidebar.appendChild(wrapper);\n+    }\n+    return true;\n+  }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M bookmarklet.js
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js\n@@\n   function ensurePanel() {\n     const existing = document.getElementById(PANEL_ID);\n     if (!isPullDetailPage()) {\n       if (existing) existing.remove();\n       removeBadge();\n@@\n     ensureStyles();\n \n     if (existing) {\n+      mountPanel(existing);\n       updatePanel(existing);\n       return;\n     }\n \n     const wrapper = document.createElement(\"div\");\n     wrapper.id = PANEL_ID;\n+    wrapper.className = \"discussion-sidebar-item\";\n     wrapper.innerHTML = `\n       <div class=\"md-pr-panel\">\n         <div class=\"md-pr-header\">\n-          <span></span>\n+          <h3 class=\"discussion-sidebar-heading md-pr-heading\">Contributor insights</h3>\n           <button class=\"md-pr-gear\" type=\"button\" aria-label=\"Settings\">\n             <span aria-hidden=\"true\">⚙</span>\n           </button>\n         </div>\n         <div class=\"md-pr-body\">\n@@\n-        <div class=\"md-pr-settings ${state.config.settingsOpen ? \"md-pr-open\" : \"\"}\">\n-          <label>API key</label>\n-          <input type=\"password\" data-config=\"apiKey\" />\n+        <div class=\"md-pr-settings ${state.config.settingsOpen ? \"md-pr-open\" : \"\"}\">\n+          <label for=\"${PANEL_ID}-api-key\">API key</label>\n+          <input id=\"${PANEL_ID}-api-key\" type=\"password\" data-config=\"apiKey\" />\n           <div class=\"md-pr-status\"></div>\n         </div>\n+        <div class=\"md-pr-powered\">Powered by the Open Source Explorer</div>\n       </div>\n     `;\n@@\n       input.addEventListener(\"change\", () => {\n         saveConfig({ ...state.config, [key]: input.value });\n         applyCheck();\n       });\n     });\n \n-    document.body.appendChild(wrapper);\n+    if (!mountPanel(wrapper)) {\n+      return;\n+    }\n+\n     updatePanel(wrapper);\n   }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M bookmarklet.js
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js\n@@\n     if (result.state === \"not-expert\") {\n       statusBlocks.forEach((status) => {\n         status.innerHTML = \"\";\n       });\n-      summary.innerHTML = `No profile found on the Open Source Explorer. <a class=\"md-pr-link\" href=\"https://explore.market.dev\" target=\"_blank\" rel=\"noopener noreferrer\">Explore</a>`;\n-      details.innerHTML = \"\";\n+      summary.textContent = \"No contributor profile found yet.\";\n+      details.innerHTML = `<a class=\"md-pr-link\" href=\"https://explore.market.dev\" target=\"_blank\" rel=\"noopener noreferrer\">Browse directory</a>`;\n       return;\n     }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M bookmarklet.js
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js\n@@\n     return `\n       <div class=\"md-pr-card\">\n         <div class=\"md-pr-card-header\">\n           <div class=\"md-pr-avatar\">\n             ${avatarUrl ? `<img src=\"${avatarUrl}\" alt=\"${name}\" />` : name.slice(0, 1).toUpperCase()}\n           </div>\n           <div>\n-            <div class=\"md-pr-name\">${name}</div>\n+            <div class=\"md-pr-name\"><a class=\"md-pr-link\" href=\"https://github.com/${encodeURIComponent(username)}\" target=\"_blank\" rel=\"noopener noreferrer\">${name}</a></div>\n             <div class=\"md-pr-meta\">@${username}${location ? ` · ${location}` : \"\"}</div>\n             <div class=\"md-pr-links\">\n               <a class=\"md-pr-link\" href=\"https://github.com/${encodeURIComponent(username)}\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub</a>\n-              <a class=\"md-pr-link\" href=\"${profileUrl}\" target=\"_blank\" rel=\"noopener noreferrer\">Explore</a>\n+              <a class=\"md-pr-link\" href=\"${profileUrl}\" target=\"_blank\" rel=\"noopener noreferrer\">Market.dev</a>\n             </div>\n           </div>\n         </div>\n         ${stats.length ? `\n           <div class=\"md-pr-stats\">\n             ${stats\n               .map(\n-                (stat) => `\n-                  <div class=\"md-pr-stat-row\">\n-                    <span class=\"md-pr-stat-label\">${stat.label}</span>\n-                    <span class=\"md-pr-stat-value\">${stat.value}</span>\n-                  </div>\n-                `\n+                (stat) => `<span class=\"md-pr-stat-item\"><span class=\"md-pr-stat-label\">${stat.label}:</span> ${stat.value}</span>`\n               )\n-              .join(\"\")}\n+              .join('<span class=\"md-pr-stat-sep\">·</span>')}\n           </div>\n         ` : \"\"}\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M bookmarklet.js
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js\n@@\n   } else {\n     init();\n   }\n })();\n-      #${PANEL_ID} .md-pr-summary {\n-        margin-top: 6px;\n-        font-size: 13px;\n-        color: #111827;\n-        font-weight: 600;\n-      }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M bookmarklet.js
```

## Assistant

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension",
  "pattern": "Open Source Explorer"
}
```

## Assistant

**Result** (success):
```
Found 2 matches
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js:
  Line 307:         <div class="md-pr-powered">Powered by the Open Source Explorer</div>

/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js:
  Line 346:         <div class="md-pr-powered">Powered by the Open Source Explorer</div>
```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check content.js",
  "description": "Validate content script syntax"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check bookmarklet.js",
  "description": "Validate bookmarklet script syntax"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "pattern": "position:\\s*fixed|box-shadow|border:\\s*1px\\s+solid\\s+#d0d7de"
}
```

## Assistant

**Result** (success):
```
Found 1 matches
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js:
  Line 241:         border: 1px solid #d0d7de;
```

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "pattern": "position:\\s*fixed|box-shadow|border:\\s*1px\\s+solid\\s+#d0d7de"
}
```

## Assistant

**Result** (success):
```
No files found
```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git diff -- content.js bookmarklet.js",
  "description": "Review updated script diffs"
}
```

## Assistant

**Result** (success):
```
diff --git a/bookmarklet.js b/bookmarklet.js
index b264bbb..c44200d 100644
--- a/bookmarklet.js
+++ b/bookmarklet.js
@@ -43,116 +43,91 @@
     style.id = STYLE_ID;
     style.textContent = `
       #${PANEL_ID} {
-        position: fixed;
-        right: 16px;
-        bottom: 16px;
-        z-index: 999999;
-        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
-        color: #1f2328;
+        color: var(--fgColor-default, #24292f);
+      }
+      #${PANEL_ID}.discussion-sidebar-item {
+        margin-top: 0;
       }
       #${PANEL_ID} .md-pr-panel {
-        width: 440px;
-        background: #ffffff;
-        border: 1px solid #d0d7de;
-        border-radius: 12px;
-        box-shadow: 0 1px 3px rgba(27, 31, 36, 0.12);
-        padding: 12px 12px 10px;
-        font-size: 14px;
+        font-size: 12px;
+        line-height: 1.5;
       }
       #${PANEL_ID} .md-pr-header {
         display: flex;
-        justify-content: flex-end;
+        justify-content: space-between;
         align-items: center;
-        gap: 8px;
-        font-weight: 600;
-        font-size: 13px;
+        margin-bottom: 6px;
+      }
+      #${PANEL_ID} .md-pr-heading {
+        margin: 0;
       }
       #${PANEL_ID} .md-pr-gear {
         border: none;
-        background: #f6f8fa;
-        border-radius: 6px;
-        width: 28px;
-        height: 28px;
+        background: transparent;
+        color: var(--fgColor-muted, #57606a);
+        width: 20px;
+        height: 20px;
+        padding: 0;
         display: inline-flex;
         align-items: center;
         justify-content: center;
         cursor: pointer;
-        border: 1px solid #d0d7de;
-        color: #57606a;
       }
-      #${PANEL_ID} .md-pr-body {
-        margin-top: 10px;
+      #${PANEL_ID} .md-pr-gear:hover {
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-settings {
         display: none;
-        margin-top: 10px;
-        border-top: 1px dashed #d0d7de;
-        padding-top: 10px;
+        margin-top: 8px;
       }
       #${PANEL_ID} .md-pr-settings.md-pr-open {
         display: block;
       }
-      #${PANEL_ID} label {
+      #${PANEL_ID} .md-pr-settings label {
         display: block;
-        margin-bottom: 6px;
-        font-weight: 600;
+        margin-bottom: 4px;
         font-size: 12px;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
       }
-      #${PANEL_ID} input[type="text"],
-      #${PANEL_ID} input[type="password"] {
+      #${PANEL_ID} .md-pr-settings input[type="password"] {
         width: 100%;
-        border: 1px solid #d0d7de;
+        border: 1px solid var(--borderColor-default, #d0d7de);
         border-radius: 6px;
-        padding: 6px 8px;
-        font-size: 14px;
-        background: #ffffff;
-        margin-bottom: 8px;
+        padding: 5px 8px;
+        font-size: 12px;
+        color: var(--fgColor-default, #24292f);
+        background: var(--bgColor-default, #ffffff);
       }
       #${PANEL_ID} .md-pr-status {
-        margin-top: 8px;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-warning {
-        color: #cf222e;
-        font-weight: 600;
-      }
-      #${PANEL_ID} .md-pr-success {
-        color: #1a7f37;
-        font-weight: 600;
+        color: var(--fgColor-danger, #cf222e);
       }
       #${PANEL_ID} .md-pr-details {
-        margin-top: 6px;
-        color: #24292f;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-summary {
-        margin-top: 6px;
-        font-size: 18px;
-        color: #24292f;
-        font-weight: 600;
-      }
-      #${PANEL_ID} .md-pr-card {
-        border: 1px solid #d0d7de;
-        border-radius: 10px;
-        padding: 12px;
+        margin-bottom: 8px;
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-card-header {
         display: flex;
-        gap: 12px;
-        align-items: center;
+        gap: 8px;
+        align-items: flex-start;
       }
       #${PANEL_ID} .md-pr-avatar {
-        width: 56px;
-        height: 56px;
+        width: 32px;
+        height: 32px;
         border-radius: 50%;
-        background: #f6f8fa;
-        border: 1px solid #d0d7de;
         overflow: hidden;
+        background: var(--bgColor-muted, #f6f8fa);
         display: inline-flex;
         align-items: center;
         justify-content: center;
         font-weight: 600;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
+        flex-shrink: 0;
       }
       #${PANEL_ID} .md-pr-avatar img {
         width: 100%;
@@ -160,144 +135,78 @@
         object-fit: cover;
       }
       #${PANEL_ID} .md-pr-name {
-        font-size: 18px;
-        font-weight: 700;
-        color: #1a7f37;
+        font-size: 13px;
+        font-weight: 600;
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-meta {
-        margin-top: 6px;
-        color: #57606a;
-        font-size: 14px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-links {
-        margin-top: 6px;
+        margin-top: 2px;
         display: flex;
-        gap: 12px;
-        font-size: 14px;
+        gap: 8px;
       }
       #${PANEL_ID} .md-pr-link {
-        color: #0969da;
-        font-weight: 600;
+        color: var(--fgColor-accent, #0969da);
+        text-decoration: none;
       }
-      #${PANEL_ID} .md-pr-stats {
-        margin-top: 12px;
-        border: 1px solid #d0d7de;
-        border-radius: 8px;
-        overflow: hidden;
+      #${PANEL_ID} .md-pr-link:hover {
+        text-decoration: underline;
       }
-      #${PANEL_ID} .md-pr-stat-row {
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        padding: 8px 10px;
-        border-bottom: 1px solid #d0d7de;
-        font-size: 14px;
+      #${PANEL_ID} .md-pr-stats {
+        margin-top: 8px;
       }
-      #${PANEL_ID} .md-pr-stat-row:last-child {
-        border-bottom: none;
+      #${PANEL_ID} .md-pr-stat-item {
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-stat-label {
-        color: #57606a;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        font-weight: 600;
-        font-size: 11px;
+        color: var(--fgColor-muted, #57606a);
       }
-      #${PANEL_ID} .md-pr-stat-value {
-        font-weight: 700;
-        color: #24292f;
+      #${PANEL_ID} .md-pr-stat-sep {
+        margin: 0 4px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-section {
-        margin-top: 12px;
+        margin-top: 8px;
       }
       #${PANEL_ID} .md-pr-section-title {
-        font-size: 13px;
+        margin-bottom: 2px;
         font-weight: 600;
-        color: #57606a;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        margin-bottom: 6px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-ecosystems {
         display: flex;
         flex-wrap: wrap;
-        gap: 6px;
+        gap: 8px;
       }
       #${PANEL_ID} .md-pr-ecosystem-pill {
-        display: inline-flex;
-        align-items: center;
-        background: #f6f8fa;
-        border: 1px solid #d0d7de;
-        border-radius: 999px;
-        padding: 2px 8px;
-        font-size: 13px;
-        color: #57606a;
+        color: var(--fgColor-accent, #0969da);
         text-decoration: none;
       }
+      #${PANEL_ID} .md-pr-ecosystem-pill:hover {
+        text-decoration: underline;
+      }
       #${PANEL_ID} .md-pr-project-list {
         display: flex;
         flex-direction: column;
-        gap: 6px;
+        gap: 2px;
       }
       #${PANEL_ID} .md-pr-project-item {
         display: flex;
+        align-items: baseline;
         justify-content: space-between;
         gap: 8px;
-        font-size: 14px;
-        color: #24292f;
       }
       #${PANEL_ID} .md-pr-project-meta {
-        color: #57606a;
-        font-size: 13px;
+        color: var(--fgColor-muted, #57606a);
+        flex-shrink: 0;
       }
-      #${PANEL_ID} .md-pr-section {
+      #${PANEL_ID} .md-pr-powered {
         margin-top: 8px;
-      }
-      #${PANEL_ID} .md-pr-section-title {
-        font-size: 11px;
-        font-weight: 600;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        color: #6b7280;
-        margin-bottom: 4px;
-      }
-      #${PANEL_ID} .md-pr-stats {
-        display: grid;
-        grid-template-columns: repeat(3, minmax(0, 1fr));
-        gap: 6px;
-      }
-      #${PANEL_ID} .md-pr-stat {
-        background: #ffffff;
-        border: 1px solid #e5e7eb;
-        border-radius: 8px;
-        padding: 6px;
-        text-align: center;
-      }
-      #${PANEL_ID} .md-pr-stat-label {
-        font-size: 10px;
-        text-transform: uppercase;
-        letter-spacing: 0.05em;
-        color: #6b7280;
-      }
-      #${PANEL_ID} .md-pr-stat-value {
-        font-size: 13px;
-        font-weight: 600;
-        color: #111827;
-      }
-      #${PANEL_ID} .md-pr-pill {
-        display: inline-flex;
-        align-items: center;
-        padding: 2px 6px;
-        border-radius: 999px;
-        background: #eef2ff;
-        color: #3730a3;
         font-size: 11px;
-        margin-right: 4px;
-        margin-bottom: 4px;
-      }
-      #${PANEL_ID} .md-pr-link {
-        color: #0a3069;
-        font-weight: 600;
+        color: var(--fgColor-muted, #57606a);
+        opacity: 0.65;
       }
       #${BADGE_ID} {
         display: inline-flex;
@@ -321,6 +230,43 @@
     document.head.appendChild(style);
   }
 
+  function findSidebar() {
+    return document.querySelector(".discussion-sidebar");
+  }
+
+  function findReviewersSection(sidebar) {
+    if (!sidebar) return null;
+    const byClass = sidebar.querySelector(".discussion-sidebar-item.sidebar-reviewers");
+    if (byClass) return byClass;
+
+    const headings = sidebar.querySelectorAll(".discussion-sidebar-heading, h3");
+    for (const heading of headings) {
+      if (heading.textContent.trim().toLowerCase() !== "reviewers") continue;
+      const item = heading.closest(".discussion-sidebar-item");
+      if (item) return item;
+    }
+
+    return null;
+  }
+
+  function mountPanel(wrapper) {
+    const sidebar = findSidebar();
+    if (!sidebar) return false;
+
+    const reviewersSection = findReviewersSection(sidebar);
+    if (reviewersSection) {
+      if (reviewersSection.nextElementSibling !== wrapper) {
+        reviewersSection.insertAdjacentElement("afterend", wrapper);
+      }
+      return true;
+    }
+
+    if (wrapper.parentElement !== sidebar) {
+      sidebar.appendChild(wrapper);
+    }
+    return true;
+  }
+
   function ensurePanel() {
     const existing = document.getElementById(PANEL_ID);
     if (!isPullDetailPage()) {
@@ -332,16 +278,18 @@
     ensureStyles();
 
     if (existing) {
+      mountPanel(existing);
       updatePanel(existing);
       return;
     }
 
     const wrapper = document.createElement("div");
     wrapper.id = PANEL_ID;
+    wrapper.className = "discussion-sidebar-item";
     wrapper.innerHTML = `
       <div class="md-pr-panel">
         <div class="md-pr-header">
-          <span></span>
+          <h3 class="discussion-sidebar-heading md-pr-heading">Contributor insights</h3>
           <button class="md-pr-gear" type="button" aria-label="Settings">
             <span aria-hidden="true">⚙</span>
           </button>
@@ -352,10 +300,11 @@
           <div class="md-pr-details"></div>
         </div>
         <div class="md-pr-settings ${state.config.settingsOpen ? "md-pr-open" : ""}">
-          <label>API key</label>
-          <input type="password" data-config="apiKey" />
+          <label for="${PANEL_ID}-api-key">API key</label>
+          <input id="${PANEL_ID}-api-key" type="password" data-config="apiKey" />
           <div class="md-pr-status"></div>
         </div>
+        <div class="md-pr-powered">Powered by the Open Source Explorer</div>
       </div>
     `;
 
@@ -374,7 +323,10 @@
       });
     });
 
-    document.body.appendChild(wrapper);
+    if (!mountPanel(wrapper)) {
+      return;
+    }
+
     updatePanel(wrapper);
   }
 
@@ -420,8 +372,8 @@
       statusBlocks.forEach((status) => {
         status.innerHTML = "";
       });
-      summary.innerHTML = `No profile found on the Open Source Explorer. <a class="md-pr-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Explore</a>`;
-      details.innerHTML = "";
+      summary.textContent = "No contributor profile found yet.";
+      details.innerHTML = `<a class="md-pr-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Browse directory</a>`;
       return;
     }
 
@@ -523,11 +475,11 @@
             ${avatarUrl ? `<img src="${avatarUrl}" alt="${name}" />` : name.slice(0, 1).toUpperCase()}
           </div>
           <div>
-            <div class="md-pr-name">${name}</div>
+            <div class="md-pr-name"><a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">${name}</a></div>
             <div class="md-pr-meta">@${username}${location ? ` · ${location}` : ""}</div>
             <div class="md-pr-links">
               <a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">GitHub</a>
-              <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Explore</a>
+              <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Market.dev</a>
             </div>
           </div>
         </div>
@@ -535,14 +487,9 @@
           <div class="md-pr-stats">
             ${stats
               .map(
-                (stat) => `
-                  <div class="md-pr-stat-row">
-                    <span class="md-pr-stat-label">${stat.label}</span>
-                    <span class="md-pr-stat-value">${stat.value}</span>
-                  </div>
-                `
+                (stat) => `<span class="md-pr-stat-item"><span class="md-pr-stat-label">${stat.label}:</span> ${stat.value}</span>`
               )
-              .join("")}
+              .join('<span class="md-pr-stat-sep">·</span>')}
           </div>
         ` : ""}
         ${ecosystemNames.length ? `
@@ -676,9 +623,3 @@
     init();
   }
 })();
-      #${PANEL_ID} .md-pr-summary {
-        margin-top: 6px;
-        font-size: 13px;
-        color: #111827;
-        font-weight: 600;
-      }
diff --git a/content.js b/content.js
index 6c186a7..f2a3e03 100644
--- a/content.js
+++ b/content.js
@@ -65,116 +65,91 @@
     style.id = STYLE_ID;
     style.textContent = `
       #${PANEL_ID} {
-        position: fixed;
-        right: 16px;
-        bottom: 16px;
-        z-index: 999999;
-        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
-        color: #1f2328;
+        color: var(--fgColor-default, #24292f);
+      }
+      #${PANEL_ID}.discussion-sidebar-item {
+        margin-top: 0;
       }
       #${PANEL_ID} .md-pr-panel {
-        width: 440px;
-        background: #ffffff;
-        border: 1px solid #d0d7de;
-        border-radius: 12px;
-        box-shadow: 0 1px 3px rgba(27, 31, 36, 0.12);
-        padding: 12px 12px 10px;
-        font-size: 14px;
+        font-size: 12px;
+        line-height: 1.5;
       }
       #${PANEL_ID} .md-pr-header {
         display: flex;
-        justify-content: flex-end;
+        justify-content: space-between;
         align-items: center;
-        gap: 8px;
-        font-weight: 600;
-        font-size: 13px;
+        margin-bottom: 6px;
+      }
+      #${PANEL_ID} .md-pr-heading {
+        margin: 0;
       }
       #${PANEL_ID} .md-pr-gear {
         border: none;
-        background: #f6f8fa;
-        border-radius: 6px;
-        width: 28px;
-        height: 28px;
+        background: transparent;
+        color: var(--fgColor-muted, #57606a);
+        width: 20px;
+        height: 20px;
+        padding: 0;
         display: inline-flex;
         align-items: center;
         justify-content: center;
         cursor: pointer;
-        border: 1px solid #d0d7de;
-        color: #57606a;
       }
-      #${PANEL_ID} .md-pr-body {
-        margin-top: 10px;
+      #${PANEL_ID} .md-pr-gear:hover {
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-settings {
         display: none;
-        margin-top: 10px;
-        border-top: 1px dashed #d0d7de;
-        padding-top: 10px;
+        margin-top: 8px;
       }
       #${PANEL_ID} .md-pr-settings.md-pr-open {
         display: block;
       }
-      #${PANEL_ID} label {
+      #${PANEL_ID} .md-pr-settings label {
         display: block;
-        margin-bottom: 6px;
-        font-weight: 600;
+        margin-bottom: 4px;
         font-size: 12px;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
       }
-      #${PANEL_ID} input[type="text"],
-      #${PANEL_ID} input[type="password"] {
+      #${PANEL_ID} .md-pr-settings input[type="password"] {
         width: 100%;
-        border: 1px solid #d0d7de;
+        border: 1px solid var(--borderColor-default, #d0d7de);
         border-radius: 6px;
-        padding: 6px 8px;
-        font-size: 14px;
-        background: #ffffff;
-        margin-bottom: 8px;
+        padding: 5px 8px;
+        font-size: 12px;
+        color: var(--fgColor-default, #24292f);
+        background: var(--bgColor-default, #ffffff);
       }
       #${PANEL_ID} .md-pr-status {
-        margin-top: 8px;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-warning {
-        color: #cf222e;
-        font-weight: 600;
-      }
-      #${PANEL_ID} .md-pr-success {
-        color: #1a7f37;
-        font-weight: 600;
+        color: var(--fgColor-danger, #cf222e);
       }
       #${PANEL_ID} .md-pr-details {
-        margin-top: 6px;
-        color: #24292f;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-summary {
-        margin-top: 6px;
-        font-size: 18px;
-        color: #24292f;
-        font-weight: 600;
-      }
-      #${PANEL_ID} .md-pr-card {
-        border: 1px solid #d0d7de;
-        border-radius: 10px;
-        padding: 12px;
+        margin-bottom: 8px;
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-card-header {
         display: flex;
-        gap: 12px;
-        align-items: center;
+        gap: 8px;
+        align-items: flex-start;
       }
       #${PANEL_ID} .md-pr-avatar {
-        width: 56px;
-        height: 56px;
+        width: 32px;
+        height: 32px;
         border-radius: 50%;
-        background: #f6f8fa;
-        border: 1px solid #d0d7de;
         overflow: hidden;
+        background: var(--bgColor-muted, #f6f8fa);
         display: inline-flex;
         align-items: center;
         justify-content: center;
         font-weight: 600;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
+        flex-shrink: 0;
       }
       #${PANEL_ID} .md-pr-avatar img {
         width: 100%;
@@ -182,95 +157,78 @@
         object-fit: cover;
       }
       #${PANEL_ID} .md-pr-name {
-        font-size: 18px;
-        font-weight: 700;
-        color: #1a7f37;
+        font-size: 13px;
+        font-weight: 600;
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-meta {
-        margin-top: 6px;
-        color: #57606a;
-        font-size: 14px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-links {
-        margin-top: 6px;
+        margin-top: 2px;
         display: flex;
-        gap: 12px;
-        font-size: 14px;
+        gap: 8px;
       }
       #${PANEL_ID} .md-pr-link {
-        color: #0969da;
-        font-weight: 600;
+        color: var(--fgColor-accent, #0969da);
+        text-decoration: none;
       }
-      #${PANEL_ID} .md-pr-stats {
-        margin-top: 12px;
-        border: 1px solid #d0d7de;
-        border-radius: 8px;
-        overflow: hidden;
+      #${PANEL_ID} .md-pr-link:hover {
+        text-decoration: underline;
       }
-      #${PANEL_ID} .md-pr-stat-row {
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        padding: 8px 10px;
-        border-bottom: 1px solid #d0d7de;
-        font-size: 14px;
+      #${PANEL_ID} .md-pr-stats {
+        margin-top: 8px;
       }
-      #${PANEL_ID} .md-pr-stat-row:last-child {
-        border-bottom: none;
+      #${PANEL_ID} .md-pr-stat-item {
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-stat-label {
-        color: #57606a;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        font-weight: 600;
-        font-size: 11px;
+        color: var(--fgColor-muted, #57606a);
       }
-      #${PANEL_ID} .md-pr-stat-value {
-        font-weight: 700;
-        color: #24292f;
+      #${PANEL_ID} .md-pr-stat-sep {
+        margin: 0 4px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-section {
-        margin-top: 12px;
+        margin-top: 8px;
       }
       #${PANEL_ID} .md-pr-section-title {
-        font-size: 13px;
+        margin-bottom: 2px;
         font-weight: 600;
-        color: #57606a;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        margin-bottom: 6px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-ecosystems {
         display: flex;
         flex-wrap: wrap;
-        gap: 6px;
+        gap: 8px;
       }
       #${PANEL_ID} .md-pr-ecosystem-pill {
-        display: inline-flex;
-        align-items: center;
-        background: #f6f8fa;
-        border: 1px solid #d0d7de;
-        border-radius: 999px;
-        padding: 2px 8px;
-        font-size: 13px;
-        color: #57606a;
+        color: var(--fgColor-accent, #0969da);
         text-decoration: none;
       }
+      #${PANEL_ID} .md-pr-ecosystem-pill:hover {
+        text-decoration: underline;
+      }
       #${PANEL_ID} .md-pr-project-list {
         display: flex;
         flex-direction: column;
-        gap: 6px;
+        gap: 2px;
       }
       #${PANEL_ID} .md-pr-project-item {
         display: flex;
+        align-items: baseline;
         justify-content: space-between;
         gap: 8px;
-        font-size: 14px;
-        color: #24292f;
       }
       #${PANEL_ID} .md-pr-project-meta {
-        color: #57606a;
-        font-size: 13px;
+        color: var(--fgColor-muted, #57606a);
+        flex-shrink: 0;
+      }
+      #${PANEL_ID} .md-pr-powered {
+        margin-top: 8px;
+        font-size: 11px;
+        color: var(--fgColor-muted, #57606a);
+        opacity: 0.65;
       }
       .md-pr-list-indicator {
         display: inline-flex;
@@ -289,55 +247,6 @@
       .md-pr-list-indicator.md-pr-list-missing {
         background: #afb8c1;
       }
-      #${PANEL_ID} .md-pr-section {
-        margin-top: 8px;
-      }
-      #${PANEL_ID} .md-pr-section-title {
-        font-size: 11px;
-        font-weight: 600;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        color: #6b7280;
-        margin-bottom: 4px;
-      }
-      #${PANEL_ID} .md-pr-stats {
-        display: grid;
-        grid-template-columns: repeat(3, minmax(0, 1fr));
-        gap: 6px;
-      }
-      #${PANEL_ID} .md-pr-stat {
-        background: #ffffff;
-        border: 1px solid #e5e7eb;
-        border-radius: 8px;
-        padding: 6px;
-        text-align: center;
-      }
-      #${PANEL_ID} .md-pr-stat-label {
-        font-size: 10px;
-        text-transform: uppercase;
-        letter-spacing: 0.05em;
-        color: #6b7280;
-      }
-      #${PANEL_ID} .md-pr-stat-value {
-        font-size: 13px;
-        font-weight: 600;
-        color: #111827;
-      }
-      #${PANEL_ID} .md-pr-pill {
-        display: inline-flex;
-        align-items: center;
-        padding: 2px 6px;
-        border-radius: 999px;
-        background: #eef2ff;
-        color: #3730a3;
-        font-size: 11px;
-        margin-right: 4px;
-        margin-bottom: 4px;
-      }
-      #${PANEL_ID} .md-pr-link {
-        color: #0a3069;
-        font-weight: 600;
-      }
       #${BADGE_ID} {
         display: inline-flex;
         align-items: center;
@@ -360,6 +269,43 @@
     document.head.appendChild(style);
   }
 
+  function findSidebar() {
+    return document.querySelector(".discussion-sidebar");
+  }
+
+  function findReviewersSection(sidebar) {
+    if (!sidebar) return null;
+    const byClass = sidebar.querySelector(".discussion-sidebar-item.sidebar-reviewers");
+    if (byClass) return byClass;
+
+    const headings = sidebar.querySelectorAll(".discussion-sidebar-heading, h3");
+    for (const heading of headings) {
+      if (heading.textContent.trim().toLowerCase() !== "reviewers") continue;
+      const item = heading.closest(".discussion-sidebar-item");
+      if (item) return item;
+    }
+
+    return null;
+  }
+
+  function mountPanel(wrapper) {
+    const sidebar = findSidebar();
+    if (!sidebar) return false;
+
+    const reviewersSection = findReviewersSection(sidebar);
+    if (reviewersSection) {
+      if (reviewersSection.nextElementSibling !== wrapper) {
+        reviewersSection.insertAdjacentElement("afterend", wrapper);
+      }
+      return true;
+    }
+
+    if (wrapper.parentElement !== sidebar) {
+      sidebar.appendChild(wrapper);
+    }
+    return true;
+  }
+
   function ensurePanel() {
     const existing = document.getElementById(PANEL_ID);
     if (!isPullDetailPage()) {
@@ -371,16 +317,18 @@
     ensureStyles();
 
     if (existing) {
+      mountPanel(existing);
       updatePanel(existing);
       return;
     }
 
     const wrapper = document.createElement("div");
     wrapper.id = PANEL_ID;
+    wrapper.className = "discussion-sidebar-item";
     wrapper.innerHTML = `
       <div class="md-pr-panel">
         <div class="md-pr-header">
-          <span></span>
+          <h3 class="discussion-sidebar-heading md-pr-heading">Contributor insights</h3>
           <button class="md-pr-gear" type="button" aria-label="Settings">
             <span aria-hidden="true">⚙</span>
           </button>
@@ -391,10 +339,11 @@
           <div class="md-pr-details"></div>
         </div>
         <div class="md-pr-settings ${state.config.settingsOpen ? "md-pr-open" : ""}">
-          <label>API key</label>
-          <input type="password" data-config="apiKey" />
+          <label for="${PANEL_ID}-api-key">API key</label>
+          <input id="${PANEL_ID}-api-key" type="password" data-config="apiKey" />
           <div class="md-pr-status"></div>
         </div>
+        <div class="md-pr-powered">Powered by the Open Source Explorer</div>
       </div>
     `;
 
@@ -417,7 +366,10 @@
       });
     });
 
-    document.body.appendChild(wrapper);
+    if (!mountPanel(wrapper)) {
+      return;
+    }
+
     updatePanel(wrapper);
   }
 
@@ -463,8 +415,8 @@
       statusBlocks.forEach((status) => {
         status.innerHTML = "";
       });
-      summary.innerHTML = `No profile found on the Open Source Explorer. <a class="md-pr-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Explore</a>`;
-      details.innerHTML = "";
+      summary.textContent = "No contributor profile found yet.";
+      details.innerHTML = `<a class="md-pr-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Browse directory</a>`;
       return;
     }
 
@@ -566,7 +518,7 @@
             ${avatarUrl ? `<img src="${avatarUrl}" alt="${name}" />` : name.slice(0, 1).toUpperCase()}
           </div>
           <div>
-            <div class="md-pr-name">${name}</div>
+            <div class="md-pr-name"><a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">${name}</a></div>
             <div class="md-pr-meta">@${username}${location ? ` · ${location}` : ""}</div>
             <div class="md-pr-links">
               <a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">GitHub</a>
@@ -578,14 +530,9 @@
           <div class="md-pr-stats">
             ${stats
               .map(
-                (stat) => `
-                  <div class="md-pr-stat-row">
-                    <span class="md-pr-stat-label">${stat.label}</span>
-                    <span class="md-pr-stat-value">${stat.value}</span>
-                  </div>
-                `
+                (stat) => `<span class="md-pr-stat-item"><span class="md-pr-stat-label">${stat.label}:</span> ${stat.value}</span>`
               )
-              .join("")}
+              .join('<span class="md-pr-stat-sep">·</span>')}
           </div>
         ` : ""}
         ${ecosystemNames.length ? `

```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git status --short",
  "description": "List modified files after edits"
}
```

## Assistant

**Result** (success):
```
 M bookmarklet.js
 M content.js

```

## Assistant

## Assistant

Perfect — I removed the popup treatment entirely.

- The panel now mounts as a native GitHub sidebar section directly under **Reviewers** instead of floating (`content.js` and `bookmarklet.js`).
- I stripped popup/card chrome (fixed positioning, large borders, shadow, boxed stat rows) and switched to GitHub-like sidebar spacing and color tokens so it blends in.
- I removed inline mentions of “Open Source Explorer” from the body states; the only mention left is the subtle footer line: `Powered by the Open Source Explorer`.
- I applied the same inline/no-popup behavior to both scripts so extension and bookmarklet match.
- Syntax checks pass: `node --check content.js` and `node --check bookmarklet.js`.

If you refresh GitHub and still see the old UI, reload the extension once in `chrome://extensions` and hard refresh the PR page.

## User

i dont see anything now

## Assistant

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/README.md",
  "pattern": "discussion-sidebar|sidebar-reviewers|reviewers"
}
```

## Assistant

**Result** (success):
```
No files found
```

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 260,
  "offset": 1
}
```

## Assistant

**Result** (success):
```
<file>
00002|   const STORAGE_KEY = "md_expert_pr_config";
00003|   const STYLE_ID = "md-expert-pr-style";
00004|   const PANEL_ID = "md-expert-pr-panel";
00005|   const BADGE_ID = "md-expert-pr-badge";
00006| 
00007|   const DEFAULT_CONFIG = {
00008|     apiKey: "",
00009|     settingsOpen: false
00010|   };
00011| 
00012|   const state = {
00013|     config: loadConfig(),
00014|     currentResult: null,
00015|     listCache: new Map()
00016|   };
00017| 
00018|   function loadConfig() {
00019|     const raw = window.localStorage.getItem(STORAGE_KEY);
00020|     if (!raw) return { ...DEFAULT_CONFIG };
00021|     try {
00022|       const parsed = JSON.parse(raw);
00023|       return { ...DEFAULT_CONFIG, ...parsed };
00024|     } catch (error) {
00025|       return { ...DEFAULT_CONFIG };
00026|     }
00027|   }
00028| 
00029|   function saveConfig(nextConfig) {
00030|     state.config = { ...DEFAULT_CONFIG, ...nextConfig };
00031|     window.localStorage.setItem(STORAGE_KEY, JSON.stringify(state.config));
00032|   }
00033| 
00034|   function isPullDetailPage() {
00035|     return /\/pull\/(\d+)(\/|$)/.test(window.location.pathname);
00036|   }
00037| 
00038|   function isPullListPage() {
00039|     return /\/pulls(\/|$)/.test(window.location.pathname);
00040|   }
00041| 
00042|   function canUseBackground() {
00043|     return typeof chrome !== "undefined" && chrome.runtime && chrome.runtime.sendMessage;
00044|   }
00045| 
00046|   function fetchViaBackground(url, apiKey) {
00047|     if (!canUseBackground()) return Promise.resolve(null);
00048|     return new Promise((resolve) => {
00049|       chrome.runtime.sendMessage(
00050|         { type: "md-expert-pr-check", url, apiKey },
00051|         (response) => {
00052|           if (chrome.runtime.lastError) {
00053|             resolve(null);
00054|             return;
00055|           }
00056|           resolve(response);
00057|         }
00058|       );
00059|     });
00060|   }
00061| 
00062|   function ensureStyles() {
00063|     if (document.getElementById(STYLE_ID)) return;
00064|     const style = document.createElement("style");
00065|     style.id = STYLE_ID;
00066|     style.textContent = `
00067|       #${PANEL_ID} {
00068|         color: var(--fgColor-default, #24292f);
00069|       }
00070|       #${PANEL_ID}.discussion-sidebar-item {
00071|         margin-top: 0;
00072|       }
00073|       #${PANEL_ID} .md-pr-panel {
00074|         font-size: 12px;
00075|         line-height: 1.5;
00076|       }
00077|       #${PANEL_ID} .md-pr-header {
00078|         display: flex;
00079|         justify-content: space-between;
00080|         align-items: center;
00081|         margin-bottom: 6px;
00082|       }
00083|       #${PANEL_ID} .md-pr-heading {
00084|         margin: 0;
00085|       }
00086|       #${PANEL_ID} .md-pr-gear {
00087|         border: none;
00088|         background: transparent;
00089|         color: var(--fgColor-muted, #57606a);
00090|         width: 20px;
00091|         height: 20px;
00092|         padding: 0;
00093|         display: inline-flex;
00094|         align-items: center;
00095|         justify-content: center;
00096|         cursor: pointer;
00097|       }
00098|       #${PANEL_ID} .md-pr-gear:hover {
00099|         color: var(--fgColor-default, #24292f);
00100|       }
00101|       #${PANEL_ID} .md-pr-settings {
00102|         display: none;
00103|         margin-top: 8px;
00104|       }
00105|       #${PANEL_ID} .md-pr-settings.md-pr-open {
00106|         display: block;
00107|       }
00108|       #${PANEL_ID} .md-pr-settings label {
00109|         display: block;
00110|         margin-bottom: 4px;
00111|         font-size: 12px;
00112|         color: var(--fgColor-muted, #57606a);
00113|       }
00114|       #${PANEL_ID} .md-pr-settings input[type="password"] {
00115|         width: 100%;
00116|         border: 1px solid var(--borderColor-default, #d0d7de);
00117|         border-radius: 6px;
00118|         padding: 5px 8px;
00119|         font-size: 12px;
00120|         color: var(--fgColor-default, #24292f);
00121|         background: var(--bgColor-default, #ffffff);
00122|       }
00123|       #${PANEL_ID} .md-pr-status {
00124|         color: var(--fgColor-muted, #57606a);
00125|       }
00126|       #${PANEL_ID} .md-pr-warning {
00127|         color: var(--fgColor-danger, #cf222e);
00128|       }
00129|       #${PANEL_ID} .md-pr-details {
00130|         color: var(--fgColor-muted, #57606a);
00131|       }
00132|       #${PANEL_ID} .md-pr-summary {
00133|         margin-bottom: 8px;
00134|         color: var(--fgColor-default, #24292f);
00135|       }
00136|       #${PANEL_ID} .md-pr-card-header {
00137|         display: flex;
00138|         gap: 8px;
00139|         align-items: flex-start;
00140|       }
00141|       #${PANEL_ID} .md-pr-avatar {
00142|         width: 32px;
00143|         height: 32px;
00144|         border-radius: 50%;
00145|         overflow: hidden;
00146|         background: var(--bgColor-muted, #f6f8fa);
00147|         display: inline-flex;
00148|         align-items: center;
00149|         justify-content: center;
00150|         font-weight: 600;
00151|         color: var(--fgColor-muted, #57606a);
00152|         flex-shrink: 0;
00153|       }
00154|       #${PANEL_ID} .md-pr-avatar img {
00155|         width: 100%;
00156|         height: 100%;
00157|         object-fit: cover;
00158|       }
00159|       #${PANEL_ID} .md-pr-name {
00160|         font-size: 13px;
00161|         font-weight: 600;
00162|         color: var(--fgColor-default, #24292f);
00163|       }
00164|       #${PANEL_ID} .md-pr-meta {
00165|         color: var(--fgColor-muted, #57606a);
00166|       }
00167|       #${PANEL_ID} .md-pr-links {
00168|         margin-top: 2px;
00169|         display: flex;
00170|         gap: 8px;
00171|       }
00172|       #${PANEL_ID} .md-pr-link {
00173|         color: var(--fgColor-accent, #0969da);
00174|         text-decoration: none;
00175|       }
00176|       #${PANEL_ID} .md-pr-link:hover {
00177|         text-decoration: underline;
00178|       }
00179|       #${PANEL_ID} .md-pr-stats {
00180|         margin-top: 8px;
00181|       }
00182|       #${PANEL_ID} .md-pr-stat-item {
00183|         color: var(--fgColor-default, #24292f);
00184|       }
00185|       #${PANEL_ID} .md-pr-stat-label {
00186|         color: var(--fgColor-muted, #57606a);
00187|       }
00188|       #${PANEL_ID} .md-pr-stat-sep {
00189|         margin: 0 4px;
00190|         color: var(--fgColor-muted, #57606a);
00191|       }
00192|       #${PANEL_ID} .md-pr-section {
00193|         margin-top: 8px;
00194|       }
00195|       #${PANEL_ID} .md-pr-section-title {
00196|         margin-bottom: 2px;
00197|         font-weight: 600;
00198|         color: var(--fgColor-muted, #57606a);
00199|       }
00200|       #${PANEL_ID} .md-pr-ecosystems {
00201|         display: flex;
00202|         flex-wrap: wrap;
00203|         gap: 8px;
00204|       }
00205|       #${PANEL_ID} .md-pr-ecosystem-pill {
00206|         color: var(--fgColor-accent, #0969da);
00207|         text-decoration: none;
00208|       }
00209|       #${PANEL_ID} .md-pr-ecosystem-pill:hover {
00210|         text-decoration: underline;
00211|       }
00212|       #${PANEL_ID} .md-pr-project-list {
00213|         display: flex;
00214|         flex-direction: column;
00215|         gap: 2px;
00216|       }
00217|       #${PANEL_ID} .md-pr-project-item {
00218|         display: flex;
00219|         align-items: baseline;
00220|         justify-content: space-between;
00221|         gap: 8px;
00222|       }
00223|       #${PANEL_ID} .md-pr-project-meta {
00224|         color: var(--fgColor-muted, #57606a);
00225|         flex-shrink: 0;
00226|       }
00227|       #${PANEL_ID} .md-pr-powered {
00228|         margin-top: 8px;
00229|         font-size: 11px;
00230|         color: var(--fgColor-muted, #57606a);
00231|         opacity: 0.65;
00232|       }
00233|       .md-pr-list-indicator {
00234|         display: inline-flex;
00235|         align-items: center;
00236|         justify-content: center;
00237|         width: 8px;
00238|         height: 8px;
00239|         border-radius: 999px;
00240|         margin-left: 6px;
00241|         border: 1px solid #d0d7de;
00242|       }
00243|       .md-pr-list-indicator.md-pr-list-expert {
00244|         background: #2da44e;
00245|         border-color: #2da44e;
00246|       }
00247|       .md-pr-list-indicator.md-pr-list-missing {
00248|         background: #afb8c1;
00249|       }
00250|       #${BADGE_ID} {
00251|         display: inline-flex;
00252|         align-items: center;
00253|         gap: 6px;
00254|         margin-left: 8px;
00255|         padding: 2px 8px;
00256|         border-radius: 999px;
00257|         font-size: 11px;
00258|         font-weight: 600;
00259|       }
00260|       #${BADGE_ID}.md-pr-badge-error {
00261|         background: #ffe4e8;

(File has more lines. Use 'offset' parameter to read beyond line 261)
</file>
```

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 220,
  "offset": 260
}
```

## Assistant

**Result** (success):
```
<file>
00261|         background: #ffe4e8;
00262|         color: #9f1239;
00263|       }
00264|       #${BADGE_ID}.md-pr-badge-success {
00265|         background: #dcfce7;
00266|         color: #166534;
00267|       }
00268|     `;
00269|     document.head.appendChild(style);
00270|   }
00271| 
00272|   function findSidebar() {
00273|     return document.querySelector(".discussion-sidebar");
00274|   }
00275| 
00276|   function findReviewersSection(sidebar) {
00277|     if (!sidebar) return null;
00278|     const byClass = sidebar.querySelector(".discussion-sidebar-item.sidebar-reviewers");
00279|     if (byClass) return byClass;
00280| 
00281|     const headings = sidebar.querySelectorAll(".discussion-sidebar-heading, h3");
00282|     for (const heading of headings) {
00283|       if (heading.textContent.trim().toLowerCase() !== "reviewers") continue;
00284|       const item = heading.closest(".discussion-sidebar-item");
00285|       if (item) return item;
00286|     }
00287| 
00288|     return null;
00289|   }
00290| 
00291|   function mountPanel(wrapper) {
00292|     const sidebar = findSidebar();
00293|     if (!sidebar) return false;
00294| 
00295|     const reviewersSection = findReviewersSection(sidebar);
00296|     if (reviewersSection) {
00297|       if (reviewersSection.nextElementSibling !== wrapper) {
00298|         reviewersSection.insertAdjacentElement("afterend", wrapper);
00299|       }
00300|       return true;
00301|     }
00302| 
00303|     if (wrapper.parentElement !== sidebar) {
00304|       sidebar.appendChild(wrapper);
00305|     }
00306|     return true;
00307|   }
00308| 
00309|   function ensurePanel() {
00310|     const existing = document.getElementById(PANEL_ID);
00311|     if (!isPullDetailPage()) {
00312|       if (existing) existing.remove();
00313|       removeBadge();
00314|       return;
00315|     }
00316| 
00317|     ensureStyles();
00318| 
00319|     if (existing) {
00320|       mountPanel(existing);
00321|       updatePanel(existing);
00322|       return;
00323|     }
00324| 
00325|     const wrapper = document.createElement("div");
00326|     wrapper.id = PANEL_ID;
00327|     wrapper.className = "discussion-sidebar-item";
00328|     wrapper.innerHTML = `
00329|       <div class="md-pr-panel">
00330|         <div class="md-pr-header">
00331|           <h3 class="discussion-sidebar-heading md-pr-heading">Contributor insights</h3>
00332|           <button class="md-pr-gear" type="button" aria-label="Settings">
00333|             <span aria-hidden="true">⚙</span>
00334|           </button>
00335|         </div>
00336|         <div class="md-pr-body">
00337|           <div class="md-pr-summary"></div>
00338|           <div class="md-pr-status"></div>
00339|           <div class="md-pr-details"></div>
00340|         </div>
00341|         <div class="md-pr-settings ${state.config.settingsOpen ? "md-pr-open" : ""}">
00342|           <label for="${PANEL_ID}-api-key">API key</label>
00343|           <input id="${PANEL_ID}-api-key" type="password" data-config="apiKey" />
00344|           <div class="md-pr-status"></div>
00345|         </div>
00346|         <div class="md-pr-powered">Powered by the Open Source Explorer</div>
00347|       </div>
00348|     `;
00349| 
00350|     wrapper.querySelector(".md-pr-gear").addEventListener("click", () => {
00351|       const settings = wrapper.querySelector(".md-pr-settings");
00352|       const open = settings.classList.toggle("md-pr-open");
00353|       saveConfig({ ...state.config, settingsOpen: open });
00354|     });
00355| 
00356|     wrapper.querySelectorAll("[data-config]").forEach((input) => {
00357|       const key = input.getAttribute("data-config");
00358|       input.value = state.config[key] ?? "";
00359|       input.addEventListener("change", () => {
00360|         if (key === "apiKey") {
00361|           state.listCache.clear();
00362|         }
00363|         saveConfig({ ...state.config, [key]: input.value });
00364|         applyCheck();
00365|         applyListIndicators();
00366|       });
00367|     });
00368| 
00369|     if (!mountPanel(wrapper)) {
00370|       return;
00371|     }
00372| 
00373|     updatePanel(wrapper);
00374|   }
00375| 
00376|   function updatePanel(wrapper) {
00377|     const summary = wrapper.querySelector(".md-pr-summary");
00378|     const statusBlocks = wrapper.querySelectorAll(".md-pr-status");
00379|     const details = wrapper.querySelector(".md-pr-details");
00380|     const result = state.currentResult;
00381| 
00382|     statusBlocks.forEach((status) => {
00383|       status.textContent = "";
00384|       status.innerHTML = "";
00385|     });
00386| 
00387|     if (!result) {
00388|       statusBlocks.forEach((status) => {
00389|         status.textContent = "Checking PR author...";
00390|       });
00391|       summary.textContent = "";
00392|       details.textContent = "";
00393|       return;
00394|     }
00395| 
00396|     if (result.state === "missing-key") {
00397|       statusBlocks.forEach((status) => {
00398|         status.innerHTML = `<span class="md-pr-warning">API key required</span>`;
00399|       });
00400|       summary.textContent = "";
00401|       details.textContent = "";
00402|       return;
00403|     }
00404| 
00405|     if (result.state === "error") {
00406|       statusBlocks.forEach((status) => {
00407|         status.innerHTML = `<span class="md-pr-warning">${result.message}</span>`;
00408|       });
00409|       summary.textContent = "";
00410|       details.textContent = "";
00411|       return;
00412|     }
00413| 
00414|     if (result.state === "not-expert") {
00415|       statusBlocks.forEach((status) => {
00416|         status.innerHTML = "";
00417|       });
00418|       summary.textContent = "No contributor profile found yet.";
00419|       details.innerHTML = `<a class="md-pr-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Browse directory</a>`;
00420|       return;
00421|     }
00422| 
00423|     if (result.state === "expert") {
00424|       statusBlocks.forEach((status) => {
00425|         status.innerHTML = "";
00426|       });
00427|       const info = result.expert && result.expert.expert ? result.expert.expert : result.expert;
00428|       summary.textContent = buildSummary(info, result.username);
00429|       details.innerHTML = renderExpertDetails(info, result.username);
00430|     }
00431|   }
00432| 
00433|   function buildSummary(info, username) {
00434|     if (!info) return `This PR was opened by ${username}.`;
00435|     const name = info.name || username;
00436|     const downloadsRaw = Number(info.total_downloads || 0);
00437|     const downloads = downloadsRaw > 0 ? formatCompactNumber(downloadsRaw) : null;
00438|     const stars = formatCompactNumber(info.total_stars);
00439|     const downloadText = downloads ? `${downloads} total downloads` : "";
00440|     const starsText = stars ? `${stars} stars on repos` : "";
00441|     const stats = [downloadText, starsText].filter(Boolean).join(", ");
00442|     if (!stats) return `This PR was opened by ${name} (${username}).`;
00443|     return `This PR was opened by ${name} (${username}). They have received ${stats}.`;
00444|   }
00445| 
00446|   function formatCompactNumber(value) {
00447|     if (value === null || value === undefined) return null;
00448|     const num = Number(value);
00449|     if (Number.isNaN(num)) return null;
00450|     return new Intl.NumberFormat("en", {
00451|       notation: "compact",
00452|       maximumFractionDigits: 1
00453|     }).format(num);
00454|   }
00455| 
00456|   function renderExpertDetails(info, username) {
00457|     const profileUrl = `https://explore.market.dev/experts/${encodeURIComponent(username)}`;
00458|     if (!info) {
00459|       return `Expert profile: <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Open</a>`;
00460|     }
00461| 
00462|     const name = info.name || username;
00463|     const avatarUrl = info.avatar_url || info.avatar || null;
00464|     const location = info.location || info.display_location || "";
00465| 
00466|     const stats = [
00467|       { label: "Projects", value: formatCompactNumber(info.projects_count) },
00468|       { label: "Downloads", value: formatCompactNumber(info.total_downloads) },
00469|       { label: "Stars", value: formatCompactNumber(info.total_stars) }
00470|     ].filter((stat) => stat.value !== null);
00471| 
00472|     const projects = Array.isArray(info.projects) ? info.projects : [];
00473|     const sortedProjects = [...projects].sort((a, b) => {
00474|       const starsA = Number(a.total_stars || a.stars || 0);
00475|       const starsB = Number(b.total_stars || b.stars || 0);
00476|       if (starsB !== starsA) return starsB - starsA;
00477|       const downloadsA = Number(a.total_downloads || a.downloads || 0);
00478|       const downloadsB = Number(b.total_downloads || b.downloads || 0);
00479|       return downloadsB - downloadsA;
00480|     });

(File has more lines. Use 'offset' parameter to read beyond line 480)
</file>
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n   const state = {\n     config: loadConfig(),\n     currentResult: null,\n-    listCache: new Map()\n+    listCache: new Map(),\n+    mountRetryTimer: null,\n+    mountRetryCount: 0\n   };\n@@\n   function ensureStyles() {\n@@\n     document.head.appendChild(style);\n   }\n+\n+  function clearMountRetry() {\n+    if (!state.mountRetryTimer) return;\n+    window.clearTimeout(state.mountRetryTimer);\n+    state.mountRetryTimer = null;\n+  }\n+\n+  function scheduleMountRetry() {\n+    if (state.mountRetryTimer || state.mountRetryCount >= 40 || !isPullDetailPage()) return;\n+    state.mountRetryTimer = window.setTimeout(() => {\n+      state.mountRetryTimer = null;\n+      state.mountRetryCount += 1;\n+      ensurePanel();\n+    }, 250);\n+  }\n \n   function findSidebar() {\n-    return document.querySelector(\".discussion-sidebar\");\n+    const selectors = [\n+      \".discussion-sidebar\",\n+      \".Layout-sidebar .discussion-sidebar\",\n+      \".Layout-sidebar\"\n+    ];\n+\n+    for (const selector of selectors) {\n+      const element = document.querySelector(selector);\n+      if (element) return element;\n+    }\n+\n+    return null;\n   }\n \n   function findReviewersSection(sidebar) {\n     if (!sidebar) return null;\n     const byClass = sidebar.querySelector(\".discussion-sidebar-item.sidebar-reviewers\");\n     if (byClass) return byClass;\n \n-    const headings = sidebar.querySelectorAll(\".discussion-sidebar-heading, h3\");\n+    const headings = sidebar.querySelectorAll(\".discussion-sidebar-heading, h2, h3, h4\");\n     for (const heading of headings) {\n-      if (heading.textContent.trim().toLowerCase() !== \"reviewers\") continue;\n-      const item = heading.closest(\".discussion-sidebar-item\");\n+      if (heading.textContent.trim().toLowerCase() !== \"reviewers\") continue;\n+      const item = heading.closest(\n+        \".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section\"\n+      );\n       if (item) return item;\n     }\n \n     return null;\n   }\n@@\n   function ensurePanel() {\n     const existing = document.getElementById(PANEL_ID);\n     if (!isPullDetailPage()) {\n       if (existing) existing.remove();\n+      clearMountRetry();\n+      state.mountRetryCount = 0;\n       removeBadge();\n       return;\n     }\n@@\n     ensureStyles();\n \n     if (existing) {\n-      mountPanel(existing);\n+      if (!mountPanel(existing)) {\n+        scheduleMountRetry();\n+        return;\n+      }\n+      clearMountRetry();\n+      state.mountRetryCount = 0;\n       updatePanel(existing);\n       return;\n     }\n@@\n     });\n \n     if (!mountPanel(wrapper)) {\n+      scheduleMountRetry();\n       return;\n     }\n+\n+    clearMountRetry();\n+    state.mountRetryCount = 0;\n \n     updatePanel(wrapper);\n   }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js\n@@\n   const state = {\n     config: loadConfig(),\n-    currentResult: null\n+    currentResult: null,\n+    mountRetryTimer: null,\n+    mountRetryCount: 0\n   };\n@@\n   function ensureStyles() {\n@@\n     document.head.appendChild(style);\n   }\n+\n+  function clearMountRetry() {\n+    if (!state.mountRetryTimer) return;\n+    window.clearTimeout(state.mountRetryTimer);\n+    state.mountRetryTimer = null;\n+  }\n+\n+  function scheduleMountRetry() {\n+    if (state.mountRetryTimer || state.mountRetryCount >= 40 || !isPullDetailPage()) return;\n+    state.mountRetryTimer = window.setTimeout(() => {\n+      state.mountRetryTimer = null;\n+      state.mountRetryCount += 1;\n+      ensurePanel();\n+    }, 250);\n+  }\n \n   function findSidebar() {\n-    return document.querySelector(\".discussion-sidebar\");\n+    const selectors = [\n+      \".discussion-sidebar\",\n+      \".Layout-sidebar .discussion-sidebar\",\n+      \".Layout-sidebar\"\n+    ];\n+\n+    for (const selector of selectors) {\n+      const element = document.querySelector(selector);\n+      if (element) return element;\n+    }\n+\n+    return null;\n   }\n \n   function findReviewersSection(sidebar) {\n     if (!sidebar) return null;\n     const byClass = sidebar.querySelector(\".discussion-sidebar-item.sidebar-reviewers\");\n     if (byClass) return byClass;\n \n-    const headings = sidebar.querySelectorAll(\".discussion-sidebar-heading, h3\");\n+    const headings = sidebar.querySelectorAll(\".discussion-sidebar-heading, h2, h3, h4\");\n     for (const heading of headings) {\n       if (heading.textContent.trim().toLowerCase() !== \"reviewers\") continue;\n-      const item = heading.closest(\".discussion-sidebar-item\");\n+      const item = heading.closest(\n+        \".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section\"\n+      );\n       if (item) return item;\n     }\n@@\n   function ensurePanel() {\n     const existing = document.getElementById(PANEL_ID);\n     if (!isPullDetailPage()) {\n       if (existing) existing.remove();\n+      clearMountRetry();\n+      state.mountRetryCount = 0;\n       removeBadge();\n       return;\n     }\n@@\n     ensureStyles();\n \n     if (existing) {\n-      mountPanel(existing);\n+      if (!mountPanel(existing)) {\n+        scheduleMountRetry();\n+        return;\n+      }\n+      clearMountRetry();\n+      state.mountRetryCount = 0;\n       updatePanel(existing);\n       return;\n     }\n@@\n     });\n \n     if (!mountPanel(wrapper)) {\n+      scheduleMountRetry();\n       return;\n     }\n+\n+    clearMountRetry();\n+    state.mountRetryCount = 0;\n \n     updatePanel(wrapper);\n   }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M bookmarklet.js
```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check content.js",
  "description": "Verify content script syntax"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check bookmarklet.js",
  "description": "Verify bookmarklet syntax"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git diff -- content.js bookmarklet.js",
  "description": "Inspect latest script modifications"
}
```

## Assistant

**Result** (success):
```
diff --git a/bookmarklet.js b/bookmarklet.js
index b264bbb..6a770d6 100644
--- a/bookmarklet.js
+++ b/bookmarklet.js
@@ -14,7 +14,9 @@
 
   const state = {
     config: loadConfig(),
-    currentResult: null
+    currentResult: null,
+    mountRetryTimer: null,
+    mountRetryCount: 0
   };
 
   function loadConfig() {
@@ -43,116 +45,91 @@
     style.id = STYLE_ID;
     style.textContent = `
       #${PANEL_ID} {
-        position: fixed;
-        right: 16px;
-        bottom: 16px;
-        z-index: 999999;
-        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
-        color: #1f2328;
+        color: var(--fgColor-default, #24292f);
+      }
+      #${PANEL_ID}.discussion-sidebar-item {
+        margin-top: 0;
       }
       #${PANEL_ID} .md-pr-panel {
-        width: 440px;
-        background: #ffffff;
-        border: 1px solid #d0d7de;
-        border-radius: 12px;
-        box-shadow: 0 1px 3px rgba(27, 31, 36, 0.12);
-        padding: 12px 12px 10px;
-        font-size: 14px;
+        font-size: 12px;
+        line-height: 1.5;
       }
       #${PANEL_ID} .md-pr-header {
         display: flex;
-        justify-content: flex-end;
+        justify-content: space-between;
         align-items: center;
-        gap: 8px;
-        font-weight: 600;
-        font-size: 13px;
+        margin-bottom: 6px;
+      }
+      #${PANEL_ID} .md-pr-heading {
+        margin: 0;
       }
       #${PANEL_ID} .md-pr-gear {
         border: none;
-        background: #f6f8fa;
-        border-radius: 6px;
-        width: 28px;
-        height: 28px;
+        background: transparent;
+        color: var(--fgColor-muted, #57606a);
+        width: 20px;
+        height: 20px;
+        padding: 0;
         display: inline-flex;
         align-items: center;
         justify-content: center;
         cursor: pointer;
-        border: 1px solid #d0d7de;
-        color: #57606a;
       }
-      #${PANEL_ID} .md-pr-body {
-        margin-top: 10px;
+      #${PANEL_ID} .md-pr-gear:hover {
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-settings {
         display: none;
-        margin-top: 10px;
-        border-top: 1px dashed #d0d7de;
-        padding-top: 10px;
+        margin-top: 8px;
       }
       #${PANEL_ID} .md-pr-settings.md-pr-open {
         display: block;
       }
-      #${PANEL_ID} label {
+      #${PANEL_ID} .md-pr-settings label {
         display: block;
-        margin-bottom: 6px;
-        font-weight: 600;
+        margin-bottom: 4px;
         font-size: 12px;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
       }
-      #${PANEL_ID} input[type="text"],
-      #${PANEL_ID} input[type="password"] {
+      #${PANEL_ID} .md-pr-settings input[type="password"] {
         width: 100%;
-        border: 1px solid #d0d7de;
+        border: 1px solid var(--borderColor-default, #d0d7de);
         border-radius: 6px;
-        padding: 6px 8px;
-        font-size: 14px;
-        background: #ffffff;
-        margin-bottom: 8px;
+        padding: 5px 8px;
+        font-size: 12px;
+        color: var(--fgColor-default, #24292f);
+        background: var(--bgColor-default, #ffffff);
       }
       #${PANEL_ID} .md-pr-status {
-        margin-top: 8px;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-warning {
-        color: #cf222e;
-        font-weight: 600;
-      }
-      #${PANEL_ID} .md-pr-success {
-        color: #1a7f37;
-        font-weight: 600;
+        color: var(--fgColor-danger, #cf222e);
       }
       #${PANEL_ID} .md-pr-details {
-        margin-top: 6px;
-        color: #24292f;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-summary {
-        margin-top: 6px;
-        font-size: 18px;
-        color: #24292f;
-        font-weight: 600;
-      }
-      #${PANEL_ID} .md-pr-card {
-        border: 1px solid #d0d7de;
-        border-radius: 10px;
-        padding: 12px;
+        margin-bottom: 8px;
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-card-header {
         display: flex;
-        gap: 12px;
-        align-items: center;
+        gap: 8px;
+        align-items: flex-start;
       }
       #${PANEL_ID} .md-pr-avatar {
-        width: 56px;
-        height: 56px;
+        width: 32px;
+        height: 32px;
         border-radius: 50%;
-        background: #f6f8fa;
-        border: 1px solid #d0d7de;
         overflow: hidden;
+        background: var(--bgColor-muted, #f6f8fa);
         display: inline-flex;
         align-items: center;
         justify-content: center;
         font-weight: 600;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
+        flex-shrink: 0;
       }
       #${PANEL_ID} .md-pr-avatar img {
         width: 100%;
@@ -160,144 +137,78 @@
         object-fit: cover;
       }
       #${PANEL_ID} .md-pr-name {
-        font-size: 18px;
-        font-weight: 700;
-        color: #1a7f37;
+        font-size: 13px;
+        font-weight: 600;
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-meta {
-        margin-top: 6px;
-        color: #57606a;
-        font-size: 14px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-links {
-        margin-top: 6px;
+        margin-top: 2px;
         display: flex;
-        gap: 12px;
-        font-size: 14px;
+        gap: 8px;
       }
       #${PANEL_ID} .md-pr-link {
-        color: #0969da;
-        font-weight: 600;
+        color: var(--fgColor-accent, #0969da);
+        text-decoration: none;
       }
-      #${PANEL_ID} .md-pr-stats {
-        margin-top: 12px;
-        border: 1px solid #d0d7de;
-        border-radius: 8px;
-        overflow: hidden;
+      #${PANEL_ID} .md-pr-link:hover {
+        text-decoration: underline;
       }
-      #${PANEL_ID} .md-pr-stat-row {
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        padding: 8px 10px;
-        border-bottom: 1px solid #d0d7de;
-        font-size: 14px;
+      #${PANEL_ID} .md-pr-stats {
+        margin-top: 8px;
       }
-      #${PANEL_ID} .md-pr-stat-row:last-child {
-        border-bottom: none;
+      #${PANEL_ID} .md-pr-stat-item {
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-stat-label {
-        color: #57606a;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        font-weight: 600;
-        font-size: 11px;
+        color: var(--fgColor-muted, #57606a);
       }
-      #${PANEL_ID} .md-pr-stat-value {
-        font-weight: 700;
-        color: #24292f;
+      #${PANEL_ID} .md-pr-stat-sep {
+        margin: 0 4px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-section {
-        margin-top: 12px;
+        margin-top: 8px;
       }
       #${PANEL_ID} .md-pr-section-title {
-        font-size: 13px;
+        margin-bottom: 2px;
         font-weight: 600;
-        color: #57606a;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        margin-bottom: 6px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-ecosystems {
         display: flex;
         flex-wrap: wrap;
-        gap: 6px;
+        gap: 8px;
       }
       #${PANEL_ID} .md-pr-ecosystem-pill {
-        display: inline-flex;
-        align-items: center;
-        background: #f6f8fa;
-        border: 1px solid #d0d7de;
-        border-radius: 999px;
-        padding: 2px 8px;
-        font-size: 13px;
-        color: #57606a;
+        color: var(--fgColor-accent, #0969da);
         text-decoration: none;
       }
+      #${PANEL_ID} .md-pr-ecosystem-pill:hover {
+        text-decoration: underline;
+      }
       #${PANEL_ID} .md-pr-project-list {
         display: flex;
         flex-direction: column;
-        gap: 6px;
+        gap: 2px;
       }
       #${PANEL_ID} .md-pr-project-item {
         display: flex;
+        align-items: baseline;
         justify-content: space-between;
         gap: 8px;
-        font-size: 14px;
-        color: #24292f;
       }
       #${PANEL_ID} .md-pr-project-meta {
-        color: #57606a;
-        font-size: 13px;
+        color: var(--fgColor-muted, #57606a);
+        flex-shrink: 0;
       }
-      #${PANEL_ID} .md-pr-section {
+      #${PANEL_ID} .md-pr-powered {
         margin-top: 8px;
-      }
-      #${PANEL_ID} .md-pr-section-title {
         font-size: 11px;
-        font-weight: 600;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        color: #6b7280;
-        margin-bottom: 4px;
-      }
-      #${PANEL_ID} .md-pr-stats {
-        display: grid;
-        grid-template-columns: repeat(3, minmax(0, 1fr));
-        gap: 6px;
-      }
-      #${PANEL_ID} .md-pr-stat {
-        background: #ffffff;
-        border: 1px solid #e5e7eb;
-        border-radius: 8px;
-        padding: 6px;
-        text-align: center;
-      }
-      #${PANEL_ID} .md-pr-stat-label {
-        font-size: 10px;
-        text-transform: uppercase;
-        letter-spacing: 0.05em;
-        color: #6b7280;
-      }
-      #${PANEL_ID} .md-pr-stat-value {
-        font-size: 13px;
-        font-weight: 600;
-        color: #111827;
-      }
-      #${PANEL_ID} .md-pr-pill {
-        display: inline-flex;
-        align-items: center;
-        padding: 2px 6px;
-        border-radius: 999px;
-        background: #eef2ff;
-        color: #3730a3;
-        font-size: 11px;
-        margin-right: 4px;
-        margin-bottom: 4px;
-      }
-      #${PANEL_ID} .md-pr-link {
-        color: #0a3069;
-        font-weight: 600;
+        color: var(--fgColor-muted, #57606a);
+        opacity: 0.65;
       }
       #${BADGE_ID} {
         display: inline-flex;
@@ -321,10 +232,77 @@
     document.head.appendChild(style);
   }
 
+  function clearMountRetry() {
+    if (!state.mountRetryTimer) return;
+    window.clearTimeout(state.mountRetryTimer);
+    state.mountRetryTimer = null;
+  }
+
+  function scheduleMountRetry() {
+    if (state.mountRetryTimer || state.mountRetryCount >= 40 || !isPullDetailPage()) return;
+    state.mountRetryTimer = window.setTimeout(() => {
+      state.mountRetryTimer = null;
+      state.mountRetryCount += 1;
+      ensurePanel();
+    }, 250);
+  }
+
+  function findSidebar() {
+    const selectors = [
+      ".discussion-sidebar",
+      ".Layout-sidebar .discussion-sidebar",
+      ".Layout-sidebar"
+    ];
+
+    for (const selector of selectors) {
+      const element = document.querySelector(selector);
+      if (element) return element;
+    }
+
+    return null;
+  }
+
+  function findReviewersSection(sidebar) {
+    if (!sidebar) return null;
+    const byClass = sidebar.querySelector(".discussion-sidebar-item.sidebar-reviewers");
+    if (byClass) return byClass;
+
+    const headings = sidebar.querySelectorAll(".discussion-sidebar-heading, h2, h3, h4");
+    for (const heading of headings) {
+      if (heading.textContent.trim().toLowerCase() !== "reviewers") continue;
+      const item = heading.closest(
+        ".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section"
+      );
+      if (item) return item;
+    }
+
+    return null;
+  }
+
+  function mountPanel(wrapper) {
+    const sidebar = findSidebar();
+    if (!sidebar) return false;
+
+    const reviewersSection = findReviewersSection(sidebar);
+    if (reviewersSection) {
+      if (reviewersSection.nextElementSibling !== wrapper) {
+        reviewersSection.insertAdjacentElement("afterend", wrapper);
+      }
+      return true;
+    }
+
+    if (wrapper.parentElement !== sidebar) {
+      sidebar.appendChild(wrapper);
+    }
+    return true;
+  }
+
   function ensurePanel() {
     const existing = document.getElementById(PANEL_ID);
     if (!isPullDetailPage()) {
       if (existing) existing.remove();
+      clearMountRetry();
+      state.mountRetryCount = 0;
       removeBadge();
       return;
     }
@@ -332,16 +310,23 @@
     ensureStyles();
 
     if (existing) {
+      if (!mountPanel(existing)) {
+        scheduleMountRetry();
+        return;
+      }
+      clearMountRetry();
+      state.mountRetryCount = 0;
       updatePanel(existing);
       return;
     }
 
     const wrapper = document.createElement("div");
     wrapper.id = PANEL_ID;
+    wrapper.className = "discussion-sidebar-item";
     wrapper.innerHTML = `
       <div class="md-pr-panel">
         <div class="md-pr-header">
-          <span></span>
+          <h3 class="discussion-sidebar-heading md-pr-heading">Contributor insights</h3>
           <button class="md-pr-gear" type="button" aria-label="Settings">
             <span aria-hidden="true">⚙</span>
           </button>
@@ -352,10 +337,11 @@
           <div class="md-pr-details"></div>
         </div>
         <div class="md-pr-settings ${state.config.settingsOpen ? "md-pr-open" : ""}">
-          <label>API key</label>
-          <input type="password" data-config="apiKey" />
+          <label for="${PANEL_ID}-api-key">API key</label>
+          <input id="${PANEL_ID}-api-key" type="password" data-config="apiKey" />
           <div class="md-pr-status"></div>
         </div>
+        <div class="md-pr-powered">Powered by the Open Source Explorer</div>
       </div>
     `;
 
@@ -374,7 +360,14 @@
       });
     });
 
-    document.body.appendChild(wrapper);
+    if (!mountPanel(wrapper)) {
+      scheduleMountRetry();
+      return;
+    }
+
+    clearMountRetry();
+    state.mountRetryCount = 0;
+
     updatePanel(wrapper);
   }
 
@@ -420,8 +413,8 @@
       statusBlocks.forEach((status) => {
         status.innerHTML = "";
       });
-      summary.innerHTML = `No profile found on the Open Source Explorer. <a class="md-pr-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Explore</a>`;
-      details.innerHTML = "";
+      summary.textContent = "No contributor profile found yet.";
+      details.innerHTML = `<a class="md-pr-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Browse directory</a>`;
       return;
     }
 
@@ -523,11 +516,11 @@
             ${avatarUrl ? `<img src="${avatarUrl}" alt="${name}" />` : name.slice(0, 1).toUpperCase()}
           </div>
           <div>
-            <div class="md-pr-name">${name}</div>
+            <div class="md-pr-name"><a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">${name}</a></div>
             <div class="md-pr-meta">@${username}${location ? ` · ${location}` : ""}</div>
             <div class="md-pr-links">
               <a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">GitHub</a>
-              <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Explore</a>
+              <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Market.dev</a>
             </div>
           </div>
         </div>
@@ -535,14 +528,9 @@
           <div class="md-pr-stats">
             ${stats
               .map(
-                (stat) => `
-                  <div class="md-pr-stat-row">
-                    <span class="md-pr-stat-label">${stat.label}</span>
-                    <span class="md-pr-stat-value">${stat.value}</span>
-                  </div>
-                `
+                (stat) => `<span class="md-pr-stat-item"><span class="md-pr-stat-label">${stat.label}:</span> ${stat.value}</span>`
               )
-              .join("")}
+              .join('<span class="md-pr-stat-sep">·</span>')}
           </div>
         ` : ""}
         ${ecosystemNames.length ? `
@@ -676,9 +664,3 @@
     init();
   }
 })();
-      #${PANEL_ID} .md-pr-summary {
-        margin-top: 6px;
-        font-size: 13px;
-        color: #111827;
-        font-weight: 600;
-      }
diff --git a/content.js b/content.js
index 6c186a7..ebe083a 100644
--- a/content.js
+++ b/content.js
@@ -12,7 +12,9 @@
   const state = {
     config: loadConfig(),
     currentResult: null,
-    listCache: new Map()
+    listCache: new Map(),
+    mountRetryTimer: null,
+    mountRetryCount: 0
   };
 
   function loadConfig() {
@@ -65,116 +67,91 @@
     style.id = STYLE_ID;
     style.textContent = `
       #${PANEL_ID} {
-        position: fixed;
-        right: 16px;
-        bottom: 16px;
-        z-index: 999999;
-        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
-        color: #1f2328;
+        color: var(--fgColor-default, #24292f);
+      }
+      #${PANEL_ID}.discussion-sidebar-item {
+        margin-top: 0;
       }
       #${PANEL_ID} .md-pr-panel {
-        width: 440px;
-        background: #ffffff;
-        border: 1px solid #d0d7de;
-        border-radius: 12px;
-        box-shadow: 0 1px 3px rgba(27, 31, 36, 0.12);
-        padding: 12px 12px 10px;
-        font-size: 14px;
+        font-size: 12px;
+        line-height: 1.5;
       }
       #${PANEL_ID} .md-pr-header {
         display: flex;
-        justify-content: flex-end;
+        justify-content: space-between;
         align-items: center;
-        gap: 8px;
-        font-weight: 600;
-        font-size: 13px;
+        margin-bottom: 6px;
+      }
+      #${PANEL_ID} .md-pr-heading {
+        margin: 0;
       }
       #${PANEL_ID} .md-pr-gear {
         border: none;
-        background: #f6f8fa;
-        border-radius: 6px;
-        width: 28px;
-        height: 28px;
+        background: transparent;
+        color: var(--fgColor-muted, #57606a);
+        width: 20px;
+        height: 20px;
+        padding: 0;
         display: inline-flex;
         align-items: center;
         justify-content: center;
         cursor: pointer;
-        border: 1px solid #d0d7de;
-        color: #57606a;
       }
-      #${PANEL_ID} .md-pr-body {
-        margin-top: 10px;
+      #${PANEL_ID} .md-pr-gear:hover {
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-settings {
         display: none;
-        margin-top: 10px;
-        border-top: 1px dashed #d0d7de;
-        padding-top: 10px;
+        margin-top: 8px;
       }
       #${PANEL_ID} .md-pr-settings.md-pr-open {
         display: block;
       }
-      #${PANEL_ID} label {
+      #${PANEL_ID} .md-pr-settings label {
         display: block;
-        margin-bottom: 6px;
-        font-weight: 600;
+        margin-bottom: 4px;
         font-size: 12px;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
       }
-      #${PANEL_ID} input[type="text"],
-      #${PANEL_ID} input[type="password"] {
+      #${PANEL_ID} .md-pr-settings input[type="password"] {
         width: 100%;
-        border: 1px solid #d0d7de;
+        border: 1px solid var(--borderColor-default, #d0d7de);
         border-radius: 6px;
-        padding: 6px 8px;
-        font-size: 14px;
-        background: #ffffff;
-        margin-bottom: 8px;
+        padding: 5px 8px;
+        font-size: 12px;
+        color: var(--fgColor-default, #24292f);
+        background: var(--bgColor-default, #ffffff);
       }
       #${PANEL_ID} .md-pr-status {
-        margin-top: 8px;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-warning {
-        color: #cf222e;
-        font-weight: 600;
-      }
-      #${PANEL_ID} .md-pr-success {
-        color: #1a7f37;
-        font-weight: 600;
+        color: var(--fgColor-danger, #cf222e);
       }
       #${PANEL_ID} .md-pr-details {
-        margin-top: 6px;
-        color: #24292f;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-summary {
-        margin-top: 6px;
-        font-size: 18px;
-        color: #24292f;
-        font-weight: 600;
-      }
-      #${PANEL_ID} .md-pr-card {
-        border: 1px solid #d0d7de;
-        border-radius: 10px;
-        padding: 12px;
+        margin-bottom: 8px;
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-card-header {
         display: flex;
-        gap: 12px;
-        align-items: center;
+        gap: 8px;
+        align-items: flex-start;
       }
       #${PANEL_ID} .md-pr-avatar {
-        width: 56px;
-        height: 56px;
+        width: 32px;
+        height: 32px;
         border-radius: 50%;
-        background: #f6f8fa;
-        border: 1px solid #d0d7de;
         overflow: hidden;
+        background: var(--bgColor-muted, #f6f8fa);
         display: inline-flex;
         align-items: center;
         justify-content: center;
         font-weight: 600;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
+        flex-shrink: 0;
       }
       #${PANEL_ID} .md-pr-avatar img {
         width: 100%;
@@ -182,95 +159,78 @@
         object-fit: cover;
       }
       #${PANEL_ID} .md-pr-name {
-        font-size: 18px;
-        font-weight: 700;
-        color: #1a7f37;
+        font-size: 13px;
+        font-weight: 600;
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-meta {
-        margin-top: 6px;
-        color: #57606a;
-        font-size: 14px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-links {
-        margin-top: 6px;
+        margin-top: 2px;
         display: flex;
-        gap: 12px;
-        font-size: 14px;
+        gap: 8px;
       }
       #${PANEL_ID} .md-pr-link {
-        color: #0969da;
-        font-weight: 600;
+        color: var(--fgColor-accent, #0969da);
+        text-decoration: none;
       }
-      #${PANEL_ID} .md-pr-stats {
-        margin-top: 12px;
-        border: 1px solid #d0d7de;
-        border-radius: 8px;
-        overflow: hidden;
+      #${PANEL_ID} .md-pr-link:hover {
+        text-decoration: underline;
       }
-      #${PANEL_ID} .md-pr-stat-row {
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        padding: 8px 10px;
-        border-bottom: 1px solid #d0d7de;
-        font-size: 14px;
+      #${PANEL_ID} .md-pr-stats {
+        margin-top: 8px;
       }
-      #${PANEL_ID} .md-pr-stat-row:last-child {
-        border-bottom: none;
+      #${PANEL_ID} .md-pr-stat-item {
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-stat-label {
-        color: #57606a;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        font-weight: 600;
-        font-size: 11px;
+        color: var(--fgColor-muted, #57606a);
       }
-      #${PANEL_ID} .md-pr-stat-value {
-        font-weight: 700;
-        color: #24292f;
+      #${PANEL_ID} .md-pr-stat-sep {
+        margin: 0 4px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-section {
-        margin-top: 12px;
+        margin-top: 8px;
       }
       #${PANEL_ID} .md-pr-section-title {
-        font-size: 13px;
+        margin-bottom: 2px;
         font-weight: 600;
-        color: #57606a;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        margin-bottom: 6px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-ecosystems {
         display: flex;
         flex-wrap: wrap;
-        gap: 6px;
+        gap: 8px;
       }
       #${PANEL_ID} .md-pr-ecosystem-pill {
-        display: inline-flex;
-        align-items: center;
-        background: #f6f8fa;
-        border: 1px solid #d0d7de;
-        border-radius: 999px;
-        padding: 2px 8px;
-        font-size: 13px;
-        color: #57606a;
+        color: var(--fgColor-accent, #0969da);
         text-decoration: none;
       }
+      #${PANEL_ID} .md-pr-ecosystem-pill:hover {
+        text-decoration: underline;
+      }
       #${PANEL_ID} .md-pr-project-list {
         display: flex;
         flex-direction: column;
-        gap: 6px;
+        gap: 2px;
       }
       #${PANEL_ID} .md-pr-project-item {
         display: flex;
+        align-items: baseline;
         justify-content: space-between;
         gap: 8px;
-        font-size: 14px;
-        color: #24292f;
       }
       #${PANEL_ID} .md-pr-project-meta {
-        color: #57606a;
-        font-size: 13px;
+        color: var(--fgColor-muted, #57606a);
+        flex-shrink: 0;
+      }
+      #${PANEL_ID} .md-pr-powered {
+        margin-top: 8px;
+        font-size: 11px;
+        color: var(--fgColor-muted, #57606a);
+        opacity: 0.65;
       }
       .md-pr-list-indicator {
         display: inline-flex;
@@ -289,55 +249,6 @@
       .md-pr-list-indicator.md-pr-list-missing {
         background: #afb8c1;
       }
-      #${PANEL_ID} .md-pr-section {
-        margin-top: 8px;
-      }
-      #${PANEL_ID} .md-pr-section-title {
-        font-size: 11px;
-        font-weight: 600;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        color: #6b7280;
-        margin-bottom: 4px;
-      }
-      #${PANEL_ID} .md-pr-stats {
-        display: grid;
-        grid-template-columns: repeat(3, minmax(0, 1fr));
-        gap: 6px;
-      }
-      #${PANEL_ID} .md-pr-stat {
-        background: #ffffff;
-        border: 1px solid #e5e7eb;
-        border-radius: 8px;
-        padding: 6px;
-        text-align: center;
-      }
-      #${PANEL_ID} .md-pr-stat-label {
-        font-size: 10px;
-        text-transform: uppercase;
-        letter-spacing: 0.05em;
-        color: #6b7280;
-      }
-      #${PANEL_ID} .md-pr-stat-value {
-        font-size: 13px;
-        font-weight: 600;
-        color: #111827;
-      }
-      #${PANEL_ID} .md-pr-pill {
-        display: inline-flex;
-        align-items: center;
-        padding: 2px 6px;
-        border-radius: 999px;
-        background: #eef2ff;
-        color: #3730a3;
-        font-size: 11px;
-        margin-right: 4px;
-        margin-bottom: 4px;
-      }
-      #${PANEL_ID} .md-pr-link {
-        color: #0a3069;
-        font-weight: 600;
-      }
       #${BADGE_ID} {
         display: inline-flex;
         align-items: center;
@@ -360,10 +271,77 @@
     document.head.appendChild(style);
   }
 
+  function clearMountRetry() {
+    if (!state.mountRetryTimer) return;
+    window.clearTimeout(state.mountRetryTimer);
+    state.mountRetryTimer = null;
+  }
+
+  function scheduleMountRetry() {
+    if (state.mountRetryTimer || state.mountRetryCount >= 40 || !isPullDetailPage()) return;
+    state.mountRetryTimer = window.setTimeout(() => {
+      state.mountRetryTimer = null;
+      state.mountRetryCount += 1;
+      ensurePanel();
+    }, 250);
+  }
+
+  function findSidebar() {
+    const selectors = [
+      ".discussion-sidebar",
+      ".Layout-sidebar .discussion-sidebar",
+      ".Layout-sidebar"
+    ];
+
+    for (const selector of selectors) {
+      const element = document.querySelector(selector);
+      if (element) return element;
+    }
+
+    return null;
+  }
+
+  function findReviewersSection(sidebar) {
+    if (!sidebar) return null;
+    const byClass = sidebar.querySelector(".discussion-sidebar-item.sidebar-reviewers");
+    if (byClass) return byClass;
+
+    const headings = sidebar.querySelectorAll(".discussion-sidebar-heading, h2, h3, h4");
+    for (const heading of headings) {
+      if (heading.textContent.trim().toLowerCase() !== "reviewers") continue;
+      const item = heading.closest(
+        ".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section"
+      );
+      if (item) return item;
+    }
+
+    return null;
+  }
+
+  function mountPanel(wrapper) {
+    const sidebar = findSidebar();
+    if (!sidebar) return false;
+
+    const reviewersSection = findReviewersSection(sidebar);
+    if (reviewersSection) {
+      if (reviewersSection.nextElementSibling !== wrapper) {
+        reviewersSection.insertAdjacentElement("afterend", wrapper);
+      }
+      return true;
+    }
+
+    if (wrapper.parentElement !== sidebar) {
+      sidebar.appendChild(wrapper);
+    }
+    return true;
+  }
+
   function ensurePanel() {
     const existing = document.getElementById(PANEL_ID);
     if (!isPullDetailPage()) {
       if (existing) existing.remove();
+      clearMountRetry();
+      state.mountRetryCount = 0;
       removeBadge();
       return;
     }
@@ -371,16 +349,23 @@
     ensureStyles();
 
     if (existing) {
+      if (!mountPanel(existing)) {
+        scheduleMountRetry();
+        return;
+      }
+      clearMountRetry();
+      state.mountRetryCount = 0;
       updatePanel(existing);
       return;
     }
 
     const wrapper = document.createElement("div");
     wrapper.id = PANEL_ID;
+    wrapper.className = "discussion-sidebar-item";
     wrapper.innerHTML = `
       <div class="md-pr-panel">
         <div class="md-pr-header">
-          <span></span>
+          <h3 class="discussion-sidebar-heading md-pr-heading">Contributor insights</h3>
           <button class="md-pr-gear" type="button" aria-label="Settings">
             <span aria-hidden="true">⚙</span>
           </button>
@@ -391,10 +376,11 @@
           <div class="md-pr-details"></div>
         </div>
         <div class="md-pr-settings ${state.config.settingsOpen ? "md-pr-open" : ""}">
-          <label>API key</label>
-          <input type="password" data-config="apiKey" />
+          <label for="${PANEL_ID}-api-key">API key</label>
+          <input id="${PANEL_ID}-api-key" type="password" data-config="apiKey" />
           <div class="md-pr-status"></div>
         </div>
+        <div class="md-pr-powered">Powered by the Open Source Explorer</div>
       </div>
     `;
 
@@ -417,7 +403,14 @@
       });
     });
 
-    document.body.appendChild(wrapper);
+    if (!mountPanel(wrapper)) {
+      scheduleMountRetry();
+      return;
+    }
+
+    clearMountRetry();
+    state.mountRetryCount = 0;
+
     updatePanel(wrapper);
   }
 
@@ -463,8 +456,8 @@
       statusBlocks.forEach((status) => {
         status.innerHTML = "";
       });
-      summary.innerHTML = `No profile found on the Open Source Explorer. <a class="md-pr-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Explore</a>`;
-      details.innerHTML = "";
+      summary.textContent = "No contributor profile found yet.";
+      details.innerHTML = `<a class="md-pr-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Browse directory</a>`;
       return;
     }
 
@@ -566,7 +559,7 @@
             ${avatarUrl ? `<img src="${avatarUrl}" alt="${name}" />` : name.slice(0, 1).toUpperCase()}
           </div>
           <div>
-            <div class="md-pr-name">${name}</div>
+            <div class="md-pr-name"><a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">${name}</a></div>
             <div class="md-pr-meta">@${username}${location ? ` · ${location}` : ""}</div>
             <div class="md-pr-links">
               <a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">GitHub</a>
@@ -578,14 +571,9 @@
           <div class="md-pr-stats">
             ${stats
               .map(
-                (stat) => `
-                  <div class="md-pr-stat-row">
-                    <span class="md-pr-stat-label">${stat.label}</span>
-                    <span class="md-pr-stat-value">${stat.value}</span>
-                  </div>
-                `
+                (stat) => `<span class="md-pr-stat-item"><span class="md-pr-stat-label">${stat.label}:</span> ${stat.value}</span>`
               )
-              .join("")}
+              .join('<span class="md-pr-stat-sep">·</span>')}
           </div>
         ` : ""}
         ${ecosystemNames.length ? `

```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n   function findSidebar() {\n     const selectors = [\n       \".discussion-sidebar\",\n       \".Layout-sidebar .discussion-sidebar\",\n       \".Layout-sidebar\"\n     ];\n-\n-    for (const selector of selectors) {\n-      const element = document.querySelector(selector);\n-      if (element) return element;\n+\n+    const seen = new Set();\n+    const candidates = [];\n+\n+    for (const selector of selectors) {\n+      document.querySelectorAll(selector).forEach((element) => {\n+        if (seen.has(element)) return;\n+        seen.add(element);\n+        candidates.push(element);\n+      });\n     }\n+\n+    const visible = candidates.find((element) => element.getClientRects().length > 0);\n+    if (visible) return visible;\n+\n+    if (candidates.length) return candidates[0];\n \n     return null;\n   }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js\n@@\n   function findSidebar() {\n     const selectors = [\n       \".discussion-sidebar\",\n       \".Layout-sidebar .discussion-sidebar\",\n       \".Layout-sidebar\"\n     ];\n-\n-    for (const selector of selectors) {\n-      const element = document.querySelector(selector);\n-      if (element) return element;\n+\n+    const seen = new Set();\n+    const candidates = [];\n+\n+    for (const selector of selectors) {\n+      document.querySelectorAll(selector).forEach((element) => {\n+        if (seen.has(element)) return;\n+        seen.add(element);\n+        candidates.push(element);\n+      });\n     }\n+\n+    const visible = candidates.find((element) => element.getClientRects().length > 0);\n+    if (visible) return visible;\n+\n+    if (candidates.length) return candidates[0];\n \n     return null;\n   }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M bookmarklet.js
```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check content.js",
  "description": "Check content syntax after sidebar fix"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check bookmarklet.js",
  "description": "Check bookmarklet syntax after sidebar fix"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git status --short",
  "description": "Verify modified files"
}
```

## Assistant

**Result** (success):
```
 M bookmarklet.js
 M content.js

```

## Assistant

## Assistant

Got it — I just fixed that.

I updated the mount logic so it no longer silently fails when GitHub renders the sidebar late or uses a different sidebar container.

- It now retries mounting for a few seconds if the sidebar isn’t ready yet.
- It now targets the visible right sidebar (not a hidden one) and falls back across GitHub sidebar variants.
- Applied in both `content.js` and `bookmarklet.js`.

Please do this once:
1. Reload the extension in `chrome://extensions`
2. Hard refresh the PR page (`Cmd+Shift+R`)

If it still doesn’t appear, send me what this returns in DevTools console and I’ll patch immediately:
```js
({
  panel: !!document.querySelector("#md-expert-pr-panel"),
  sidebar: document.querySelector(".discussion-sidebar, .Layout-sidebar")?.className || null
})
```

## User

i ju[Image 1] 

## Assistant

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "pattern": "function findSidebar|function findReviewersSection|function mountPanel"
}
```

## Assistant

**Result** (success):
```
Found 3 matches
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js:
  Line 289:   function findSidebar() {
  Line 315:   function findReviewersSection(sidebar) {
  Line 332:   function mountPanel(wrapper) {
```

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 120,
  "offset": 276
}
```

## Assistant

**Result** (success):
```
<file>
00277|     state.mountRetryTimer = null;
00278|   }
00279| 
00280|   function scheduleMountRetry() {
00281|     if (state.mountRetryTimer || state.mountRetryCount >= 40 || !isPullDetailPage()) return;
00282|     state.mountRetryTimer = window.setTimeout(() => {
00283|       state.mountRetryTimer = null;
00284|       state.mountRetryCount += 1;
00285|       ensurePanel();
00286|     }, 250);
00287|   }
00288| 
00289|   function findSidebar() {
00290|     const selectors = [
00291|       ".discussion-sidebar",
00292|       ".Layout-sidebar .discussion-sidebar",
00293|       ".Layout-sidebar"
00294|     ];
00295| 
00296|     const seen = new Set();
00297|     const candidates = [];
00298| 
00299|     for (const selector of selectors) {
00300|       document.querySelectorAll(selector).forEach((element) => {
00301|         if (seen.has(element)) return;
00302|         seen.add(element);
00303|         candidates.push(element);
00304|       });
00305|     }
00306| 
00307|     const visible = candidates.find((element) => element.getClientRects().length > 0);
00308|     if (visible) return visible;
00309| 
00310|     if (candidates.length) return candidates[0];
00311| 
00312|     return null;
00313|   }
00314| 
00315|   function findReviewersSection(sidebar) {
00316|     if (!sidebar) return null;
00317|     const byClass = sidebar.querySelector(".discussion-sidebar-item.sidebar-reviewers");
00318|     if (byClass) return byClass;
00319| 
00320|     const headings = sidebar.querySelectorAll(".discussion-sidebar-heading, h2, h3, h4");
00321|     for (const heading of headings) {
00322|       if (heading.textContent.trim().toLowerCase() !== "reviewers") continue;
00323|       const item = heading.closest(
00324|         ".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section"
00325|       );
00326|       if (item) return item;
00327|     }
00328| 
00329|     return null;
00330|   }
00331| 
00332|   function mountPanel(wrapper) {
00333|     const sidebar = findSidebar();
00334|     if (!sidebar) return false;
00335| 
00336|     const reviewersSection = findReviewersSection(sidebar);
00337|     if (reviewersSection) {
00338|       if (reviewersSection.nextElementSibling !== wrapper) {
00339|         reviewersSection.insertAdjacentElement("afterend", wrapper);
00340|       }
00341|       return true;
00342|     }
00343| 
00344|     if (wrapper.parentElement !== sidebar) {
00345|       sidebar.appendChild(wrapper);
00346|     }
00347|     return true;
00348|   }
00349| 
00350|   function ensurePanel() {
00351|     const existing = document.getElementById(PANEL_ID);
00352|     if (!isPullDetailPage()) {
00353|       if (existing) existing.remove();
00354|       clearMountRetry();
00355|       state.mountRetryCount = 0;
00356|       removeBadge();
00357|       return;
00358|     }
00359| 
00360|     ensureStyles();
00361| 
00362|     if (existing) {
00363|       if (!mountPanel(existing)) {
00364|         scheduleMountRetry();
00365|         return;
00366|       }
00367|       clearMountRetry();
00368|       state.mountRetryCount = 0;
00369|       updatePanel(existing);
00370|       return;
00371|     }
00372| 
00373|     const wrapper = document.createElement("div");
00374|     wrapper.id = PANEL_ID;
00375|     wrapper.className = "discussion-sidebar-item";
00376|     wrapper.innerHTML = `
00377|       <div class="md-pr-panel">
00378|         <div class="md-pr-header">
00379|           <h3 class="discussion-sidebar-heading md-pr-heading">Contributor insights</h3>
00380|           <button class="md-pr-gear" type="button" aria-label="Settings">
00381|             <span aria-hidden="true">⚙</span>
00382|           </button>
00383|         </div>
00384|         <div class="md-pr-body">
00385|           <div class="md-pr-summary"></div>
00386|           <div class="md-pr-status"></div>
00387|           <div class="md-pr-details"></div>
00388|         </div>
00389|         <div class="md-pr-settings ${state.config.settingsOpen ? "md-pr-open" : ""}">
00390|           <label for="${PANEL_ID}-api-key">API key</label>
00391|           <input id="${PANEL_ID}-api-key" type="password" data-config="apiKey" />
00392|           <div class="md-pr-status"></div>
00393|         </div>
00394|         <div class="md-pr-powered">Powered by the Open Source Explorer</div>
00395|       </div>
00396|     `;

(File has more lines. Use 'offset' parameter to read beyond line 396)
</file>
```

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "limit": 130,
  "offset": 236
}
```

## Assistant

**Result** (success):
```
<file>
00237|     window.clearTimeout(state.mountRetryTimer);
00238|     state.mountRetryTimer = null;
00239|   }
00240| 
00241|   function scheduleMountRetry() {
00242|     if (state.mountRetryTimer || state.mountRetryCount >= 40 || !isPullDetailPage()) return;
00243|     state.mountRetryTimer = window.setTimeout(() => {
00244|       state.mountRetryTimer = null;
00245|       state.mountRetryCount += 1;
00246|       ensurePanel();
00247|     }, 250);
00248|   }
00249| 
00250|   function findSidebar() {
00251|     const selectors = [
00252|       ".discussion-sidebar",
00253|       ".Layout-sidebar .discussion-sidebar",
00254|       ".Layout-sidebar"
00255|     ];
00256| 
00257|     const seen = new Set();
00258|     const candidates = [];
00259| 
00260|     for (const selector of selectors) {
00261|       document.querySelectorAll(selector).forEach((element) => {
00262|         if (seen.has(element)) return;
00263|         seen.add(element);
00264|         candidates.push(element);
00265|       });
00266|     }
00267| 
00268|     const visible = candidates.find((element) => element.getClientRects().length > 0);
00269|     if (visible) return visible;
00270| 
00271|     if (candidates.length) return candidates[0];
00272| 
00273|     return null;
00274|   }
00275| 
00276|   function findReviewersSection(sidebar) {
00277|     if (!sidebar) return null;
00278|     const byClass = sidebar.querySelector(".discussion-sidebar-item.sidebar-reviewers");
00279|     if (byClass) return byClass;
00280| 
00281|     const headings = sidebar.querySelectorAll(".discussion-sidebar-heading, h2, h3, h4");
00282|     for (const heading of headings) {
00283|       if (heading.textContent.trim().toLowerCase() !== "reviewers") continue;
00284|       const item = heading.closest(
00285|         ".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section"
00286|       );
00287|       if (item) return item;
00288|     }
00289| 
00290|     return null;
00291|   }
00292| 
00293|   function mountPanel(wrapper) {
00294|     const sidebar = findSidebar();
00295|     if (!sidebar) return false;
00296| 
00297|     const reviewersSection = findReviewersSection(sidebar);
00298|     if (reviewersSection) {
00299|       if (reviewersSection.nextElementSibling !== wrapper) {
00300|         reviewersSection.insertAdjacentElement("afterend", wrapper);
00301|       }
00302|       return true;
00303|     }
00304| 
00305|     if (wrapper.parentElement !== sidebar) {
00306|       sidebar.appendChild(wrapper);
00307|     }
00308|     return true;
00309|   }
00310| 
00311|   function ensurePanel() {
00312|     const existing = document.getElementById(PANEL_ID);
00313|     if (!isPullDetailPage()) {
00314|       if (existing) existing.remove();
00315|       clearMountRetry();
00316|       state.mountRetryCount = 0;
00317|       removeBadge();
00318|       return;
00319|     }
00320| 
00321|     ensureStyles();
00322| 
00323|     if (existing) {
00324|       if (!mountPanel(existing)) {
00325|         scheduleMountRetry();
00326|         return;
00327|       }
00328|       clearMountRetry();
00329|       state.mountRetryCount = 0;
00330|       updatePanel(existing);
00331|       return;
00332|     }
00333| 
00334|     const wrapper = document.createElement("div");
00335|     wrapper.id = PANEL_ID;
00336|     wrapper.className = "discussion-sidebar-item";
00337|     wrapper.innerHTML = `
00338|       <div class="md-pr-panel">
00339|         <div class="md-pr-header">
00340|           <h3 class="discussion-sidebar-heading md-pr-heading">Contributor insights</h3>
00341|           <button class="md-pr-gear" type="button" aria-label="Settings">
00342|             <span aria-hidden="true">⚙</span>
00343|           </button>
00344|         </div>
00345|         <div class="md-pr-body">
00346|           <div class="md-pr-summary"></div>
00347|           <div class="md-pr-status"></div>
00348|           <div class="md-pr-details"></div>
00349|         </div>
00350|         <div class="md-pr-settings ${state.config.settingsOpen ? "md-pr-open" : ""}">
00351|           <label for="${PANEL_ID}-api-key">API key</label>
00352|           <input id="${PANEL_ID}-api-key" type="password" data-config="apiKey" />
00353|           <div class="md-pr-status"></div>
00354|         </div>
00355|         <div class="md-pr-powered">Powered by the Open Source Explorer</div>
00356|       </div>
00357|     `;
00358| 
00359|     wrapper.querySelector(".md-pr-gear").addEventListener("click", () => {
00360|       const settings = wrapper.querySelector(".md-pr-settings");
00361|       const open = settings.classList.toggle("md-pr-open");
00362|       saveConfig({ ...state.config, settingsOpen: open });
00363|     });
00364| 
00365|     wrapper.querySelectorAll("[data-config]").forEach((input) => {
00366|       const key = input.getAttribute("data-config");

(File has more lines. Use 'offset' parameter to read beyond line 366)
</file>
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n       #${PANEL_ID}.discussion-sidebar-item {\n         margin-top: 0;\n       }\n+      #${PANEL_ID}.md-pr-fallback {\n+        margin: 16px 0;\n+      }\n       #${PANEL_ID} .md-pr-panel {\n         font-size: 12px;\n         line-height: 1.5;\n       }\n@@\n     }, 250);\n   }\n+\n+  function normalizeText(value) {\n+    return String(value || \"\").replace(/\\s+/g, \" \").trim().toLowerCase();\n+  }\n+\n+  function isVisibleElement(element) {\n+    return Boolean(element && element.isConnected && element.getClientRects().length > 0);\n+  }\n \n   function findSidebar() {\n     const selectors = [\n       \".discussion-sidebar\",\n       \".Layout-sidebar .discussion-sidebar\",\n-      \".Layout-sidebar\"\n+      \".Layout-sidebar\",\n+      \".js-discussion-sidebar\",\n+      \"#partial-discussion-sidebar\",\n+      \"[data-testid*='sidebar']\",\n+      \"aside\"\n     ];\n \n     const seen = new Set();\n     const candidates = [];\n@@\n         candidates.push(element);\n       });\n     }\n \n-    const visible = candidates.find((element) => element.getClientRects().length > 0);\n-    if (visible) return visible;\n+    const scoredVisible = candidates\n+      .filter((element) => isVisibleElement(element))\n+      .map((element) => {\n+        const text = normalizeText(element.textContent);\n+        let score = 0;\n+        if (text.includes(\"reviewers\")) score += 5;\n+        if (text.includes(\"assignees\")) score += 2;\n+        if (normalizeText(element.className).includes(\"sidebar\")) score += 2;\n+        if (element.tagName === \"ASIDE\") score += 1;\n+        return { element, score };\n+      })\n+      .sort((a, b) => b.score - a.score);\n+\n+    if (scoredVisible.length) return scoredVisible[0].element;\n \n     if (candidates.length) return candidates[0];\n \n     return null;\n   }\n \n-  function findReviewersSection(sidebar) {\n-    if (!sidebar) return null;\n-    const byClass = sidebar.querySelector(\".discussion-sidebar-item.sidebar-reviewers\");\n-    if (byClass) return byClass;\n-\n-    const headings = sidebar.querySelectorAll(\".discussion-sidebar-heading, h2, h3, h4\");\n-    for (const heading of headings) {\n-      if (heading.textContent.trim().toLowerCase() !== \"reviewers\") continue;\n-      const item = heading.closest(\n-        \".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section\"\n-      );\n-      if (item) return item;\n+  function findReviewersSection(sidebar) {\n+    const roots = [];\n+    if (sidebar) roots.push(sidebar);\n+    const discoveredSidebar = findSidebar();\n+    if (discoveredSidebar && !roots.includes(discoveredSidebar)) roots.push(discoveredSidebar);\n+    roots.push(document);\n+\n+    for (const root of roots) {\n+      const byClass = root.querySelector(\n+        \".discussion-sidebar-item.sidebar-reviewers, .js-discussion-sidebar-item.sidebar-reviewers\"\n+      );\n+      if (byClass && isVisibleElement(byClass)) return byClass;\n+\n+      const byTestId = root.querySelector(\"[data-testid*='reviewer']\");\n+      if (byTestId && isVisibleElement(byTestId)) {\n+        const item = byTestId.closest(\n+          \".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section, li\"\n+        );\n+        if (item && isVisibleElement(item)) return item;\n+      }\n+\n+      const headings = root.querySelectorAll(\".discussion-sidebar-heading, h2, h3, h4, [role='heading']\");\n+      for (const heading of headings) {\n+        if (normalizeText(heading.textContent) !== \"reviewers\") continue;\n+        const item = heading.closest(\n+          \".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section, li, aside\"\n+        );\n+        if (item && isVisibleElement(item)) return item;\n+      }\n     }\n \n     return null;\n   }\n+\n+  function findFallbackAnchor() {\n+    const selectors = [\n+      \".gh-header-show\",\n+      \".gh-header-meta\",\n+      \".js-pull-discussion-timeline\",\n+      \"main [data-testid='issue-viewer']\",\n+      \"main\"\n+    ];\n+\n+    for (const selector of selectors) {\n+      const element = document.querySelector(selector);\n+      if (element && isVisibleElement(element)) return element;\n+    }\n+\n+    return null;\n+  }\n+\n+  function setWrapperPlacementClass(wrapper, inSidebar) {\n+    if (inSidebar) {\n+      wrapper.classList.add(\"discussion-sidebar-item\");\n+      wrapper.classList.remove(\"md-pr-fallback\");\n+      return;\n+    }\n+\n+    wrapper.classList.remove(\"discussion-sidebar-item\");\n+    wrapper.classList.add(\"md-pr-fallback\");\n+  }\n \n   function mountPanel(wrapper) {\n-    const sidebar = findSidebar();\n-    if (!sidebar) return false;\n-\n-    const reviewersSection = findReviewersSection(sidebar);\n+    const reviewersSection = findReviewersSection();\n     if (reviewersSection) {\n+      setWrapperPlacementClass(wrapper, true);\n       if (reviewersSection.nextElementSibling !== wrapper) {\n         reviewersSection.insertAdjacentElement(\"afterend\", wrapper);\n       }\n       return true;\n     }\n+\n+    const sidebar = findSidebar();\n+    if (sidebar) {\n+      setWrapperPlacementClass(wrapper, true);\n+      if (wrapper.parentElement !== sidebar) {\n+        sidebar.appendChild(wrapper);\n+      }\n+      return true;\n+    }\n \n-    if (wrapper.parentElement !== sidebar) {\n-      sidebar.appendChild(wrapper);\n+    const fallbackAnchor = findFallbackAnchor();\n+    if (fallbackAnchor) {\n+      setWrapperPlacementClass(wrapper, false);\n+      if (fallbackAnchor.nextElementSibling !== wrapper) {\n+        fallbackAnchor.insertAdjacentElement(\"afterend\", wrapper);\n+      }\n+      return true;\n     }\n-    return true;\n+\n+    return false;\n   }\n@@\n     const wrapper = document.createElement(\"div\");\n     wrapper.id = PANEL_ID;\n-    wrapper.className = \"discussion-sidebar-item\";\n     wrapper.innerHTML = `\n       <div class=\"md-pr-panel\">\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js\n@@\n       #${PANEL_ID}.discussion-sidebar-item {\n         margin-top: 0;\n       }\n+      #${PANEL_ID}.md-pr-fallback {\n+        margin: 16px 0;\n+      }\n       #${PANEL_ID} .md-pr-panel {\n         font-size: 12px;\n         line-height: 1.5;\n       }\n@@\n     }, 250);\n   }\n+\n+  function normalizeText(value) {\n+    return String(value || \"\").replace(/\\s+/g, \" \").trim().toLowerCase();\n+  }\n+\n+  function isVisibleElement(element) {\n+    return Boolean(element && element.isConnected && element.getClientRects().length > 0);\n+  }\n \n   function findSidebar() {\n     const selectors = [\n       \".discussion-sidebar\",\n       \".Layout-sidebar .discussion-sidebar\",\n-      \".Layout-sidebar\"\n+      \".Layout-sidebar\",\n+      \".js-discussion-sidebar\",\n+      \"#partial-discussion-sidebar\",\n+      \"[data-testid*='sidebar']\",\n+      \"aside\"\n     ];\n \n     const seen = new Set();\n     const candidates = [];\n@@\n         candidates.push(element);\n       });\n     }\n \n-    const visible = candidates.find((element) => element.getClientRects().length > 0);\n-    if (visible) return visible;\n+    const scoredVisible = candidates\n+      .filter((element) => isVisibleElement(element))\n+      .map((element) => {\n+        const text = normalizeText(element.textContent);\n+        let score = 0;\n+        if (text.includes(\"reviewers\")) score += 5;\n+        if (text.includes(\"assignees\")) score += 2;\n+        if (normalizeText(element.className).includes(\"sidebar\")) score += 2;\n+        if (element.tagName === \"ASIDE\") score += 1;\n+        return { element, score };\n+      })\n+      .sort((a, b) => b.score - a.score);\n+\n+    if (scoredVisible.length) return scoredVisible[0].element;\n \n     if (candidates.length) return candidates[0];\n \n     return null;\n   }\n \n   function findReviewersSection(sidebar) {\n-    if (!sidebar) return null;\n-    const byClass = sidebar.querySelector(\".discussion-sidebar-item.sidebar-reviewers\");\n-    if (byClass) return byClass;\n-\n-    const headings = sidebar.querySelectorAll(\".discussion-sidebar-heading, h2, h3, h4\");\n-    for (const heading of headings) {\n-      if (heading.textContent.trim().toLowerCase() !== \"reviewers\") continue;\n-      const item = heading.closest(\n-        \".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section\"\n-      );\n-      if (item) return item;\n+    const roots = [];\n+    if (sidebar) roots.push(sidebar);\n+    const discoveredSidebar = findSidebar();\n+    if (discoveredSidebar && !roots.includes(discoveredSidebar)) roots.push(discoveredSidebar);\n+    roots.push(document);\n+\n+    for (const root of roots) {\n+      const byClass = root.querySelector(\n+        \".discussion-sidebar-item.sidebar-reviewers, .js-discussion-sidebar-item.sidebar-reviewers\"\n+      );\n+      if (byClass && isVisibleElement(byClass)) return byClass;\n+\n+      const byTestId = root.querySelector(\"[data-testid*='reviewer']\");\n+      if (byTestId && isVisibleElement(byTestId)) {\n+        const item = byTestId.closest(\n+          \".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section, li\"\n+        );\n+        if (item && isVisibleElement(item)) return item;\n+      }\n+\n+      const headings = root.querySelectorAll(\".discussion-sidebar-heading, h2, h3, h4, [role='heading']\");\n+      for (const heading of headings) {\n+        if (normalizeText(heading.textContent) !== \"reviewers\") continue;\n+        const item = heading.closest(\n+          \".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section, li, aside\"\n+        );\n+        if (item && isVisibleElement(item)) return item;\n+      }\n     }\n \n     return null;\n   }\n+\n+  function findFallbackAnchor() {\n+    const selectors = [\n+      \".gh-header-show\",\n+      \".gh-header-meta\",\n+      \".js-pull-discussion-timeline\",\n+      \"main [data-testid='issue-viewer']\",\n+      \"main\"\n+    ];\n+\n+    for (const selector of selectors) {\n+      const element = document.querySelector(selector);\n+      if (element && isVisibleElement(element)) return element;\n+    }\n+\n+    return null;\n+  }\n+\n+  function setWrapperPlacementClass(wrapper, inSidebar) {\n+    if (inSidebar) {\n+      wrapper.classList.add(\"discussion-sidebar-item\");\n+      wrapper.classList.remove(\"md-pr-fallback\");\n+      return;\n+    }\n+\n+    wrapper.classList.remove(\"discussion-sidebar-item\");\n+    wrapper.classList.add(\"md-pr-fallback\");\n+  }\n \n   function mountPanel(wrapper) {\n-    const sidebar = findSidebar();\n-    if (!sidebar) return false;\n-\n-    const reviewersSection = findReviewersSection(sidebar);\n+    const reviewersSection = findReviewersSection();\n     if (reviewersSection) {\n+      setWrapperPlacementClass(wrapper, true);\n       if (reviewersSection.nextElementSibling !== wrapper) {\n         reviewersSection.insertAdjacentElement(\"afterend\", wrapper);\n       }\n       return true;\n     }\n+\n+    const sidebar = findSidebar();\n+    if (sidebar) {\n+      setWrapperPlacementClass(wrapper, true);\n+      if (wrapper.parentElement !== sidebar) {\n+        sidebar.appendChild(wrapper);\n+      }\n+      return true;\n+    }\n \n-    if (wrapper.parentElement !== sidebar) {\n-      sidebar.appendChild(wrapper);\n+    const fallbackAnchor = findFallbackAnchor();\n+    if (fallbackAnchor) {\n+      setWrapperPlacementClass(wrapper, false);\n+      if (fallbackAnchor.nextElementSibling !== wrapper) {\n+        fallbackAnchor.insertAdjacentElement(\"afterend\", wrapper);\n+      }\n+      return true;\n     }\n-    return true;\n+\n+    return false;\n   }\n@@\n     const wrapper = document.createElement(\"div\");\n     wrapper.id = PANEL_ID;\n-    wrapper.className = \"discussion-sidebar-item\";\n     wrapper.innerHTML = `\n       <div class=\"md-pr-panel\">\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M bookmarklet.js
```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check content.js",
  "description": "Syntax check content script"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check bookmarklet.js",
  "description": "Syntax check bookmarklet script"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "pattern": "position:\\s*fixed"
}
```

## Assistant

**Result** (success):
```
No files found
```

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "pattern": "position:\\s*fixed"
}
```

## Assistant

**Result** (success):
```
No files found
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n     const fallbackAnchor = findFallbackAnchor();\n     if (fallbackAnchor) {\n       setWrapperPlacementClass(wrapper, false);\n-      if (fallbackAnchor.nextElementSibling !== wrapper) {\n-        fallbackAnchor.insertAdjacentElement(\"afterend\", wrapper);\n+      if (fallbackAnchor.tagName === \"MAIN\") {\n+        if (wrapper.parentElement !== fallbackAnchor || fallbackAnchor.firstElementChild !== wrapper) {\n+          fallbackAnchor.prepend(wrapper);\n+        }\n+        return true;\n+      }\n+\n+      if (fallbackAnchor.nextElementSibling !== wrapper) {\n+        fallbackAnchor.insertAdjacentElement(\"afterend\", wrapper);\n       }\n       return true;\n     }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js\n@@\n     const fallbackAnchor = findFallbackAnchor();\n     if (fallbackAnchor) {\n       setWrapperPlacementClass(wrapper, false);\n-      if (fallbackAnchor.nextElementSibling !== wrapper) {\n-        fallbackAnchor.insertAdjacentElement(\"afterend\", wrapper);\n+      if (fallbackAnchor.tagName === \"MAIN\") {\n+        if (wrapper.parentElement !== fallbackAnchor || fallbackAnchor.firstElementChild !== wrapper) {\n+          fallbackAnchor.prepend(wrapper);\n+        }\n+        return true;\n+      }\n+\n+      if (fallbackAnchor.nextElementSibling !== wrapper) {\n+        fallbackAnchor.insertAdjacentElement(\"afterend\", wrapper);\n       }\n       return true;\n     }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M bookmarklet.js
```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check content.js",
  "description": "Verify syntax after fallback placement fix"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check bookmarklet.js",
  "description": "Verify bookmarklet syntax after fallback placement fix"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

## Assistant

Thanks — that screenshot was super helpful.  
`sidebar: null` means your GitHub PR view doesn’t use the old `.discussion-sidebar` classes, so the previous selector path missed it.

I just patched this again in both `content.js` and `bookmarklet.js`:

- Finds the **Reviewers** section by text/role/testid (not just old sidebar classes).
- Handles newer/alternate GitHub layouts.
- Keeps retrying while GitHub lazily renders the page.
- Falls back to inline placement in the main PR view if no sidebar exists (still **not** popup style).

Please do this once:

1. Reload extension in `chrome://extensions`
2. Hard refresh PR page (`Cmd+Shift+R`)

If it still doesn’t show, run this in console and send me output:

```js
({
  styleLoaded: !!document.getElementById("md-expert-pr-style"),
  panelMounted: !!document.getElementById("md-expert-pr-panel"),
  reviewersTextNodes: [...document.querySelectorAll("h2,h3,h4,[role='heading']")]
    .filter(n => (n.textContent || "").trim().toLowerCase() === "reviewers")
    .length
})
```

## User

great. now just drop the "Github" and "market.dev" links 

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "pattern": "md-pr-links|Market.dev|GitHub"
}
```

## Assistant

**Result** (success):
```
Found 4 matches
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js:
  Line 172:       #${PANEL_ID} .md-pr-links {
  Line 666:             <div class="md-pr-links">
  Line 667:               <a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">GitHub</a>
  Line 668:               <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Market.dev</a>
```

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "pattern": "md-pr-links|Market.dev|GitHub"
}
```

## Assistant

**Result** (success):
```
Found 4 matches
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js:
  Line 150:       #${PANEL_ID} .md-pr-links {
  Line 623:             <div class="md-pr-links">
  Line 624:               <a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">GitHub</a>
  Line 625:               <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Market.dev</a>
```

## Assistant

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 50,
  "offset": 640
}
```

## Assistant

**Result** (success):
```
<file>
00641|     }).filter(Boolean);
00642| 
00643|     const ecosystems =
00644|       (Array.isArray(info.ecosystems) && info.ecosystems) ||
00645|       (Array.isArray(info.ecosystem_names) && info.ecosystem_names) ||
00646|       [];
00647| 
00648|     const ecosystemNames = ecosystems
00649|       .map((eco) => (typeof eco === "string" ? eco : eco.name))
00650|       .filter(Boolean)
00651|       .slice(0, 8)
00652|       .map((name) => ({
00653|         name,
00654|         url: `https://explore.market.dev/ecosystems/${encodeURIComponent(name)}`
00655|       }));
00656| 
00657|     return `
00658|       <div class="md-pr-card">
00659|         <div class="md-pr-card-header">
00660|           <div class="md-pr-avatar">
00661|             ${avatarUrl ? `<img src="${avatarUrl}" alt="${name}" />` : name.slice(0, 1).toUpperCase()}
00662|           </div>
00663|           <div>
00664|             <div class="md-pr-name"><a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">${name}</a></div>
00665|             <div class="md-pr-meta">@${username}${location ? ` · ${location}` : ""}</div>
00666|             <div class="md-pr-links">
00667|               <a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">GitHub</a>
00668|               <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Market.dev</a>
00669|             </div>
00670|           </div>
00671|         </div>
00672|         ${stats.length ? `
00673|           <div class="md-pr-stats">
00674|             ${stats
00675|               .map(
00676|                 (stat) => `<span class="md-pr-stat-item"><span class="md-pr-stat-label">${stat.label}:</span> ${stat.value}</span>`
00677|               )
00678|               .join('<span class="md-pr-stat-sep">·</span>')}
00679|           </div>
00680|         ` : ""}
00681|         ${ecosystemNames.length ? `
00682|           <div class="md-pr-section">
00683|             <div class="md-pr-section-title">Ecosystems</div>
00684|             <div class="md-pr-ecosystems">
00685|               ${ecosystemNames
00686|                 .map((eco) => `<a class="md-pr-ecosystem-pill" href="${eco.url}" target="_blank" rel="noopener noreferrer">${eco.name}</a>`)
00687|                 .join("")}
00688|             </div>
00689|           </div>
00690|         ` : ""}

(File has more lines. Use 'offset' parameter to read beyond line 690)
</file>
```

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "limit": 50,
  "offset": 600
}
```

## Assistant

**Result** (success):
```
<file>
00601|       (Array.isArray(info.ecosystems) && info.ecosystems) ||
00602|       (Array.isArray(info.ecosystem_names) && info.ecosystem_names) ||
00603|       [];
00604| 
00605|     const ecosystemNames = ecosystems
00606|       .map((eco) => (typeof eco === "string" ? eco : eco.name))
00607|       .filter(Boolean)
00608|       .slice(0, 8)
00609|       .map((name) => ({
00610|         name,
00611|         url: `https://explore.market.dev/ecosystems/${encodeURIComponent(name)}`
00612|       }));
00613| 
00614|     return `
00615|       <div class="md-pr-card">
00616|         <div class="md-pr-card-header">
00617|           <div class="md-pr-avatar">
00618|             ${avatarUrl ? `<img src="${avatarUrl}" alt="${name}" />` : name.slice(0, 1).toUpperCase()}
00619|           </div>
00620|           <div>
00621|             <div class="md-pr-name"><a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">${name}</a></div>
00622|             <div class="md-pr-meta">@${username}${location ? ` · ${location}` : ""}</div>
00623|             <div class="md-pr-links">
00624|               <a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">GitHub</a>
00625|               <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Market.dev</a>
00626|             </div>
00627|           </div>
00628|         </div>
00629|         ${stats.length ? `
00630|           <div class="md-pr-stats">
00631|             ${stats
00632|               .map(
00633|                 (stat) => `<span class="md-pr-stat-item"><span class="md-pr-stat-label">${stat.label}:</span> ${stat.value}</span>`
00634|               )
00635|               .join('<span class="md-pr-stat-sep">·</span>')}
00636|           </div>
00637|         ` : ""}
00638|         ${ecosystemNames.length ? `
00639|           <div class="md-pr-section">
00640|             <div class="md-pr-section-title">Ecosystems</div>
00641|             <div class="md-pr-ecosystems">
00642|               ${ecosystemNames
00643|                 .map((eco) => `<a class="md-pr-ecosystem-pill" href="${eco.url}" target="_blank" rel="noopener noreferrer">${eco.name}</a>`)
00644|                 .join("")}
00645|             </div>
00646|           </div>
00647|         ` : ""}
00648|         ${maintainerItems.length ? `
00649|           <div class="md-pr-section">
00650|             <div class="md-pr-section-title">Projects</div>

(File has more lines. Use 'offset' parameter to read beyond line 650)
</file>
```

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 30,
  "offset": 156
}
```

## Assistant

**Result** (success):
```
<file>
00157|         flex-shrink: 0;
00158|       }
00159|       #${PANEL_ID} .md-pr-avatar img {
00160|         width: 100%;
00161|         height: 100%;
00162|         object-fit: cover;
00163|       }
00164|       #${PANEL_ID} .md-pr-name {
00165|         font-size: 13px;
00166|         font-weight: 600;
00167|         color: var(--fgColor-default, #24292f);
00168|       }
00169|       #${PANEL_ID} .md-pr-meta {
00170|         color: var(--fgColor-muted, #57606a);
00171|       }
00172|       #${PANEL_ID} .md-pr-links {
00173|         margin-top: 2px;
00174|         display: flex;
00175|         gap: 8px;
00176|       }
00177|       #${PANEL_ID} .md-pr-link {
00178|         color: var(--fgColor-accent, #0969da);
00179|         text-decoration: none;
00180|       }
00181|       #${PANEL_ID} .md-pr-link:hover {
00182|         text-decoration: underline;
00183|       }
00184|       #${PANEL_ID} .md-pr-stats {
00185|         margin-top: 8px;
00186|       }

(File has more lines. Use 'offset' parameter to read beyond line 186)
</file>
```

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "limit": 30,
  "offset": 134
}
```

## Assistant

**Result** (success):
```
<file>
00135|         flex-shrink: 0;
00136|       }
00137|       #${PANEL_ID} .md-pr-avatar img {
00138|         width: 100%;
00139|         height: 100%;
00140|         object-fit: cover;
00141|       }
00142|       #${PANEL_ID} .md-pr-name {
00143|         font-size: 13px;
00144|         font-weight: 600;
00145|         color: var(--fgColor-default, #24292f);
00146|       }
00147|       #${PANEL_ID} .md-pr-meta {
00148|         color: var(--fgColor-muted, #57606a);
00149|       }
00150|       #${PANEL_ID} .md-pr-links {
00151|         margin-top: 2px;
00152|         display: flex;
00153|         gap: 8px;
00154|       }
00155|       #${PANEL_ID} .md-pr-link {
00156|         color: var(--fgColor-accent, #0969da);
00157|         text-decoration: none;
00158|       }
00159|       #${PANEL_ID} .md-pr-link:hover {
00160|         text-decoration: underline;
00161|       }
00162|       #${PANEL_ID} .md-pr-stats {
00163|         margin-top: 8px;
00164|       }

(File has more lines. Use 'offset' parameter to read beyond line 164)
</file>
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n       #${PANEL_ID} .md-pr-meta {\n         color: var(--fgColor-muted, #57606a);\n       }\n-      #${PANEL_ID} .md-pr-links {\n-        margin-top: 2px;\n-        display: flex;\n-        gap: 8px;\n-      }\n       #${PANEL_ID} .md-pr-link {\n         color: var(--fgColor-accent, #0969da);\n         text-decoration: none;\n       }\n@@\n           <div>\n             <div class=\"md-pr-name\"><a class=\"md-pr-link\" href=\"https://github.com/${encodeURIComponent(username)}\" target=\"_blank\" rel=\"noopener noreferrer\">${name}</a></div>\n             <div class=\"md-pr-meta\">@${username}${location ? ` · ${location}` : \"\"}</div>\n-            <div class=\"md-pr-links\">\n-              <a class=\"md-pr-link\" href=\"https://github.com/${encodeURIComponent(username)}\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub</a>\n-              <a class=\"md-pr-link\" href=\"${profileUrl}\" target=\"_blank\" rel=\"noopener noreferrer\">Market.dev</a>\n-            </div>\n           </div>\n         </div>\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js\n@@\n       #${PANEL_ID} .md-pr-meta {\n         color: var(--fgColor-muted, #57606a);\n       }\n-      #${PANEL_ID} .md-pr-links {\n-        margin-top: 2px;\n-        display: flex;\n-        gap: 8px;\n-      }\n       #${PANEL_ID} .md-pr-link {\n         color: var(--fgColor-accent, #0969da);\n         text-decoration: none;\n       }\n@@\n           <div>\n             <div class=\"md-pr-name\"><a class=\"md-pr-link\" href=\"https://github.com/${encodeURIComponent(username)}\" target=\"_blank\" rel=\"noopener noreferrer\">${name}</a></div>\n             <div class=\"md-pr-meta\">@${username}${location ? ` · ${location}` : \"\"}</div>\n-            <div class=\"md-pr-links\">\n-              <a class=\"md-pr-link\" href=\"https://github.com/${encodeURIComponent(username)}\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub</a>\n-              <a class=\"md-pr-link\" href=\"${profileUrl}\" target=\"_blank\" rel=\"noopener noreferrer\">Market.dev</a>\n-            </div>\n           </div>\n         </div>\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M bookmarklet.js
```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check bookmarklet.js",
  "description": "Validate bookmarklet syntax after link removal"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check content.js",
  "description": "Validate content script syntax after link removal"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "pattern": ">GitHub<|>Market.dev<"
}
```

## Assistant

**Result** (success):
```
No files found
```

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "pattern": ">GitHub<|>Market.dev<"
}
```

## Assistant

**Result** (success):
```
No files found
```

## Assistant

Done — I removed those two links from the contributor card in both places:

- `content.js`
- `bookmarklet.js`

Specifically, the `GitHub` and `Market.dev` link row is gone now (and related row styling removed).  
I also rechecked syntax for both files.

If you want, I can also make the contributor name non-clickable too.

## Assistant

## User

also remove browse directory

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n     if (result.state === \"not-expert\") {\n       statusBlocks.forEach((status) => {\n         status.innerHTML = \"\";\n       });\n       summary.textContent = \"No contributor profile found yet.\";\n-      details.innerHTML = `<a class=\"md-pr-link\" href=\"https://explore.market.dev\" target=\"_blank\" rel=\"noopener noreferrer\">Browse directory</a>`;\n+      details.textContent = \"\";\n       return;\n     }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js\n@@\n     if (result.state === \"not-expert\") {\n       statusBlocks.forEach((status) => {\n         status.innerHTML = \"\";\n       });\n       summary.textContent = \"No contributor profile found yet.\";\n-      details.innerHTML = `<a class=\"md-pr-link\" href=\"https://explore.market.dev\" target=\"_blank\" rel=\"noopener noreferrer\">Browse directory</a>`;\n+      details.textContent = \"\";\n       return;\n     }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M bookmarklet.js
```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check content.js",
  "description": "Validate content script after removing browse link"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check bookmarklet.js",
  "description": "Validate bookmarklet after removing browse link"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

Done — removed “Browse directory” in both files.

- Updated `content.js` and `bookmarklet.js` so the not-found state now just shows:
  - `No contributor profile found yet.`
  - no extra link below it

Syntax checks still pass for both files.

## User

pls commit and push

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git status --short",
  "description": "Show modified and untracked files"
}
```

## Assistant

**Result** (success):
```
 M bookmarklet.js
 M content.js

```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git diff",
  "description": "Show unstaged working tree changes"
}
```

## Assistant

**Result** (success):
```
diff --git a/bookmarklet.js b/bookmarklet.js
index b264bbb..51a15a5 100644
--- a/bookmarklet.js
+++ b/bookmarklet.js
@@ -14,7 +14,9 @@
 
   const state = {
     config: loadConfig(),
-    currentResult: null
+    currentResult: null,
+    mountRetryTimer: null,
+    mountRetryCount: 0
   };
 
   function loadConfig() {
@@ -43,116 +45,94 @@
     style.id = STYLE_ID;
     style.textContent = `
       #${PANEL_ID} {
-        position: fixed;
-        right: 16px;
-        bottom: 16px;
-        z-index: 999999;
-        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
-        color: #1f2328;
+        color: var(--fgColor-default, #24292f);
+      }
+      #${PANEL_ID}.discussion-sidebar-item {
+        margin-top: 0;
+      }
+      #${PANEL_ID}.md-pr-fallback {
+        margin: 16px 0;
       }
       #${PANEL_ID} .md-pr-panel {
-        width: 440px;
-        background: #ffffff;
-        border: 1px solid #d0d7de;
-        border-radius: 12px;
-        box-shadow: 0 1px 3px rgba(27, 31, 36, 0.12);
-        padding: 12px 12px 10px;
-        font-size: 14px;
+        font-size: 12px;
+        line-height: 1.5;
       }
       #${PANEL_ID} .md-pr-header {
         display: flex;
-        justify-content: flex-end;
+        justify-content: space-between;
         align-items: center;
-        gap: 8px;
-        font-weight: 600;
-        font-size: 13px;
+        margin-bottom: 6px;
+      }
+      #${PANEL_ID} .md-pr-heading {
+        margin: 0;
       }
       #${PANEL_ID} .md-pr-gear {
         border: none;
-        background: #f6f8fa;
-        border-radius: 6px;
-        width: 28px;
-        height: 28px;
+        background: transparent;
+        color: var(--fgColor-muted, #57606a);
+        width: 20px;
+        height: 20px;
+        padding: 0;
         display: inline-flex;
         align-items: center;
         justify-content: center;
         cursor: pointer;
-        border: 1px solid #d0d7de;
-        color: #57606a;
       }
-      #${PANEL_ID} .md-pr-body {
-        margin-top: 10px;
+      #${PANEL_ID} .md-pr-gear:hover {
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-settings {
         display: none;
-        margin-top: 10px;
-        border-top: 1px dashed #d0d7de;
-        padding-top: 10px;
+        margin-top: 8px;
       }
       #${PANEL_ID} .md-pr-settings.md-pr-open {
         display: block;
       }
-      #${PANEL_ID} label {
+      #${PANEL_ID} .md-pr-settings label {
         display: block;
-        margin-bottom: 6px;
-        font-weight: 600;
+        margin-bottom: 4px;
         font-size: 12px;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
       }
-      #${PANEL_ID} input[type="text"],
-      #${PANEL_ID} input[type="password"] {
+      #${PANEL_ID} .md-pr-settings input[type="password"] {
         width: 100%;
-        border: 1px solid #d0d7de;
+        border: 1px solid var(--borderColor-default, #d0d7de);
         border-radius: 6px;
-        padding: 6px 8px;
-        font-size: 14px;
-        background: #ffffff;
-        margin-bottom: 8px;
+        padding: 5px 8px;
+        font-size: 12px;
+        color: var(--fgColor-default, #24292f);
+        background: var(--bgColor-default, #ffffff);
       }
       #${PANEL_ID} .md-pr-status {
-        margin-top: 8px;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-warning {
-        color: #cf222e;
-        font-weight: 600;
-      }
-      #${PANEL_ID} .md-pr-success {
-        color: #1a7f37;
-        font-weight: 600;
+        color: var(--fgColor-danger, #cf222e);
       }
       #${PANEL_ID} .md-pr-details {
-        margin-top: 6px;
-        color: #24292f;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-summary {
-        margin-top: 6px;
-        font-size: 18px;
-        color: #24292f;
-        font-weight: 600;
-      }
-      #${PANEL_ID} .md-pr-card {
-        border: 1px solid #d0d7de;
-        border-radius: 10px;
-        padding: 12px;
+        margin-bottom: 8px;
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-card-header {
         display: flex;
-        gap: 12px;
-        align-items: center;
+        gap: 8px;
+        align-items: flex-start;
       }
       #${PANEL_ID} .md-pr-avatar {
-        width: 56px;
-        height: 56px;
+        width: 32px;
+        height: 32px;
         border-radius: 50%;
-        background: #f6f8fa;
-        border: 1px solid #d0d7de;
         overflow: hidden;
+        background: var(--bgColor-muted, #f6f8fa);
         display: inline-flex;
         align-items: center;
         justify-content: center;
         font-weight: 600;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
+        flex-shrink: 0;
       }
       #${PANEL_ID} .md-pr-avatar img {
         width: 100%;
@@ -160,144 +140,73 @@
         object-fit: cover;
       }
       #${PANEL_ID} .md-pr-name {
-        font-size: 18px;
-        font-weight: 700;
-        color: #1a7f37;
+        font-size: 13px;
+        font-weight: 600;
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-meta {
-        margin-top: 6px;
-        color: #57606a;
-        font-size: 14px;
-      }
-      #${PANEL_ID} .md-pr-links {
-        margin-top: 6px;
-        display: flex;
-        gap: 12px;
-        font-size: 14px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-link {
-        color: #0969da;
-        font-weight: 600;
+        color: var(--fgColor-accent, #0969da);
+        text-decoration: none;
       }
-      #${PANEL_ID} .md-pr-stats {
-        margin-top: 12px;
-        border: 1px solid #d0d7de;
-        border-radius: 8px;
-        overflow: hidden;
+      #${PANEL_ID} .md-pr-link:hover {
+        text-decoration: underline;
       }
-      #${PANEL_ID} .md-pr-stat-row {
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        padding: 8px 10px;
-        border-bottom: 1px solid #d0d7de;
-        font-size: 14px;
+      #${PANEL_ID} .md-pr-stats {
+        margin-top: 8px;
       }
-      #${PANEL_ID} .md-pr-stat-row:last-child {
-        border-bottom: none;
+      #${PANEL_ID} .md-pr-stat-item {
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-stat-label {
-        color: #57606a;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        font-weight: 600;
-        font-size: 11px;
+        color: var(--fgColor-muted, #57606a);
       }
-      #${PANEL_ID} .md-pr-stat-value {
-        font-weight: 700;
-        color: #24292f;
+      #${PANEL_ID} .md-pr-stat-sep {
+        margin: 0 4px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-section {
-        margin-top: 12px;
+        margin-top: 8px;
       }
       #${PANEL_ID} .md-pr-section-title {
-        font-size: 13px;
+        margin-bottom: 2px;
         font-weight: 600;
-        color: #57606a;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        margin-bottom: 6px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-ecosystems {
         display: flex;
         flex-wrap: wrap;
-        gap: 6px;
+        gap: 8px;
       }
       #${PANEL_ID} .md-pr-ecosystem-pill {
-        display: inline-flex;
-        align-items: center;
-        background: #f6f8fa;
-        border: 1px solid #d0d7de;
-        border-radius: 999px;
-        padding: 2px 8px;
-        font-size: 13px;
-        color: #57606a;
+        color: var(--fgColor-accent, #0969da);
         text-decoration: none;
       }
+      #${PANEL_ID} .md-pr-ecosystem-pill:hover {
+        text-decoration: underline;
+      }
       #${PANEL_ID} .md-pr-project-list {
         display: flex;
         flex-direction: column;
-        gap: 6px;
+        gap: 2px;
       }
       #${PANEL_ID} .md-pr-project-item {
         display: flex;
+        align-items: baseline;
         justify-content: space-between;
         gap: 8px;
-        font-size: 14px;
-        color: #24292f;
       }
       #${PANEL_ID} .md-pr-project-meta {
-        color: #57606a;
-        font-size: 13px;
+        color: var(--fgColor-muted, #57606a);
+        flex-shrink: 0;
       }
-      #${PANEL_ID} .md-pr-section {
+      #${PANEL_ID} .md-pr-powered {
         margin-top: 8px;
-      }
-      #${PANEL_ID} .md-pr-section-title {
         font-size: 11px;
-        font-weight: 600;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        color: #6b7280;
-        margin-bottom: 4px;
-      }
-      #${PANEL_ID} .md-pr-stats {
-        display: grid;
-        grid-template-columns: repeat(3, minmax(0, 1fr));
-        gap: 6px;
-      }
-      #${PANEL_ID} .md-pr-stat {
-        background: #ffffff;
-        border: 1px solid #e5e7eb;
-        border-radius: 8px;
-        padding: 6px;
-        text-align: center;
-      }
-      #${PANEL_ID} .md-pr-stat-label {
-        font-size: 10px;
-        text-transform: uppercase;
-        letter-spacing: 0.05em;
-        color: #6b7280;
-      }
-      #${PANEL_ID} .md-pr-stat-value {
-        font-size: 13px;
-        font-weight: 600;
-        color: #111827;
-      }
-      #${PANEL_ID} .md-pr-pill {
-        display: inline-flex;
-        align-items: center;
-        padding: 2px 6px;
-        border-radius: 999px;
-        background: #eef2ff;
-        color: #3730a3;
-        font-size: 11px;
-        margin-right: 4px;
-        margin-bottom: 4px;
-      }
-      #${PANEL_ID} .md-pr-link {
-        color: #0a3069;
-        font-weight: 600;
+        color: var(--fgColor-muted, #57606a);
+        opacity: 0.65;
       }
       #${BADGE_ID} {
         display: inline-flex;
@@ -321,10 +230,177 @@
     document.head.appendChild(style);
   }
 
+  function clearMountRetry() {
+    if (!state.mountRetryTimer) return;
+    window.clearTimeout(state.mountRetryTimer);
+    state.mountRetryTimer = null;
+  }
+
+  function scheduleMountRetry() {
+    if (state.mountRetryTimer || state.mountRetryCount >= 40 || !isPullDetailPage()) return;
+    state.mountRetryTimer = window.setTimeout(() => {
+      state.mountRetryTimer = null;
+      state.mountRetryCount += 1;
+      ensurePanel();
+    }, 250);
+  }
+
+  function normalizeText(value) {
+    return String(value || "").replace(/\s+/g, " ").trim().toLowerCase();
+  }
+
+  function isVisibleElement(element) {
+    return Boolean(element && element.isConnected && element.getClientRects().length > 0);
+  }
+
+  function findSidebar() {
+    const selectors = [
+      ".discussion-sidebar",
+      ".Layout-sidebar .discussion-sidebar",
+      ".Layout-sidebar",
+      ".js-discussion-sidebar",
+      "#partial-discussion-sidebar",
+      "[data-testid*='sidebar']",
+      "aside"
+    ];
+
+    const seen = new Set();
+    const candidates = [];
+
+    for (const selector of selectors) {
+      document.querySelectorAll(selector).forEach((element) => {
+        if (seen.has(element)) return;
+        seen.add(element);
+        candidates.push(element);
+      });
+    }
+
+    const scoredVisible = candidates
+      .filter((element) => isVisibleElement(element))
+      .map((element) => {
+        const text = normalizeText(element.textContent);
+        let score = 0;
+        if (text.includes("reviewers")) score += 5;
+        if (text.includes("assignees")) score += 2;
+        if (normalizeText(element.className).includes("sidebar")) score += 2;
+        if (element.tagName === "ASIDE") score += 1;
+        return { element, score };
+      })
+      .sort((a, b) => b.score - a.score);
+
+    if (scoredVisible.length) return scoredVisible[0].element;
+
+    if (candidates.length) return candidates[0];
+
+    return null;
+  }
+
+  function findReviewersSection(sidebar) {
+    const roots = [];
+    if (sidebar) roots.push(sidebar);
+    const discoveredSidebar = findSidebar();
+    if (discoveredSidebar && !roots.includes(discoveredSidebar)) roots.push(discoveredSidebar);
+    roots.push(document);
+
+    for (const root of roots) {
+      const byClass = root.querySelector(
+        ".discussion-sidebar-item.sidebar-reviewers, .js-discussion-sidebar-item.sidebar-reviewers"
+      );
+      if (byClass && isVisibleElement(byClass)) return byClass;
+
+      const byTestId = root.querySelector("[data-testid*='reviewer']");
+      if (byTestId && isVisibleElement(byTestId)) {
+        const item = byTestId.closest(
+          ".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section, li"
+        );
+        if (item && isVisibleElement(item)) return item;
+      }
+
+      const headings = root.querySelectorAll(".discussion-sidebar-heading, h2, h3, h4, [role='heading']");
+      for (const heading of headings) {
+        if (normalizeText(heading.textContent) !== "reviewers") continue;
+        const item = heading.closest(
+          ".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section, li, aside"
+        );
+        if (item && isVisibleElement(item)) return item;
+      }
+    }
+
+    return null;
+  }
+
+  function findFallbackAnchor() {
+    const selectors = [
+      ".gh-header-show",
+      ".gh-header-meta",
+      ".js-pull-discussion-timeline",
+      "main [data-testid='issue-viewer']",
+      "main"
+    ];
+
+    for (const selector of selectors) {
+      const element = document.querySelector(selector);
+      if (element && isVisibleElement(element)) return element;
+    }
+
+    return null;
+  }
+
+  function setWrapperPlacementClass(wrapper, inSidebar) {
+    if (inSidebar) {
+      wrapper.classList.add("discussion-sidebar-item");
+      wrapper.classList.remove("md-pr-fallback");
+      return;
+    }
+
+    wrapper.classList.remove("discussion-sidebar-item");
+    wrapper.classList.add("md-pr-fallback");
+  }
+
+  function mountPanel(wrapper) {
+    const reviewersSection = findReviewersSection();
+    if (reviewersSection) {
+      setWrapperPlacementClass(wrapper, true);
+      if (reviewersSection.nextElementSibling !== wrapper) {
+        reviewersSection.insertAdjacentElement("afterend", wrapper);
+      }
+      return true;
+    }
+
+    const sidebar = findSidebar();
+    if (sidebar) {
+      setWrapperPlacementClass(wrapper, true);
+      if (wrapper.parentElement !== sidebar) {
+        sidebar.appendChild(wrapper);
+      }
+      return true;
+    }
+
+    const fallbackAnchor = findFallbackAnchor();
+    if (fallbackAnchor) {
+      setWrapperPlacementClass(wrapper, false);
+      if (fallbackAnchor.tagName === "MAIN") {
+        if (wrapper.parentElement !== fallbackAnchor || fallbackAnchor.firstElementChild !== wrapper) {
+          fallbackAnchor.prepend(wrapper);
+        }
+        return true;
+      }
+
+      if (fallbackAnchor.nextElementSibling !== wrapper) {
+        fallbackAnchor.insertAdjacentElement("afterend", wrapper);
+      }
+      return true;
+    }
+
+    return false;
+  }
+
   function ensurePanel() {
     const existing = document.getElementById(PANEL_ID);
     if (!isPullDetailPage()) {
       if (existing) existing.remove();
+      clearMountRetry();
+      state.mountRetryCount = 0;
       removeBadge();
       return;
     }
@@ -332,6 +408,12 @@
     ensureStyles();
 
     if (existing) {
+      if (!mountPanel(existing)) {
+        scheduleMountRetry();
+        return;
+      }
+      clearMountRetry();
+      state.mountRetryCount = 0;
       updatePanel(existing);
       return;
     }
@@ -341,7 +423,7 @@
     wrapper.innerHTML = `
       <div class="md-pr-panel">
         <div class="md-pr-header">
-          <span></span>
+          <h3 class="discussion-sidebar-heading md-pr-heading">Contributor insights</h3>
           <button class="md-pr-gear" type="button" aria-label="Settings">
             <span aria-hidden="true">⚙</span>
           </button>
@@ -352,10 +434,11 @@
           <div class="md-pr-details"></div>
         </div>
         <div class="md-pr-settings ${state.config.settingsOpen ? "md-pr-open" : ""}">
-          <label>API key</label>
-          <input type="password" data-config="apiKey" />
+          <label for="${PANEL_ID}-api-key">API key</label>
+          <input id="${PANEL_ID}-api-key" type="password" data-config="apiKey" />
           <div class="md-pr-status"></div>
         </div>
+        <div class="md-pr-powered">Powered by the Open Source Explorer</div>
       </div>
     `;
 
@@ -374,7 +457,14 @@
       });
     });
 
-    document.body.appendChild(wrapper);
+    if (!mountPanel(wrapper)) {
+      scheduleMountRetry();
+      return;
+    }
+
+    clearMountRetry();
+    state.mountRetryCount = 0;
+
     updatePanel(wrapper);
   }
 
@@ -420,8 +510,8 @@
       statusBlocks.forEach((status) => {
         status.innerHTML = "";
       });
-      summary.innerHTML = `No profile found on the Open Source Explorer. <a class="md-pr-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Explore</a>`;
-      details.innerHTML = "";
+      summary.textContent = "No contributor profile found yet.";
+      details.textContent = "";
       return;
     }
 
@@ -523,26 +613,17 @@
             ${avatarUrl ? `<img src="${avatarUrl}" alt="${name}" />` : name.slice(0, 1).toUpperCase()}
           </div>
           <div>
-            <div class="md-pr-name">${name}</div>
+            <div class="md-pr-name"><a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">${name}</a></div>
             <div class="md-pr-meta">@${username}${location ? ` · ${location}` : ""}</div>
-            <div class="md-pr-links">
-              <a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">GitHub</a>
-              <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Explore</a>
-            </div>
           </div>
         </div>
         ${stats.length ? `
           <div class="md-pr-stats">
             ${stats
               .map(
-                (stat) => `
-                  <div class="md-pr-stat-row">
-                    <span class="md-pr-stat-label">${stat.label}</span>
-                    <span class="md-pr-stat-value">${stat.value}</span>
-                  </div>
-                `
+                (stat) => `<span class="md-pr-stat-item"><span class="md-pr-stat-label">${stat.label}:</span> ${stat.value}</span>`
               )
-              .join("")}
+              .join('<span class="md-pr-stat-sep">·</span>')}
           </div>
         ` : ""}
         ${ecosystemNames.length ? `
@@ -676,9 +757,3 @@
     init();
   }
 })();
-      #${PANEL_ID} .md-pr-summary {
-        margin-top: 6px;
-        font-size: 13px;
-        color: #111827;
-        font-weight: 600;
-      }
diff --git a/content.js b/content.js
index 6c186a7..036a794 100644
--- a/content.js
+++ b/content.js
@@ -12,7 +12,9 @@
   const state = {
     config: loadConfig(),
     currentResult: null,
-    listCache: new Map()
+    listCache: new Map(),
+    mountRetryTimer: null,
+    mountRetryCount: 0
   };
 
   function loadConfig() {
@@ -65,116 +67,94 @@
     style.id = STYLE_ID;
     style.textContent = `
       #${PANEL_ID} {
-        position: fixed;
-        right: 16px;
-        bottom: 16px;
-        z-index: 999999;
-        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
-        color: #1f2328;
+        color: var(--fgColor-default, #24292f);
+      }
+      #${PANEL_ID}.discussion-sidebar-item {
+        margin-top: 0;
+      }
+      #${PANEL_ID}.md-pr-fallback {
+        margin: 16px 0;
       }
       #${PANEL_ID} .md-pr-panel {
-        width: 440px;
-        background: #ffffff;
-        border: 1px solid #d0d7de;
-        border-radius: 12px;
-        box-shadow: 0 1px 3px rgba(27, 31, 36, 0.12);
-        padding: 12px 12px 10px;
-        font-size: 14px;
+        font-size: 12px;
+        line-height: 1.5;
       }
       #${PANEL_ID} .md-pr-header {
         display: flex;
-        justify-content: flex-end;
+        justify-content: space-between;
         align-items: center;
-        gap: 8px;
-        font-weight: 600;
-        font-size: 13px;
+        margin-bottom: 6px;
+      }
+      #${PANEL_ID} .md-pr-heading {
+        margin: 0;
       }
       #${PANEL_ID} .md-pr-gear {
         border: none;
-        background: #f6f8fa;
-        border-radius: 6px;
-        width: 28px;
-        height: 28px;
+        background: transparent;
+        color: var(--fgColor-muted, #57606a);
+        width: 20px;
+        height: 20px;
+        padding: 0;
         display: inline-flex;
         align-items: center;
         justify-content: center;
         cursor: pointer;
-        border: 1px solid #d0d7de;
-        color: #57606a;
       }
-      #${PANEL_ID} .md-pr-body {
-        margin-top: 10px;
+      #${PANEL_ID} .md-pr-gear:hover {
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-settings {
         display: none;
-        margin-top: 10px;
-        border-top: 1px dashed #d0d7de;
-        padding-top: 10px;
+        margin-top: 8px;
       }
       #${PANEL_ID} .md-pr-settings.md-pr-open {
         display: block;
       }
-      #${PANEL_ID} label {
+      #${PANEL_ID} .md-pr-settings label {
         display: block;
-        margin-bottom: 6px;
-        font-weight: 600;
+        margin-bottom: 4px;
         font-size: 12px;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
       }
-      #${PANEL_ID} input[type="text"],
-      #${PANEL_ID} input[type="password"] {
+      #${PANEL_ID} .md-pr-settings input[type="password"] {
         width: 100%;
-        border: 1px solid #d0d7de;
+        border: 1px solid var(--borderColor-default, #d0d7de);
         border-radius: 6px;
-        padding: 6px 8px;
-        font-size: 14px;
-        background: #ffffff;
-        margin-bottom: 8px;
+        padding: 5px 8px;
+        font-size: 12px;
+        color: var(--fgColor-default, #24292f);
+        background: var(--bgColor-default, #ffffff);
       }
       #${PANEL_ID} .md-pr-status {
-        margin-top: 8px;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-warning {
-        color: #cf222e;
-        font-weight: 600;
-      }
-      #${PANEL_ID} .md-pr-success {
-        color: #1a7f37;
-        font-weight: 600;
+        color: var(--fgColor-danger, #cf222e);
       }
       #${PANEL_ID} .md-pr-details {
-        margin-top: 6px;
-        color: #24292f;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-summary {
-        margin-top: 6px;
-        font-size: 18px;
-        color: #24292f;
-        font-weight: 600;
-      }
-      #${PANEL_ID} .md-pr-card {
-        border: 1px solid #d0d7de;
-        border-radius: 10px;
-        padding: 12px;
+        margin-bottom: 8px;
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-card-header {
         display: flex;
-        gap: 12px;
-        align-items: center;
+        gap: 8px;
+        align-items: flex-start;
       }
       #${PANEL_ID} .md-pr-avatar {
-        width: 56px;
-        height: 56px;
+        width: 32px;
+        height: 32px;
         border-radius: 50%;
-        background: #f6f8fa;
-        border: 1px solid #d0d7de;
         overflow: hidden;
+        background: var(--bgColor-muted, #f6f8fa);
         display: inline-flex;
         align-items: center;
         justify-content: center;
         font-weight: 600;
-        color: #57606a;
+        color: var(--fgColor-muted, #57606a);
+        flex-shrink: 0;
       }
       #${PANEL_ID} .md-pr-avatar img {
         width: 100%;
@@ -182,95 +162,73 @@
         object-fit: cover;
       }
       #${PANEL_ID} .md-pr-name {
-        font-size: 18px;
-        font-weight: 700;
-        color: #1a7f37;
+        font-size: 13px;
+        font-weight: 600;
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-meta {
-        margin-top: 6px;
-        color: #57606a;
-        font-size: 14px;
-      }
-      #${PANEL_ID} .md-pr-links {
-        margin-top: 6px;
-        display: flex;
-        gap: 12px;
-        font-size: 14px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-link {
-        color: #0969da;
-        font-weight: 600;
+        color: var(--fgColor-accent, #0969da);
+        text-decoration: none;
       }
-      #${PANEL_ID} .md-pr-stats {
-        margin-top: 12px;
-        border: 1px solid #d0d7de;
-        border-radius: 8px;
-        overflow: hidden;
+      #${PANEL_ID} .md-pr-link:hover {
+        text-decoration: underline;
       }
-      #${PANEL_ID} .md-pr-stat-row {
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        padding: 8px 10px;
-        border-bottom: 1px solid #d0d7de;
-        font-size: 14px;
+      #${PANEL_ID} .md-pr-stats {
+        margin-top: 8px;
       }
-      #${PANEL_ID} .md-pr-stat-row:last-child {
-        border-bottom: none;
+      #${PANEL_ID} .md-pr-stat-item {
+        color: var(--fgColor-default, #24292f);
       }
       #${PANEL_ID} .md-pr-stat-label {
-        color: #57606a;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        font-weight: 600;
-        font-size: 11px;
+        color: var(--fgColor-muted, #57606a);
       }
-      #${PANEL_ID} .md-pr-stat-value {
-        font-weight: 700;
-        color: #24292f;
+      #${PANEL_ID} .md-pr-stat-sep {
+        margin: 0 4px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-section {
-        margin-top: 12px;
+        margin-top: 8px;
       }
       #${PANEL_ID} .md-pr-section-title {
-        font-size: 13px;
+        margin-bottom: 2px;
         font-weight: 600;
-        color: #57606a;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        margin-bottom: 6px;
+        color: var(--fgColor-muted, #57606a);
       }
       #${PANEL_ID} .md-pr-ecosystems {
         display: flex;
         flex-wrap: wrap;
-        gap: 6px;
+        gap: 8px;
       }
       #${PANEL_ID} .md-pr-ecosystem-pill {
-        display: inline-flex;
-        align-items: center;
-        background: #f6f8fa;
-        border: 1px solid #d0d7de;
-        border-radius: 999px;
-        padding: 2px 8px;
-        font-size: 13px;
-        color: #57606a;
+        color: var(--fgColor-accent, #0969da);
         text-decoration: none;
       }
+      #${PANEL_ID} .md-pr-ecosystem-pill:hover {
+        text-decoration: underline;
+      }
       #${PANEL_ID} .md-pr-project-list {
         display: flex;
         flex-direction: column;
-        gap: 6px;
+        gap: 2px;
       }
       #${PANEL_ID} .md-pr-project-item {
         display: flex;
+        align-items: baseline;
         justify-content: space-between;
         gap: 8px;
-        font-size: 14px;
-        color: #24292f;
       }
       #${PANEL_ID} .md-pr-project-meta {
-        color: #57606a;
-        font-size: 13px;
+        color: var(--fgColor-muted, #57606a);
+        flex-shrink: 0;
+      }
+      #${PANEL_ID} .md-pr-powered {
+        margin-top: 8px;
+        font-size: 11px;
+        color: var(--fgColor-muted, #57606a);
+        opacity: 0.65;
       }
       .md-pr-list-indicator {
         display: inline-flex;
@@ -289,55 +247,6 @@
       .md-pr-list-indicator.md-pr-list-missing {
         background: #afb8c1;
       }
-      #${PANEL_ID} .md-pr-section {
-        margin-top: 8px;
-      }
-      #${PANEL_ID} .md-pr-section-title {
-        font-size: 11px;
-        font-weight: 600;
-        text-transform: uppercase;
-        letter-spacing: 0.04em;
-        color: #6b7280;
-        margin-bottom: 4px;
-      }
-      #${PANEL_ID} .md-pr-stats {
-        display: grid;
-        grid-template-columns: repeat(3, minmax(0, 1fr));
-        gap: 6px;
-      }
-      #${PANEL_ID} .md-pr-stat {
-        background: #ffffff;
-        border: 1px solid #e5e7eb;
-        border-radius: 8px;
-        padding: 6px;
-        text-align: center;
-      }
-      #${PANEL_ID} .md-pr-stat-label {
-        font-size: 10px;
-        text-transform: uppercase;
-        letter-spacing: 0.05em;
-        color: #6b7280;
-      }
-      #${PANEL_ID} .md-pr-stat-value {
-        font-size: 13px;
-        font-weight: 600;
-        color: #111827;
-      }
-      #${PANEL_ID} .md-pr-pill {
-        display: inline-flex;
-        align-items: center;
-        padding: 2px 6px;
-        border-radius: 999px;
-        background: #eef2ff;
-        color: #3730a3;
-        font-size: 11px;
-        margin-right: 4px;
-        margin-bottom: 4px;
-      }
-      #${PANEL_ID} .md-pr-link {
-        color: #0a3069;
-        font-weight: 600;
-      }
       #${BADGE_ID} {
         display: inline-flex;
         align-items: center;
@@ -360,10 +269,177 @@
     document.head.appendChild(style);
   }
 
+  function clearMountRetry() {
+    if (!state.mountRetryTimer) return;
+    window.clearTimeout(state.mountRetryTimer);
+    state.mountRetryTimer = null;
+  }
+
+  function scheduleMountRetry() {
+    if (state.mountRetryTimer || state.mountRetryCount >= 40 || !isPullDetailPage()) return;
+    state.mountRetryTimer = window.setTimeout(() => {
+      state.mountRetryTimer = null;
+      state.mountRetryCount += 1;
+      ensurePanel();
+    }, 250);
+  }
+
+  function normalizeText(value) {
+    return String(value || "").replace(/\s+/g, " ").trim().toLowerCase();
+  }
+
+  function isVisibleElement(element) {
+    return Boolean(element && element.isConnected && element.getClientRects().length > 0);
+  }
+
+  function findSidebar() {
+    const selectors = [
+      ".discussion-sidebar",
+      ".Layout-sidebar .discussion-sidebar",
+      ".Layout-sidebar",
+      ".js-discussion-sidebar",
+      "#partial-discussion-sidebar",
+      "[data-testid*='sidebar']",
+      "aside"
+    ];
+
+    const seen = new Set();
+    const candidates = [];
+
+    for (const selector of selectors) {
+      document.querySelectorAll(selector).forEach((element) => {
+        if (seen.has(element)) return;
+        seen.add(element);
+        candidates.push(element);
+      });
+    }
+
+    const scoredVisible = candidates
+      .filter((element) => isVisibleElement(element))
+      .map((element) => {
+        const text = normalizeText(element.textContent);
+        let score = 0;
+        if (text.includes("reviewers")) score += 5;
+        if (text.includes("assignees")) score += 2;
+        if (normalizeText(element.className).includes("sidebar")) score += 2;
+        if (element.tagName === "ASIDE") score += 1;
+        return { element, score };
+      })
+      .sort((a, b) => b.score - a.score);
+
+    if (scoredVisible.length) return scoredVisible[0].element;
+
+    if (candidates.length) return candidates[0];
+
+    return null;
+  }
+
+  function findReviewersSection(sidebar) {
+    const roots = [];
+    if (sidebar) roots.push(sidebar);
+    const discoveredSidebar = findSidebar();
+    if (discoveredSidebar && !roots.includes(discoveredSidebar)) roots.push(discoveredSidebar);
+    roots.push(document);
+
+    for (const root of roots) {
+      const byClass = root.querySelector(
+        ".discussion-sidebar-item.sidebar-reviewers, .js-discussion-sidebar-item.sidebar-reviewers"
+      );
+      if (byClass && isVisibleElement(byClass)) return byClass;
+
+      const byTestId = root.querySelector("[data-testid*='reviewer']");
+      if (byTestId && isVisibleElement(byTestId)) {
+        const item = byTestId.closest(
+          ".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section, li"
+        );
+        if (item && isVisibleElement(item)) return item;
+      }
+
+      const headings = root.querySelectorAll(".discussion-sidebar-heading, h2, h3, h4, [role='heading']");
+      for (const heading of headings) {
+        if (normalizeText(heading.textContent) !== "reviewers") continue;
+        const item = heading.closest(
+          ".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section, li, aside"
+        );
+        if (item && isVisibleElement(item)) return item;
+      }
+    }
+
+    return null;
+  }
+
+  function findFallbackAnchor() {
+    const selectors = [
+      ".gh-header-show",
+      ".gh-header-meta",
+      ".js-pull-discussion-timeline",
+      "main [data-testid='issue-viewer']",
+      "main"
+    ];
+
+    for (const selector of selectors) {
+      const element = document.querySelector(selector);
+      if (element && isVisibleElement(element)) return element;
+    }
+
+    return null;
+  }
+
+  function setWrapperPlacementClass(wrapper, inSidebar) {
+    if (inSidebar) {
+      wrapper.classList.add("discussion-sidebar-item");
+      wrapper.classList.remove("md-pr-fallback");
+      return;
+    }
+
+    wrapper.classList.remove("discussion-sidebar-item");
+    wrapper.classList.add("md-pr-fallback");
+  }
+
+  function mountPanel(wrapper) {
+    const reviewersSection = findReviewersSection();
+    if (reviewersSection) {
+      setWrapperPlacementClass(wrapper, true);
+      if (reviewersSection.nextElementSibling !== wrapper) {
+        reviewersSection.insertAdjacentElement("afterend", wrapper);
+      }
+      return true;
+    }
+
+    const sidebar = findSidebar();
+    if (sidebar) {
+      setWrapperPlacementClass(wrapper, true);
+      if (wrapper.parentElement !== sidebar) {
+        sidebar.appendChild(wrapper);
+      }
+      return true;
+    }
+
+    const fallbackAnchor = findFallbackAnchor();
+    if (fallbackAnchor) {
+      setWrapperPlacementClass(wrapper, false);
+      if (fallbackAnchor.tagName === "MAIN") {
+        if (wrapper.parentElement !== fallbackAnchor || fallbackAnchor.firstElementChild !== wrapper) {
+          fallbackAnchor.prepend(wrapper);
+        }
+        return true;
+      }
+
+      if (fallbackAnchor.nextElementSibling !== wrapper) {
+        fallbackAnchor.insertAdjacentElement("afterend", wrapper);
+      }
+      return true;
+    }
+
+    return false;
+  }
+
   function ensurePanel() {
     const existing = document.getElementById(PANEL_ID);
     if (!isPullDetailPage()) {
       if (existing) existing.remove();
+      clearMountRetry();
+      state.mountRetryCount = 0;
       removeBadge();
       return;
     }
@@ -371,6 +447,12 @@
     ensureStyles();
 
     if (existing) {
+      if (!mountPanel(existing)) {
+        scheduleMountRetry();
+        return;
+      }
+      clearMountRetry();
+      state.mountRetryCount = 0;
       updatePanel(existing);
       return;
     }
@@ -380,7 +462,7 @@
     wrapper.innerHTML = `
       <div class="md-pr-panel">
         <div class="md-pr-header">
-          <span></span>
+          <h3 class="discussion-sidebar-heading md-pr-heading">Contributor insights</h3>
           <button class="md-pr-gear" type="button" aria-label="Settings">
             <span aria-hidden="true">⚙</span>
           </button>
@@ -391,10 +473,11 @@
           <div class="md-pr-details"></div>
         </div>
         <div class="md-pr-settings ${state.config.settingsOpen ? "md-pr-open" : ""}">
-          <label>API key</label>
-          <input type="password" data-config="apiKey" />
+          <label for="${PANEL_ID}-api-key">API key</label>
+          <input id="${PANEL_ID}-api-key" type="password" data-config="apiKey" />
           <div class="md-pr-status"></div>
         </div>
+        <div class="md-pr-powered">Powered by the Open Source Explorer</div>
       </div>
     `;
 
@@ -417,7 +500,14 @@
       });
     });
 
-    document.body.appendChild(wrapper);
+    if (!mountPanel(wrapper)) {
+      scheduleMountRetry();
+      return;
+    }
+
+    clearMountRetry();
+    state.mountRetryCount = 0;
+
     updatePanel(wrapper);
   }
 
@@ -463,8 +553,8 @@
       statusBlocks.forEach((status) => {
         status.innerHTML = "";
       });
-      summary.innerHTML = `No profile found on the Open Source Explorer. <a class="md-pr-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Explore</a>`;
-      details.innerHTML = "";
+      summary.textContent = "No contributor profile found yet.";
+      details.textContent = "";
       return;
     }
 
@@ -566,26 +656,17 @@
             ${avatarUrl ? `<img src="${avatarUrl}" alt="${name}" />` : name.slice(0, 1).toUpperCase()}
           </div>
           <div>
-            <div class="md-pr-name">${name}</div>
+            <div class="md-pr-name"><a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">${name}</a></div>
             <div class="md-pr-meta">@${username}${location ? ` · ${location}` : ""}</div>
-            <div class="md-pr-links">
-              <a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">GitHub</a>
-              <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Market.dev</a>
-            </div>
           </div>
         </div>
         ${stats.length ? `
           <div class="md-pr-stats">
             ${stats
               .map(
-                (stat) => `
-                  <div class="md-pr-stat-row">
-                    <span class="md-pr-stat-label">${stat.label}</span>
-                    <span class="md-pr-stat-value">${stat.value}</span>
-                  </div>
-                `
+                (stat) => `<span class="md-pr-stat-item"><span class="md-pr-stat-label">${stat.label}:</span> ${stat.value}</span>`
               )
-              .join("")}
+              .join('<span class="md-pr-stat-sep">·</span>')}
           </div>
         ` : ""}
         ${ecosystemNames.length ? `

```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git log -8 --oneline --no-decorate",
  "description": "Show recent commit message style"
}
```

## Assistant

**Result** (success):
```
ed79474 hello world

```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git add content.js bookmarklet.js && git commit -m \"Embed contributor insights inline with GitHub's PR layout\" -m \"Move the panel out of the floating popup style and mount it under Reviewers with resilient sidebar detection so it remains visible across GitHub UI variants.\" && git status --short",
  "description": "Stage files, create commit, and verify clean status"
}
```

## Assistant

**Result** (success):
```
[main 230ee91] Embed contributor insights inline with GitHub's PR layout
 2 files changed, 537 insertions(+), 381 deletions(-)

```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git status -sb && git push",
  "description": "Check branch state and push commit"
}
```

## Assistant

**Result** (success):
```
## main...origin/main [ahead 1]
To github.com:market-dot-dev/explorer-chrome-extension.git
   ed79474..230ee91  main -> main

```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git status --short",
  "description": "Confirm working tree is clean"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

Done — committed and pushed.

- Commit: `230ee91`
- Branch: `main` pushed to `origin/main` successfully (`ed79474..230ee91`)

## User

change projects heading to "Notable Projects"

## Assistant

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "pattern": "Projects"
}
```

## Assistant

**Result** (success):
```
Found 4 matches
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js:
  Line 605:       { label: "Projects", value: formatCompactNumber(info.projects_count) },
  Line 611:     const sortedProjects = [...projects].sort((a, b) => {
  Line 619:     const maintainerItems = sortedProjects.slice(0, 10).map((project) => {
  Line 684:             <div class="md-pr-section-title">Projects</div>
```

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "pattern": "Projects"
}
```

## Assistant

**Result** (success):
```
Found 4 matches
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js:
  Line 562:       { label: "Projects", value: formatCompactNumber(info.projects_count) },
  Line 568:     const sortedProjects = [...projects].sort((a, b) => {
  Line 576:     const maintainerItems = sortedProjects.slice(0, 10).map((project) => {
  Line 641:             <div class="md-pr-section-title">Projects</div>
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n-            <div class=\"md-pr-section-title\">Projects</div>\n+            <div class=\"md-pr-section-title\">Notable Projects</div>\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js\n@@\n-            <div class=\"md-pr-section-title\">Projects</div>\n+            <div class=\"md-pr-section-title\">Notable Projects</div>\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M bookmarklet.js
```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check content.js",
  "description": "Validate content script after heading text change"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check bookmarklet.js",
  "description": "Validate bookmarklet after heading text change"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

## Assistant

## Assistant

Done — I changed the section heading from `Projects` to `Notable Projects` in both:

- `content.js`
- `bookmarklet.js`

I left the stats label (`Projects` count) unchanged.

## User

provide link to Open Source Explorer (explore.market.dev)

## Assistant

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "pattern": "md-pr-powered"
}
```

## Assistant

**Result** (success):
```
Found 2 matches
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js:
  Line 227:       #${PANEL_ID} .md-pr-powered {
  Line 480:         <div class="md-pr-powered">Powered by the Open Source Explorer</div>
```

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "pattern": "md-pr-powered"
}
```

## Assistant

**Result** (success):
```
Found 2 matches
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js:
  Line 205:       #${PANEL_ID} .md-pr-powered {
  Line 441:         <div class="md-pr-powered">Powered by the Open Source Explorer</div>
```

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 35,
  "offset": 212
}
```

## Assistant

**Result** (success):
```
<file>
00213|         display: flex;
00214|         flex-direction: column;
00215|         gap: 2px;
00216|       }
00217|       #${PANEL_ID} .md-pr-project-item {
00218|         display: flex;
00219|         align-items: baseline;
00220|         justify-content: space-between;
00221|         gap: 8px;
00222|       }
00223|       #${PANEL_ID} .md-pr-project-meta {
00224|         color: var(--fgColor-muted, #57606a);
00225|         flex-shrink: 0;
00226|       }
00227|       #${PANEL_ID} .md-pr-powered {
00228|         margin-top: 8px;
00229|         font-size: 11px;
00230|         color: var(--fgColor-muted, #57606a);
00231|         opacity: 0.65;
00232|       }
00233|       .md-pr-list-indicator {
00234|         display: inline-flex;
00235|         align-items: center;
00236|         justify-content: center;
00237|         width: 8px;
00238|         height: 8px;
00239|         border-radius: 999px;
00240|         margin-left: 6px;
00241|         border: 1px solid #d0d7de;
00242|       }
00243|       .md-pr-list-indicator.md-pr-list-expert {
00244|         background: #2da44e;
00245|         border-color: #2da44e;
00246|       }
00247|       .md-pr-list-indicator.md-pr-list-missing {

(File has more lines. Use 'offset' parameter to read beyond line 247)
</file>
```

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "limit": 35,
  "offset": 190
}
```

## Assistant

**Result** (success):
```
<file>
00191|         display: flex;
00192|         flex-direction: column;
00193|         gap: 2px;
00194|       }
00195|       #${PANEL_ID} .md-pr-project-item {
00196|         display: flex;
00197|         align-items: baseline;
00198|         justify-content: space-between;
00199|         gap: 8px;
00200|       }
00201|       #${PANEL_ID} .md-pr-project-meta {
00202|         color: var(--fgColor-muted, #57606a);
00203|         flex-shrink: 0;
00204|       }
00205|       #${PANEL_ID} .md-pr-powered {
00206|         margin-top: 8px;
00207|         font-size: 11px;
00208|         color: var(--fgColor-muted, #57606a);
00209|         opacity: 0.65;
00210|       }
00211|       #${BADGE_ID} {
00212|         display: inline-flex;
00213|         align-items: center;
00214|         gap: 6px;
00215|         margin-left: 8px;
00216|         padding: 2px 8px;
00217|         border-radius: 999px;
00218|         font-size: 11px;
00219|         font-weight: 600;
00220|       }
00221|       #${BADGE_ID}.md-pr-badge-error {
00222|         background: #ffe4e8;
00223|         color: #9f1239;
00224|       }
00225|       #${BADGE_ID}.md-pr-badge-success {

(File has more lines. Use 'offset' parameter to read beyond line 225)
</file>
```

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 30,
  "offset": 464
}
```

## Assistant

**Result** (success):
```
<file>
00465|           <h3 class="discussion-sidebar-heading md-pr-heading">Contributor insights</h3>
00466|           <button class="md-pr-gear" type="button" aria-label="Settings">
00467|             <span aria-hidden="true">⚙</span>
00468|           </button>
00469|         </div>
00470|         <div class="md-pr-body">
00471|           <div class="md-pr-summary"></div>
00472|           <div class="md-pr-status"></div>
00473|           <div class="md-pr-details"></div>
00474|         </div>
00475|         <div class="md-pr-settings ${state.config.settingsOpen ? "md-pr-open" : ""}">
00476|           <label for="${PANEL_ID}-api-key">API key</label>
00477|           <input id="${PANEL_ID}-api-key" type="password" data-config="apiKey" />
00478|           <div class="md-pr-status"></div>
00479|         </div>
00480|         <div class="md-pr-powered">Powered by the Open Source Explorer</div>
00481|       </div>
00482|     `;
00483| 
00484|     wrapper.querySelector(".md-pr-gear").addEventListener("click", () => {
00485|       const settings = wrapper.querySelector(".md-pr-settings");
00486|       const open = settings.classList.toggle("md-pr-open");
00487|       saveConfig({ ...state.config, settingsOpen: open });
00488|     });
00489| 
00490|     wrapper.querySelectorAll("[data-config]").forEach((input) => {
00491|       const key = input.getAttribute("data-config");
00492|       input.value = state.config[key] ?? "";
00493|       input.addEventListener("change", () => {
00494|         if (key === "apiKey") {

(File has more lines. Use 'offset' parameter to read beyond line 494)
</file>
```

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "limit": 30,
  "offset": 425
}
```

## Assistant

**Result** (success):
```
<file>
00426|           <h3 class="discussion-sidebar-heading md-pr-heading">Contributor insights</h3>
00427|           <button class="md-pr-gear" type="button" aria-label="Settings">
00428|             <span aria-hidden="true">⚙</span>
00429|           </button>
00430|         </div>
00431|         <div class="md-pr-body">
00432|           <div class="md-pr-summary"></div>
00433|           <div class="md-pr-status"></div>
00434|           <div class="md-pr-details"></div>
00435|         </div>
00436|         <div class="md-pr-settings ${state.config.settingsOpen ? "md-pr-open" : ""}">
00437|           <label for="${PANEL_ID}-api-key">API key</label>
00438|           <input id="${PANEL_ID}-api-key" type="password" data-config="apiKey" />
00439|           <div class="md-pr-status"></div>
00440|         </div>
00441|         <div class="md-pr-powered">Powered by the Open Source Explorer</div>
00442|       </div>
00443|     `;
00444| 
00445|     wrapper.querySelector(".md-pr-gear").addEventListener("click", () => {
00446|       const settings = wrapper.querySelector(".md-pr-settings");
00447|       const open = settings.classList.toggle("md-pr-open");
00448|       saveConfig({ ...state.config, settingsOpen: open });
00449|     });
00450| 
00451|     wrapper.querySelectorAll("[data-config]").forEach((input) => {
00452|       const key = input.getAttribute("data-config");
00453|       input.value = state.config[key] ?? "";
00454|       input.addEventListener("change", () => {
00455|         saveConfig({ ...state.config, [key]: input.value });

(File has more lines. Use 'offset' parameter to read beyond line 455)
</file>
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n       #${PANEL_ID} .md-pr-powered {\n         margin-top: 8px;\n         font-size: 11px;\n         color: var(--fgColor-muted, #57606a);\n         opacity: 0.65;\n       }\n+      #${PANEL_ID} .md-pr-powered-link {\n+        color: inherit;\n+        text-decoration: none;\n+      }\n+      #${PANEL_ID} .md-pr-powered-link:hover {\n+        text-decoration: underline;\n+      }\n@@\n-        <div class=\"md-pr-powered\">Powered by the Open Source Explorer</div>\n+        <div class=\"md-pr-powered\">Powered by the <a class=\"md-pr-powered-link\" href=\"https://explore.market.dev\" target=\"_blank\" rel=\"noopener noreferrer\">Open Source Explorer</a></div>\n       </div>\n     `;\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js\n@@\n       #${PANEL_ID} .md-pr-powered {\n         margin-top: 8px;\n         font-size: 11px;\n         color: var(--fgColor-muted, #57606a);\n         opacity: 0.65;\n       }\n+      #${PANEL_ID} .md-pr-powered-link {\n+        color: inherit;\n+        text-decoration: none;\n+      }\n+      #${PANEL_ID} .md-pr-powered-link:hover {\n+        text-decoration: underline;\n+      }\n@@\n-        <div class=\"md-pr-powered\">Powered by the Open Source Explorer</div>\n+        <div class=\"md-pr-powered\">Powered by the <a class=\"md-pr-powered-link\" href=\"https://explore.market.dev\" target=\"_blank\" rel=\"noopener noreferrer\">Open Source Explorer</a></div>\n       </div>\n     `;\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M bookmarklet.js
```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check content.js",
  "description": "Validate content script syntax"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check bookmarklet.js",
  "description": "Validate bookmarklet syntax"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

Done — I added a subtle footer link to `https://explore.market.dev` (“Open Source Explorer”) in both `content.js` and `bookmarklet.js`.

It keeps the muted styling and only underlines on hover. Refresh the PR page to see it.

## Assistant

## User

commit and push; can we add a keyboard shortcut so that we can cycle through to the next PR? is that psosible

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git status --short",
  "description": "Show tracked and untracked changes"
}
```

## Assistant

**Result** (success):
```
 M bookmarklet.js
 M content.js

```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git diff",
  "description": "Show full staged and unstaged diff"
}
```

## Assistant

**Result** (success):
```
diff --git a/bookmarklet.js b/bookmarklet.js
index 51a15a5..8bed6a7 100644
--- a/bookmarklet.js
+++ b/bookmarklet.js
@@ -208,6 +208,13 @@
         color: var(--fgColor-muted, #57606a);
         opacity: 0.65;
       }
+      #${PANEL_ID} .md-pr-powered-link {
+        color: inherit;
+        text-decoration: none;
+      }
+      #${PANEL_ID} .md-pr-powered-link:hover {
+        text-decoration: underline;
+      }
       #${BADGE_ID} {
         display: inline-flex;
         align-items: center;
@@ -438,7 +445,7 @@
           <input id="${PANEL_ID}-api-key" type="password" data-config="apiKey" />
           <div class="md-pr-status"></div>
         </div>
-        <div class="md-pr-powered">Powered by the Open Source Explorer</div>
+        <div class="md-pr-powered">Powered by the <a class="md-pr-powered-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Open Source Explorer</a></div>
       </div>
     `;
 
@@ -638,7 +645,7 @@
         ` : ""}
         ${maintainerItems.length ? `
           <div class="md-pr-section">
-            <div class="md-pr-section-title">Projects</div>
+            <div class="md-pr-section-title">Notable Projects</div>
             <div class="md-pr-project-list">
               ${maintainerItems
                 .map(
diff --git a/content.js b/content.js
index 036a794..2475cdf 100644
--- a/content.js
+++ b/content.js
@@ -230,6 +230,13 @@
         color: var(--fgColor-muted, #57606a);
         opacity: 0.65;
       }
+      #${PANEL_ID} .md-pr-powered-link {
+        color: inherit;
+        text-decoration: none;
+      }
+      #${PANEL_ID} .md-pr-powered-link:hover {
+        text-decoration: underline;
+      }
       .md-pr-list-indicator {
         display: inline-flex;
         align-items: center;
@@ -477,7 +484,7 @@
           <input id="${PANEL_ID}-api-key" type="password" data-config="apiKey" />
           <div class="md-pr-status"></div>
         </div>
-        <div class="md-pr-powered">Powered by the Open Source Explorer</div>
+        <div class="md-pr-powered">Powered by the <a class="md-pr-powered-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Open Source Explorer</a></div>
       </div>
     `;
 
@@ -681,7 +688,7 @@
         ` : ""}
         ${maintainerItems.length ? `
           <div class="md-pr-section">
-            <div class="md-pr-section-title">Projects</div>
+            <div class="md-pr-section-title">Notable Projects</div>
             <div class="md-pr-project-list">
               ${maintainerItems
                 .map(

```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git log -8 --oneline --no-decorate",
  "description": "Inspect recent commit message style"
}
```

## Assistant

**Result** (success):
```
230ee91 Embed contributor insights inline with GitHub's PR layout
ed79474 hello world

```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git add content.js bookmarklet.js && git commit -m \"Polish contributor panel copy and footer link\" -m \"Rename the projects section to Notable Projects and make the Powered by Open Source Explorer footer clickable while keeping the subtle inline styling.\" && git status --short",
  "description": "Stage changes, commit updates, and verify status"
}
```

## Assistant

**Result** (success):
```
[main 19c69e3] Polish contributor panel copy and footer link
 2 files changed, 18 insertions(+), 4 deletions(-)

```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git status -sb && git push",
  "description": "Check branch and push latest commit"
}
```

## Assistant

**Result** (success):
```
## main...origin/main [ahead 1]
To github.com:market-dot-dev/explorer-chrome-extension.git
   230ee91..19c69e3  main -> main

```

## Assistant

## Assistant

Done — committed and pushed.

- Commit: `19c69e3`
- Pushed: `main` -> `origin/main`

Yes, keyboard shortcut navigation is definitely possible in this extension.

Best implementation options:
1. Next/prev by **PR list order** (recommended) — follows the current GitHub ordering/filter.
2. Next/prev by **PR number** (`+1/-1`) — simpler but can jump to closed/missing PRs.

If you want, reply with `1` or `2` and I’ll implement it next (I can use `]` for next and `[` for previous by default).

## User

1

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 900,
  "offset": 1
}
```

## Assistant

**Result** (success):
```
<file>
00002|   const STORAGE_KEY = "md_expert_pr_config";
00003|   const STYLE_ID = "md-expert-pr-style";
00004|   const PANEL_ID = "md-expert-pr-panel";
00005|   const BADGE_ID = "md-expert-pr-badge";
00006| 
00007|   const DEFAULT_CONFIG = {
00008|     apiKey: "",
00009|     settingsOpen: false
00010|   };
00011| 
00012|   const state = {
00013|     config: loadConfig(),
00014|     currentResult: null,
00015|     listCache: new Map(),
00016|     mountRetryTimer: null,
00017|     mountRetryCount: 0
00018|   };
00019| 
00020|   function loadConfig() {
00021|     const raw = window.localStorage.getItem(STORAGE_KEY);
00022|     if (!raw) return { ...DEFAULT_CONFIG };
00023|     try {
00024|       const parsed = JSON.parse(raw);
00025|       return { ...DEFAULT_CONFIG, ...parsed };
00026|     } catch (error) {
00027|       return { ...DEFAULT_CONFIG };
00028|     }
00029|   }
00030| 
00031|   function saveConfig(nextConfig) {
00032|     state.config = { ...DEFAULT_CONFIG, ...nextConfig };
00033|     window.localStorage.setItem(STORAGE_KEY, JSON.stringify(state.config));
00034|   }
00035| 
00036|   function isPullDetailPage() {
00037|     return /\/pull\/(\d+)(\/|$)/.test(window.location.pathname);
00038|   }
00039| 
00040|   function isPullListPage() {
00041|     return /\/pulls(\/|$)/.test(window.location.pathname);
00042|   }
00043| 
00044|   function canUseBackground() {
00045|     return typeof chrome !== "undefined" && chrome.runtime && chrome.runtime.sendMessage;
00046|   }
00047| 
00048|   function fetchViaBackground(url, apiKey) {
00049|     if (!canUseBackground()) return Promise.resolve(null);
00050|     return new Promise((resolve) => {
00051|       chrome.runtime.sendMessage(
00052|         { type: "md-expert-pr-check", url, apiKey },
00053|         (response) => {
00054|           if (chrome.runtime.lastError) {
00055|             resolve(null);
00056|             return;
00057|           }
00058|           resolve(response);
00059|         }
00060|       );
00061|     });
00062|   }
00063| 
00064|   function ensureStyles() {
00065|     if (document.getElementById(STYLE_ID)) return;
00066|     const style = document.createElement("style");
00067|     style.id = STYLE_ID;
00068|     style.textContent = `
00069|       #${PANEL_ID} {
00070|         color: var(--fgColor-default, #24292f);
00071|       }
00072|       #${PANEL_ID}.discussion-sidebar-item {
00073|         margin-top: 0;
00074|       }
00075|       #${PANEL_ID}.md-pr-fallback {
00076|         margin: 16px 0;
00077|       }
00078|       #${PANEL_ID} .md-pr-panel {
00079|         font-size: 12px;
00080|         line-height: 1.5;
00081|       }
00082|       #${PANEL_ID} .md-pr-header {
00083|         display: flex;
00084|         justify-content: space-between;
00085|         align-items: center;
00086|         margin-bottom: 6px;
00087|       }
00088|       #${PANEL_ID} .md-pr-heading {
00089|         margin: 0;
00090|       }
00091|       #${PANEL_ID} .md-pr-gear {
00092|         border: none;
00093|         background: transparent;
00094|         color: var(--fgColor-muted, #57606a);
00095|         width: 20px;
00096|         height: 20px;
00097|         padding: 0;
00098|         display: inline-flex;
00099|         align-items: center;
00100|         justify-content: center;
00101|         cursor: pointer;
00102|       }
00103|       #${PANEL_ID} .md-pr-gear:hover {
00104|         color: var(--fgColor-default, #24292f);
00105|       }
00106|       #${PANEL_ID} .md-pr-settings {
00107|         display: none;
00108|         margin-top: 8px;
00109|       }
00110|       #${PANEL_ID} .md-pr-settings.md-pr-open {
00111|         display: block;
00112|       }
00113|       #${PANEL_ID} .md-pr-settings label {
00114|         display: block;
00115|         margin-bottom: 4px;
00116|         font-size: 12px;
00117|         color: var(--fgColor-muted, #57606a);
00118|       }
00119|       #${PANEL_ID} .md-pr-settings input[type="password"] {
00120|         width: 100%;
00121|         border: 1px solid var(--borderColor-default, #d0d7de);
00122|         border-radius: 6px;
00123|         padding: 5px 8px;
00124|         font-size: 12px;
00125|         color: var(--fgColor-default, #24292f);
00126|         background: var(--bgColor-default, #ffffff);
00127|       }
00128|       #${PANEL_ID} .md-pr-status {
00129|         color: var(--fgColor-muted, #57606a);
00130|       }
00131|       #${PANEL_ID} .md-pr-warning {
00132|         color: var(--fgColor-danger, #cf222e);
00133|       }
00134|       #${PANEL_ID} .md-pr-details {
00135|         color: var(--fgColor-muted, #57606a);
00136|       }
00137|       #${PANEL_ID} .md-pr-summary {
00138|         margin-bottom: 8px;
00139|         color: var(--fgColor-default, #24292f);
00140|       }
00141|       #${PANEL_ID} .md-pr-card-header {
00142|         display: flex;
00143|         gap: 8px;
00144|         align-items: flex-start;
00145|       }
00146|       #${PANEL_ID} .md-pr-avatar {
00147|         width: 32px;
00148|         height: 32px;
00149|         border-radius: 50%;
00150|         overflow: hidden;
00151|         background: var(--bgColor-muted, #f6f8fa);
00152|         display: inline-flex;
00153|         align-items: center;
00154|         justify-content: center;
00155|         font-weight: 600;
00156|         color: var(--fgColor-muted, #57606a);
00157|         flex-shrink: 0;
00158|       }
00159|       #${PANEL_ID} .md-pr-avatar img {
00160|         width: 100%;
00161|         height: 100%;
00162|         object-fit: cover;
00163|       }
00164|       #${PANEL_ID} .md-pr-name {
00165|         font-size: 13px;
00166|         font-weight: 600;
00167|         color: var(--fgColor-default, #24292f);
00168|       }
00169|       #${PANEL_ID} .md-pr-meta {
00170|         color: var(--fgColor-muted, #57606a);
00171|       }
00172|       #${PANEL_ID} .md-pr-link {
00173|         color: var(--fgColor-accent, #0969da);
00174|         text-decoration: none;
00175|       }
00176|       #${PANEL_ID} .md-pr-link:hover {
00177|         text-decoration: underline;
00178|       }
00179|       #${PANEL_ID} .md-pr-stats {
00180|         margin-top: 8px;
00181|       }
00182|       #${PANEL_ID} .md-pr-stat-item {
00183|         color: var(--fgColor-default, #24292f);
00184|       }
00185|       #${PANEL_ID} .md-pr-stat-label {
00186|         color: var(--fgColor-muted, #57606a);
00187|       }
00188|       #${PANEL_ID} .md-pr-stat-sep {
00189|         margin: 0 4px;
00190|         color: var(--fgColor-muted, #57606a);
00191|       }
00192|       #${PANEL_ID} .md-pr-section {
00193|         margin-top: 8px;
00194|       }
00195|       #${PANEL_ID} .md-pr-section-title {
00196|         margin-bottom: 2px;
00197|         font-weight: 600;
00198|         color: var(--fgColor-muted, #57606a);
00199|       }
00200|       #${PANEL_ID} .md-pr-ecosystems {
00201|         display: flex;
00202|         flex-wrap: wrap;
00203|         gap: 8px;
00204|       }
00205|       #${PANEL_ID} .md-pr-ecosystem-pill {
00206|         color: var(--fgColor-accent, #0969da);
00207|         text-decoration: none;
00208|       }
00209|       #${PANEL_ID} .md-pr-ecosystem-pill:hover {
00210|         text-decoration: underline;
00211|       }
00212|       #${PANEL_ID} .md-pr-project-list {
00213|         display: flex;
00214|         flex-direction: column;
00215|         gap: 2px;
00216|       }
00217|       #${PANEL_ID} .md-pr-project-item {
00218|         display: flex;
00219|         align-items: baseline;
00220|         justify-content: space-between;
00221|         gap: 8px;
00222|       }
00223|       #${PANEL_ID} .md-pr-project-meta {
00224|         color: var(--fgColor-muted, #57606a);
00225|         flex-shrink: 0;
00226|       }
00227|       #${PANEL_ID} .md-pr-powered {
00228|         margin-top: 8px;
00229|         font-size: 11px;
00230|         color: var(--fgColor-muted, #57606a);
00231|         opacity: 0.65;
00232|       }
00233|       #${PANEL_ID} .md-pr-powered-link {
00234|         color: inherit;
00235|         text-decoration: none;
00236|       }
00237|       #${PANEL_ID} .md-pr-powered-link:hover {
00238|         text-decoration: underline;
00239|       }
00240|       .md-pr-list-indicator {
00241|         display: inline-flex;
00242|         align-items: center;
00243|         justify-content: center;
00244|         width: 8px;
00245|         height: 8px;
00246|         border-radius: 999px;
00247|         margin-left: 6px;
00248|         border: 1px solid #d0d7de;
00249|       }
00250|       .md-pr-list-indicator.md-pr-list-expert {
00251|         background: #2da44e;
00252|         border-color: #2da44e;
00253|       }
00254|       .md-pr-list-indicator.md-pr-list-missing {
00255|         background: #afb8c1;
00256|       }
00257|       #${BADGE_ID} {
00258|         display: inline-flex;
00259|         align-items: center;
00260|         gap: 6px;
00261|         margin-left: 8px;
00262|         padding: 2px 8px;
00263|         border-radius: 999px;
00264|         font-size: 11px;
00265|         font-weight: 600;
00266|       }
00267|       #${BADGE_ID}.md-pr-badge-error {
00268|         background: #ffe4e8;
00269|         color: #9f1239;
00270|       }
00271|       #${BADGE_ID}.md-pr-badge-success {
00272|         background: #dcfce7;
00273|         color: #166534;
00274|       }
00275|     `;
00276|     document.head.appendChild(style);
00277|   }
00278| 
00279|   function clearMountRetry() {
00280|     if (!state.mountRetryTimer) return;
00281|     window.clearTimeout(state.mountRetryTimer);
00282|     state.mountRetryTimer = null;
00283|   }
00284| 
00285|   function scheduleMountRetry() {
00286|     if (state.mountRetryTimer || state.mountRetryCount >= 40 || !isPullDetailPage()) return;
00287|     state.mountRetryTimer = window.setTimeout(() => {
00288|       state.mountRetryTimer = null;
00289|       state.mountRetryCount += 1;
00290|       ensurePanel();
00291|     }, 250);
00292|   }
00293| 
00294|   function normalizeText(value) {
00295|     return String(value || "").replace(/\s+/g, " ").trim().toLowerCase();
00296|   }
00297| 
00298|   function isVisibleElement(element) {
00299|     return Boolean(element && element.isConnected && element.getClientRects().length > 0);
00300|   }
00301| 
00302|   function findSidebar() {
00303|     const selectors = [
00304|       ".discussion-sidebar",
00305|       ".Layout-sidebar .discussion-sidebar",
00306|       ".Layout-sidebar",
00307|       ".js-discussion-sidebar",
00308|       "#partial-discussion-sidebar",
00309|       "[data-testid*='sidebar']",
00310|       "aside"
00311|     ];
00312| 
00313|     const seen = new Set();
00314|     const candidates = [];
00315| 
00316|     for (const selector of selectors) {
00317|       document.querySelectorAll(selector).forEach((element) => {
00318|         if (seen.has(element)) return;
00319|         seen.add(element);
00320|         candidates.push(element);
00321|       });
00322|     }
00323| 
00324|     const scoredVisible = candidates
00325|       .filter((element) => isVisibleElement(element))
00326|       .map((element) => {
00327|         const text = normalizeText(element.textContent);
00328|         let score = 0;
00329|         if (text.includes("reviewers")) score += 5;
00330|         if (text.includes("assignees")) score += 2;
00331|         if (normalizeText(element.className).includes("sidebar")) score += 2;
00332|         if (element.tagName === "ASIDE") score += 1;
00333|         return { element, score };
00334|       })
00335|       .sort((a, b) => b.score - a.score);
00336| 
00337|     if (scoredVisible.length) return scoredVisible[0].element;
00338| 
00339|     if (candidates.length) return candidates[0];
00340| 
00341|     return null;
00342|   }
00343| 
00344|   function findReviewersSection(sidebar) {
00345|     const roots = [];
00346|     if (sidebar) roots.push(sidebar);
00347|     const discoveredSidebar = findSidebar();
00348|     if (discoveredSidebar && !roots.includes(discoveredSidebar)) roots.push(discoveredSidebar);
00349|     roots.push(document);
00350| 
00351|     for (const root of roots) {
00352|       const byClass = root.querySelector(
00353|         ".discussion-sidebar-item.sidebar-reviewers, .js-discussion-sidebar-item.sidebar-reviewers"
00354|       );
00355|       if (byClass && isVisibleElement(byClass)) return byClass;
00356| 
00357|       const byTestId = root.querySelector("[data-testid*='reviewer']");
00358|       if (byTestId && isVisibleElement(byTestId)) {
00359|         const item = byTestId.closest(
00360|           ".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section, li"
00361|         );
00362|         if (item && isVisibleElement(item)) return item;
00363|       }
00364| 
00365|       const headings = root.querySelectorAll(".discussion-sidebar-heading, h2, h3, h4, [role='heading']");
00366|       for (const heading of headings) {
00367|         if (normalizeText(heading.textContent) !== "reviewers") continue;
00368|         const item = heading.closest(
00369|           ".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section, li, aside"
00370|         );
00371|         if (item && isVisibleElement(item)) return item;
00372|       }
00373|     }
00374| 
00375|     return null;
00376|   }
00377| 
00378|   function findFallbackAnchor() {
00379|     const selectors = [
00380|       ".gh-header-show",
00381|       ".gh-header-meta",
00382|       ".js-pull-discussion-timeline",
00383|       "main [data-testid='issue-viewer']",
00384|       "main"
00385|     ];
00386| 
00387|     for (const selector of selectors) {
00388|       const element = document.querySelector(selector);
00389|       if (element && isVisibleElement(element)) return element;
00390|     }
00391| 
00392|     return null;
00393|   }
00394| 
00395|   function setWrapperPlacementClass(wrapper, inSidebar) {
00396|     if (inSidebar) {
00397|       wrapper.classList.add("discussion-sidebar-item");
00398|       wrapper.classList.remove("md-pr-fallback");
00399|       return;
00400|     }
00401| 
00402|     wrapper.classList.remove("discussion-sidebar-item");
00403|     wrapper.classList.add("md-pr-fallback");
00404|   }
00405| 
00406|   function mountPanel(wrapper) {
00407|     const reviewersSection = findReviewersSection();
00408|     if (reviewersSection) {
00409|       setWrapperPlacementClass(wrapper, true);
00410|       if (reviewersSection.nextElementSibling !== wrapper) {
00411|         reviewersSection.insertAdjacentElement("afterend", wrapper);
00412|       }
00413|       return true;
00414|     }
00415| 
00416|     const sidebar = findSidebar();
00417|     if (sidebar) {
00418|       setWrapperPlacementClass(wrapper, true);
00419|       if (wrapper.parentElement !== sidebar) {
00420|         sidebar.appendChild(wrapper);
00421|       }
00422|       return true;
00423|     }
00424| 
00425|     const fallbackAnchor = findFallbackAnchor();
00426|     if (fallbackAnchor) {
00427|       setWrapperPlacementClass(wrapper, false);
00428|       if (fallbackAnchor.tagName === "MAIN") {
00429|         if (wrapper.parentElement !== fallbackAnchor || fallbackAnchor.firstElementChild !== wrapper) {
00430|           fallbackAnchor.prepend(wrapper);
00431|         }
00432|         return true;
00433|       }
00434| 
00435|       if (fallbackAnchor.nextElementSibling !== wrapper) {
00436|         fallbackAnchor.insertAdjacentElement("afterend", wrapper);
00437|       }
00438|       return true;
00439|     }
00440| 
00441|     return false;
00442|   }
00443| 
00444|   function ensurePanel() {
00445|     const existing = document.getElementById(PANEL_ID);
00446|     if (!isPullDetailPage()) {
00447|       if (existing) existing.remove();
00448|       clearMountRetry();
00449|       state.mountRetryCount = 0;
00450|       removeBadge();
00451|       return;
00452|     }
00453| 
00454|     ensureStyles();
00455| 
00456|     if (existing) {
00457|       if (!mountPanel(existing)) {
00458|         scheduleMountRetry();
00459|         return;
00460|       }
00461|       clearMountRetry();
00462|       state.mountRetryCount = 0;
00463|       updatePanel(existing);
00464|       return;
00465|     }
00466| 
00467|     const wrapper = document.createElement("div");
00468|     wrapper.id = PANEL_ID;
00469|     wrapper.innerHTML = `
00470|       <div class="md-pr-panel">
00471|         <div class="md-pr-header">
00472|           <h3 class="discussion-sidebar-heading md-pr-heading">Contributor insights</h3>
00473|           <button class="md-pr-gear" type="button" aria-label="Settings">
00474|             <span aria-hidden="true">⚙</span>
00475|           </button>
00476|         </div>
00477|         <div class="md-pr-body">
00478|           <div class="md-pr-summary"></div>
00479|           <div class="md-pr-status"></div>
00480|           <div class="md-pr-details"></div>
00481|         </div>
00482|         <div class="md-pr-settings ${state.config.settingsOpen ? "md-pr-open" : ""}">
00483|           <label for="${PANEL_ID}-api-key">API key</label>
00484|           <input id="${PANEL_ID}-api-key" type="password" data-config="apiKey" />
00485|           <div class="md-pr-status"></div>
00486|         </div>
00487|         <div class="md-pr-powered">Powered by the <a class="md-pr-powered-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Open Source Explorer</a></div>
00488|       </div>
00489|     `;
00490| 
00491|     wrapper.querySelector(".md-pr-gear").addEventListener("click", () => {
00492|       const settings = wrapper.querySelector(".md-pr-settings");
00493|       const open = settings.classList.toggle("md-pr-open");
00494|       saveConfig({ ...state.config, settingsOpen: open });
00495|     });
00496| 
00497|     wrapper.querySelectorAll("[data-config]").forEach((input) => {
00498|       const key = input.getAttribute("data-config");
00499|       input.value = state.config[key] ?? "";
00500|       input.addEventListener("change", () => {
00501|         if (key === "apiKey") {
00502|           state.listCache.clear();
00503|         }
00504|         saveConfig({ ...state.config, [key]: input.value });
00505|         applyCheck();
00506|         applyListIndicators();
00507|       });
00508|     });
00509| 
00510|     if (!mountPanel(wrapper)) {
00511|       scheduleMountRetry();
00512|       return;
00513|     }
00514| 
00515|     clearMountRetry();
00516|     state.mountRetryCount = 0;
00517| 
00518|     updatePanel(wrapper);
00519|   }
00520| 
00521|   function updatePanel(wrapper) {
00522|     const summary = wrapper.querySelector(".md-pr-summary");
00523|     const statusBlocks = wrapper.querySelectorAll(".md-pr-status");
00524|     const details = wrapper.querySelector(".md-pr-details");
00525|     const result = state.currentResult;
00526| 
00527|     statusBlocks.forEach((status) => {
00528|       status.textContent = "";
00529|       status.innerHTML = "";
00530|     });
00531| 
00532|     if (!result) {
00533|       statusBlocks.forEach((status) => {
00534|         status.textContent = "Checking PR author...";
00535|       });
00536|       summary.textContent = "";
00537|       details.textContent = "";
00538|       return;
00539|     }
00540| 
00541|     if (result.state === "missing-key") {
00542|       statusBlocks.forEach((status) => {
00543|         status.innerHTML = `<span class="md-pr-warning">API key required</span>`;
00544|       });
00545|       summary.textContent = "";
00546|       details.textContent = "";
00547|       return;
00548|     }
00549| 
00550|     if (result.state === "error") {
00551|       statusBlocks.forEach((status) => {
00552|         status.innerHTML = `<span class="md-pr-warning">${result.message}</span>`;
00553|       });
00554|       summary.textContent = "";
00555|       details.textContent = "";
00556|       return;
00557|     }
00558| 
00559|     if (result.state === "not-expert") {
00560|       statusBlocks.forEach((status) => {
00561|         status.innerHTML = "";
00562|       });
00563|       summary.textContent = "No contributor profile found yet.";
00564|       details.textContent = "";
00565|       return;
00566|     }
00567| 
00568|     if (result.state === "expert") {
00569|       statusBlocks.forEach((status) => {
00570|         status.innerHTML = "";
00571|       });
00572|       const info = result.expert && result.expert.expert ? result.expert.expert : result.expert;
00573|       summary.textContent = buildSummary(info, result.username);
00574|       details.innerHTML = renderExpertDetails(info, result.username);
00575|     }
00576|   }
00577| 
00578|   function buildSummary(info, username) {
00579|     if (!info) return `This PR was opened by ${username}.`;
00580|     const name = info.name || username;
00581|     const downloadsRaw = Number(info.total_downloads || 0);
00582|     const downloads = downloadsRaw > 0 ? formatCompactNumber(downloadsRaw) : null;
00583|     const stars = formatCompactNumber(info.total_stars);
00584|     const downloadText = downloads ? `${downloads} total downloads` : "";
00585|     const starsText = stars ? `${stars} stars on repos` : "";
00586|     const stats = [downloadText, starsText].filter(Boolean).join(", ");
00587|     if (!stats) return `This PR was opened by ${name} (${username}).`;
00588|     return `This PR was opened by ${name} (${username}). They have received ${stats}.`;
00589|   }
00590| 
00591|   function formatCompactNumber(value) {
00592|     if (value === null || value === undefined) return null;
00593|     const num = Number(value);
00594|     if (Number.isNaN(num)) return null;
00595|     return new Intl.NumberFormat("en", {
00596|       notation: "compact",
00597|       maximumFractionDigits: 1
00598|     }).format(num);
00599|   }
00600| 
00601|   function renderExpertDetails(info, username) {
00602|     const profileUrl = `https://explore.market.dev/experts/${encodeURIComponent(username)}`;
00603|     if (!info) {
00604|       return `Expert profile: <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Open</a>`;
00605|     }
00606| 
00607|     const name = info.name || username;
00608|     const avatarUrl = info.avatar_url || info.avatar || null;
00609|     const location = info.location || info.display_location || "";
00610| 
00611|     const stats = [
00612|       { label: "Projects", value: formatCompactNumber(info.projects_count) },
00613|       { label: "Downloads", value: formatCompactNumber(info.total_downloads) },
00614|       { label: "Stars", value: formatCompactNumber(info.total_stars) }
00615|     ].filter((stat) => stat.value !== null);
00616| 
00617|     const projects = Array.isArray(info.projects) ? info.projects : [];
00618|     const sortedProjects = [...projects].sort((a, b) => {
00619|       const starsA = Number(a.total_stars || a.stars || 0);
00620|       const starsB = Number(b.total_stars || b.stars || 0);
00621|       if (starsB !== starsA) return starsB - starsA;
00622|       const downloadsA = Number(a.total_downloads || a.downloads || 0);
00623|       const downloadsB = Number(b.total_downloads || b.downloads || 0);
00624|       return downloadsB - downloadsA;
00625|     });
00626|     const maintainerItems = sortedProjects.slice(0, 10).map((project) => {
00627|       const role = project.role || project.project_experts?.[0]?.role;
00628|       const name = project.name || project.slug || "";
00629|       if (!name) return null;
00630|       const stars = formatCompactNumber(project.total_stars || project.stars);
00631|       const downloads = formatCompactNumber(project.total_downloads || project.downloads);
00632|       const metaParts = [stars ? `${stars} stars` : null, downloads ? `${downloads} downloads` : null]
00633|         .filter(Boolean)
00634|         .join(" · ");
00635|       const label = role ? `${role} of ${name}` : name;
00636|       const projectSlug = project.slug || project.name || "";
00637|       const projectUrl =
00638|         project.github_url ||
00639|         project.repo_url ||
00640|         project.url ||
00641|         (projectSlug ? `https://explore.market.dev/projects/${encodeURIComponent(projectSlug)}` : null);
00642|       return { label, meta: metaParts, url: projectUrl };
00643|     }).filter(Boolean);
00644| 
00645|     const ecosystems =
00646|       (Array.isArray(info.ecosystems) && info.ecosystems) ||
00647|       (Array.isArray(info.ecosystem_names) && info.ecosystem_names) ||
00648|       [];
00649| 
00650|     const ecosystemNames = ecosystems
00651|       .map((eco) => (typeof eco === "string" ? eco : eco.name))
00652|       .filter(Boolean)
00653|       .slice(0, 8)
00654|       .map((name) => ({
00655|         name,
00656|         url: `https://explore.market.dev/ecosystems/${encodeURIComponent(name)}`
00657|       }));
00658| 
00659|     return `
00660|       <div class="md-pr-card">
00661|         <div class="md-pr-card-header">
00662|           <div class="md-pr-avatar">
00663|             ${avatarUrl ? `<img src="${avatarUrl}" alt="${name}" />` : name.slice(0, 1).toUpperCase()}
00664|           </div>
00665|           <div>
00666|             <div class="md-pr-name"><a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">${name}</a></div>
00667|             <div class="md-pr-meta">@${username}${location ? ` · ${location}` : ""}</div>
00668|           </div>
00669|         </div>
00670|         ${stats.length ? `
00671|           <div class="md-pr-stats">
00672|             ${stats
00673|               .map(
00674|                 (stat) => `<span class="md-pr-stat-item"><span class="md-pr-stat-label">${stat.label}:</span> ${stat.value}</span>`
00675|               )
00676|               .join('<span class="md-pr-stat-sep">·</span>')}
00677|           </div>
00678|         ` : ""}
00679|         ${ecosystemNames.length ? `
00680|           <div class="md-pr-section">
00681|             <div class="md-pr-section-title">Ecosystems</div>
00682|             <div class="md-pr-ecosystems">
00683|               ${ecosystemNames
00684|                 .map((eco) => `<a class="md-pr-ecosystem-pill" href="${eco.url}" target="_blank" rel="noopener noreferrer">${eco.name}</a>`)
00685|                 .join("")}
00686|             </div>
00687|           </div>
00688|         ` : ""}
00689|         ${maintainerItems.length ? `
00690|           <div class="md-pr-section">
00691|             <div class="md-pr-section-title">Notable Projects</div>
00692|             <div class="md-pr-project-list">
00693|               ${maintainerItems
00694|                 .map(
00695|                   (item) => `
00696|                     <div class="md-pr-project-item">
00697|                       ${item.url ? `<a class="md-pr-link" href="${item.url}" target="_blank" rel="noopener noreferrer">${item.label}</a>` : `<span>${item.label}</span>`}
00698|                       ${item.meta ? `<span class="md-pr-project-meta">${item.meta}</span>` : ""}
00699|                     </div>
00700|                   `
00701|                 )
00702|                 .join("")}
00703|             </div>
00704|           </div>
00705|         ` : ""}
00706|       </div>
00707|     `;
00708|   }
00709| 
00710|   function findPrAuthor() {
00711|     const selectors = [
00712|       ".gh-header-meta .author",
00713|       ".js-discussion .timeline-comment-header .author",
00714|       ".js-discussion .author",
00715|       ".timeline-comment-header .author",
00716|       "a.author"
00717|     ];
00718|     for (const selector of selectors) {
00719|       const el = document.querySelector(selector);
00720|       if (el && el.textContent.trim()) return el.textContent.trim();
00721|     }
00722|     return null;
00723|   }
00724| 
00725|   function removeBadge() {
00726|     const existing = document.getElementById(BADGE_ID);
00727|     if (existing) existing.remove();
00728|   }
00729| 
00730|   function updateBadge(result) {
00731|     const header = document.querySelector(".gh-header-title") || document.querySelector(".gh-header-meta");
00732|     if (!header) return;
00733| 
00734|     removeBadge();
00735|     if (!result || result.state === "error" || result.state === "missing-key") return;
00736| 
00737|     const badge = document.createElement("span");
00738|     badge.id = BADGE_ID;
00739| 
00740|     if (result.state === "not-expert") {
00741|       badge.className = "md-pr-badge-error";
00742|       badge.textContent = "No Profile";
00743|       header.appendChild(badge);
00744|     }
00745|   }
00746| 
00747|   async function fetchExpert(username) {
00748|     const apiKey = String(state.config.apiKey || "").trim();
00749|     if (!apiKey) return { state: "missing-key" };
00750| 
00751|     const url = `https://explore.market.dev/api/v1/experts/${encodeURIComponent(username)}`;
00752| 
00753|     try {
00754|       const backgroundResponse = await fetchViaBackground(url, apiKey);
00755|       let responseStatus = 0;
00756|       let responseData = null;
00757| 
00758|       if (backgroundResponse) {
00759|         responseStatus = backgroundResponse.status || 0;
00760|         responseData = backgroundResponse.data || null;
00761|       } else {
00762|         const response = await fetch(url, {
00763|           headers: {
00764|             Authorization: `Bearer ${apiKey}`,
00765|             Accept: "application/json"
00766|           }
00767|         });
00768|         responseStatus = response.status;
00769|         const text = await response.text();
00770|         try {
00771|           responseData = text ? JSON.parse(text) : null;
00772|         } catch (error) {
00773|           responseData = null;
00774|         }
00775|       }
00776| 
00777|       if (responseStatus === 200) return { state: "expert", expert: responseData };
00778|       if (responseStatus === 404) return { state: "not-expert" };
00779|       if (responseStatus === 401) return { state: "error", message: "Auth failed" };
00780|       return { state: "error", message: "API request failed" };
00781|     } catch (error) {
00782|       return { state: "error", message: "API request failed" };
00783|     }
00784|   }
00785| 
00786|   async function fetchExpertStatus(username) {
00787|     if (state.listCache.has(username)) {
00788|       return state.listCache.get(username);
00789|     }
00790| 
00791|     const apiKey = String(state.config.apiKey || "").trim();
00792|     if (!apiKey) return null;
00793| 
00794|     const url = `https://explore.market.dev/api/v1/experts/${encodeURIComponent(username)}`;
00795|     try {
00796|       const backgroundResponse = await fetchViaBackground(url, apiKey);
00797|       const status = backgroundResponse ? backgroundResponse.status : null;
00798|       if (status === 200 || status === 404) {
00799|         const value = status === 200 ? "expert" : "missing";
00800|         state.listCache.set(username, value);
00801|         return value;
00802|       }
00803|       return null;
00804|     } catch (error) {
00805|       return null;
00806|     }
00807|   }
00808| 
00809|   async function applyListIndicators() {
00810|     if (!isPullListPage()) return;
00811| 
00812|     const rows = document.querySelectorAll("div.js-issue-row");
00813|     rows.forEach((row) => {
00814|       const author = row.getAttribute("data-author");
00815|       if (!author) return;
00816|       const authorLink = row.querySelector("a[data-hovercard-type='user']") || row.querySelector("a.author");
00817|       if (!authorLink) return;
00818|       if (authorLink.parentElement?.querySelector(".md-pr-list-indicator")) return;
00819| 
00820|       fetchExpertStatus(author).then((status) => {
00821|         if (!status) return;
00822|         if (authorLink.parentElement?.querySelector(".md-pr-list-indicator")) return;
00823|         const indicator = document.createElement("span");
00824|         indicator.className = `md-pr-list-indicator ${status === "expert" ? "md-pr-list-expert" : "md-pr-list-missing"}`;
00825|         indicator.title = status === "expert" ? "Expert profile found" : "No expert profile";
00826|         authorLink.insertAdjacentElement("afterend", indicator);
00827|       });
00828|     });
00829|   }
00830| 
00831|   async function applyCheck() {
00832|     ensurePanel();
00833|     if (!isPullDetailPage()) return;
00834| 
00835|     const username = findPrAuthor();
00836|     if (!username) {
00837|       state.currentResult = { state: "error", message: "PR author not found" };
00838|       updateBadge(state.currentResult);
00839|       const panel = document.getElementById(PANEL_ID);
00840|       if (panel) updatePanel(panel);
00841|       return;
00842|     }
00843| 
00844|     state.currentResult = null;
00845|     const panel = document.getElementById(PANEL_ID);
00846|     if (panel) updatePanel(panel);
00847| 
00848|     const result = await fetchExpert(username);
00849|     state.currentResult = { ...result, username };
00850|     updateBadge(state.currentResult);
00851|     if (panel) updatePanel(panel);
00852|   }
00853| 
00854|   function init() {
00855|     applyCheck();
00856|     applyListIndicators();
00857|   }
00858| 
00859|   document.addEventListener("pjax:end", init);
00860|   document.addEventListener("turbo:load", init);
00861|   if (document.readyState === "loading") {
00862|     document.addEventListener("DOMContentLoaded", init);
00863|   } else {
00864|     init();
00865|   }
00866| })();
00867| 

(End of file - total 867 lines)
</file>
```

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/bookmarklet.js",
  "limit": 780,
  "offset": 1
}
```

## Assistant

**Result** (success):
```
<file>
00002|   if (window.__mdExpertPrBookmarklet) return;
00003|   window.__mdExpertPrBookmarklet = true;
00004| 
00005|   const STORAGE_KEY = "md_expert_pr_config";
00006|   const STYLE_ID = "md-expert-pr-style";
00007|   const PANEL_ID = "md-expert-pr-panel";
00008|   const BADGE_ID = "md-expert-pr-badge";
00009| 
00010|   const DEFAULT_CONFIG = {
00011|     apiKey: "",
00012|     settingsOpen: false
00013|   };
00014| 
00015|   const state = {
00016|     config: loadConfig(),
00017|     currentResult: null,
00018|     mountRetryTimer: null,
00019|     mountRetryCount: 0
00020|   };
00021| 
00022|   function loadConfig() {
00023|     const raw = window.localStorage.getItem(STORAGE_KEY);
00024|     if (!raw) return { ...DEFAULT_CONFIG };
00025|     try {
00026|       const parsed = JSON.parse(raw);
00027|       return { ...DEFAULT_CONFIG, ...parsed };
00028|     } catch (error) {
00029|       return { ...DEFAULT_CONFIG };
00030|     }
00031|   }
00032| 
00033|   function saveConfig(nextConfig) {
00034|     state.config = { ...DEFAULT_CONFIG, ...nextConfig };
00035|     window.localStorage.setItem(STORAGE_KEY, JSON.stringify(state.config));
00036|   }
00037| 
00038|   function isPullDetailPage() {
00039|     return /\/pull\/(\d+)(\/|$)/.test(window.location.pathname);
00040|   }
00041| 
00042|   function ensureStyles() {
00043|     if (document.getElementById(STYLE_ID)) return;
00044|     const style = document.createElement("style");
00045|     style.id = STYLE_ID;
00046|     style.textContent = `
00047|       #${PANEL_ID} {
00048|         color: var(--fgColor-default, #24292f);
00049|       }
00050|       #${PANEL_ID}.discussion-sidebar-item {
00051|         margin-top: 0;
00052|       }
00053|       #${PANEL_ID}.md-pr-fallback {
00054|         margin: 16px 0;
00055|       }
00056|       #${PANEL_ID} .md-pr-panel {
00057|         font-size: 12px;
00058|         line-height: 1.5;
00059|       }
00060|       #${PANEL_ID} .md-pr-header {
00061|         display: flex;
00062|         justify-content: space-between;
00063|         align-items: center;
00064|         margin-bottom: 6px;
00065|       }
00066|       #${PANEL_ID} .md-pr-heading {
00067|         margin: 0;
00068|       }
00069|       #${PANEL_ID} .md-pr-gear {
00070|         border: none;
00071|         background: transparent;
00072|         color: var(--fgColor-muted, #57606a);
00073|         width: 20px;
00074|         height: 20px;
00075|         padding: 0;
00076|         display: inline-flex;
00077|         align-items: center;
00078|         justify-content: center;
00079|         cursor: pointer;
00080|       }
00081|       #${PANEL_ID} .md-pr-gear:hover {
00082|         color: var(--fgColor-default, #24292f);
00083|       }
00084|       #${PANEL_ID} .md-pr-settings {
00085|         display: none;
00086|         margin-top: 8px;
00087|       }
00088|       #${PANEL_ID} .md-pr-settings.md-pr-open {
00089|         display: block;
00090|       }
00091|       #${PANEL_ID} .md-pr-settings label {
00092|         display: block;
00093|         margin-bottom: 4px;
00094|         font-size: 12px;
00095|         color: var(--fgColor-muted, #57606a);
00096|       }
00097|       #${PANEL_ID} .md-pr-settings input[type="password"] {
00098|         width: 100%;
00099|         border: 1px solid var(--borderColor-default, #d0d7de);
00100|         border-radius: 6px;
00101|         padding: 5px 8px;
00102|         font-size: 12px;
00103|         color: var(--fgColor-default, #24292f);
00104|         background: var(--bgColor-default, #ffffff);
00105|       }
00106|       #${PANEL_ID} .md-pr-status {
00107|         color: var(--fgColor-muted, #57606a);
00108|       }
00109|       #${PANEL_ID} .md-pr-warning {
00110|         color: var(--fgColor-danger, #cf222e);
00111|       }
00112|       #${PANEL_ID} .md-pr-details {
00113|         color: var(--fgColor-muted, #57606a);
00114|       }
00115|       #${PANEL_ID} .md-pr-summary {
00116|         margin-bottom: 8px;
00117|         color: var(--fgColor-default, #24292f);
00118|       }
00119|       #${PANEL_ID} .md-pr-card-header {
00120|         display: flex;
00121|         gap: 8px;
00122|         align-items: flex-start;
00123|       }
00124|       #${PANEL_ID} .md-pr-avatar {
00125|         width: 32px;
00126|         height: 32px;
00127|         border-radius: 50%;
00128|         overflow: hidden;
00129|         background: var(--bgColor-muted, #f6f8fa);
00130|         display: inline-flex;
00131|         align-items: center;
00132|         justify-content: center;
00133|         font-weight: 600;
00134|         color: var(--fgColor-muted, #57606a);
00135|         flex-shrink: 0;
00136|       }
00137|       #${PANEL_ID} .md-pr-avatar img {
00138|         width: 100%;
00139|         height: 100%;
00140|         object-fit: cover;
00141|       }
00142|       #${PANEL_ID} .md-pr-name {
00143|         font-size: 13px;
00144|         font-weight: 600;
00145|         color: var(--fgColor-default, #24292f);
00146|       }
00147|       #${PANEL_ID} .md-pr-meta {
00148|         color: var(--fgColor-muted, #57606a);
00149|       }
00150|       #${PANEL_ID} .md-pr-link {
00151|         color: var(--fgColor-accent, #0969da);
00152|         text-decoration: none;
00153|       }
00154|       #${PANEL_ID} .md-pr-link:hover {
00155|         text-decoration: underline;
00156|       }
00157|       #${PANEL_ID} .md-pr-stats {
00158|         margin-top: 8px;
00159|       }
00160|       #${PANEL_ID} .md-pr-stat-item {
00161|         color: var(--fgColor-default, #24292f);
00162|       }
00163|       #${PANEL_ID} .md-pr-stat-label {
00164|         color: var(--fgColor-muted, #57606a);
00165|       }
00166|       #${PANEL_ID} .md-pr-stat-sep {
00167|         margin: 0 4px;
00168|         color: var(--fgColor-muted, #57606a);
00169|       }
00170|       #${PANEL_ID} .md-pr-section {
00171|         margin-top: 8px;
00172|       }
00173|       #${PANEL_ID} .md-pr-section-title {
00174|         margin-bottom: 2px;
00175|         font-weight: 600;
00176|         color: var(--fgColor-muted, #57606a);
00177|       }
00178|       #${PANEL_ID} .md-pr-ecosystems {
00179|         display: flex;
00180|         flex-wrap: wrap;
00181|         gap: 8px;
00182|       }
00183|       #${PANEL_ID} .md-pr-ecosystem-pill {
00184|         color: var(--fgColor-accent, #0969da);
00185|         text-decoration: none;
00186|       }
00187|       #${PANEL_ID} .md-pr-ecosystem-pill:hover {
00188|         text-decoration: underline;
00189|       }
00190|       #${PANEL_ID} .md-pr-project-list {
00191|         display: flex;
00192|         flex-direction: column;
00193|         gap: 2px;
00194|       }
00195|       #${PANEL_ID} .md-pr-project-item {
00196|         display: flex;
00197|         align-items: baseline;
00198|         justify-content: space-between;
00199|         gap: 8px;
00200|       }
00201|       #${PANEL_ID} .md-pr-project-meta {
00202|         color: var(--fgColor-muted, #57606a);
00203|         flex-shrink: 0;
00204|       }
00205|       #${PANEL_ID} .md-pr-powered {
00206|         margin-top: 8px;
00207|         font-size: 11px;
00208|         color: var(--fgColor-muted, #57606a);
00209|         opacity: 0.65;
00210|       }
00211|       #${PANEL_ID} .md-pr-powered-link {
00212|         color: inherit;
00213|         text-decoration: none;
00214|       }
00215|       #${PANEL_ID} .md-pr-powered-link:hover {
00216|         text-decoration: underline;
00217|       }
00218|       #${BADGE_ID} {
00219|         display: inline-flex;
00220|         align-items: center;
00221|         gap: 6px;
00222|         margin-left: 8px;
00223|         padding: 2px 8px;
00224|         border-radius: 999px;
00225|         font-size: 11px;
00226|         font-weight: 600;
00227|       }
00228|       #${BADGE_ID}.md-pr-badge-error {
00229|         background: #ffe4e8;
00230|         color: #9f1239;
00231|       }
00232|       #${BADGE_ID}.md-pr-badge-success {
00233|         background: #dcfce7;
00234|         color: #166534;
00235|       }
00236|     `;
00237|     document.head.appendChild(style);
00238|   }
00239| 
00240|   function clearMountRetry() {
00241|     if (!state.mountRetryTimer) return;
00242|     window.clearTimeout(state.mountRetryTimer);
00243|     state.mountRetryTimer = null;
00244|   }
00245| 
00246|   function scheduleMountRetry() {
00247|     if (state.mountRetryTimer || state.mountRetryCount >= 40 || !isPullDetailPage()) return;
00248|     state.mountRetryTimer = window.setTimeout(() => {
00249|       state.mountRetryTimer = null;
00250|       state.mountRetryCount += 1;
00251|       ensurePanel();
00252|     }, 250);
00253|   }
00254| 
00255|   function normalizeText(value) {
00256|     return String(value || "").replace(/\s+/g, " ").trim().toLowerCase();
00257|   }
00258| 
00259|   function isVisibleElement(element) {
00260|     return Boolean(element && element.isConnected && element.getClientRects().length > 0);
00261|   }
00262| 
00263|   function findSidebar() {
00264|     const selectors = [
00265|       ".discussion-sidebar",
00266|       ".Layout-sidebar .discussion-sidebar",
00267|       ".Layout-sidebar",
00268|       ".js-discussion-sidebar",
00269|       "#partial-discussion-sidebar",
00270|       "[data-testid*='sidebar']",
00271|       "aside"
00272|     ];
00273| 
00274|     const seen = new Set();
00275|     const candidates = [];
00276| 
00277|     for (const selector of selectors) {
00278|       document.querySelectorAll(selector).forEach((element) => {
00279|         if (seen.has(element)) return;
00280|         seen.add(element);
00281|         candidates.push(element);
00282|       });
00283|     }
00284| 
00285|     const scoredVisible = candidates
00286|       .filter((element) => isVisibleElement(element))
00287|       .map((element) => {
00288|         const text = normalizeText(element.textContent);
00289|         let score = 0;
00290|         if (text.includes("reviewers")) score += 5;
00291|         if (text.includes("assignees")) score += 2;
00292|         if (normalizeText(element.className).includes("sidebar")) score += 2;
00293|         if (element.tagName === "ASIDE") score += 1;
00294|         return { element, score };
00295|       })
00296|       .sort((a, b) => b.score - a.score);
00297| 
00298|     if (scoredVisible.length) return scoredVisible[0].element;
00299| 
00300|     if (candidates.length) return candidates[0];
00301| 
00302|     return null;
00303|   }
00304| 
00305|   function findReviewersSection(sidebar) {
00306|     const roots = [];
00307|     if (sidebar) roots.push(sidebar);
00308|     const discoveredSidebar = findSidebar();
00309|     if (discoveredSidebar && !roots.includes(discoveredSidebar)) roots.push(discoveredSidebar);
00310|     roots.push(document);
00311| 
00312|     for (const root of roots) {
00313|       const byClass = root.querySelector(
00314|         ".discussion-sidebar-item.sidebar-reviewers, .js-discussion-sidebar-item.sidebar-reviewers"
00315|       );
00316|       if (byClass && isVisibleElement(byClass)) return byClass;
00317| 
00318|       const byTestId = root.querySelector("[data-testid*='reviewer']");
00319|       if (byTestId && isVisibleElement(byTestId)) {
00320|         const item = byTestId.closest(
00321|           ".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section, li"
00322|         );
00323|         if (item && isVisibleElement(item)) return item;
00324|       }
00325| 
00326|       const headings = root.querySelectorAll(".discussion-sidebar-heading, h2, h3, h4, [role='heading']");
00327|       for (const heading of headings) {
00328|         if (normalizeText(heading.textContent) !== "reviewers") continue;
00329|         const item = heading.closest(
00330|           ".discussion-sidebar-item, .js-discussion-sidebar-item, [class*='sidebar-item'], section, li, aside"
00331|         );
00332|         if (item && isVisibleElement(item)) return item;
00333|       }
00334|     }
00335| 
00336|     return null;
00337|   }
00338| 
00339|   function findFallbackAnchor() {
00340|     const selectors = [
00341|       ".gh-header-show",
00342|       ".gh-header-meta",
00343|       ".js-pull-discussion-timeline",
00344|       "main [data-testid='issue-viewer']",
00345|       "main"
00346|     ];
00347| 
00348|     for (const selector of selectors) {
00349|       const element = document.querySelector(selector);
00350|       if (element && isVisibleElement(element)) return element;
00351|     }
00352| 
00353|     return null;
00354|   }
00355| 
00356|   function setWrapperPlacementClass(wrapper, inSidebar) {
00357|     if (inSidebar) {
00358|       wrapper.classList.add("discussion-sidebar-item");
00359|       wrapper.classList.remove("md-pr-fallback");
00360|       return;
00361|     }
00362| 
00363|     wrapper.classList.remove("discussion-sidebar-item");
00364|     wrapper.classList.add("md-pr-fallback");
00365|   }
00366| 
00367|   function mountPanel(wrapper) {
00368|     const reviewersSection = findReviewersSection();
00369|     if (reviewersSection) {
00370|       setWrapperPlacementClass(wrapper, true);
00371|       if (reviewersSection.nextElementSibling !== wrapper) {
00372|         reviewersSection.insertAdjacentElement("afterend", wrapper);
00373|       }
00374|       return true;
00375|     }
00376| 
00377|     const sidebar = findSidebar();
00378|     if (sidebar) {
00379|       setWrapperPlacementClass(wrapper, true);
00380|       if (wrapper.parentElement !== sidebar) {
00381|         sidebar.appendChild(wrapper);
00382|       }
00383|       return true;
00384|     }
00385| 
00386|     const fallbackAnchor = findFallbackAnchor();
00387|     if (fallbackAnchor) {
00388|       setWrapperPlacementClass(wrapper, false);
00389|       if (fallbackAnchor.tagName === "MAIN") {
00390|         if (wrapper.parentElement !== fallbackAnchor || fallbackAnchor.firstElementChild !== wrapper) {
00391|           fallbackAnchor.prepend(wrapper);
00392|         }
00393|         return true;
00394|       }
00395| 
00396|       if (fallbackAnchor.nextElementSibling !== wrapper) {
00397|         fallbackAnchor.insertAdjacentElement("afterend", wrapper);
00398|       }
00399|       return true;
00400|     }
00401| 
00402|     return false;
00403|   }
00404| 
00405|   function ensurePanel() {
00406|     const existing = document.getElementById(PANEL_ID);
00407|     if (!isPullDetailPage()) {
00408|       if (existing) existing.remove();
00409|       clearMountRetry();
00410|       state.mountRetryCount = 0;
00411|       removeBadge();
00412|       return;
00413|     }
00414| 
00415|     ensureStyles();
00416| 
00417|     if (existing) {
00418|       if (!mountPanel(existing)) {
00419|         scheduleMountRetry();
00420|         return;
00421|       }
00422|       clearMountRetry();
00423|       state.mountRetryCount = 0;
00424|       updatePanel(existing);
00425|       return;
00426|     }
00427| 
00428|     const wrapper = document.createElement("div");
00429|     wrapper.id = PANEL_ID;
00430|     wrapper.innerHTML = `
00431|       <div class="md-pr-panel">
00432|         <div class="md-pr-header">
00433|           <h3 class="discussion-sidebar-heading md-pr-heading">Contributor insights</h3>
00434|           <button class="md-pr-gear" type="button" aria-label="Settings">
00435|             <span aria-hidden="true">⚙</span>
00436|           </button>
00437|         </div>
00438|         <div class="md-pr-body">
00439|           <div class="md-pr-summary"></div>
00440|           <div class="md-pr-status"></div>
00441|           <div class="md-pr-details"></div>
00442|         </div>
00443|         <div class="md-pr-settings ${state.config.settingsOpen ? "md-pr-open" : ""}">
00444|           <label for="${PANEL_ID}-api-key">API key</label>
00445|           <input id="${PANEL_ID}-api-key" type="password" data-config="apiKey" />
00446|           <div class="md-pr-status"></div>
00447|         </div>
00448|         <div class="md-pr-powered">Powered by the <a class="md-pr-powered-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Open Source Explorer</a></div>
00449|       </div>
00450|     `;
00451| 
00452|     wrapper.querySelector(".md-pr-gear").addEventListener("click", () => {
00453|       const settings = wrapper.querySelector(".md-pr-settings");
00454|       const open = settings.classList.toggle("md-pr-open");
00455|       saveConfig({ ...state.config, settingsOpen: open });
00456|     });
00457| 
00458|     wrapper.querySelectorAll("[data-config]").forEach((input) => {
00459|       const key = input.getAttribute("data-config");
00460|       input.value = state.config[key] ?? "";
00461|       input.addEventListener("change", () => {
00462|         saveConfig({ ...state.config, [key]: input.value });
00463|         applyCheck();
00464|       });
00465|     });
00466| 
00467|     if (!mountPanel(wrapper)) {
00468|       scheduleMountRetry();
00469|       return;
00470|     }
00471| 
00472|     clearMountRetry();
00473|     state.mountRetryCount = 0;
00474| 
00475|     updatePanel(wrapper);
00476|   }
00477| 
00478|   function updatePanel(wrapper) {
00479|     const summary = wrapper.querySelector(".md-pr-summary");
00480|     const statusBlocks = wrapper.querySelectorAll(".md-pr-status");
00481|     const details = wrapper.querySelector(".md-pr-details");
00482|     const result = state.currentResult;
00483| 
00484|     statusBlocks.forEach((status) => {
00485|       status.textContent = "";
00486|       status.innerHTML = "";
00487|     });
00488| 
00489|     if (!result) {
00490|       statusBlocks.forEach((status) => {
00491|         status.textContent = "Checking PR author...";
00492|       });
00493|       summary.textContent = "";
00494|       details.textContent = "";
00495|       return;
00496|     }
00497| 
00498|     if (result.state === "missing-key") {
00499|       statusBlocks.forEach((status) => {
00500|         status.innerHTML = `<span class="md-pr-warning">API key required</span>`;
00501|       });
00502|       summary.textContent = "";
00503|       details.textContent = "";
00504|       return;
00505|     }
00506| 
00507|     if (result.state === "error") {
00508|       statusBlocks.forEach((status) => {
00509|         status.innerHTML = `<span class="md-pr-warning">${result.message}</span>`;
00510|       });
00511|       summary.textContent = "";
00512|       details.textContent = "";
00513|       return;
00514|     }
00515| 
00516|     if (result.state === "not-expert") {
00517|       statusBlocks.forEach((status) => {
00518|         status.innerHTML = "";
00519|       });
00520|       summary.textContent = "No contributor profile found yet.";
00521|       details.textContent = "";
00522|       return;
00523|     }
00524| 
00525|     if (result.state === "expert") {
00526|       statusBlocks.forEach((status) => {
00527|         status.innerHTML = "";
00528|       });
00529|       const info = result.expert && result.expert.expert ? result.expert.expert : result.expert;
00530|       summary.textContent = buildSummary(info, result.username);
00531|       details.innerHTML = renderExpertDetails(info, result.username);
00532|     }
00533|   }
00534| 
00535|   function buildSummary(info, username) {
00536|     if (!info) return `This PR was opened by ${username}.`;
00537|     const name = info.name || username;
00538|     const downloadsRaw = Number(info.total_downloads || 0);
00539|     const downloads = downloadsRaw > 0 ? formatCompactNumber(downloadsRaw) : null;
00540|     const stars = formatCompactNumber(info.total_stars);
00541|     const downloadText = downloads ? `${downloads} total downloads` : "";
00542|     const starsText = stars ? `${stars} stars on repos` : "";
00543|     const stats = [downloadText, starsText].filter(Boolean).join(", ");
00544|     if (!stats) return `This PR was opened by ${name} (${username}).`;
00545|     return `This PR was opened by ${name} (${username}). They have received ${stats}.`;
00546|   }
00547| 
00548|   function formatCompactNumber(value) {
00549|     if (value === null || value === undefined) return null;
00550|     const num = Number(value);
00551|     if (Number.isNaN(num)) return null;
00552|     return new Intl.NumberFormat("en", {
00553|       notation: "compact",
00554|       maximumFractionDigits: 1
00555|     }).format(num);
00556|   }
00557| 
00558|   function renderExpertDetails(info, username) {
00559|     const profileUrl = `https://explore.market.dev/experts/${encodeURIComponent(username)}`;
00560|     if (!info) {
00561|       return `Expert profile: <a class="md-pr-link" href="${profileUrl}" target="_blank" rel="noopener noreferrer">Open</a>`;
00562|     }
00563| 
00564|     const name = info.name || username;
00565|     const avatarUrl = info.avatar_url || info.avatar || null;
00566|     const location = info.location || info.display_location || "";
00567| 
00568|     const stats = [
00569|       { label: "Projects", value: formatCompactNumber(info.projects_count) },
00570|       { label: "Downloads", value: formatCompactNumber(info.total_downloads) },
00571|       { label: "Stars", value: formatCompactNumber(info.total_stars) }
00572|     ].filter((stat) => stat.value !== null);
00573| 
00574|     const projects = Array.isArray(info.projects) ? info.projects : [];
00575|     const sortedProjects = [...projects].sort((a, b) => {
00576|       const starsA = Number(a.total_stars || a.stars || 0);
00577|       const starsB = Number(b.total_stars || b.stars || 0);
00578|       if (starsB !== starsA) return starsB - starsA;
00579|       const downloadsA = Number(a.total_downloads || a.downloads || 0);
00580|       const downloadsB = Number(b.total_downloads || b.downloads || 0);
00581|       return downloadsB - downloadsA;
00582|     });
00583|     const maintainerItems = sortedProjects.slice(0, 10).map((project) => {
00584|       const role = project.role || project.project_experts?.[0]?.role;
00585|       const name = project.name || project.slug || "";
00586|       if (!name) return null;
00587|       const stars = formatCompactNumber(project.total_stars || project.stars);
00588|       const downloads = formatCompactNumber(project.total_downloads || project.downloads);
00589|       const metaParts = [stars ? `${stars} stars` : null, downloads ? `${downloads} downloads` : null]
00590|         .filter(Boolean)
00591|         .join(" · ");
00592|       const label = role ? `${role} of ${name}` : name;
00593|       const projectSlug = project.slug || project.name || "";
00594|       const projectUrl =
00595|         project.github_url ||
00596|         project.repo_url ||
00597|         project.url ||
00598|         (projectSlug ? `https://explore.market.dev/projects/${encodeURIComponent(projectSlug)}` : null);
00599|       return { label, meta: metaParts, url: projectUrl };
00600|     }).filter(Boolean);
00601| 
00602|     const ecosystems =
00603|       (Array.isArray(info.ecosystems) && info.ecosystems) ||
00604|       (Array.isArray(info.ecosystem_names) && info.ecosystem_names) ||
00605|       [];
00606| 
00607|     const ecosystemNames = ecosystems
00608|       .map((eco) => (typeof eco === "string" ? eco : eco.name))
00609|       .filter(Boolean)
00610|       .slice(0, 8)
00611|       .map((name) => ({
00612|         name,
00613|         url: `https://explore.market.dev/ecosystems/${encodeURIComponent(name)}`
00614|       }));
00615| 
00616|     return `
00617|       <div class="md-pr-card">
00618|         <div class="md-pr-card-header">
00619|           <div class="md-pr-avatar">
00620|             ${avatarUrl ? `<img src="${avatarUrl}" alt="${name}" />` : name.slice(0, 1).toUpperCase()}
00621|           </div>
00622|           <div>
00623|             <div class="md-pr-name"><a class="md-pr-link" href="https://github.com/${encodeURIComponent(username)}" target="_blank" rel="noopener noreferrer">${name}</a></div>
00624|             <div class="md-pr-meta">@${username}${location ? ` · ${location}` : ""}</div>
00625|           </div>
00626|         </div>
00627|         ${stats.length ? `
00628|           <div class="md-pr-stats">
00629|             ${stats
00630|               .map(
00631|                 (stat) => `<span class="md-pr-stat-item"><span class="md-pr-stat-label">${stat.label}:</span> ${stat.value}</span>`
00632|               )
00633|               .join('<span class="md-pr-stat-sep">·</span>')}
00634|           </div>
00635|         ` : ""}
00636|         ${ecosystemNames.length ? `
00637|           <div class="md-pr-section">
00638|             <div class="md-pr-section-title">Ecosystems</div>
00639|             <div class="md-pr-ecosystems">
00640|               ${ecosystemNames
00641|                 .map((eco) => `<a class="md-pr-ecosystem-pill" href="${eco.url}" target="_blank" rel="noopener noreferrer">${eco.name}</a>`)
00642|                 .join("")}
00643|             </div>
00644|           </div>
00645|         ` : ""}
00646|         ${maintainerItems.length ? `
00647|           <div class="md-pr-section">
00648|             <div class="md-pr-section-title">Notable Projects</div>
00649|             <div class="md-pr-project-list">
00650|               ${maintainerItems
00651|                 .map(
00652|                   (item) => `
00653|                     <div class="md-pr-project-item">
00654|                       ${item.url ? `<a class="md-pr-link" href="${item.url}" target="_blank" rel="noopener noreferrer">${item.label}</a>` : `<span>${item.label}</span>`}
00655|                       ${item.meta ? `<span class="md-pr-project-meta">${item.meta}</span>` : ""}
00656|                     </div>
00657|                   `
00658|                 )
00659|                 .join("")}
00660|             </div>
00661|           </div>
00662|         ` : ""}
00663|       </div>
00664|     `;
00665|   }
00666| 
00667|   function findPrAuthor() {
00668|     const selectors = [
00669|       ".gh-header-meta .author",
00670|       ".js-discussion .timeline-comment-header .author",
00671|       ".js-discussion .author",
00672|       ".timeline-comment-header .author",
00673|       "a.author"
00674|     ];
00675|     for (const selector of selectors) {
00676|       const el = document.querySelector(selector);
00677|       if (el && el.textContent.trim()) return el.textContent.trim();
00678|     }
00679|     return null;
00680|   }
00681| 
00682|   function removeBadge() {
00683|     const existing = document.getElementById(BADGE_ID);
00684|     if (existing) existing.remove();
00685|   }
00686| 
00687|   function updateBadge(result) {
00688|     const header = document.querySelector(".gh-header-title") || document.querySelector(".gh-header-meta");
00689|     if (!header) return;
00690| 
00691|     removeBadge();
00692|     if (!result || result.state === "error" || result.state === "missing-key") return;
00693| 
00694|     const badge = document.createElement("span");
00695|     badge.id = BADGE_ID;
00696| 
00697|     if (result.state === "not-expert") {
00698|       badge.className = "md-pr-badge-error";
00699|       badge.textContent = "No Profile";
00700|       header.appendChild(badge);
00701|     }
00702|   }
00703| 
00704|   async function fetchExpert(username) {
00705|     const apiKey = String(state.config.apiKey || "").trim();
00706|     if (!apiKey) return { state: "missing-key" };
00707| 
00708|     const url = `https://explore.market.dev/api/v1/experts/${encodeURIComponent(username)}`;
00709| 
00710|     try {
00711|       const response = await fetch(url, {
00712|         headers: {
00713|           Authorization: `Bearer ${apiKey}`,
00714|           Accept: "application/json"
00715|         }
00716|       });
00717|       const text = await response.text();
00718|       let data = null;
00719|       try {
00720|         data = text ? JSON.parse(text) : null;
00721|       } catch (error) {
00722|         data = null;
00723|       }
00724| 
00725|       if (response.status === 200) return { state: "expert", expert: data };
00726|       if (response.status === 404) return { state: "not-expert" };
00727|       if (response.status === 401) return { state: "error", message: "Auth failed" };
00728|       return { state: "error", message: "API request failed" };
00729|     } catch (error) {
00730|       return { state: "error", message: "API request failed" };
00731|     }
00732|   }
00733| 
00734|   async function applyCheck() {
00735|     ensurePanel();
00736|     if (!isPullDetailPage()) return;
00737| 
00738|     const username = findPrAuthor();
00739|     if (!username) {
00740|       state.currentResult = { state: "error", message: "PR author not found" };
00741|       updateBadge(state.currentResult);
00742|       const panel = document.getElementById(PANEL_ID);
00743|       if (panel) updatePanel(panel);
00744|       return;
00745|     }
00746| 
00747|     state.currentResult = null;
00748|     const panel = document.getElementById(PANEL_ID);
00749|     if (panel) updatePanel(panel);
00750| 
00751|     const result = await fetchExpert(username);
00752|     state.currentResult = { ...result, username };
00753|     updateBadge(state.currentResult);
00754|     if (panel) updatePanel(panel);
00755|   }
00756| 
00757|   function init() {
00758|     applyCheck();
00759|   }
00760| 
00761|   if (document.readyState === "loading") {
00762|     document.addEventListener("DOMContentLoaded", init);
00763|   } else {
00764|     init();
00765|   }
00766| })();
00767| 

(End of file - total 767 lines)
</file>
```

## Assistant

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n   const STORAGE_KEY = \"md_expert_pr_config\";\n+  const NAV_CACHE_KEY = \"md_expert_pr_nav_cache\";\n   const STYLE_ID = \"md-expert-pr-style\";\n   const PANEL_ID = \"md-expert-pr-panel\";\n   const BADGE_ID = \"md-expert-pr-badge\";\n+  const NAV_CACHE_MAX_AGE_MS = 1000 * 60 * 60 * 8;\n@@\n   const state = {\n     config: loadConfig(),\n     currentResult: null,\n     listCache: new Map(),\n     mountRetryTimer: null,\n-    mountRetryCount: 0\n+    mountRetryCount: 0,\n+    keyboardListenerAttached: false\n   };\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n   function isPullListPage() {\n     return /\\/pulls(\\/|$)/.test(window.location.pathname);\n   }\n+\n+  function normalizePullPath(urlLike) {\n+    try {\n+      const url = new URL(String(urlLike || \"\"), window.location.origin);\n+      const match = url.pathname.match(/^\\/[^/]+\\/[^/]+\\/pull\\/\\d+/);\n+      return match ? match[0] : null;\n+    } catch (error) {\n+      return null;\n+    }\n+  }\n+\n+  function getRepoPathFromPullPath(pullPath) {\n+    const match = String(pullPath || \"\").match(/^\\/[^/]+\\/[^/]+/);\n+    return match ? match[0] : null;\n+  }\n+\n+  function readNavigationCache() {\n+    const raw = window.localStorage.getItem(NAV_CACHE_KEY);\n+    if (!raw) return null;\n+    try {\n+      const parsed = JSON.parse(raw);\n+      if (!parsed || !Array.isArray(parsed.pullPaths)) return null;\n+      if (typeof parsed.updatedAt !== \"number\") return null;\n+      return parsed;\n+    } catch (error) {\n+      return null;\n+    }\n+  }\n+\n+  function writeNavigationCache(pullPaths) {\n+    if (!Array.isArray(pullPaths) || !pullPaths.length) return;\n+    const repoPath = getRepoPathFromPullPath(pullPaths[0]);\n+    if (!repoPath) return;\n+\n+    window.localStorage.setItem(\n+      NAV_CACHE_KEY,\n+      JSON.stringify({\n+        repoPath,\n+        listPath: window.location.pathname,\n+        listSearch: window.location.search || \"\",\n+        pullPaths,\n+        updatedAt: Date.now()\n+      })\n+    );\n+  }\n+\n+  function cachePullListOrder() {\n+    if (!isPullListPage()) return;\n+\n+    const rows = document.querySelectorAll(\"div.js-issue-row\");\n+    const pullPaths = [];\n+    const seen = new Set();\n+\n+    rows.forEach((row) => {\n+      const titleLink =\n+        row.querySelector(\"a[data-hovercard-type='pull_request']\") ||\n+        row.querySelector(\"a[id^='issue_']\") ||\n+        row.querySelector(\"a.Link--primary[href*='/pull/']\");\n+      if (!titleLink) return;\n+\n+      const pullPath = normalizePullPath(titleLink.getAttribute(\"href\") || titleLink.href);\n+      if (!pullPath || seen.has(pullPath)) return;\n+\n+      seen.add(pullPath);\n+      pullPaths.push(pullPath);\n+    });\n+\n+    writeNavigationCache(pullPaths);\n+  }\n+\n+  function isEditableTarget(target) {\n+    const element = target instanceof Element ? target : null;\n+    if (!element) return false;\n+    if (element.closest(\"input, textarea, select, button, [contenteditable=''], [contenteditable='true'], [role='textbox']\")) {\n+      return true;\n+    }\n+    return false;\n+  }\n+\n+  function getAdjacentPullPath(direction) {\n+    const currentPullPath = normalizePullPath(window.location.href);\n+    if (!currentPullPath) return null;\n+\n+    const cache = readNavigationCache();\n+    if (!cache) return null;\n+    if (!Array.isArray(cache.pullPaths) || cache.pullPaths.length < 2) return null;\n+    if (Date.now() - cache.updatedAt > NAV_CACHE_MAX_AGE_MS) return null;\n+\n+    const repoPath = getRepoPathFromPullPath(currentPullPath);\n+    if (!repoPath || cache.repoPath !== repoPath) return null;\n+\n+    const currentIndex = cache.pullPaths.indexOf(currentPullPath);\n+    if (currentIndex === -1) return null;\n+\n+    const targetIndex = (currentIndex + direction + cache.pullPaths.length) % cache.pullPaths.length;\n+    if (targetIndex === currentIndex) return null;\n+\n+    return cache.pullPaths[targetIndex];\n+  }\n+\n+  function navigateToAdjacentPull(direction) {\n+    const targetPath = getAdjacentPullPath(direction);\n+    if (!targetPath) return false;\n+    window.location.assign(targetPath);\n+    return true;\n+  }\n+\n+  function handlePullNavigationShortcut(event) {\n+    if (!isPullDetailPage()) return;\n+    if (event.defaultPrevented) return;\n+    if (event.metaKey || event.ctrlKey || event.altKey) return;\n+    if (isEditableTarget(event.target)) return;\n+\n+    let direction = 0;\n+    if (event.key === \"]\") direction = 1;\n+    if (event.key === \"[\") direction = -1;\n+    if (!direction) return;\n+\n+    const navigated = navigateToAdjacentPull(direction);\n+    if (!navigated) return;\n+\n+    event.preventDefault();\n+    event.stopPropagation();\n+  }\n+\n+  function ensureKeyboardShortcutBinding() {\n+    if (state.keyboardListenerAttached) return;\n+    state.keyboardListenerAttached = true;\n+    document.addEventListener(\"keydown\", handlePullNavigationShortcut, true);\n+  }\n \n   function canUseBackground() {\n     return typeof chrome !== \"undefined\" && chrome.runtime && chrome.runtime.sendMessage;\n   }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n   async function applyListIndicators() {\n     if (!isPullListPage()) return;\n+\n+    cachePullListOrder();\n \n     const rows = document.querySelectorAll(\"div.js-issue-row\");\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n   function init() {\n+    ensureKeyboardShortcutBinding();\n+    cachePullListOrder();\n     applyCheck();\n     applyListIndicators();\n   }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check content.js",
  "description": "Validate content script after shortcut feature"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git diff -- content.js",
  "description": "Review content script changes for shortcut support"
}
```

## Assistant

**Result** (success):
```
diff --git a/content.js b/content.js
index 2475cdf..584293d 100644
--- a/content.js
+++ b/content.js
@@ -1,8 +1,10 @@
 (() => {
   const STORAGE_KEY = "md_expert_pr_config";
+  const NAV_CACHE_KEY = "md_expert_pr_nav_cache";
   const STYLE_ID = "md-expert-pr-style";
   const PANEL_ID = "md-expert-pr-panel";
   const BADGE_ID = "md-expert-pr-badge";
+  const NAV_CACHE_MAX_AGE_MS = 1000 * 60 * 60 * 8;
 
   const DEFAULT_CONFIG = {
     apiKey: "",
@@ -14,7 +16,8 @@
     currentResult: null,
     listCache: new Map(),
     mountRetryTimer: null,
-    mountRetryCount: 0
+    mountRetryCount: 0,
+    keyboardListenerAttached: false
   };
 
   function loadConfig() {
@@ -41,6 +44,136 @@
     return /\/pulls(\/|$)/.test(window.location.pathname);
   }
 
+  function normalizePullPath(urlLike) {
+    try {
+      const url = new URL(String(urlLike || ""), window.location.origin);
+      const match = url.pathname.match(/^\/[^/]+\/[^/]+\/pull\/\d+/);
+      return match ? match[0] : null;
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function getRepoPathFromPullPath(pullPath) {
+    const match = String(pullPath || "").match(/^\/[^/]+\/[^/]+/);
+    return match ? match[0] : null;
+  }
+
+  function readNavigationCache() {
+    const raw = window.localStorage.getItem(NAV_CACHE_KEY);
+    if (!raw) return null;
+    try {
+      const parsed = JSON.parse(raw);
+      if (!parsed || !Array.isArray(parsed.pullPaths)) return null;
+      if (typeof parsed.updatedAt !== "number") return null;
+      return parsed;
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeNavigationCache(pullPaths) {
+    if (!Array.isArray(pullPaths) || !pullPaths.length) return;
+    const repoPath = getRepoPathFromPullPath(pullPaths[0]);
+    if (!repoPath) return;
+
+    window.localStorage.setItem(
+      NAV_CACHE_KEY,
+      JSON.stringify({
+        repoPath,
+        listPath: window.location.pathname,
+        listSearch: window.location.search || "",
+        pullPaths,
+        updatedAt: Date.now()
+      })
+    );
+  }
+
+  function cachePullListOrder() {
+    if (!isPullListPage()) return;
+
+    const rows = document.querySelectorAll("div.js-issue-row");
+    const pullPaths = [];
+    const seen = new Set();
+
+    rows.forEach((row) => {
+      const titleLink =
+        row.querySelector("a[data-hovercard-type='pull_request']") ||
+        row.querySelector("a[id^='issue_']") ||
+        row.querySelector("a.Link--primary[href*='/pull/']");
+      if (!titleLink) return;
+
+      const pullPath = normalizePullPath(titleLink.getAttribute("href") || titleLink.href);
+      if (!pullPath || seen.has(pullPath)) return;
+
+      seen.add(pullPath);
+      pullPaths.push(pullPath);
+    });
+
+    writeNavigationCache(pullPaths);
+  }
+
+  function isEditableTarget(target) {
+    const element = target instanceof Element ? target : null;
+    if (!element) return false;
+    if (element.closest("input, textarea, select, button, [contenteditable=''], [contenteditable='true'], [role='textbox']")) {
+      return true;
+    }
+    return false;
+  }
+
+  function getAdjacentPullPath(direction) {
+    const currentPullPath = normalizePullPath(window.location.href);
+    if (!currentPullPath) return null;
+
+    const cache = readNavigationCache();
+    if (!cache) return null;
+    if (!Array.isArray(cache.pullPaths) || cache.pullPaths.length < 2) return null;
+    if (Date.now() - cache.updatedAt > NAV_CACHE_MAX_AGE_MS) return null;
+
+    const repoPath = getRepoPathFromPullPath(currentPullPath);
+    if (!repoPath || cache.repoPath !== repoPath) return null;
+
+    const currentIndex = cache.pullPaths.indexOf(currentPullPath);
+    if (currentIndex === -1) return null;
+
+    const targetIndex = (currentIndex + direction + cache.pullPaths.length) % cache.pullPaths.length;
+    if (targetIndex === currentIndex) return null;
+
+    return cache.pullPaths[targetIndex];
+  }
+
+  function navigateToAdjacentPull(direction) {
+    const targetPath = getAdjacentPullPath(direction);
+    if (!targetPath) return false;
+    window.location.assign(targetPath);
+    return true;
+  }
+
+  function handlePullNavigationShortcut(event) {
+    if (!isPullDetailPage()) return;
+    if (event.defaultPrevented) return;
+    if (event.metaKey || event.ctrlKey || event.altKey) return;
+    if (isEditableTarget(event.target)) return;
+
+    let direction = 0;
+    if (event.key === "]") direction = 1;
+    if (event.key === "[") direction = -1;
+    if (!direction) return;
+
+    const navigated = navigateToAdjacentPull(direction);
+    if (!navigated) return;
+
+    event.preventDefault();
+    event.stopPropagation();
+  }
+
+  function ensureKeyboardShortcutBinding() {
+    if (state.keyboardListenerAttached) return;
+    state.keyboardListenerAttached = true;
+    document.addEventListener("keydown", handlePullNavigationShortcut, true);
+  }
+
   function canUseBackground() {
     return typeof chrome !== "undefined" && chrome.runtime && chrome.runtime.sendMessage;
   }
@@ -809,6 +942,8 @@
   async function applyListIndicators() {
     if (!isPullListPage()) return;
 
+    cachePullListOrder();
+
     const rows = document.querySelectorAll("div.js-issue-row");
     rows.forEach((row) => {
       const author = row.getAttribute("data-author");
@@ -852,6 +987,8 @@
   }
 
   function init() {
+    ensureKeyboardShortcutBinding();
+    cachePullListOrder();
     applyCheck();
     applyListIndicators();
   }

```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git status --short",
  "description": "Check modified files after shortcut implementation"
}
```

## Assistant

**Result** (success):
```
 M content.js

```

## Assistant

## Assistant

Implemented option 1 in the extension (`content.js`).

- Added keyboard shortcuts on PR detail pages:
  - `]` = next PR
  - `[` = previous PR
- It follows the PR order from the most recent `/pulls` list you visited in that repo (so it tracks current list ordering/filtering).
- It wraps around at the ends (last -> first, first -> last).
- It won’t trigger while you’re typing in inputs/textareas/contenteditable fields.

Notes:
- If you open a PR directly (without visiting the PR list first), there may be no cached order yet. Open that repo’s `/pulls` once, then shortcuts work.
- Not committed/pushed yet. If you want, I can commit and push this change now.

## User

Make the arrows -> do the nav, and add a small hint at the bottom after Powered by: saying "View next PR using <- ->" 

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n       #${PANEL_ID} .md-pr-powered {\n         margin-top: 8px;\n         font-size: 11px;\n         color: var(--fgColor-muted, #57606a);\n         opacity: 0.65;\n       }\n+      #${PANEL_ID} .md-pr-nav-hint {\n+        margin-top: 2px;\n+        font-size: 10px;\n+        color: var(--fgColor-muted, #57606a);\n+        opacity: 0.55;\n+      }\n       #${PANEL_ID} .md-pr-powered-link {\n         color: inherit;\n         text-decoration: none;\n       }\n@@\n-    if (event.metaKey || event.ctrlKey || event.altKey) return;\n+    if (event.metaKey || event.ctrlKey || event.altKey) return;\n     if (isEditableTarget(event.target)) return;\n \n     let direction = 0;\n+    if (event.key === \"ArrowRight\") direction = 1;\n+    if (event.key === \"ArrowLeft\") direction = -1;\n     if (event.key === \"]\") direction = 1;\n     if (event.key === \"[\") direction = -1;\n     if (!direction) return;\n@@\n         <div class=\"md-pr-settings ${state.config.settingsOpen ? \"md-pr-open\" : \"\"}\">\n           <label for=\"${PANEL_ID}-api-key\">API key</label>\n           <input id=\"${PANEL_ID}-api-key\" type=\"password\" data-config=\"apiKey\" />\n           <div class=\"md-pr-status\"></div>\n         </div>\n         <div class=\"md-pr-powered\">Powered by the <a class=\"md-pr-powered-link\" href=\"https://explore.market.dev\" target=\"_blank\" rel=\"noopener noreferrer\">Open Source Explorer</a></div>\n+        <div class=\"md-pr-nav-hint\">View next PR using <- -></div>\n       </div>\n     `;\n*** End Patch"
}
```

## Assistant

**Result** (error):
```
(empty result)
```

## Assistant

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "pattern": "function handlePullNavigationShortcut|md-pr-powered|md-pr-powered-link"
}
```

## Assistant

**Result** (success):
```
Found 5 matches
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js:
  Line 153:   function handlePullNavigationShortcut(event) {
  Line 360:       #${PANEL_ID} .md-pr-powered {
  Line 366:       #${PANEL_ID} .md-pr-powered-link {
  Line 370:       #${PANEL_ID} .md-pr-powered-link:hover {
  Line 620:         <div class="md-pr-powered">Powered by the <a class="md-pr-powered-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Open Source Explorer</a></div>
```

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 80,
  "offset": 120
}
```

## Assistant

**Result** (success):
```
<file>
00121|     }
00122|     return false;
00123|   }
00124| 
00125|   function getAdjacentPullPath(direction) {
00126|     const currentPullPath = normalizePullPath(window.location.href);
00127|     if (!currentPullPath) return null;
00128| 
00129|     const cache = readNavigationCache();
00130|     if (!cache) return null;
00131|     if (!Array.isArray(cache.pullPaths) || cache.pullPaths.length < 2) return null;
00132|     if (Date.now() - cache.updatedAt > NAV_CACHE_MAX_AGE_MS) return null;
00133| 
00134|     const repoPath = getRepoPathFromPullPath(currentPullPath);
00135|     if (!repoPath || cache.repoPath !== repoPath) return null;
00136| 
00137|     const currentIndex = cache.pullPaths.indexOf(currentPullPath);
00138|     if (currentIndex === -1) return null;
00139| 
00140|     const targetIndex = (currentIndex + direction + cache.pullPaths.length) % cache.pullPaths.length;
00141|     if (targetIndex === currentIndex) return null;
00142| 
00143|     return cache.pullPaths[targetIndex];
00144|   }
00145| 
00146|   function navigateToAdjacentPull(direction) {
00147|     const targetPath = getAdjacentPullPath(direction);
00148|     if (!targetPath) return false;
00149|     window.location.assign(targetPath);
00150|     return true;
00151|   }
00152| 
00153|   function handlePullNavigationShortcut(event) {
00154|     if (!isPullDetailPage()) return;
00155|     if (event.defaultPrevented) return;
00156|     if (event.metaKey || event.ctrlKey || event.altKey) return;
00157|     if (isEditableTarget(event.target)) return;
00158| 
00159|     let direction = 0;
00160|     if (event.key === "]") direction = 1;
00161|     if (event.key === "[") direction = -1;
00162|     if (!direction) return;
00163| 
00164|     const navigated = navigateToAdjacentPull(direction);
00165|     if (!navigated) return;
00166| 
00167|     event.preventDefault();
00168|     event.stopPropagation();
00169|   }
00170| 
00171|   function ensureKeyboardShortcutBinding() {
00172|     if (state.keyboardListenerAttached) return;
00173|     state.keyboardListenerAttached = true;
00174|     document.addEventListener("keydown", handlePullNavigationShortcut, true);
00175|   }
00176| 
00177|   function canUseBackground() {
00178|     return typeof chrome !== "undefined" && chrome.runtime && chrome.runtime.sendMessage;
00179|   }
00180| 
00181|   function fetchViaBackground(url, apiKey) {
00182|     if (!canUseBackground()) return Promise.resolve(null);
00183|     return new Promise((resolve) => {
00184|       chrome.runtime.sendMessage(
00185|         { type: "md-expert-pr-check", url, apiKey },
00186|         (response) => {
00187|           if (chrome.runtime.lastError) {
00188|             resolve(null);
00189|             return;
00190|           }
00191|           resolve(response);
00192|         }
00193|       );
00194|     });
00195|   }
00196| 
00197|   function ensureStyles() {
00198|     if (document.getElementById(STYLE_ID)) return;
00199|     const style = document.createElement("style");
00200|     style.id = STYLE_ID;

(File has more lines. Use 'offset' parameter to read beyond line 200)
</file>
```

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 60,
  "offset": 336
}
```

## Assistant

**Result** (success):
```
<file>
00337|       }
00338|       #${PANEL_ID} .md-pr-ecosystem-pill {
00339|         color: var(--fgColor-accent, #0969da);
00340|         text-decoration: none;
00341|       }
00342|       #${PANEL_ID} .md-pr-ecosystem-pill:hover {
00343|         text-decoration: underline;
00344|       }
00345|       #${PANEL_ID} .md-pr-project-list {
00346|         display: flex;
00347|         flex-direction: column;
00348|         gap: 2px;
00349|       }
00350|       #${PANEL_ID} .md-pr-project-item {
00351|         display: flex;
00352|         align-items: baseline;
00353|         justify-content: space-between;
00354|         gap: 8px;
00355|       }
00356|       #${PANEL_ID} .md-pr-project-meta {
00357|         color: var(--fgColor-muted, #57606a);
00358|         flex-shrink: 0;
00359|       }
00360|       #${PANEL_ID} .md-pr-powered {
00361|         margin-top: 8px;
00362|         font-size: 11px;
00363|         color: var(--fgColor-muted, #57606a);
00364|         opacity: 0.65;
00365|       }
00366|       #${PANEL_ID} .md-pr-powered-link {
00367|         color: inherit;
00368|         text-decoration: none;
00369|       }
00370|       #${PANEL_ID} .md-pr-powered-link:hover {
00371|         text-decoration: underline;
00372|       }
00373|       .md-pr-list-indicator {
00374|         display: inline-flex;
00375|         align-items: center;
00376|         justify-content: center;
00377|         width: 8px;
00378|         height: 8px;
00379|         border-radius: 999px;
00380|         margin-left: 6px;
00381|         border: 1px solid #d0d7de;
00382|       }
00383|       .md-pr-list-indicator.md-pr-list-expert {
00384|         background: #2da44e;
00385|         border-color: #2da44e;
00386|       }
00387|       .md-pr-list-indicator.md-pr-list-missing {
00388|         background: #afb8c1;
00389|       }
00390|       #${BADGE_ID} {
00391|         display: inline-flex;
00392|         align-items: center;
00393|         gap: 6px;
00394|         margin-left: 8px;
00395|         padding: 2px 8px;
00396|         border-radius: 999px;

(File has more lines. Use 'offset' parameter to read beyond line 396)
</file>
```

## Assistant

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 40,
  "offset": 602
}
```

## Assistant

**Result** (success):
```
<file>
00603|       <div class="md-pr-panel">
00604|         <div class="md-pr-header">
00605|           <h3 class="discussion-sidebar-heading md-pr-heading">Contributor insights</h3>
00606|           <button class="md-pr-gear" type="button" aria-label="Settings">
00607|             <span aria-hidden="true">⚙</span>
00608|           </button>
00609|         </div>
00610|         <div class="md-pr-body">
00611|           <div class="md-pr-summary"></div>
00612|           <div class="md-pr-status"></div>
00613|           <div class="md-pr-details"></div>
00614|         </div>
00615|         <div class="md-pr-settings ${state.config.settingsOpen ? "md-pr-open" : ""}">
00616|           <label for="${PANEL_ID}-api-key">API key</label>
00617|           <input id="${PANEL_ID}-api-key" type="password" data-config="apiKey" />
00618|           <div class="md-pr-status"></div>
00619|         </div>
00620|         <div class="md-pr-powered">Powered by the <a class="md-pr-powered-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Open Source Explorer</a></div>
00621|       </div>
00622|     `;
00623| 
00624|     wrapper.querySelector(".md-pr-gear").addEventListener("click", () => {
00625|       const settings = wrapper.querySelector(".md-pr-settings");
00626|       const open = settings.classList.toggle("md-pr-open");
00627|       saveConfig({ ...state.config, settingsOpen: open });
00628|     });
00629| 
00630|     wrapper.querySelectorAll("[data-config]").forEach((input) => {
00631|       const key = input.getAttribute("data-config");
00632|       input.value = state.config[key] ?? "";
00633|       input.addEventListener("change", () => {
00634|         if (key === "apiKey") {
00635|           state.listCache.clear();
00636|         }
00637|         saveConfig({ ...state.config, [key]: input.value });
00638|         applyCheck();
00639|         applyListIndicators();
00640|       });
00641|     });
00642| 

(File has more lines. Use 'offset' parameter to read beyond line 642)
</file>
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n   function handlePullNavigationShortcut(event) {\n     if (!isPullDetailPage()) return;\n     if (event.defaultPrevented) return;\n     if (event.metaKey || event.ctrlKey || event.altKey) return;\n     if (isEditableTarget(event.target)) return;\n \n     let direction = 0;\n+    if (event.key === \"ArrowRight\") direction = 1;\n+    if (event.key === \"ArrowLeft\") direction = -1;\n     if (event.key === \"]\") direction = 1;\n     if (event.key === \"[\") direction = -1;\n     if (!direction) return;\n@@\n       #${PANEL_ID} .md-pr-powered {\n         margin-top: 8px;\n         font-size: 11px;\n         color: var(--fgColor-muted, #57606a);\n         opacity: 0.65;\n       }\n+      #${PANEL_ID} .md-pr-nav-hint {\n+        margin-top: 2px;\n+        font-size: 10px;\n+        color: var(--fgColor-muted, #57606a);\n+        opacity: 0.55;\n+      }\n       #${PANEL_ID} .md-pr-powered-link {\n         color: inherit;\n         text-decoration: none;\n       }\n@@\n         <div class=\"md-pr-settings ${state.config.settingsOpen ? \"md-pr-open\" : \"\"}\">\n           <label for=\"${PANEL_ID}-api-key\">API key</label>\n           <input id=\"${PANEL_ID}-api-key\" type=\"password\" data-config=\"apiKey\" />\n           <div class=\"md-pr-status\"></div>\n         </div>\n         <div class=\"md-pr-powered\">Powered by the <a class=\"md-pr-powered-link\" href=\"https://explore.market.dev\" target=\"_blank\" rel=\"noopener noreferrer\">Open Source Explorer</a></div>\n+        <div class=\"md-pr-nav-hint\">View next PR using <- -></div>\n       </div>\n     `;\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check content.js",
  "description": "Validate content script after arrow key changes"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git diff -- content.js",
  "description": "Review final diff for arrow navigation and hint"
}
```

## Assistant

**Result** (success):
```
diff --git a/content.js b/content.js
index 2475cdf..16a0fab 100644
--- a/content.js
+++ b/content.js
@@ -1,8 +1,10 @@
 (() => {
   const STORAGE_KEY = "md_expert_pr_config";
+  const NAV_CACHE_KEY = "md_expert_pr_nav_cache";
   const STYLE_ID = "md-expert-pr-style";
   const PANEL_ID = "md-expert-pr-panel";
   const BADGE_ID = "md-expert-pr-badge";
+  const NAV_CACHE_MAX_AGE_MS = 1000 * 60 * 60 * 8;
 
   const DEFAULT_CONFIG = {
     apiKey: "",
@@ -14,7 +16,8 @@
     currentResult: null,
     listCache: new Map(),
     mountRetryTimer: null,
-    mountRetryCount: 0
+    mountRetryCount: 0,
+    keyboardListenerAttached: false
   };
 
   function loadConfig() {
@@ -41,6 +44,138 @@
     return /\/pulls(\/|$)/.test(window.location.pathname);
   }
 
+  function normalizePullPath(urlLike) {
+    try {
+      const url = new URL(String(urlLike || ""), window.location.origin);
+      const match = url.pathname.match(/^\/[^/]+\/[^/]+\/pull\/\d+/);
+      return match ? match[0] : null;
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function getRepoPathFromPullPath(pullPath) {
+    const match = String(pullPath || "").match(/^\/[^/]+\/[^/]+/);
+    return match ? match[0] : null;
+  }
+
+  function readNavigationCache() {
+    const raw = window.localStorage.getItem(NAV_CACHE_KEY);
+    if (!raw) return null;
+    try {
+      const parsed = JSON.parse(raw);
+      if (!parsed || !Array.isArray(parsed.pullPaths)) return null;
+      if (typeof parsed.updatedAt !== "number") return null;
+      return parsed;
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeNavigationCache(pullPaths) {
+    if (!Array.isArray(pullPaths) || !pullPaths.length) return;
+    const repoPath = getRepoPathFromPullPath(pullPaths[0]);
+    if (!repoPath) return;
+
+    window.localStorage.setItem(
+      NAV_CACHE_KEY,
+      JSON.stringify({
+        repoPath,
+        listPath: window.location.pathname,
+        listSearch: window.location.search || "",
+        pullPaths,
+        updatedAt: Date.now()
+      })
+    );
+  }
+
+  function cachePullListOrder() {
+    if (!isPullListPage()) return;
+
+    const rows = document.querySelectorAll("div.js-issue-row");
+    const pullPaths = [];
+    const seen = new Set();
+
+    rows.forEach((row) => {
+      const titleLink =
+        row.querySelector("a[data-hovercard-type='pull_request']") ||
+        row.querySelector("a[id^='issue_']") ||
+        row.querySelector("a.Link--primary[href*='/pull/']");
+      if (!titleLink) return;
+
+      const pullPath = normalizePullPath(titleLink.getAttribute("href") || titleLink.href);
+      if (!pullPath || seen.has(pullPath)) return;
+
+      seen.add(pullPath);
+      pullPaths.push(pullPath);
+    });
+
+    writeNavigationCache(pullPaths);
+  }
+
+  function isEditableTarget(target) {
+    const element = target instanceof Element ? target : null;
+    if (!element) return false;
+    if (element.closest("input, textarea, select, button, [contenteditable=''], [contenteditable='true'], [role='textbox']")) {
+      return true;
+    }
+    return false;
+  }
+
+  function getAdjacentPullPath(direction) {
+    const currentPullPath = normalizePullPath(window.location.href);
+    if (!currentPullPath) return null;
+
+    const cache = readNavigationCache();
+    if (!cache) return null;
+    if (!Array.isArray(cache.pullPaths) || cache.pullPaths.length < 2) return null;
+    if (Date.now() - cache.updatedAt > NAV_CACHE_MAX_AGE_MS) return null;
+
+    const repoPath = getRepoPathFromPullPath(currentPullPath);
+    if (!repoPath || cache.repoPath !== repoPath) return null;
+
+    const currentIndex = cache.pullPaths.indexOf(currentPullPath);
+    if (currentIndex === -1) return null;
+
+    const targetIndex = (currentIndex + direction + cache.pullPaths.length) % cache.pullPaths.length;
+    if (targetIndex === currentIndex) return null;
+
+    return cache.pullPaths[targetIndex];
+  }
+
+  function navigateToAdjacentPull(direction) {
+    const targetPath = getAdjacentPullPath(direction);
+    if (!targetPath) return false;
+    window.location.assign(targetPath);
+    return true;
+  }
+
+  function handlePullNavigationShortcut(event) {
+    if (!isPullDetailPage()) return;
+    if (event.defaultPrevented) return;
+    if (event.metaKey || event.ctrlKey || event.altKey) return;
+    if (isEditableTarget(event.target)) return;
+
+    let direction = 0;
+    if (event.key === "ArrowRight") direction = 1;
+    if (event.key === "ArrowLeft") direction = -1;
+    if (event.key === "]") direction = 1;
+    if (event.key === "[") direction = -1;
+    if (!direction) return;
+
+    const navigated = navigateToAdjacentPull(direction);
+    if (!navigated) return;
+
+    event.preventDefault();
+    event.stopPropagation();
+  }
+
+  function ensureKeyboardShortcutBinding() {
+    if (state.keyboardListenerAttached) return;
+    state.keyboardListenerAttached = true;
+    document.addEventListener("keydown", handlePullNavigationShortcut, true);
+  }
+
   function canUseBackground() {
     return typeof chrome !== "undefined" && chrome.runtime && chrome.runtime.sendMessage;
   }
@@ -230,6 +365,12 @@
         color: var(--fgColor-muted, #57606a);
         opacity: 0.65;
       }
+      #${PANEL_ID} .md-pr-nav-hint {
+        margin-top: 2px;
+        font-size: 10px;
+        color: var(--fgColor-muted, #57606a);
+        opacity: 0.55;
+      }
       #${PANEL_ID} .md-pr-powered-link {
         color: inherit;
         text-decoration: none;
@@ -485,6 +626,7 @@
           <div class="md-pr-status"></div>
         </div>
         <div class="md-pr-powered">Powered by the <a class="md-pr-powered-link" href="https://explore.market.dev" target="_blank" rel="noopener noreferrer">Open Source Explorer</a></div>
+        <div class="md-pr-nav-hint">View next PR using <- -></div>
       </div>
     `;
 
@@ -809,6 +951,8 @@
   async function applyListIndicators() {
     if (!isPullListPage()) return;
 
+    cachePullListOrder();
+
     const rows = document.querySelectorAll("div.js-issue-row");
     rows.forEach((row) => {
       const author = row.getAttribute("data-author");
@@ -852,6 +996,8 @@
   }
 
   function init() {
+    ensureKeyboardShortcutBinding();
+    cachePullListOrder();
     applyCheck();
     applyListIndicators();
   }

```

## Assistant

## Assistant

Done — I updated it.

- Arrow key navigation now works on PR pages:
  - `->` (`ArrowRight`) = next PR
  - `<-` (`ArrowLeft`) = previous PR
- I kept `[` and `]` working too, so both options work.
- Added a subtle footer hint under Powered by:
  - `View next PR using <- ->`

File updated: `content.js`

Refresh the PR page (hard refresh) to load the new shortcut behavior.

## User

Nah, I don't like that hint here. Put 2 arrow buttons under this code button [Image 1], make it match the width of the code button with a small gap, the arrow should show the character -> not - > 

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n   const NAV_CACHE_KEY = \"md_expert_pr_nav_cache\";\n   const STYLE_ID = \"md-expert-pr-style\";\n   const PANEL_ID = \"md-expert-pr-panel\";\n   const BADGE_ID = \"md-expert-pr-badge\";\n+  const NAV_BUTTONS_ID = \"md-expert-pr-nav-buttons\";\n   const NAV_CACHE_MAX_AGE_MS = 1000 * 60 * 60 * 8;\n@@\n     listCache: new Map(),\n     mountRetryTimer: null,\n     mountRetryCount: 0,\n-    keyboardListenerAttached: false\n+    keyboardListenerAttached: false,\n+    navMountRetryTimer: null,\n+    navMountRetryCount: 0\n   };\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 90,
  "offset": 132
}
```

## Assistant

**Result** (success):
```
<file>
00133|     if (!cache) return null;
00134|     if (!Array.isArray(cache.pullPaths) || cache.pullPaths.length < 2) return null;
00135|     if (Date.now() - cache.updatedAt > NAV_CACHE_MAX_AGE_MS) return null;
00136| 
00137|     const repoPath = getRepoPathFromPullPath(currentPullPath);
00138|     if (!repoPath || cache.repoPath !== repoPath) return null;
00139| 
00140|     const currentIndex = cache.pullPaths.indexOf(currentPullPath);
00141|     if (currentIndex === -1) return null;
00142| 
00143|     const targetIndex = (currentIndex + direction + cache.pullPaths.length) % cache.pullPaths.length;
00144|     if (targetIndex === currentIndex) return null;
00145| 
00146|     return cache.pullPaths[targetIndex];
00147|   }
00148| 
00149|   function navigateToAdjacentPull(direction) {
00150|     const targetPath = getAdjacentPullPath(direction);
00151|     if (!targetPath) return false;
00152|     window.location.assign(targetPath);
00153|     return true;
00154|   }
00155| 
00156|   function handlePullNavigationShortcut(event) {
00157|     if (!isPullDetailPage()) return;
00158|     if (event.defaultPrevented) return;
00159|     if (event.metaKey || event.ctrlKey || event.altKey) return;
00160|     if (isEditableTarget(event.target)) return;
00161| 
00162|     let direction = 0;
00163|     if (event.key === "ArrowRight") direction = 1;
00164|     if (event.key === "ArrowLeft") direction = -1;
00165|     if (event.key === "]") direction = 1;
00166|     if (event.key === "[") direction = -1;
00167|     if (!direction) return;
00168| 
00169|     const navigated = navigateToAdjacentPull(direction);
00170|     if (!navigated) return;
00171| 
00172|     event.preventDefault();
00173|     event.stopPropagation();
00174|   }
00175| 
00176|   function ensureKeyboardShortcutBinding() {
00177|     if (state.keyboardListenerAttached) return;
00178|     state.keyboardListenerAttached = true;
00179|     document.addEventListener("keydown", handlePullNavigationShortcut, true);
00180|   }
00181| 
00182|   function canUseBackground() {
00183|     return typeof chrome !== "undefined" && chrome.runtime && chrome.runtime.sendMessage;
00184|   }
00185| 
00186|   function fetchViaBackground(url, apiKey) {
00187|     if (!canUseBackground()) return Promise.resolve(null);
00188|     return new Promise((resolve) => {
00189|       chrome.runtime.sendMessage(
00190|         { type: "md-expert-pr-check", url, apiKey },
00191|         (response) => {
00192|           if (chrome.runtime.lastError) {
00193|             resolve(null);
00194|             return;
00195|           }
00196|           resolve(response);
00197|         }
00198|       );
00199|     });
00200|   }
00201| 
00202|   function ensureStyles() {
00203|     if (document.getElementById(STYLE_ID)) return;
00204|     const style = document.createElement("style");
00205|     style.id = STYLE_ID;
00206|     style.textContent = `
00207|       #${PANEL_ID} {
00208|         color: var(--fgColor-default, #24292f);
00209|       }
00210|       #${PANEL_ID}.discussion-sidebar-item {
00211|         margin-top: 0;
00212|       }
00213|       #${PANEL_ID}.md-pr-fallback {
00214|         margin: 16px 0;
00215|       }
00216|       #${PANEL_ID} .md-pr-panel {
00217|         font-size: 12px;
00218|         line-height: 1.5;
00219|       }
00220|       #${PANEL_ID} .md-pr-header {
00221|         display: flex;
00222|         justify-content: space-between;

(File has more lines. Use 'offset' parameter to read beyond line 222)
</file>
```

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n   function ensureKeyboardShortcutBinding() {\n     if (state.keyboardListenerAttached) return;\n     state.keyboardListenerAttached = true;\n     document.addEventListener(\"keydown\", handlePullNavigationShortcut, true);\n   }\n+\n+  function clearNavMountRetry() {\n+    if (!state.navMountRetryTimer) return;\n+    window.clearTimeout(state.navMountRetryTimer);\n+    state.navMountRetryTimer = null;\n+  }\n+\n+  function scheduleNavMountRetry() {\n+    if (state.navMountRetryTimer || state.navMountRetryCount >= 40 || !isPullDetailPage()) return;\n+    state.navMountRetryTimer = window.setTimeout(() => {\n+      state.navMountRetryTimer = null;\n+      state.navMountRetryCount += 1;\n+      ensureNavButtons();\n+    }, 250);\n+  }\n+\n+  function getCodeButtonMatchScore(element) {\n+    const text = normalizeText(element.textContent);\n+    const ariaLabel = normalizeText(element.getAttribute(\"aria-label\"));\n+\n+    let score = 0;\n+    if (text === \"code\") score += 4;\n+    else if (text.startsWith(\"code \")) score += 2;\n+\n+    if (ariaLabel === \"code\") score += 3;\n+    else if (ariaLabel.startsWith(\"code \")) score += 2;\n+\n+    return score;\n+  }\n+\n+  function findCodeButton() {\n+    const sidebar = findSidebar();\n+    const roots = [sidebar, document].filter(Boolean);\n+    const seen = new Set();\n+    const candidates = [];\n+\n+    roots.forEach((root) => {\n+      root.querySelectorAll(\"button, summary, a\").forEach((element) => {\n+        if (seen.has(element)) return;\n+        seen.add(element);\n+\n+        if (!isVisibleElement(element)) return;\n+        if (element.closest(`#${PANEL_ID}`) || element.closest(`#${NAV_BUTTONS_ID}`)) return;\n+\n+        const textScore = getCodeButtonMatchScore(element);\n+        if (!textScore) return;\n+\n+        const classText = normalizeText(element.className);\n+        const rect = element.getBoundingClientRect();\n+\n+        let score = textScore;\n+        if (sidebar && sidebar.contains(element)) score += 8;\n+        if (classText.includes(\"btn\") || classText.includes(\"button\")) score += 2;\n+        if (element.closest(\"details\")) score += 1;\n+        if (rect.width >= 80 && rect.width <= 240) score += 2;\n+        if (rect.height >= 28 && rect.height <= 44) score += 1;\n+\n+        candidates.push({ element, score });\n+      });\n+    });\n+\n+    if (!candidates.length) return null;\n+    candidates.sort((a, b) => b.score - a.score);\n+    return candidates[0].element;\n+  }\n+\n+  function getNavButtonsAnchor(codeButton) {\n+    if (!codeButton) return null;\n+\n+    const buttonGroup = codeButton.closest(\".BtnGroup, .ButtonGroup, [class*='ButtonGroup']\");\n+    if (buttonGroup && isVisibleElement(buttonGroup)) return buttonGroup;\n+\n+    if (codeButton.tagName === \"SUMMARY\" && codeButton.parentElement?.tagName === \"DETAILS\") {\n+      return codeButton.parentElement;\n+    }\n+\n+    return codeButton;\n+  }\n+\n+  function updateNavButtonsState(wrapper) {\n+    if (!wrapper) return;\n+\n+    const prevButton = wrapper.querySelector(\"[data-nav='prev']\");\n+    const nextButton = wrapper.querySelector(\"[data-nav='next']\");\n+    if (!prevButton || !nextButton) return;\n+\n+    const canGoPrev = Boolean(getAdjacentPullPath(-1));\n+    const canGoNext = Boolean(getAdjacentPullPath(1));\n+\n+    prevButton.disabled = !canGoPrev;\n+    nextButton.disabled = !canGoNext;\n+\n+    const disabledTitle = \"Visit the repo PR list to enable\";\n+    prevButton.title = canGoPrev ? \"Previous PR (ArrowLeft)\" : disabledTitle;\n+    nextButton.title = canGoNext ? \"Next PR (ArrowRight)\" : disabledTitle;\n+  }\n+\n+  function ensureNavButtons() {\n+    const existing = document.getElementById(NAV_BUTTONS_ID);\n+\n+    if (!isPullDetailPage()) {\n+      if (existing) existing.remove();\n+      clearNavMountRetry();\n+      state.navMountRetryCount = 0;\n+      return;\n+    }\n+\n+    const codeButton = findCodeButton();\n+    if (!codeButton) {\n+      if (existing) existing.remove();\n+      scheduleNavMountRetry();\n+      return;\n+    }\n+\n+    let wrapper = existing;\n+    if (!wrapper) {\n+      wrapper = document.createElement(\"div\");\n+      wrapper.id = NAV_BUTTONS_ID;\n+      wrapper.innerHTML = `\n+        <button class=\"md-pr-nav-btn\" type=\"button\" data-nav=\"prev\" aria-label=\"Previous pull request\">&lt;-</button>\n+        <button class=\"md-pr-nav-btn\" type=\"button\" data-nav=\"next\" aria-label=\"Next pull request\">-&gt;</button>\n+      `;\n+\n+      wrapper.querySelector(\"[data-nav='prev']\")?.addEventListener(\"click\", (event) => {\n+        event.preventDefault();\n+        navigateToAdjacentPull(-1);\n+      });\n+      wrapper.querySelector(\"[data-nav='next']\")?.addEventListener(\"click\", (event) => {\n+        event.preventDefault();\n+        navigateToAdjacentPull(1);\n+      });\n+    }\n+\n+    const anchor = getNavButtonsAnchor(codeButton);\n+    if (!anchor) {\n+      scheduleNavMountRetry();\n+      return;\n+    }\n+\n+    const width = Math.round(codeButton.getBoundingClientRect().width);\n+    if (width > 0) {\n+      wrapper.style.width = `${width}px`;\n+    } else {\n+      wrapper.style.width = \"\";\n+    }\n+\n+    if (anchor.nextElementSibling !== wrapper) {\n+      anchor.insertAdjacentElement(\"afterend\", wrapper);\n+    }\n+\n+    updateNavButtonsState(wrapper);\n+    clearNavMountRetry();\n+    state.navMountRetryCount = 0;\n+  }\n \n   function canUseBackground() {\n     return typeof chrome !== \"undefined\" && chrome.runtime && chrome.runtime.sendMessage;\n   }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 95,
  "offset": 500
}
```

## Assistant

**Result** (success):
```
<file>
00501|       #${PANEL_ID} .md-pr-ecosystem-pill:hover {
00502|         text-decoration: underline;
00503|       }
00504|       #${PANEL_ID} .md-pr-project-list {
00505|         display: flex;
00506|         flex-direction: column;
00507|         gap: 2px;
00508|       }
00509|       #${PANEL_ID} .md-pr-project-item {
00510|         display: flex;
00511|         align-items: baseline;
00512|         justify-content: space-between;
00513|         gap: 8px;
00514|       }
00515|       #${PANEL_ID} .md-pr-project-meta {
00516|         color: var(--fgColor-muted, #57606a);
00517|         flex-shrink: 0;
00518|       }
00519|       #${PANEL_ID} .md-pr-powered {
00520|         margin-top: 8px;
00521|         font-size: 11px;
00522|         color: var(--fgColor-muted, #57606a);
00523|         opacity: 0.65;
00524|       }
00525|       #${PANEL_ID} .md-pr-nav-hint {
00526|         margin-top: 2px;
00527|         font-size: 10px;
00528|         color: var(--fgColor-muted, #57606a);
00529|         opacity: 0.55;
00530|       }
00531|       #${PANEL_ID} .md-pr-powered-link {
00532|         color: inherit;
00533|         text-decoration: none;
00534|       }
00535|       #${PANEL_ID} .md-pr-powered-link:hover {
00536|         text-decoration: underline;
00537|       }
00538|       .md-pr-list-indicator {
00539|         display: inline-flex;
00540|         align-items: center;
00541|         justify-content: center;
00542|         width: 8px;
00543|         height: 8px;
00544|         border-radius: 999px;
00545|         margin-left: 6px;
00546|         border: 1px solid #d0d7de;
00547|       }
00548|       .md-pr-list-indicator.md-pr-list-expert {
00549|         background: #2da44e;
00550|         border-color: #2da44e;
00551|       }
00552|       .md-pr-list-indicator.md-pr-list-missing {
00553|         background: #afb8c1;
00554|       }
00555|       #${BADGE_ID} {
00556|         display: inline-flex;
00557|         align-items: center;
00558|         gap: 6px;
00559|         margin-left: 8px;
00560|         padding: 2px 8px;
00561|         border-radius: 999px;
00562|         font-size: 11px;
00563|         font-weight: 600;
00564|       }
00565|       #${BADGE_ID}.md-pr-badge-error {
00566|         background: #ffe4e8;
00567|         color: #9f1239;
00568|       }
00569|       #${BADGE_ID}.md-pr-badge-success {
00570|         background: #dcfce7;
00571|         color: #166534;
00572|       }
00573|     `;
00574|     document.head.appendChild(style);
00575|   }
00576| 
00577|   function clearMountRetry() {
00578|     if (!state.mountRetryTimer) return;
00579|     window.clearTimeout(state.mountRetryTimer);
00580|     state.mountRetryTimer = null;
00581|   }
00582| 
00583|   function scheduleMountRetry() {
00584|     if (state.mountRetryTimer || state.mountRetryCount >= 40 || !isPullDetailPage()) return;
00585|     state.mountRetryTimer = window.setTimeout(() => {
00586|       state.mountRetryTimer = null;
00587|       state.mountRetryCount += 1;
00588|       ensurePanel();
00589|     }, 250);
00590|   }
00591| 
00592|   function normalizeText(value) {
00593|     return String(value || "").replace(/\s+/g, " ").trim().toLowerCase();
00594|   }
00595| 

(File has more lines. Use 'offset' parameter to read beyond line 595)
</file>
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n       #${PANEL_ID} .md-pr-powered {\n         margin-top: 8px;\n         font-size: 11px;\n         color: var(--fgColor-muted, #57606a);\n         opacity: 0.65;\n       }\n-      #${PANEL_ID} .md-pr-nav-hint {\n-        margin-top: 2px;\n-        font-size: 10px;\n-        color: var(--fgColor-muted, #57606a);\n-        opacity: 0.55;\n-      }\n       #${PANEL_ID} .md-pr-powered-link {\n         color: inherit;\n         text-decoration: none;\n       }\n       #${PANEL_ID} .md-pr-powered-link:hover {\n         text-decoration: underline;\n       }\n+      #${NAV_BUTTONS_ID} {\n+        display: grid;\n+        grid-template-columns: repeat(2, minmax(0, 1fr));\n+        gap: 6px;\n+        margin-top: 6px;\n+      }\n+      #${NAV_BUTTONS_ID} .md-pr-nav-btn {\n+        appearance: none;\n+        border: 1px solid var(--button-default-borderColor-rest, var(--borderColor-default, #d0d7de));\n+        background: var(--button-default-bgColor-rest, var(--bgColor-muted, #f6f8fa));\n+        color: var(--button-default-fgColor-rest, var(--fgColor-default, #24292f));\n+        border-radius: 6px;\n+        height: 32px;\n+        padding: 0;\n+        font-size: 12px;\n+        font-weight: 600;\n+        line-height: 1;\n+        cursor: pointer;\n+      }\n+      #${NAV_BUTTONS_ID} .md-pr-nav-btn:hover:not(:disabled) {\n+        background: var(--button-default-bgColor-hover, var(--bgColor-neutral-muted, #f3f4f6));\n+      }\n+      #${NAV_BUTTONS_ID} .md-pr-nav-btn:disabled {\n+        cursor: default;\n+        opacity: 0.55;\n+      }\n       .md-pr-list-indicator {\n         display: inline-flex;\n         align-items: center;\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "pattern": "md-pr-nav-hint"
}
```

## Assistant

**Result** (success):
```
Found 1 matches
/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js:
  Line 806:         <div class="md-pr-nav-hint">View next PR using <- -></div>
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n         <div class=\"md-pr-settings ${state.config.settingsOpen ? \"md-pr-open\" : \"\"}\">\n           <label for=\"${PANEL_ID}-api-key\">API key</label>\n           <input id=\"${PANEL_ID}-api-key\" type=\"password\" data-config=\"apiKey\" />\n           <div class=\"md-pr-status\"></div>\n         </div>\n         <div class=\"md-pr-powered\">Powered by the <a class=\"md-pr-powered-link\" href=\"https://explore.market.dev\" target=\"_blank\" rel=\"noopener noreferrer\">Open Source Explorer</a></div>\n-        <div class=\"md-pr-nav-hint\">View next PR using <- -></div>\n       </div>\n     `;\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 120,
  "offset": 1000
}
```

## Assistant

**Result** (success):
```
<file>
01001|               ${ecosystemNames
01002|                 .map((eco) => `<a class="md-pr-ecosystem-pill" href="${eco.url}" target="_blank" rel="noopener noreferrer">${eco.name}</a>`)
01003|                 .join("")}
01004|             </div>
01005|           </div>
01006|         ` : ""}
01007|         ${maintainerItems.length ? `
01008|           <div class="md-pr-section">
01009|             <div class="md-pr-section-title">Notable Projects</div>
01010|             <div class="md-pr-project-list">
01011|               ${maintainerItems
01012|                 .map(
01013|                   (item) => `
01014|                     <div class="md-pr-project-item">
01015|                       ${item.url ? `<a class="md-pr-link" href="${item.url}" target="_blank" rel="noopener noreferrer">${item.label}</a>` : `<span>${item.label}</span>`}
01016|                       ${item.meta ? `<span class="md-pr-project-meta">${item.meta}</span>` : ""}
01017|                     </div>
01018|                   `
01019|                 )
01020|                 .join("")}
01021|             </div>
01022|           </div>
01023|         ` : ""}
01024|       </div>
01025|     `;
01026|   }
01027| 
01028|   function findPrAuthor() {
01029|     const selectors = [
01030|       ".gh-header-meta .author",
01031|       ".js-discussion .timeline-comment-header .author",
01032|       ".js-discussion .author",
01033|       ".timeline-comment-header .author",
01034|       "a.author"
01035|     ];
01036|     for (const selector of selectors) {
01037|       const el = document.querySelector(selector);
01038|       if (el && el.textContent.trim()) return el.textContent.trim();
01039|     }
01040|     return null;
01041|   }
01042| 
01043|   function removeBadge() {
01044|     const existing = document.getElementById(BADGE_ID);
01045|     if (existing) existing.remove();
01046|   }
01047| 
01048|   function updateBadge(result) {
01049|     const header = document.querySelector(".gh-header-title") || document.querySelector(".gh-header-meta");
01050|     if (!header) return;
01051| 
01052|     removeBadge();
01053|     if (!result || result.state === "error" || result.state === "missing-key") return;
01054| 
01055|     const badge = document.createElement("span");
01056|     badge.id = BADGE_ID;
01057| 
01058|     if (result.state === "not-expert") {
01059|       badge.className = "md-pr-badge-error";
01060|       badge.textContent = "No Profile";
01061|       header.appendChild(badge);
01062|     }
01063|   }
01064| 
01065|   async function fetchExpert(username) {
01066|     const apiKey = String(state.config.apiKey || "").trim();
01067|     if (!apiKey) return { state: "missing-key" };
01068| 
01069|     const url = `https://explore.market.dev/api/v1/experts/${encodeURIComponent(username)}`;
01070| 
01071|     try {
01072|       const backgroundResponse = await fetchViaBackground(url, apiKey);
01073|       let responseStatus = 0;
01074|       let responseData = null;
01075| 
01076|       if (backgroundResponse) {
01077|         responseStatus = backgroundResponse.status || 0;
01078|         responseData = backgroundResponse.data || null;
01079|       } else {
01080|         const response = await fetch(url, {
01081|           headers: {
01082|             Authorization: `Bearer ${apiKey}`,
01083|             Accept: "application/json"
01084|           }
01085|         });
01086|         responseStatus = response.status;
01087|         const text = await response.text();
01088|         try {
01089|           responseData = text ? JSON.parse(text) : null;
01090|         } catch (error) {
01091|           responseData = null;
01092|         }
01093|       }
01094| 
01095|       if (responseStatus === 200) return { state: "expert", expert: responseData };
01096|       if (responseStatus === 404) return { state: "not-expert" };
01097|       if (responseStatus === 401) return { state: "error", message: "Auth failed" };
01098|       return { state: "error", message: "API request failed" };
01099|     } catch (error) {
01100|       return { state: "error", message: "API request failed" };
01101|     }
01102|   }
01103| 
01104|   async function fetchExpertStatus(username) {
01105|     if (state.listCache.has(username)) {
01106|       return state.listCache.get(username);
01107|     }
01108| 
01109|     const apiKey = String(state.config.apiKey || "").trim();
01110|     if (!apiKey) return null;
01111| 
01112|     const url = `https://explore.market.dev/api/v1/experts/${encodeURIComponent(username)}`;
01113|     try {
01114|       const backgroundResponse = await fetchViaBackground(url, apiKey);
01115|       const status = backgroundResponse ? backgroundResponse.status : null;
01116|       if (status === 200 || status === 404) {
01117|         const value = status === 200 ? "expert" : "missing";
01118|         state.listCache.set(username, value);
01119|         return value;
01120|       }

(File has more lines. Use 'offset' parameter to read beyond line 1120)
</file>
```

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 120,
  "offset": 1120
}
```

## Assistant

**Result** (success):
```
<file>
01121|       return null;
01122|     } catch (error) {
01123|       return null;
01124|     }
01125|   }
01126| 
01127|   async function applyListIndicators() {
01128|     if (!isPullListPage()) return;
01129| 
01130|     cachePullListOrder();
01131| 
01132|     const rows = document.querySelectorAll("div.js-issue-row");
01133|     rows.forEach((row) => {
01134|       const author = row.getAttribute("data-author");
01135|       if (!author) return;
01136|       const authorLink = row.querySelector("a[data-hovercard-type='user']") || row.querySelector("a.author");
01137|       if (!authorLink) return;
01138|       if (authorLink.parentElement?.querySelector(".md-pr-list-indicator")) return;
01139| 
01140|       fetchExpertStatus(author).then((status) => {
01141|         if (!status) return;
01142|         if (authorLink.parentElement?.querySelector(".md-pr-list-indicator")) return;
01143|         const indicator = document.createElement("span");
01144|         indicator.className = `md-pr-list-indicator ${status === "expert" ? "md-pr-list-expert" : "md-pr-list-missing"}`;
01145|         indicator.title = status === "expert" ? "Expert profile found" : "No expert profile";
01146|         authorLink.insertAdjacentElement("afterend", indicator);
01147|       });
01148|     });
01149|   }
01150| 
01151|   async function applyCheck() {
01152|     ensurePanel();
01153|     if (!isPullDetailPage()) return;
01154| 
01155|     const username = findPrAuthor();
01156|     if (!username) {
01157|       state.currentResult = { state: "error", message: "PR author not found" };
01158|       updateBadge(state.currentResult);
01159|       const panel = document.getElementById(PANEL_ID);
01160|       if (panel) updatePanel(panel);
01161|       return;
01162|     }
01163| 
01164|     state.currentResult = null;
01165|     const panel = document.getElementById(PANEL_ID);
01166|     if (panel) updatePanel(panel);
01167| 
01168|     const result = await fetchExpert(username);
01169|     state.currentResult = { ...result, username };
01170|     updateBadge(state.currentResult);
01171|     if (panel) updatePanel(panel);
01172|   }
01173| 
01174|   function init() {
01175|     ensureKeyboardShortcutBinding();
01176|     cachePullListOrder();
01177|     applyCheck();
01178|     applyListIndicators();
01179|   }
01180| 
01181|   document.addEventListener("pjax:end", init);
01182|   document.addEventListener("turbo:load", init);
01183|   if (document.readyState === "loading") {
01184|     document.addEventListener("DOMContentLoaded", init);
01185|   } else {
01186|     init();
01187|   }
01188| })();
01189| 

(End of file - total 1189 lines)
</file>
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n   async function applyCheck() {\n     ensurePanel();\n+    ensureNavButtons();\n     if (!isPullDetailPage()) return;\n@@\n   function init() {\n     ensureKeyboardShortcutBinding();\n     cachePullListOrder();\n+    ensureNavButtons();\n     applyCheck();\n     applyListIndicators();\n   }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "pattern": "md-pr-nav-hint"
}
```

## Assistant

**Result** (success):
```
No files found
```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check content.js",
  "description": "Validate content script syntax after nav button UI"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git diff -- content.js",
  "description": "Inspect content script diff for requested UI placement"
}
```

## Assistant

**Result** (success):
```
diff --git a/content.js b/content.js
index 2475cdf..2eb8fe0 100644
--- a/content.js
+++ b/content.js
@@ -1,8 +1,11 @@
 (() => {
   const STORAGE_KEY = "md_expert_pr_config";
+  const NAV_CACHE_KEY = "md_expert_pr_nav_cache";
   const STYLE_ID = "md-expert-pr-style";
   const PANEL_ID = "md-expert-pr-panel";
   const BADGE_ID = "md-expert-pr-badge";
+  const NAV_BUTTONS_ID = "md-expert-pr-nav-buttons";
+  const NAV_CACHE_MAX_AGE_MS = 1000 * 60 * 60 * 8;
 
   const DEFAULT_CONFIG = {
     apiKey: "",
@@ -14,7 +17,10 @@
     currentResult: null,
     listCache: new Map(),
     mountRetryTimer: null,
-    mountRetryCount: 0
+    mountRetryCount: 0,
+    keyboardListenerAttached: false,
+    navMountRetryTimer: null,
+    navMountRetryCount: 0
   };
 
   function loadConfig() {
@@ -41,6 +47,292 @@
     return /\/pulls(\/|$)/.test(window.location.pathname);
   }
 
+  function normalizePullPath(urlLike) {
+    try {
+      const url = new URL(String(urlLike || ""), window.location.origin);
+      const match = url.pathname.match(/^\/[^/]+\/[^/]+\/pull\/\d+/);
+      return match ? match[0] : null;
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function getRepoPathFromPullPath(pullPath) {
+    const match = String(pullPath || "").match(/^\/[^/]+\/[^/]+/);
+    return match ? match[0] : null;
+  }
+
+  function readNavigationCache() {
+    const raw = window.localStorage.getItem(NAV_CACHE_KEY);
+    if (!raw) return null;
+    try {
+      const parsed = JSON.parse(raw);
+      if (!parsed || !Array.isArray(parsed.pullPaths)) return null;
+      if (typeof parsed.updatedAt !== "number") return null;
+      return parsed;
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeNavigationCache(pullPaths) {
+    if (!Array.isArray(pullPaths) || !pullPaths.length) return;
+    const repoPath = getRepoPathFromPullPath(pullPaths[0]);
+    if (!repoPath) return;
+
+    window.localStorage.setItem(
+      NAV_CACHE_KEY,
+      JSON.stringify({
+        repoPath,
+        listPath: window.location.pathname,
+        listSearch: window.location.search || "",
+        pullPaths,
+        updatedAt: Date.now()
+      })
+    );
+  }
+
+  function cachePullListOrder() {
+    if (!isPullListPage()) return;
+
+    const rows = document.querySelectorAll("div.js-issue-row");
+    const pullPaths = [];
+    const seen = new Set();
+
+    rows.forEach((row) => {
+      const titleLink =
+        row.querySelector("a[data-hovercard-type='pull_request']") ||
+        row.querySelector("a[id^='issue_']") ||
+        row.querySelector("a.Link--primary[href*='/pull/']");
+      if (!titleLink) return;
+
+      const pullPath = normalizePullPath(titleLink.getAttribute("href") || titleLink.href);
+      if (!pullPath || seen.has(pullPath)) return;
+
+      seen.add(pullPath);
+      pullPaths.push(pullPath);
+    });
+
+    writeNavigationCache(pullPaths);
+  }
+
+  function isEditableTarget(target) {
+    const element = target instanceof Element ? target : null;
+    if (!element) return false;
+    if (element.closest("input, textarea, select, button, [contenteditable=''], [contenteditable='true'], [role='textbox']")) {
+      return true;
+    }
+    return false;
+  }
+
+  function getAdjacentPullPath(direction) {
+    const currentPullPath = normalizePullPath(window.location.href);
+    if (!currentPullPath) return null;
+
+    const cache = readNavigationCache();
+    if (!cache) return null;
+    if (!Array.isArray(cache.pullPaths) || cache.pullPaths.length < 2) return null;
+    if (Date.now() - cache.updatedAt > NAV_CACHE_MAX_AGE_MS) return null;
+
+    const repoPath = getRepoPathFromPullPath(currentPullPath);
+    if (!repoPath || cache.repoPath !== repoPath) return null;
+
+    const currentIndex = cache.pullPaths.indexOf(currentPullPath);
+    if (currentIndex === -1) return null;
+
+    const targetIndex = (currentIndex + direction + cache.pullPaths.length) % cache.pullPaths.length;
+    if (targetIndex === currentIndex) return null;
+
+    return cache.pullPaths[targetIndex];
+  }
+
+  function navigateToAdjacentPull(direction) {
+    const targetPath = getAdjacentPullPath(direction);
+    if (!targetPath) return false;
+    window.location.assign(targetPath);
+    return true;
+  }
+
+  function handlePullNavigationShortcut(event) {
+    if (!isPullDetailPage()) return;
+    if (event.defaultPrevented) return;
+    if (event.metaKey || event.ctrlKey || event.altKey) return;
+    if (isEditableTarget(event.target)) return;
+
+    let direction = 0;
+    if (event.key === "ArrowRight") direction = 1;
+    if (event.key === "ArrowLeft") direction = -1;
+    if (event.key === "]") direction = 1;
+    if (event.key === "[") direction = -1;
+    if (!direction) return;
+
+    const navigated = navigateToAdjacentPull(direction);
+    if (!navigated) return;
+
+    event.preventDefault();
+    event.stopPropagation();
+  }
+
+  function ensureKeyboardShortcutBinding() {
+    if (state.keyboardListenerAttached) return;
+    state.keyboardListenerAttached = true;
+    document.addEventListener("keydown", handlePullNavigationShortcut, true);
+  }
+
+  function clearNavMountRetry() {
+    if (!state.navMountRetryTimer) return;
+    window.clearTimeout(state.navMountRetryTimer);
+    state.navMountRetryTimer = null;
+  }
+
+  function scheduleNavMountRetry() {
+    if (state.navMountRetryTimer || state.navMountRetryCount >= 40 || !isPullDetailPage()) return;
+    state.navMountRetryTimer = window.setTimeout(() => {
+      state.navMountRetryTimer = null;
+      state.navMountRetryCount += 1;
+      ensureNavButtons();
+    }, 250);
+  }
+
+  function getCodeButtonMatchScore(element) {
+    const text = normalizeText(element.textContent);
+    const ariaLabel = normalizeText(element.getAttribute("aria-label"));
+
+    let score = 0;
+    if (text === "code") score += 4;
+    else if (text.startsWith("code ")) score += 2;
+
+    if (ariaLabel === "code") score += 3;
+    else if (ariaLabel.startsWith("code ")) score += 2;
+
+    return score;
+  }
+
+  function findCodeButton() {
+    const sidebar = findSidebar();
+    const roots = [sidebar, document].filter(Boolean);
+    const seen = new Set();
+    const candidates = [];
+
+    roots.forEach((root) => {
+      root.querySelectorAll("button, summary, a").forEach((element) => {
+        if (seen.has(element)) return;
+        seen.add(element);
+
+        if (!isVisibleElement(element)) return;
+        if (element.closest(`#${PANEL_ID}`) || element.closest(`#${NAV_BUTTONS_ID}`)) return;
+
+        const textScore = getCodeButtonMatchScore(element);
+        if (!textScore) return;
+
+        const classText = normalizeText(element.className);
+        const rect = element.getBoundingClientRect();
+
+        let score = textScore;
+        if (sidebar && sidebar.contains(element)) score += 8;
+        if (classText.includes("btn") || classText.includes("button")) score += 2;
+        if (element.closest("details")) score += 1;
+        if (rect.width >= 80 && rect.width <= 240) score += 2;
+        if (rect.height >= 28 && rect.height <= 44) score += 1;
+
+        candidates.push({ element, score });
+      });
+    });
+
+    if (!candidates.length) return null;
+    candidates.sort((a, b) => b.score - a.score);
+    return candidates[0].element;
+  }
+
+  function getNavButtonsAnchor(codeButton) {
+    if (!codeButton) return null;
+
+    const buttonGroup = codeButton.closest(".BtnGroup, .ButtonGroup, [class*='ButtonGroup']");
+    if (buttonGroup && isVisibleElement(buttonGroup)) return buttonGroup;
+
+    if (codeButton.tagName === "SUMMARY" && codeButton.parentElement?.tagName === "DETAILS") {
+      return codeButton.parentElement;
+    }
+
+    return codeButton;
+  }
+
+  function updateNavButtonsState(wrapper) {
+    if (!wrapper) return;
+
+    const prevButton = wrapper.querySelector("[data-nav='prev']");
+    const nextButton = wrapper.querySelector("[data-nav='next']");
+    if (!prevButton || !nextButton) return;
+
+    const canGoPrev = Boolean(getAdjacentPullPath(-1));
+    const canGoNext = Boolean(getAdjacentPullPath(1));
+
+    prevButton.disabled = !canGoPrev;
+    nextButton.disabled = !canGoNext;
+
+    const disabledTitle = "Visit the repo PR list to enable";
+    prevButton.title = canGoPrev ? "Previous PR (ArrowLeft)" : disabledTitle;
+    nextButton.title = canGoNext ? "Next PR (ArrowRight)" : disabledTitle;
+  }
+
+  function ensureNavButtons() {
+    const existing = document.getElementById(NAV_BUTTONS_ID);
+
+    if (!isPullDetailPage()) {
+      if (existing) existing.remove();
+      clearNavMountRetry();
+      state.navMountRetryCount = 0;
+      return;
+    }
+
+    const codeButton = findCodeButton();
+    if (!codeButton) {
+      if (existing) existing.remove();
+      scheduleNavMountRetry();
+      return;
+    }
+
+    let wrapper = existing;
+    if (!wrapper) {
+      wrapper = document.createElement("div");
+      wrapper.id = NAV_BUTTONS_ID;
+      wrapper.innerHTML = `
+        <button class="md-pr-nav-btn" type="button" data-nav="prev" aria-label="Previous pull request">&lt;-</button>
+        <button class="md-pr-nav-btn" type="button" data-nav="next" aria-label="Next pull request">-&gt;</button>
+      `;
+
+      wrapper.querySelector("[data-nav='prev']")?.addEventListener("click", (event) => {
+        event.preventDefault();
+        navigateToAdjacentPull(-1);
+      });
+      wrapper.querySelector("[data-nav='next']")?.addEventListener("click", (event) => {
+        event.preventDefault();
+        navigateToAdjacentPull(1);
+      });
+    }
+
+    const anchor = getNavButtonsAnchor(codeButton);
+    if (!anchor) {
+      scheduleNavMountRetry();
+      return;
+    }
+
+    const width = Math.round(codeButton.getBoundingClientRect().width);
+    if (width > 0) {
+      wrapper.style.width = `${width}px`;
+    } else {
+      wrapper.style.width = "";
+    }
+
+    if (anchor.nextElementSibling !== wrapper) {
+      anchor.insertAdjacentElement("afterend", wrapper);
+    }
+
+    updateNavButtonsState(wrapper);
+    clearNavMountRetry();
+    state.navMountRetryCount = 0;
+  }
+
   function canUseBackground() {
     return typeof chrome !== "undefined" && chrome.runtime && chrome.runtime.sendMessage;
   }
@@ -237,6 +529,32 @@
       #${PANEL_ID} .md-pr-powered-link:hover {
         text-decoration: underline;
       }
+      #${NAV_BUTTONS_ID} {
+        display: grid;
+        grid-template-columns: repeat(2, minmax(0, 1fr));
+        gap: 6px;
+        margin-top: 6px;
+      }
+      #${NAV_BUTTONS_ID} .md-pr-nav-btn {
+        appearance: none;
+        border: 1px solid var(--button-default-borderColor-rest, var(--borderColor-default, #d0d7de));
+        background: var(--button-default-bgColor-rest, var(--bgColor-muted, #f6f8fa));
+        color: var(--button-default-fgColor-rest, var(--fgColor-default, #24292f));
+        border-radius: 6px;
+        height: 32px;
+        padding: 0;
+        font-size: 12px;
+        font-weight: 600;
+        line-height: 1;
+        cursor: pointer;
+      }
+      #${NAV_BUTTONS_ID} .md-pr-nav-btn:hover:not(:disabled) {
+        background: var(--button-default-bgColor-hover, var(--bgColor-neutral-muted, #f3f4f6));
+      }
+      #${NAV_BUTTONS_ID} .md-pr-nav-btn:disabled {
+        cursor: default;
+        opacity: 0.55;
+      }
       .md-pr-list-indicator {
         display: inline-flex;
         align-items: center;
@@ -809,6 +1127,8 @@
   async function applyListIndicators() {
     if (!isPullListPage()) return;
 
+    cachePullListOrder();
+
     const rows = document.querySelectorAll("div.js-issue-row");
     rows.forEach((row) => {
       const author = row.getAttribute("data-author");
@@ -830,6 +1150,7 @@
 
   async function applyCheck() {
     ensurePanel();
+    ensureNavButtons();
     if (!isPullDetailPage()) return;
 
     const username = findPrAuthor();
@@ -852,6 +1173,9 @@
   }
 
   function init() {
+    ensureKeyboardShortcutBinding();
+    cachePullListOrder();
+    ensureNavButtons();
     applyCheck();
     applyListIndicators();
   }

```

## Assistant

## Assistant

### Tool: grep

**Args:**
```json
{
  "path": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "pattern": "View next PR using|md-pr-nav-hint"
}
```

## Assistant

**Result** (success):
```
No files found
```

## Assistant

## Assistant

Done — I removed the footer hint and moved navigation to two buttons under the GitHub `Code` button.

What I changed in `content.js`:
- Added a nav button row (`<-` and `->`) that mounts directly under the detected `Code` button.
- Matched width to the `Code` button dynamically.
- Added a small gap (`6px`) between the `Code` button and nav row, and between the two nav buttons.
- Styled buttons to blend with GitHub button styles.
- Wired both buttons to previous/next PR navigation.
- Kept keyboard navigation working too (`ArrowLeft` / `ArrowRight`, and `[` / `]`).

Also removed:
- The “View next PR using <- ->” hint text from the panel.

Reload the extension and hard-refresh the PR page to see it.

## User

[Image 1] 

Close, but look at this
- Layout is off
- So are the arrows

## Assistant

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 240,
  "offset": 180
}
```

## Assistant

**Result** (success):
```
<file>
00181| 
00182|   function clearNavMountRetry() {
00183|     if (!state.navMountRetryTimer) return;
00184|     window.clearTimeout(state.navMountRetryTimer);
00185|     state.navMountRetryTimer = null;
00186|   }
00187| 
00188|   function scheduleNavMountRetry() {
00189|     if (state.navMountRetryTimer || state.navMountRetryCount >= 40 || !isPullDetailPage()) return;
00190|     state.navMountRetryTimer = window.setTimeout(() => {
00191|       state.navMountRetryTimer = null;
00192|       state.navMountRetryCount += 1;
00193|       ensureNavButtons();
00194|     }, 250);
00195|   }
00196| 
00197|   function getCodeButtonMatchScore(element) {
00198|     const text = normalizeText(element.textContent);
00199|     const ariaLabel = normalizeText(element.getAttribute("aria-label"));
00200| 
00201|     let score = 0;
00202|     if (text === "code") score += 4;
00203|     else if (text.startsWith("code ")) score += 2;
00204| 
00205|     if (ariaLabel === "code") score += 3;
00206|     else if (ariaLabel.startsWith("code ")) score += 2;
00207| 
00208|     return score;
00209|   }
00210| 
00211|   function findCodeButton() {
00212|     const sidebar = findSidebar();
00213|     const roots = [sidebar, document].filter(Boolean);
00214|     const seen = new Set();
00215|     const candidates = [];
00216| 
00217|     roots.forEach((root) => {
00218|       root.querySelectorAll("button, summary, a").forEach((element) => {
00219|         if (seen.has(element)) return;
00220|         seen.add(element);
00221| 
00222|         if (!isVisibleElement(element)) return;
00223|         if (element.closest(`#${PANEL_ID}`) || element.closest(`#${NAV_BUTTONS_ID}`)) return;
00224| 
00225|         const textScore = getCodeButtonMatchScore(element);
00226|         if (!textScore) return;
00227| 
00228|         const classText = normalizeText(element.className);
00229|         const rect = element.getBoundingClientRect();
00230| 
00231|         let score = textScore;
00232|         if (sidebar && sidebar.contains(element)) score += 8;
00233|         if (classText.includes("btn") || classText.includes("button")) score += 2;
00234|         if (element.closest("details")) score += 1;
00235|         if (rect.width >= 80 && rect.width <= 240) score += 2;
00236|         if (rect.height >= 28 && rect.height <= 44) score += 1;
00237| 
00238|         candidates.push({ element, score });
00239|       });
00240|     });
00241| 
00242|     if (!candidates.length) return null;
00243|     candidates.sort((a, b) => b.score - a.score);
00244|     return candidates[0].element;
00245|   }
00246| 
00247|   function getNavButtonsAnchor(codeButton) {
00248|     if (!codeButton) return null;
00249| 
00250|     const buttonGroup = codeButton.closest(".BtnGroup, .ButtonGroup, [class*='ButtonGroup']");
00251|     if (buttonGroup && isVisibleElement(buttonGroup)) return buttonGroup;
00252| 
00253|     if (codeButton.tagName === "SUMMARY" && codeButton.parentElement?.tagName === "DETAILS") {
00254|       return codeButton.parentElement;
00255|     }
00256| 
00257|     return codeButton;
00258|   }
00259| 
00260|   function updateNavButtonsState(wrapper) {
00261|     if (!wrapper) return;
00262| 
00263|     const prevButton = wrapper.querySelector("[data-nav='prev']");
00264|     const nextButton = wrapper.querySelector("[data-nav='next']");
00265|     if (!prevButton || !nextButton) return;
00266| 
00267|     const canGoPrev = Boolean(getAdjacentPullPath(-1));
00268|     const canGoNext = Boolean(getAdjacentPullPath(1));
00269| 
00270|     prevButton.disabled = !canGoPrev;
00271|     nextButton.disabled = !canGoNext;
00272| 
00273|     const disabledTitle = "Visit the repo PR list to enable";
00274|     prevButton.title = canGoPrev ? "Previous PR (ArrowLeft)" : disabledTitle;
00275|     nextButton.title = canGoNext ? "Next PR (ArrowRight)" : disabledTitle;
00276|   }
00277| 
00278|   function ensureNavButtons() {
00279|     const existing = document.getElementById(NAV_BUTTONS_ID);
00280| 
00281|     if (!isPullDetailPage()) {
00282|       if (existing) existing.remove();
00283|       clearNavMountRetry();
00284|       state.navMountRetryCount = 0;
00285|       return;
00286|     }
00287| 
00288|     const codeButton = findCodeButton();
00289|     if (!codeButton) {
00290|       if (existing) existing.remove();
00291|       scheduleNavMountRetry();
00292|       return;
00293|     }
00294| 
00295|     let wrapper = existing;
00296|     if (!wrapper) {
00297|       wrapper = document.createElement("div");
00298|       wrapper.id = NAV_BUTTONS_ID;
00299|       wrapper.innerHTML = `
00300|         <button class="md-pr-nav-btn" type="button" data-nav="prev" aria-label="Previous pull request">&lt;-</button>
00301|         <button class="md-pr-nav-btn" type="button" data-nav="next" aria-label="Next pull request">-&gt;</button>
00302|       `;
00303| 
00304|       wrapper.querySelector("[data-nav='prev']")?.addEventListener("click", (event) => {
00305|         event.preventDefault();
00306|         navigateToAdjacentPull(-1);
00307|       });
00308|       wrapper.querySelector("[data-nav='next']")?.addEventListener("click", (event) => {
00309|         event.preventDefault();
00310|         navigateToAdjacentPull(1);
00311|       });
00312|     }
00313| 
00314|     const anchor = getNavButtonsAnchor(codeButton);
00315|     if (!anchor) {
00316|       scheduleNavMountRetry();
00317|       return;
00318|     }
00319| 
00320|     const width = Math.round(codeButton.getBoundingClientRect().width);
00321|     if (width > 0) {
00322|       wrapper.style.width = `${width}px`;
00323|     } else {
00324|       wrapper.style.width = "";
00325|     }
00326| 
00327|     if (anchor.nextElementSibling !== wrapper) {
00328|       anchor.insertAdjacentElement("afterend", wrapper);
00329|     }
00330| 
00331|     updateNavButtonsState(wrapper);
00332|     clearNavMountRetry();
00333|     state.navMountRetryCount = 0;
00334|   }
00335| 
00336|   function canUseBackground() {
00337|     return typeof chrome !== "undefined" && chrome.runtime && chrome.runtime.sendMessage;
00338|   }
00339| 
00340|   function fetchViaBackground(url, apiKey) {
00341|     if (!canUseBackground()) return Promise.resolve(null);
00342|     return new Promise((resolve) => {
00343|       chrome.runtime.sendMessage(
00344|         { type: "md-expert-pr-check", url, apiKey },
00345|         (response) => {
00346|           if (chrome.runtime.lastError) {
00347|             resolve(null);
00348|             return;
00349|           }
00350|           resolve(response);
00351|         }
00352|       );
00353|     });
00354|   }
00355| 
00356|   function ensureStyles() {
00357|     if (document.getElementById(STYLE_ID)) return;
00358|     const style = document.createElement("style");
00359|     style.id = STYLE_ID;
00360|     style.textContent = `
00361|       #${PANEL_ID} {
00362|         color: var(--fgColor-default, #24292f);
00363|       }
00364|       #${PANEL_ID}.discussion-sidebar-item {
00365|         margin-top: 0;
00366|       }
00367|       #${PANEL_ID}.md-pr-fallback {
00368|         margin: 16px 0;
00369|       }
00370|       #${PANEL_ID} .md-pr-panel {
00371|         font-size: 12px;
00372|         line-height: 1.5;
00373|       }
00374|       #${PANEL_ID} .md-pr-header {
00375|         display: flex;
00376|         justify-content: space-between;
00377|         align-items: center;
00378|         margin-bottom: 6px;
00379|       }
00380|       #${PANEL_ID} .md-pr-heading {
00381|         margin: 0;
00382|       }
00383|       #${PANEL_ID} .md-pr-gear {
00384|         border: none;
00385|         background: transparent;
00386|         color: var(--fgColor-muted, #57606a);
00387|         width: 20px;
00388|         height: 20px;
00389|         padding: 0;
00390|         display: inline-flex;
00391|         align-items: center;
00392|         justify-content: center;
00393|         cursor: pointer;
00394|       }
00395|       #${PANEL_ID} .md-pr-gear:hover {
00396|         color: var(--fgColor-default, #24292f);
00397|       }
00398|       #${PANEL_ID} .md-pr-settings {
00399|         display: none;
00400|         margin-top: 8px;
00401|       }
00402|       #${PANEL_ID} .md-pr-settings.md-pr-open {
00403|         display: block;
00404|       }
00405|       #${PANEL_ID} .md-pr-settings label {
00406|         display: block;
00407|         margin-bottom: 4px;
00408|         font-size: 12px;
00409|         color: var(--fgColor-muted, #57606a);
00410|       }
00411|       #${PANEL_ID} .md-pr-settings input[type="password"] {
00412|         width: 100%;
00413|         border: 1px solid var(--borderColor-default, #d0d7de);
00414|         border-radius: 6px;
00415|         padding: 5px 8px;
00416|         font-size: 12px;
00417|         color: var(--fgColor-default, #24292f);
00418|         background: var(--bgColor-default, #ffffff);
00419|       }
00420|       #${PANEL_ID} .md-pr-status {

(File has more lines. Use 'offset' parameter to read beyond line 420)
</file>
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n-  function getNavButtonsAnchor(codeButton) {\n-    if (!codeButton) return null;\n-\n-    const buttonGroup = codeButton.closest(\".BtnGroup, .ButtonGroup, [class*='ButtonGroup']\");\n-    if (buttonGroup && isVisibleElement(buttonGroup)) return buttonGroup;\n-\n-    if (codeButton.tagName === \"SUMMARY\" && codeButton.parentElement?.tagName === \"DETAILS\") {\n-      return codeButton.parentElement;\n-    }\n-\n-    return codeButton;\n-  }\n-\n   function updateNavButtonsState(wrapper) {\n     if (!wrapper) return;\n@@\n   function ensureNavButtons() {\n     const existing = document.getElementById(NAV_BUTTONS_ID);\n@@\n     const codeButton = findCodeButton();\n     if (!codeButton) {\n       if (existing) existing.remove();\n       scheduleNavMountRetry();\n       return;\n     }\n+\n+    const codeRect = codeButton.getBoundingClientRect();\n+    if (!codeRect.width || !codeRect.height) {\n+      scheduleNavMountRetry();\n+      return;\n+    }\n \n     let wrapper = existing;\n     if (!wrapper) {\n       wrapper = document.createElement(\"div\");\n       wrapper.id = NAV_BUTTONS_ID;\n@@\n         navigateToAdjacentPull(1);\n       });\n     }\n-\n-    const anchor = getNavButtonsAnchor(codeButton);\n-    if (!anchor) {\n-      scheduleNavMountRetry();\n-      return;\n-    }\n-\n-    const width = Math.round(codeButton.getBoundingClientRect().width);\n-    if (width > 0) {\n-      wrapper.style.width = `${width}px`;\n-    } else {\n-      wrapper.style.width = \"\";\n-    }\n-\n-    if (anchor.nextElementSibling !== wrapper) {\n-      anchor.insertAdjacentElement(\"afterend\", wrapper);\n-    }\n+\n+    if (wrapper.parentElement !== document.body) {\n+      document.body.appendChild(wrapper);\n+    }\n+\n+    wrapper.style.left = `${Math.round(window.scrollX + codeRect.left)}px`;\n+    wrapper.style.top = `${Math.round(window.scrollY + codeRect.bottom + 6)}px`;\n+    wrapper.style.width = `${Math.round(codeRect.width)}px`;\n \n     updateNavButtonsState(wrapper);\n     clearNavMountRetry();\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n       #${NAV_BUTTONS_ID} {\n+        position: absolute;\n+        z-index: 30;\n         display: grid;\n         grid-template-columns: repeat(2, minmax(0, 1fr));\n         gap: 6px;\n-        margin-top: 6px;\n       }\n       #${NAV_BUTTONS_ID} .md-pr-nav-btn {\n         appearance: none;\n         border: 1px solid var(--button-default-borderColor-rest, var(--borderColor-default, #d0d7de));\n         background: var(--button-default-bgColor-rest, var(--bgColor-muted, #f6f8fa));\n@@\n         border-radius: 6px;\n         height: 32px;\n         padding: 0;\n-        font-size: 12px;\n+        font-size: 13px;\n         font-weight: 600;\n+        font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n         line-height: 1;\n+        letter-spacing: 0;\n         cursor: pointer;\n       }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n     mountRetryCount: 0,\n     keyboardListenerAttached: false,\n     navMountRetryTimer: null,\n-    navMountRetryCount: 0\n+    navMountRetryCount: 0,\n+    navViewportListenerAttached: false,\n+    navRepositionFrame: null\n   };\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n   function scheduleNavMountRetry() {\n     if (state.navMountRetryTimer || state.navMountRetryCount >= 40 || !isPullDetailPage()) return;\n     state.navMountRetryTimer = window.setTimeout(() => {\n       state.navMountRetryTimer = null;\n       state.navMountRetryCount += 1;\n       ensureNavButtons();\n     }, 250);\n   }\n+\n+  function queueNavButtonsRefresh() {\n+    if (state.navRepositionFrame !== null) return;\n+    state.navRepositionFrame = window.requestAnimationFrame(() => {\n+      state.navRepositionFrame = null;\n+      ensureNavButtons();\n+    });\n+  }\n+\n+  function ensureNavViewportBinding() {\n+    if (state.navViewportListenerAttached) return;\n+    state.navViewportListenerAttached = true;\n+    window.addEventListener(\"resize\", queueNavButtonsRefresh);\n+    window.addEventListener(\"scroll\", queueNavButtonsRefresh, true);\n+  }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n   function init() {\n     ensureKeyboardShortcutBinding();\n+    ensureNavViewportBinding();\n     cachePullListOrder();\n     ensureNavButtons();\n     applyCheck();\n     applyListIndicators();\n   }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check content.js",
  "description": "Validate content script syntax after nav layout fixes"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

## Assistant

Fixed — I adjusted both issues in `content.js`:

- Buttons are now positioned **directly under the Code button** (not inline to the right).
- Nav row width is locked to the **exact Code button width**.
- Kept a small vertical gap.
- Arrow labels are now rendered as plain ASCII `"<-"` and `"->"` with monospace styling so they read as single arrow strings cleanly.

I also kept keyboard navigation (`ArrowLeft` / `ArrowRight`) working.

Please hard refresh the PR page (`Cmd+Shift+R`) so the updated content script loads.

## User

[Image 1] Placement is better, although heihgt still off a bit

But the arrow character is off

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 90,
  "offset": 520
}
```

## Assistant

**Result** (success):
```
<file>
00521|         margin-top: 8px;
00522|         font-size: 11px;
00523|         color: var(--fgColor-muted, #57606a);
00524|         opacity: 0.65;
00525|       }
00526|       #${PANEL_ID} .md-pr-powered-link {
00527|         color: inherit;
00528|         text-decoration: none;
00529|       }
00530|       #${PANEL_ID} .md-pr-powered-link:hover {
00531|         text-decoration: underline;
00532|       }
00533|       #${NAV_BUTTONS_ID} {
00534|         position: absolute;
00535|         z-index: 30;
00536|         display: grid;
00537|         grid-template-columns: repeat(2, minmax(0, 1fr));
00538|         gap: 6px;
00539|       }
00540|       #${NAV_BUTTONS_ID} .md-pr-nav-btn {
00541|         appearance: none;
00542|         border: 1px solid var(--button-default-borderColor-rest, var(--borderColor-default, #d0d7de));
00543|         background: var(--button-default-bgColor-rest, var(--bgColor-muted, #f6f8fa));
00544|         color: var(--button-default-fgColor-rest, var(--fgColor-default, #24292f));
00545|         border-radius: 6px;
00546|         height: 32px;
00547|         padding: 0;
00548|         font-size: 13px;
00549|         font-weight: 600;
00550|         font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
00551|         line-height: 1;
00552|         letter-spacing: 0;
00553|         cursor: pointer;
00554|       }
00555|       #${NAV_BUTTONS_ID} .md-pr-nav-btn:hover:not(:disabled) {
00556|         background: var(--button-default-bgColor-hover, var(--bgColor-neutral-muted, #f3f4f6));
00557|       }
00558|       #${NAV_BUTTONS_ID} .md-pr-nav-btn:disabled {
00559|         cursor: default;
00560|         opacity: 0.55;
00561|       }
00562|       .md-pr-list-indicator {
00563|         display: inline-flex;
00564|         align-items: center;
00565|         justify-content: center;
00566|         width: 8px;
00567|         height: 8px;
00568|         border-radius: 999px;
00569|         margin-left: 6px;
00570|         border: 1px solid #d0d7de;
00571|       }
00572|       .md-pr-list-indicator.md-pr-list-expert {
00573|         background: #2da44e;
00574|         border-color: #2da44e;
00575|       }
00576|       .md-pr-list-indicator.md-pr-list-missing {
00577|         background: #afb8c1;
00578|       }
00579|       #${BADGE_ID} {
00580|         display: inline-flex;
00581|         align-items: center;
00582|         gap: 6px;
00583|         margin-left: 8px;
00584|         padding: 2px 8px;
00585|         border-radius: 999px;
00586|         font-size: 11px;
00587|         font-weight: 600;
00588|       }
00589|       #${BADGE_ID}.md-pr-badge-error {
00590|         background: #ffe4e8;
00591|         color: #9f1239;
00592|       }
00593|       #${BADGE_ID}.md-pr-badge-success {
00594|         background: #dcfce7;
00595|         color: #166534;
00596|       }
00597|     `;
00598|     document.head.appendChild(style);
00599|   }
00600| 
00601|   function clearMountRetry() {
00602|     if (!state.mountRetryTimer) return;
00603|     window.clearTimeout(state.mountRetryTimer);
00604|     state.mountRetryTimer = null;
00605|   }
00606| 
00607|   function scheduleMountRetry() {
00608|     if (state.mountRetryTimer || state.mountRetryCount >= 40 || !isPullDetailPage()) return;
00609|     state.mountRetryTimer = window.setTimeout(() => {
00610|       state.mountRetryTimer = null;

(File has more lines. Use 'offset' parameter to read beyond line 610)
</file>
```

## Assistant

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n       #${NAV_BUTTONS_ID} .md-pr-nav-btn {\n         appearance: none;\n         border: 1px solid var(--button-default-borderColor-rest, var(--borderColor-default, #d0d7de));\n         background: var(--button-default-bgColor-rest, var(--bgColor-muted, #f6f8fa));\n         color: var(--button-default-fgColor-rest, var(--fgColor-default, #24292f));\n-        border-radius: 6px;\n-        height: 32px;\n+        border-radius: var(--md-pr-nav-btn-radius, 6px);\n+        height: var(--md-pr-nav-btn-height, 32px);\n         padding: 0;\n-        font-size: 13px;\n+        font-size: 16px;\n         font-weight: 600;\n-        font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n+        font-family: inherit;\n         line-height: 1;\n         letter-spacing: 0;\n         cursor: pointer;\n       }\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n     const canGoPrev = Boolean(getAdjacentPullPath(-1));\n     const canGoNext = Boolean(getAdjacentPullPath(1));\n@@\n     prevButton.disabled = !canGoPrev;\n     nextButton.disabled = !canGoNext;\n \n     const disabledTitle = \"Visit the repo PR list to enable\";\n-    prevButton.title = canGoPrev ? \"Previous PR (ArrowLeft)\" : disabledTitle;\n-    nextButton.title = canGoNext ? \"Next PR (ArrowRight)\" : disabledTitle;\n+    prevButton.title = canGoPrev ? \"Previous PR (ArrowLeft)\" : disabledTitle;\n+    nextButton.title = canGoNext ? \"Next PR (ArrowRight)\" : disabledTitle;\n   }\n@@\n     let wrapper = existing;\n     if (!wrapper) {\n       wrapper = document.createElement(\"div\");\n       wrapper.id = NAV_BUTTONS_ID;\n       wrapper.innerHTML = `\n-        <button class=\"md-pr-nav-btn\" type=\"button\" data-nav=\"prev\" aria-label=\"Previous pull request\">&lt;-</button>\n-        <button class=\"md-pr-nav-btn\" type=\"button\" data-nav=\"next\" aria-label=\"Next pull request\">-&gt;</button>\n+        <button class=\"md-pr-nav-btn\" type=\"button\" data-nav=\"prev\" aria-label=\"Previous pull request\">&#8592;</button>\n+        <button class=\"md-pr-nav-btn\" type=\"button\" data-nav=\"next\" aria-label=\"Next pull request\">&#8594;</button>\n       `;\n@@\n     const width = Math.round(codeRect.width);\n     if (width > 0) {\n       wrapper.style.width = `${width}px`;\n     } else {\n       wrapper.style.width = \"\";\n     }\n+\n+    const height = Math.round(codeRect.height);\n+    if (height > 0) {\n+      wrapper.style.setProperty(\"--md-pr-nav-btn-height\", `${height}px`);\n+    }\n+\n+    const borderRadius = window.getComputedStyle(codeButton).borderRadius;\n+    if (borderRadius) {\n+      wrapper.style.setProperty(\"--md-pr-nav-btn-radius\", borderRadius);\n+    }\n*** End Patch"
}
```

## Assistant

**Result** (error):
```
(empty result)
```

## Assistant

### Tool: read

**Args:**
```json
{
  "filePath": "/Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js",
  "limit": 120,
  "offset": 260
}
```

## Assistant

**Result** (success):
```
<file>
00261|     return candidates[0].element;
00262|   }
00263| 
00264|   function updateNavButtonsState(wrapper) {
00265|     if (!wrapper) return;
00266| 
00267|     const prevButton = wrapper.querySelector("[data-nav='prev']");
00268|     const nextButton = wrapper.querySelector("[data-nav='next']");
00269|     if (!prevButton || !nextButton) return;
00270| 
00271|     const canGoPrev = Boolean(getAdjacentPullPath(-1));
00272|     const canGoNext = Boolean(getAdjacentPullPath(1));
00273| 
00274|     prevButton.disabled = !canGoPrev;
00275|     nextButton.disabled = !canGoNext;
00276| 
00277|     const disabledTitle = "Visit the repo PR list to enable";
00278|     prevButton.title = canGoPrev ? "Previous PR (ArrowLeft)" : disabledTitle;
00279|     nextButton.title = canGoNext ? "Next PR (ArrowRight)" : disabledTitle;
00280|   }
00281| 
00282|   function ensureNavButtons() {
00283|     const existing = document.getElementById(NAV_BUTTONS_ID);
00284| 
00285|     if (!isPullDetailPage()) {
00286|       if (existing) existing.remove();
00287|       clearNavMountRetry();
00288|       state.navMountRetryCount = 0;
00289|       return;
00290|     }
00291| 
00292|     const codeButton = findCodeButton();
00293|     if (!codeButton) {
00294|       if (existing) existing.remove();
00295|       scheduleNavMountRetry();
00296|       return;
00297|     }
00298| 
00299|     const codeRect = codeButton.getBoundingClientRect();
00300|     if (!codeRect.width || !codeRect.height) {
00301|       scheduleNavMountRetry();
00302|       return;
00303|     }
00304| 
00305|     let wrapper = existing;
00306|     if (!wrapper) {
00307|       wrapper = document.createElement("div");
00308|       wrapper.id = NAV_BUTTONS_ID;
00309|       wrapper.innerHTML = `
00310|         <button class="md-pr-nav-btn" type="button" data-nav="prev" aria-label="Previous pull request">&lt;-</button>
00311|         <button class="md-pr-nav-btn" type="button" data-nav="next" aria-label="Next pull request">-&gt;</button>
00312|       `;
00313| 
00314|       wrapper.querySelector("[data-nav='prev']")?.addEventListener("click", (event) => {
00315|         event.preventDefault();
00316|         navigateToAdjacentPull(-1);
00317|       });
00318|       wrapper.querySelector("[data-nav='next']")?.addEventListener("click", (event) => {
00319|         event.preventDefault();
00320|         navigateToAdjacentPull(1);
00321|       });
00322|     }
00323| 
00324|     if (wrapper.parentElement !== document.body) {
00325|       document.body.appendChild(wrapper);
00326|     }
00327| 
00328|     wrapper.style.left = `${Math.round(window.scrollX + codeRect.left)}px`;
00329|     wrapper.style.top = `${Math.round(window.scrollY + codeRect.bottom + 6)}px`;
00330|     wrapper.style.width = `${Math.round(codeRect.width)}px`;
00331| 
00332|     updateNavButtonsState(wrapper);
00333|     clearNavMountRetry();
00334|     state.navMountRetryCount = 0;
00335|   }
00336| 
00337|   function canUseBackground() {
00338|     return typeof chrome !== "undefined" && chrome.runtime && chrome.runtime.sendMessage;
00339|   }
00340| 
00341|   function fetchViaBackground(url, apiKey) {
00342|     if (!canUseBackground()) return Promise.resolve(null);
00343|     return new Promise((resolve) => {
00344|       chrome.runtime.sendMessage(
00345|         { type: "md-expert-pr-check", url, apiKey },
00346|         (response) => {
00347|           if (chrome.runtime.lastError) {
00348|             resolve(null);
00349|             return;
00350|           }
00351|           resolve(response);
00352|         }
00353|       );
00354|     });
00355|   }
00356| 
00357|   function ensureStyles() {
00358|     if (document.getElementById(STYLE_ID)) return;
00359|     const style = document.createElement("style");
00360|     style.id = STYLE_ID;
00361|     style.textContent = `
00362|       #${PANEL_ID} {
00363|         color: var(--fgColor-default, #24292f);
00364|       }
00365|       #${PANEL_ID}.discussion-sidebar-item {
00366|         margin-top: 0;
00367|       }
00368|       #${PANEL_ID}.md-pr-fallback {
00369|         margin: 16px 0;
00370|       }
00371|       #${PANEL_ID} .md-pr-panel {
00372|         font-size: 12px;
00373|         line-height: 1.5;
00374|       }
00375|       #${PANEL_ID} .md-pr-header {
00376|         display: flex;
00377|         justify-content: space-between;
00378|         align-items: center;
00379|         margin-bottom: 6px;
00380|       }

(File has more lines. Use 'offset' parameter to read beyond line 380)
</file>
```

## Assistant

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n       wrapper = document.createElement(\"div\");\n       wrapper.id = NAV_BUTTONS_ID;\n       wrapper.innerHTML = `\n-        <button class=\"md-pr-nav-btn\" type=\"button\" data-nav=\"prev\" aria-label=\"Previous pull request\">&lt;-</button>\n-        <button class=\"md-pr-nav-btn\" type=\"button\" data-nav=\"next\" aria-label=\"Next pull request\">-&gt;</button>\n+        <button class=\"md-pr-nav-btn\" type=\"button\" data-nav=\"prev\" aria-label=\"Previous pull request\">&#8592;</button>\n+        <button class=\"md-pr-nav-btn\" type=\"button\" data-nav=\"next\" aria-label=\"Next pull request\">&#8594;</button>\n       `;\n@@\n     wrapper.style.left = `${Math.round(window.scrollX + codeRect.left)}px`;\n     wrapper.style.top = `${Math.round(window.scrollY + codeRect.bottom + 6)}px`;\n     wrapper.style.width = `${Math.round(codeRect.width)}px`;\n+    wrapper.style.setProperty(\"--md-pr-nav-btn-height\", `${Math.round(codeRect.height)}px`);\n+\n+    const borderRadius = window.getComputedStyle(codeButton).borderRadius;\n+    if (borderRadius) {\n+      wrapper.style.setProperty(\"--md-pr-nav-btn-radius\", borderRadius);\n+    }\n \n     updateNavButtonsState(wrapper);\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

### Tool: apply_patch

**Args:**
```json
{
  "patchText": "*** Begin Patch\n*** Update File: /Users/tarunsachdeva/code/market.dev/explorer-chrome-extension/content.js\n@@\n       #${NAV_BUTTONS_ID} .md-pr-nav-btn {\n         appearance: none;\n         border: 1px solid var(--button-default-borderColor-rest, var(--borderColor-default, #d0d7de));\n         background: var(--button-default-bgColor-rest, var(--bgColor-muted, #f6f8fa));\n         color: var(--button-default-fgColor-rest, var(--fgColor-default, #24292f));\n         border-radius: var(--md-pr-nav-btn-radius, 6px);\n         height: var(--md-pr-nav-btn-height, 32px);\n         padding: 0;\n-        font-size: 16px;\n+        display: inline-flex;\n+        align-items: center;\n+        justify-content: center;\n+        font-size: 14px;\n         font-weight: 600;\n         font-family: inherit;\n         line-height: 1;\n         letter-spacing: 0;\n         cursor: pointer;\n*** End Patch"
}
```

## Assistant

**Result** (success):
```
Success. Updated the following files:
M content.js
```

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "node --check content.js",
  "description": "Validate script after arrow glyph and size tweaks"
}
```

## Assistant

**Result** (success):
```
(empty result)
```

## Assistant

## Assistant

Great catch — I fixed both in `content.js`:

- Arrows now use actual arrow glyphs: `←` and `→` (not `<-` / `->` text combos).
- Button height now matches the detected `Code` button height exactly.
- Border radius also mirrors the `Code` button so the shape feels native.
- Arrow centering is tightened with flex centering.

Please hard refresh the PR page (`Cmd+Shift+R`) and check again. If it’s still 1–2px off on your zoom level, I can add a tiny visual offset tweak.

## User

share this trace 

## Assistant

## Assistant

### Tool: bash

**Args:**
```json
{
  "command": "git status --short && git diff -- content.js",
  "description": "Show working tree status and content script diff trace"
}
```

## Assistant

**Result** (success):
```
 M content.js
diff --git a/content.js b/content.js
index 2475cdf..cee318c 100644
--- a/content.js
+++ b/content.js
@@ -1,8 +1,11 @@
 (() => {
   const STORAGE_KEY = "md_expert_pr_config";
+  const NAV_CACHE_KEY = "md_expert_pr_nav_cache";
   const STYLE_ID = "md-expert-pr-style";
   const PANEL_ID = "md-expert-pr-panel";
   const BADGE_ID = "md-expert-pr-badge";
+  const NAV_BUTTONS_ID = "md-expert-pr-nav-buttons";
+  const NAV_CACHE_MAX_AGE_MS = 1000 * 60 * 60 * 8;
 
   const DEFAULT_CONFIG = {
     apiKey: "",
@@ -14,7 +17,12 @@
     currentResult: null,
     listCache: new Map(),
     mountRetryTimer: null,
-    mountRetryCount: 0
+    mountRetryCount: 0,
+    keyboardListenerAttached: false,
+    navMountRetryTimer: null,
+    navMountRetryCount: 0,
+    navViewportListenerAttached: false,
+    navRepositionFrame: null
   };
 
   function loadConfig() {
@@ -41,6 +49,297 @@
     return /\/pulls(\/|$)/.test(window.location.pathname);
   }
 
+  function normalizePullPath(urlLike) {
+    try {
+      const url = new URL(String(urlLike || ""), window.location.origin);
+      const match = url.pathname.match(/^\/[^/]+\/[^/]+\/pull\/\d+/);
+      return match ? match[0] : null;
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function getRepoPathFromPullPath(pullPath) {
+    const match = String(pullPath || "").match(/^\/[^/]+\/[^/]+/);
+    return match ? match[0] : null;
+  }
+
+  function readNavigationCache() {
+    const raw = window.localStorage.getItem(NAV_CACHE_KEY);
+    if (!raw) return null;
+    try {
+      const parsed = JSON.parse(raw);
+      if (!parsed || !Array.isArray(parsed.pullPaths)) return null;
+      if (typeof parsed.updatedAt !== "number") return null;
+      return parsed;
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeNavigationCache(pullPaths) {
+    if (!Array.isArray(pullPaths) || !pullPaths.length) return;
+    const repoPath = getRepoPathFromPullPath(pullPaths[0]);
+    if (!repoPath) return;
+
+    window.localStorage.setItem(
+      NAV_CACHE_KEY,
+      JSON.stringify({
+        repoPath,
+        listPath: window.location.pathname,
+        listSearch: window.location.search || "",
+        pullPaths,
+        updatedAt: Date.now()
+      })
+    );
+  }
+
+  function cachePullListOrder() {
+    if (!isPullListPage()) return;
+
+    const rows = document.querySelectorAll("div.js-issue-row");
+    const pullPaths = [];
+    const seen = new Set();
+
+    rows.forEach((row) => {
+      const titleLink =
+        row.querySelector("a[data-hovercard-type='pull_request']") ||
+        row.querySelector("a[id^='issue_']") ||
+        row.querySelector("a.Link--primary[href*='/pull/']");
+      if (!titleLink) return;
+
+      const pullPath = normalizePullPath(titleLink.getAttribute("href") || titleLink.href);
+      if (!pullPath || seen.has(pullPath)) return;
+
+      seen.add(pullPath);
+      pullPaths.push(pullPath);
+    });
+
+    writeNavigationCache(pullPaths);
+  }
+
+  function isEditableTarget(target) {
+    const element = target instanceof Element ? target : null;
+    if (!element) return false;
+    if (element.closest("input, textarea, select, button, [contenteditable=''], [contenteditable='true'], [role='textbox']")) {
+      return true;
+    }
+    return false;
+  }
+
+  function getAdjacentPullPath(direction) {
+    const currentPullPath = normalizePullPath(window.location.href);
+    if (!currentPullPath) return null;
+
+    const cache = readNavigationCache();
+    if (!cache) return null;
+    if (!Array.isArray(cache.pullPaths) || cache.pullPaths.length < 2) return null;
+    if (Date.now() - cache.updatedAt > NAV_CACHE_MAX_AGE_MS) return null;
+
+    const repoPath = getRepoPathFromPullPath(currentPullPath);
+    if (!repoPath || cache.repoPath !== repoPath) return null;
+
+    const currentIndex = cache.pullPaths.indexOf(currentPullPath);
+    if (currentIndex === -1) return null;
+
+    const targetIndex = (currentIndex + direction + cache.pullPaths.length) % cache.pullPaths.length;
+    if (targetIndex === currentIndex) return null;
+
+    return cache.pullPaths[targetIndex];
+  }
+
+  function navigateToAdjacentPull(direction) {
+    const targetPath = getAdjacentPullPath(direction);
+    if (!targetPath) return false;
+    window.location.assign(targetPath);
+    return true;
+  }
+
+  function handlePullNavigationShortcut(event) {
+    if (!isPullDetailPage()) return;
+    if (event.defaultPrevented) return;
+    if (event.metaKey || event.ctrlKey || event.altKey) return;
+    if (isEditableTarget(event.target)) return;
+
+    let direction = 0;
+    if (event.key === "ArrowRight") direction = 1;
+    if (event.key === "ArrowLeft") direction = -1;
+    if (event.key === "]") direction = 1;
+    if (event.key === "[") direction = -1;
+    if (!direction) return;
+
+    const navigated = navigateToAdjacentPull(direction);
+    if (!navigated) return;
+
+    event.preventDefault();
+    event.stopPropagation();
+  }
+
+  function ensureKeyboardShortcutBinding() {
+    if (state.keyboardListenerAttached) return;
+    state.keyboardListenerAttached = true;
+    document.addEventListener("keydown", handlePullNavigationShortcut, true);
+  }
+
+  function clearNavMountRetry() {
+    if (!state.navMountRetryTimer) return;
+    window.clearTimeout(state.navMountRetryTimer);
+    state.navMountRetryTimer = null;
+  }
+
+  function scheduleNavMountRetry() {
+    if (state.navMountRetryTimer || state.navMountRetryCount >= 40 || !isPullDetailPage()) return;
+    state.navMountRetryTimer = window.setTimeout(() => {
+      state.navMountRetryTimer = null;
+      state.navMountRetryCount += 1;
+      ensureNavButtons();
+    }, 250);
+  }
+
+  function queueNavButtonsRefresh() {
+    if (state.navRepositionFrame !== null) return;
+    state.navRepositionFrame = window.requestAnimationFrame(() => {
+      state.navRepositionFrame = null;
+      ensureNavButtons();
+    });
+  }
+
+  function ensureNavViewportBinding() {
+    if (state.navViewportListenerAttached) return;
+    state.navViewportListenerAttached = true;
+    window.addEventListener("resize", queueNavButtonsRefresh);
+    window.addEventListener("scroll", queueNavButtonsRefresh, true);
+  }
+
+  function getCodeButtonMatchScore(element) {
+    const text = normalizeText(element.textContent);
+    const ariaLabel = normalizeText(element.getAttribute("aria-label"));
+
+    let score = 0;
+    if (text === "code") score += 4;
+    else if (text.startsWith("code ")) score += 2;
+
+    if (ariaLabel === "code") score += 3;
+    else if (ariaLabel.startsWith("code ")) score += 2;
+
+    return score;
+  }
+
+  function findCodeButton() {
+    const sidebar = findSidebar();
+    const roots = [sidebar, document].filter(Boolean);
+    const seen = new Set();
+    const candidates = [];
+
+    roots.forEach((root) => {
+      root.querySelectorAll("button, summary, a").forEach((element) => {
+        if (seen.has(element)) return;
+        seen.add(element);
+
+        if (!isVisibleElement(element)) return;
+        if (element.closest(`#${PANEL_ID}`) || element.closest(`#${NAV_BUTTONS_ID}`)) return;
+
+        const textScore = getCodeButtonMatchScore(element);
+        if (!textScore) return;
+
+        const classText = normalizeText(element.className);
+        const rect = element.getBoundingClientRect();
+
+        let score = textScore;
+        if (sidebar && sidebar.contains(element)) score += 8;
+        if (classText.includes("btn") || classText.includes("button")) score += 2;
+        if (element.closest("details")) score += 1;
+        if (rect.width >= 80 && rect.width <= 240) score += 2;
+        if (rect.height >= 28 && rect.height <= 44) score += 1;
+
+        candidates.push({ element, score });
+      });
+    });
+
+    if (!candidates.length) return null;
+    candidates.sort((a, b) => b.score - a.score);
+    return candidates[0].element;
+  }
+
+  function updateNavButtonsState(wrapper) {
+    if (!wrapper) return;
+
+    const prevButton = wrapper.querySelector("[data-nav='prev']");
+    const nextButton = wrapper.querySelector("[data-nav='next']");
+    if (!prevButton || !nextButton) return;
+
+    const canGoPrev = Boolean(getAdjacentPullPath(-1));
+    const canGoNext = Boolean(getAdjacentPullPath(1));
+
+    prevButton.disabled = !canGoPrev;
+    nextButton.disabled = !canGoNext;
+
+    const disabledTitle = "Visit the repo PR list to enable";
+    prevButton.title = canGoPrev ? "Previous PR (ArrowLeft)" : disabledTitle;
+    nextButton.title = canGoNext ? "Next PR (ArrowRight)" : disabledTitle;
+  }
+
+  function ensureNavButtons() {
+    const existing = document.getElementById(NAV_BUTTONS_ID);
+
+    if (!isPullDetailPage()) {
+      if (existing) existing.remove();
+      clearNavMountRetry();
+      state.navMountRetryCount = 0;
+      return;
+    }
+
+    const codeButton = findCodeButton();
+    if (!codeButton) {
+      if (existing) existing.remove();
+      scheduleNavMountRetry();
+      return;
+    }
+
+    const codeRect = codeButton.getBoundingClientRect();
+    if (!codeRect.width || !codeRect.height) {
+      scheduleNavMountRetry();
+      return;
+    }
+
+    let wrapper = existing;
+    if (!wrapper) {
+      wrapper = document.createElement("div");
+      wrapper.id = NAV_BUTTONS_ID;
+      wrapper.innerHTML = `
+        <button class="md-pr-nav-btn" type="button" data-nav="prev" aria-label="Previous pull request">&#8592;</button>
+        <button class="md-pr-nav-btn" type="button" data-nav="next" aria-label="Next pull request">&#8594;</button>
+      `;
+
+      wrapper.querySelector("[data-nav='prev']")?.addEventListener("click", (event) => {
+        event.preventDefault();
+        navigateToAdjacentPull(-1);
+      });
+      wrapper.querySelector("[data-nav='next']")?.addEventListener("click", (event) => {
+        event.preventDefault();
+        navigateToAdjacentPull(1);
+      });
+    }
+
+    if (wrapper.parentElement !== document.body) {
+      document.body.appendChild(wrapper);
+    }
+
+    wrapper.style.left = `${Math.round(window.scrollX + codeRect.left)}px`;
+    wrapper.style.top = `${Math.round(window.scrollY + codeRect.bottom + 6)}px`;
+    wrapper.style.width = `${Math.round(codeRect.width)}px`;
+    wrapper.style.setProperty("--md-pr-nav-btn-height", `${Math.round(codeRect.height)}px`);
+
+    const borderRadius = window.getComputedStyle(codeButton).borderRadius;
+    if (borderRadius) {
+      wrapper.style.setProperty("--md-pr-nav-btn-radius", borderRadius);
+    }
+
+    updateNavButtonsState(wrapper);
+    clearNavMountRetry();
+    state.navMountRetryCount = 0;
+  }
+
   function canUseBackground() {
     return typeof chrome !== "undefined" && chrome.runtime && chrome.runtime.sendMessage;
   }
@@ -237,6 +536,38 @@
       #${PANEL_ID} .md-pr-powered-link:hover {
         text-decoration: underline;
       }
+      #${NAV_BUTTONS_ID} {
+        position: absolute;
+        z-index: 30;
+        display: grid;
+        grid-template-columns: repeat(2, minmax(0, 1fr));
+        gap: 6px;
+      }
+      #${NAV_BUTTONS_ID} .md-pr-nav-btn {
+        appearance: none;
+        border: 1px solid var(--button-default-borderColor-rest, var(--borderColor-default, #d0d7de));
+        background: var(--button-default-bgColor-rest, var(--bgColor-muted, #f6f8fa));
+        color: var(--button-default-fgColor-rest, var(--fgColor-default, #24292f));
+        border-radius: var(--md-pr-nav-btn-radius, 6px);
+        height: var(--md-pr-nav-btn-height, 32px);
+        padding: 0;
+        display: inline-flex;
+        align-items: center;
+        justify-content: center;
+        font-size: 14px;
+        font-weight: 600;
+        font-family: inherit;
+        line-height: 1;
+        letter-spacing: 0;
+        cursor: pointer;
+      }
+      #${NAV_BUTTONS_ID} .md-pr-nav-btn:hover:not(:disabled) {
+        background: var(--button-default-bgColor-hover, var(--bgColor-neutral-muted, #f3f4f6));
+      }
+      #${NAV_BUTTONS_ID} .md-pr-nav-btn:disabled {
+        cursor: default;
+        opacity: 0.55;
+      }
       .md-pr-list-indicator {
         display: inline-flex;
         align-items: center;
@@ -809,6 +1140,8 @@
   async function applyListIndicators() {
     if (!isPullListPage()) return;
 
+    cachePullListOrder();
+
     const rows = document.querySelectorAll("div.js-issue-row");
     rows.forEach((row) => {
       const author = row.getAttribute("data-author");
@@ -830,6 +1163,7 @@
 
   async function applyCheck() {
     ensurePanel();
+    ensureNavButtons();
     if (!isPullDetailPage()) return;
 
     const username = findPrAuthor();
@@ -852,6 +1186,10 @@
   }
 
   function init() {
+    ensureKeyboardShortcutBinding();
+    ensureNavViewportBinding();
+    cachePullListOrder();
+    ensureNavButtons();
     applyCheck();
     applyListIndicators();
   }

```

## Assistant

## Assistant

Yep — here’s the trace from the current state (shareable):

```text
git status --short
M content.js
```

Key diff trace in `content.js`:
- Added nav constants/state: `NAV_CACHE_KEY`, `NAV_BUTTONS_ID`, nav retry/reposition state.
- Added PR-order cache + navigation logic:
  - `normalizePullPath`, `readNavigationCache`, `writeNavigationCache`, `cachePullListOrder`
  - `getAdjacentPullPath`, `navigateToAdjacentPull`
- Added keyboard nav:
  - `ArrowLeft` / `ArrowRight` (plus `[` / `]`)
- Added Code-button anchored nav UI:
  - `findCodeButton`, `ensureNavButtons`, retry + viewport reposition listeners
  - Buttons now render as `←` and `→`
  - Width/height/radius derived from the actual Code button
- Added styles for `#md-expert-pr-nav-buttons` and `.md-pr-nav-btn`.
- Hooked nav refresh into page lifecycle:
  - `init()` now binds keyboard + viewport listeners and mounts nav buttons
  - `applyCheck()` also calls `ensureNavButtons()`.

If you want, I can commit this as a separate “PR navigation controls” commit now.
