# rclone-jav (Brave extension + native messaging host) Session memory for Claude. Read before making changes here. ## Architecture ``` Brave tab title -> content script extracts JAV ID -> background.js connectNative("com.rcjav.host") -> host/rcjav-host.bat (portable: py launcher or python on PATH) -> host/rcjav-host.py -> subprocess python rc-jav.py --search ID --basic --no-color --format json -> structured hits back through native port -> popup or in-page overlay ``` Two separate codebases: - This repo: Brave extension + native messaging host. - `D:\DEV\Project\rclone-jav\` — Python rc-jav CLI. The host shells out to `rc-jav.py` here. ## Folder layout (post-rename) ``` D:\DEV\Extensions\Production\rclone-jav\ (PC 1) D:\DEV\Extensions\Staging\rclone-jav\ (PC 2) ├── manifest.json ├── background.js ├── content.js ├── popup.{html,js,css} ├── options.{html,js} ├── host\ │ ├── rcjav-host.py │ ├── rcjav-host.bat (portable: py launcher fallback) │ ├── install-host.ps1 (self-elevates to HKLM) │ ├── register-host.bat (prompts for ID, calls install-host.ps1) │ ├── com.rcjav.host.json (generated; UTF-8 NO BOM) │ └── (logs) └── docs\ ├── INSTALL.md (gotcha table at the bottom) └── README.md ``` ## Critical gotchas (learned the hard way) | Symptom | Cause | Fix | |---|---|---| | "Specified native messaging host not found" | UTF-8 BOM in com.rcjav.host.json | `WriteAllText` with `UTF8Encoding($false)` | | Same error after registering HKCU | Brave on Windows ignores HKCU on some installs | Register HKLM too. `install-host.ps1` does both. | | Host launches then disconnects | Python text-mode stdio mangles 4-byte length prefix | `msvcrt.setmode(stdin/stdout, O_BINARY)` at host startup | | Host log says "stdin closed, exiting" immediately | bat-side stderr leak corrupts protocol | `python -u` + redirect stderr to log file | | `Missing closing '}'` in install-host.ps1 | Em-dashes in comments + LF endings + Windows PS 5.1 (cp1252 fallback) | Strip em-dashes from .ps1 files, or save with BOM, or use pwsh | | Brave reload != Brave restart | NM cache survives extension reload | Kill all brave.exe processes then reopen | | `IBW-902z` page title fails to parse | `\b` after `\d` blocked by following word char | Extension regex uses `[a-zA-Z]?\b` trailing — captured but discarded | | Delete safety too broad | Allowlist reduced `cq:JAV` to `cq:` | Match full configured prefixes, not remote roots | | Overlay feels ~1.5s late on SPA pages | `SPA_SETTLE_MS` waits before auto-check | Current value is 800ms; tune carefully if detection gets flaky | ## Internal names — keep as-is - Native messaging host: `com.rcjav.host` (NOT renamed despite extension rename) - Window flag in content.js: `__rclonex_loaded__` (idempotency guard for content script re-injection) - CSS IDs starting with `rclonex-` (overlay) - Host logs: `host/logs/rcjav-host.log`, `host/logs/rcjav-host-events.log`, `host/logs/rcjav-host-stderr.log`, `host/logs/deletes.log` - Host scan progress state: `host/state/scan-state.json` Don't rename these unless there's a real reason. They're orthogonal to the user-facing extension name. ## Settings Stored in `chrome.storage.sync` under key `settings`. Per-extension-ID namespacing → if extension is reloaded under a different path, settings are wiped. **Backup/restore lives in Options → Setup & Transfer** — JSON export/import to survive reloads or PC migrations. Use it before renaming or relocating the extension. DEFAULT_SETTINGS lives in background.js. Keep in sync with options.html defaults. ## Decision log ### Deletion allowlist uses full prefixes (2026-05-20) **Decision:** host delete allowlist must use full configured path prefixes (`cq:JAV`, trash dir, etc.), not only remote roots like `cq:`. **Reasoning:** Reducing `cq:JAV` to `cq:` lets any path on the same rclone remote pass the safety check. Deletion is opt-in but must be tightly scoped. **Important:** extension delete calls must forward `rcjav_path`, or the host may read the wrong `config.json` and derive the wrong allowlist. ### Toolbar popup setting gates auto-check (2026-05-20) **Decision:** `triggers.toolbarClick` does not remove the MV3 popup, but it does gate whether the popup auto-runs `checkTab` on open. If disabled, popup stays idle until user clicks Re-Scan. ### Quick search and ID padding (2026-05-20) **Decision:** rc-jav canonical JAV IDs use at least 3 digits (`ABC-027`) and preserve 4+ digit IDs (`ABCD-1294`). Quick search emits canonical uppercase globs only. **Reasoning:** user clarified real JAV filenames are never `ABC-27` or `ABC-0027`; they are `ABC-027`. User also never uses lowercase filenames, so quick search should not use rclone `--ignore-case` because it added noticeable delay. **Operational note:** this changes cache keys. Run `python rc-jav.py --scan` in `D:\DEV\Project\rclone-jav` after this change. ### No-match overlay metadata (2026-05-20) **Decision:** host search response includes `cache_meta` and `scanned_remotes` from rc-jav JSON so no-match overlays can show what was scanned instead of falling back to "library". ### IBW-902z trailing letter (2026-05-20) **Decision:** minimal regex fix in extension only. NOT a full variant-suffix rewrite of the index. **Reasoning:** User's library uses one ID per number (either `IBW-902` OR `IBW-902z`, not both). Page titles failing on `IBW-902z` is the real bug. Extension regex now matches optional trailing letter and discards it. rc-jav's index continues to strip trailing letters at extract_id time. Effective: extension queries `IBW-902` for any title `IBW-902` or `IBW-902z`, finds the file regardless of how it's named on rclone. **Revisit if:** both `IBW-902.mp4` and `IBW-902z.mp4` ever coexist in library — they'd collide on the same ID. Then implement variant suffix (#var_Z) end-to-end. ### Native messaging host name stayed `com.rcjav.host` When extension was renamed `rclonex` → `rclone-jav`, the NM host name was NOT renamed. Reason: zero user impact (it's an internal identifier in registry/manifest), but every rename costs registry rewrites + script churn. Not worth it. ### WinCatalog backslash normalization Done in rc-jav catalog loading. Catalog CSV/XML paths are normalized from Windows `\` to rclone-style `/` before the extension sees them. ## When making changes - Extension settings schema change → update `DEFAULT_SETTINGS` in background.js AND defaults in options.html + options.js load() - New native messaging action → handler in rcjav-host.py + DISPATCH map + extension code that sends it - New options pane → sidebar item in options.html + new `.pane` div + load/save bindings in options.js - Any rc-jav.py CLI change → host invocation in rcjav-host.py handle_search must keep pace --- ## Console consolidation refactor — execution status **Spec / blueprint:** - `D:\DEV\Project\rclone-jav\mockups\console-consolidation-claude.html` (refactor spec — decision table, sequence, acceptance criteria) - `D:\DEV\Project\rclone-jav\mockups\console-consolidation-options.html` (Codex's visual annotation variant) **Shipped (in execution order):** 1. **Sim Dupe deleted from popup.** Button + click handler removed from `popup.html` / `popup.js`. Payload preserved in `samples/sim-dupe.js` for future layout work. 2. **CSS extracted from options.html.** Embedded `