@koda-sl/baker-cli 0.379.0 → 0.380.0-dev.824ccf426

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/README.md CHANGED
@@ -2621,7 +2621,7 @@ baker images ingest https://images.pexels.com/photos/13219418/pexels-photo-13219
2621
2621
  baker images ingest https://acme.com/hero.png --source firecrawl --external-url https://acme.com/pricing --context "competitor pricing hero"
2622
2622
  ```
2623
2623
 
2624
- `--source` is a closed set, validated before the request so a wrong value costs nothing: `uploaded`, `website`, `google_testimonial`, `trustpilot_testimonial`, `instagram`, `pexels`, `pixabay`, `magnific` (retired provider, kept for existing rows), `brandfetch`, `google_images`, `firecrawl`, `screenshotone`, `iconify`, `giphy`, `pinterest`, `ai_generated`, `layer_edit`. Use `website` for an asset pulled off a company's own site.
2624
+ `--source` is a closed set, validated before the request so a wrong value costs nothing: `uploaded`, `website`, `google_testimonial`, `trustpilot_testimonial`, `instagram`, `tiktok`, `linkedin`, `facebook`, `pexels`, `pixabay`, `magnific` (retired provider, kept for existing rows), `brandfetch`, `google_images`, `firecrawl`, `screenshotone`, `iconify`, `giphy`, `pinterest`, `ai_generated`, `layer_edit`. Use `website` for an asset pulled off a company's own site.
2625
2625
 
2626
2626
  Returns `{ imageId, deduped, contentHash }`. When `deduped: true`, an existing library row is returned — no new bytes are stored. Max ingest size 25MB.
2627
2627
 
@@ -2955,7 +2955,7 @@ Re-ingesting the same link returns the existing row with `deduped: true` instead
2955
2955
 
2956
2956
  | Flag | Purpose |
2957
2957
  |---|---|
2958
- | `--source` | Provenance. Inferred from the link's host when omitted, and that inference covers 20 video platforms — `youtube`, `instagram`, `tiktok`, `twitter`, `facebook`, `reddit`, `vimeo`, `dailymotion`, `twitch`, `bluesky`, `bilibili`, `vk`, `ok`, `pinterest`, `tumblr`, `snapchat`, `loom`, `streamable`, `newgrounds`, `rutube` — plus `uploaded` and `url`. A link from anywhere else still ingests, recorded as `url`. |
2958
+ | `--source` | Provenance. Inferred from the link's host when omitted, and that inference covers 21 video platforms — `youtube`, `instagram`, `tiktok`, `twitter`, `facebook`, `linkedin`, `reddit`, `vimeo`, `dailymotion`, `twitch`, `bluesky`, `bilibili`, `vk`, `ok`, `pinterest`, `tumblr`, `snapchat`, `loom`, `streamable`, `newgrounds`, `rutube` — plus `uploaded` and `url`. A link from anywhere else still ingests, recorded as `url`. |
2959
2959
  | `--external-id` | Dedupe key — re-running the same link returns the existing video. Derived from the link automatically on the download route. |
2960
2960
  | `--external-url` | Canonical page URL. Defaults to the input for a page URL. |
2961
2961
  | `--download` | Skip the direct attempt and always download. |
@@ -2987,6 +2987,16 @@ Requires `yt-dlp` on `PATH` (present in the Baker Runtime). Private, age-restric
2987
2987
 
2988
2988
  **yt-dlp goes stale, and that looks like a broken video.** Large platforms change their players every few weeks and an out-of-date `yt-dlp` then resolves *no* formats at all, failing with "Requested format is not available" or "Only images are available" rather than anything that names the real cause. The error classifies this case separately and says the link is probably fine. The Runtime image installs `yt-dlp` unpinned at build time (`packages/e2b-template/src/template.ts`), so it ages with the image — if platform ingests start failing across the board, rebuild the template before investigating anything else. Direct file URLs don't depend on `yt-dlp` at all and keep working regardless.
2989
2989
 
2990
+ ### `baker videos fetch <url> --out <dir>`
2991
+
2992
+ Download a video page (YouTube, TikTok, Vimeo, …) to a local `.mp4` without adding it to the library — the download half of `ingest`, with the same proxy fallback and duration check. `--max-seconds` lowers the length limit (default 3 hours); `--timeout-ms` bounds the download. By default it keeps the best quality the site offers; `--max-height 1080` keeps a version no taller than that when there is one (a 4K master can be five times the bytes). Returns `{ file, durationSeconds, egress }`.
2993
+
2994
+ ```bash
2995
+ baker videos fetch https://www.youtube.com/watch?v=abc123 --out ./clips
2996
+ ```
2997
+
2998
+ Baker's YouTube source sync runs this same command on a disposable machine, with `--max-height 1080`, because a YouTube file URL only works from the IP that requested it.
2999
+
2990
3000
  ### `baker videos delete <id>`
2991
3001
 
2992
3002
  Delete a video by ID.
@@ -3140,6 +3150,32 @@ baker avatars delete marta --archive
3140
3150
 
3141
3151
  ---
3142
3152
 
3153
+ ### Media Sources (`baker media-sources`)
3154
+
3155
+ Connect a public social account so its posts fill the image and video libraries: **Instagram**, **TikTok**, **YouTube** (videos and Shorts only), **LinkedIn** company pages and **Facebook** pages — or a **Google Drive folder** shared with Baker. Each social sync reaches back up to a year, stops paging at the first page it already has, imports only what the library doesn't have yet, keeps carousels/albums/documents together as a set (`images group` / `videos group`), and passes the post caption to the analysis. A source is named by its key, `<platform>:<handle>`.
3156
+
3157
+ Connecting and removing apply immediately and show on the chat as an already-applied change.
3158
+
3159
+ | Command | What it does |
3160
+ |---|---|
3161
+ | `baker media-sources add <profile URL \| Drive folder link \| @handle> [--platform <p>] [--every never\|daily\|weekly\|monthly]` | Look the account up (must exist and be public) or check the folder is shared with Baker, and connect it; the import starts in the background. `--platform` only for a bare handle. Idempotent. |
3162
+ | `baker media-sources list` | Every source: key, platform, label, auto-sync, and per library `{ status, stored, pending?, failed?, error? }`. |
3163
+ | `baker media-sources sync <key>` | Import new posts now. |
3164
+ | `baker media-sources schedule <key> --every <interval>` | Set the auto-sync cadence. |
3165
+ | `baker media-sources remove <key>` | Disconnect; imported media stays in the library. |
3166
+
3167
+ ```bash
3168
+ baker media-sources add https://www.tiktok.com/@acme
3169
+ baker media-sources add @acme --platform instagram --every daily
3170
+ baker media-sources list
3171
+ ```
3172
+
3173
+ YouTube downloads are the expensive import (a disposable machine per batch), so a YouTube sync takes the newest 25 videos it hasn't stored, skips videos over 20 minutes, and continues with older ones on the next sync.
3174
+
3175
+ A Google Drive folder is usually connected by the user in the dashboard (Add source → Google Drive → Choose a folder, which shares it with Baker in one step); `add` takes a folder that is already shared with Baker's service account (the error names the address) or open to anyone with the link, and shared by a member of the company. Everything in it and its subfolders is imported in batches of 150 images and 20 videos (60 minutes / 5 GB at most each), new files arrive within minutes through Drive change notifications, and images are stored resized to 2560 px. Imported images from every source are resized the same way.
3176
+
3177
+ ---
3178
+
3143
3179
  ### Winning Ads (`baker winning-ads`)
3144
3180
 
3145
3181
  Search the **ad-dna** corpus of scored "winning" competitor ads for reference creatives to reproduce (e.g. with `baker canvas`), and manage the brands your library tracks (`follow` / `following` / `feed` / `unfollow`). Each result carries a presigned media URL (~1h TTL), the ad's DNA summary, and scores. The CLI authenticates with the normal `BAKER_API_KEY`; the Baker backend proxies the request to the ad-dna service with a server-held token — no extra credential in the sandbox.
@@ -20,9 +20,9 @@ import {
20
20
  shouldEscalate
21
21
  } from "./chunk-HJEMOSPH.js";
22
22
 
23
- // ../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/index.js
23
+ // ../../.pnpm-store/v10/links/@/safe-stable-stringify/2.5.0/766ad107c42df28eeadaf0ac2f9089c8a9e200f6ba0b2b1a817b8d536cbdcc49/node_modules/safe-stable-stringify/index.js
24
24
  var require_safe_stable_stringify = __commonJS({
25
- "../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/index.js"(exports, module) {
25
+ "../../.pnpm-store/v10/links/@/safe-stable-stringify/2.5.0/766ad107c42df28eeadaf0ac2f9089c8a9e200f6ba0b2b1a817b8d536cbdcc49/node_modules/safe-stable-stringify/index.js"(exports, module) {
26
26
  "use strict";
27
27
  var { hasOwnProperty } = Object.prototype;
28
28
  var stringify = configure2();
@@ -1123,7 +1123,7 @@ function resolveAdaptFormats(params) {
1123
1123
  return params.formats ?? [];
1124
1124
  }
1125
1125
 
1126
- // ../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/esm/wrapper.js
1126
+ // ../../.pnpm-store/v10/links/@/safe-stable-stringify/2.5.0/766ad107c42df28eeadaf0ac2f9089c8a9e200f6ba0b2b1a817b8d536cbdcc49/node_modules/safe-stable-stringify/esm/wrapper.js
1127
1127
  var import__ = __toESM(require_safe_stable_stringify(), 1);
1128
1128
  var configure = import__.default.configure;
1129
1129
  var wrapper_default = import__.default;
@@ -5999,6 +5999,12 @@ function isVimeoAuthFailure(detail) {
5999
5999
  return VIMEO_AUTH_SIGNATURES.some((signature) => haystack.includes(signature));
6000
6000
  }
6001
6001
 
6002
+ // src/lib/ytDlpFormat.ts
6003
+ function videoFormatArgs(maxHeight) {
6004
+ const format = maxHeight ? `bv*[height<=${maxHeight}]+ba/b[height<=${maxHeight}]/bv*+ba/b` : "bv*+ba/b";
6005
+ return ["--format", format, "--merge-output-format", "mp4"];
6006
+ }
6007
+
6002
6008
  // src/lib/ytDlpPlayerClient.ts
6003
6009
  var YOUTUBE_FALLBACK_CLIENT_ARGS = ["--extractor-args", "youtube:player_client=android"];
6004
6010
  var MEDIA_FETCH_REFUSED = "unable to download video data";
@@ -6067,7 +6073,7 @@ async function runYtDlp(args) {
6067
6073
  if (args.audioOnly) {
6068
6074
  argv.push("-x", "--audio-format", "m4a");
6069
6075
  } else {
6070
- argv.push("--format", "bv*+ba/b", "--merge-output-format", "mp4");
6076
+ argv.push(...videoFormatArgs(args.maxHeight));
6071
6077
  }
6072
6078
  const cookieFile = await writeVimeoCookieFile(args.vimeoCookie, args.workDir);
6073
6079
  if (cookieFile) argv.push("--cookies", cookieFile);
@@ -9986,4 +9992,4 @@ export {
9986
9992
  defaultRegistry,
9987
9993
  createEngineFromEnv
9988
9994
  };
9989
- //# sourceMappingURL=chunk-FGHMWBUD.js.map
9995
+ //# sourceMappingURL=chunk-HOMVJ2D3.js.map