Commit Graph

1587 Commits

Author SHA1 Message Date
万物生腾·Omnisurge 1c66cc9eab fix(errors): duck-typing for cross-package CliError in toEnvelope (#2388)
* fix(errors): duck-typing for cross-package CliError in toEnvelope

Plugins resolve their own copy of @jackwener/opencli (own node_modules), so
 fails across package copies and every plugin error
degrades to code: UNKNOWN with the hint lost. Switch to shape-based detection
(code + message strings, optional hint) — real CliError instances behave
identically, plain Errors still map to UNKNOWN.

Also serializes error-like plain objects carrying code/message. Adds tests
for the cross-package shape, plain-object passthrough, and UNKNOWN fallback.

* fix(errors): require exitCode when duck-typing CliError

The shape check accepted any object with string code+message, which also
matches Node system errors (ENOENT, ECONNREFUSED, EACCES) and library
errors carrying a string code. Those would surface their errno as the
envelope code, widening the machine-readable contract callers switch on:

  before this commit: ENOENT -> code "ENOENT"
  intended/base:      ENOENT -> code "UNKNOWN"

CliError's constructor always assigns exitCode (defaulting to
GENERIC_ERROR) while Node system errors never do, so requiring a numeric
exitCode separates genuine cross-package CliError copies from foreign
errors without adding any new concept.

Tests: make the cross-package mock faithful by giving it exitCode, pin
the bare {code,message} object as UNKNOWN, and add an ENOENT regression.

---------

Co-authored-by: jackwener <jakevingoo@gmail.com>
2026-08-29 20:59:06 +08:00
axxop 4e8109b6c8 fix: honor manual CDP endpoint for web adapters (#2148) 2026-08-29 20:56:03 +08:00
陈家名 25dece3f18 fix(pipeline): reject invalid concurrency limits (#2407) 2026-08-29 20:50:15 +08:00
jakevin 49907e53dc fix(dribbble): distinguish empty states from selector drift (#2423)
* fix(dribbble): distinguish empty states from drift

* fix(dribbble): handle promoted and nested list items

---------

Co-authored-by: OpenCLI-sol <opencli-sol@users.noreply.github.com>
2026-08-28 20:37:04 +08:00
Jamie 5767c07bd8 feat(dribbble): add browser adapter commands (#2403)
* feat(dribbble): add browser adapter commands

* fix(dribbble): improve adapter commands

* fix(dribbble): verify and complete adapter contracts

---------

Co-authored-by: OpenCLI-sol <opencli-sol@users.noreply.github.com>
2026-08-28 19:07:49 +08:00
Jiacheng 439945fd3d chore(pack): prune @mixmark-io/domino's vendored test suite on install (#2411)
turndown pulls in @mixmark-io/domino, which publishes its full test suite
to npm: 959 files / 7 MB, ~94% of the package's file count. Upstream has
been unmaintained since 2024 (mixmark-io/domino#2), so remove the test
directory in our postinstall instead. Runs before the CI early-return so
packaged app bundles (OpenCLIApp stages node_modules into Resources/)
shrink as well. Best-effort: resolution failure or a missing dir never
fails the install.

Co-authored-by: exe.dev user <exedev@koala-fife.exe.xyz>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 17:36:49 +08:00
Jiacheng c9fb444c0c chore(pack): exclude test files and fixtures from npm package (#2410)
The published tarball ships 601 compiled *.test.js files, ~100 *.test.d.ts,
stray *.test.ts sources, and clis/**/__fixtures__/ HTML snapshots — none of
which are used at runtime. Excluding them shrinks the package from 2340 to
1638 files and from 14.0 MB to 9.2 MB unpacked (tarball 3.1 MB -> 2.2 MB),
which noticeably speeds up npm install.

Verified with npm pack --dry-run against the extracted 1.8.7 tarball
contents: no .test.* or __fixtures__ entries remain.

Co-authored-by: exe.dev user <exedev@koala-fife.exe.xyz>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 17:36:00 +08:00
jakevin 90d507091c chore: refresh convention audit baselines (#2377) 2026-08-26 17:23:21 +08:00
jakevin 50902ffe6b fix(browser): preserve structured network captures (#2406)
* fix(browser): preserve structured network captures

* test(browser): cover direct CDP request capture

* fix(browser): redact credential-shaped request values

* fix(browser): redact bare CSRF request fields

---------

Co-authored-by: OpenCLI-sol <opencli-sol@users.noreply.github.com>
2026-08-26 17:14:39 +08:00
jakevin c2964f9572 fix(output): keep markdown rows intact for multi-line cells (#2375)
renderMarkdown escaped pipes but not newlines, so a cell containing a
line break terminated the table row and broke the markdown structure.
Render embedded newlines as <br>, matching how renderCsv already
handles multi-line values.
2026-08-26 17:09:36 +08:00
jakevin 6b3dffd398 feat(gmail): add browser-backed Gmail adapter (#2396)
* feat(gmail): add browser-backed adapter

* docs(gmail): document adapter commands

* refactor(gmail): remove unsupported write surface

* chore(gmail): split author workflow into dedicated PR

---------

Co-authored-by: OpenCLI-sol <opencli-sol@users.noreply.github.com>
2026-08-25 21:37:08 +08:00
jakevin b2fc86eb0f docs(skill): add evidence-first deep recon workflow (#2398)
Co-authored-by: OpenCLI-sol <opencli-sol@users.noreply.github.com>
2026-08-25 21:34:25 +08:00
jakevin 0a4a863b36 fix(linkedin): make sent invitations and thread snapshots accurate (#2395)
* fix(linkedin): use accurate invitation and thread sources

* fix(linkedin): preserve thread discovery budget

---------

Co-authored-by: OpenCLI-sol <opencli-sol@users.noreply.github.com>
2026-08-25 16:56:29 +08:00
jakevin 35002644d3 feat(jike): use structured APIs for search and notifications (#2394)
Co-authored-by: OpenCLI-sol <opencli-sol@users.noreply.github.com>
2026-08-25 16:05:42 +08:00
jakevin 64e6f0e39b fix(ctrip): read structured flight results (#2393)
Co-authored-by: OpenCLI-sol <opencli-sol@users.noreply.github.com>
2026-08-25 15:19:58 +08:00
Ao Liu cee4713918 fix(nowcoder): validate mixed post entities (#2218)
Co-authored-by: jackwener <jakevingoo@gmail.com>
2026-08-25 00:56:06 +08:00
Yisi Liu c6f8c26b8b fix(trip): repair flight extraction — dropped font-black class emptied every row (#2385)
* fix(trip): read airport codes from leaf nodes, not the dropped font-black class

`buildFlightExtractJs` sourced the departure/arrival IATA codes from
`[class*="font-black"]`. Trip.com no longer emits that class, so `codes` was
always empty, the `codes.length < 2` guard dropped every card, and `flight` /
`flight-round` failed with EMPTY_RESULT on every route — including the
`LON -> NYC` example in the adapter docs.

The codes are still in the DOM as plain leaf nodes, and the extractor already
walks the leaves to collect times. Filter the codes out of that same scan and
drop the `font-black` dependency.

The unit fixture pinned the stale markup (`<div class="font-black_x">LGW</div>`),
which is why 114 adapter tests stayed green while the adapter returned nothing
against the live site. Replace it with markup captured from Trip.com in 2026-08
so the fixture can actually falsify the extractor.

Verified against the live site: 0/8 result cards parsed before, 8/8 after;
`opencli trip flight` now returns rows for PVG->LHR, SHA->LON and LON->NYC.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(trip): mark later-day arrivals with a +N suffix

Overnight legs lost a day. The extractor built `arrivalTime` from the `HH:MM`
and `AM`/`PM` leaf nodes alone, so a China Southern SHA -> LGW leg departing
19:50 on 2026-09-07 and landing 06:30 on 2026-09-08 was reported as a plain
`6:30 AM`, indistinguishable from a same-day arrival.

Each card already carries `data-testid="flight-time-<ISO>"` on both legs. Diff
the date halves of those two anchors and append `+N` to the arrival time, which
is how Trip.com itself renders it (the card shows a literal `+1` beside the
arrival airport).

Same-day arrivals are unchanged, so the `columns` contract is untouched and only
the previously-wrong rows move.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(trip): bind flight routes to endpoint anchors

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: jackwener <jakevingoo@gmail.com>
2026-08-25 00:46:25 +08:00
billow 5d102265e6 feat(pixiv): add novel commands (#2112)
* feat(pixiv): add novel commands

* feat(pixiv): add account bookmarks and novel downloads

* fix(pixiv): harden novel payload validation

* fix(pixiv): tighten auth proof and numeric args

* fix(pixiv): harden archive boundaries

* fix(pixiv): validate novel archive metadata

---------

Co-authored-by: jackwener <jakevingoo@gmail.com>
2026-08-24 23:52:03 +08:00
jakevin 3e65c17621 chore: npm audit fix for dev-dependency advisories (#2378)
Clears the esbuild, nanoid, and postcss dev-chain advisories
(6 findings → 3). package-lock.json only; package.json ranges
untouched; production dependency audit remains at zero. The remaining
vite/launch-editor + vitepress findings have no in-range fix upstream
yet (dev-only, Windows-only vector) and are documented in the PR.
2026-08-24 23:34:32 +08:00
jakevin dc0a1ef1f5 fix(midjourney): poll job state before timeout (#2383) 2026-08-24 22:32:04 +08:00
jakevin d667222c90 fix(youtube): paginate search results (#2387)
Co-authored-by: OpenCLI-sol <opencli-sol@users.noreply.github.com>
2026-08-24 21:57:33 +08:00
jakevin 05b2830062 feat(youtube): paginate authenticated watch history (#2386)
Co-authored-by: OpenCLI-sol <opencli-sol@users.noreply.github.com>
2026-08-24 20:30:27 +08:00
Jared Su 14b9b9c595 feat(execution): support site session env default (#2221)
Co-authored-by: jackwener <jakevingoo@gmail.com>
2026-08-24 20:17:00 +08:00
jakevin 9adf995c34 fix(jike): reject anonymous read sessions (#2384)
* fix(jike): reject anonymous read sessions

* fix(jike): preserve login polling retries

---------

Co-authored-by: OpenCLI-sol <opencli-sol@users.noreply.github.com>
2026-08-24 19:55:10 +08:00
Mingming Lou b4910ed6a8 feat(xiaoyuzhou): add playback history (#2260)
Co-authored-by: jackwener <jakevingoo@gmail.com>
2026-08-24 19:29:55 +08:00
jakevin c559c996d6 fix(twitter): read current following follower counts (#2382)
Co-authored-by: OpenCLI-sol <opencli-sol@users.noreply.github.com>
2026-08-24 19:13:33 +08:00
jakevin 527b77ad57 fix: declare the Node >=20.18.1 floor that undici 7.x already requires (#2381)
undici 7.29.0 (pinned since the CVE-2026-13697 fix) requires Node
>=20.18.1, but engines still promised >=20.0.0. First-principles call:
Node 20 reached EOL in April 2026, so 20.0-20.17 users are on an
unpatched runtime either way — staying on the maintained undici 7.x
line and updating the declaration honestly beats downgrading to the
aging 6.x line for a contract that protects nobody. Updates engines,
the lock root mirror, and both README Node claims.
2026-08-24 19:05:47 +08:00
lingjiuu 4a1cc3a457 fix(notebooklm): migrate redirected domain session (#2228) 2026-08-24 18:49:37 +08:00
jakevin 56360604f1 feat(twitter): intercept complete followers timeline (#2380)
Co-authored-by: OpenCLI-sol <opencli-sol@users.noreply.github.com>
2026-08-24 18:32:15 +08:00
qiuyang bc7d20e6d0 feat(xiaohongshu): add deterministic search filters (#2276)
Co-authored-by: jackwener <jakevingoo@gmail.com>
2026-08-24 18:22:21 +08:00
ele-yufo c16a2539fe feat(bilibili): add creator analytics adapter (#2268)
* feat(bilibili): add creator analytics adapter

* feat(bilibili): narrow creator stats contract

---------

Co-authored-by: yufo <yufo@MacBook-Pro.local>
Co-authored-by: jackwener <jakevingoo@gmail.com>
2026-08-24 17:39:26 +08:00
Octopus 5cb60a8468 feat(minimax): add guarded music generation adapter (#2290)
Co-authored-by: jackwener <jakevingoo@gmail.com>
2026-08-24 17:24:23 +08:00
Ninglin Du 48c151c6e3 feat(jira): add custom field support (#2289)
* feat(twitter): add custom field support

* change to comma fields

* remove ATLASSIAN_JIRA_FIELDS add --fields

* fix(jira): preserve selected field identity

---------

Co-authored-by: jackwener <jakevingoo@gmail.com>
2026-08-24 16:27:10 +08:00
sleepy dog 3ec6eb086a fix(xiaohongshu): recover collapsed search targets safely (#2355)
Co-authored-by: jackwener <jakevingoo@gmail.com>
2026-08-24 16:07:25 +08:00
kino 14d47c08bc feat(zhihu): export answers with local images (#2304)
* feat(zhihu): export answers with local images

* test(zhihu): cover answer image normalization

* fix(zhihu): harden answer export boundaries

* fix(zhihu): require question URL provenance

---------

Co-authored-by: jackwener <jakevingoo@gmail.com>
2026-08-24 15:38:10 +08:00
kino 85e95870bb feat(zhihu): preserve comment reply threads (#2306)
Co-authored-by: jackwener <jakevingoo@gmail.com>
2026-08-24 14:51:40 +08:00
jakevin 2e373b612e chore(xiaohongshu): share evaluate unwrap helper (#2363)
Collapse seven local unwrapEvaluateResult copies (ask, feed, search,
creator-notes, delete-note, follow, unfollow) into a single
clis/xiaohongshu/shared.js export, and point rednote/search at it.

The three variants differed only in an Array.isArray guard and
condition order; arrays cannot carry the session/data envelope keys
across the CDP JSON boundary, so behavior is identical for every
reachable payload. The canonical copy keeps the guard.

Contract tests move to shared.test.js (strengthened with identity
assertions); the direct duplicates in ask.test.js / search.test.js are
deleted as subsumed. creator-notes __test__ drops the imported key.
2026-08-24 14:36:30 +08:00
jakevin c003a1b1c2 refactor(sinafinance): use rolling news API (#2365)
Co-authored-by: OpenCLI-sol <opencli-sol@users.noreply.github.com>
2026-08-24 09:02:41 +08:00
sleepy dog a0fbe90a7f fix(xiaohongshu): harvest search rows during scroll instead of first/last screen union (#2349)
* fix(xiaohongshu): harvest search rows during scroll instead of first/last screen union

The search results page is a virtualized masonry list: cards scrolled past
are evicted from the DOM. The previous flow extracted once, scrolled to the
bottom, then extracted again, so the result set was only the union of the
first and last screens -- capped near 20 rows regardless of --limit.

Harvest inside the scroll loop instead. A single page.evaluate now drives
the scroll and accumulates rows into a page-land Map keyed by note id, so
nothing is lost when a card is recycled. On a query that previously returned
34 rows, `--limit 100` now saturates at 100 across repeated runs.

Three related fixes ride along:

- Rows are merged rather than deduplicated on first sight. Masonry cards
  render in stages -- the link appears before the title -- so a row first
  seen with an empty title used to be cached empty and then dropped by the
  title filter. Empty fields are now backfilled on a later encounter,
  non-empty fields are never overwritten, and an unsigned /explore/ URL can
  be upgraded to an xsec_token-signed one but never downgraded. The likes
  emptiness check treats '0' as a placeholder because the extractor writes
  '0' for an unrendered count.

  For the same reason the target check counts only rows that already have a
  title. Counting raw discoveries let the loop stop the moment 100 cards
  were known, before the last screen had rendered its titles, and the filter
  then silently cut the output back to 84.

- "No new rows this round" is no longer, on its own, a reason to stop.
  It was observed firing at scrollTop=4500 of scrollHeight=6960 -- squarely
  mid-page, where Xiaohongshu had merely paused lazy-loading. Stopping now
  requires the plateau to coincide with either a real bottom or wedged
  scrolling, alongside the target/round/wall-clock bounds.

- Risk-control interstitials are detected and raise SECURITY_BLOCK instead
  of surfacing as a silently short result set indistinguishable from the
  truncation bug above.

Scrolling advances by a viewport-sized step rather than jumping to
document.body.scrollHeight, which would skip whole screens of cards. Round
and wall-clock budgets are derived from the already-validated --limit, so
no new CLI arguments and no cli-manifest.json change. Small --limit values
now finish sooner than before, since reaching the target ends the loop.

buildScrollUntilJs is untouched and buildSearchExtractJs keeps its signature
and semantics, so clis/rednote/search.js -- which imports both -- is
unaffected.

* fix(xiaohongshu): harden virtual search harvesting

* fix(xiaohongshu): validate harvested search rows

---------

Co-authored-by: jackwener <jakevingoo@gmail.com>
2026-08-24 04:21:02 +08:00
Henry 144629740d feat(bilibili): add --top to fetch pinned comments (#2106)
* feat(bilibili): add --top to fetch pinned comments

The comments command already fetches /x/v2/reply/main, whose response
includes top_replies (置顶评论) alongside regular replies but discarded
them. Add a --top flag that returns only the pinned comments.

- --top reads data.top_replies (reusing formatReplyRow)
- --top is mutually exclusive with --parent (楼中楼 threads have no
  top_replies) and raises ArgumentError before any request
- generalize requireReplies to accept a key; absent top_replies is
  treated as empty, and an empty pinned list raises EmptyResultError

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(bilibili): harden pinned comment contract

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: jackwener <jakevingoo@gmail.com>
2026-08-24 04:01:50 +08:00
jakevin 5bb8f5ac9d fix(weixin): recover draft cover uploads (#2362) 2026-08-24 03:53:24 +08:00
OctoBored d2aec509e8 docs: point star history chart to a working endpoint (#2301)
The star history chart in the README was broken because its data source is no longer reliable under GitHub's current stargazer API restrictions. Update the chart in both README.md and README.zh-CN.md to use a working endpoint so the chart renders correctly again.

Co-authored-by: OctoBored <212877535+OctoBored@users.noreply.github.com>
2026-08-24 03:21:58 +08:00
jakevin d9b018fa0b fix: sync package-lock with undici 7.29.0 bump (#2361)
#2326 pinned undici 7.29.0 in package.json without regenerating the
lockfile, so npm ci fails with EUSAGE on main and every PR merge ref.
Regenerated with npm install --package-lock-only.
2026-08-24 03:04:33 +08:00
Anupam Mediratta 6d2b11e6ea fix: CVE-2026-13697 security vulnerability (#2326)
Automated dependency upgrade by OrbisAI Security
2026-08-24 02:26:21 +08:00
jakevin 87b60a3659 chore(release): bump version to 1.8.7 (#2359) v1.8.7 2026-08-23 23:58:41 +08:00
jakevin 432cf23101 chore(linkedin): share people search auth helpers (#2358) 2026-08-23 23:48:37 +08:00
jakevin dfc13ea69b chore(linkedin): share messaging thread URL helpers 2026-08-23 23:28:45 +08:00
jakevin f2de8ab808 chore(linkedin): reuse shared unwrap in connect flows 2026-08-23 23:02:43 +08:00
jakevin b158a4a831 chore(linkedin): reuse shared unwrap in salesnav 2026-08-23 22:46:36 +08:00
jakevin 77a4e19f0b chore(linkedin): reuse shared evaluate unwrap
Reuses the existing LinkedIn shared evaluate envelope unwrap helper across general messaging commands while preserving subsystem-local copies for later batches.
2026-08-23 22:28:52 +08:00