@steipete/summarize 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +75 -0
- package/LICENSE +1 -1
- package/README.md +307 -184
- package/dist/cli.js +1 -1
- package/dist/esm/cache.js +72 -4
- package/dist/esm/cache.js.map +1 -1
- package/dist/esm/config.js +127 -1
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/daemon/agent.js +547 -0
- package/dist/esm/daemon/agent.js.map +1 -0
- package/dist/esm/daemon/chat.js +83 -175
- package/dist/esm/daemon/chat.js.map +1 -1
- package/dist/esm/daemon/cli.js +35 -3
- package/dist/esm/daemon/cli.js.map +1 -1
- package/dist/esm/daemon/env-snapshot.js +3 -0
- package/dist/esm/daemon/env-snapshot.js.map +1 -1
- package/dist/esm/daemon/flow-context.js +31 -8
- package/dist/esm/daemon/flow-context.js.map +1 -1
- package/dist/esm/daemon/launchd.js +27 -0
- package/dist/esm/daemon/launchd.js.map +1 -1
- package/dist/esm/daemon/process-registry.js +206 -0
- package/dist/esm/daemon/process-registry.js.map +1 -0
- package/dist/esm/daemon/schtasks.js +64 -0
- package/dist/esm/daemon/schtasks.js.map +1 -1
- package/dist/esm/daemon/server.js +712 -42
- package/dist/esm/daemon/server.js.map +1 -1
- package/dist/esm/daemon/summarize.js +33 -4
- package/dist/esm/daemon/summarize.js.map +1 -1
- package/dist/esm/daemon/systemd.js +61 -0
- package/dist/esm/daemon/systemd.js.map +1 -1
- package/dist/esm/flags.js +24 -0
- package/dist/esm/flags.js.map +1 -1
- package/dist/esm/llm/providers/openai.js +1 -1
- package/dist/esm/llm/providers/openai.js.map +1 -1
- package/dist/esm/media-cache.js +251 -0
- package/dist/esm/media-cache.js.map +1 -0
- package/dist/esm/processes.js +2 -0
- package/dist/esm/processes.js.map +1 -0
- package/dist/esm/run/bird.js +118 -5
- package/dist/esm/run/bird.js.map +1 -1
- package/dist/esm/run/cli-preflight.js +19 -1
- package/dist/esm/run/cli-preflight.js.map +1 -1
- package/dist/esm/run/finish-line.js +11 -4
- package/dist/esm/run/finish-line.js.map +1 -1
- package/dist/esm/run/flows/asset/extract.js +70 -0
- package/dist/esm/run/flows/asset/extract.js.map +1 -0
- package/dist/esm/run/flows/asset/input.js +208 -24
- package/dist/esm/run/flows/asset/input.js.map +1 -1
- package/dist/esm/run/flows/asset/media-policy.js +3 -0
- package/dist/esm/run/flows/asset/media-policy.js.map +1 -0
- package/dist/esm/run/flows/asset/media.js +224 -0
- package/dist/esm/run/flows/asset/media.js.map +1 -0
- package/dist/esm/run/flows/asset/output.js +98 -0
- package/dist/esm/run/flows/asset/output.js.map +1 -0
- package/dist/esm/run/flows/asset/summary.js +157 -7
- package/dist/esm/run/flows/asset/summary.js.map +1 -1
- package/dist/esm/run/flows/url/extract.js +6 -6
- package/dist/esm/run/flows/url/extract.js.map +1 -1
- package/dist/esm/run/flows/url/flow.js +336 -36
- package/dist/esm/run/flows/url/flow.js.map +1 -1
- package/dist/esm/run/flows/url/markdown.js +6 -1
- package/dist/esm/run/flows/url/markdown.js.map +1 -1
- package/dist/esm/run/flows/url/slides-output.js +485 -0
- package/dist/esm/run/flows/url/slides-output.js.map +1 -0
- package/dist/esm/run/flows/url/slides-text.js +628 -0
- package/dist/esm/run/flows/url/slides-text.js.map +1 -0
- package/dist/esm/run/flows/url/summary.js +356 -82
- package/dist/esm/run/flows/url/summary.js.map +1 -1
- package/dist/esm/run/help.js +94 -5
- package/dist/esm/run/help.js.map +1 -1
- package/dist/esm/run/logging.js +12 -4
- package/dist/esm/run/logging.js.map +1 -1
- package/dist/esm/run/media-cache-state.js +33 -0
- package/dist/esm/run/media-cache-state.js.map +1 -0
- package/dist/esm/run/progress.js +19 -1
- package/dist/esm/run/progress.js.map +1 -1
- package/dist/esm/run/run-settings.js +39 -1
- package/dist/esm/run/run-settings.js.map +1 -1
- package/dist/esm/run/runner.js +196 -8
- package/dist/esm/run/runner.js.map +1 -1
- package/dist/esm/run/slides-cli.js +225 -0
- package/dist/esm/run/slides-cli.js.map +1 -0
- package/dist/esm/run/slides-render.js +163 -0
- package/dist/esm/run/slides-render.js.map +1 -0
- package/dist/esm/run/stream-output.js +10 -3
- package/dist/esm/run/stream-output.js.map +1 -1
- package/dist/esm/run/summary-engine.js +33 -7
- package/dist/esm/run/summary-engine.js.map +1 -1
- package/dist/esm/run/transcriber-cli.js +148 -0
- package/dist/esm/run/transcriber-cli.js.map +1 -0
- package/dist/esm/shared/sse-events.js +4 -0
- package/dist/esm/shared/sse-events.js.map +1 -1
- package/dist/esm/slides/extract.js +1942 -0
- package/dist/esm/slides/extract.js.map +1 -0
- package/dist/esm/slides/index.js +4 -0
- package/dist/esm/slides/index.js.map +1 -0
- package/dist/esm/slides/settings.js +73 -0
- package/dist/esm/slides/settings.js.map +1 -0
- package/dist/esm/slides/store.js +111 -0
- package/dist/esm/slides/store.js.map +1 -0
- package/dist/esm/slides/types.js +2 -0
- package/dist/esm/slides/types.js.map +1 -0
- package/dist/esm/tty/osc-progress.js +21 -1
- package/dist/esm/tty/osc-progress.js.map +1 -1
- package/dist/esm/tty/progress/fetch-html.js +8 -4
- package/dist/esm/tty/progress/fetch-html.js.map +1 -1
- package/dist/esm/tty/progress/transcript.js +82 -31
- package/dist/esm/tty/progress/transcript.js.map +1 -1
- package/dist/esm/tty/spinner.js +2 -2
- package/dist/esm/tty/spinner.js.map +1 -1
- package/dist/esm/tty/theme.js +189 -0
- package/dist/esm/tty/theme.js.map +1 -0
- package/dist/esm/tty/website-progress.js +17 -13
- package/dist/esm/tty/website-progress.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/types/cache.d.ts +14 -2
- package/dist/types/config.d.ts +23 -0
- package/dist/types/daemon/agent.d.ts +25 -0
- package/dist/types/daemon/chat.d.ts +10 -18
- package/dist/types/daemon/env-snapshot.d.ts +1 -1
- package/dist/types/daemon/flow-context.d.ts +21 -1
- package/dist/types/daemon/launchd.d.ts +4 -0
- package/dist/types/daemon/process-registry.d.ts +73 -0
- package/dist/types/daemon/schtasks.d.ts +4 -0
- package/dist/types/daemon/summarize.d.ts +36 -5
- package/dist/types/daemon/systemd.d.ts +4 -0
- package/dist/types/flags.d.ts +1 -0
- package/dist/types/media-cache.d.ts +22 -0
- package/dist/types/processes.d.ts +1 -0
- package/dist/types/run/bird.d.ts +7 -0
- package/dist/types/run/finish-line.d.ts +2 -1
- package/dist/types/run/flows/asset/extract.d.ts +18 -0
- package/dist/types/run/flows/asset/input.d.ts +12 -2
- package/dist/types/run/flows/asset/media-policy.d.ts +2 -0
- package/dist/types/run/flows/asset/media.d.ts +21 -0
- package/dist/types/run/flows/asset/output.d.ts +42 -0
- package/dist/types/run/flows/asset/summary.d.ts +6 -0
- package/dist/types/run/flows/url/extract.d.ts +2 -1
- package/dist/types/run/flows/url/slides-output.d.ts +66 -0
- package/dist/types/run/flows/url/slides-text.d.ts +87 -0
- package/dist/types/run/flows/url/summary.d.ts +11 -3
- package/dist/types/run/flows/url/types.d.ts +29 -2
- package/dist/types/run/help.d.ts +3 -0
- package/dist/types/run/logging.d.ts +3 -2
- package/dist/types/run/media-cache-state.d.ts +7 -0
- package/dist/types/run/progress.d.ts +2 -1
- package/dist/types/run/run-settings.d.ts +7 -1
- package/dist/types/run/slides-cli.d.ts +9 -0
- package/dist/types/run/slides-render.d.ts +30 -0
- package/dist/types/run/stream-output.d.ts +2 -1
- package/dist/types/run/summary-engine.d.ts +11 -1
- package/dist/types/run/transcriber-cli.d.ts +8 -0
- package/dist/types/shared/sse-events.d.ts +20 -0
- package/dist/types/slides/extract.d.ts +42 -0
- package/dist/types/slides/index.d.ts +5 -0
- package/dist/types/slides/settings.d.ts +20 -0
- package/dist/types/slides/store.d.ts +15 -0
- package/dist/types/slides/types.d.ts +40 -0
- package/dist/types/tty/osc-progress.d.ts +2 -2
- package/dist/types/tty/progress/fetch-html.d.ts +3 -1
- package/dist/types/tty/progress/transcript.d.ts +3 -1
- package/dist/types/tty/spinner.d.ts +3 -1
- package/dist/types/tty/theme.d.ts +44 -0
- package/dist/types/tty/website-progress.d.ts +3 -1
- package/dist/types/version.d.ts +1 -1
- package/docs/README.md +1 -1
- package/docs/_config.yml +26 -0
- package/docs/_layouts/default.html +60 -0
- package/docs/agent.md +333 -0
- package/docs/assets/site.css +748 -0
- package/docs/assets/site.js +72 -0
- package/docs/assets/summarize-cli.png +0 -0
- package/docs/assets/summarize-extension.png +0 -0
- package/docs/assets/youtube-slides.png +0 -0
- package/docs/cache.md +29 -3
- package/docs/chrome-extension.md +61 -11
- package/docs/config.md +50 -2
- package/docs/extract-only.md +8 -0
- package/docs/index.html +205 -0
- package/docs/index.md +25 -0
- package/docs/llm.md +11 -1
- package/docs/manual-tests.md +2 -0
- package/docs/media.md +3 -0
- package/docs/nvidia-onnx-transcription.md +55 -0
- package/docs/site/assets/site.css +399 -228
- package/docs/site/assets/summarize-cli.png +0 -0
- package/docs/site/assets/summarize-extension.png +0 -0
- package/docs/site/docs/chrome-extension.html +89 -0
- package/docs/site/docs/config.html +1 -0
- package/docs/site/docs/extract-only.html +1 -0
- package/docs/site/docs/firecrawl.html +1 -0
- package/docs/site/docs/index.html +5 -0
- package/docs/site/docs/llm.html +1 -0
- package/docs/site/docs/openai.html +1 -0
- package/docs/site/docs/website.html +1 -0
- package/docs/site/docs/youtube.html +1 -0
- package/docs/site/index.html +148 -84
- package/docs/slides.md +74 -0
- package/docs/timestamps.md +103 -0
- package/docs/website.md +12 -0
- package/docs/youtube.md +16 -0
- package/package.json +16 -15
package/README.md
CHANGED
|
@@ -1,17 +1,93 @@
|
|
|
1
|
-
# Summarize
|
|
1
|
+
# Summarize — Chrome Side Panel + CLI
|
|
2
2
|
|
|
3
|
-
Fast
|
|
3
|
+
Fast summaries from URLs, files, and media. Works in the terminal, a Chrome Side Panel and Firefox Sidebar.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- YouTube links (best-effort transcripts; can fall back to audio transcription)
|
|
7
|
-
- Podcasts (Apple Podcasts / Spotify / RSS; prefers published transcripts when available; otherwise transcribes full episodes)
|
|
8
|
-
- Any audio/video (local files or direct media URLs; transcribe via Whisper, then summarize)
|
|
9
|
-
- Remote files (PDFs/images/audio/video via URL — downloaded and forwarded to the model)
|
|
10
|
-
- Local files (PDFs/images/audio/video/text — forwarded or inlined; support depends on provider/model)
|
|
5
|
+
**0.10.0 preview (unreleased):** this README reflects the upcoming release.
|
|
11
6
|
|
|
12
|
-
|
|
7
|
+
## 0.10.0 preview highlights (most interesting first)
|
|
13
8
|
|
|
14
|
-
|
|
9
|
+
- Chrome Side Panel **chat** (streaming agent + history) inside the sidebar.
|
|
10
|
+
- **YouTube slides**: screenshots + OCR + transcript cards, timestamped seek, OCR/Transcript toggle.
|
|
11
|
+
- Media-aware summaries: auto‑detect video/audio vs page content.
|
|
12
|
+
- Streaming Markdown + metrics + cache‑aware status.
|
|
13
|
+
- CLI supports URLs, files, podcasts, YouTube, audio/video, PDFs.
|
|
14
|
+
|
|
15
|
+
## Feature overview
|
|
16
|
+
|
|
17
|
+
- URLs, files, and media: web pages, PDFs, images, audio/video, YouTube, podcasts, RSS.
|
|
18
|
+
- Slide extraction for video sources (YouTube/direct media) with OCR + timestamped cards.
|
|
19
|
+
- Transcript-first media flow: published transcripts when available, Whisper fallback when not.
|
|
20
|
+
- Streaming output with Markdown rendering, metrics, and cache-aware status.
|
|
21
|
+
- Local, paid, and free models: OpenAI‑compatible local endpoints, paid providers, plus an OpenRouter free preset.
|
|
22
|
+
- Output modes: Markdown/text, JSON diagnostics, extract-only, metrics, timing, and cost estimates.
|
|
23
|
+
- Smart default: if content is shorter than the requested length, we return it as-is (use `--force-summary` to override).
|
|
24
|
+
|
|
25
|
+
## Get the extension (recommended)
|
|
26
|
+
|
|
27
|
+

|
|
28
|
+
|
|
29
|
+
One‑click summarizer for the current tab. Chrome Side Panel + Firefox Sidebar + local daemon for streaming Markdown.
|
|
30
|
+
|
|
31
|
+
**Chrome Web Store:** [Summarize Side Panel](https://chromewebstore.google.com/detail/summarize/cejgnmmhbbpdmjnfppjdfkocebngehfg)
|
|
32
|
+
|
|
33
|
+
YouTube slide screenshots (from the browser):
|
|
34
|
+
|
|
35
|
+

|
|
36
|
+
|
|
37
|
+
### Beginner quickstart (extension)
|
|
38
|
+
|
|
39
|
+
1) Install the CLI (choose one):
|
|
40
|
+
- **npm** (cross‑platform): `npm i -g @steipete/summarize`
|
|
41
|
+
- **Homebrew** (macOS arm64): `brew install steipete/tap/summarize`
|
|
42
|
+
2) Install the extension (Chrome Web Store link above) and open the Side Panel.
|
|
43
|
+
3) The panel shows a token + install command. Run it in Terminal:
|
|
44
|
+
- `summarize daemon install --token <TOKEN>`
|
|
45
|
+
|
|
46
|
+
Why a daemon/service?
|
|
47
|
+
- The extension can’t run heavy extraction inside the browser. It talks to a local background service on `127.0.0.1` for fast streaming and media tools (yt‑dlp, ffmpeg, OCR, transcription).
|
|
48
|
+
- The service autostarts (launchd/systemd/Scheduled Task) so the Side Panel is always ready.
|
|
49
|
+
|
|
50
|
+
If you only want the **CLI**, you can skip the daemon install entirely.
|
|
51
|
+
|
|
52
|
+
Notes:
|
|
53
|
+
|
|
54
|
+
- Summarization only runs when the Side Panel is open.
|
|
55
|
+
- Auto mode summarizes on navigation (incl. SPAs); otherwise use the button.
|
|
56
|
+
- Daemon is localhost-only and requires a shared token.
|
|
57
|
+
- Autostart: macOS (launchd), Linux (systemd user), Windows (Scheduled Task).
|
|
58
|
+
- Tip: configure `free` via `summarize refresh-free` (needs `OPENROUTER_API_KEY`). Add `--set-default` to set model=`free`.
|
|
59
|
+
|
|
60
|
+
More:
|
|
61
|
+
|
|
62
|
+
- Step-by-step install: [apps/chrome-extension/README.md](apps/chrome-extension/README.md)
|
|
63
|
+
- Architecture + troubleshooting: [docs/chrome-extension.md](docs/chrome-extension.md)
|
|
64
|
+
- Firefox compatibility notes: [apps/chrome-extension/docs/firefox.md](apps/chrome-extension/docs/firefox.md)
|
|
65
|
+
|
|
66
|
+
### Slides (extension)
|
|
67
|
+
|
|
68
|
+
- Select **Video + Slides** in the Summarize picker.
|
|
69
|
+
- Slides render at the top; expand to full‑width cards with timestamps.
|
|
70
|
+
- Click a slide to seek the video; toggle **Transcript/OCR** when OCR is significant.
|
|
71
|
+
- Requirements: `yt-dlp` + `ffmpeg` for extraction; `tesseract` for OCR. Missing tools show an in‑panel notice.
|
|
72
|
+
|
|
73
|
+
### Advanced (unpacked / dev)
|
|
74
|
+
|
|
75
|
+
1) Build + load the extension (unpacked):
|
|
76
|
+
- Chrome: `pnpm -C apps/chrome-extension build`
|
|
77
|
+
- `chrome://extensions` → Developer mode → Load unpacked
|
|
78
|
+
- Pick: `apps/chrome-extension/.output/chrome-mv3`
|
|
79
|
+
- Firefox: `pnpm -C apps/chrome-extension build:firefox`
|
|
80
|
+
- `about:debugging#/runtime/this-firefox` → Load Temporary Add-on
|
|
81
|
+
- Pick: `apps/chrome-extension/.output/firefox-mv3/manifest.json`
|
|
82
|
+
2) Open Side Panel/Sidebar → copy token.
|
|
83
|
+
3) Install daemon in dev mode:
|
|
84
|
+
- `pnpm summarize daemon install --token <TOKEN> --dev`
|
|
85
|
+
|
|
86
|
+
## CLI
|
|
87
|
+
|
|
88
|
+

|
|
89
|
+
|
|
90
|
+
### Install
|
|
15
91
|
|
|
16
92
|
Requires Node 22+.
|
|
17
93
|
|
|
@@ -21,7 +97,7 @@ Requires Node 22+.
|
|
|
21
97
|
npx -y @steipete/summarize "https://example.com"
|
|
22
98
|
```
|
|
23
99
|
|
|
24
|
-
- npm (global
|
|
100
|
+
- npm (global):
|
|
25
101
|
|
|
26
102
|
```bash
|
|
27
103
|
npm i -g @steipete/summarize
|
|
@@ -45,110 +121,95 @@ brew install steipete/tap/summarize
|
|
|
45
121
|
|
|
46
122
|
Apple Silicon only (arm64).
|
|
47
123
|
|
|
48
|
-
|
|
124
|
+
### CLI vs extension
|
|
125
|
+
|
|
126
|
+
- **CLI only:** just install via npm/Homebrew and run `summarize ...` (no daemon needed).
|
|
127
|
+
- **Chrome/Firefox extension:** install the CLI **and** run `summarize daemon install --token <TOKEN>` so the Side Panel can stream results and use local tools.
|
|
128
|
+
|
|
129
|
+
### Quickstart
|
|
49
130
|
|
|
50
131
|
```bash
|
|
51
132
|
summarize "https://example.com"
|
|
52
133
|
```
|
|
53
134
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
Want a one-click “always-on” summarizer in Chrome (real Side Panel, not injected UI)?
|
|
57
|
-
|
|
58
|
-
This is a **Chrome extension** + a tiny local **daemon** (autostart service) that streams Markdown summaries for the **currently visible tab** into the Side Panel.
|
|
59
|
-
|
|
60
|
-
- Step-by-step install (Chrome + daemon): `apps/chrome-extension/README.md`
|
|
61
|
-
- Architecture + troubleshooting: `docs/chrome-extension.md`
|
|
62
|
-
|
|
63
|
-
Quickstart (local daemon):
|
|
64
|
-
|
|
65
|
-
1) Install summarize (choose one):
|
|
66
|
-
- `npm i -g @steipete/summarize`
|
|
67
|
-
- `brew install steipete/tap/summarize` (macOS arm64)
|
|
68
|
-
2) Build + load the extension (unpacked):
|
|
69
|
-
- `pnpm -C apps/chrome-extension build`
|
|
70
|
-
- Chrome → `chrome://extensions` → Developer mode → “Load unpacked”
|
|
71
|
-
- Pick: `apps/chrome-extension/.output/chrome-mv3`
|
|
72
|
-
3) Open the Side Panel → it shows a token + install command.
|
|
73
|
-
4) Run the install command in Terminal:
|
|
74
|
-
- Installed binary: `summarize daemon install --token <TOKEN>`
|
|
75
|
-
- Repo/dev checkout: `pnpm summarize daemon install --token <TOKEN> --dev`
|
|
76
|
-
5) Verify / debug:
|
|
77
|
-
- `summarize daemon status`
|
|
78
|
-
- `summarize daemon restart`
|
|
79
|
-
|
|
80
|
-
Notes:
|
|
81
|
-
|
|
82
|
-
- Summarization only runs when the Side Panel is open.
|
|
83
|
-
- “Auto” mode summarizes on navigation (incl. SPAs); otherwise use the button.
|
|
84
|
-
- The daemon is localhost-only and requires a shared token.
|
|
85
|
-
- Daemon autostart: macOS (launchd), Linux (systemd user), Windows (Scheduled Task).
|
|
86
|
-
- Tip: configure `free` via `summarize refresh-free` (requires `OPENROUTER_API_KEY`). Add `--set-default` to also set model=`free`, then set Model to `free` in extension settings.
|
|
87
|
-
|
|
88
|
-
Troubleshooting:
|
|
89
|
-
|
|
90
|
-
- **“Receiving end does not exist”**: Chrome didn’t inject the content script yet.
|
|
91
|
-
- Extension details → “Site access” → set to “On all sites” (or allow this domain)
|
|
92
|
-
- Reload the tab once.
|
|
93
|
-
- **“Failed to fetch” / daemon unreachable**:
|
|
94
|
-
- Run `summarize daemon status`
|
|
95
|
-
- Check logs: `~/.summarize/logs/daemon.err.log`
|
|
135
|
+
### Inputs
|
|
96
136
|
|
|
97
|
-
|
|
137
|
+
URLs or local paths:
|
|
98
138
|
|
|
99
139
|
```bash
|
|
100
|
-
|
|
101
|
-
|
|
140
|
+
summarize "/path/to/file.pdf" --model google/gemini-3-flash-preview
|
|
141
|
+
summarize "https://example.com/report.pdf" --model google/gemini-3-flash-preview
|
|
142
|
+
summarize "/path/to/audio.mp3"
|
|
143
|
+
summarize "/path/to/video.mp4"
|
|
102
144
|
```
|
|
103
145
|
|
|
104
|
-
|
|
146
|
+
YouTube (supports `youtube.com` and `youtu.be`):
|
|
105
147
|
|
|
106
148
|
```bash
|
|
107
|
-
|
|
149
|
+
summarize "https://youtu.be/dQw4w9WgXcQ" --youtube auto
|
|
108
150
|
```
|
|
109
151
|
|
|
110
|
-
|
|
152
|
+
Podcast RSS (transcribes latest enclosure):
|
|
111
153
|
|
|
112
154
|
```bash
|
|
113
|
-
|
|
155
|
+
summarize "https://feeds.npr.org/500005/podcast.xml"
|
|
114
156
|
```
|
|
115
157
|
|
|
116
|
-
|
|
158
|
+
Apple Podcasts episode page:
|
|
117
159
|
|
|
118
160
|
```bash
|
|
119
|
-
|
|
161
|
+
summarize "https://podcasts.apple.com/us/podcast/2424-jelly-roll/id360084272?i=1000740717432"
|
|
120
162
|
```
|
|
121
163
|
|
|
122
|
-
|
|
164
|
+
Spotify episode page (best-effort; may fail for exclusives):
|
|
123
165
|
|
|
124
166
|
```bash
|
|
125
|
-
|
|
167
|
+
summarize "https://open.spotify.com/episode/5auotqWAXhhKyb9ymCuBJY"
|
|
126
168
|
```
|
|
127
169
|
|
|
128
|
-
|
|
170
|
+
### Output length
|
|
171
|
+
|
|
172
|
+
`--length` controls how much output we ask for (guideline), not a hard cap.
|
|
129
173
|
|
|
130
174
|
```bash
|
|
131
|
-
|
|
175
|
+
summarize "https://example.com" --length long
|
|
176
|
+
summarize "https://example.com" --length 20k
|
|
132
177
|
```
|
|
133
178
|
|
|
134
|
-
|
|
179
|
+
- Presets: `short|medium|long|xl|xxl`
|
|
180
|
+
- Character targets: `1500`, `20k`, `20000`
|
|
181
|
+
- Optional hard cap: `--max-output-tokens <count>` (e.g. `2000`, `2k`)
|
|
182
|
+
- Provider/model APIs still enforce their own maximum output limits.
|
|
183
|
+
- If omitted, no max token parameter is sent (provider default).
|
|
184
|
+
- Prefer `--length` unless you need a hard cap.
|
|
185
|
+
- Short content: when extracted content is shorter than the requested length, the CLI returns the content as-is.
|
|
186
|
+
- Override with `--force-summary` to always run the LLM.
|
|
187
|
+
- Minimums: `--length` numeric values must be >= 50 chars; `--max-output-tokens` must be >= 16.
|
|
188
|
+
- Preset targets (source of truth: `packages/core/src/prompts/summary-lengths.ts`):
|
|
189
|
+
- short: target ~900 chars (range 600-1,200)
|
|
190
|
+
- medium: target ~1,800 chars (range 1,200-2,500)
|
|
191
|
+
- long: target ~4,200 chars (range 2,500-6,000)
|
|
192
|
+
- xl: target ~9,000 chars (range 6,000-14,000)
|
|
193
|
+
- xxl: target ~17,000 chars (range 14,000-22,000)
|
|
135
194
|
|
|
136
|
-
|
|
195
|
+
### What file types work?
|
|
137
196
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
-
|
|
197
|
+
Best effort and provider-dependent. These usually work well:
|
|
198
|
+
|
|
199
|
+
- `text/*` and common structured text (`.txt`, `.md`, `.json`, `.yaml`, `.xml`, ...)
|
|
200
|
+
- Text-like files are inlined into the prompt for better provider compatibility.
|
|
201
|
+
- PDFs: `application/pdf` (provider support varies; Google is the most reliable here)
|
|
141
202
|
- Images: `image/jpeg`, `image/png`, `image/webp`, `image/gif`
|
|
142
|
-
- Audio/Video: `audio/*`, `video/*` (when supported by the model)
|
|
203
|
+
- Audio/Video: `audio/*`, `video/*` (local audio/video files MP3/WAV/M4A/OGG/FLAC/MP4/MOV/WEBM automatically transcribed, when supported by the model)
|
|
143
204
|
|
|
144
205
|
Notes:
|
|
145
206
|
|
|
146
|
-
- If a provider rejects a media type, the CLI fails fast with a friendly message
|
|
147
|
-
- xAI models
|
|
207
|
+
- If a provider rejects a media type, the CLI fails fast with a friendly message.
|
|
208
|
+
- xAI models do not support attaching generic files (like PDFs) via the AI SDK; use Google/OpenAI/Anthropic for those.
|
|
148
209
|
|
|
149
|
-
|
|
210
|
+
### Model ids
|
|
150
211
|
|
|
151
|
-
Use
|
|
212
|
+
Use gateway-style ids: `<provider>/<model>`.
|
|
152
213
|
|
|
153
214
|
Examples:
|
|
154
215
|
|
|
@@ -159,104 +220,54 @@ Examples:
|
|
|
159
220
|
- `zai/glm-4.7`
|
|
160
221
|
- `openrouter/openai/gpt-5-mini` (force OpenRouter)
|
|
161
222
|
|
|
162
|
-
Note: some models/providers
|
|
163
|
-
|
|
164
|
-
## Output length
|
|
165
|
-
|
|
166
|
-
`--length` controls *how much output we ask for* (guideline), not a hard truncation.
|
|
167
|
-
|
|
168
|
-
```bash
|
|
169
|
-
npx -y @steipete/summarize "https://example.com" --length long
|
|
170
|
-
npx -y @steipete/summarize "https://example.com" --length 20k
|
|
171
|
-
```
|
|
223
|
+
Note: some models/providers do not support streaming or certain file media types. When that happens, the CLI prints a friendly error (or auto-disables streaming for that model when supported by the provider).
|
|
172
224
|
|
|
173
|
-
|
|
174
|
-
- Character targets: `1500`, `20k`, `20000`
|
|
175
|
-
- Optional hard cap: `--max-output-tokens <count>` (e.g. `2000`, `2k`)
|
|
176
|
-
- Provider/model APIs still enforce their own maximum output limits.
|
|
177
|
-
- If omitted, no max token parameter is sent (provider default).
|
|
178
|
-
- Prefer `--length` unless you need a hard cap (some providers count “reasoning” into the cap).
|
|
179
|
-
- Minimums: `--length` numeric values must be ≥ 50 chars; `--max-output-tokens` must be ≥ 16.
|
|
180
|
-
- Preset targets (source of truth: `packages/core/src/prompts/summary-lengths.ts`):
|
|
181
|
-
- short: target ~900 chars (range 600-1,200)
|
|
182
|
-
- medium: target ~1,800 chars (range 1,200-2,500)
|
|
183
|
-
- long: target ~4,200 chars (range 2,500-6,000)
|
|
184
|
-
- xl: target ~9,000 chars (range 6,000-14,000)
|
|
185
|
-
- xxl: target ~17,000 chars (range 14,000-22,000)
|
|
186
|
-
|
|
187
|
-
## Limits
|
|
225
|
+
### Limits
|
|
188
226
|
|
|
189
227
|
- Text inputs over 10 MB are rejected before tokenization.
|
|
190
|
-
- Text prompts are preflighted against the model
|
|
228
|
+
- Text prompts are preflighted against the model input limit (LiteLLM catalog), using a GPT tokenizer.
|
|
191
229
|
|
|
192
|
-
|
|
230
|
+
### Common flags
|
|
193
231
|
|
|
194
232
|
```bash
|
|
195
|
-
|
|
233
|
+
summarize <input> [flags]
|
|
196
234
|
```
|
|
197
235
|
|
|
198
236
|
Use `summarize --help` or `summarize help` for the full help text.
|
|
199
237
|
|
|
200
238
|
- `--model <provider/model>`: which model to use (defaults to `auto`)
|
|
201
239
|
- `--model auto`: automatic model selection + fallback (default)
|
|
202
|
-
- `--model <name>`: use a config-defined model (see
|
|
240
|
+
- `--model <name>`: use a config-defined model (see Configuration)
|
|
203
241
|
- `--timeout <duration>`: `30s`, `2m`, `5000ms` (default `2m`)
|
|
204
242
|
- `--retries <count>`: LLM retry attempts on timeout (default `1`)
|
|
205
243
|
- `--length short|medium|long|xl|xxl|s|m|l|<chars>`
|
|
206
|
-
- `--language, --lang <language>`: output language (`auto` = match source
|
|
207
|
-
- `--max-output-tokens <count>`: hard cap for LLM output tokens
|
|
208
|
-
- `--cli [provider]`: use a CLI provider (
|
|
244
|
+
- `--language, --lang <language>`: output language (`auto` = match source)
|
|
245
|
+
- `--max-output-tokens <count>`: hard cap for LLM output tokens
|
|
246
|
+
- `--cli [provider]`: use a CLI provider (`--model cli/<provider>`). If omitted, uses auto selection with CLI enabled.
|
|
209
247
|
- `--stream auto|on|off`: stream LLM output (`auto` = TTY only; disabled in `--json` mode)
|
|
210
|
-
- `--plain`:
|
|
248
|
+
- `--plain`: keep raw output (no ANSI/OSC Markdown rendering)
|
|
211
249
|
- `--no-color`: disable ANSI colors
|
|
250
|
+
- `--theme <name>`: CLI theme (`aurora`, `ember`, `moss`, `mono`)
|
|
212
251
|
- `--format md|text`: website/file content format (default `text`)
|
|
213
|
-
- `--markdown-mode off|auto|llm|readability`: Markdown
|
|
214
|
-
- `--preprocess off|auto|always`: controls `uvx markitdown` usage (default `auto
|
|
252
|
+
- `--markdown-mode off|auto|llm|readability`: HTML -> Markdown mode (default `readability`)
|
|
253
|
+
- `--preprocess off|auto|always`: controls `uvx markitdown` usage (default `auto`)
|
|
215
254
|
- Install `uvx`: `brew install uv` (or https://astral.sh/uv/)
|
|
216
|
-
- `--extract`: print extracted content and exit (
|
|
255
|
+
- `--extract`: print extracted content and exit (URLs only)
|
|
217
256
|
- Deprecated alias: `--extract-only`
|
|
257
|
+
- `--slides`: extract slides for YouTube/direct video URLs and render them inline in the summary narrative (auto-renders inline in supported terminals)
|
|
258
|
+
- `--slides-ocr`: run OCR on extracted slides (requires `tesseract`)
|
|
259
|
+
- `--slides-dir <dir>`: base output dir for slide images (default `./slides`)
|
|
260
|
+
- `--slides-scene-threshold <value>`: scene detection threshold (0.1-1.0)
|
|
261
|
+
- `--slides-max <count>`: maximum slides to extract (default `6`)
|
|
262
|
+
- `--slides-min-duration <seconds>`: minimum seconds between slides
|
|
218
263
|
- `--json`: machine-readable output with diagnostics, prompt, `metrics`, and optional summary
|
|
219
264
|
- `--verbose`: debug/diagnostics on stderr
|
|
220
|
-
- `--metrics off|on|detailed`: metrics output (default `on
|
|
265
|
+
- `--metrics off|on|detailed`: metrics output (default `on`)
|
|
221
266
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
Run: `summarize <url>`
|
|
225
|
-
|
|
226
|
-
- Apple Podcasts
|
|
227
|
-
- Spotify
|
|
228
|
-
- Amazon Music / Audible podcast pages
|
|
229
|
-
- Podbean
|
|
230
|
-
- Podchaser
|
|
231
|
-
- RSS feeds (Podcasting 2.0 transcripts when available)
|
|
232
|
-
- Embedded YouTube podcast pages (e.g. JREPodcast)
|
|
233
|
-
|
|
234
|
-
Transcription: prefers local `whisper.cpp` when installed; otherwise uses OpenAI Whisper or FAL when keys are set.
|
|
235
|
-
|
|
236
|
-
## Translation paths
|
|
237
|
-
|
|
238
|
-
`--language/--lang` controls the *output language* of the summary (and other LLM-generated text). Default is `auto` (match source language).
|
|
239
|
-
|
|
240
|
-
When the input is audio/video, the CLI needs a transcript first. The transcript comes from one of these paths:
|
|
241
|
-
|
|
242
|
-
1. **Existing transcript (preferred)**
|
|
243
|
-
- YouTube: uses `youtubei` / `captionTracks` when available.
|
|
244
|
-
- Podcasts: uses Podcasting 2.0 RSS `<podcast:transcript>` (JSON/VTT) when the feed publishes it.
|
|
245
|
-
2. **Whisper transcription (fallback)**
|
|
246
|
-
- YouTube: falls back to `yt-dlp` (audio download) + Whisper transcription when configured; Apify is a last-last resort (requires `APIFY_API_TOKEN`).
|
|
247
|
-
- Prefers local `whisper.cpp` when installed + model available.
|
|
248
|
-
- Otherwise uses cloud Whisper (OpenAI `OPENAI_API_KEY`) or FAL (`FAL_KEY`) depending on configuration.
|
|
249
|
-
|
|
250
|
-
For “any video/audio file” (local path or direct media URL), use `--video-mode transcript` to force “transcribe → summarize”:
|
|
251
|
-
|
|
252
|
-
```bash
|
|
253
|
-
summarize /path/to/file.mp4 --video-mode transcript --lang en
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
## Auto model ordering
|
|
267
|
+
### Auto model ordering
|
|
257
268
|
|
|
258
269
|
`--model auto` builds candidate attempts from built-in rules (or your `model.rules` overrides).
|
|
259
|
-
CLI tools are
|
|
270
|
+
CLI tools are not used in auto mode unless you enable them via `cli.enabled` in config.
|
|
260
271
|
Why: CLI adds ~4s latency per attempt and higher variance.
|
|
261
272
|
Shortcut: `--cli` (with no provider) uses auto selection with CLI enabled.
|
|
262
273
|
|
|
@@ -280,28 +291,31 @@ Disable CLI attempts:
|
|
|
280
291
|
}
|
|
281
292
|
```
|
|
282
293
|
|
|
283
|
-
Note: when `cli.enabled` is set, it
|
|
294
|
+
Note: when `cli.enabled` is set, it is also an allowlist for explicit `--cli` / `--model cli/...`.
|
|
284
295
|
|
|
285
|
-
|
|
296
|
+
### Website extraction (Firecrawl + Markdown)
|
|
286
297
|
|
|
287
|
-
Non-YouTube URLs go through a
|
|
298
|
+
Non-YouTube URLs go through a fetch -> extract pipeline. When direct fetch/extraction is blocked or too thin,
|
|
299
|
+
`--firecrawl auto` can fall back to Firecrawl (if configured).
|
|
288
300
|
|
|
289
301
|
- `--firecrawl off|auto|always` (default `auto`)
|
|
290
302
|
- `--extract --format md|text` (default `text`; if `--format` is omitted, `--extract` defaults to `md` for non-YouTube URLs)
|
|
291
|
-
- `--markdown-mode off|auto|llm|readability` (default `readability
|
|
303
|
+
- `--markdown-mode off|auto|llm|readability` (default `readability`)
|
|
292
304
|
- `auto`: use an LLM converter when configured; may fall back to `uvx markitdown`
|
|
293
305
|
- `llm`: force LLM conversion (requires a configured model key)
|
|
294
306
|
- `off`: disable LLM conversion (still may return Firecrawl Markdown when configured)
|
|
295
307
|
- Plain-text mode: use `--format text`.
|
|
296
308
|
|
|
297
|
-
|
|
309
|
+
### YouTube transcripts
|
|
298
310
|
|
|
299
|
-
`--youtube auto` tries best-effort web transcript endpoints first. When captions
|
|
311
|
+
`--youtube auto` tries best-effort web transcript endpoints first. When captions are not available, it falls back to:
|
|
300
312
|
|
|
301
|
-
1.
|
|
302
|
-
2.
|
|
313
|
+
1. Apify (if `APIFY_API_TOKEN` is set): uses a scraping actor (`faVsWy9VTSNVIhWpR`)
|
|
314
|
+
2. yt-dlp + Whisper (if `yt-dlp` is available): downloads audio, then transcribes with local `whisper.cpp` when installed
|
|
315
|
+
(preferred), otherwise falls back to OpenAI (`OPENAI_API_KEY`) or FAL (`FAL_KEY`)
|
|
303
316
|
|
|
304
317
|
Environment variables for yt-dlp mode:
|
|
318
|
+
|
|
305
319
|
- `YT_DLP_PATH` - optional path to yt-dlp binary (otherwise `yt-dlp` is resolved via `PATH`)
|
|
306
320
|
- `SUMMARIZE_WHISPER_CPP_MODEL_PATH` - optional override for the local `whisper.cpp` model file
|
|
307
321
|
- `SUMMARIZE_WHISPER_CPP_BINARY` - optional override for the local binary (default: `whisper-cli`)
|
|
@@ -311,17 +325,82 @@ Environment variables for yt-dlp mode:
|
|
|
311
325
|
|
|
312
326
|
Apify costs money but tends to be more reliable when captions exist.
|
|
313
327
|
|
|
328
|
+
### Slide extraction (YouTube + direct video URLs)
|
|
329
|
+
|
|
330
|
+
Extract slide screenshots (scene detection via `ffmpeg`) and optional OCR:
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
summarize "https://www.youtube.com/watch?v=..." --slides
|
|
334
|
+
summarize "https://www.youtube.com/watch?v=..." --slides --slides-ocr
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
Outputs are written under `./slides/<sourceId>/` (or `--slides-dir`). OCR results are included in JSON output
|
|
338
|
+
(`--json`) and stored in `slides.json` inside the slide directory. When scene detection is too sparse, the
|
|
339
|
+
extractor also samples at a fixed interval to improve coverage.
|
|
340
|
+
When using `--slides`, supported terminals (kitty/iTerm/Konsole) render inline thumbnails automatically inside the
|
|
341
|
+
summary narrative (the model inserts `[slide:N]` markers). Timestamp links are clickable when the terminal supports
|
|
342
|
+
OSC-8 (YouTube/Vimeo/Loom/Dropbox). If inline images are unsupported, Summarize prints a note with the on-disk
|
|
343
|
+
slide directory.
|
|
344
|
+
|
|
345
|
+
Use `--slides --extract` to print the full timed transcript and insert slide images inline at matching timestamps.
|
|
346
|
+
|
|
314
347
|
Format the extracted transcript as Markdown (headings + paragraphs) via an LLM:
|
|
315
348
|
|
|
316
349
|
```bash
|
|
317
350
|
summarize "https://www.youtube.com/watch?v=..." --extract --format md --markdown-mode llm
|
|
318
351
|
```
|
|
319
352
|
|
|
320
|
-
|
|
353
|
+
### Media transcription (Whisper)
|
|
354
|
+
|
|
355
|
+
Local audio/video files are transcribed first, then summarized. `--video-mode transcript` forces
|
|
356
|
+
direct media URLs (and embedded media) through Whisper first. Prefers local `whisper.cpp` when available; otherwise requires
|
|
357
|
+
`OPENAI_API_KEY` or `FAL_KEY`.
|
|
321
358
|
|
|
322
|
-
|
|
359
|
+
### Local ONNX transcription (Parakeet/Canary)
|
|
323
360
|
|
|
324
|
-
|
|
361
|
+
Summarize can use NVIDIA Parakeet/Canary ONNX models via a local CLI you provide. Auto selection (default) prefers ONNX when configured.
|
|
362
|
+
|
|
363
|
+
- Setup helper: `summarize transcriber setup`
|
|
364
|
+
- Install `sherpa-onnx` from upstream binaries/build (Homebrew may not have a formula)
|
|
365
|
+
- Auto selection: set `SUMMARIZE_ONNX_PARAKEET_CMD` or `SUMMARIZE_ONNX_CANARY_CMD` (no flag needed)
|
|
366
|
+
- Force a model: `--transcriber parakeet|canary|whisper|auto`
|
|
367
|
+
- Docs: `docs/nvidia-onnx-transcription.md`
|
|
368
|
+
|
|
369
|
+
### Verified podcast services (2025-12-25)
|
|
370
|
+
|
|
371
|
+
Run: `summarize <url>`
|
|
372
|
+
|
|
373
|
+
- Apple Podcasts
|
|
374
|
+
- Spotify
|
|
375
|
+
- Amazon Music / Audible podcast pages
|
|
376
|
+
- Podbean
|
|
377
|
+
- Podchaser
|
|
378
|
+
- RSS feeds (Podcasting 2.0 transcripts when available)
|
|
379
|
+
- Embedded YouTube podcast pages (e.g. JREPodcast)
|
|
380
|
+
|
|
381
|
+
Transcription: prefers local `whisper.cpp` when installed; otherwise uses OpenAI Whisper or FAL when keys are set.
|
|
382
|
+
|
|
383
|
+
### Translation paths
|
|
384
|
+
|
|
385
|
+
`--language/--lang` controls the output language of the summary (and other LLM-generated text). Default is `auto`.
|
|
386
|
+
|
|
387
|
+
When the input is audio/video, the CLI needs a transcript first. The transcript comes from one of these paths:
|
|
388
|
+
|
|
389
|
+
1. Existing transcript (preferred)
|
|
390
|
+
- YouTube: uses `youtubei` / `captionTracks` when available.
|
|
391
|
+
- Podcasts: uses Podcasting 2.0 RSS `<podcast:transcript>` (JSON/VTT) when the feed publishes it.
|
|
392
|
+
2. Whisper transcription (fallback)
|
|
393
|
+
- YouTube: falls back to yt-dlp (audio download) + Whisper transcription when configured; Apify is a last resort.
|
|
394
|
+
- Prefers local `whisper.cpp` when installed + model available.
|
|
395
|
+
- Otherwise uses cloud Whisper (OpenAI `OPENAI_API_KEY`) or FAL (`FAL_KEY`).
|
|
396
|
+
|
|
397
|
+
For direct media URLs, use `--video-mode transcript` to force transcribe -> summarize:
|
|
398
|
+
|
|
399
|
+
```bash
|
|
400
|
+
summarize https://example.com/file.mp4 --video-mode transcript --lang en
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Configuration
|
|
325
404
|
|
|
326
405
|
Single config location:
|
|
327
406
|
|
|
@@ -331,7 +410,8 @@ Supported keys today:
|
|
|
331
410
|
|
|
332
411
|
```json
|
|
333
412
|
{
|
|
334
|
-
"model": { "id": "openai/gpt-5-mini" }
|
|
413
|
+
"model": { "id": "openai/gpt-5-mini" },
|
|
414
|
+
"ui": { "theme": "ember" }
|
|
335
415
|
}
|
|
336
416
|
```
|
|
337
417
|
|
|
@@ -345,14 +425,28 @@ Shorthand (equivalent):
|
|
|
345
425
|
|
|
346
426
|
Also supported:
|
|
347
427
|
|
|
348
|
-
- `model: { "mode": "auto" }` (automatic model selection + fallback; see
|
|
428
|
+
- `model: { "mode": "auto" }` (automatic model selection + fallback; see [docs/model-auto.md](docs/model-auto.md))
|
|
349
429
|
- `model.rules` (customize candidates / ordering)
|
|
350
430
|
- `models` (define presets selectable via `--model <preset>`)
|
|
431
|
+
- `cache.media` (media download cache: TTL 7 days, 2048 MB cap by default; `--no-media-cache` disables)
|
|
351
432
|
- `media.videoMode: "auto"|"transcript"|"understand"`
|
|
433
|
+
- `slides.enabled` / `slides.max` / `slides.ocr` / `slides.dir` (defaults for `--slides`)
|
|
434
|
+
- `ui.theme: "aurora"|"ember"|"moss"|"mono"`
|
|
352
435
|
- `openai.useChatCompletions: true` (force OpenAI-compatible chat completions)
|
|
353
436
|
|
|
354
|
-
Note: the config is parsed leniently (JSON5), but
|
|
355
|
-
|
|
437
|
+
Note: the config is parsed leniently (JSON5), but comments are not allowed. Unknown keys are ignored.
|
|
438
|
+
|
|
439
|
+
Media cache defaults:
|
|
440
|
+
|
|
441
|
+
```json
|
|
442
|
+
{
|
|
443
|
+
"cache": {
|
|
444
|
+
"media": { "enabled": true, "ttlDays": 7, "maxMb": 2048, "verify": "size" }
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
Note: `--no-cache` bypasses summary caching only (LLM output). Extract/transcript caches still apply. Use `--no-media-cache` to skip media files.
|
|
356
450
|
|
|
357
451
|
Precedence:
|
|
358
452
|
|
|
@@ -361,7 +455,14 @@ Precedence:
|
|
|
361
455
|
3) `~/.summarize/config.json`
|
|
362
456
|
4) default (`auto`)
|
|
363
457
|
|
|
364
|
-
|
|
458
|
+
Theme precedence:
|
|
459
|
+
|
|
460
|
+
1) `--theme`
|
|
461
|
+
2) `SUMMARIZE_THEME`
|
|
462
|
+
3) `~/.summarize/config.json` (`ui.theme`)
|
|
463
|
+
4) default (`aurora`)
|
|
464
|
+
|
|
465
|
+
### Environment variables
|
|
365
466
|
|
|
366
467
|
Set the key matching your chosen `--model`:
|
|
367
468
|
|
|
@@ -369,43 +470,44 @@ Set the key matching your chosen `--model`:
|
|
|
369
470
|
- `ANTHROPIC_API_KEY` (for `anthropic/...`)
|
|
370
471
|
- `XAI_API_KEY` (for `xai/...`)
|
|
371
472
|
- `Z_AI_API_KEY` (for `zai/...`; supports `ZAI_API_KEY` alias)
|
|
372
|
-
- `GEMINI_API_KEY` (for `google/...`)
|
|
473
|
+
- `GEMINI_API_KEY` (for `google/...`)
|
|
373
474
|
- also accepts `GOOGLE_GENERATIVE_AI_API_KEY` and `GOOGLE_API_KEY` as aliases
|
|
374
475
|
|
|
375
476
|
OpenAI-compatible chat completions toggle:
|
|
376
477
|
|
|
377
478
|
- `OPENAI_USE_CHAT_COMPLETIONS=1` (or set `openai.useChatCompletions` in config)
|
|
378
479
|
|
|
480
|
+
UI theme:
|
|
481
|
+
|
|
482
|
+
- `SUMMARIZE_THEME=aurora|ember|moss|mono`
|
|
483
|
+
- `SUMMARIZE_TRUECOLOR=1` (force 24-bit ANSI)
|
|
484
|
+
- `SUMMARIZE_NO_TRUECOLOR=1` (disable 24-bit ANSI)
|
|
485
|
+
|
|
379
486
|
OpenRouter (OpenAI-compatible):
|
|
380
487
|
|
|
381
488
|
- Set `OPENROUTER_API_KEY=...`
|
|
382
|
-
- Prefer forcing OpenRouter per model id: `--model openrouter/<author>/<slug>`
|
|
383
|
-
- Built-in preset: `--model free` (uses a default set of OpenRouter `:free` models)
|
|
489
|
+
- Prefer forcing OpenRouter per model id: `--model openrouter/<author>/<slug>`
|
|
490
|
+
- Built-in preset: `--model free` (uses a default set of OpenRouter `:free` models)
|
|
384
491
|
|
|
385
492
|
### `summarize refresh-free`
|
|
386
493
|
|
|
387
494
|
Quick start: make free the default (keep `auto` available)
|
|
388
495
|
|
|
389
496
|
```bash
|
|
390
|
-
# writes ~/.summarize/config.json (models.free) and sets model="free"
|
|
391
497
|
summarize refresh-free --set-default
|
|
392
|
-
|
|
393
|
-
# now this defaults to free models
|
|
394
498
|
summarize "https://example.com"
|
|
395
|
-
|
|
396
|
-
# whenever you want best quality instead
|
|
397
499
|
summarize "https://example.com" --model auto
|
|
398
500
|
```
|
|
399
501
|
|
|
400
|
-
Regenerates the `free` preset (
|
|
502
|
+
Regenerates the `free` preset (`models.free` in `~/.summarize/config.json`) by:
|
|
401
503
|
|
|
402
504
|
- Fetching OpenRouter `/models`, filtering `:free`
|
|
403
|
-
- Skipping models that look very small (<27B by default) based on the model id/name
|
|
505
|
+
- Skipping models that look very small (<27B by default) based on the model id/name
|
|
404
506
|
- Testing which ones return non-empty text (concurrency 4, timeout 10s)
|
|
405
|
-
- Picking a mix of
|
|
406
|
-
- Refining timings
|
|
507
|
+
- Picking a mix of smart-ish (bigger `context_length` / output cap) and fast models
|
|
508
|
+
- Refining timings and writing the sorted list back
|
|
407
509
|
|
|
408
|
-
If `--model free` stops working
|
|
510
|
+
If `--model free` stops working, run:
|
|
409
511
|
|
|
410
512
|
```bash
|
|
411
513
|
summarize refresh-free
|
|
@@ -414,7 +516,7 @@ summarize refresh-free
|
|
|
414
516
|
Flags:
|
|
415
517
|
|
|
416
518
|
- `--runs 2` (default): extra timing runs per selected model (total runs = 1 + runs)
|
|
417
|
-
- `--smart 3` (default): how many
|
|
519
|
+
- `--smart 3` (default): how many smart-first picks (rest filled by fastest)
|
|
418
520
|
- `--min-params 27b` (default): ignore models with inferred size smaller than N billion parameters
|
|
419
521
|
- `--max-age-days 180` (default): ignore models older than N days (set 0 to disable)
|
|
420
522
|
- `--set-default`: also sets `"model": "free"` in `~/.summarize/config.json`
|
|
@@ -426,7 +528,7 @@ OPENROUTER_API_KEY=sk-or-... summarize "https://example.com" --model openrouter/
|
|
|
426
528
|
```
|
|
427
529
|
|
|
428
530
|
If your OpenRouter account enforces an allowed-provider list, make sure at least one provider
|
|
429
|
-
is allowed for the selected model.
|
|
531
|
+
is allowed for the selected model. When routing fails, `summarize` prints the exact providers to allow.
|
|
430
532
|
|
|
431
533
|
Legacy: `OPENAI_BASE_URL=https://openrouter.ai/api/v1` (and either `OPENAI_API_KEY` or `OPENROUTER_API_KEY`) also works.
|
|
432
534
|
|
|
@@ -442,14 +544,14 @@ Optional services:
|
|
|
442
544
|
- `FAL_KEY` (FAL AI API key for audio transcription via Whisper)
|
|
443
545
|
- `APIFY_API_TOKEN` (YouTube transcript fallback)
|
|
444
546
|
|
|
445
|
-
|
|
547
|
+
### Model limits
|
|
446
548
|
|
|
447
549
|
The CLI uses the LiteLLM model catalog for model limits (like max output tokens):
|
|
448
550
|
|
|
449
551
|
- Downloaded from: `https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json`
|
|
450
552
|
- Cached at: `~/.summarize/cache/`
|
|
451
553
|
|
|
452
|
-
|
|
554
|
+
### Library usage (optional)
|
|
453
555
|
|
|
454
556
|
Recommended (minimal deps):
|
|
455
557
|
|
|
@@ -461,9 +563,30 @@ Compatibility (pulls in CLI deps):
|
|
|
461
563
|
- `@steipete/summarize/content`
|
|
462
564
|
- `@steipete/summarize/prompts`
|
|
463
565
|
|
|
464
|
-
|
|
566
|
+
### Development
|
|
465
567
|
|
|
466
568
|
```bash
|
|
467
569
|
pnpm install
|
|
468
570
|
pnpm check
|
|
469
571
|
```
|
|
572
|
+
|
|
573
|
+
## More
|
|
574
|
+
|
|
575
|
+
- Docs index: [docs/README.md](docs/README.md)
|
|
576
|
+
- CLI providers and config: [docs/cli.md](docs/cli.md)
|
|
577
|
+
- Auto model rules: [docs/model-auto.md](docs/model-auto.md)
|
|
578
|
+
- Website extraction: [docs/website.md](docs/website.md)
|
|
579
|
+
- YouTube handling: [docs/youtube.md](docs/youtube.md)
|
|
580
|
+
- Media pipeline: [docs/media.md](docs/media.md)
|
|
581
|
+
- Config schema and precedence: [docs/config.md](docs/config.md)
|
|
582
|
+
|
|
583
|
+
## Troubleshooting
|
|
584
|
+
|
|
585
|
+
- "Receiving end does not exist": Chrome did not inject the content script yet.
|
|
586
|
+
- Extension details -> Site access -> On all sites (or allow this domain)
|
|
587
|
+
- Reload the tab once.
|
|
588
|
+
- "Failed to fetch" / daemon unreachable:
|
|
589
|
+
- `summarize daemon status`
|
|
590
|
+
- Logs: `~/.summarize/logs/daemon.err.log`
|
|
591
|
+
|
|
592
|
+
License: MIT
|