- boss/chatlist: List chat conversations (招聘端聊天列表)
Uses getBossFriendListV2 API with pagination and job filter support.
- boss/chatmsg: Read chat message history with a candidate
Resolves encryptUid to numeric uid/securityId, fetches via historyMsg API.
- boss/send: Send chat message to a candidate via UI automation
BOSS chat uses MQTT protocol (not HTTP), so this command automates the
web chat UI: clicks on user in list → types in contenteditable editor →
clicks the send button.
All three commands use Strategy.COOKIE and require an active BOSS直聘
login session in Chrome.
The previous approach (nativeSetter + Enter keydown on the search input)
does not reliably trigger Twitter's form submission - the synthetic
KeyboardEvent is ignored by React, leaving the page on /explore with
zero API calls captured.
Use history.pushState + PopStateEvent instead, which triggers React
Router's listener and performs a true SPA navigation to /search.
The interceptor survives because no full page reload occurs.
Tested: "opencli", "it's a test" (single quote), "hello" all return
results with correct author attribution.
Add CLI commands to view Chaoxing assignments and exams by reusing
Chrome login session via the Browser Bridge.
Chaoxing has no flat API for listing assignments/exams. The adapter
follows the browser flow: establish session → fetch course list via
backclazzdata API → enter each course via stucoursemiddle redirect →
click tab to capture iframe URL → navigate and parse DOM.
Commands:
opencli chaoxing assignments [--course <name>] [--status] [--limit]
opencli chaoxing exams [--course <name>] [--status] [--limit]
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(intercept): use evaluate() for IIFE wrapping in installInterceptor/getInterceptedRequests
Root cause: daemon migration changed these methods from this.evaluate()
to direct sendCommand('exec'), losing the wrapForEval() IIFE wrapping.
CDP received bare arrow functions that were never invoked.
Fixes#98
* fix(twitter): SPA navigation, data path, and author resolution for INTERCEPT commands
- followers/following: install interceptor on profile page, then click
followers/following link (SPA navigation preserves JS context).
Use JSON.stringify for targetUser to prevent injection. Throw on
navigation failure. Update selector: /verified_followers.
- notifications: install interceptor on home, then pushState+popstate
to /notifications. Validate navigation URL.
- search: fix author resolution (core.screen_name, not legacy).
- All: fix GraphQL data path (remove extra .data level), update author
resolution to try core.screen_name before legacy.screen_name.
- followers: remove erroneous .filter(r => r?.url) — interceptor stores
response body JSON, URL filtering happens at capture time.
Replace eager close-window (which caused race conditions when
parallel commands shared the window) with an idle-based timer:
- Window auto-closes 30s after the last command completes
- Each incoming command resets the idle timer
- Consecutive commands reuse the same window (faster)
- No race conditions with parallel execution
- Close-window action kept for explicit cleanup if needed
- Add 'close-window' action to extension protocol and background.ts
- Add Page.closeWindow() method to send close-window command
- browserSession() now closes automation window in cleanup
- Remove domain pre-navigation + 2s wait from main.ts (CDP handles
cross-domain cookies natively, no same-origin workaround needed)
- Net effect: commands run faster, no stale windows left behind
- Delete unused extension/src/executor.ts (chrome.scripting experiment)
- Remove 15 no-op backward-compat exports from doctor.ts
- Remove getTokenFingerprint no-op from browser/index.ts
- Rename PlaywrightMCP → BrowserBridge across all source files
(backward-compat alias kept in mcp.ts and browser/index.ts)
- Remove unnecessary host_permissions from extension manifest
- Sync extension package.json version to 0.2.0
- All 14 tests pass
All opencli operations now run in a dedicated Chrome window instead
of hijacking the user's active tab. The automation window:
- Created on first command via chrome.windows.create({ focused: false })
- 1280x900 viewport, auto-cleaned up when closed
- All tabs resolved within this window only
- User's main browsing session is never touched
Tested: twitter trending ✅, zhihu hot ✅
Both commands now scroll the conversation list to load more items
before processing. Scrolls up to 20-30 times, stops after 3
consecutive scrolls with no new items loaded.
Previously limited to ~14 visible conversations, now loads as many
as needed (up to --max).
- Rewrite accept.ts: use [data-testid=conversation] click-based approach
instead of extracting href links (requests page has no /messages/xxx links)
- Support comma-separated keywords for OR matching (e.g. '群,微信')
- Add timeoutSeconds: 600 (10 min) for batch DM operations
- Bump default OPENCLI_BROWSER_COMMAND_TIMEOUT from 45s to 60s
- Track visited conversations to avoid infinite loops
Usage:
opencli twitter accept --keyword '微信' --max 20
Workflow:
1. Navigate to /messages/requests
2. Click into each conversation
3. If message contains keyword, click Accept
4. After accept (auto-redirects to /messages), go back to requests
5. Repeat until --max reached or no more matches
process.execPath is always plain 'node' even under tsx,
so .ts files could not be executed. Use --import tsx/esm
flag to enable TypeScript loading in spawned daemon.
Add weread adapter for issue #82, covering search, rankings, book details,
bookshelf, notebooks, highlights, and notes.
Public commands (no login required):
- weread search <keyword> — search books
- weread ranking [category] — book rankings (all/rising/category ID)
Private commands (cookie auth via browser):
- weread book <bookId> — book details
- weread shelf — personal bookshelf
- weread notebooks — books with highlights/notes
- weread highlights <bookId> — underlines in a book
- weread notes <bookId> — personal notes on a book
Closes#82
goto() triggers a full page navigation that resets the JS execution
context, wiping any previously injected fetch/XHR monkey-patches.
The old code installed the interceptor on x.com then navigated away,
so the interceptor was always destroyed before it could capture data.
Fix: navigate directly to the target page, install interceptor after
page load, then scroll to trigger API calls via pagination.
Also fixes the same bug in notifications.ts.
Closes#86
Exponential backoff:
- Reconnect delay: 2s, 4s, 8s, 16s, ..., capped at 60s
- Resets to base delay on successful connection
- Reduces idle CPU waste vs fixed 3s reconnect
Screenshot via CDP Page.captureScreenshot:
- New 'screenshot' action in protocol (5th action)
- Supports format (png/jpeg), quality, fullPage
- Full-page: uses Emulation.setDeviceMetricsOverride for scroll height
- CLI-side: page.screenshot() with optional file save
- Extension build: 9.81KB (+1.7KB from 8.11KB)
Inspired by bb-browser's architecture patterns.
When using CDP mode (OPENCLI_CDP_ENDPOINT), the browser page context is
the user's active tab which may be on an unrelated domain. Cookie/header
strategy commands that use fetch() with credentials: 'include' then fail
with "Failed to fetch" due to the browser's same-origin policy.
Fix: before executing cookie/header strategy commands, navigate to the
command's declared domain so the fetch runs in same-origin context.
This mirrors the pre-navigation already done in the cascade command.
Affects all cookie-strategy adapters (bilibili, twitter, zhihu, xueqiu,
etc.) when OPENCLI_CDP_ENDPOINT is enabled and the active Chrome tab is
on a different site.
Co-authored-by: kensei <backtime1993@gmail.com>
* chore(ci): add Dependabot for npm and GitHub Actions updates
- Weekly npm dependency updates with PR limit of 10
- Weekly GitHub Actions version updates with PR limit of 5
- Conventional commit prefixes (chore(deps), chore(ci))
* ci: add security audit workflow
- Run npm audit on push/PR and weekly schedule
- Fail on high-severity vulnerabilities using audit-ci
- Only audit production dependencies
* ci: add release-please for automated changelog and versioning
- Auto-generate CHANGELOG.md from Conventional Commits
- Create version bump PRs on push to main
- Works alongside existing release.yml for npm publish
* ci: add concurrency controls and Node.js version matrix
- Add concurrency groups to ci, e2e-headed, security workflows
to cancel duplicate runs on the same branch
- Test unit tests across Node 18/20/22 with fail-fast: false
- Update test step name to show Node version
* chore: bump minimum Node.js version from 18 to 20
- Update engines.node in package.json to >=20.0.0
- Update prerequisites in README.md and README.zh-CN.md
- Remove Node 18 from CI test matrix
* review: fix release token and prod-only audit scope
* docs: align Node 20 troubleshooting guidance
---------
Co-authored-by: jackwener <jakevingoo@gmail.com>
Feishu uses custom 'Lark Framework' (Chromium-based but NOT Electron).
CDP port test failed — --remote-debugging-port has no effect.
Uses AppleScript + clipboard approach (same as WeChat/ChatGPT).
Commands: status, send, read, search (Cmd+K), new (Cmd+N)
Includes adapter READMEs (EN+ZH).