Commit Graph

433 Commits

Author SHA1 Message Date
AstroHan fbf051d539 fix(extension): skip chrome-extension:// tabs in resolveTabId fallback (#198)
* fix(extension): skip chrome-extension:// tabs in resolveTabId fallback

Remove the unsafe fallback that returned `tabs[0]` regardless of URL
type. When no web-accessible tab exists in the automation window (e.g.
a New Tab Override extension replaced about:blank with its own
chrome-extension:// page), we now always create a fresh about:blank
tab instead. This prevents chrome.debugger.attach from failing with
"Cannot access a chrome-extension:// URL of different extension".

Fixes #195, fixes #197

* refactor(extension): rename isWebUrl → isDebuggableUrl & reuse tabs in resolveTabId

Improvements over the original fix:

1. Rename isWebUrl() → isDebuggableUrl(): better reflects the intent —
   the function determines whether a URL can be attached via CDP, not
   just whether it's a "web" URL (about:blank is debuggable but not
   really a web URL).

2. Reuse existing non-debuggable tabs: when a New Tab Override extension
   replaces about:blank with chrome-extension://, use chrome.tabs.update()
   to navigate the existing tab to about:blank instead of creating a new
   one. This prevents orphan tab accumulation since chrome.tabs.create()
   may also get intercepted by the same extension.

3. Only fall back to chrome.tabs.create() when the window has zero tabs,
   which is the truly empty-window edge case.

---------

Co-authored-by: jackwener <jakevingoo@gmail.com>
2026-03-21 23:05:06 +08:00
Kasumi fcff2e40be feat(grok): add opt-in --web flow for grok ask (#193) 2026-03-21 23:00:10 +08:00
sline 4391ccfcb8 feat(tiktok): add TikTok adapter with 15 commands (#202)
* feat(tiktok): add TikTok adapter with 15 commands

TikTok (15 commands, browser mode):

Read commands:
- profile: user profile info via rehydration script parsing
- search: search videos via internal search API
- explore: trending videos from explore page (DOM scraping)
- user: recent videos from a user page (DOM scraping)
- following: list accounts you follow
- friends: friend suggestions
- live: browse live streams with viewer counts
- notifications: activity notifications

Write commands (verified with real interactions):
- like/unlike: like or unlike a video by URL
- save/unsave: add or remove video from Favorites
- follow/unfollow: follow or unfollow a user
- comment: comment on a video

All write operations verified with live TikTok interactions.

* docs: add missing adapter documentation for doc-coverage CI
2026-03-21 22:57:56 +08:00
sline ce484c2a63 feat: add Lobste.rs, Instagram, and Facebook adapters (#199)
* feat(lobsters): add Lobste.rs adapter with hot, newest, active, tag commands

Add public API adapter for Lobste.rs (lobste.rs), a developer-focused
link aggregation community. All commands use the public JSON API and
require no authentication or browser.

Commands:
- hot: hottest stories
- newest: latest stories
- active: most active discussions
- tag: filter stories by tag (e.g. rust, security, programming)

* feat(instagram,facebook): add Instagram and Facebook adapters

Instagram (7 commands, browser mode - internal REST API):
- profile: user profile info (followers, following, posts, bio)
- search: search users
- user: recent posts from a user
- followers: list user's followers
- following: list user's following
- saved: saved posts
- explore: discover trending posts

Facebook (4 commands, browser mode - DOM scraping):
- profile: user/page profile info
- notifications: recent notifications
- feed: news feed posts
- search: search people, pages, posts

All commands require Chrome to be logged in to the respective site.
Instagram uses stable internal API endpoints with cookie auth.
Facebook uses DOM scraping via role attributes and semantic selectors.
2026-03-21 20:43:32 +08:00
VK 06c902aeed feat(medium): add medium adapter (#190) 2026-03-21 20:42:45 +08:00
AlexYue 1d39295f4b feat: plugin system (Stage 0-2)
* feat: plugin system (Stage 0-2)

- Stage 0: discoverPlugins() scans ~/.opencli/plugins/ at startup
- Stage 1: demo plugin repos (github-trending, hot-digest)
- Stage 2: opencli plugin install/uninstall/list commands
- package.json exports ./registry for TS plugin peerDep support
- 17 new/updated tests, tsc --noEmit clean

* fix: CDPBridge connect timeout unit mismatch (seconds vs ms)

opts.timeout is passed in seconds from runtime.ts but CDPBridge
was using it as milliseconds, causing instant timeout (30ms).

* feat: add registry-api public entry point for TS plugin peerDep support

- Add src/registry-api.ts: re-exports core registration API (cli, Strategy,
  getRegistry) without transitive side-effects, safe for plugin imports
- Update package.json exports: './registry' -> './dist/registry-api.js'
- Update src/registry.ts: use globalThis shared registry to ensure single
  instance across npm-linked plugin modules
- Update .gitignore for plugin-related artifacts

* fix: symlink host opencli into plugin node_modules on install

After npm install, replace the npm-installed @jackwener/opencli
with a symlink to the running host's package root. This ensures
TS plugins always resolve '@jackwener/opencli/registry' against
the host installation, avoiding version mismatches when the
published npm package lags behind.

* fix: transpile TS plugins to JS on install, deduplicate .ts/.js discovery

- installPlugin: after symlinking host opencli, transpile any .ts files
  to .js using esbuild from the host's node_modules/.bin/
- discoverPluginDir: skip .ts files when a .js sibling exists (production
  node cannot load .ts directly)
- scanPluginCommands: deduplicate basenames via Set to avoid showing
  'aggregate, aggregate' when both .ts and .js exist

* docs: add plugin system user guide

- New docs/guide/plugins.md covering:
  - Installation/uninstallation commands
  - Creating YAML plugins (zero-dep)
  - Creating TS plugins (with peerDep)
  - TS plugin install lifecycle (clone → deps → symlink → transpile)
  - Example plugins and troubleshooting
- Add Plugins to VitePress sidebar (EN + ZH)
- Link from getting-started.md Next Steps

* fix: address review issues in plugin system

- Security: replace execSync with execFileSync to prevent shell injection
- Replace deprecated npm --production with --omit=dev
- Tighten parseSource regex to [\w.-]+ to reject special chars
- Fix ZH sidebar plugin link (/guide/plugins → /zh/guide/plugins)
- Return plugin name from installPlugin() to avoid duplicated logic
- Use execFileSync for esbuild transpilation
- Fix misleading comment in linkHostOpencli

---------

Co-authored-by: jackwener <jakevingoo@gmail.com>
2026-03-21 19:41:15 +08:00
jakevin 50ec7c6868 fix(docs): remove dead link to deleted github adapter (#194) 2026-03-21 13:48:49 +08:00
jackwener 644b8bcbd4 chore: remove github adapter (covered by gh CLI hub) 2026-03-21 10:55:03 +08:00
jackwener 4e274a92b7 v1.1.1 v1.1.1 2026-03-21 10:49:39 +08:00
jakevin d1ade61e8c fix(twitter): rewrite trending from YAML to TS with DOM scraping fallback (#189)
* fix(twitter): rewrite trending from YAML to TS with DOM scraping fallback

The old REST API /i/api/2/guide.json returns 503. Replace with a TS
adapter that:
- Tries legacy guide.json API first (with proper auth headers)
- Falls back to DOM scraping via [data-testid='trend'] elements
- Filters out promoted content
- Follows the same Strategy.COOKIE pattern as timeline.ts

* fix: use 'help' instead of 'description' in Arg (matches Arg interface)

* docs(steam): add adapter documentation, update READMEs

- Create docs/adapters/browser/steam.md
- Add steam entry to README.md and README.zh-CN.md
- Fixes doc-coverage CI check (44/44)
2026-03-21 10:44:32 +08:00
jakevin 5d84c6f63e Merge pull request #187 from yanCode/codex/fix-apple-podcasts
Fix Apple Podcasts search query handling and top chart failures
2026-03-21 10:32:03 +08:00
Noah cbd50ccb91 feat(steam): add top sellers command (#178)
YAML adapter for Steam Store top selling games via public API.
Displays game name, price (in cents), discount %, and store URL.

Made-with: Cursor
2026-03-21 10:30:20 +08:00
Alex Yang 3f16d42e27 feat(twitter): add block, unblock, and hide-reply commands (#182)
Add three new Twitter/X UI-strategy commands:
- `block` / `unblock` — block or unblock a user by username
- `hide-reply` — hide a bot/spam reply on your own tweet thread
2026-03-21 10:27:22 +08:00
Sheng-Yan, Zhang c8e8c773c0 Fix apple-podcasts search and top handling 2026-03-21 09:24:41 +08:00
jakevin 5de920a994 docs: fix additional issues found in deep review (#181)
- Add missing codex/dump to README command tables
- Fix reddit subreddit --name → positional
- Update architecture.md for PR #152 engine.ts split:
  engine.ts → discovery.ts + execution.ts + commanderAdapter.ts
- Add intercept and ui strategies to auth table
2026-03-21 03:10:05 +08:00
Yunxiao_Li 476fe115de docs(chatgpt): sync read docs with AX behavior (#180) 2026-03-21 03:00:34 +08:00
jakevin 8d45019119 docs: sync documentation with PR #150 arg renames and positional changes (#179) 2026-03-21 02:59:22 +08:00
jackwener 36cf3067f7 feat: register gws CLI + use Commander passThroughOptions for external CLI passthrough (closes #147) 2026-03-21 02:29:36 +08:00
jakevin 516f1be3e6 refactor: deep CLI layer architecture improvements (#164)
CLI Layer:
1. execution.ts: auto-manages browser sessions, simplified signature
2. runtime.ts: add getBrowserFactory()
3. serialization.ts: new module for serialization helpers
4. cli.ts: format all built-in commands, extract inferHost()
5. commanderAdapter.ts: pure thin adapter

Src-wide cleanup:
6. download/index.ts: shared VIDEO_PLATFORM_DOMAINS, reuse isBinaryInstalled
7. Move site helpers: coupang/bilibili/chaoxing.ts -> clis/*/utils.ts
8. explore.ts: decompose into analyzeEndpoints, inferCapabilities, writeArtifacts

244 tests pass. 240 commands registered.
2026-03-21 02:24:12 +08:00
jakevin d556eeb512 refactor: deep CLI layer architecture improvements (#152)
1. execution.ts: executeCommand auto-manages browser sessions
   - Signature simplified: (cmd, kwargs, debug) — callers dont handle browser
   - Internal runCommand() does lazy-loading, func/pipeline dispatch
   - shouldUseBrowserSession + domain pre-nav moved here from adapter

2. runtime.ts: add getBrowserFactory()
   - Eliminates 4x duplicate CDPBridge/BrowserBridge selection

3. serialization.ts: new module (79 LOC)
   - serializeArg, serializeCommand, formatArgSummary, formatRegistryHelpText
   - registry.ts re-exports for backward compat (160 -> 96 LOC)

4. cli.ts: format all built-in commands
   - Un-compressed explore/generate/cascade from 300-char single lines
   - Extracted inferHost() helper
   - Uses getBrowserFactory() instead of inline CDPBridge selection
   - Clear section comments

5. commanderAdapter.ts: pure thin adapter (113 LOC)
   - Only does: arg collection → executeCommand → renderOutput
   - Zero browser/session/strategy logic

All 244 tests pass. No behavioral changes.
2026-03-21 02:09:46 +08:00
jakevin d7c895592f refactor!: standardize all CLI arg names to kebab-case (#150)
* refactor!: standardize all CLI arg names to kebab-case

BREAKING CHANGE: All CLI argument names have been renamed for consistency.

Renames:
- keyword -> query (11 search commands)
- bookId -> book-id (weread)
- productId -> product-id (coupang)
- post_id -> post-id (reddit)
- job_id -> job-id (boss)
- tweet_id -> tweet-id (twitter)
- note_id -> note-id (xiaohongshu)
- security_id -> security-id (boss)
- model_name -> model-name (chatwise/codex/cursor)
- max_length -> max-length (reddit)
- experience_level -> experience-level (linkedin)
- job_type -> job-type (linkedin)
- date_posted -> date-posted (linkedin)

36 renames across 32 files. All 240 commands now use kebab-case.

* refactor!: standardize positional vs --named arg style

BREAKING CHANGE: Required "subject" args are now positional.

Rules applied:
- query, id, text, url, username → positional (when required)
- output → always --named

Also fixes engine.ts YAML arg parser to support positional property.

50 changes across 49 files. All 240 commands verified consistent.
2026-03-21 01:53:11 +08:00
jakevin eeace115cb fix: harden external CLI hub — command injection, denylist, sync API, build-copy (#149) 2026-03-21 01:26:02 +08:00
jakevin 35676a101f refactor: extract serialization helpers to registry.ts and stabilize arg schema (#148)
- Add serializeArg() with stable schema (all fields always present)
- Add serializeCommand() for structured output (json/yaml)
- Add formatArgSummary() for human-readable arg display (<required> [--optional])
- Add formatRegistryHelpText() for --help appendix
- Refactor cli.ts to use these shared helpers (~30 lines removed)
- Non-structured formats now show arg signatures instead of comma-joined names
2026-03-21 01:21:18 +08:00
AstroHan cd0c6f874e feat: enhance --help with registry metadata and enrich list --json with full arg schema (#142)
* feat: add `opencli describe` command for unified CLI capability discovery

Add a new `describe` command that helps AI agents discover and understand
both built-in site commands and external CLI tools through a single entry point.

- Built-in commands: reads structured data from CliCommand registry
  (args with type/choices/default, columns, strategy, domain)
- External CLIs: collects help text via `binary --help`, extracts
  subcommand names + summaries, passes through raw help text
- Supports `--format json` for programmatic consumption by AI agents
- Graceful degradation: parse failures return raw help text, uninstalled
  CLIs show install instructions without triggering auto-install

Closes #141

* fix: address code review findings for describe command

- Strip trailing colons from Cobra-style subcommand names (browse: → browse)
- Use CliError instead of bare Error for consistent error handling with hints
- Remove decorative section separators to match project comment style
- Validate --format flag (text/json only) with clear error message
- Truncate raw help output to 50 lines to prevent excessive output
- Add deduplication test for multi-section command groups

* refactor: replace describe command with enhanced --help and list --json

Per maintainer feedback, remove the standalone `describe` command and instead:

1. Enhance --help for all built-in commands:
   - Show argument choices (from registry, not shown by Commander)
   - Show execution metadata: Strategy / Browser / Domain
   - Show output columns

2. Enhance `list -f json/yaml` with full argument schema:
   - args field now includes type, required, positional, choices, default, help
   - Added columns and domain fields for structured formats
   - Table/csv/md formats unchanged (args remain comma-joined names)

This follows the principle that --help is the standard CLI discovery
mechanism and AI models already know to use it.

* fix: stabilize JSON schema and fix positional choices rendering

- Always output columns/domain in json/yaml ([] and null when empty)
- Use <name> instead of --name for positional args with choices
- Remove extra blank line when no choices args present
2026-03-21 01:12:05 +08:00
ajia1206 0b71c6c4da fix: correct xiaohongshu creator metric parsing (#146) 2026-03-21 01:02:51 +08:00
Kasumi 7700704923 feat: add Bloomberg adapter (#145)
* feat: add Bloomberg adapter with RSS feeds and article extraction

* refactor: improve Bloomberg adapter review fixes

- news.ts: reorder flow (goto before loadStory), increase wait times for slow hydration, add clarity comments
- utils.ts: clarify validateBloombergLink regex (use non-capturing group)
- build-manifest.ts: log warning on scanTs parse failure (match scanYaml pattern)
- public-commands.test.ts: use it.each for section RSS tests (better isolation & reporting)

---------

Co-authored-by: ByteYue <yj976240184@gmail.com>
2026-03-21 00:35:30 +08:00
jackwener 4d3b972d67 feat: auto-discover and dynamically register any local CLI on the fly 2026-03-20 23:00:27 +08:00
AlexYue 15d3583c60 docs: add missing adapter docs, fix sidebar 404s, add doc-check CI (#140)
* docs: add missing adapter docs, fix sidebar 404s, add doc-check CI

- Add doc pages for 11 undocumented adapters: arxiv, barchart,
  chaoxing, grok, hf, jike, jimeng, linux-do, sinafinance,
  stackoverflow, weread, wikipedia
- Update adapters/index.md with all new adapter entries
- Update VitePress sidebar config with 12 new entries
- Remove broken zh/ sidebar refs (troubleshooting, testing)
- Add doc-check CI workflow (adapter coverage + build + link check)
- Add scripts/check-doc-coverage.sh for adapter doc enforcement
- Enhance PR template with adapter doc checklist

* fix(ci): use --root-dir instead of --base for lychee link checker

lychee v0.23 requires --base to be a URL or absolute path.
Use --root-dir for resolving root-relative links in local files.

* fix(ci): remove lychee link-check job, rely on VitePress build

VitePress links use extension-less paths (e.g. /adapters/browser/twitter)
which lychee cannot resolve. The docs-build job already catches all
broken internal links via VitePress dead link detection during build.
2026-03-20 22:08:38 +08:00
AlexYue 53a95ed0ce Open ci: migrate docs deployment to cross-repo build via opencli-website (#138) 2026-03-20 20:55:08 +08:00
jackwener 0a2591842c docs: emphasize AI agent integration via AGENT.md 2026-03-20 20:50:34 +08:00
jakevin d9a71da596 chore(main): release 1.1.0 (#134) 2026-03-20 20:40:42 +08:00
jackwener 9a79501bfd 1.1.0 v1.1.0 2026-03-20 20:37:30 +08:00
jackwener 46d0f00aa6 chore: bump SKILL.md version to 1.1.0 2026-03-20 20:37:29 +08:00
jackwener b3e32d8a05 feat: add external CLI hub for discovery, auto-installation, and execution of external tools. 2026-03-20 20:30:40 +08:00
jackwener 36bc57a962 fix(serve): update model mappings to match actual Antigravity UI
- Default to 'claude sonnet 4.6'
- Map 'sonnet' -> 'claude sonnet 4.6'
- Map 'opus' -> 'claude opus 4.6'
- Map 'gemini.*pro' -> 'gemini 3.1 pro (high)'
- Map 'gemini.*flash' -> 'gemini 3 flash'
- Map 'gpt' -> 'gpt-oss 120b'
2026-03-20 18:55:45 +08:00
jackwener 0e8c96b6d9 feat(serve): implement auto new conv, model mapping, and precise completion detection
- Auto-click New Conversation if session has only 1 message
- Map Anthropic models (claude-3-7-sonnet) to Antigravity UI models
- Refactor waitForReply to check for Cancel/Stop button presence to
  detect generation completion reliably, with text stability fallback
2026-03-20 18:52:00 +08:00
jackwener c63af6d418 feat(serve): use CDP mouse click + Input.insertText for reliable message injection
- Replace document.execCommand (deprecated) with CDP Input.insertText
- Use Input.dispatchMouseEvent to physically click + focus the Lexical editor
  before text injection (fixes focus issues with JS-only .focus())
- Improve getLastAssistantReply: strip echoed user message, thinking blocks,
  Copy button text, and de-duplicate repeated content artifacts
2026-03-20 18:24:49 +08:00
jackwener 35a0fed8a0 feat: add antigravity serve command — Anthropic API proxy
- New command: opencli antigravity serve --port 8082
- Starts HTTP server compatible with Anthropic /v1/messages API
- Connects to Antigravity via CDP (OPENCLI_CDP_ENDPOINT)
- Uses Input.dispatchKeyEvent for reliable Enter key submission
- Polls for reply with text-change detection + 3s stability check
- Precise DOM walker for extracting last assistant reply
- Lazy CDP connection (connects on first request)
- Auto-reconnect on CDP connection loss
- CORS headers for Claude Code compatibility

Usage:
  OPENCLI_CDP_ENDPOINT=http://127.0.0.1:9224 opencli antigravity serve
  ANTHROPIC_BASE_URL=http://localhost:8082 claude
2026-03-20 18:16:41 +08:00
jackwener 593436e4cb fix(xiaohongshu): use fixed UTC+8 offset in trend timestamp formatting (CI timezone fix) 2026-03-20 17:57:31 +08:00
jackwener 02793e990e feat: add sinafinance 7x24 news adapter (#131)
Based on PR #131 by larria, with fixes applied:
- Renamed command 724 → news for clarity
- Fixed indentation to 2-space project standard
- Added SinaNewsItem type (removed item: any)
- Added res.ok check + CliError for HTTP failures
- Added stripHtml() for rich_text content
- Updated README, README.zh-CN, SKILL.md

Co-authored-by: larria <1115524+larria@users.noreply.github.com>
2026-03-20 17:22:42 +08:00
jackwener 03f067d907 fix: use UTC+8 for XHS timestamp formatting (CI timezone fix)
formatPostTime() used local timezone methods, causing test failure
on UTC CI servers. XHS API timestamps are Beijing time (UTC+8),
so use explicit UTC offset with getUTC*() methods.
2026-03-20 17:13:00 +08:00
云比云 7e973ca592 feat(boss): add 8 new recruitment management commands (#133)
New commands:
- joblist: view my published jobs
- recommend: view recommended candidates (new greetings list)
- greet: send greeting to initiate chat with candidate
- mark: add/remove labels on candidates
- invite: send interview invitation
- stats: job statistics (chats count)
- batchgreet: batch greet recommended candidates
- exchange: request phone/wechat exchange

All commands tested and build passing (222 entries).
2026-03-20 17:10:48 +08:00
jackwener 4600b9d46d fix: type safety for wikiFetch and arxiv abstract truncation
- wikiFetch return Promise<unknown> instead of Promise<any>
- Add WikiSearchResult type, remove r: any
- Type wikiFetch responses with inline type assertions
- Only append ... to abstract when actually truncated
2026-03-20 17:08:30 +08:00
BruceLoveDecimal 3cda14a2ab feat: add arxiv and wikipedia adapters (#132)
Add arXiv (search, paper) and Wikipedia (search, summary) public API adapters.

- arxiv/search: search papers by keyword
- arxiv/paper: get paper details by ID  
- wikipedia/search: search articles with lang support
- wikipedia/summary: get article summary

Type safety fixes applied: wikiFetch returns unknown, typed search results.

Co-authored-by: BruceLoveDecimal <39156883+BruceLoveDecimal@users.noreply.github.com>
2026-03-20 17:08:17 +08:00
jackwener 4f74b45963 refactor: remove raw CDP code, use IPage throughout
- Remove fetchCreatorNotesByCdp() and captureNoteDetailApiPayload() raw
  WebSocket code (~240 lines) — adapters should use IPage, not raw CDP
- Replace direct CDP WebSocket with IPage.evaluate() in-page fetch
- Fix page: any → IPage in all function signatures
- Simplify to two-tier fallback: API+interceptor → DOM parse
- Rebase onto latest main (resolves cdp.ts/daemon.ts conflicts)
2026-03-20 16:34:08 +08:00
ajia1206 8f1725982e feat: xiaohongshu creator flows migration (#124)
Migrated xiaohongshu creator flows to v1.0.2+.
- creator-notes with API + DOM fallback
- creator-note-detail with audience/trend data
- creator-notes-summary batch overview
- Tests: 3 files, 9 tests

Co-authored-by: ajia <491387123@qq.com>
2026-03-20 16:33:48 +08:00
AlexYue 2876750891 fix(docs): use base '/' for custom domain and add CNAME file (#129)
- Change VitePress base from '/opencli/' to '/' for custom domain opencli.info
- Add docs/public/CNAME so GitHub Pages preserves custom domain on re-deploy
2026-03-20 16:31:28 +08:00
jakevin 4ab4f88bcd chore(main): release 1.0.6 (#128) v1.0.6 2026-03-20 16:25:30 +08:00
AlexYue 9eb7a1eaa1 docs: add VitePress documentation site with GitHub Pages deployment (#127)
* docs: deduplicate documentation — single source of truth in docs/

- Remove root CDP.md, CDP.zh-CN.md, CLI-ELECTRON.md (now in docs/advanced/)
- Slim adapter READMEs to one-liner + link to docs/ (11 files)
- Update README.md adapter table links to point to docs/

* docs: set VitePress base path for GitHub Pages deployment
2026-03-20 16:08:34 +08:00
Chencheng Li 4cabca12df fix: use %20 instead of + for spaces in Bilibili WBI signed requests (#126)
URLSearchParams.toString() encodes spaces as +, but Bilibili's WBI
signature verification expects %20. This mismatch causes search
queries with spaces (e.g. "亚马逊 滞销产品") to fail with
TypeError: Failed to fetch due to CORS-blocked error responses.

Fixes #125

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 16:07:46 +08:00