@steipete/summarize 0.10.0 → 0.11.1
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 +80 -28
- package/README.md +115 -30
- package/dist/cli.js +1 -1
- package/dist/esm/cache.js +67 -65
- package/dist/esm/cache.js.map +1 -1
- package/dist/esm/cli-main.js +27 -27
- package/dist/esm/cli-main.js.map +1 -1
- package/dist/esm/cli.js +2 -2
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/config.js +310 -166
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/content/asset.js +53 -50
- package/dist/esm/content/asset.js.map +1 -1
- package/dist/esm/content/index.js +1 -1
- package/dist/esm/content/index.js.map +1 -1
- package/dist/esm/costs.js +1 -1
- package/dist/esm/costs.js.map +1 -1
- package/dist/esm/daemon/agent.js +165 -164
- package/dist/esm/daemon/agent.js.map +1 -1
- package/dist/esm/daemon/auto-mode.js +3 -3
- package/dist/esm/daemon/auto-mode.js.map +1 -1
- package/dist/esm/daemon/chat.js +16 -14
- package/dist/esm/daemon/chat.js.map +1 -1
- package/dist/esm/daemon/cli-entrypoint.js +72 -0
- package/dist/esm/daemon/cli-entrypoint.js.map +1 -0
- package/dist/esm/daemon/cli.js +63 -87
- package/dist/esm/daemon/cli.js.map +1 -1
- package/dist/esm/daemon/config.js +15 -15
- package/dist/esm/daemon/config.js.map +1 -1
- package/dist/esm/daemon/constants.js +6 -6
- package/dist/esm/daemon/constants.js.map +1 -1
- package/dist/esm/daemon/env-merge.js.map +1 -1
- package/dist/esm/daemon/env-snapshot.js +36 -31
- package/dist/esm/daemon/env-snapshot.js.map +1 -1
- package/dist/esm/daemon/flow-context.js +59 -28
- package/dist/esm/daemon/flow-context.js.map +1 -1
- package/dist/esm/daemon/launchd.js +100 -55
- package/dist/esm/daemon/launchd.js.map +1 -1
- package/dist/esm/daemon/meta.js +5 -5
- package/dist/esm/daemon/meta.js.map +1 -1
- package/dist/esm/daemon/models.js +54 -31
- package/dist/esm/daemon/models.js.map +1 -1
- package/dist/esm/daemon/process-registry.js +15 -15
- package/dist/esm/daemon/process-registry.js.map +1 -1
- package/dist/esm/daemon/schtasks.js +42 -42
- package/dist/esm/daemon/schtasks.js.map +1 -1
- package/dist/esm/daemon/server.js +248 -244
- package/dist/esm/daemon/server.js.map +1 -1
- package/dist/esm/daemon/summarize-progress.js +11 -11
- package/dist/esm/daemon/summarize-progress.js.map +1 -1
- package/dist/esm/daemon/summarize.js +29 -29
- package/dist/esm/daemon/summarize.js.map +1 -1
- package/dist/esm/daemon/systemd.js +47 -47
- package/dist/esm/daemon/systemd.js.map +1 -1
- package/dist/esm/firecrawl.js +12 -12
- package/dist/esm/firecrawl.js.map +1 -1
- package/dist/esm/flags.js +32 -32
- package/dist/esm/flags.js.map +1 -1
- package/dist/esm/index.js +3 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/language.js +1 -1
- package/dist/esm/language.js.map +1 -1
- package/dist/esm/llm/cli.js +128 -64
- package/dist/esm/llm/cli.js.map +1 -1
- package/dist/esm/llm/errors.js +1 -1
- package/dist/esm/llm/errors.js.map +1 -1
- package/dist/esm/llm/generate-text.js +107 -98
- package/dist/esm/llm/generate-text.js.map +1 -1
- package/dist/esm/llm/google-models.js +17 -17
- package/dist/esm/llm/google-models.js.map +1 -1
- package/dist/esm/llm/html-to-markdown.js +3 -3
- package/dist/esm/llm/html-to-markdown.js.map +1 -1
- package/dist/esm/llm/model-id.js +38 -16
- package/dist/esm/llm/model-id.js.map +1 -1
- package/dist/esm/llm/prompt.js +5 -5
- package/dist/esm/llm/prompt.js.map +1 -1
- package/dist/esm/llm/providers/anthropic.js +33 -33
- package/dist/esm/llm/providers/anthropic.js.map +1 -1
- package/dist/esm/llm/providers/google.js +19 -19
- package/dist/esm/llm/providers/google.js.map +1 -1
- package/dist/esm/llm/providers/models.js +30 -30
- package/dist/esm/llm/providers/models.js.map +1 -1
- package/dist/esm/llm/providers/openai.js +35 -34
- package/dist/esm/llm/providers/openai.js.map +1 -1
- package/dist/esm/llm/providers/shared.js +8 -8
- package/dist/esm/llm/providers/shared.js.map +1 -1
- package/dist/esm/llm/transcript-to-markdown.js +9 -5
- package/dist/esm/llm/transcript-to-markdown.js.map +1 -1
- package/dist/esm/llm/usage.js +18 -18
- package/dist/esm/llm/usage.js.map +1 -1
- package/dist/esm/logging/daemon.js +21 -21
- package/dist/esm/logging/daemon.js.map +1 -1
- package/dist/esm/logging/ring-file.js +5 -5
- package/dist/esm/logging/ring-file.js.map +1 -1
- package/dist/esm/markitdown.js +21 -19
- package/dist/esm/markitdown.js.map +1 -1
- package/dist/esm/media-cache.js +39 -39
- package/dist/esm/media-cache.js.map +1 -1
- package/dist/esm/model-auto.js +175 -106
- package/dist/esm/model-auto.js.map +1 -1
- package/dist/esm/model-spec.js +52 -42
- package/dist/esm/model-spec.js.map +1 -1
- package/dist/esm/pricing/litellm.js +4 -4
- package/dist/esm/pricing/litellm.js.map +1 -1
- package/dist/esm/processes.js +1 -1
- package/dist/esm/processes.js.map +1 -1
- package/dist/esm/prompts/index.js +1 -1
- package/dist/esm/prompts/index.js.map +1 -1
- package/dist/esm/refresh-free.js +81 -81
- package/dist/esm/refresh-free.js.map +1 -1
- package/dist/esm/run/attachments.js +47 -44
- package/dist/esm/run/attachments.js.map +1 -1
- package/dist/esm/run/bird.js +26 -26
- package/dist/esm/run/bird.js.map +1 -1
- package/dist/esm/run/cache-state.js +7 -7
- package/dist/esm/run/cache-state.js.map +1 -1
- package/dist/esm/run/cli-fallback-state.js +45 -0
- package/dist/esm/run/cli-fallback-state.js.map +1 -0
- package/dist/esm/run/cli-preflight.js +24 -24
- package/dist/esm/run/cli-preflight.js.map +1 -1
- package/dist/esm/run/constants.js +12 -12
- package/dist/esm/run/constants.js.map +1 -1
- package/dist/esm/run/cookies/twitter.js +47 -47
- package/dist/esm/run/cookies/twitter.js.map +1 -1
- package/dist/esm/run/env.js +21 -15
- package/dist/esm/run/env.js.map +1 -1
- package/dist/esm/run/fetch-with-timeout.js +4 -4
- package/dist/esm/run/fetch-with-timeout.js.map +1 -1
- package/dist/esm/run/finish-line.js +68 -68
- package/dist/esm/run/finish-line.js.map +1 -1
- package/dist/esm/run/flows/asset/extract.js +15 -15
- package/dist/esm/run/flows/asset/extract.js.map +1 -1
- package/dist/esm/run/flows/asset/input.js +47 -66
- package/dist/esm/run/flows/asset/input.js.map +1 -1
- package/dist/esm/run/flows/asset/media-policy.js +1 -1
- package/dist/esm/run/flows/asset/media-policy.js.map +1 -1
- package/dist/esm/run/flows/asset/media.js +49 -40
- package/dist/esm/run/flows/asset/media.js.map +1 -1
- package/dist/esm/run/flows/asset/output.js +12 -12
- package/dist/esm/run/flows/asset/output.js.map +1 -1
- package/dist/esm/run/flows/asset/preprocess.js +79 -44
- package/dist/esm/run/flows/asset/preprocess.js.map +1 -1
- package/dist/esm/run/flows/asset/summary.js +173 -106
- package/dist/esm/run/flows/asset/summary.js.map +1 -1
- package/dist/esm/run/flows/url/extract.js +26 -26
- package/dist/esm/run/flows/url/extract.js.map +1 -1
- package/dist/esm/run/flows/url/flow.js +104 -98
- package/dist/esm/run/flows/url/flow.js.map +1 -1
- package/dist/esm/run/flows/url/markdown.js +57 -57
- package/dist/esm/run/flows/url/markdown.js.map +1 -1
- package/dist/esm/run/flows/url/slides-output.js +61 -59
- package/dist/esm/run/flows/url/slides-output.js.map +1 -1
- package/dist/esm/run/flows/url/slides-text.js +85 -85
- package/dist/esm/run/flows/url/slides-text.js.map +1 -1
- package/dist/esm/run/flows/url/summary.js +174 -107
- package/dist/esm/run/flows/url/summary.js.map +1 -1
- package/dist/esm/run/format.js +10 -10
- package/dist/esm/run/format.js.map +1 -1
- package/dist/esm/run/help.js +141 -135
- package/dist/esm/run/help.js.map +1 -1
- package/dist/esm/run/logging.js +10 -10
- package/dist/esm/run/logging.js.map +1 -1
- package/dist/esm/run/markdown.js +12 -12
- package/dist/esm/run/markdown.js.map +1 -1
- package/dist/esm/run/media-cache-state.js +5 -5
- package/dist/esm/run/media-cache-state.js.map +1 -1
- package/dist/esm/run/model-attempts.js.map +1 -1
- package/dist/esm/run/openrouter.js +11 -11
- package/dist/esm/run/openrouter.js.map +1 -1
- package/dist/esm/run/progress.js +1 -1
- package/dist/esm/run/progress.js.map +1 -1
- package/dist/esm/run/run-config.js +16 -16
- package/dist/esm/run/run-config.js.map +1 -1
- package/dist/esm/run/run-context.js +2 -2
- package/dist/esm/run/run-context.js.map +1 -1
- package/dist/esm/run/run-env.js +55 -54
- package/dist/esm/run/run-env.js.map +1 -1
- package/dist/esm/run/run-input.js +3 -3
- package/dist/esm/run/run-input.js.map +1 -1
- package/dist/esm/run/run-metrics.js +16 -16
- package/dist/esm/run/run-metrics.js.map +1 -1
- package/dist/esm/run/run-models.js +28 -23
- package/dist/esm/run/run-models.js.map +1 -1
- package/dist/esm/run/run-output.js +3 -3
- package/dist/esm/run/run-output.js.map +1 -1
- package/dist/esm/run/run-settings.js +83 -34
- package/dist/esm/run/run-settings.js.map +1 -1
- package/dist/esm/run/run-stream.js +4 -4
- package/dist/esm/run/run-stream.js.map +1 -1
- package/dist/esm/run/runner.js +166 -127
- package/dist/esm/run/runner.js.map +1 -1
- package/dist/esm/run/slides-cli.js +43 -42
- package/dist/esm/run/slides-cli.js.map +1 -1
- package/dist/esm/run/slides-render.js +36 -36
- package/dist/esm/run/slides-render.js.map +1 -1
- package/dist/esm/run/stdin-temp-file.js +77 -0
- package/dist/esm/run/stdin-temp-file.js.map +1 -0
- package/dist/esm/run/stream-output.js +7 -7
- package/dist/esm/run/stream-output.js.map +1 -1
- package/dist/esm/run/streaming.js +16 -16
- package/dist/esm/run/streaming.js.map +1 -1
- package/dist/esm/run/summary-engine.js +57 -51
- package/dist/esm/run/summary-engine.js.map +1 -1
- package/dist/esm/run/summary-llm.js +3 -3
- package/dist/esm/run/summary-llm.js.map +1 -1
- package/dist/esm/run/terminal.js +4 -4
- package/dist/esm/run/terminal.js.map +1 -1
- package/dist/esm/run/tips.js +2 -2
- package/dist/esm/run/tips.js.map +1 -1
- package/dist/esm/run/transcriber-cli.js +49 -49
- package/dist/esm/run/transcriber-cli.js.map +1 -1
- package/dist/esm/run.js +1 -1
- package/dist/esm/run.js.map +1 -1
- package/dist/esm/shared/contracts.js +1 -1
- package/dist/esm/shared/contracts.js.map +1 -1
- package/dist/esm/shared/sse-events.js +16 -16
- package/dist/esm/shared/sse-events.js.map +1 -1
- package/dist/esm/shared/streaming-merge.js +3 -3
- package/dist/esm/shared/streaming-merge.js.map +1 -1
- package/dist/esm/slides/extract.js +258 -249
- package/dist/esm/slides/extract.js.map +1 -1
- package/dist/esm/slides/index.js +3 -3
- package/dist/esm/slides/index.js.map +1 -1
- package/dist/esm/slides/settings.js +14 -14
- package/dist/esm/slides/settings.js.map +1 -1
- package/dist/esm/slides/store.js +9 -9
- package/dist/esm/slides/store.js.map +1 -1
- package/dist/esm/tty/format.js +13 -13
- package/dist/esm/tty/format.js.map +1 -1
- package/dist/esm/tty/osc-progress.js +1 -1
- package/dist/esm/tty/osc-progress.js.map +1 -1
- package/dist/esm/tty/progress/fetch-html.js +14 -14
- package/dist/esm/tty/progress/fetch-html.js.map +1 -1
- package/dist/esm/tty/progress/transcript.js +70 -62
- package/dist/esm/tty/progress/transcript.js.map +1 -1
- package/dist/esm/tty/spinner.js +20 -9
- package/dist/esm/tty/spinner.js.map +1 -1
- package/dist/esm/tty/theme.js +92 -92
- package/dist/esm/tty/theme.js.map +1 -1
- package/dist/esm/tty/website-progress.js +32 -32
- package/dist/esm/tty/website-progress.js.map +1 -1
- package/dist/esm/version.js +29 -29
- package/dist/esm/version.js.map +1 -1
- package/dist/types/cache.d.ts +6 -6
- package/dist/types/config.d.ts +49 -7
- package/dist/types/content/asset.d.ts +8 -6
- package/dist/types/content/index.d.ts +1 -1
- package/dist/types/costs.d.ts +3 -3
- package/dist/types/daemon/agent.d.ts +1 -1
- package/dist/types/daemon/auto-mode.d.ts +3 -3
- package/dist/types/daemon/chat.d.ts +2 -2
- package/dist/types/daemon/cli-entrypoint.d.ts +2 -0
- package/dist/types/daemon/config.d.ts +2 -2
- package/dist/types/daemon/env-merge.d.ts +1 -1
- package/dist/types/daemon/env-snapshot.d.ts +1 -1
- package/dist/types/daemon/flow-context.d.ts +7 -7
- package/dist/types/daemon/launchd.d.ts +8 -0
- package/dist/types/daemon/models.d.ts +6 -2
- package/dist/types/daemon/process-registry.d.ts +5 -5
- package/dist/types/daemon/server.d.ts +2 -2
- package/dist/types/daemon/summarize-progress.d.ts +1 -1
- package/dist/types/daemon/summarize.d.ts +7 -7
- package/dist/types/firecrawl.d.ts +1 -1
- package/dist/types/flags.d.ts +11 -11
- package/dist/types/index.d.ts +4 -4
- package/dist/types/language.d.ts +1 -1
- package/dist/types/llm/attachments.d.ts +1 -1
- package/dist/types/llm/cli.d.ts +3 -3
- package/dist/types/llm/generate-text.d.ts +7 -7
- package/dist/types/llm/html-to-markdown.d.ts +3 -3
- package/dist/types/llm/model-id.d.ts +1 -1
- package/dist/types/llm/prompt.d.ts +2 -2
- package/dist/types/llm/providers/anthropic.d.ts +3 -3
- package/dist/types/llm/providers/google.d.ts +3 -3
- package/dist/types/llm/providers/models.d.ts +2 -2
- package/dist/types/llm/providers/openai.d.ts +4 -4
- package/dist/types/llm/providers/shared.d.ts +2 -2
- package/dist/types/llm/transcript-to-markdown.d.ts +4 -2
- package/dist/types/llm/usage.d.ts +1 -1
- package/dist/types/logging/daemon.d.ts +4 -4
- package/dist/types/markitdown.d.ts +1 -1
- package/dist/types/media-cache.d.ts +2 -2
- package/dist/types/model-auto.d.ts +14 -4
- package/dist/types/model-spec.d.ts +10 -10
- package/dist/types/pricing/litellm.d.ts +1 -1
- package/dist/types/processes.d.ts +1 -1
- package/dist/types/prompts/index.d.ts +1 -1
- package/dist/types/run/attachments.d.ts +7 -7
- package/dist/types/run/bird.d.ts +2 -2
- package/dist/types/run/cache-state.d.ts +2 -2
- package/dist/types/run/cli-fallback-state.d.ts +6 -0
- package/dist/types/run/constants.d.ts +1 -1
- package/dist/types/run/cookies/twitter.d.ts +1 -1
- package/dist/types/run/env.d.ts +1 -1
- package/dist/types/run/finish-line.d.ts +5 -5
- package/dist/types/run/flows/asset/extract.d.ts +4 -4
- package/dist/types/run/flows/asset/input.d.ts +9 -3
- package/dist/types/run/flows/asset/media.d.ts +1 -1
- package/dist/types/run/flows/asset/output.d.ts +5 -5
- package/dist/types/run/flows/asset/preprocess.d.ts +23 -17
- package/dist/types/run/flows/asset/summary.d.ts +19 -17
- package/dist/types/run/flows/url/extract.d.ts +1 -1
- package/dist/types/run/flows/url/flow.d.ts +1 -1
- package/dist/types/run/flows/url/markdown.d.ts +6 -6
- package/dist/types/run/flows/url/slides-output.d.ts +7 -7
- package/dist/types/run/flows/url/slides-text.d.ts +9 -9
- package/dist/types/run/flows/url/summary.d.ts +11 -11
- package/dist/types/run/flows/url/types.d.ts +26 -22
- package/dist/types/run/format.d.ts +3 -3
- package/dist/types/run/help.d.ts +1 -1
- package/dist/types/run/media-cache-state.d.ts +2 -2
- package/dist/types/run/model-attempts.d.ts +1 -1
- package/dist/types/run/run-config.d.ts +4 -4
- package/dist/types/run/run-context.d.ts +3 -1
- package/dist/types/run/run-env.d.ts +3 -1
- package/dist/types/run/run-input.d.ts +2 -2
- package/dist/types/run/run-metrics.d.ts +3 -3
- package/dist/types/run/run-models.d.ts +3 -2
- package/dist/types/run/run-output.d.ts +1 -1
- package/dist/types/run/run-settings.d.ts +15 -6
- package/dist/types/run/run-stream.d.ts +2 -2
- package/dist/types/run/runner.d.ts +3 -2
- package/dist/types/run/slides-render.d.ts +4 -4
- package/dist/types/run/stdin-temp-file.d.ts +9 -0
- package/dist/types/run/stream-output.d.ts +1 -1
- package/dist/types/run/streaming.d.ts +4 -4
- package/dist/types/run/summary-engine.d.ts +11 -11
- package/dist/types/run/summary-llm.d.ts +5 -5
- package/dist/types/run/types.d.ts +4 -4
- package/dist/types/run.d.ts +1 -1
- package/dist/types/shared/contracts.d.ts +2 -2
- package/dist/types/shared/sse-events.d.ts +9 -9
- package/dist/types/slides/extract.d.ts +5 -4
- package/dist/types/slides/index.d.ts +5 -5
- package/dist/types/slides/store.d.ts +2 -2
- package/dist/types/slides/types.d.ts +2 -2
- package/dist/types/tty/osc-progress.d.ts +5 -5
- package/dist/types/tty/progress/fetch-html.d.ts +3 -3
- package/dist/types/tty/progress/transcript.d.ts +3 -3
- package/dist/types/tty/spinner.d.ts +2 -2
- package/dist/types/tty/theme.d.ts +2 -2
- package/dist/types/tty/website-progress.d.ts +3 -3
- package/dist/types/version.d.ts +1 -1
- package/docs/agent.md +38 -4
- package/docs/assets/site.js +46 -46
- package/docs/chrome-extension.md +11 -5
- package/docs/cli.md +59 -13
- package/docs/config.md +59 -10
- package/docs/extract-only.md +2 -0
- package/docs/index.html +33 -14
- package/docs/llm.md +7 -4
- package/docs/media.md +5 -4
- package/docs/model-auto.md +3 -2
- package/docs/nvidia-onnx-transcription.md +3 -3
- package/docs/openai.md +1 -1
- package/docs/releasing.md +3 -0
- package/docs/site/404.html +4 -1
- package/docs/site/assets/site.js +46 -46
- package/docs/site/docs/chrome-extension.html +18 -6
- package/docs/site/docs/config.html +29 -8
- package/docs/site/docs/extract-only.html +16 -4
- package/docs/site/docs/firecrawl.html +12 -3
- package/docs/site/docs/index.html +35 -6
- package/docs/site/docs/llm.html +19 -5
- package/docs/site/docs/openai.html +18 -5
- package/docs/site/docs/website.html +29 -9
- package/docs/site/docs/youtube.html +12 -3
- package/docs/site/index.html +33 -14
- package/docs/slides.md +13 -5
- package/docs/smoketest.md +29 -20
- package/docs/timestamps.md +21 -0
- package/docs/website.md +2 -1
- package/docs/youtube.md +4 -0
- package/package.json +36 -35
package/dist/esm/run/runner.js
CHANGED
|
@@ -1,41 +1,46 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import { clearCacheFiles, DEFAULT_CACHE_MAX_MB, resolveCachePath, } from
|
|
5
|
-
import { loadSummarizeConfig } from
|
|
6
|
-
import { parseExtractFormat, parseMaxExtractCharactersArg, parseMetricsMode, parseStreamMode, } from
|
|
7
|
-
import { resolveSlideSettings } from
|
|
8
|
-
import { createThemeRenderer, resolveThemeNameFromSources, resolveTrueColor } from
|
|
9
|
-
import { formatVersionLine } from
|
|
10
|
-
import { createCacheStateFromConfig } from
|
|
11
|
-
import { handleDaemonCliRequest, handleHelpRequest, handleRefreshFreeRequest, } from
|
|
12
|
-
import { parseCliProviderArg } from
|
|
13
|
-
import { extractAssetContent } from
|
|
14
|
-
import { handleFileInput, withUrlAsset } from
|
|
15
|
-
import { summarizeMediaFile as summarizeMediaFileImpl } from
|
|
16
|
-
import { outputExtractedAsset } from
|
|
17
|
-
import { summarizeAsset as summarizeAssetFlow } from
|
|
18
|
-
import { runUrlFlow } from
|
|
19
|
-
import { attachRichHelp, buildProgram } from
|
|
20
|
-
import { createMediaCacheFromConfig } from
|
|
21
|
-
import { createProgressGate } from
|
|
22
|
-
import { resolveRunContextState } from
|
|
23
|
-
import { resolveRunInput } from
|
|
24
|
-
import { createRunMetrics } from
|
|
25
|
-
import { resolveModelSelection } from
|
|
26
|
-
import { resolveDesiredOutputTokens } from
|
|
27
|
-
import { resolveCliRunSettings } from
|
|
28
|
-
import { resolveStreamSettings } from
|
|
29
|
-
import { handleSlidesCliRequest } from
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
|
|
34
|
-
|
|
1
|
+
import { CommanderError } from "commander";
|
|
2
|
+
import { execFile } from "node:child_process";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
|
+
import { clearCacheFiles, DEFAULT_CACHE_MAX_MB, resolveCachePath, } from "../cache.js";
|
|
5
|
+
import { loadSummarizeConfig, mergeConfigEnv } from "../config.js";
|
|
6
|
+
import { parseExtractFormat, parseMaxExtractCharactersArg, parseMetricsMode, parseStreamMode, } from "../flags.js";
|
|
7
|
+
import { resolveSlideSettings } from "../slides/index.js";
|
|
8
|
+
import { createThemeRenderer, resolveThemeNameFromSources, resolveTrueColor, } from "../tty/theme.js";
|
|
9
|
+
import { formatVersionLine } from "../version.js";
|
|
10
|
+
import { createCacheStateFromConfig } from "./cache-state.js";
|
|
11
|
+
import { handleDaemonCliRequest, handleHelpRequest, handleRefreshFreeRequest, } from "./cli-preflight.js";
|
|
12
|
+
import { parseCliProviderArg } from "./env.js";
|
|
13
|
+
import { extractAssetContent } from "./flows/asset/extract.js";
|
|
14
|
+
import { handleFileInput, isTranscribableExtension, withUrlAsset } from "./flows/asset/input.js";
|
|
15
|
+
import { summarizeMediaFile as summarizeMediaFileImpl } from "./flows/asset/media.js";
|
|
16
|
+
import { outputExtractedAsset } from "./flows/asset/output.js";
|
|
17
|
+
import { summarizeAsset as summarizeAssetFlow } from "./flows/asset/summary.js";
|
|
18
|
+
import { runUrlFlow } from "./flows/url/flow.js";
|
|
19
|
+
import { attachRichHelp, buildProgram } from "./help.js";
|
|
20
|
+
import { createMediaCacheFromConfig } from "./media-cache-state.js";
|
|
21
|
+
import { createProgressGate } from "./progress.js";
|
|
22
|
+
import { resolveRunContextState } from "./run-context.js";
|
|
23
|
+
import { resolveRunInput } from "./run-input.js";
|
|
24
|
+
import { createRunMetrics } from "./run-metrics.js";
|
|
25
|
+
import { resolveModelSelection } from "./run-models.js";
|
|
26
|
+
import { resolveDesiredOutputTokens } from "./run-output.js";
|
|
27
|
+
import { resolveCliRunSettings } from "./run-settings.js";
|
|
28
|
+
import { resolveStreamSettings } from "./run-stream.js";
|
|
29
|
+
import { handleSlidesCliRequest } from "./slides-cli.js";
|
|
30
|
+
import { createTempFileFromStdin } from "./stdin-temp-file.js";
|
|
31
|
+
import { createSummaryEngine } from "./summary-engine.js";
|
|
32
|
+
import { isRichTty, supportsColor } from "./terminal.js";
|
|
33
|
+
import { handleTranscriberCliRequest } from "./transcriber-cli.js";
|
|
34
|
+
export async function runCli(argv, { env: inputEnv, fetch, execFile: execFileOverride, stdin, stdout, stderr }) {
|
|
35
35
|
globalThis.AI_SDK_LOG_WARNINGS = false;
|
|
36
|
-
const normalizedArgv = argv.filter((arg) => arg !==
|
|
37
|
-
const noColorFlag = normalizedArgv.includes(
|
|
38
|
-
|
|
36
|
+
const normalizedArgv = argv.filter((arg) => arg !== "--");
|
|
37
|
+
const noColorFlag = normalizedArgv.includes("--no-color");
|
|
38
|
+
let envForRun = noColorFlag
|
|
39
|
+
? { ...inputEnv, NO_COLOR: "1", FORCE_COLOR: "0" }
|
|
40
|
+
: { ...inputEnv };
|
|
41
|
+
const { config: bootstrapConfig } = loadSummarizeConfig({ env: envForRun });
|
|
42
|
+
envForRun = mergeConfigEnv({ env: envForRun, config: bootstrapConfig });
|
|
43
|
+
const env = envForRun;
|
|
39
44
|
if (handleHelpRequest({ normalizedArgv, envForRun, stdout, stderr })) {
|
|
40
45
|
return;
|
|
41
46
|
}
|
|
@@ -87,10 +92,10 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
87
92
|
program.exitOverride();
|
|
88
93
|
attachRichHelp(program, envForRun, stdout);
|
|
89
94
|
try {
|
|
90
|
-
program.parse(normalizedArgv, { from:
|
|
95
|
+
program.parse(normalizedArgv, { from: "user" });
|
|
91
96
|
}
|
|
92
97
|
catch (error) {
|
|
93
|
-
if (error instanceof CommanderError && error.code ===
|
|
98
|
+
if (error instanceof CommanderError && error.code === "commander.helpDisplayed") {
|
|
94
99
|
return;
|
|
95
100
|
}
|
|
96
101
|
throw error;
|
|
@@ -99,16 +104,16 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
99
104
|
stdout.write(`${formatVersionLine()}\n`);
|
|
100
105
|
return;
|
|
101
106
|
}
|
|
102
|
-
const promptArg = typeof program.opts().prompt ===
|
|
103
|
-
const promptFileArg = typeof program.opts().promptFile ===
|
|
107
|
+
const promptArg = typeof program.opts().prompt === "string" ? program.opts().prompt : null;
|
|
108
|
+
const promptFileArg = typeof program.opts().promptFile === "string" ? program.opts().promptFile : null;
|
|
104
109
|
if (promptArg && promptFileArg) {
|
|
105
|
-
throw new Error(
|
|
110
|
+
throw new Error("Use either --prompt or --prompt-file (not both).");
|
|
106
111
|
}
|
|
107
112
|
let promptOverride = null;
|
|
108
113
|
if (promptFileArg) {
|
|
109
114
|
let text;
|
|
110
115
|
try {
|
|
111
|
-
text = await readFile(promptFileArg,
|
|
116
|
+
text = await fs.readFile(promptFileArg, "utf8");
|
|
112
117
|
}
|
|
113
118
|
catch (error) {
|
|
114
119
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -123,15 +128,15 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
123
128
|
else if (promptArg) {
|
|
124
129
|
const trimmed = promptArg.trim();
|
|
125
130
|
if (!trimmed) {
|
|
126
|
-
throw new Error(
|
|
131
|
+
throw new Error("Prompt must not be empty.");
|
|
127
132
|
}
|
|
128
133
|
promptOverride = trimmed;
|
|
129
134
|
}
|
|
130
|
-
const clearCacheFlag = normalizedArgv.includes(
|
|
135
|
+
const clearCacheFlag = normalizedArgv.includes("--clear-cache");
|
|
131
136
|
if (clearCacheFlag) {
|
|
132
|
-
const extraArgs = normalizedArgv.filter((arg) => arg !==
|
|
137
|
+
const extraArgs = normalizedArgv.filter((arg) => arg !== "--clear-cache");
|
|
133
138
|
if (extraArgs.length > 0) {
|
|
134
|
-
throw new Error(
|
|
139
|
+
throw new Error("--clear-cache must be used alone.");
|
|
135
140
|
}
|
|
136
141
|
const { config } = loadSummarizeConfig({ env: envForRun });
|
|
137
142
|
const cachePath = resolveCachePath({
|
|
@@ -139,17 +144,17 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
139
144
|
cachePath: config?.cache?.path ?? null,
|
|
140
145
|
});
|
|
141
146
|
if (!cachePath) {
|
|
142
|
-
throw new Error(
|
|
147
|
+
throw new Error("Unable to resolve cache path (missing HOME).");
|
|
143
148
|
}
|
|
144
149
|
clearCacheFiles(cachePath);
|
|
145
|
-
stdout.write(
|
|
150
|
+
stdout.write("Cache cleared.\n");
|
|
146
151
|
return;
|
|
147
152
|
}
|
|
148
|
-
const cacheStatsFlag = normalizedArgv.includes(
|
|
153
|
+
const cacheStatsFlag = normalizedArgv.includes("--cache-stats");
|
|
149
154
|
if (cacheStatsFlag) {
|
|
150
|
-
const extraArgs = normalizedArgv.filter((arg) => arg !==
|
|
155
|
+
const extraArgs = normalizedArgv.filter((arg) => arg !== "--cache-stats");
|
|
151
156
|
if (extraArgs.length > 0) {
|
|
152
|
-
throw new Error(
|
|
157
|
+
throw new Error("--cache-stats must be used alone.");
|
|
153
158
|
}
|
|
154
159
|
const { config } = loadSummarizeConfig({ env: envForRun });
|
|
155
160
|
const cachePath = resolveCachePath({
|
|
@@ -157,26 +162,26 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
157
162
|
cachePath: config?.cache?.path ?? null,
|
|
158
163
|
});
|
|
159
164
|
if (!cachePath) {
|
|
160
|
-
throw new Error(
|
|
165
|
+
throw new Error("Unable to resolve cache path (missing HOME).");
|
|
161
166
|
}
|
|
162
|
-
const cacheMaxMb = typeof config?.cache?.maxMb ===
|
|
167
|
+
const cacheMaxMb = typeof config?.cache?.maxMb === "number" ? config.cache.maxMb : DEFAULT_CACHE_MAX_MB;
|
|
163
168
|
const cacheMaxBytes = Math.max(0, cacheMaxMb) * 1024 * 1024;
|
|
164
|
-
const { readCacheStats } = await import(
|
|
165
|
-
const { formatBytes } = await import(
|
|
169
|
+
const { readCacheStats } = await import("../cache.js");
|
|
170
|
+
const { formatBytes } = await import("../tty/format.js");
|
|
166
171
|
const stats = await readCacheStats(cachePath);
|
|
167
172
|
stdout.write(`Cache path: ${cachePath}\n`);
|
|
168
173
|
if (!stats) {
|
|
169
|
-
stdout.write(
|
|
174
|
+
stdout.write("Cache is empty.\n");
|
|
170
175
|
return;
|
|
171
176
|
}
|
|
172
177
|
const sizeLabel = formatBytes(stats.sizeBytes);
|
|
173
|
-
const maxLabel = cacheMaxBytes > 0 ? formatBytes(cacheMaxBytes) :
|
|
178
|
+
const maxLabel = cacheMaxBytes > 0 ? formatBytes(cacheMaxBytes) : "disabled";
|
|
174
179
|
stdout.write(`Size: ${sizeLabel} (max ${maxLabel})\n`);
|
|
175
180
|
stdout.write(`Entries: total=${stats.totalEntries} extract=${stats.counts.extract} summary=${stats.counts.summary} transcript=${stats.counts.transcript}\n`);
|
|
176
181
|
return;
|
|
177
182
|
}
|
|
178
|
-
const cliFlagPresent = normalizedArgv.some((arg) => arg ===
|
|
179
|
-
let cliProviderArgRaw = typeof program.opts().cli ===
|
|
183
|
+
const cliFlagPresent = normalizedArgv.some((arg) => arg === "--cli" || arg.startsWith("--cli="));
|
|
184
|
+
let cliProviderArgRaw = typeof program.opts().cli === "string" ? program.opts().cli : null;
|
|
180
185
|
const inputResolution = resolveRunInput({
|
|
181
186
|
program,
|
|
182
187
|
cliFlagPresent,
|
|
@@ -187,12 +192,12 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
187
192
|
const inputTarget = inputResolution.inputTarget;
|
|
188
193
|
const url = inputResolution.url;
|
|
189
194
|
const runStartedAtMs = Date.now();
|
|
190
|
-
const videoModeExplicitlySet = normalizedArgv.some((arg) => arg ===
|
|
191
|
-
const lengthExplicitlySet = normalizedArgv.some((arg) => arg ===
|
|
192
|
-
const languageExplicitlySet = normalizedArgv.some((arg) => arg ===
|
|
193
|
-
arg.startsWith(
|
|
194
|
-
arg ===
|
|
195
|
-
arg.startsWith(
|
|
195
|
+
const videoModeExplicitlySet = normalizedArgv.some((arg) => arg === "--video-mode" || arg.startsWith("--video-mode="));
|
|
196
|
+
const lengthExplicitlySet = normalizedArgv.some((arg) => arg === "--length" || arg.startsWith("--length="));
|
|
197
|
+
const languageExplicitlySet = normalizedArgv.some((arg) => arg === "--language" ||
|
|
198
|
+
arg.startsWith("--language=") ||
|
|
199
|
+
arg === "--lang" ||
|
|
200
|
+
arg.startsWith("--lang="));
|
|
196
201
|
const noCacheFlag = program.opts().cache === false;
|
|
197
202
|
const noMediaCacheFlag = program.opts().mediaCache === false;
|
|
198
203
|
const extractMode = Boolean(program.opts().extract) || Boolean(program.opts().extractOnly);
|
|
@@ -204,47 +209,47 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
204
209
|
const debug = Boolean(program.opts().debug);
|
|
205
210
|
const verbose = Boolean(program.opts().verbose) || debug;
|
|
206
211
|
const normalizeTranscriber = (value) => {
|
|
207
|
-
if (typeof value !==
|
|
212
|
+
if (typeof value !== "string")
|
|
208
213
|
return null;
|
|
209
214
|
const normalized = value.trim().toLowerCase();
|
|
210
|
-
if (normalized ===
|
|
211
|
-
normalized ===
|
|
212
|
-
normalized ===
|
|
213
|
-
normalized ===
|
|
215
|
+
if (normalized === "auto" ||
|
|
216
|
+
normalized === "whisper" ||
|
|
217
|
+
normalized === "parakeet" ||
|
|
218
|
+
normalized === "canary")
|
|
214
219
|
return normalized;
|
|
215
220
|
return null;
|
|
216
221
|
};
|
|
217
|
-
const transcriberExplicitlySet = normalizedArgv.some((arg) => arg ===
|
|
222
|
+
const transcriberExplicitlySet = normalizedArgv.some((arg) => arg === "--transcriber" || arg.startsWith("--transcriber="));
|
|
218
223
|
const envTranscriber = envForRun?.SUMMARIZE_TRANSCRIBER ??
|
|
219
224
|
process.env.SUMMARIZE_TRANSCRIBER ??
|
|
220
225
|
null;
|
|
221
226
|
const transcriber = normalizeTranscriber(transcriberExplicitlySet ? program.opts().transcriber : envTranscriber) ??
|
|
222
|
-
|
|
227
|
+
"auto";
|
|
223
228
|
envForRun.SUMMARIZE_TRANSCRIBER = transcriber;
|
|
224
|
-
const maxExtractCharacters = parseMaxExtractCharactersArg(typeof program.opts().maxExtractCharacters ===
|
|
229
|
+
const maxExtractCharacters = parseMaxExtractCharactersArg(typeof program.opts().maxExtractCharacters === "string"
|
|
225
230
|
? program.opts().maxExtractCharacters
|
|
226
231
|
: program.opts().maxExtractCharacters != null
|
|
227
232
|
? String(program.opts().maxExtractCharacters)
|
|
228
233
|
: undefined);
|
|
229
|
-
const isYoutubeUrl = typeof url ===
|
|
230
|
-
const formatExplicitlySet = normalizedArgv.some((arg) => arg ===
|
|
231
|
-
const rawFormatOpt = typeof program.opts().format ===
|
|
234
|
+
const isYoutubeUrl = typeof url === "string" ? /youtube\.com|youtu\.be/i.test(url) : false;
|
|
235
|
+
const formatExplicitlySet = normalizedArgv.some((arg) => arg === "--format" || arg.startsWith("--format="));
|
|
236
|
+
const rawFormatOpt = typeof program.opts().format === "string" ? program.opts().format : null;
|
|
232
237
|
const format = parseExtractFormat(formatExplicitlySet
|
|
233
|
-
? (rawFormatOpt ??
|
|
234
|
-
: extractMode && inputTarget.kind ===
|
|
235
|
-
?
|
|
236
|
-
:
|
|
238
|
+
? (rawFormatOpt ?? "text")
|
|
239
|
+
: extractMode && inputTarget.kind === "url" && !isYoutubeUrl
|
|
240
|
+
? "md"
|
|
241
|
+
: "text");
|
|
237
242
|
const runSettings = resolveCliRunSettings({
|
|
238
243
|
length: String(program.opts().length),
|
|
239
244
|
firecrawl: String(program.opts().firecrawl),
|
|
240
|
-
markdownMode: typeof program.opts().markdownMode ===
|
|
241
|
-
markdown: typeof program.opts().markdown ===
|
|
245
|
+
markdownMode: typeof program.opts().markdownMode === "string" ? program.opts().markdownMode : undefined,
|
|
246
|
+
markdown: typeof program.opts().markdown === "string" ? program.opts().markdown : undefined,
|
|
242
247
|
format,
|
|
243
248
|
preprocess: String(program.opts().preprocess),
|
|
244
249
|
youtube: String(program.opts().youtube),
|
|
245
250
|
timeout: String(program.opts().timeout),
|
|
246
251
|
retries: String(program.opts().retries),
|
|
247
|
-
maxOutputTokens: typeof program.opts().maxOutputTokens ===
|
|
252
|
+
maxOutputTokens: typeof program.opts().maxOutputTokens === "string"
|
|
248
253
|
? program.opts().maxOutputTokens
|
|
249
254
|
: program.opts().maxOutputTokens != null
|
|
250
255
|
? String(program.opts().maxOutputTokens)
|
|
@@ -252,31 +257,31 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
252
257
|
});
|
|
253
258
|
const { youtubeMode, lengthArg, maxOutputTokensArg, timeoutMs, retries, preprocessMode, firecrawlMode: requestedFirecrawlMode, markdownMode, } = runSettings;
|
|
254
259
|
if (extractMode && lengthExplicitlySet && !json && isRichTty(stderr)) {
|
|
255
|
-
stderr.write(
|
|
260
|
+
stderr.write("Warning: --length is ignored with --extract (no summary is generated).\n");
|
|
256
261
|
}
|
|
257
|
-
const metricsExplicitlySet = normalizedArgv.some((arg) => arg ===
|
|
258
|
-
const metricsMode = parseMetricsMode(debug && !metricsExplicitlySet ?
|
|
259
|
-
const metricsEnabled = metricsMode !==
|
|
260
|
-
const metricsDetailed = metricsMode ===
|
|
262
|
+
const metricsExplicitlySet = normalizedArgv.some((arg) => arg === "--metrics" || arg.startsWith("--metrics="));
|
|
263
|
+
const metricsMode = parseMetricsMode(debug && !metricsExplicitlySet ? "detailed" : program.opts().metrics);
|
|
264
|
+
const metricsEnabled = metricsMode !== "off";
|
|
265
|
+
const metricsDetailed = metricsMode === "detailed";
|
|
261
266
|
const shouldComputeReport = metricsEnabled;
|
|
262
|
-
const _firecrawlExplicitlySet = normalizedArgv.some((arg) => arg ===
|
|
263
|
-
const markdownModeExplicitlySet = normalizedArgv.some((arg) => arg ===
|
|
264
|
-
arg.startsWith(
|
|
265
|
-
arg ===
|
|
266
|
-
arg.startsWith(
|
|
267
|
-
const modelArg = typeof program.opts().model ===
|
|
268
|
-
const cliProviderArg = typeof cliProviderArgRaw ===
|
|
267
|
+
const _firecrawlExplicitlySet = normalizedArgv.some((arg) => arg === "--firecrawl" || arg.startsWith("--firecrawl="));
|
|
268
|
+
const markdownModeExplicitlySet = normalizedArgv.some((arg) => arg === "--markdown-mode" ||
|
|
269
|
+
arg.startsWith("--markdown-mode=") ||
|
|
270
|
+
arg === "--markdown" ||
|
|
271
|
+
arg.startsWith("--markdown="));
|
|
272
|
+
const modelArg = typeof program.opts().model === "string" ? program.opts().model : null;
|
|
273
|
+
const cliProviderArg = typeof cliProviderArgRaw === "string" && cliProviderArgRaw.trim().length > 0
|
|
269
274
|
? parseCliProviderArg(cliProviderArgRaw)
|
|
270
275
|
: null;
|
|
271
276
|
if (cliFlagPresent && modelArg) {
|
|
272
|
-
throw new Error(
|
|
277
|
+
throw new Error("Use either --model or --cli (not both).");
|
|
273
278
|
}
|
|
274
279
|
const explicitModelArg = cliProviderArg
|
|
275
280
|
? `cli/${cliProviderArg}`
|
|
276
281
|
: cliFlagPresent
|
|
277
|
-
?
|
|
282
|
+
? "auto"
|
|
278
283
|
: modelArg;
|
|
279
|
-
const { config, configPath, outputLanguage, openaiWhisperUsdPerMinute, videoMode, cliConfigForRun, configForCli, openaiUseChatCompletions, configModelLabel, apiKey, openrouterApiKey, openrouterConfigured, openaiTranscriptionKey, xaiApiKey, googleApiKey, anthropicApiKey, zaiApiKey, zaiBaseUrl, providerBaseUrls, firecrawlApiKey, firecrawlConfigured, googleConfigured, anthropicConfigured, apifyToken, ytDlpPath, falApiKey, cliAvailability, envForAuto, } = resolveRunContextState({
|
|
284
|
+
const { config, configPath, outputLanguage, openaiWhisperUsdPerMinute, videoMode, cliConfigForRun, configForCli, openaiUseChatCompletions, configModelLabel, apiKey, openrouterApiKey, openrouterConfigured, groqApiKey, openaiTranscriptionKey, xaiApiKey, googleApiKey, anthropicApiKey, zaiApiKey, zaiBaseUrl, providerBaseUrls, firecrawlApiKey, firecrawlConfigured, googleConfigured, anthropicConfigured, apifyToken, ytDlpPath, ytDlpCookiesFromBrowser, falApiKey, cliAvailability, envForAuto, } = resolveRunContextState({
|
|
280
285
|
env,
|
|
281
286
|
envForRun,
|
|
282
287
|
programOpts: program.opts(),
|
|
@@ -291,15 +296,15 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
291
296
|
config: config?.ui?.theme,
|
|
292
297
|
});
|
|
293
298
|
envForRun.SUMMARIZE_THEME = themeName;
|
|
294
|
-
if (!promptOverride && typeof config?.prompt ===
|
|
299
|
+
if (!promptOverride && typeof config?.prompt === "string" && config.prompt.trim().length > 0) {
|
|
295
300
|
promptOverride = config.prompt.trim();
|
|
296
301
|
}
|
|
297
|
-
const slidesExplicitlySet = normalizedArgv.some((arg) => arg ===
|
|
298
|
-
const slidesOcrExplicitlySet = normalizedArgv.some((arg) => arg ===
|
|
299
|
-
const slidesDirExplicitlySet = normalizedArgv.some((arg) => arg ===
|
|
300
|
-
const slidesSceneThresholdExplicitlySet = normalizedArgv.some((arg) => arg ===
|
|
301
|
-
const slidesMaxExplicitlySet = normalizedArgv.some((arg) => arg ===
|
|
302
|
-
const slidesMinDurationExplicitlySet = normalizedArgv.some((arg) => arg ===
|
|
302
|
+
const slidesExplicitlySet = normalizedArgv.some((arg) => arg === "--slides" || arg === "--no-slides" || arg.startsWith("--slides="));
|
|
303
|
+
const slidesOcrExplicitlySet = normalizedArgv.some((arg) => arg === "--slides-ocr" || arg === "--no-slides-ocr" || arg.startsWith("--slides-ocr="));
|
|
304
|
+
const slidesDirExplicitlySet = normalizedArgv.some((arg) => arg === "--slides-dir" || arg.startsWith("--slides-dir="));
|
|
305
|
+
const slidesSceneThresholdExplicitlySet = normalizedArgv.some((arg) => arg === "--slides-scene-threshold" || arg.startsWith("--slides-scene-threshold="));
|
|
306
|
+
const slidesMaxExplicitlySet = normalizedArgv.some((arg) => arg === "--slides-max" || arg.startsWith("--slides-max="));
|
|
307
|
+
const slidesMinDurationExplicitlySet = normalizedArgv.some((arg) => arg === "--slides-min-duration" || arg.startsWith("--slides-min-duration="));
|
|
303
308
|
const slidesConfig = config?.slides;
|
|
304
309
|
const slidesSettings = resolveSlideSettings({
|
|
305
310
|
slides: slidesExplicitlySet
|
|
@@ -314,7 +319,7 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
314
319
|
slidesSceneThreshold: slidesSceneThresholdExplicitlySet
|
|
315
320
|
? program.opts().slidesSceneThreshold
|
|
316
321
|
: (slidesConfig?.sceneThreshold ?? program.opts().slidesSceneThreshold),
|
|
317
|
-
slidesSceneThresholdExplicit: slidesSceneThresholdExplicitlySet || typeof slidesConfig?.sceneThreshold ===
|
|
322
|
+
slidesSceneThresholdExplicit: slidesSceneThresholdExplicitlySet || typeof slidesConfig?.sceneThreshold === "number",
|
|
318
323
|
slidesMax: slidesMaxExplicitlySet
|
|
319
324
|
? program.opts().slidesMax
|
|
320
325
|
: (slidesConfig?.max ?? program.opts().slidesMax),
|
|
@@ -323,14 +328,14 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
323
328
|
: (slidesConfig?.minDuration ?? program.opts().slidesMinDuration),
|
|
324
329
|
cwd: process.cwd(),
|
|
325
330
|
});
|
|
326
|
-
if (slidesSettings && inputTarget.kind !==
|
|
327
|
-
throw new Error(
|
|
331
|
+
if (slidesSettings && inputTarget.kind !== "url") {
|
|
332
|
+
throw new Error("--slides is only supported for URL inputs");
|
|
328
333
|
}
|
|
329
334
|
const transcriptTimestamps = Boolean(program.opts().timestamps) || Boolean(slidesSettings);
|
|
330
|
-
const lengthInstruction = promptOverride && lengthExplicitlySet && lengthArg.kind ===
|
|
335
|
+
const lengthInstruction = promptOverride && lengthExplicitlySet && lengthArg.kind === "chars"
|
|
331
336
|
? `Output is ${lengthArg.maxCharacters.toLocaleString()} characters.`
|
|
332
337
|
: null;
|
|
333
|
-
const languageInstruction = promptOverride && languageExplicitlySet && outputLanguage.kind ===
|
|
338
|
+
const languageInstruction = promptOverride && languageExplicitlySet && outputLanguage.kind === "fixed"
|
|
334
339
|
? `Output should be ${outputLanguage.label}.`
|
|
335
340
|
: null;
|
|
336
341
|
const transcriptNamespace = `yt:${youtubeMode}`;
|
|
@@ -346,11 +351,19 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
346
351
|
noMediaCacheFlag,
|
|
347
352
|
});
|
|
348
353
|
try {
|
|
349
|
-
if (markdownModeExplicitlySet && format !==
|
|
350
|
-
throw new Error(
|
|
354
|
+
if (markdownModeExplicitlySet && format !== "markdown") {
|
|
355
|
+
throw new Error("--markdown-mode is only supported with --format md");
|
|
351
356
|
}
|
|
352
|
-
if (markdownModeExplicitlySet &&
|
|
353
|
-
|
|
357
|
+
if (markdownModeExplicitlySet &&
|
|
358
|
+
inputTarget.kind !== "url" &&
|
|
359
|
+
inputTarget.kind !== "file" &&
|
|
360
|
+
inputTarget.kind !== "stdin") {
|
|
361
|
+
throw new Error("--markdown-mode is only supported for URL, file, or stdin inputs");
|
|
362
|
+
}
|
|
363
|
+
if (markdownModeExplicitlySet &&
|
|
364
|
+
(inputTarget.kind === "file" || inputTarget.kind === "stdin") &&
|
|
365
|
+
markdownMode !== "llm") {
|
|
366
|
+
throw new Error("Only --markdown-mode llm is supported for file/stdin inputs; other modes require a URL");
|
|
354
367
|
}
|
|
355
368
|
const metrics = createRunMetrics({
|
|
356
369
|
env,
|
|
@@ -358,7 +371,7 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
358
371
|
maxOutputTokensArg,
|
|
359
372
|
});
|
|
360
373
|
const { llmCalls, trackedFetch, buildReport, estimateCostUsd, getLiteLlmCatalog, resolveMaxOutputTokensForCall, resolveMaxInputTokensForCall, setTranscriptionCost, } = metrics;
|
|
361
|
-
const { requestedModel, requestedModelInput, requestedModelLabel, isNamedModelSelection, wantsFreeNamedModel, configForModelSelection, isFallbackModel, } = resolveModelSelection({
|
|
374
|
+
const { requestedModel, requestedModelInput, requestedModelLabel, isNamedModelSelection, isImplicitAutoSelection, wantsFreeNamedModel, configForModelSelection, isFallbackModel, } = resolveModelSelection({
|
|
362
375
|
config,
|
|
363
376
|
configForCli,
|
|
364
377
|
configPath,
|
|
@@ -371,23 +384,28 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
371
384
|
enabled: verboseColor,
|
|
372
385
|
trueColor: resolveTrueColor(envForRun),
|
|
373
386
|
});
|
|
374
|
-
const renderSpinnerStatus = (label, detail =
|
|
375
|
-
const renderSpinnerStatusWithModel = (label, modelId) => `${themeForStderr.label(label)}${themeForStderr.dim(
|
|
387
|
+
const renderSpinnerStatus = (label, detail = "…") => `${themeForStderr.label(label)}${themeForStderr.dim(detail)}`;
|
|
388
|
+
const renderSpinnerStatusWithModel = (label, modelId) => `${themeForStderr.label(label)}${themeForStderr.dim(" (model: ")}${themeForStderr.accent(modelId)}${themeForStderr.dim(")…")}`;
|
|
376
389
|
const { streamingEnabled } = resolveStreamSettings({
|
|
377
390
|
streamMode,
|
|
378
391
|
stdout,
|
|
379
392
|
json,
|
|
380
393
|
extractMode,
|
|
381
394
|
});
|
|
382
|
-
if (extractMode &&
|
|
383
|
-
|
|
395
|
+
if (extractMode &&
|
|
396
|
+
inputTarget.kind === "file" &&
|
|
397
|
+
!isTranscribableExtension(inputTarget.filePath)) {
|
|
398
|
+
throw new Error("--extract for local files is only supported for media files (MP3, MP4, WAV, etc.)");
|
|
399
|
+
}
|
|
400
|
+
if (extractMode && inputTarget.kind === "stdin") {
|
|
401
|
+
throw new Error("--extract is not supported for piped stdin input");
|
|
384
402
|
}
|
|
385
403
|
// Progress UI (spinner + OSC progress) is shown on stderr. Before writing to stdout (including
|
|
386
404
|
// streaming output), we stop + clear progress via the progress gate to keep scrollback clean.
|
|
387
405
|
const progressEnabled = isRichTty(stderr) && !verbose && !json;
|
|
388
406
|
const progressGate = createProgressGate();
|
|
389
407
|
const { clearProgressForStdout, restoreProgressAfterStdout, setClearProgressBeforeStdout, clearProgressIfCurrent, } = progressGate;
|
|
390
|
-
const fixedModelSpec = requestedModel.kind ===
|
|
408
|
+
const fixedModelSpec = requestedModel.kind === "fixed" ? requestedModel : null;
|
|
391
409
|
const desiredOutputTokens = resolveDesiredOutputTokens({ lengthArg, maxOutputTokensArg });
|
|
392
410
|
const summaryEngine = createSummaryEngine({
|
|
393
411
|
env,
|
|
@@ -437,7 +455,7 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
437
455
|
if (filtered.length === 0)
|
|
438
456
|
return;
|
|
439
457
|
clearProgressForStdout();
|
|
440
|
-
stderr.write(`${themeForStderr.dim(`via ${filtered.join(
|
|
458
|
+
stderr.write(`${themeForStderr.dim(`via ${filtered.join(", ")}`)}\n`);
|
|
441
459
|
restoreProgressAfterStdout?.();
|
|
442
460
|
};
|
|
443
461
|
const assetSummaryContext = {
|
|
@@ -459,6 +477,8 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
459
477
|
lengthInstruction,
|
|
460
478
|
languageInstruction,
|
|
461
479
|
isFallbackModel,
|
|
480
|
+
isImplicitAutoSelection,
|
|
481
|
+
allowAutoCliFallback: false,
|
|
462
482
|
desiredOutputTokens,
|
|
463
483
|
envForAuto,
|
|
464
484
|
configForModelSelection,
|
|
@@ -517,6 +537,21 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
517
537
|
setClearProgressBeforeStdout,
|
|
518
538
|
clearProgressIfCurrent,
|
|
519
539
|
};
|
|
540
|
+
if (inputTarget.kind === "stdin") {
|
|
541
|
+
const stdinTempFile = await createTempFileFromStdin({
|
|
542
|
+
stream: stdin ?? process.stdin,
|
|
543
|
+
});
|
|
544
|
+
try {
|
|
545
|
+
const stdinInputTarget = { kind: "file", filePath: stdinTempFile.filePath };
|
|
546
|
+
if (await handleFileInput(assetInputContext, stdinInputTarget)) {
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
throw new Error("Failed to process stdin input");
|
|
550
|
+
}
|
|
551
|
+
finally {
|
|
552
|
+
await stdinTempFile.cleanup();
|
|
553
|
+
}
|
|
554
|
+
}
|
|
520
555
|
if (await handleFileInput(assetInputContext, inputTarget)) {
|
|
521
556
|
return;
|
|
522
557
|
}
|
|
@@ -524,7 +559,7 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
524
559
|
(await withUrlAsset(assetInputContext, url, isYoutubeUrl, async ({ loaded, spinner }) => {
|
|
525
560
|
if (extractMode) {
|
|
526
561
|
if (progressEnabled)
|
|
527
|
-
spinner.setText(renderSpinnerStatus(
|
|
562
|
+
spinner.setText(renderSpinnerStatus("Extracting text"));
|
|
528
563
|
const extracted = await extractAssetContent({
|
|
529
564
|
ctx: {
|
|
530
565
|
env,
|
|
@@ -572,22 +607,22 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
572
607
|
return;
|
|
573
608
|
}
|
|
574
609
|
if (progressEnabled)
|
|
575
|
-
spinner.setText(renderSpinnerStatus(
|
|
610
|
+
spinner.setText(renderSpinnerStatus("Summarizing"));
|
|
576
611
|
await summarizeAsset({
|
|
577
|
-
sourceKind:
|
|
612
|
+
sourceKind: "asset-url",
|
|
578
613
|
sourceLabel: loaded.sourceLabel,
|
|
579
614
|
attachment: loaded.attachment,
|
|
580
615
|
onModelChosen: (modelId) => {
|
|
581
616
|
if (!progressEnabled)
|
|
582
617
|
return;
|
|
583
|
-
spinner.setText(renderSpinnerStatusWithModel(
|
|
618
|
+
spinner.setText(renderSpinnerStatusWithModel("Summarizing", modelId));
|
|
584
619
|
},
|
|
585
620
|
});
|
|
586
621
|
}))) {
|
|
587
622
|
return;
|
|
588
623
|
}
|
|
589
624
|
if (!url) {
|
|
590
|
-
throw new Error(
|
|
625
|
+
throw new Error("Only HTTP and HTTPS URLs can be summarized");
|
|
591
626
|
}
|
|
592
627
|
const urlFlowContext = {
|
|
593
628
|
io: {
|
|
@@ -641,6 +676,8 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
641
676
|
requestedModelLabel,
|
|
642
677
|
fixedModelSpec,
|
|
643
678
|
isFallbackModel,
|
|
679
|
+
isImplicitAutoSelection,
|
|
680
|
+
allowAutoCliFallback: false,
|
|
644
681
|
isNamedModelSelection,
|
|
645
682
|
wantsFreeNamedModel,
|
|
646
683
|
desiredOutputTokens,
|
|
@@ -665,7 +702,9 @@ export async function runCli(argv, { env, fetch, execFile: execFileOverride, std
|
|
|
665
702
|
firecrawlApiKey,
|
|
666
703
|
apifyToken,
|
|
667
704
|
ytDlpPath,
|
|
705
|
+
ytDlpCookiesFromBrowser,
|
|
668
706
|
falApiKey,
|
|
707
|
+
groqApiKey,
|
|
669
708
|
openaiTranscriptionKey,
|
|
670
709
|
},
|
|
671
710
|
summaryEngine,
|