@koda-sl/baker-cli 0.28.1 → 0.31.0-dev.31ee8d9c
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 +279 -15
- package/dist/cli.js +1 -1
- package/dist/commands/actions/complete.d.ts +2 -2
- package/dist/commands/actions/complete.d.ts.map +1 -1
- package/dist/commands/actions/complete.js +10 -8
- package/dist/commands/actions/complete.js.map +1 -1
- package/dist/commands/actions/shared.d.ts +1 -0
- package/dist/commands/actions/shared.d.ts.map +1 -1
- package/dist/commands/actions/shared.js +3 -0
- package/dist/commands/actions/shared.js.map +1 -1
- package/dist/commands/images/extract.d.ts +23 -0
- package/dist/commands/images/extract.d.ts.map +1 -0
- package/dist/commands/images/extract.js +53 -0
- package/dist/commands/images/extract.js.map +1 -0
- package/dist/commands/images/find.d.ts +33 -0
- package/dist/commands/images/find.d.ts.map +1 -0
- package/dist/commands/images/find.js +70 -0
- package/dist/commands/images/find.js.map +1 -0
- package/dist/commands/images/gif.d.ts +33 -0
- package/dist/commands/images/gif.d.ts.map +1 -0
- package/dist/commands/images/gif.js +81 -0
- package/dist/commands/images/gif.js.map +1 -0
- package/dist/commands/images/google.d.ts +38 -0
- package/dist/commands/images/google.d.ts.map +1 -0
- package/dist/commands/images/google.js +77 -0
- package/dist/commands/images/google.js.map +1 -0
- package/dist/commands/images/icon.d.ts +23 -0
- package/dist/commands/images/icon.d.ts.map +1 -0
- package/dist/commands/images/icon.js +57 -0
- package/dist/commands/images/icon.js.map +1 -0
- package/dist/commands/images/index.d.ts.map +1 -1
- package/dist/commands/images/index.js +45 -7
- package/dist/commands/images/index.js.map +1 -1
- package/dist/commands/images/ingest.d.ts +28 -0
- package/dist/commands/images/ingest.d.ts.map +1 -0
- package/dist/commands/images/ingest.js +60 -0
- package/dist/commands/images/ingest.js.map +1 -0
- package/dist/commands/images/library.d.ts +55 -0
- package/dist/commands/images/library.d.ts.map +1 -0
- package/dist/commands/images/library.js +86 -0
- package/dist/commands/images/library.js.map +1 -0
- package/dist/commands/images/logo.d.ts +18 -0
- package/dist/commands/images/logo.d.ts.map +1 -0
- package/dist/commands/images/logo.js +49 -0
- package/dist/commands/images/logo.js.map +1 -0
- package/dist/commands/images/meme.d.ts +28 -0
- package/dist/commands/images/meme.d.ts.map +1 -0
- package/dist/commands/images/meme.js +66 -0
- package/dist/commands/images/meme.js.map +1 -0
- package/dist/commands/images/screenshot.d.ts +23 -0
- package/dist/commands/images/screenshot.d.ts.map +1 -0
- package/dist/commands/images/screenshot.js +64 -0
- package/dist/commands/images/screenshot.js.map +1 -0
- package/dist/commands/images/search.d.ts.map +1 -1
- package/dist/commands/images/search.js +1 -0
- package/dist/commands/images/search.js.map +1 -1
- package/dist/commands/images/sticker.d.ts +33 -0
- package/dist/commands/images/sticker.d.ts.map +1 -0
- package/dist/commands/images/sticker.js +81 -0
- package/dist/commands/images/sticker.js.map +1 -0
- package/dist/commands/images/stock.d.ts +58 -0
- package/dist/commands/images/stock.d.ts.map +1 -0
- package/dist/commands/images/stock.js +116 -0
- package/dist/commands/images/stock.js.map +1 -0
- package/dist/commands/images/use.d.ts +18 -0
- package/dist/commands/images/use.d.ts.map +1 -0
- package/dist/commands/images/use.js +57 -0
- package/dist/commands/images/use.js.map +1 -0
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +1 -0
- package/dist/output.js.map +1 -1
- package/dist/output.test.js +1 -0
- package/dist/output.test.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1573,27 +1573,291 @@ Research data is cached server-side (shared across all callers). No local cache
|
|
|
1573
1573
|
|
|
1574
1574
|
### Assets (`baker images`, `baker videos`, `baker testimonials`)
|
|
1575
1575
|
|
|
1576
|
-
|
|
1576
|
+
#### Image sourcing — verb-per-provider overview
|
|
1577
1577
|
|
|
1578
|
-
|
|
1578
|
+
Each external source is its own subcommand. Pick the verb that matches the source — license, cost, and result shape are all provider-specific.
|
|
1579
|
+
|
|
1580
|
+
| Command | Purpose | Cost | Auto-ingest default |
|
|
1581
|
+
|---|---|---|---|
|
|
1582
|
+
| `baker images library <q>` | Hybrid library search (replaces `search`) | $0 | n/a |
|
|
1583
|
+
| `baker images find <q>` | Fanout: library + opted-in providers | sum of providers | off |
|
|
1584
|
+
| `baker images stock <q> [--type photo\|vector\|psd]` | Magnific (Freepik's dev API) — photos, vectors, illustrations, PSDs (~250M assets) | $0.002/req | off |
|
|
1585
|
+
| `baker images google <q>` | Google Images via the official Custom Search JSON API | $0 under 100/day, then $0.005/query | off |
|
|
1586
|
+
| `baker images logo <domain>` | Brand logo via Brandfetch CDN | $0 | **on** (top 1) |
|
|
1587
|
+
| `baker images icon <name>` | Iconify (200+ icon sets, no API key) | $0 | off (CDN URL is stable) |
|
|
1588
|
+
| `baker images gif <q>` | Reaction GIFs / memes via Giphy (paid-social creative) | $0 | off |
|
|
1589
|
+
| `baker images sticker <q>` | Transparent stickers via Giphy (overlay-friendly for ad creative) | $0 | off |
|
|
1590
|
+
| `baker images extract <url>` | Pull every image off a URL via Firecrawl | $0.001/scrape | off |
|
|
1591
|
+
| `baker images screenshot <url>` | Website screenshot via ScreenshotOne | $0.009/capture | **on** |
|
|
1592
|
+
| `baker images ingest <url>` | Save a remote URL to the library | ~$0.001–$0.002 (describe + embed) | always on |
|
|
1593
|
+
| `baker images use <url>` | Sugar over `ingest` — waits until `ready` | same as `ingest` | always on |
|
|
1594
|
+
| `baker images get <id>` | Single record | $0 | n/a |
|
|
1595
|
+
| `baker images upload <file>` | Upload a local file | $0 | always on |
|
|
1596
|
+
| `baker images delete <id>` | Delete a record | $0 | n/a |
|
|
1597
|
+
|
|
1598
|
+
**Auto-ingest** runs the full `processImage` pipeline (Gemini describe + Voyage multimodal embed + OpenRouter text embed, ~$0.001–$0.002/image) on top of the provider cost. Override with `--auto-ingest N` (turn on) or `--no-auto-ingest` (turn off where default is on). After auto-ingest the next `baker images library` query for the same concept hits the local row.
|
|
1599
|
+
|
|
1600
|
+
**Hash-dedup is automatic.** `contentHash` (sha256 of bytes) + `externalId` per-source — same JPEG from two providers becomes one library row.
|
|
1601
|
+
|
|
1602
|
+
**`baker images search` is a deprecated alias** for `library` (stderr deprecation log, removed in next minor).
|
|
1603
|
+
|
|
1604
|
+
**Migrating from Tenor:** the old `baker images meme` command and Tenor provider have been removed. Use `baker images gif` (Giphy) instead. Existing library rows ingested via Tenor remain stored with `source: "tenor"` but are no longer returned by `baker images find` and `--source tenor` is no longer a valid filter on `library`. Re-ingest via `baker images gif --auto-ingest N` if you need fresh equivalents.
|
|
1605
|
+
|
|
1606
|
+
### `baker images library <query>`
|
|
1607
|
+
|
|
1608
|
+
Search the company library (hybrid BM25 + vector + Cohere rerank). Use this FIRST before any external provider.
|
|
1609
|
+
|
|
1610
|
+
```bash
|
|
1611
|
+
baker images library "hero banner"
|
|
1612
|
+
baker images library "logo" --aspect-ratio 1:1 --tags logo
|
|
1613
|
+
baker images library "office" --source magnific
|
|
1614
|
+
baker images library "pricing" --external-url-host competitor.com
|
|
1615
|
+
```
|
|
1616
|
+
|
|
1617
|
+
**Flags:**
|
|
1618
|
+
|
|
1619
|
+
| Flag | Description |
|
|
1620
|
+
|-----------------------|--------------------------------------------------------------------------|
|
|
1621
|
+
| `--limit` | Max results (default 5) |
|
|
1622
|
+
| `--min-score` | Minimum relevance score, 0-1 |
|
|
1623
|
+
| `--aspect-ratio` | Filter by aspect ratio |
|
|
1624
|
+
| `--tags` | Comma-separated tag names |
|
|
1625
|
+
| `--source` | Filter by source (uploaded, magnific, brandfetch, google_images, firecrawl, screenshotone, iconify, giphy, …) |
|
|
1626
|
+
| `--external-url-host` | Filter by host substring of `externalUrl` (e.g. competitor.com) |
|
|
1627
|
+
| `--output` | Output format: `json` \| `files` \| `md` |
|
|
1628
|
+
| `--fields` | Comma-separated field names to include |
|
|
1629
|
+
| `--full` | Include full metadata |
|
|
1630
|
+
|
|
1631
|
+
> `baker images search` is a deprecated alias for `library` (emits a deprecation log on stderr; removed in the next minor).
|
|
1632
|
+
|
|
1633
|
+
### `baker images find <query> --sources <list>`
|
|
1634
|
+
|
|
1635
|
+
Fanout image search: library first, then opted-in providers in parallel.
|
|
1636
|
+
|
|
1637
|
+
```bash
|
|
1638
|
+
baker images find "office" --sources library,magnific --limit 20
|
|
1639
|
+
baker images find "office" --sources library,magnific --fallback --threshold 0.4
|
|
1640
|
+
baker images find "celebration" --sources library,giphy --auto-ingest 3
|
|
1641
|
+
```
|
|
1642
|
+
|
|
1643
|
+
Providers: `library`, `magnific`, `google`, `iconify`, `brandfetch`, `giphy`. Response shape: `{ groups: { library, external }, meta: { counts, errors } }`. Partial failures (one provider throws) return the successful providers plus a `meta.errors` array; the whole call never fails on a single provider error.
|
|
1644
|
+
|
|
1645
|
+
**Flags:**
|
|
1646
|
+
|
|
1647
|
+
| Flag | Description |
|
|
1648
|
+
|------------------|--------------------------------------------------------------------------------------------|
|
|
1649
|
+
| `--sources` | Comma-separated providers (default `library`) |
|
|
1650
|
+
| `--limit` | Max results per group (default 20, max 50) |
|
|
1651
|
+
| `--fallback` | Skip external providers when the top library score ≥ `--threshold` |
|
|
1652
|
+
| `--threshold` | Library score floor for `--fallback` (default `0.4`) |
|
|
1653
|
+
| `--auto-ingest` | Ingest top N external hits into the library (0–20, default 0) |
|
|
1654
|
+
|
|
1655
|
+
### `baker images stock <query>`
|
|
1656
|
+
|
|
1657
|
+
Stock search via **Magnific** — Freepik's developer API (post-acquisition rebrand — `api.magnific.com`, header `x-magnific-api-key`). One library, ~250M assets covering photos, vectors, illustrations, icon sets, mockups, PSDs.
|
|
1658
|
+
|
|
1659
|
+
```bash
|
|
1660
|
+
baker images stock "minimalist office"
|
|
1661
|
+
baker images stock "flat office workers" --type vector
|
|
1662
|
+
baker images stock "hero photo of a kitchen" --type photo --orientation landscape --ai exclude
|
|
1663
|
+
baker images stock "brand pattern" --color "#0a0a0a" --license freemium --auto-ingest 2
|
|
1664
|
+
baker images stock "office reaction" --people only
|
|
1665
|
+
```
|
|
1666
|
+
|
|
1667
|
+
Cost: $0.002/req. Free tier exists but watermarks previews — pass `--license freemium` to filter to clean free assets explicitly.
|
|
1668
|
+
|
|
1669
|
+
**Flags:**
|
|
1670
|
+
|
|
1671
|
+
| Flag | Description |
|
|
1672
|
+
|------------------|--------------------------------------------------------------------------------------------|
|
|
1673
|
+
| `--type` | Content type: `photo \| vector \| psd` |
|
|
1674
|
+
| `--orientation` | `landscape \| portrait \| square \| panoramic` |
|
|
1675
|
+
| `--license` | `freemium` (free with attribution) or `premium` (paid, watermark-free) |
|
|
1676
|
+
| `--color` | Hex color filter (`#0a0a0a` or `0a0a0a`) |
|
|
1677
|
+
| `--ai` | AI-generated filter: `exclude` or `only` (default: no filter) |
|
|
1678
|
+
| `--people` | People-in-image filter: `include` \| `exclude` \| `only` |
|
|
1679
|
+
| `--order` | `relevance` (default) or `recent` |
|
|
1680
|
+
| `--limit` | Max results (1–50, default 10) |
|
|
1681
|
+
| `--page` | Page number for pagination |
|
|
1682
|
+
| `--auto-ingest` | Ingest top N hits (0–20, default 0) |
|
|
1683
|
+
|
|
1684
|
+
### `baker images google <query>`
|
|
1685
|
+
|
|
1686
|
+
Google Images via the official Custom Search JSON API. ⚠ Source is unverified web content — inspect before placing.
|
|
1687
|
+
|
|
1688
|
+
```bash
|
|
1689
|
+
baker images google "industrial workshop" --type photo --size large --limit 20
|
|
1690
|
+
```
|
|
1691
|
+
|
|
1692
|
+
Cost: $0.005/query above the free tier (100 queries/day free). Custom Search caps at 10 results per call — pagination is automatic and bills per page (`--limit 30` = 3 queries against your daily quota).
|
|
1693
|
+
|
|
1694
|
+
Requires both `GOOGLE_CUSTOM_SEARCH_API_KEY` and `GOOGLE_CUSTOM_SEARCH_ENGINE_ID` (Programmable Search Engine `cx`) set on the Convex deployment, with the engine configured to "Search the entire web" + Image search ON.
|
|
1695
|
+
|
|
1696
|
+
**Flags:**
|
|
1697
|
+
|
|
1698
|
+
| Flag | Description |
|
|
1699
|
+
|------------------|----------------------------------------------------------------------------------------------------------|
|
|
1700
|
+
| `--type` | `imgType`: `photo \| clipart \| lineart \| stock \| animated \| face \| news` |
|
|
1701
|
+
| `--size` | `imgSize`: `icon \| small \| medium \| large \| xlarge \| xxlarge \| huge` |
|
|
1702
|
+
| `--color` | `imgColorType`: `color \| gray \| mono \| trans` |
|
|
1703
|
+
| `--safe` | `off \| active` |
|
|
1704
|
+
| `--limit` | Max results (1–50, paginated 10 per call) |
|
|
1705
|
+
| `--auto-ingest` | Ingest top N (0–20, default 0) |
|
|
1706
|
+
|
|
1707
|
+
### `baker images logo <domain>`
|
|
1708
|
+
|
|
1709
|
+
Brand logo via Brandfetch CDN (`fallback/404`). Returns up to 5 variants per domain (icon, light/dark logo, light/dark symbol). Auto-ingests the first by default.
|
|
1710
|
+
|
|
1711
|
+
```bash
|
|
1712
|
+
baker images logo stripe.com
|
|
1713
|
+
baker images logo linear.app --variant logo
|
|
1714
|
+
baker images logo example.com --no-auto-ingest
|
|
1715
|
+
```
|
|
1716
|
+
|
|
1717
|
+
If the domain isn't in Brandfetch the result is empty — fall back to `baker images extract https://<domain>` to pull the logo from the site directly.
|
|
1718
|
+
|
|
1719
|
+
**Flags:**
|
|
1720
|
+
|
|
1721
|
+
| Flag | Description |
|
|
1722
|
+
|---------------------|--------------------------------------------------------------------------|
|
|
1723
|
+
| `--variant` | Pin to one variant: `icon \| logo \| symbol` (default: try all 5) |
|
|
1724
|
+
| `--no-auto-ingest` | Skip the default top-1 ingest |
|
|
1725
|
+
|
|
1726
|
+
### `baker images icon <name> [--set <set>]`
|
|
1727
|
+
|
|
1728
|
+
Icon lookup via Iconify (200+ icon sets). Free, no API key.
|
|
1729
|
+
|
|
1730
|
+
```bash
|
|
1731
|
+
baker images icon react --set devicon
|
|
1732
|
+
baker images icon lucide:check --color "#0a0a0a" --width 24
|
|
1733
|
+
baker images icon stripe # tries simple-icons → logos → devicon
|
|
1734
|
+
```
|
|
1735
|
+
|
|
1736
|
+
Pass a prefixed id (`lucide:check`) to pin both set and name explicitly. Without `--set`, the lookup chain is `simple-icons → logos → devicon`.
|
|
1737
|
+
|
|
1738
|
+
**Flags:**
|
|
1739
|
+
|
|
1740
|
+
| Flag | Description |
|
|
1741
|
+
|------------|------------------------------------------------------------------------------------------------------|
|
|
1742
|
+
| `--set` | Iconify set (`simple-icons`, `logos`, `lucide`, `devicon`, `heroicons`, `tabler`, `phosphor`, …) |
|
|
1743
|
+
| `--color` | Hex color — replaces `currentColor` in the SVG |
|
|
1744
|
+
| `--width` | Render width in px (height auto-scales) |
|
|
1745
|
+
|
|
1746
|
+
### `baker images gif <query>`
|
|
1747
|
+
|
|
1748
|
+
Search **Giphy** for GIFs / reaction memes — built for paid-social creative (Meta, TikTok, LinkedIn, X). Free API, no per-request cost. Replaces the discontinued Tenor integration.
|
|
1749
|
+
|
|
1750
|
+
```bash
|
|
1751
|
+
baker images gif "this is fine" --limit 10
|
|
1752
|
+
baker images gif "office reaction" --rating pg --auto-ingest 2
|
|
1753
|
+
baker images gif "celebration" --lang es
|
|
1754
|
+
baker images gif --trending --limit 25
|
|
1755
|
+
```
|
|
1756
|
+
|
|
1757
|
+
Each hit returns the primary URL (WebP — best for ingest) plus `providerMeta.gifUrl`, `providerMeta.mp4Url`, `providerMeta.webpUrl` so you can pick the right format per platform. `providerMeta.kind` is `"gif"`. `externalUrl` points at the Giphy permalink for verification.
|
|
1758
|
+
|
|
1759
|
+
**Flags:**
|
|
1760
|
+
|
|
1761
|
+
| Flag | Description |
|
|
1762
|
+
|------------------|--------------------------------------------------------------------------------------------|
|
|
1763
|
+
| `--trending` | Fetch the current trending feed (omit `<query>` when set) |
|
|
1764
|
+
| `--limit` | Max results (default 20, max 50) |
|
|
1765
|
+
| `--rating` | Content rating: `g \| pg \| pg-13 \| r` (default `pg`) |
|
|
1766
|
+
| `--lang` | ISO 639-1 language code (`en`, `es`, `fr`, …) to bias results |
|
|
1767
|
+
| `--auto-ingest` | Ingest top N (0–20, default 0). Ingest uses the WebP URL; `processImage` partial-fails on animated GIFs (no thumbhash/palette) but describe + embed still work. |
|
|
1768
|
+
|
|
1769
|
+
### `baker images sticker <query>`
|
|
1770
|
+
|
|
1771
|
+
Search **Giphy's sticker corpus** — same API as `gif`, different corpus. Stickers are transparent-background WebPs / GIFs, ideal for overlaying on ad creative (Stories, Reels, banners).
|
|
1772
|
+
|
|
1773
|
+
```bash
|
|
1774
|
+
baker images sticker "thumbs up" --limit 10
|
|
1775
|
+
baker images sticker celebration --rating g --auto-ingest 3
|
|
1776
|
+
baker images sticker --trending --limit 25
|
|
1777
|
+
```
|
|
1778
|
+
|
|
1779
|
+
Same response shape as `gif`. `providerMeta.kind` is `"sticker"`; `externalUrl` points at `https://giphy.com/stickers/<id>`.
|
|
1780
|
+
|
|
1781
|
+
**Flags:** identical to `baker images gif` (`--trending`, `--limit`, `--rating`, `--lang`, `--auto-ingest`).
|
|
1782
|
+
|
|
1783
|
+
### `baker images extract <url>`
|
|
1784
|
+
|
|
1785
|
+
Pull every image from a single URL via Firecrawl (`formats: ["images"]`).
|
|
1786
|
+
|
|
1787
|
+
```bash
|
|
1788
|
+
baker images extract https://stripe.com --auto-ingest 5
|
|
1789
|
+
baker images extract https://example.com --wait-for 1500 --limit 20
|
|
1790
|
+
```
|
|
1791
|
+
|
|
1792
|
+
Every image extracted from a page shares the scraped-page URL as `externalUrl`. Big pages can return 100+ images — cap auto-ingest at 20.
|
|
1793
|
+
|
|
1794
|
+
Cost: $0.001/scrape. JS-rendered pages with `--wait-for` cost the heavier credit bucket.
|
|
1795
|
+
|
|
1796
|
+
**Flags:**
|
|
1797
|
+
|
|
1798
|
+
| Flag | Description |
|
|
1799
|
+
|------------------|--------------------------------------------------------------------------------------------|
|
|
1800
|
+
| `--wait-for` | JS render wait in ms (0–30000) |
|
|
1801
|
+
| `--limit` | Max images returned (default 50) |
|
|
1802
|
+
| `--auto-ingest` | Ingest top N (0–20, default 0) |
|
|
1803
|
+
|
|
1804
|
+
### `baker images screenshot <url>`
|
|
1805
|
+
|
|
1806
|
+
Capture a website screenshot via ScreenshotOne. Auto-ingests on success.
|
|
1807
|
+
|
|
1808
|
+
```bash
|
|
1809
|
+
baker images screenshot https://stripe.com
|
|
1810
|
+
baker images screenshot https://stripe.com --full-page --viewport 1440x900
|
|
1811
|
+
baker images screenshot https://stripe.com --format png
|
|
1812
|
+
```
|
|
1813
|
+
|
|
1814
|
+
Auto-ingests with prefetched bytes (no double-fetch). The screenshot bytes themselves are the artifact — `externalUrl` is the captured URL.
|
|
1815
|
+
|
|
1816
|
+
Cost: $0.009/capture. ScreenshotOne caches captures for 30 days, so re-shotting the same URL within that window is cheap.
|
|
1817
|
+
|
|
1818
|
+
**Flags:**
|
|
1819
|
+
|
|
1820
|
+
| Flag | Description |
|
|
1821
|
+
|----------------|--------------------------------------------------------------------------------------------|
|
|
1822
|
+
| `--full-page` | Capture the full scrolled page (default: viewport only) |
|
|
1823
|
+
| `--viewport` | `WxH` viewport (default `1280x800`) |
|
|
1824
|
+
| `--format` | `webp \| png \| jpg` (default `webp`) |
|
|
1825
|
+
|
|
1826
|
+
### `baker images ingest <url> --source <enum>`
|
|
1827
|
+
|
|
1828
|
+
Download a remote URL and store it in the library. Byte-exact deduped via sha256 + externalId, then queued for describe + embed.
|
|
1829
|
+
|
|
1830
|
+
```bash
|
|
1831
|
+
baker images ingest https://img.freepik.com/free-photo/xyz.jpg --source magnific --external-id 12345
|
|
1832
|
+
baker images ingest https://acme.com/hero.png --source firecrawl --external-url https://acme.com/pricing --context "competitor pricing hero"
|
|
1833
|
+
```
|
|
1834
|
+
|
|
1835
|
+
Returns `{ imageId, deduped, contentHash }`. When `deduped: true`, an existing library row is returned — no new bytes are stored. Max ingest size 25MB.
|
|
1836
|
+
|
|
1837
|
+
**Flags:**
|
|
1838
|
+
|
|
1839
|
+
| Flag | Description |
|
|
1840
|
+
|------------------|--------------------------------------------------------------------------------------------|
|
|
1841
|
+
| `--source` | **Required.** Source enum (`uploaded`, `magnific`, `brandfetch`, `google_images`, `firecrawl`, `screenshotone`, `iconify`, `giphy`, `instagram`, …) |
|
|
1842
|
+
| `--external-id` | Provider asset id — enables per-source dedup before bytes are fetched |
|
|
1843
|
+
| `--external-url` | Canonical page URL (parent page for scraped/Google hits, provider page for stock) |
|
|
1844
|
+
| `--context` | Free-text hint passed to Gemini describe to bias the generated description and tags |
|
|
1845
|
+
|
|
1846
|
+
### `baker images use <url>`
|
|
1847
|
+
|
|
1848
|
+
Sugar over `ingest`: stores the URL and polls `get` until the library record is `ready` (or errored). Returns the ingest result plus the ready image doc — synchronous from the agent's perspective.
|
|
1579
1849
|
|
|
1580
1850
|
```bash
|
|
1581
|
-
baker images
|
|
1582
|
-
baker images
|
|
1583
|
-
baker images search "team photo" --limit 5 --min-score 0.3
|
|
1851
|
+
baker images use https://cdn.example.com/hero.png
|
|
1852
|
+
baker images use https://cdn.example.com/hero.png --source magnific --max-wait 60000
|
|
1584
1853
|
```
|
|
1585
1854
|
|
|
1586
1855
|
**Flags:**
|
|
1587
1856
|
|
|
1588
|
-
| Flag
|
|
1589
|
-
|
|
1590
|
-
| `--
|
|
1591
|
-
| `--
|
|
1592
|
-
| `--aspect-ratio` | Filter by aspect ratio (1:1, 16:9, 9:16, 2:3, 3:4, 1:2, 2:1, 4:5, 3:2, 4:3) |
|
|
1593
|
-
| `--tags` | Comma-separated tag names to filter by |
|
|
1594
|
-
| `--output` | Output format: `json` \| `files` \| `md` |
|
|
1595
|
-
| `--fields` | Comma-separated field names to include |
|
|
1596
|
-
| `--full` | Include full metadata |
|
|
1857
|
+
| Flag | Description |
|
|
1858
|
+
|----------------|--------------------------------------------------------------------------------------------|
|
|
1859
|
+
| `--source` | Source enum (default `uploaded`) |
|
|
1860
|
+
| `--max-wait` | Max wait ms before returning `TIMEOUT` (default `30000`, polled every 1500ms) |
|
|
1597
1861
|
|
|
1598
1862
|
### `baker images get <id>`
|
|
1599
1863
|
|
|
@@ -1694,7 +1958,7 @@ baker actions release <action-id>
|
|
|
1694
1958
|
baker actions create --name "Build hero" --description "..." --tag copy,landing
|
|
1695
1959
|
# → returns { ok, data: { tempId }, hints: [...] } — check hints for dependencies/tags/description reminders
|
|
1696
1960
|
baker actions update <action-id> --name "Better name"
|
|
1697
|
-
baker actions complete <action-id> --note "What was done" # stages — applies on chat publish
|
|
1961
|
+
baker actions complete <action-id-or-tempId> --note "What was done" # stages — applies on chat publish
|
|
1698
1962
|
baker actions discard <action-id> --reason "obsolete"
|
|
1699
1963
|
|
|
1700
1964
|
baker actions link --blocker <id-or-tempId> --blocked <id-or-tempId>
|
package/dist/cli.js
CHANGED
|
@@ -12,7 +12,7 @@ import { videosCommand } from "./commands/videos/index.js";
|
|
|
12
12
|
const main = defineCommand({
|
|
13
13
|
meta: {
|
|
14
14
|
name: "baker",
|
|
15
|
-
version: "0.
|
|
15
|
+
version: "0.32.0",
|
|
16
16
|
description: `AI-agent CLI for finding and managing images, videos, testimonials, action items, and ad platform data in Baker.
|
|
17
17
|
|
|
18
18
|
Auth: Set BAKER_API_KEY (starts with bk_) and BAKER_API_URL environment variables.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export declare const completeCommand: import("citty").CommandDef<{
|
|
2
2
|
readonly id: {
|
|
3
3
|
readonly type: "positional";
|
|
4
|
-
readonly description: "Action ID";
|
|
4
|
+
readonly description: "Action ID or temp ID";
|
|
5
5
|
readonly required: false;
|
|
6
6
|
};
|
|
7
7
|
readonly "action-id": {
|
|
8
8
|
readonly type: "string";
|
|
9
|
-
readonly description: "Action ID";
|
|
9
|
+
readonly description: "Action ID or temp ID";
|
|
10
10
|
readonly required: false;
|
|
11
11
|
};
|
|
12
12
|
readonly note: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../../../src/commands/actions/complete.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../../../src/commands/actions/complete.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;EA2B1B,CAAC"}
|
|
@@ -2,23 +2,23 @@ import { defineCommand } from "citty";
|
|
|
2
2
|
import { apiPost, validateConvexId } from "../../client.js";
|
|
3
3
|
import { requireChatId } from "../../env.js";
|
|
4
4
|
import { registerSchema } from "../../schemas.js";
|
|
5
|
-
import { failApi, failValidation, writeOk } from "./shared.js";
|
|
5
|
+
import { failApi, failValidation, isTempId, writeOk } from "./shared.js";
|
|
6
6
|
registerSchema({
|
|
7
7
|
command: "actions.complete",
|
|
8
|
-
description: "Stage completion of
|
|
8
|
+
description: "Stage completion of an action. Accepts a real action ID (must be claimed) or a temp ID from the same draft. The action becomes completed when the chat is published.",
|
|
9
9
|
args: {
|
|
10
|
-
id: { type: "string", description: "Action ID
|
|
10
|
+
id: { type: "string", description: "Action ID or temp ID", required: true },
|
|
11
11
|
note: { type: "string", description: "What was done — context for the team and AI", required: false },
|
|
12
12
|
},
|
|
13
13
|
});
|
|
14
14
|
export const completeCommand = defineCommand({
|
|
15
15
|
meta: {
|
|
16
16
|
name: "complete",
|
|
17
|
-
description: "Stage completion of
|
|
17
|
+
description: "Stage completion of an action. Accepts real IDs (claimed) or temp IDs (same draft). Example: baker actions complete <id>",
|
|
18
18
|
},
|
|
19
19
|
args: {
|
|
20
|
-
id: { type: "positional", description: "Action ID", required: false },
|
|
21
|
-
"action-id": { type: "string", description: "Action ID", required: false },
|
|
20
|
+
id: { type: "positional", description: "Action ID or temp ID", required: false },
|
|
21
|
+
"action-id": { type: "string", description: "Action ID or temp ID", required: false },
|
|
22
22
|
note: { type: "string", description: "What was done — context for the team and AI", required: false },
|
|
23
23
|
},
|
|
24
24
|
run: async ({ args }) => {
|
|
@@ -27,9 +27,11 @@ export const completeCommand = defineCommand({
|
|
|
27
27
|
if (!id) {
|
|
28
28
|
failValidation("Action ID is required.");
|
|
29
29
|
}
|
|
30
|
-
|
|
30
|
+
if (!isTempId(id)) {
|
|
31
|
+
validateConvexId(id);
|
|
32
|
+
}
|
|
31
33
|
const chatId = requireChatId();
|
|
32
|
-
await apiPost("/api/actions/complete", { chatId,
|
|
34
|
+
await apiPost("/api/actions/complete", { chatId, actionRef: id, note: args.note });
|
|
33
35
|
writeOk();
|
|
34
36
|
}
|
|
35
37
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"complete.js","sourceRoot":"","sources":["../../../src/commands/actions/complete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"complete.js","sourceRoot":"","sources":["../../../src/commands/actions/complete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEzE,cAAc,CAAC;IACb,OAAO,EAAE,kBAAkB;IAC3B,WAAW,EACT,sKAAsK;IACxK,IAAI,EAAE;QACJ,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sBAAsB,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC3E,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6CAA6C,EAAE,QAAQ,EAAE,KAAK,EAAE;KACtG;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAAC;IAC3C,IAAI,EAAE;QACJ,IAAI,EAAE,UAAU;QAChB,WAAW,EACT,0HAA0H;KAC7H;IACD,IAAI,EAAE;QACJ,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,sBAAsB,EAAE,QAAQ,EAAE,KAAK,EAAE;QAChF,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sBAAsB,EAAE,QAAQ,EAAE,KAAK,EAAE;QACrF,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6CAA6C,EAAE,QAAQ,EAAE,KAAK,EAAE;KACtG;IACD,GAAG,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACtB,IAAI,CAAC;YACH,MAAM,EAAE,GAAI,IAAI,CAAC,EAAyB,IAAK,IAAI,CAAC,WAAW,CAAwB,CAAC;YACxF,IAAI,CAAC,EAAE,EAAE,CAAC;gBACR,cAAc,CAAC,wBAAwB,CAAC,CAAC;YAC3C,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;gBAClB,gBAAgB,CAAC,EAAE,CAAC,CAAC;YACvB,CAAC;YACD,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;YAC/B,MAAM,OAAO,CAAe,uBAAuB,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YACjG,OAAO,EAAE,CAAC;QACZ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,CAAC;QACf,CAAC;IACH,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -2,4 +2,5 @@ export declare function writeOk<T = null>(data?: T): void;
|
|
|
2
2
|
export declare function failValidation(message: string): never;
|
|
3
3
|
export declare function failApi(err: unknown): never;
|
|
4
4
|
export declare function generateTempId(): string;
|
|
5
|
+
export declare function isTempId(id: string): boolean;
|
|
5
6
|
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/commands/actions/shared.ts"],"names":[],"mappings":"AAGA,wBAAgB,OAAO,CAAC,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAEhD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAGrD;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,CAW3C;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC"}
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/commands/actions/shared.ts"],"names":[],"mappings":"AAGA,wBAAgB,OAAO,CAAC,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAEhD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAGrD;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,CAW3C;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE5C"}
|
|
@@ -22,4 +22,7 @@ export function failApi(err) {
|
|
|
22
22
|
export function generateTempId() {
|
|
23
23
|
return `temp_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
24
24
|
}
|
|
25
|
+
export function isTempId(id) {
|
|
26
|
+
return id.startsWith("temp_");
|
|
27
|
+
}
|
|
25
28
|
//# sourceMappingURL=shared.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/commands/actions/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,UAAU,OAAO,CAAW,IAAQ;IACxC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,IAAI,CAAM,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;IACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,GAAY;IAClC,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;QAC5B,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAClF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;IACzF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,QAAQ,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AACtF,CAAC"}
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/commands/actions/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,UAAU,OAAO,CAAW,IAAQ;IACxC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,IAAI,CAAM,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;IACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,GAAY;IAClC,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;QAC5B,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAClF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;IACzF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,QAAQ,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,EAAU;IACjC,OAAO,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare const extractCommand: import("citty").CommandDef<{
|
|
2
|
+
readonly url: {
|
|
3
|
+
readonly type: "positional";
|
|
4
|
+
readonly description: "URL to scrape";
|
|
5
|
+
readonly required: false;
|
|
6
|
+
};
|
|
7
|
+
readonly "wait-for": {
|
|
8
|
+
readonly type: "string";
|
|
9
|
+
readonly description: "JS render wait ms";
|
|
10
|
+
readonly required: false;
|
|
11
|
+
};
|
|
12
|
+
readonly limit: {
|
|
13
|
+
readonly type: "string";
|
|
14
|
+
readonly description: "Max returned images";
|
|
15
|
+
readonly required: false;
|
|
16
|
+
};
|
|
17
|
+
readonly "auto-ingest": {
|
|
18
|
+
readonly type: "string";
|
|
19
|
+
readonly description: "Auto-ingest top N";
|
|
20
|
+
readonly required: false;
|
|
21
|
+
};
|
|
22
|
+
}>;
|
|
23
|
+
//# sourceMappingURL=extract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../../src/commands/images/extract.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;EAmCzB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { defineCommand } from "citty";
|
|
2
|
+
import { ApiError, apiPost } from "../../client.js";
|
|
3
|
+
import { writeJson } from "../../output.js";
|
|
4
|
+
import { registerSchema } from "../../schemas.js";
|
|
5
|
+
registerSchema({
|
|
6
|
+
command: "images.extract",
|
|
7
|
+
description: "Extract images from a URL via Firecrawl (formats: images).",
|
|
8
|
+
args: {
|
|
9
|
+
url: { type: "string", description: "URL to scrape", required: true },
|
|
10
|
+
"wait-for": { type: "number", description: "JS render wait ms", required: false },
|
|
11
|
+
limit: { type: "number", description: "Limit returned images", required: false, default: 50 },
|
|
12
|
+
"auto-ingest": { type: "number", description: "Auto-ingest top N", required: false, default: 0 },
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
export const extractCommand = defineCommand({
|
|
16
|
+
meta: {
|
|
17
|
+
name: "extract",
|
|
18
|
+
description: "Pull every image from a single URL via Firecrawl. ~$0.001/scrape. Cap auto-ingest at 20.\n\nExample: baker images extract https://stripe.com --auto-ingest 5",
|
|
19
|
+
},
|
|
20
|
+
args: {
|
|
21
|
+
url: { type: "positional", description: "URL to scrape", required: false },
|
|
22
|
+
"wait-for": { type: "string", description: "JS render wait ms", required: false },
|
|
23
|
+
limit: { type: "string", description: "Max returned images", required: false },
|
|
24
|
+
"auto-ingest": { type: "string", description: "Auto-ingest top N", required: false },
|
|
25
|
+
},
|
|
26
|
+
run: async ({ args }) => {
|
|
27
|
+
try {
|
|
28
|
+
const url = args.url;
|
|
29
|
+
if (!url) {
|
|
30
|
+
writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: "URL is required" } });
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
const body = { url };
|
|
34
|
+
if (args["wait-for"])
|
|
35
|
+
body.waitFor = Number(args["wait-for"]);
|
|
36
|
+
if (args.limit)
|
|
37
|
+
body.limit = Number(args.limit);
|
|
38
|
+
if (args["auto-ingest"])
|
|
39
|
+
body.autoIngest = Number(args["auto-ingest"]);
|
|
40
|
+
const data = await apiPost("/api/images/extract", body);
|
|
41
|
+
writeJson({ ok: true, data });
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
if (err instanceof ApiError) {
|
|
45
|
+
writeJson({ ok: false, error: { code: err.code, message: err.message } });
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: "Unexpected error" } });
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=extract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.js","sourceRoot":"","sources":["../../../src/commands/images/extract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare const findCommand: import("citty").CommandDef<{
|
|
2
|
+
readonly query: {
|
|
3
|
+
readonly type: "positional";
|
|
4
|
+
readonly description: "Search query";
|
|
5
|
+
readonly required: false;
|
|
6
|
+
};
|
|
7
|
+
readonly sources: {
|
|
8
|
+
readonly type: "string";
|
|
9
|
+
readonly description: "Comma-separated providers";
|
|
10
|
+
readonly required: false;
|
|
11
|
+
};
|
|
12
|
+
readonly limit: {
|
|
13
|
+
readonly type: "string";
|
|
14
|
+
readonly description: "Max results per group (default 20)";
|
|
15
|
+
readonly required: false;
|
|
16
|
+
};
|
|
17
|
+
readonly fallback: {
|
|
18
|
+
readonly type: "boolean";
|
|
19
|
+
readonly description: "Cascade to externals only when library thin";
|
|
20
|
+
readonly required: false;
|
|
21
|
+
};
|
|
22
|
+
readonly threshold: {
|
|
23
|
+
readonly type: "string";
|
|
24
|
+
readonly description: "Fallback threshold (default 0.4)";
|
|
25
|
+
readonly required: false;
|
|
26
|
+
};
|
|
27
|
+
readonly "auto-ingest": {
|
|
28
|
+
readonly type: "string";
|
|
29
|
+
readonly description: "Auto-ingest top N external hits";
|
|
30
|
+
readonly required: false;
|
|
31
|
+
};
|
|
32
|
+
}>;
|
|
33
|
+
//# sourceMappingURL=find.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../../src/commands/images/find.ts"],"names":[],"mappings":"AA2BA,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuCtB,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { defineCommand } from "citty";
|
|
2
|
+
import { ApiError, apiPost } from "../../client.js";
|
|
3
|
+
import { writeJson } from "../../output.js";
|
|
4
|
+
import { registerSchema } from "../../schemas.js";
|
|
5
|
+
registerSchema({
|
|
6
|
+
command: "images.find",
|
|
7
|
+
description: "Fanout image search: library first, then opted-in external providers.",
|
|
8
|
+
args: {
|
|
9
|
+
query: { type: "string", description: "Search query", required: true },
|
|
10
|
+
sources: {
|
|
11
|
+
type: "string",
|
|
12
|
+
description: "Comma-separated providers: library,magnific,google,iconify,brandfetch,giphy",
|
|
13
|
+
required: false,
|
|
14
|
+
},
|
|
15
|
+
limit: { type: "number", description: "Max results per group", required: false, default: 20 },
|
|
16
|
+
fallback: {
|
|
17
|
+
type: "boolean",
|
|
18
|
+
description: "Only cascade to externals when top library score < threshold",
|
|
19
|
+
required: false,
|
|
20
|
+
default: false,
|
|
21
|
+
},
|
|
22
|
+
threshold: { type: "number", description: "Fallback threshold (0-1)", required: false, default: 0.4 },
|
|
23
|
+
"auto-ingest": { type: "number", description: "Auto-ingest top N external hits", required: false, default: 0 },
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
export const findCommand = defineCommand({
|
|
27
|
+
meta: {
|
|
28
|
+
name: "find",
|
|
29
|
+
description: "Library-first fanout image search. Opt in to providers with --sources. `--fallback` short-circuits to externals only when library is thin.\n\nExample: baker images find 'office' --sources library,magnific --limit 20",
|
|
30
|
+
},
|
|
31
|
+
args: {
|
|
32
|
+
query: { type: "positional", description: "Search query", required: false },
|
|
33
|
+
sources: { type: "string", description: "Comma-separated providers", required: false },
|
|
34
|
+
limit: { type: "string", description: "Max results per group (default 20)", required: false },
|
|
35
|
+
fallback: { type: "boolean", description: "Cascade to externals only when library thin", required: false },
|
|
36
|
+
threshold: { type: "string", description: "Fallback threshold (default 0.4)", required: false },
|
|
37
|
+
"auto-ingest": { type: "string", description: "Auto-ingest top N external hits", required: false },
|
|
38
|
+
},
|
|
39
|
+
run: async ({ args }) => {
|
|
40
|
+
try {
|
|
41
|
+
const query = args.query;
|
|
42
|
+
if (!query) {
|
|
43
|
+
writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: "Query is required" } });
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
const body = { query };
|
|
47
|
+
if (args.sources)
|
|
48
|
+
body.sources = args.sources.split(",").filter(Boolean);
|
|
49
|
+
if (args.limit)
|
|
50
|
+
body.limit = Number(args.limit);
|
|
51
|
+
if (args.fallback)
|
|
52
|
+
body.fallback = true;
|
|
53
|
+
if (args.threshold)
|
|
54
|
+
body.threshold = Number(args.threshold);
|
|
55
|
+
if (args["auto-ingest"])
|
|
56
|
+
body.autoIngest = Number(args["auto-ingest"]);
|
|
57
|
+
const data = await apiPost("/api/images/find", body);
|
|
58
|
+
writeJson({ ok: true, data });
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
if (err instanceof ApiError) {
|
|
62
|
+
writeJson({ ok: false, error: { code: err.code, message: err.message } });
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: "Unexpected error" } });
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
//# sourceMappingURL=find.js.map
|