@stephenyang/stephen
v0.1.5
Published
A personal TypeScript CLI for agent-friendly workflows.
Readme
stephen
stephen is a personal TypeScript CLI for scriptable, agent-friendly workflows. It returns structured JSON by default and provides table output for list-style commands when human inspection is more convenient.
Current npm package:
npm install -g @stephenyang/stephenAfter installation:
stephen --helpCommand Overview
stephen ak Manage local API key records
stephen config Manage local CLI configuration
stephen disk Preview or run conservative disk cleanup
stephen video Sniff, download, and compress video media
stephen 36kr Fetch 36kr article details and channel lists
stephen toutiao Fetch Toutiao channels, searches, author feeds, and article details
stephen hn Fetch Hacker News top/new/best/search listsOutput rules:
- JSON is the default output format. Successful responses usually look like
{ "ok": true, "data": ... }. - Errors are rendered as JSON, usually
{ "ok": false, "error": { "code": "...", "message": "..." } }. - List and summary commands support
-t/--table, equivalent to--format table. - Detail commands stay JSON-only so downstream scripts can consume the full structure.
Requirements
- Node.js 22+
- npm
curl: used by36krwith browser-like request headers- Playwright Chromium: required by
toutiaoand browser-basedvideosniffing ffmpeg: required byvideo compress
Install the Playwright browser:
npx playwright install chromiumak API Key Manager
ak stores API key records in a local SQLite database. Keys are encrypted at rest and masked by default in normal output. Record IDs are generated as sha1(key), so records can be retrieved by either ID or original key.
Record fields:
env
userId
userName
email
phone
keyRecommended environment names:
bzy-pre
bzy-prod
op-pre
op-prod
gitee
github
gitlabCustom machine-friendly env values are also supported.
Common Commands
Add a record:
stephen ak add -e github -k ghp_xxx -n Stephen -m [email protected]Get a record by key or ID:
stephen ak get -e github -k ghp_xxx
stephen ak get --id fdb441954fd4573a72fb5a52ce359e0d77c3fa0eList records:
stephen ak list
stephen ak list -e github
stephen ak list -q ste -f userName,email
stephen ak list -q ghp_ -f key -tUpdate metadata:
stephen ak update -e github -k ghp_xxx -n StephenYang
stephen ak update --id fdb441954fd4573a72fb5a52ce359e0d77c3fa0e -m [email protected]Delete a record:
stephen ak delete --id fdb441954fd4573a72fb5a52ce359e0d77c3fa0e --yesak Options
-e, --env <env> Environment
-u, --user-id <userId> User ID
-n, --user-name <userName> User name
-m, --email <email> Email
-p, --phone <phone> Phone number
-k, --key <key> API key
-q, --query <query> Fuzzy query
-f, --field <field> Search fields, comma-separated
--id <id> Record ID
--limit <limit> List limit, default 50, max 100
--raw-key Show the full key
--format <json|table> Output format
-t, --table Table outputQuery rules:
userId,userName,email, andphonesupport fuzzy search.keysearch only supports low-sensitivity prefix matching.- Keys are masked unless
--raw-keyis passed.
config Local Configuration
config manages local machine configuration. Currently supported key:
ak.dbPathList all config entries:
stephen config list
stephen config list -tGet one config entry:
stephen config get ak.dbPathSet the API key database path:
stephen config set ak.dbPath /Users/stephen/iDrive/stephen/ak.dbak.dbPath resolution priority:
- Local config file value
ak.dbPath STEPHEN_AK_DB_PATH- Legacy environment variable
STEPHEN_CLI_AK_DB_PATH - Default
env-pathsdata directory
disk cleanup
disk cleanup provides conservative Windows disk cleanup. It previews by default and does not delete anything unless --apply is passed.
Cleanup levels:
safe Default level for common safe caches
dev safe + common developer caches
system safe + Windows system cleanup actions; apply mode requires --confirm
deep dev + system, and reports the largest 100 Downloads entries without deleting themCommon commands:
stephen disk cleanup
stephen disk cleanup -t
stephen disk cleanup --level dev
stephen disk cleanup --level deep
stephen disk cleanup --apply
stephen disk cleanup --level system --apply --confirm
stephen disk cleanup --apply --disable-hibernateNotes:
--applyis required before cleanup actions are executed.systemanddeeprequire--confirmin apply mode.- Downloads is never deleted;
deeponly reports the largest files and directories for manual review.
video
video can sniff video candidates from pages or media URLs, download mp4 / m3u8, and compress local videos with ffmpeg.
Sniff
stephen video sniff https://example.com/watch/123
stephen video sniff https://example.com/watch/123 -t
stephen video sniff https://example.com/watch/123 --mode browser
stephen video sniff https://cdn.example.com/video.mp4 --mode httpModes:
auto Default; try browser sniffing first, then HTTP fallback
browser Use Playwright to capture page network requests
http Inspect direct URLs, HTML, and scripts without browser executionProxy examples:
stephen video sniff https://example.com/watch/123 --proxy http://127.0.0.1:7890
stephen video sniff https://example.com/watch/123 --skip-proxyDownload
stephen video download https://cdn.example.com/video.mp4
stephen video download https://cdn.example.com/master.m3u8
stephen video download https://example.com/watch/123 --mode browser
stephen video download https://example.com/watch/123 --output-dir ./downloadsDownload behavior:
- Direct
mp4URLs are downloaded directly. m3u8playlists are fetched with their segments and merged into one output.- Page URLs are sniffed first, then a compatible candidate is downloaded.
- Page downloads use the parsed page title as the automatic filename when available. HTTP mode prefers
og:titleand falls back to<title>; browser mode uses the final browser page title. - Direct media URLs keep their media-derived filename when no page title is available.
- Downloads are written to a sibling temporary file and hashed with MD5 only after the transfer completes.
- If the same-title family already contains the same MD5, the temporary file is removed and the result returns the existing path with
status: "already_downloaded". - If the content differs, filename collisions use
Title (2).ext,Title (3).ext, and so on without overwriting existing files.
Successful download output includes status, md5, mediaType, outputPath, and sourceUrl. MD5 deduplication happens after transfer; it does not skip the network request before the content is available locally.
Compress
stephen video compress ./input.mov
stephen video compress ./input.mov --output-path ./output.mp4
stephen video compress ./input.mov --resolution 1280x720
stephen video compress ./input.mov --video-bitrate 1800k --audio-bitrate 64k
stephen video compress ./input.mov -tDefault compression settings:
container mp4
video codec libx265
audio codec aac
audio bitrate 64k36kr
36kr uses curl to request 36kr pages and pagination APIs with browser-like headers. It supports article details and two information channels.
Article Details
Pass the article ID; the CLI builds the article detail URL:
stephen 36kr article 3853011900142848Output includes:
id
url
title
summary
author
publishTime
content.html
content.paragraphs
coverImage
images
imageSources
stats
organizations
newestArticles
relatedArticles
latestArticles
nextArticle
requestChannel Lists
Supported channels:
AI
technologyExamples:
stephen 36kr list AI
stephen 36kr list technology --pages 3
stephen 36kr list AI --pages 2 -tNotes:
--pagesmust be between 1 and 20.- The first page is parsed from
https://36kr.com/information/<channel>/. - Later pages use the
pageCallbackfrom the page and call the 36kr pagination API.
List output includes:
channel
items[].id
items[].title
items[].summary
items[].authorName
items[].publishTime
items[].url
meta.fetchedPages
meta.totalItems
meta.hasNextPage
meta.nextPageCallback
requesttoutiao
toutiao uses Playwright Chromium to collect Toutiao page data. This is useful for pages that require real browser execution, scrolling, or response interception.
Channels and Keyword Feeds
Supported sources:
tech
AI
光刻机
芯片
半导体Examples:
stephen toutiao list tech
stephen toutiao list AI --pages 2
stephen toutiao list 光刻机 -t
stephen toutiao list 芯片 --pages 3 -t
stephen toutiao list 半导体Notes:
techuses the Toutiao technology channel.AI,光刻机,芯片, and半导体use Toutiao search feeds.--pagesmust be between 1 and 5.
List output includes:
source
keyword
items[].id
items[].title
items[].abstract
items[].authorName
items[].commentCount
items[].publishTime
items[].url
items[].sourceUrl
hasMore
next
metaArticle Details
Pass either an article ID or URL:
stephen toutiao article 1234567890
stephen toutiao article https://www.toutiao.com/article/1234567890/Output includes:
id
url
title
authorName
publishTimeText
content.text
content.paragraphs
requestAuthor Feeds
Pass either an author token or author homepage URL:
stephen toutiao author MS4wLjABAAAAVuJhKsIQSKk3hYJ17wPrQUnUnNT7WadBo4T-QiyRk0A
stephen toutiao author 'https://www.toutiao.com/c/user/token/MS4wLjABAAAAVuJhKsIQSKk3hYJ17wPrQUnUnNT7WadBo4T-QiyRk0A/?source=profile'
stephen toutiao author MS4wLjABAAAAVuJhKsIQSKk3hYJ17wPrQUnUnNT7WadBo4T-QiyRk0A --pages 2 -tFetch article details for the author feed:
stephen toutiao author MS4wLjABAAAAVuJhKsIQSKk3hYJ17wPrQUnUnNT7WadBo4T-QiyRk0A --with-contentNotes:
--pagesmust be between 1 and 5.- Without
--with-content, the command returns only the author article list. - With
--with-content, article details are fetched and returned in thearticlesfield.
hn Hacker News
hn supports Hacker News story lists and search. JSON is the default output format, and list output supports -t.
Top stories:
stephen hn top
stephen hn top --limit 10 -tNew stories:
stephen hn new
stephen hn new --limit 20Best stories:
stephen hn best
stephen hn best --limit 20 -tSearch:
stephen hn search openai
stephen hn search "browser automation" --sort date --limit 20 -tOptions:
--limit <limit> Number of items, 1 to 100
--sort <relevance|date> Search sort, default relevance
--format <json|table> Output format
-t, --table Table outputOutput includes:
items[].id
items[].title
items[].author
items[].score
items[].commentCount
items[].time
items[].url
metaCommands With Table Output
These commands are useful for quick human inspection:
stephen ak list -t
stephen config list -t
stephen disk cleanup -t
stephen video sniff <url> -t
stephen video download <url> -t
stephen video compress <file> -t
stephen 36kr list AI -t
stephen toutiao list tech -t
stephen toutiao author <token-or-url> -t
stephen hn top -t
stephen hn new -t
stephen hn best -t
stephen hn search openai -tDevelopment
Install dependencies:
npm installType check:
npm run checkRun tests:
npm testRun coverage:
npm run coverageBuild:
npm run buildRun the built CLI locally:
node dist/index.js --helpPreview the npm package:
npm pack --dry-runPublishing
The current package is a scoped public package:
@stephenyang/stephenPublish:
npm publish --access publicVerify after publishing:
npm view @stephenyang/stephen version --json