- upsertJsonConfigToken: detect format by file path (opencode → mcp format,
others → mcpServers). Previously empty files always got OpenCode format.
- Dynamic Chrome profile enumeration: scan for Default/Profile N directories
instead of hardcoding 4 profiles.
- Fish shell: use 'set -gx' syntax for config.fish, not 'export'.
- Pass filePath through all callers (setup.ts, applyBrowserDoctorFix).
- Reduce setup auto-verify timeout from 8s to 5s.
- Add 7 new tests (19 total): empty file format, opencode path detection,
claude.json path detection, fish shell set/replace/append, zshrc fallback.
- When token scan fails, diagnose exact cause via checkExtensionInstalled()
(extension not installed vs token not in LevelDB)
- Show actionable fix instructions instead of generic warning
- Auto-verify browser connectivity after writing configs (Step 7)
- Simplify README setup flow to 2 steps (install + setup)
Logical flow: install extension → doctor (verify token discoverable) →
setup (distribute token to tools). --fix moved to a Tip block for
post-setup maintenance.
The previous strings+grep pipeline failed because LevelDB's internal
encoding fragments ASCII strings like 'auth-token' and the extension ID
across byte boundaries. Replace extractTokenViaStrings with a unified
binary read approach that scans for the extension ID prefix and searches
a 500-byte window for base64url tokens.
Also removes unused execSync import.
- checkExtensionInstalled(): scans Chrome/Edge/Chromium Extensions dirs
- checkTokenConnectivity(): actual MCP handshake via --live flag
- Updated DoctorReport type and report rendering
- Added unit tests for new rendering (12/12 pass)
Add two new YouTube adapters:
- **youtube video**: fetch metadata (title, views, description, etc.) from ytInitialPlayerResponse and ytInitialData
- **youtube transcript**: fetch subtitles via Android InnerTube API to bypass PoToken requirement on Web client caption URLs
- Two output modes: --mode grouped (sentence merging, speaker detection, chapter headings) and --mode raw (precise sub-second timestamps)
- CJK support with 30s time-window fallback for unpunctuated captions
- Language selection with --lang and stderr warning on fallback
- URL normalization for watch, youtu.be, shorts, embed, live formats
Co-authored-by: Ji Zhang <jizhang.work@gmail.com>
Replace flat top-level-only read.yaml with recursive tree walker:
- Configurable depth and breadth (--depth, --replies)
- Replies sorted by score, top-K selected at each level
- Hidden replies surfaced as [+N more replies]
- Multiline bodies preserve indentation at all depths
- Configurable --max_length (was hard-coded 500 chars)
- Input validation: all numeric params clamped to safe minimums
- Add *.log to .gitignore, remove debug.log from tracking
- Fix dev-mode FS scan to discover .ts adapter files (not just .js)
- Deduplicate CONNECT_TIMEOUT: browser.ts now uses runtime.ts constant
- Fix CSV output: escape newlines in field values per RFC 4180
- Add proper type interfaces for validate/verify (remove any types)
- Remove unused hadOuterQuotes variable in snapshotFormatter
- Derive CliOptions from CliCommand via Omit+Partial to reduce duplication
- Expand dense one-liner action callbacks in main.ts for readability
This commit introduces the long-form Article adapter, a rewritten Profile adapter, and 4 new UI-based Write commands for managing relationships and bookmarks. Also adds support for positional arguments across the dynamic CLI engine.
- Fix district/address field duplication (district now uses areaDistrict·businessDistrict)
- Fix template string injection risk in evaluate script (use JSON.stringify)
- Add jobInfo empty guard with user-friendly error message
- Replace raw setTimeout with page.wait for IPage compatibility
- Update README docs to include boss detail command
Expose securityId in search results so users can pipe it to
`boss detail` for full job information.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add `boss detail` command to fetch full job posting details using
securityId from search results.
Fields returned: job description, skills, welfare, boss info (name,
title, active time), company info (industry, scale, stage), address.
Tested with real API calls against multiple job postings.
Usage:
opencli boss detail --security_id <id_from_search>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
## Changes
### E2E Test Suite (~52 test cases)
- public-commands.test.ts — Public API commands (hackernews, v2ex)
- browser-public.test.ts — Browser commands for public data across all sites
- browser-auth.test.ts — Graceful failure verification for login-required commands
- management.test.ts — Full coverage of management commands
- output-formats.test.ts — Output format validation (json/yaml/csv/md)
- smoke/api-health.test.ts — Scheduled API health checks
### Auto-detect Browser Mode
- buildMcpArgs uses CI env var to select mode:
- Local (no CI) → --extension (connect to user's Chrome)
- CI → standalone (launches its own browser)
### CI Pipeline
- e2e-headed.yml — Real Chrome via setup-chrome + xvfb in headed mode
- ci.yml — build + unit-test (2 shards) + smoke-test (scheduled/manual)
- Composite action for shared Chrome + xvfb setup
### Documentation
- New TESTING.md — Architecture, coverage, local setup, how to add tests
Co-authored-by: AlexYue <yj976240184@qq.com>
Scan Chrome/Edge/Chromium localStorage LevelDB files to extract the
Playwright MCP Bridge auth-token directly from the extension's storage.
Uses a fast 'strings | grep' shell pipeline (~200ms) on macOS/Linux
with a pure-Node fallback for Windows.
The discovered token is now shown in 'opencli doctor' output and takes
priority as the recommended token when using '--fix'.