Compare commits

...

10 Commits

Author SHA1 Message Date
jackwener 59d9339158 fix(doctor): keep no-live status truthful 2026-04-08 14:37:46 +08:00
jackwener 0f19f0978f refactor(doctor/status): unify daemon health checks, remove fragile code paths
- Add getDaemonHealth() as single entry point for daemon status checks
  returning a discriminated union: 'stopped' | 'no-extension' | 'ready'
- Delete browser/discover.ts (was a thin wrapper adding no value)
- Remove isExtensionConnected() (replaced by getDaemonHealth)
- Simplify doctor.ts: remove self-managed auto-start and double status
  check — bridge.connect() already handles auto-start, so doctor now
  does 1 live test + 1 health check instead of 2 checks + 1 bridge + 1 live + 1 check
- Update bridge.ts to throw typed BrowserConnectError (via formatBrowserConnectError)
  instead of plain Error, enabling precise catch without string matching
- Extract _pollUntilReady() in bridge.ts to deduplicate polling loops
- Simplify commanderAdapter.ts renderError(): use err.kind directly
  instead of making a separate real-time status check that could race/fail
- Update execution.ts fail-fast to use getDaemonHealth() with typed error kind
- Update all affected tests (doctor, daemon-client, browser bridge)
2026-04-08 14:22:31 +08:00
jackwener ab2dde5f75 test(xueqiu): mock logger via src path 2026-04-05 03:29:34 +08:00
jackwener bfffdc77d0 fix: update LessWrong and hupu adapter imports to use src/ paths
Fix imports in newly merged LessWrong and hupu/mentions adapter
files that were still referencing the deleted root shim files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-05 03:27:04 +08:00
jackwener d9323c088d Merge remote-tracking branch 'origin/main' into refactor/simplify-core-modules 2026-04-05 03:26:42 +08:00
jackwener 164771a019 fix: update xiaohongshu tests for /search_result/ URL change
Tests now expect /search_result/<id> for bare note IDs (matching
the note-helpers.ts change from PR #774) and updated empty-shell
hint assertion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-05 03:24:34 +08:00
jackwener e07f25cd21 fix: update new Gemini adapter imports to use src/ paths
Fix imports in newly added deep-research adapter files that were
still referencing the deleted root shim files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-05 03:18:28 +08:00
jackwener 2a13fcb504 Merge remote-tracking branch 'origin/main' into refactor/simplify-core-modules 2026-04-05 03:15:33 +08:00
jackwener 7f8104a551 docs: update import paths in contributor docs and skill templates
Update all documentation and skill files to reference src/ directly,
matching the shim removal in the previous commit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-05 03:12:07 +08:00
jackwener 314bc6f231 refactor: simplify core modules — remove root shims, consolidate error classification, streamline cascade/interceptor, clean up synthesize
1. Remove root-level shim files (errors.ts, logger.ts, registry.ts, types.ts, utils.ts, launcher.ts) — update all ~840 adapter imports to reference src/ directly
2. Consolidate interceptor: reuse shared DISGUISE_FN in tap interceptor instead of reimplementing
3. Unify error classification: single ClassifiedError type with icon/exitCode/hint lookup table, eliminating duplicated pattern matching between resolveExitCode and renderError
4. Simplify cascade probe: replace repetitive switch cases with PROBE_OPTIONS lookup map
12. Clean up synthesize.ts: remove deprecated snake_case field aliases (recommended_args, recommended_columns, recommendedColumnsLegacy) and unnecessary constant aliases

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-05 03:06:47 +08:00
526 changed files with 1202 additions and 1152 deletions
+1 -1
View File
@@ -73,7 +73,7 @@ See [`hackernews/top.yaml`](src/clis/hackernews/top.yaml) for a real example.
Create a file like `src/clis/<site>/<command>.ts`:
```typescript
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
cli({
site: 'mysite',
+4 -4
View File
@@ -1,7 +1,7 @@
import { CommandExecutionError } from '../../errors.js';
import { cli, Strategy } from '../../registry.js';
import type { IPage } from '../../types.js';
import { isRecord } from '../../utils.js';
import { CommandExecutionError } from '../../src/errors.js';
import { cli, Strategy } from '../../src/registry.js';
import type { IPage } from '../../src/types.js';
import { isRecord } from '../../src/utils.js';
import {
assertAuthenticatedState,
buildDetailUrl,
+3 -3
View File
@@ -1,6 +1,6 @@
import { CommandExecutionError, EmptyResultError } from '../../errors.js';
import { cli, Strategy } from '../../registry.js';
import type { IPage } from '../../types.js';
import { CommandExecutionError, EmptyResultError } from '../../src/errors.js';
import { cli, Strategy } from '../../src/registry.js';
import type { IPage } from '../../src/types.js';
import {
FACTORY_BADGE_PATTERNS,
SERVICE_BADGE_PATTERNS,
+2 -2
View File
@@ -1,5 +1,5 @@
import { ArgumentError, AuthRequiredError, CommandExecutionError } from '../../errors.js';
import type { IPage } from '../../types.js';
import { ArgumentError, AuthRequiredError, CommandExecutionError } from '../../src/errors.js';
import type { IPage } from '../../src/types.js';
export const SITE = '1688';
export const HOME_URL = 'https://www.1688.com/';
+3 -3
View File
@@ -1,6 +1,6 @@
import { CommandExecutionError, EmptyResultError } from '../../errors.js';
import { cli, Strategy } from '../../registry.js';
import type { IPage } from '../../types.js';
import { CommandExecutionError, EmptyResultError } from '../../src/errors.js';
import { cli, Strategy } from '../../src/registry.js';
import type { IPage } from '../../src/types.js';
import {
FACTORY_BADGE_PATTERNS,
SERVICE_BADGE_PATTERNS,
+3 -3
View File
@@ -3,9 +3,9 @@
*
* Fetches the full content of a 36kr article given its ID or URL.
*/
import { cli, Strategy } from '../../registry.js';
import { CliError } from '../../errors.js';
import type { IPage } from '../../types.js';
import { cli, Strategy } from '../../src/registry.js';
import { CliError } from '../../src/errors.js';
import type { IPage } from '../../src/types.js';
/** Extract article ID from a full URL or a bare numeric ID string */
function parseArticleId(input: string): string {
+3 -3
View File
@@ -4,9 +4,9 @@
* Navigates to the 36kr hot-list page and scrapes rendered article links.
* Supports category types: renqi (人气), zonghe (综合), shoucang (收藏), catalog (综合热门).
*/
import { cli, Strategy } from '../../registry.js';
import { CliError } from '../../errors.js';
import type { IPage } from '../../types.js';
import { cli, Strategy } from '../../src/registry.js';
import { CliError } from '../../src/errors.js';
import type { IPage } from '../../src/types.js';
const TYPE_MAP: Record<string, string> = {
renqi: '人气榜',
+1 -1
View File
@@ -1,7 +1,7 @@
/**
* 36kr latest news — public RSS feed, no browser needed.
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
cli({
site: '36kr',
+3 -3
View File
@@ -3,9 +3,9 @@
*
* Navigates to the 36kr search results page and scrapes rendered articles.
*/
import { cli, Strategy } from '../../registry.js';
import { CliError } from '../../errors.js';
import type { IPage } from '../../types.js';
import { cli, Strategy } from '../../src/registry.js';
import { CliError } from '../../src/errors.js';
import type { IPage } from '../../src/types.js';
cli({
site: '36kr',
+3 -3
View File
@@ -5,9 +5,9 @@
*/
import * as fs from 'node:fs';
import { cli, Strategy } from '../../registry.js';
import type { IPage } from '../../types.js';
import type { CliOptions } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import type { IPage } from '../../src/types.js';
import type { CliOptions } from '../../src/registry.js';
/**
* Factory: capture DOM HTML + accessibility snapshot.
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli } from '../../registry.js';
import { cli } from '../../src/registry.js';
import { createRankingCliOptions } from './rankings.js';
cli(createRankingCliOptions({
+3 -3
View File
@@ -1,6 +1,6 @@
import { CommandExecutionError } from '../../errors.js';
import { cli, Strategy } from '../../registry.js';
import type { IPage } from '../../types.js';
import { CommandExecutionError } from '../../src/errors.js';
import { cli, Strategy } from '../../src/registry.js';
import type { IPage } from '../../src/types.js';
import {
buildDiscussionUrl,
buildProvenance,
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli } from '../../registry.js';
import { cli } from '../../src/registry.js';
import { createRankingCliOptions } from './rankings.js';
cli(createRankingCliOptions({
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli } from '../../registry.js';
import { cli } from '../../src/registry.js';
import { createRankingCliOptions } from './rankings.js';
cli(createRankingCliOptions({
+3 -3
View File
@@ -1,6 +1,6 @@
import { CommandExecutionError } from '../../errors.js';
import { cli, Strategy } from '../../registry.js';
import type { IPage } from '../../types.js';
import { CommandExecutionError } from '../../src/errors.js';
import { cli, Strategy } from '../../src/registry.js';
import type { IPage } from '../../src/types.js';
import {
buildProductUrl,
buildProvenance,
+3 -3
View File
@@ -1,6 +1,6 @@
import { CommandExecutionError } from '../../errors.js';
import { cli, Strategy } from '../../registry.js';
import type { IPage } from '../../types.js';
import { CommandExecutionError } from '../../src/errors.js';
import { cli, Strategy } from '../../src/registry.js';
import type { IPage } from '../../src/types.js';
import {
buildProductUrl,
buildProvenance,
+3 -3
View File
@@ -1,6 +1,6 @@
import { CommandExecutionError } from '../../errors.js';
import { Strategy, type CliOptions } from '../../registry.js';
import type { IPage } from '../../types.js';
import { CommandExecutionError } from '../../src/errors.js';
import { Strategy, type CliOptions } from '../../src/registry.js';
import type { IPage } from '../../src/types.js';
import {
assertUsableState,
buildProvenance,
+3 -3
View File
@@ -1,6 +1,6 @@
import { CommandExecutionError } from '../../errors.js';
import { cli, Strategy } from '../../registry.js';
import type { IPage } from '../../types.js';
import { CommandExecutionError } from '../../src/errors.js';
import { cli, Strategy } from '../../src/registry.js';
import type { IPage } from '../../src/types.js';
import {
buildProvenance,
buildSearchUrl,
+2 -2
View File
@@ -1,5 +1,5 @@
import { ArgumentError, CommandExecutionError } from '../../errors.js';
import type { IPage } from '../../types.js';
import { ArgumentError, CommandExecutionError } from '../../src/errors.js';
import type { IPage } from '../../src/types.js';
export const SITE = 'amazon';
export const DOMAIN = 'amazon.com';
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import * as fs from 'node:fs';
export const dumpCommand = cli({
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
export const extractCodeCommand = cli({
site: 'antigravity',
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
export const modelCommand = cli({
site: 'antigravity',
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
export const newCommand = cli({
site: 'antigravity',
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
export const readCommand = cli({
site: 'antigravity',
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
export const sendCommand = cli({
site: 'antigravity',
+3 -3
View File
@@ -12,9 +12,9 @@
import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';
import { CDPBridge } from '../../browser/cdp.js';
import type { IPage } from '../../types.js';
import { resolveElectronEndpoint } from '../../launcher.js';
import { EXIT_CODES, getErrorMessage } from '../../errors.js';
import type { IPage } from '../../src/types.js';
import { resolveElectronEndpoint } from '../../src/launcher.js';
import { EXIT_CODES, getErrorMessage } from '../../src/errors.js';
// ─── Types ───────────────────────────────────────────────────────────
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
export const statusCommand = cli({
site: 'antigravity',
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
export const watchCommand = cli({
site: 'antigravity',
+1 -1
View File
@@ -1,5 +1,5 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { getRegistry } from '../../registry.js';
import { getRegistry } from '../../src/registry.js';
import './search.js';
import './top.js';
+2 -2
View File
@@ -1,5 +1,5 @@
import { cli, Strategy } from '../../registry.js';
import { CliError } from '../../errors.js';
import { cli, Strategy } from '../../src/registry.js';
import { CliError } from '../../src/errors.js';
import { itunesFetch, formatDuration, formatDate } from './utils.js';
cli({
+2 -2
View File
@@ -1,5 +1,5 @@
import { cli, Strategy } from '../../registry.js';
import { CliError } from '../../errors.js';
import { cli, Strategy } from '../../src/registry.js';
import { CliError } from '../../src/errors.js';
import { itunesFetch } from './utils.js';
cli({
+2 -2
View File
@@ -1,5 +1,5 @@
import { cli, Strategy } from '../../registry.js';
import { CliError } from '../../errors.js';
import { cli, Strategy } from '../../src/registry.js';
import { CliError } from '../../src/errors.js';
// Apple Marketing Tools RSS API — public, no key required
const CHARTS_URL = 'https://rss.marketingtools.apple.com/api/v2';
+1 -1
View File
@@ -5,7 +5,7 @@
* https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/iTuneSearchAPI/
*/
import { CliError } from '../../errors.js';
import { CliError } from '../../src/errors.js';
const BASE = 'https://itunes.apple.com';
+2 -2
View File
@@ -1,5 +1,5 @@
import { cli, Strategy } from '../../registry.js';
import { CliError } from '../../errors.js';
import { cli, Strategy } from '../../src/registry.js';
import { CliError } from '../../src/errors.js';
import { arxivFetch, parseEntries } from './utils.js';
cli({
+2 -2
View File
@@ -1,5 +1,5 @@
import { cli, Strategy } from '../../registry.js';
import { CliError } from '../../errors.js';
import { cli, Strategy } from '../../src/registry.js';
import { CliError } from '../../src/errors.js';
import { arxivFetch, parseEntries } from './utils.js';
cli({
+1 -1
View File
@@ -5,7 +5,7 @@
* https://info.arxiv.org/help/api/index.html
*/
import { CliError } from '../../errors.js';
import { CliError } from '../../src/errors.js';
export const ARXIV_BASE = 'https://export.arxiv.org/api/query';
+2 -2
View File
@@ -1,5 +1,5 @@
import { AuthRequiredError, EmptyResultError } from '../../errors.js';
import { cli, Strategy } from '../../registry.js';
import { AuthRequiredError, EmptyResultError } from '../../src/errors.js';
import { cli, Strategy } from '../../src/registry.js';
/**
* band bands List all Bands you belong to.
+2 -2
View File
@@ -1,5 +1,5 @@
import { AuthRequiredError, EmptyResultError, SelectorError } from '../../errors.js';
import { cli, Strategy } from '../../registry.js';
import { AuthRequiredError, EmptyResultError, SelectorError } from '../../src/errors.js';
import { cli, Strategy } from '../../src/registry.js';
/**
* band mentions Show Band notifications where you were @mentioned.
+2 -2
View File
@@ -1,7 +1,7 @@
import { AuthRequiredError, EmptyResultError } from '../../errors.js';
import { AuthRequiredError, EmptyResultError } from '../../src/errors.js';
import { formatCookieHeader } from '../../download/index.js';
import { downloadMedia } from '../../download/media-download.js';
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
/**
* band post Export full content of a Band post: body, comments, and optional photo download.
+2 -2
View File
@@ -1,5 +1,5 @@
import { AuthRequiredError, EmptyResultError } from '../../errors.js';
import { cli, Strategy } from '../../registry.js';
import { AuthRequiredError, EmptyResultError } from '../../src/errors.js';
import { cli, Strategy } from '../../src/registry.js';
/**
* band posts List posts from a specific Band.
+1 -1
View File
@@ -3,7 +3,7 @@
* Shows high volume/OI ratio trades that may indicate institutional activity.
* Auth: CSRF token from <meta name="csrf-token"> + session cookies.
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
cli({
site: 'barchart',
+1 -1
View File
@@ -3,7 +3,7 @@
* for near-the-money options on a given symbol.
* Auth: CSRF token from <meta name="csrf-token"> + session cookies.
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
cli({
site: 'barchart',
+1 -1
View File
@@ -2,7 +2,7 @@
* Barchart options chain strike, bid/ask, volume, OI, greeks, IV.
* Auth: CSRF token from <meta name="csrf-token"> + session cookies.
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
cli({
site: 'barchart',
+1 -1
View File
@@ -2,7 +2,7 @@
* Barchart stock quote price, volume, market cap, P/E, EPS, and key metrics.
* Auth: CSRF token from <meta name="csrf-token"> + session cookies.
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
cli({
site: 'barchart',
+1 -1
View File
@@ -1,7 +1,7 @@
/**
* BBC News headlines public RSS feed, no browser needed.
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
cli({
site: 'bbc',
+1 -1
View File
@@ -9,7 +9,7 @@ vi.mock('./utils.js', async (importOriginal) => ({
apiGet: mockApiGet,
}));
import { getRegistry } from '../../registry.js';
import { getRegistry } from '../../src/registry.js';
import './comments.js';
describe('bilibili comments', () => {
+1 -1
View File
@@ -3,7 +3,7 @@
* Uses the /x/v2/reply/main endpoint which is stable and doesn't depend on DOM structure.
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { apiGet, resolveBvid } from './utils.js';
cli({
+1 -1
View File
@@ -8,7 +8,7 @@
* - yt-dlp must be installed: pip install yt-dlp
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { checkYtdlp, sanitizeFilename } from '../../download/index.js';
import { downloadMedia } from '../../download/media-download.js';
import { resolveBvid } from './utils.js';
+1 -1
View File
@@ -8,7 +8,7 @@ vi.mock('./utils.js', () => ({
apiGet: mockApiGet,
}));
import { getRegistry } from '../../registry.js';
import { getRegistry } from '../../src/registry.js';
import './dynamic.js';
describe('bilibili dynamic adapter', () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { apiGet } from './utils.js';
cli({
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { apiGet, payloadData, getSelfUid } from './utils.js';
cli({
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { apiGet, payloadData, getSelfUid, stripHtml } from './utils.js';
cli({
+3 -3
View File
@@ -1,6 +1,6 @@
import { cli, Strategy } from '../../registry.js';
import { CommandExecutionError } from '../../errors.js';
import type { IPage } from '../../types.js';
import { cli, Strategy } from '../../src/registry.js';
import { CommandExecutionError } from '../../src/errors.js';
import type { IPage } from '../../src/types.js';
import { fetchJson, getSelfUid, resolveUid } from './utils.js';
cli({
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { apiGet, payloadData } from './utils.js';
cli({
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { apiGet, getSelfUid } from './utils.js';
cli({
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { apiGet } from './utils.js';
cli({
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { apiGet, stripHtml } from './utils.js';
cli({
+2 -2
View File
@@ -1,6 +1,6 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { AuthRequiredError, EmptyResultError } from '../../errors.js';
import { AuthRequiredError, EmptyResultError } from '../../src/errors.js';
const { mockApiGet } = vi.hoisted(() => ({
mockApiGet: vi.fn(),
@@ -11,7 +11,7 @@ vi.mock('./utils.js', async (importOriginal) => ({
apiGet: mockApiGet,
}));
import { getRegistry } from '../../registry.js';
import { getRegistry } from '../../src/registry.js';
import './subtitle.js';
describe('bilibili subtitle', () => {
+3 -3
View File
@@ -1,6 +1,6 @@
import { cli, Strategy } from '../../registry.js';
import { AuthRequiredError, CommandExecutionError, EmptyResultError, SelectorError } from '../../errors.js';
import type { IPage } from '../../types.js';
import { cli, Strategy } from '../../src/registry.js';
import { AuthRequiredError, CommandExecutionError, EmptyResultError, SelectorError } from '../../src/errors.js';
import type { IPage } from '../../src/types.js';
import { apiGet, resolveBvid } from './utils.js';
cli({
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { apiGet, payloadData, resolveUid } from './utils.js';
cli({
+2 -2
View File
@@ -3,8 +3,8 @@
*/
import https from 'node:https';
import type { IPage } from '../../types.js';
import { AuthRequiredError, EmptyResultError } from '../../errors.js';
import type { IPage } from '../../src/types.js';
import { AuthRequiredError, EmptyResultError } from '../../src/errors.js';
/**
* Resolve Bilibili short URL / short code to BV ID.
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { fetchBloombergFeed } from './utils.js';
cli({
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { fetchBloombergFeed } from './utils.js';
cli({
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { BLOOMBERG_FEEDS } from './utils.js';
cli({
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { fetchBloombergFeed } from './utils.js';
cli({
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { fetchBloombergFeed } from './utils.js';
cli({
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { fetchBloombergFeed } from './utils.js';
cli({
+2 -2
View File
@@ -1,5 +1,5 @@
import { cli, Strategy } from '../../registry.js';
import { CliError } from '../../errors.js';
import { cli, Strategy } from '../../src/registry.js';
import { CliError } from '../../src/errors.js';
import {
extractStoryMediaLinks,
renderStoryBody,
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { fetchBloombergFeed } from './utils.js';
cli({
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { fetchBloombergFeed } from './utils.js';
cli({
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { fetchBloombergFeed } from './utils.js';
cli({
+1 -1
View File
@@ -1,4 +1,4 @@
import { CliError } from '../../errors.js';
import { CliError } from '../../src/errors.js';
export const BLOOMBERG_FEEDS = {
main: 'https://feeds.bloomberg.com/news.rss',
+1 -1
View File
@@ -1,7 +1,7 @@
/**
* BOSS直聘 batchgreet batch greet recommended candidates.
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import {
requirePage, navigateToChat, fetchRecommendList,
clickCandidateInList, typeAndSendMessage, verbose,
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { requirePage, navigateToChat, fetchFriendList } from './utils.js';
cli({
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { requirePage, navigateToChat, bossFetch, findFriendByUid } from './utils.js';
cli({
+1 -1
View File
@@ -1,7 +1,7 @@
/**
* BOSS直聘 job detail fetch full job posting details via browser cookie API.
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { requirePage, navigateTo, bossFetch, verbose } from './utils.js';
cli({
+1 -1
View File
@@ -1,7 +1,7 @@
/**
* BOSS直聘 exchange request phone/wechat exchange with a candidate.
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { requirePage, navigateToChat, bossFetch, findFriendByUid, verbose } from './utils.js';
cli({
+1 -1
View File
@@ -1,7 +1,7 @@
/**
* BOSS直聘 greet send greeting to a new candidate (initiate chat).
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import {
requirePage, navigateToChat, findFriendByUid,
clickCandidateInList, typeAndSendMessage, verbose,
+1 -1
View File
@@ -1,7 +1,7 @@
/**
* BOSS直聘 invite send interview invitation to a candidate.
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { requirePage, navigateToChat, bossFetch, findFriendByUid, verbose } from './utils.js';
cli({
+1 -1
View File
@@ -1,7 +1,7 @@
/**
* BOSS直聘 job list list my published jobs via boss API.
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { requirePage, navigateToChat, bossFetch, verbose } from './utils.js';
cli({
+2 -2
View File
@@ -5,9 +5,9 @@
* 1=, 2=, 3=, 4=, 5=,
* 6=, 7=, 8=, 11=
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { requirePage, navigateToChat, bossFetch, findFriendByUid, verbose } from './utils.js';
import { ArgumentError, EmptyResultError } from '../../errors.js';
import { ArgumentError, EmptyResultError } from '../../src/errors.js';
const LABEL_MAP: Record<string, number> = {
'新招呼': 1, '沟通中': 2, '已约面': 3, '已获取简历': 4,
+1 -1
View File
@@ -1,7 +1,7 @@
/**
* BOSS直聘 recommend view recommended candidates (/greet sort list).
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { requirePage, navigateToChat, bossFetch, fetchRecommendList, verbose } from './utils.js';
cli({
+1 -1
View File
@@ -9,7 +9,7 @@
* .experience-content.detail-list details (company·position / school·major·degree)
* .position-content job being discussed + expectation
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { requirePage, navigateToChat, findFriendByUid, clickCandidateInList } from './utils.js';
cli({
+1 -1
View File
@@ -1,7 +1,7 @@
/**
* BOSS直聘 job search browser cookie API.
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { requirePage, navigateTo, bossFetch, assertOk, verbose } from './utils.js';
/** City name → BOSS Zhipin city code mapping */
+2 -2
View File
@@ -4,12 +4,12 @@
* BOSS chat uses MQTT (not HTTP) for messaging, so we must go through the UI
* rather than making direct API calls.
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import {
requirePage, navigateToChat, findFriendByUid,
clickCandidateInList, typeAndSendMessage,
} from './utils.js';
import { EmptyResultError, SelectorError } from '../../errors.js';
import { EmptyResultError, SelectorError } from '../../src/errors.js';
cli({
site: 'boss',
+1 -1
View File
@@ -1,7 +1,7 @@
/**
* BOSS直聘 stats job statistics overview.
*/
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import { requirePage, navigateToChat, bossFetch, fetchFriendList, verbose } from './utils.js';
cli({
+1 -1
View File
@@ -7,7 +7,7 @@
* - Cookie expiry error codes (code 7, 37)
* - Verbose logging
*/
import type { IPage } from '../../types.js';
import type { IPage } from '../../src/types.js';
// ── Constants ───────────────────────────────────────────────────────────────
+2 -2
View File
@@ -1,5 +1,5 @@
import { cli, Strategy } from '../../registry.js';
import { AuthRequiredError } from '../../errors.js';
import { cli, Strategy } from '../../src/registry.js';
import { AuthRequiredError } from '../../src/errors.js';
import {
getCourses, initSession, enterCourse, getTabIframeUrl,
parseAssignmentsFromDom, sleep,
+1 -1
View File
@@ -1,4 +1,4 @@
import { cli, Strategy } from '../../registry.js';
import { cli, Strategy } from '../../src/registry.js';
import {
getCourses, initSession, enterCourse, getTabIframeUrl,
parseExamsFromDom, sleep,
+1 -1
View File
@@ -6,7 +6,7 @@
* course pages loaded as iframes.
*/
import type { IPage } from '../../types.js';
import type { IPage } from '../../src/types.js';
// ── Utilities ────────────────────────────────────────────────────────
+3 -3
View File
@@ -1,7 +1,7 @@
import { execSync, spawnSync } from 'node:child_process';
import { cli, Strategy } from '../../registry.js';
import { ConfigError } from '../../errors.js';
import type { IPage } from '../../types.js';
import { cli, Strategy } from '../../src/registry.js';
import { ConfigError } from '../../src/errors.js';
import type { IPage } from '../../src/types.js';
import { activateChatGPT, getVisibleChatMessages, selectModel, MODEL_CHOICES, isGenerating } from './ax.js';
export const askCommand = cli({
+3 -3
View File
@@ -1,6 +1,6 @@
import { cli, Strategy } from '../../registry.js';
import { ConfigError } from '../../errors.js';
import type { IPage } from '../../types.js';
import { cli, Strategy } from '../../src/registry.js';
import { ConfigError } from '../../src/errors.js';
import type { IPage } from '../../src/types.js';
import { activateChatGPT, selectModel, MODEL_CHOICES } from './ax.js';
export const modelCommand = cli({
+3 -3
View File
@@ -1,7 +1,7 @@
import { execSync } from 'node:child_process';
import { cli, Strategy } from '../../registry.js';
import { ConfigError, getErrorMessage } from '../../errors.js';
import type { IPage } from '../../types.js';
import { cli, Strategy } from '../../src/registry.js';
import { ConfigError, getErrorMessage } from '../../src/errors.js';
import type { IPage } from '../../src/types.js';
export const newCommand = cli({
site: 'chatgpt',
+3 -3
View File
@@ -1,7 +1,7 @@
import { execSync } from 'node:child_process';
import { cli, Strategy } from '../../registry.js';
import { CommandExecutionError, ConfigError, getErrorMessage } from '../../errors.js';
import type { IPage } from '../../types.js';
import { cli, Strategy } from '../../src/registry.js';
import { CommandExecutionError, ConfigError, getErrorMessage } from '../../src/errors.js';
import type { IPage } from '../../src/types.js';
import { getVisibleChatMessages } from './ax.js';
export const readCommand = cli({
+3 -3
View File
@@ -1,7 +1,7 @@
import { execSync, spawnSync } from 'node:child_process';
import { cli, Strategy } from '../../registry.js';
import type { IPage } from '../../types.js';
import { getErrorMessage } from '../../errors.js';
import { cli, Strategy } from '../../src/registry.js';
import type { IPage } from '../../src/types.js';
import { getErrorMessage } from '../../src/errors.js';
import { activateChatGPT, selectModel, MODEL_CHOICES } from './ax.js';
export const sendCommand = cli({
+3 -3
View File
@@ -1,7 +1,7 @@
import { execSync } from 'node:child_process';
import { cli, Strategy } from '../../registry.js';
import { CommandExecutionError, ConfigError } from '../../errors.js';
import type { IPage } from '../../types.js';
import { cli, Strategy } from '../../src/registry.js';
import { CommandExecutionError, ConfigError } from '../../src/errors.js';
import type { IPage } from '../../src/types.js';
export const statusCommand = cli({
site: 'chatgpt',
+3 -3
View File
@@ -1,6 +1,6 @@
import { cli, Strategy } from '../../registry.js';
import { SelectorError } from '../../errors.js';
import type { IPage } from '../../types.js';
import { cli, Strategy } from '../../src/registry.js';
import { SelectorError } from '../../src/errors.js';
import type { IPage } from '../../src/types.js';
export const askCommand = cli({
site: 'chatwise',
+2 -2
View File
@@ -1,6 +1,6 @@
import * as fs from 'node:fs';
import { cli, Strategy } from '../../registry.js';
import type { IPage } from '../../types.js';
import { cli, Strategy } from '../../src/registry.js';
import type { IPage } from '../../src/types.js';
export const exportCommand = cli({
site: 'chatwise',
+2 -2
View File
@@ -1,5 +1,5 @@
import { cli, Strategy } from '../../registry.js';
import type { IPage } from '../../types.js';
import { cli, Strategy } from '../../src/registry.js';
import type { IPage } from '../../src/types.js';
export const historyCommand = cli({
site: 'chatwise',
+3 -3
View File
@@ -1,6 +1,6 @@
import { cli, Strategy } from '../../registry.js';
import { SelectorError } from '../../errors.js';
import type { IPage } from '../../types.js';
import { cli, Strategy } from '../../src/registry.js';
import { SelectorError } from '../../src/errors.js';
import type { IPage } from '../../src/types.js';
export const modelCommand = cli({
site: 'chatwise',

Some files were not shown because too many files have changed in this diff Show More