Files
rclone-jav/mockups/console-consolidation-claude.html

696 lines
43 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>rclone-jav consolidation — final converged plan</title>
<style>
:root {
color-scheme: dark;
--bg: #0c0e10;
--shell: #14171a;
--panel: #181b1e;
--surface: #1f2327;
--line: #292e33;
--line-2: #3a4148;
--text: #e1e6eb;
--muted: #8a949d;
--blue: #6ec5ff;
--green: #7de4a0;
--yellow: #ffd36c;
--red: #ff9097;
--purple: #c5a9ff;
--orange: #ffb072;
}
* { box-sizing: border-box; }
body { margin:0; background:var(--bg); color:var(--text); font:13px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; }
main { padding:24px; max-width:1380px; margin:0 auto; }
h1 { margin:0 0 4px; font-size:24px; }
h2 { margin:24px 0 8px; font-size:17px; color:#f4f7fa; }
h3 { margin:0 0 6px; font-size:11px; text-transform:uppercase; color:#9ba6af; letter-spacing:0.04em; }
p { margin:0; }
.intro { color:var(--muted); max-width:960px; margin:6px 0 18px; font-size:13px; }
.meta-banner { display:flex; align-items:center; gap:10px; padding:10px 14px; background:#11181f; border:1px solid #1f2b35; border-radius:6px; margin-bottom:18px; font-size:12px; color:var(--muted); }
.meta-banner .dot { width:8px; height:8px; border-radius:50%; background:var(--green); box-shadow:0 0 0 3px rgba(125,228,160,0.15); }
.meta-banner b { color:#cfdde5; }
.status-grid { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:12px; margin-bottom:24px; }
.status-card { background:#13171b; border:1px solid #232a30; border-radius:6px; padding:12px; }
.status-card h3 { color:#dce5ed; text-transform:none; letter-spacing:0; font-size:13px; margin-bottom:8px; }
.status-card.done { border-left:3px solid var(--green); }
.status-card.todo { border-left:3px solid var(--yellow); }
.status-card.work { border-left:3px solid var(--blue); }
.status-card ul { margin:0; padding-left:16px; color:var(--muted); font-size:12px; }
.status-card ul li { margin:2px 0; }
.status-card ul li b { color:#dce5ed; font-weight:600; }
.legend { display:flex; gap:6px; flex-wrap:wrap; margin-bottom:14px; }
.pill { border-radius:12px; padding:3px 9px; font-size:11px; border:1px solid var(--line-2); background:#22272b; color:var(--text); }
.pill.keep { color:var(--green); background:#143020; border-color:#245036; }
.pill.move { color:var(--blue); background:#132837; border-color:#284b66; }
.pill.del { color:var(--red); background:#321618; border-color:#5b2228; }
.pill.debug{ color:var(--purple); background:#241d35; border-color:#453363; }
.pill.warn { color:var(--yellow); background:#332b16; border-color:#645228; }
.pill.ctx { color:var(--orange); background:#3a2818; border-color:#7a4b25; }
.mock { border:1px solid #2c333a; border-radius:8px; background:var(--shell); overflow:hidden; }
.top { display:flex; align-items:center; justify-content:space-between; padding:11px 14px; border-bottom:1px solid var(--line); background:#0f1214; }
.brand { font-weight:700; color:#fff; font-size:14px; letter-spacing:0.01em; }
.toolbar { display:flex; gap:6px; align-items:center; }
button { border:1px solid var(--line-2); border-radius:4px; padding:5px 10px; background:#252a2e; color:var(--text); font:inherit; cursor:default; }
button.primary { background:#163923; color:#aaf3bf; border-color:#285b3a; }
button.live { background:#143247; color:#9fd9ff; border-color:#2e607f; }
button.danger { background:#3a191d; color:#ffb2b7; border-color:#722c33; }
button.ghost { background:transparent; color:#9aa4ac; border-color:#3a4148; }
.layout { display:grid; grid-template-columns: 200px minmax(0,1fr); min-height:480px; }
.side { background:#0d1013; border-right:1px solid var(--line); padding:14px 12px; }
.grp { margin-bottom:16px; }
.gtitle { color:#5e6970; text-transform:uppercase; letter-spacing:0.06em; font-size:10px; margin:0 0 6px; padding-left:6px; }
.nav { display:grid; gap:2px; }
.nav a { display:flex; align-items:center; justify-content:space-between; padding:6px 8px; border-radius:4px; color:#b3bdc4; text-decoration:none; gap:6px; }
.nav a.active { background:#27313a; color:#fff; box-shadow:inset 2px 0 var(--blue); }
.nav a:hover:not(.active) { background:#1a1f24; }
.nav .badge { font-size:10px; padding:1px 6px; border-radius:9px; background:#2d343a; color:#a7b2bb; }
.nav .badge.warn { background:#3a3017; color:#ffd784; }
.nav .badge.fresh{ background:#1d3826; color:#9be3b3; }
.content { padding:18px 20px; min-width:0; }
.heading { display:flex; align-items:flex-start; justify-content:space-between; gap:10px; margin-bottom:14px; }
.heading .desc { color:var(--muted); font-size:12px; margin-top:3px; }
.row-actions { display:flex; gap:6px; }
.sub-tabs { display:flex; gap:0; border-bottom:1px solid var(--line); margin-bottom:14px; }
.sub-tabs span { padding:8px 14px; color:#8b95a0; font-size:12px; cursor:default; border-bottom:2px solid transparent; }
.sub-tabs span.active { color:#fff; border-bottom-color: var(--blue); }
.grid2 { display:grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap:10px; }
.grid3 { display:grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap:10px; }
.card { background:var(--panel); border:1px solid var(--line); border-radius:6px; padding:12px; min-width:0; }
.card .meta { color:var(--muted); font-size:11px; margin-top:4px; }
.card .metric { font-size:18px; color:#fff; font-weight:600; }
.dup-list { display:grid; gap:6px; margin-top:8px; }
.dup-row { display:grid; grid-template-columns: 1fr auto auto; align-items:center; gap:8px; padding:8px 10px; background:#141a1e; border:1px solid #232a30; border-radius:4px; }
.dup-row .path { font:12px Consolas, monospace; color:#cdd6dd; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.dup-row .size { font-size:11px; color:#8a949d; }
.keep-pill { font-size:10px; padding:1px 7px; border-radius:9px; background:#143b22; color:#9be3b3; border:1px solid #245036; }
.review-pill { font-size:10px; padding:1px 7px; border-radius:9px; background:#332b16; color:#ffd784; border:1px solid #645228; }
/* Decision table */
table.spec { width:100%; border-collapse:collapse; margin-top:10px; font-size:12px; }
table.spec th { text-align:left; padding:8px 10px; background:#181d22; color:#cfdde5; font-weight:600; border-bottom:1px solid #2a3138; }
table.spec td { padding:9px 10px; border-bottom:1px solid #1c2126; color:var(--text); vertical-align:top; }
table.spec tr:nth-child(even) td { background:#10141a; }
table.spec td.order { font-family:Consolas,monospace; color:var(--blue); font-weight:600; }
table.spec td.surface { color:#dce5ed; }
table.spec td .pill { font-size:10px; }
table.spec td .small { color:var(--muted); font-size:11px; display:block; margin-top:2px; }
/* Popup launcher mock */
.popup-mock { background:#0e1114; border:1px dashed #394149; border-radius:6px; padding:18px; display:grid; place-items:center; }
.popup-frame { width:340px; border:1px solid var(--line-2); border-radius:6px; background:#181b1e; padding:12px; box-shadow:0 6px 18px rgba(0,0,0,.4); }
.popup-frame .ptop { display:flex; justify-content:space-between; align-items:center; margin-bottom:8px; }
.popup-frame input { width:100%; background:#0a0c0e; border:1px solid #313840; border-radius:3px; padding:6px 8px; color:var(--text); font:12px Consolas,monospace; }
.popup-frame .pchips { display:flex; gap:5px; flex-wrap:wrap; margin-top:8px; }
.annot { color:var(--muted); font-size:11px; margin-top:10px; font-style:italic; }
/* Checklist */
.checklist { background:#13171b; border:1px solid #232a30; border-radius:6px; padding:14px; margin-top:10px; }
.checklist h3 { color:#dce5ed; text-transform:none; letter-spacing:0; font-size:13px; margin-bottom:8px; }
.checkrow { display:grid; grid-template-columns: 22px 1fr auto; gap:8px; padding:7px 0; border-top:1px solid #1c2126; align-items:start; }
.checkrow:first-of-type { border-top:0; }
.checkrow .box { width:14px; height:14px; border:1px solid #4a5560; border-radius:3px; margin-top:3px; background:#0a0c0e; }
.checkrow .what { color:var(--text); font-size:12px; }
.checkrow .what .small { color:var(--muted); font-size:11px; }
.checkrow .who { color:#9aa4ac; font-size:11px; font-style:italic; }
/* Decisions / sub-cards */
.dec { background:#13171b; border:1px solid #232a30; border-radius:7px; padding:14px; }
.dec-head { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:8px; }
.dec-head h3 { color:#dce5ed; text-transform:none; font-size:13px; letter-spacing:0; margin:0; }
.dec-verdict { color:#a8b3bb; font-size:12px; margin-top:8px; }
.dec-verdict b { color:#ddebf3; }
.decisions-2 { display:grid; grid-template-columns: 1fr 1fr; gap:12px; margin-top:10px; }
/* Sequence */
.seq-list { display:grid; gap:6px; margin-top:10px; }
.seq-list .step { display:grid; grid-template-columns: 30px 1fr auto auto; gap:10px; padding:9px 12px; background:#13171b; border:1px solid #232a30; border-radius:5px; align-items:center; }
.seq-list .num { width:24px; height:24px; border-radius:50%; background:#18354a; color:var(--blue); display:grid; place-items:center; font-weight:700; font-size:11px; }
.seq-list .why { color:var(--muted); font-size:11px; }
.seq-list .risk { font-size:10px; padding:2px 7px; border-radius:8px; }
.seq-list .risk.low { color:#9be3b3; background:#0f2218; border:1px solid #1e3b27; }
.seq-list .risk.med { color:#ffd784; background:#231d10; border:1px solid #3d3018; }
.seq-list .risk.high { color:#ffb2b7; background:#2a1216; border:1px solid #4a1f25; }
.seq-list .deps { font-size:10px; color:#7a838c; font-family:Consolas,monospace; }
code { font-family:Consolas, monospace; background:#1a1f24; padding:1px 5px; border-radius:3px; color:#cfdde5; }
.strike { text-decoration:line-through; color:#6b757d; }
@media (max-width: 900px) {
.layout { grid-template-columns: 1fr; }
.side { border-right:0; border-bottom:1px solid var(--line); }
.grid2, .grid3, .decisions-2, .status-grid { grid-template-columns: 1fr; }
}
</style>
</head>
<body>
<main>
<h1>rclone-jav Consolidation — Final Converged Plan</h1>
<div class="meta-banner">
<span class="dot"></span>
<span><b>Status:</b> execution in progress. <b>Shipped:</b> steps 1 (Sim Dupe delete), 2 (CSS extraction), 3 (Transfer Assistant delete + Diagnostics replacement), 5 (Recent Activity + Search Troubleshooting → new Debug Tools pane). <b>Pending:</b> steps 6 (options.js split — Cache & Dup Review paired, biggest), 7a (Bulk Check standalone window), 8 (fixtures), 9 (cache contract), 10 (rc-jav.py split), 11 (host fast-path decision). See <code>D:\DEV\Extensions\Production\rclone-jav\AGENTS.md</code> "Console consolidation refactor — execution status" for current state.</span>
</div>
<div class="status-grid">
<div class="status-card done">
<h3>✓ Decided</h3>
<ul>
<li>Console / Settings / Support tri-split</li>
<li>Default landing = <b>Duplicate Review</b></li>
<li>Status badges on tabs, <b>no dashboard pane</b></li>
<li>Launcher pattern over toolbox</li>
<li>Keep Ranking nested in Dup Review</li>
<li>Sim Dupe → <b>delete</b>, samples/ HTML harness</li>
<li>Transfer wizard → <b>delete</b> after Diagnostics replacement verified</li>
<li>Bulk ID Check → <b>detached chrome.windows popup</b>, NOT a Console sidebar tab</li>
<li>Inline rule tests stay, standalone benches → Debug</li>
</ul>
</div>
<div class="status-card done">
<h3>✓ Shipped</h3>
<ul>
<li><b>Step 1:</b> Sim Dupe deleted from popup. <code>samples/sim-dupe.js</code> preserves payload.</li>
<li><b>Step 2:</b> CSS extracted → <code>options.css</code>. options.html 1179 → 794 lines.</li>
<li><b>Step 3:</b> Transfer wizard deleted. Diagnostics → Native host registration now shows Extension ID + Copy button.</li>
<li><b>Step 5:</b> Recent Activity + Search Troubleshooting moved to new Debug Tools pane. Scope verified by code read.</li>
</ul>
</div>
<div class="status-card work">
<h3>📋 Pending</h3>
<ul>
<li><b>Step 6:</b> options.js split (Cache + Dup Review paired). 3133-line file. Biggest, riskiest.</li>
<li><b>Step 7a:</b> bulk-check.html standalone + popup launcher.</li>
<li><b>Steps 810:</b> fixtures, cache contract, rc-jav.py split.</li>
<li><b>Step 11:</b> host fast-path benchmark + narrow/delete decision.</li>
</ul>
</div>
</div>
<!-- ====================================================== -->
<h2>1. Primary recommended layout</h2>
<p class="intro">Default landing = Duplicate Review (user's most-frequent maintenance workflow). Sidebar tab labels carry live status badges — no dashboard pane needed. Launcher pattern: heavy tools open focused panes, not nested fieldsets.</p>
<div class="mock">
<div class="top">
<span class="brand">rclone-jav</span>
<div class="toolbar">
<button>Profile: cq:JAV</button>
<button class="ghost"></button>
</div>
</div>
<div class="layout">
<aside class="side">
<div class="grp">
<div class="gtitle">Console</div>
<div class="nav">
<a href="#" class="active">Duplicate Review<span class="badge warn">27</span></a>
<a href="#">Cache &amp; Scans<span class="badge fresh">28m</span></a>
<a href="#">Library Issues<span class="badge">4</span></a>
</div>
<p style="color:#5e6970; font-size:10px; margin:6px 0 0 6px; font-style:italic;">Bulk Check lives in its own window — popup launcher, not sidebar.</p>
</div>
<div class="grp">
<div class="gtitle">Settings</div>
<div class="nav">
<a href="#">Profiles</a>
<a href="#">Scan Behavior</a>
<a href="#">Matching Rules</a>
<a href="#">Site Extraction</a>
<a href="#">Overlays</a>
<a href="#">Deletion</a>
</div>
</div>
<div class="grp">
<div class="gtitle">Support</div>
<div class="nav">
<a href="#">Diagnostics</a>
<a href="#">Debug Tools</a>
</div>
</div>
</aside>
<div class="content">
<div class="heading">
<div>
<h2 style="margin-top:0;">Duplicate Review <span class="pill warn" style="margin-left:6px;">27 pending</span></h2>
<p class="desc">After-upload workflow. Risky groups skipped by default. Keep Ranking lives here as configuration, not in a separate Settings tab.</p>
</div>
<div class="row-actions">
<button>Re-scan</button>
<button class="primary">Run Delete Queue (12)</button>
</div>
</div>
<div class="sub-tabs">
<span class="active">Pending Review</span>
<span>Skipped — Risky</span>
<span>Keep Ranking Rules</span>
<span>Delete History</span>
</div>
<div class="grid2">
<div class="card">
<h3>Filter (this tool only)</h3>
<div class="row-actions" style="margin-top:6px; flex-wrap:wrap;">
<button class="ghost">Multipart only</button>
<button class="ghost">VIP collision</button>
<button class="ghost">Size diff &gt; 100MB</button>
</div>
<p class="meta">Filters scoped — never exported as global settings.</p>
</div>
<div class="card">
<h3>Delete queue</h3>
<div class="metric">12 files · 47.3 GiB</div>
<p class="meta">Safety: VIP folders + multipart-risk paths auto-excluded.</p>
</div>
</div>
<div style="margin-top:12px;">
<h3>JBD-291 · 2 candidates</h3>
<div class="dup-list">
<div class="dup-row">
<span class="path">/JAV/clearjav/JBD-291 [1080p].mp4</span>
<span class="size">4.94 GiB</span>
<span class="keep-pill">KEEP</span>
</div>
<div class="dup-row">
<span class="path">/JAV/old/JBD-291.mp4</span>
<span class="size">3.82 GiB</span>
<button class="danger" style="padding:2px 8px; font-size:11px;">Queue delete</button>
</div>
</div>
</div>
<div style="margin-top:14px;">
<h3>OFJE-195 · multipart risk</h3>
<div class="dup-list">
<div class="dup-row">
<span class="path">/JAV/OFJE-195_PART1.mp4</span>
<span class="size">2.10 GiB</span>
<span class="review-pill">REVIEW</span>
</div>
<div class="dup-row">
<span class="path">/JAV/OFJE-195_PART2.mp4</span>
<span class="size">2.08 GiB</span>
<span class="review-pill">REVIEW</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- ====================================================== -->
<h2>2. Decision table (refactor spec data)</h2>
<p class="intro">Each current pane mapped to its future home, treatment, ship order, and replacement work (if any). Ship order = execution sequence within phase 3 (UI consolidation). Steps share PR scope where useful.</p>
<div class="legend">
<span class="pill keep">KEEP visible</span>
<span class="pill ctx">CONTEXTUAL (lives with feature)</span>
<span class="pill move">MOVE (relocate)</span>
<span class="pill debug">DEBUG only</span>
<span class="pill del">DELETE</span>
</div>
<table class="spec">
<thead>
<tr>
<th style="width:42px;">#</th>
<th>Current surface</th>
<th>Future home</th>
<th>Treatment</th>
<th>Replacement</th>
</tr>
</thead>
<tbody>
<tr>
<td class="order">1</td>
<td class="surface">Sim Dupe popup action</td>
<td><code>samples/popup-states.html</code> (repo file)</td>
<td><span class="pill del">DELETE</span></td>
<td><span class="small">No product replacement. Repo HTML for layout testing only.</span></td>
</tr>
<tr>
<td class="order">2</td>
<td class="surface">CSS embedded in options.html</td>
<td>Per-pane <code>.css</code> files alongside per-pane JS</td>
<td><span class="pill move">EXTRACT</span></td>
<td><span class="small">No behavior change. Reduces options.html before JS split.</span></td>
</tr>
<tr>
<td class="order">3</td>
<td class="surface">Transfer Assistant wizard</td>
<td>(gone)</td>
<td><span class="pill del">DELETE</span></td>
<td><span class="small">Replacement = Diagnostics 3 actions (see §3 checklist). Delete <em>after</em> verification.</span></td>
</tr>
<tr>
<td class="order">4</td>
<td class="surface">Cache &amp; Scans pane</td>
<td>Console → Cache &amp; Scans</td>
<td><span class="pill keep">KEEP</span></td>
<td><span class="small">Paired with Dup Review extraction. State interface shared.</span></td>
</tr>
<tr>
<td class="order">4</td>
<td class="surface">Duplicate Review pane</td>
<td>Console → Duplicate Review <em>(default landing)</em></td>
<td><span class="pill keep">KEEP</span></td>
<td><span class="small">Same PR as Cache &amp; Scans. Reads cache state.</span></td>
</tr>
<tr>
<td class="order">4</td>
<td class="surface">Keep Ranking Rules pane</td>
<td>Duplicate Review → Keep Ranking Rules <em>(sub-tab)</em></td>
<td><span class="pill ctx">CONTEXTUAL</span></td>
<td><span class="small">Moves with Dup Review. Becomes nested sub-tab.</span></td>
</tr>
<tr>
<td class="order">4</td>
<td class="surface">VIP folders config</td>
<td>Duplicate Review → Keep Ranking Rules</td>
<td><span class="pill ctx">CONTEXTUAL</span></td>
<td><span class="small">Feature-specific config moves with feature.</span></td>
</tr>
<tr>
<td class="order">5</td>
<td class="surface">Recent Activity (search/page history)</td>
<td>Support → Debug Tools → Search Activity</td>
<td><span class="pill debug">DEBUG</span></td>
<td><span class="small">If audit deletion events also present, split out (pending verification).</span></td>
</tr>
<tr>
<td class="order">5</td>
<td class="surface">Search Troubleshooting</td>
<td>Support → Debug Tools</td>
<td><span class="pill debug">DEBUG</span></td>
<td><span class="small">Standalone bench. No edit locality.</span></td>
</tr>
<tr>
<td class="order">5</td>
<td class="surface">Page Extraction Test (standalone)</td>
<td>Support → Debug Tools</td>
<td><span class="pill debug">DEBUG</span></td>
<td><span class="small">Inline "Pick Element" variant stays in Site Extraction settings.</span></td>
</tr>
<tr>
<td class="order">5</td>
<td class="surface">Test ID Extraction (inline)</td>
<td>Settings → Matching Rules (collapsible per editor)</td>
<td><span class="pill ctx">CONTEXTUAL</span></td>
<td><span class="small">Editor feedback. Stays beside rule it tests.</span></td>
</tr>
<tr>
<td class="order">5</td>
<td class="surface">Test ID Extraction (standalone bench)</td>
<td>Support → Debug Tools</td>
<td><span class="pill debug">DEBUG</span></td>
<td><span class="small">Second row — split from inline version above.</span></td>
</tr>
<tr>
<td class="order">6</td>
<td class="surface">Library Issues pane</td>
<td>Console → Library Issues</td>
<td><span class="pill keep">KEEP</span></td>
<td><span class="small">Own tab + status badge. Rename UI nested as sub-tab.</span></td>
</tr>
<tr>
<td class="order">6</td>
<td class="surface">Bulk ID Check</td>
<td><code>bulk-check.html</code> — detached <code>chrome.windows</code> popup</td>
<td><span class="pill move">RESHAPE</span></td>
<td><span class="small">Removed from Console sidebar. Single entry path = popup launcher button → opens 640×540 detached window. Different tool type than Console panes (transient utility, no sidebar context).</span></td>
</tr>
<tr>
<td class="order">7</td>
<td class="surface">Profiles, Scan Behavior, Overlays, Deletion settings</td>
<td>Settings → (separate sub-tabs)</td>
<td><span class="pill keep">KEEP</span></td>
<td><span class="small">Settings sub-tabs split into separate JS files.</span></td>
</tr>
<tr>
<td class="order">7</td>
<td class="surface">Matching Rules / Site Extraction</td>
<td>Settings → (separate sub-tabs, inline tests retained)</td>
<td><span class="pill keep">KEEP</span></td>
<td><span class="small">Collapsible inline tester beside each rule.</span></td>
</tr>
<tr>
<td class="order">8</td>
<td class="surface">(new) Shared fixture corpus</td>
<td>Top-level <code>fixtures/</code> (neutral location)</td>
<td><span class="pill move">NEW</span></td>
<td><span class="small">Contract between extension and Python. Both consume.</span></td>
</tr>
<tr>
<td class="order">9</td>
<td class="surface">Cache contract design</td>
<td>CACHE_VERSION (exists) + ID_RULES_VERSION (new)</td>
<td><span class="pill move">NEW</span></td>
<td><span class="small">Schema bump = force rebuild. Rules bump = warn-and-mark-stale.</span></td>
</tr>
<tr>
<td class="order">10</td>
<td class="surface">rc-jav.py monolith</td>
<td><code>rcjav/</code> package (ids, cache, dupes, catalog, …)</td>
<td><span class="pill move">SPLIT</span></td>
<td><span class="small">After fixtures + tests + cache contract exist.</span></td>
</tr>
<tr>
<td class="order">11</td>
<td class="surface">Host fast-path search</td>
<td>Narrow / Delete / Keep — based on §4 benchmark</td>
<td><span class="pill warn">DECIDE</span></td>
<td><span class="small">Benchmark idle + under-scan latency first.</span></td>
</tr>
</tbody>
</table>
<!-- ====================================================== -->
<h2>3. Pre-execution checklists (user handoffs)</h2>
<div class="decisions-2">
<div class="checklist">
<h3>Diagnostics replacement verification (gates step 3 — Transfer wizard delete)</h3>
<div class="checkrow"><span class="box"></span><span class="what">Current extension ID shown as one-line text with copy-to-clipboard button<div class="small">Replaces wizard's "your extension ID is…" step.</div></span><span class="who">user opens<br>Diagnostics</span></div>
<div class="checkrow"><span class="box"></span><span class="what">Button labeled "Re-register host" that triggers register-host.bat path<div class="small">Replaces wizard's "run this script" step.</div></span><span class="who">user opens<br>Diagnostics</span></div>
<div class="checkrow"><span class="box"></span><span class="what">Verification result shown inline within 2s of register click<div class="small">Replaces wizard's "now check the result" step.</div></span><span class="who">user opens<br>Diagnostics</span></div>
<div class="checkrow"><span class="box"></span><span class="what">All three above visible without expanding collapsed sections (one screen)<div class="small">If buried in expandable cards, write better UI first.</div></span><span class="who">visual<br>inspection</span></div>
</div>
<div class="checklist">
<h3>Recent Activity scope test (settles split question)</h3>
<div class="checkrow"><span class="box"></span><span class="what">Open Recent Activity. Note current entry types visible.<div class="small">LIVE search, CACHE search, MATCH, NO_MATCH, NO_ID, page-check, etc.</div></span><span class="who">user</span></div>
<div class="checkrow"><span class="box"></span><span class="what">Perform a delete in Duplicate Review. Refresh Recent Activity.<div class="small">Single delete operation, any candidate.</div></span><span class="who">user</span></div>
<div class="checkrow"><span class="box"></span><span class="what">If delete event appears → audit value exists. Split into Dup Review → Delete History.<div class="small">If no → single role. Move entire log to Debug Tools.</div></span><span class="who">user reports</span></div>
</div>
</div>
<p class="annot">Cosmetic remaining: popup launcher button label "Bulk Check" vs icon-only. Either works. Default to label until popup row gets crowded.</p>
<!-- ====================================================== -->
<h2>4. Bulk Check — detached window pattern</h2>
<p class="intro">User clarified: Bulk Check is a transient utility, not a persistent Console surface. Doesn't fit sidebar-tab pattern alongside Dup Review / Cache &amp; Scans / Library Issues. Decision: standalone <code>bulk-check.html</code> opened as detached <code>chrome.windows</code> popup, no Console sidebar entry. Single canonical entry path = popup launcher button.</p>
<div class="grid2" style="margin-top:14px;">
<div>
<h3 style="text-transform:none; letter-spacing:0; font-size:13px; color:#dce5ed; margin-bottom:8px;">Browser-action popup with launcher</h3>
<div class="popup-mock">
<div class="popup-frame">
<div class="ptop">
<b style="color:#fff; font-size:13px;">rclone-jav</b>
<button class="ghost" style="padding:2px 8px; font-size:11px;"></button>
</div>
<input value="BLK-474" />
<div class="pchips">
<button class="primary" style="padding:3px 10px; font-size:11px;">Search</button>
<button class="live" style="padding:3px 10px; font-size:11px;">📋 Bulk Check…</button>
<button class="ghost" style="padding:3px 10px; font-size:11px;"></button>
</div>
<div class="annot" style="margin-top:10px;">Single-search stays primary. Bulk button = one click to detached window.</div>
</div>
</div>
</div>
<div>
<h3 style="text-transform:none; letter-spacing:0; font-size:13px; color:#dce5ed; margin-bottom:8px;">Detached window (640×540) after launch</h3>
<div class="popup-mock" style="padding:10px;">
<div style="width:480px; max-width:100%; background:#181b1e; border:1px solid var(--line-2); border-radius:6px; box-shadow:0 8px 24px rgba(0,0,0,.5); overflow:hidden;">
<div style="display:flex; justify-content:space-between; align-items:center; background:#0f1214; border-bottom:1px solid var(--line); padding:8px 12px;">
<b style="color:#fff; font-size:13px;">Bulk ID Check</b>
<div style="display:flex; gap:4px;">
<button class="ghost" style="padding:2px 7px; font-size:11px;">_</button>
<button class="ghost" style="padding:2px 7px; font-size:11px;"></button>
<button class="ghost" style="padding:2px 7px; font-size:11px;">×</button>
</div>
</div>
<div style="padding:12px;">
<textarea style="width:100%; height:90px; background:#0a0c0e; border:1px solid #313840; border-radius:3px; padding:7px 9px; color:var(--text); font:12px Consolas,monospace; resize:vertical;">BLK-474
FC2-PPV-1841460
KV-118
PRTD-029
JBD-291</textarea>
<div class="row-actions" style="margin-top:8px;">
<button class="primary" style="font-size:12px;">Check 5 IDs</button>
<button style="font-size:12px;">Clear</button>
<button class="ghost" style="font-size:12px;">Import .txt…</button>
</div>
<div style="margin-top:12px; padding:8px 10px; background:#0f1518; border:1px solid #1d2a30; border-radius:4px; font-size:11px; color:var(--muted);">
5 IDs checked · <span style="color:#9be3b3;">3 match</span> · <span style="color:#ffd784;">2 no match</span>
</div>
<div class="dup-list" style="margin-top:8px;">
<div class="dup-row" style="padding:6px 8px;"><span class="path">BLK-474</span><span class="size">4.94 GiB</span><span class="keep-pill">MATCH</span></div>
<div class="dup-row" style="padding:6px 8px;"><span class="path">KV-118</span><span class="size">multi-part</span><span class="keep-pill">MATCH</span></div>
<div class="dup-row" style="padding:6px 8px;"><span class="path">PRTD-029</span><span class="size"></span><span class="review-pill">NO MATCH</span></div>
</div>
</div>
</div>
</div>
<p class="annot">Detached window. No tab bar, no address bar. Closes cleanly when done. Sits over browser, stays visible across tab switches.</p>
</div>
</div>
<div class="card" style="background:#13171b; border:1px solid #232a30; margin-top:14px;">
<h3 style="color:#dce5ed; text-transform:none; letter-spacing:0; font-size:13px;">Why detached window, not Console tab</h3>
<div class="grid2" style="margin-top:8px;">
<div>
<p class="meta" style="font-size:11px;"><b style="color:#cfdde5;">Other Console tools (Dup Review, Cache &amp; Scans, Library Issues):</b></p>
<ul style="color:var(--muted); font-size:11px; margin:6px 0 0 16px; padding:0;">
<li>long workflows, multi-pass</li>
<li>need sidebar context (compare to other tools)</li>
<li>persistent state (review queue, scan job)</li>
<li>fit Options sidebar tab pattern</li>
</ul>
</div>
<div>
<p class="meta" style="font-size:11px;"><b style="color:#cfdde5;">Bulk Check:</b></p>
<ul style="color:var(--muted); font-size:11px; margin:6px 0 0 16px; padding:0;">
<li>short workflow, one-shot</li>
<li>no sidebar context needed</li>
<li>transient state (last-paste persisted, results ephemeral)</li>
<li>fits detached-window pattern</li>
</ul>
</div>
</div>
<p class="annot" style="margin-top:10px;">Different tool type. Treating it like Dup Review was a category error. Single user knows the feature exists — discovery via popup button is enough.</p>
</div>
<div class="card" style="background:#13171b; border:1px solid #232a30; margin-top:10px;">
<h3 style="color:#dce5ed; text-transform:none; letter-spacing:0; font-size:13px;">Implementation notes</h3>
<pre style="font-family:Consolas,monospace; font-size:11px; color:#cfdde5; background:#0a0c0e; padding:10px; border-radius:4px; margin:8px 0 0; overflow-x:auto; white-space:pre-wrap;">// Popup launcher click handler
chrome.windows.create({
url: chrome.runtime.getURL('bulk-check.html'),
type: 'popup',
width: 640,
height: 540
});</pre>
<ul style="color:var(--muted); font-size:12px; margin:8px 0 0 16px; padding:0;">
<li><b style="color:#dce5ed;">Window dedup:</b> track open bulk-check window ID in <code>chrome.storage.session</code>. Second launcher click focuses existing window instead of spawning duplicate.</li>
<li><b style="color:#dce5ed;">State persistence:</b> last paste saved to <code>chrome.storage.local</code> key <code>bulk_check_last_paste</code>. Reopen restores. Results are ephemeral (re-run on reopen).</li>
<li><b style="color:#dce5ed;">Backend reuse:</b> calls native host via same messaging path popup search uses. No new backend code.</li>
<li><b style="color:#dce5ed;">No back nav:</b> window can't navigate. User closes when done. Ctrl+W closes the bulk window, not a browser tab.</li>
</ul>
</div>
<div class="card" style="background:#13171b; border:1px solid #232a30; margin-top:10px;">
<h3 style="color:#dce5ed; text-transform:none; letter-spacing:0; font-size:13px;">Edge cases</h3>
<ul style="color:var(--muted); font-size:12px; margin:8px 0 0 16px; padding:0;">
<li><b style="color:#dce5ed;">Popup auto-closes after launcher click</b> (Chrome behavior). Window survives. Good — that's the intent.</li>
<li><b style="color:#dce5ed;">Window positioning unreliable.</b> Chrome treats <code>left/top</code> as hints, multi-monitor users may get the window on the wrong screen. Acceptable for personal-use tool.</li>
<li><b style="color:#dce5ed;">Brave / Edge variance.</b> Detached popups behave slightly differently across Chromium forks. Test on user's actual browser before shipping. Fallback if broken: open <code>bulk-check.html</code> in a normal tab via <code>chrome.tabs.create</code>.</li>
</ul>
</div>
<div class="card" style="background:#13171b; border:1px solid #232a30; margin-top:10px;">
<h3 style="color:#dce5ed; text-transform:none; letter-spacing:0; font-size:13px;">Does NOT generalize</h3>
<p class="meta" style="font-size:12px;">Detached-window pattern fits Bulk Check because it's transient + no-sidebar-context + short. Doesn't apply to:</p>
<ul style="color:var(--muted); font-size:12px; margin:8px 0 0 16px; padding:0;">
<li>Diagnostics — reference info, lives in sidebar fine</li>
<li>Setup repair button — already inline in Diagnostics, small enough</li>
<li>Dup Review / Cache &amp; Scans / Library Issues — long workflows, sidebar context useful</li>
<li>Settings — set-and-forget, not workflow</li>
</ul>
<p class="annot" style="margin-top:10px;">One-tool answer, not a pattern across the app.</p>
</div>
<!-- ====================================================== -->
<h2>5. Execution sequence (final)</h2>
<p class="intro">Codex's revised order (triage first, boundary doc second) with my refinements. Risk and dependencies marked. Steps 14 are reversible single-file changes (warmup phase). Steps 510 = structural. Step 11 = final architectural call.</p>
<div class="seq-list">
<div class="step"><span class="num">1</span><div><b>Per-pane triage</b> <span class="why">— 30 min with user. Decision table above IS this artifact.</span></div><span class="risk low">zero risk</span><span class="deps">no deps</span></div>
<div class="step"><span class="num">2</span><div><b>Boundary ownership doc</b> <span class="why">— extension extracts query ID, Python owns filename semantics, host adapts. 1 hour, no code.</span></div><span class="risk low">zero risk</span><span class="deps">after #1</span></div>
<div class="step"><span class="num">3</span><div><b>Host fast-path benchmark</b> <span class="why">— latency under idle Python AND under scanning Python. Result gates step 11.</span></div><span class="risk low">measure only</span><span class="deps">no deps</span></div>
<div class="step"><span class="num">4</span><div><b>Delete confirmed surfaces</b> <span class="why">— Sim Dupe popup button (no replacement), Transfer wizard (after Diagnostics verification passes).</span></div><span class="risk low">trivial</span><span class="deps">after §3 checklist</span></div>
<div class="step"><span class="num">5</span><div><b>CSS extraction from options.html</b> <span class="why">— per-pane CSS files. No behavior change. Bisect-friendly.</span></div><span class="risk low">low</span><span class="deps">after #4</span></div>
<div class="step"><span class="num">6</span><div><b>options.js split: Cache &amp; Dup Review paired</b> <span class="why">— Dup Review reads cache state. Single PR extracts both. Keep Ranking moves with Dup Review.</span></div><span class="risk med">moderate</span><span class="deps">after #5</span></div>
<div class="step"><span class="num">7</span><div><b>options.js split: Debug Tools + Library Issues + Settings sub-tabs</b> <span class="why">— remaining Options extractions. Inline test components reused across rule editors. Bulk Check is NOT here — it's a new standalone file (step 7a).</span></div><span class="risk med">moderate</span><span class="deps">after #6</span></div>
<div class="step"><span class="num">7a</span><div><b>Create <code>bulk-check.html</code> standalone + popup launcher button</b> <span class="why">— new HTML file, own JS module, no Options dependency. Popup gets one button calling <code>chrome.windows.create</code>. Window dedup + state persistence in <code>chrome.storage</code>.</span></div><span class="risk low">additive</span><span class="deps">parallel to #7</span></div>
<div class="step"><span class="num">8</span><div><b>Shared fixture corpus</b> <span class="why">— top-level <code>fixtures/</code> (neutral). Python and extension both consume.</span></div><span class="risk low">additive</span><span class="deps">no blocking</span></div>
<div class="step"><span class="num">9</span><div><b>Cache contract design</b> <span class="why">— CACHE_VERSION (exists) + ID_RULES_VERSION (new). Schema vs semantics, two concepts.</span></div><span class="risk med">design decision</span><span class="deps">before #10</span></div>
<div class="step"><span class="num">10</span><div><b>rc-jav.py module split</b> <span class="why">— ids.py, cache.py, dupes.py, catalog.py, rclone_io.py, cli.py. Tests pre-exist via #8.</span></div><span class="risk med">code churn</span><span class="deps">after #8, #9</span></div>
<div class="step"><span class="num">11</span><div><b>Host narrow / keep / delete</b> <span class="why">— based on #3 benchmark. If under-scan responsiveness depends on host = keep narrow. If not = delete.</span></div><span class="risk high">behavior change</span><span class="deps">after #3, #10</span></div>
</div>
<!-- ====================================================== -->
<h2>6. Acceptance criteria template</h2>
<p class="intro">Each step in the sequence needs three things in the final spec: acceptance criterion, rollback procedure, touched-files list. Without these, "ship order N" is a wish not a plan. Template below — fill per step in spec doc.</p>
<div class="card" style="background:#13171b; border:1px solid #232a30;">
<h3>Template per sequence step</h3>
<div style="font-family:Consolas,monospace; font-size:12px; color:#cfdde5; background:#0a0c0e; padding:12px; border-radius:4px; margin-top:8px; white-space:pre-wrap;">step: 6
title: options.js split — Cache &amp; Dup Review paired
touched_files:
- options.html (script tag order changes)
- options.js (DELETE: cache section, dup review section, keep ranking section)
- options-cache.js (NEW)
- options-review.js (NEW)
- options-core.js (NEW: shared helpers, pane nav, save/load)
acceptance:
- Fresh extension reload, options.html opens
- Default landing = Duplicate Review tab
- Cache &amp; Scans tab loads, shows last scan timestamp
- Run Duplicate Review on existing cache — same result set as pre-refactor
- Keep Ranking Rules sub-tab inside Dup Review opens
- No console errors on load or interaction
rollback:
- git revert &lt;sha&gt;
- No data migration. Cache schema unchanged. Storage keys unchanged.
- Diagnostics-verified replacement of Transfer wizard remains intact (step 3 already shipped).</div>
</div>
<!-- ====================================================== -->
<h2>7. Out of scope (explicitly rejected)</h2>
<ul style="color:var(--muted); margin:0 0 30px 18px; font-size:13px;">
<li><b style="color:#dce5ed;">Dashboard pane</b> — tab badges replace. Adding a dashboard creates a feature sink.</li>
<li><b style="color:#dce5ed;">After-Upload workflow wizard page</b> — sidebar nav order already encodes the workflow.</li>
<li><b style="color:#dce5ed;">Matching Lab consolidation page</b> — inline tests cover editor needs, standalone bench in Debug covers diagnostic needs.</li>
<li><b style="color:#dce5ed;">Mode switcher top bar (Console / Settings / Support segmented control)</b> — sidebar groups do this.</li>
<li><b style="color:#dce5ed;">In-extension Sim Dupe / Debug Preview page</b> — repo HTML file is enough for single-user layout work.</li>
<li><b style="color:#dce5ed;">Popup bulk mode toggle</b> — popup stays single-job. Launcher button opens detached window, no inline bulk mode.</li>
<li><b style="color:#dce5ed;">Bulk ID Check as Console sidebar tab</b> — wrong tool type for sidebar pattern. Detached window matches its transient nature.</li>
<li><b style="color:#dce5ed;">Bulk Check as Options-page deep-link tab</b> — previously considered. Rejected: leaves a leftover tab open after use, Options sidebar adds noise to a one-shot tool.</li>
<li><b style="color:#dce5ed;">Frontend framework (React/Vue/Svelte)</b> — vanilla + ordered script files is correct for MV3 + project scale.</li>
<li><b style="color:#dce5ed;">Console.log telemetry for usage audit</b> — manual triage of single-user project beats instrumented signals.</li>
</ul>
<h2>8. Net position</h2>
<p class="intro" style="margin-bottom:30px;">Architecture decided. Three small user handoffs remain (Diagnostics verification, Recent Activity scope check, popup button label). After those, decision table expands into per-step spec with acceptance + rollback. Code work begins on step 1 (smallest, fastest, lowest risk). Total estimated execution span: phased over multiple PRs, no big-bang refactor.</p>
</main>
</body>
</html>