@koda-sl/baker-cli 0.5.1 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +718 -162
- package/dist/cli.js +7 -3
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +7 -1
- package/dist/client.js.map +1 -1
- package/dist/commands/ads/cache.d.ts +7 -0
- package/dist/commands/ads/cache.d.ts.map +1 -0
- package/dist/commands/ads/cache.js +73 -0
- package/dist/commands/ads/cache.js.map +1 -0
- package/dist/commands/ads/cache.test.d.ts +2 -0
- package/dist/commands/ads/cache.test.d.ts.map +1 -0
- package/dist/commands/ads/cache.test.js +44 -0
- package/dist/commands/ads/cache.test.js.map +1 -0
- package/dist/commands/ads/field-descriptions.d.ts +2 -0
- package/dist/commands/ads/field-descriptions.d.ts.map +1 -0
- package/dist/commands/ads/field-descriptions.js +91 -0
- package/dist/commands/ads/field-descriptions.js.map +1 -0
- package/dist/commands/ads/google/accounts.d.ts +14 -0
- package/dist/commands/ads/google/accounts.d.ts.map +1 -0
- package/dist/commands/ads/google/accounts.js +73 -0
- package/dist/commands/ads/google/accounts.js.map +1 -0
- package/dist/commands/ads/google/changes.d.ts +34 -0
- package/dist/commands/ads/google/changes.d.ts.map +1 -0
- package/dist/commands/ads/google/changes.js +80 -0
- package/dist/commands/ads/google/changes.js.map +1 -0
- package/dist/commands/ads/google/correction-table.d.ts +3 -0
- package/dist/commands/ads/google/correction-table.d.ts.map +1 -0
- package/dist/commands/ads/google/correction-table.js +340 -0
- package/dist/commands/ads/google/correction-table.js.map +1 -0
- package/dist/commands/ads/google/currency.d.ts +13 -0
- package/dist/commands/ads/google/currency.d.ts.map +1 -0
- package/dist/commands/ads/google/currency.js +68 -0
- package/dist/commands/ads/google/currency.js.map +1 -0
- package/dist/commands/ads/google/error-parser.d.ts +3 -0
- package/dist/commands/ads/google/error-parser.d.ts.map +1 -0
- package/dist/commands/ads/google/error-parser.js +91 -0
- package/dist/commands/ads/google/error-parser.js.map +1 -0
- package/dist/commands/ads/google/error-parser.test.d.ts +2 -0
- package/dist/commands/ads/google/error-parser.test.d.ts.map +1 -0
- package/dist/commands/ads/google/error-parser.test.js +48 -0
- package/dist/commands/ads/google/error-parser.test.js.map +1 -0
- package/dist/commands/ads/google/index.d.ts +2 -0
- package/dist/commands/ads/google/index.d.ts.map +1 -0
- package/dist/commands/ads/google/index.js +30 -0
- package/dist/commands/ads/google/index.js.map +1 -0
- package/dist/commands/ads/google/keywords/discover.d.ts +49 -0
- package/dist/commands/ads/google/keywords/discover.d.ts.map +1 -0
- package/dist/commands/ads/google/keywords/discover.js +139 -0
- package/dist/commands/ads/google/keywords/discover.js.map +1 -0
- package/dist/commands/ads/google/keywords/index.d.ts +2 -0
- package/dist/commands/ads/google/keywords/index.d.ts.map +1 -0
- package/dist/commands/ads/google/keywords/index.js +18 -0
- package/dist/commands/ads/google/keywords/index.js.map +1 -0
- package/dist/commands/ads/google/keywords/metrics.d.ts +34 -0
- package/dist/commands/ads/google/keywords/metrics.d.ts.map +1 -0
- package/dist/commands/ads/google/keywords/metrics.js +111 -0
- package/dist/commands/ads/google/keywords/metrics.js.map +1 -0
- package/dist/commands/ads/google/preflight.d.ts +3 -0
- package/dist/commands/ads/google/preflight.d.ts.map +1 -0
- package/dist/commands/ads/google/preflight.js +115 -0
- package/dist/commands/ads/google/preflight.js.map +1 -0
- package/dist/commands/ads/google/preflight.test.d.ts +2 -0
- package/dist/commands/ads/google/preflight.test.d.ts.map +1 -0
- package/dist/commands/ads/google/preflight.test.js +50 -0
- package/dist/commands/ads/google/preflight.test.js.map +1 -0
- package/dist/commands/ads/google/presets.d.ts +12 -0
- package/dist/commands/ads/google/presets.d.ts.map +1 -0
- package/dist/commands/ads/google/presets.js +71 -0
- package/dist/commands/ads/google/presets.js.map +1 -0
- package/dist/commands/ads/google/presets.test.d.ts +2 -0
- package/dist/commands/ads/google/presets.test.d.ts.map +1 -0
- package/dist/commands/ads/google/presets.test.js +79 -0
- package/dist/commands/ads/google/presets.test.js.map +1 -0
- package/dist/commands/ads/google/query.d.ts +64 -0
- package/dist/commands/ads/google/query.d.ts.map +1 -0
- package/dist/commands/ads/google/query.js +304 -0
- package/dist/commands/ads/google/query.js.map +1 -0
- package/dist/commands/ads/index.d.ts +2 -0
- package/dist/commands/ads/index.d.ts.map +1 -0
- package/dist/commands/ads/index.js +19 -0
- package/dist/commands/ads/index.js.map +1 -0
- package/dist/commands/ads/output.d.ts +17 -0
- package/dist/commands/ads/output.d.ts.map +1 -0
- package/dist/commands/ads/output.js +78 -0
- package/dist/commands/ads/output.js.map +1 -0
- package/dist/commands/ads/output.test.d.ts +2 -0
- package/dist/commands/ads/output.test.d.ts.map +1 -0
- package/dist/commands/ads/output.test.js +100 -0
- package/dist/commands/ads/output.test.js.map +1 -0
- package/dist/commands/ads/types.d.ts +69 -0
- package/dist/commands/ads/types.d.ts.map +1 -0
- package/dist/commands/ads/types.js +2 -0
- package/dist/commands/ads/types.js.map +1 -0
- package/dist/commands/research/advertisers.d.ts +34 -0
- package/dist/commands/research/advertisers.d.ts.map +1 -0
- package/dist/commands/research/advertisers.js +75 -0
- package/dist/commands/research/advertisers.js.map +1 -0
- package/dist/commands/research/countries.d.ts +2 -0
- package/dist/commands/research/countries.d.ts.map +1 -0
- package/dist/commands/research/countries.js +69 -0
- package/dist/commands/research/countries.js.map +1 -0
- package/dist/commands/research/index.d.ts +2 -0
- package/dist/commands/research/index.d.ts.map +1 -0
- package/dist/commands/research/index.js +40 -0
- package/dist/commands/research/index.js.map +1 -0
- package/dist/commands/research/intent.d.ts +24 -0
- package/dist/commands/research/intent.d.ts.map +1 -0
- package/dist/commands/research/intent.js +71 -0
- package/dist/commands/research/intent.js.map +1 -0
- package/dist/commands/research/keyword-gap.d.ts +49 -0
- package/dist/commands/research/keyword-gap.d.ts.map +1 -0
- package/dist/commands/research/keyword-gap.js +99 -0
- package/dist/commands/research/keyword-gap.js.map +1 -0
- package/dist/commands/research/keywords-for-site.d.ts +44 -0
- package/dist/commands/research/keywords-for-site.d.ts.map +1 -0
- package/dist/commands/research/keywords-for-site.js +83 -0
- package/dist/commands/research/keywords-for-site.js.map +1 -0
- package/dist/commands/research/languages.d.ts +2 -0
- package/dist/commands/research/languages.d.ts.map +1 -0
- package/dist/commands/research/languages.js +42 -0
- package/dist/commands/research/languages.js.map +1 -0
- package/dist/commands/research/lighthouse.d.ts +24 -0
- package/dist/commands/research/lighthouse.d.ts.map +1 -0
- package/dist/commands/research/lighthouse.js +60 -0
- package/dist/commands/research/lighthouse.js.map +1 -0
- package/dist/commands/research/output.d.ts +29 -0
- package/dist/commands/research/output.d.ts.map +1 -0
- package/dist/commands/research/output.js +81 -0
- package/dist/commands/research/output.js.map +1 -0
- package/dist/env.d.ts +1 -0
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +5 -1
- package/dist/env.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @koda-sl/baker-cli
|
|
2
2
|
|
|
3
|
-
AI-agent-first CLI for interacting with Baker. Designed for programmatic use by AI agents with structured JSON output, schema introspection,
|
|
3
|
+
AI-agent-first CLI for interacting with Baker. Designed for programmatic use by AI agents with structured JSON output, schema introspection, self-correcting errors, and built-in caching.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -12,15 +12,19 @@ pnpm add @koda-sl/baker-cli
|
|
|
12
12
|
|
|
13
13
|
## Authentication
|
|
14
14
|
|
|
15
|
-
Set
|
|
15
|
+
Set environment variables:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
export BAKER_API_KEY="bk_your_api_key_here"
|
|
19
19
|
export BAKER_API_URL="https://your-baker-instance.convex.site"
|
|
20
|
+
|
|
21
|
+
# Optional: default customer ID for Google Ads commands
|
|
22
|
+
export BAKER_GOOGLE_ADS_CUSTOMER_ID="1234567890"
|
|
20
23
|
```
|
|
21
24
|
|
|
22
25
|
- `BAKER_API_KEY` must start with `bk_`
|
|
23
26
|
- `BAKER_API_URL` is your Convex site URL
|
|
27
|
+
- `BAKER_GOOGLE_ADS_CUSTOMER_ID` — default Google Ads customer ID (10 digits). Used when `--customer-id` is not passed.
|
|
24
28
|
|
|
25
29
|
## Output Format
|
|
26
30
|
|
|
@@ -30,8 +34,14 @@ All commands return a JSON envelope:
|
|
|
30
34
|
// Success
|
|
31
35
|
{ "ok": true, "data": { ... } }
|
|
32
36
|
|
|
33
|
-
//
|
|
34
|
-
{ "ok":
|
|
37
|
+
// Success with field descriptions
|
|
38
|
+
{ "ok": true, "data": [...], "fields": { "campaign.name": "Campaign display name", "metrics.clicks": "Total clicks" } }
|
|
39
|
+
|
|
40
|
+
// Success with data disclaimer (research commands)
|
|
41
|
+
{ "ok": true, "data": [...], "fields": { ... }, "note": "Estimates based on third-party SERP data — not exact figures. Use for directional insights, not precise measurement." }
|
|
42
|
+
|
|
43
|
+
// Error with self-correction (ads commands)
|
|
44
|
+
{ "ok": false, "error": { "code": "FIELD_NOT_FOUND", "message": "...", "fix": { "action": "retry_with_modified_query", "correctedCommand": "baker ads google query \"...\"", "explanation": "..." }, "retryable": false, "gaqlExecuted": "SELECT ..." } }
|
|
35
45
|
|
|
36
46
|
// Dry-run
|
|
37
47
|
{ "ok": true, "dryRun": true, "operation": "images.delete", "params": { "id": "abc123" } }
|
|
@@ -39,39 +49,668 @@ All commands return a JSON envelope:
|
|
|
39
49
|
|
|
40
50
|
Use `--output` to change format:
|
|
41
51
|
|
|
42
|
-
| Format | Description | Best for
|
|
43
|
-
|
|
44
|
-
| `json` | Structured JSON envelope (default) | AI agents
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
52
|
+
| Format | Description | Best for |
|
|
53
|
+
|---------|------------------------------------|--------------------|
|
|
54
|
+
| `json` | Structured JSON envelope (default) | AI agents |
|
|
55
|
+
| `csv` | RFC 4180 comma-separated values | Analysis tools |
|
|
56
|
+
| `jsonl` | One JSON object per line | Streaming/appending |
|
|
57
|
+
| `files` | Tab-separated, one row per result | Piping / shell |
|
|
58
|
+
| `md` | Markdown table | Human reading |
|
|
47
59
|
|
|
48
60
|
## Commands
|
|
49
61
|
|
|
50
|
-
### `baker
|
|
62
|
+
### Ad Platforms (`baker ads`)
|
|
63
|
+
|
|
64
|
+
Multi-platform ad data commands. Currently supports Google Ads, with Meta, LinkedIn, and TikTok coming.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
### `baker ads google accounts`
|
|
69
|
+
|
|
70
|
+
List all accessible Google Ads accounts. Run this first to find account IDs.
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
baker ads google accounts
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Response:**
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"ok": true,
|
|
81
|
+
"data": [
|
|
82
|
+
{ "id": "3343516765", "name": "My Company", "access_type": "direct", "level": 0 },
|
|
83
|
+
{ "id": "4106495409", "name": "Client Account", "access_type": "managed", "manager_id": "2292659431", "level": 1 }
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Flags:**
|
|
89
|
+
|
|
90
|
+
| Flag | Description |
|
|
91
|
+
|--------------|-----------------------|
|
|
92
|
+
| `--no-cache` | Skip cache (1h TTL) |
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
### `baker ads google currency`
|
|
97
|
+
|
|
98
|
+
Get the account currency. Call before interpreting `cost_micros` values.
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
baker ads google currency --customer-id 5904042878
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Response:**
|
|
105
|
+
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"ok": true,
|
|
109
|
+
"data": { "currency_code": "EUR", "customer_id": "5904042878" }
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Flags:**
|
|
114
|
+
|
|
115
|
+
| Flag | Description |
|
|
116
|
+
|-----------------|------------------------------------------------|
|
|
117
|
+
| `--customer-id` | Google Ads customer ID (10 digits, no dashes). Falls back to `BAKER_GOOGLE_ADS_CUSTOMER_ID` env var. |
|
|
118
|
+
| `--no-cache` | Skip cache (24h TTL) |
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
### `baker ads google query`
|
|
123
|
+
|
|
124
|
+
Run arbitrary GAQL queries. The most powerful command.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# Raw GAQL
|
|
128
|
+
baker ads google query "SELECT campaign.name, metrics.clicks, metrics.cost_micros FROM campaign WHERE segments.date DURING LAST_7_DAYS AND campaign.status = 'ENABLED' ORDER BY metrics.cost_micros DESC" --customer-id 1234567890
|
|
129
|
+
|
|
130
|
+
# Use a preset (saves tokens)
|
|
131
|
+
baker ads google query --preset campaign-performance --customer-id 1234567890
|
|
132
|
+
|
|
133
|
+
# Export to CSV
|
|
134
|
+
baker ads google query --preset search-terms --customer-id 1234567890 --out results.csv
|
|
135
|
+
|
|
136
|
+
# Auto-paginate large datasets
|
|
137
|
+
baker ads google query "SELECT ..." --customer-id 1234567890 --all --out /tmp/export.csv
|
|
138
|
+
|
|
139
|
+
# List available presets
|
|
140
|
+
baker ads google query --list-presets
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Response (JSON):**
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"ok": true,
|
|
148
|
+
"data": [
|
|
149
|
+
{ "campaign.name": "Brand US", "metrics.clicks": 4521, "metrics.cost_micros": 2850000000 }
|
|
150
|
+
],
|
|
151
|
+
"fields": {
|
|
152
|
+
"campaign.name": "Campaign display name",
|
|
153
|
+
"metrics.clicks": "Total clicks (integer)",
|
|
154
|
+
"metrics.cost_micros": "Total cost in micros (÷ 1,000,000 for actual currency)"
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Response (with pagination):**
|
|
160
|
+
|
|
161
|
+
```json
|
|
162
|
+
{
|
|
163
|
+
"ok": true,
|
|
164
|
+
"data": [...],
|
|
165
|
+
"fields": { ... },
|
|
166
|
+
"pagination": { "hasMore": true, "cursor": "eyJwYWdl..." }
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Response (file output, stdout only):**
|
|
171
|
+
|
|
172
|
+
```json
|
|
173
|
+
{
|
|
174
|
+
"ok": true,
|
|
175
|
+
"fields": { ... },
|
|
176
|
+
"file": "/tmp/results.csv",
|
|
177
|
+
"rows": 12847
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Flags:**
|
|
182
|
+
|
|
183
|
+
| Flag | Description |
|
|
184
|
+
|-----------------|--------------------------------------------------------------|
|
|
185
|
+
| `--customer-id` | Google Ads customer ID (10 digits, no dashes). Falls back to `BAKER_GOOGLE_ADS_CUSTOMER_ID` env var. |
|
|
186
|
+
| `--preset` | Named query template (see presets below) |
|
|
187
|
+
| `--date-range` | Override preset date range (LAST_7_DAYS, LAST_30_DAYS, etc.) |
|
|
188
|
+
| `--limit` | Max rows per page (default 200) |
|
|
189
|
+
| `--cursor` | Pagination cursor from previous response |
|
|
190
|
+
| `--all` | Auto-paginate all results |
|
|
191
|
+
| `--out` | Write data to file (format from extension: .csv, .jsonl, .json) |
|
|
192
|
+
| `--append` | Append to existing file (skip CSV headers) |
|
|
193
|
+
| `--output` | Output format: `json` \| `csv` \| `jsonl` \| `md` |
|
|
194
|
+
| `--no-cache` | Skip cache |
|
|
195
|
+
| `--list-presets`| List all available presets |
|
|
196
|
+
|
|
197
|
+
**Presets:**
|
|
198
|
+
|
|
199
|
+
| Preset | Description | Default date range |
|
|
200
|
+
|------------------------|------------------------------------------|--------------------|
|
|
201
|
+
| `campaign-performance` | Campaign metrics overview | LAST_30_DAYS |
|
|
202
|
+
| `keyword-analysis` | Keyword performance with match type | LAST_30_DAYS |
|
|
203
|
+
| `search-terms` | Actual user queries triggering ads | LAST_7_DAYS |
|
|
204
|
+
| `ad-copy-performance` | Ad headline/description effectiveness | LAST_30_DAYS |
|
|
205
|
+
| `asset-performance` | PMax asset performance labels | LAST_30_DAYS |
|
|
206
|
+
| `shopping-products` | Product-level shopping metrics | LAST_30_DAYS |
|
|
207
|
+
| `account-summary` | Account-level totals | LAST_30_DAYS |
|
|
208
|
+
|
|
209
|
+
**Pre-flight auto-fixes:**
|
|
210
|
+
|
|
211
|
+
The CLI automatically corrects common GAQL mistakes before hitting the API:
|
|
212
|
+
|
|
213
|
+
| Pattern | Auto-fix | Warning emitted |
|
|
214
|
+
|---------|----------|-----------------|
|
|
215
|
+
| Missing LIMIT | Adds `LIMIT 200` | `"Added LIMIT 200. Use --limit to override."` |
|
|
216
|
+
| `keyword.text` | `ad_group_criterion.keyword.text` | `"keyword.text → ad_group_criterion.keyword.text"` |
|
|
217
|
+
| `shopping_performance_view.product_*` | `segments.product_*` | Field renamed |
|
|
218
|
+
| `campaign.status = 'ACTIVE'` | `= 'ENABLED'` | Enum corrected |
|
|
219
|
+
|
|
220
|
+
Auto-fixed queries proceed normally. Warnings appear in the response:
|
|
221
|
+
|
|
222
|
+
```json
|
|
223
|
+
{ "ok": true, "data": [...], "warnings": [{ "code": "FIELD_RENAMED", "message": "keyword.text → ad_group_criterion.keyword.text" }] }
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**Self-correcting errors:**
|
|
227
|
+
|
|
228
|
+
When a query fails, the error includes a `fix` object with the exact corrected command:
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
{
|
|
232
|
+
"ok": false,
|
|
233
|
+
"error": {
|
|
234
|
+
"code": "INVALID_OPERATOR",
|
|
235
|
+
"message": "GAQL does not support CONTAINS. Use LIKE with % wildcards.",
|
|
236
|
+
"fix": {
|
|
237
|
+
"action": "change_operator",
|
|
238
|
+
"correctedCommand": "baker ads google query \"SELECT campaign.name FROM campaign WHERE campaign.name LIKE '%brand%' LIMIT 200\" --customer-id 1234567890",
|
|
239
|
+
"explanation": "GAQL uses LIKE '%value%' for substring matching, not CONTAINS()"
|
|
240
|
+
},
|
|
241
|
+
"retryable": false
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
---
|
|
51
247
|
|
|
52
|
-
|
|
248
|
+
### `baker ads google changes`
|
|
249
|
+
|
|
250
|
+
Get recent change logs for an account.
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
baker ads google changes --customer-id 1234567890
|
|
254
|
+
baker ads google changes --customer-id 1234567890 --days 14 --resource-type CAMPAIGN
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**Flags:**
|
|
258
|
+
|
|
259
|
+
| Flag | Description |
|
|
260
|
+
|-------------------|---------------------------------------------------------------|
|
|
261
|
+
| `--customer-id` | Google Ads customer ID. Falls back to `BAKER_GOOGLE_ADS_CUSTOMER_ID` env var. |
|
|
262
|
+
| `--days` | Lookback days (default 7, max 90) |
|
|
263
|
+
| `--resource-type` | Filter: CAMPAIGN, AD_GROUP, AD_GROUP_AD, AD_GROUP_CRITERION |
|
|
264
|
+
| `--limit` | Max results (default 50) |
|
|
265
|
+
| `--output` | Format: `json` \| `csv` \| `jsonl` \| `md` |
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
### `baker ads google keywords discover`
|
|
270
|
+
|
|
271
|
+
Discover keyword ideas from seed keywords or URLs.
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
baker ads google keywords discover --customer-id 1234567890 --seeds "running shoes,athletic footwear"
|
|
275
|
+
baker ads google keywords discover --customer-id 1234567890 --url "https://competitor.com" --limit 50
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**Response:**
|
|
279
|
+
|
|
280
|
+
```json
|
|
281
|
+
{
|
|
282
|
+
"ok": true,
|
|
283
|
+
"data": {
|
|
284
|
+
"keywords": [
|
|
285
|
+
{
|
|
286
|
+
"keyword": "student services",
|
|
287
|
+
"avg_monthly_searches": "1000",
|
|
288
|
+
"competition": "LOW",
|
|
289
|
+
"competition_index": "4",
|
|
290
|
+
"low_top_of_page_bid_micros": 0,
|
|
291
|
+
"high_top_of_page_bid_micros": 0,
|
|
292
|
+
"monthly_search_volumes": [
|
|
293
|
+
{ "year": "2025", "month": "APRIL", "monthly_searches": "590" }
|
|
294
|
+
]
|
|
295
|
+
}
|
|
296
|
+
],
|
|
297
|
+
"total_results": 10,
|
|
298
|
+
"next_page_token": "..."
|
|
299
|
+
},
|
|
300
|
+
"fields": {
|
|
301
|
+
"keyword": "Suggested keyword text",
|
|
302
|
+
"avg_monthly_searches": "Average monthly search volume",
|
|
303
|
+
"competition": "Competition level: LOW, MEDIUM, HIGH, UNKNOWN",
|
|
304
|
+
"competition_index": "Competition index 0-100 (higher = more competitive)",
|
|
305
|
+
"low_top_of_page_bid_micros": "Low-range CPC bid in micros (÷ 1,000,000 for currency)",
|
|
306
|
+
"high_top_of_page_bid_micros": "High-range CPC bid in micros (÷ 1,000,000 for currency)"
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
**Flags:**
|
|
312
|
+
|
|
313
|
+
| Flag | Description |
|
|
314
|
+
|-----------------|-----------------------------------------------|
|
|
315
|
+
| `--customer-id` | Google Ads customer ID. Falls back to `BAKER_GOOGLE_ADS_CUSTOMER_ID` env var. |
|
|
316
|
+
| `--seeds` | Comma-separated seed keywords (max 10) |
|
|
317
|
+
| `--url` | URL to extract keyword ideas from |
|
|
318
|
+
| `--location` | Geo target ID (default: 2840 for US) |
|
|
319
|
+
| `--language` | Language ID (default: 1000 for English) |
|
|
320
|
+
| `--limit` | Max results (default 20) |
|
|
321
|
+
| `--cursor` | Pagination cursor from previous response (`next_page_token`) |
|
|
322
|
+
| `--no-cache` | Skip cache (24h TTL) |
|
|
323
|
+
| `--output` | Format: `json` \| `csv` \| `jsonl` \| `md` |
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
### `baker ads google keywords metrics`
|
|
328
|
+
|
|
329
|
+
Get historical metrics for specific keywords.
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
baker ads google keywords metrics --customer-id 1234567890 --keywords "running shoes,nike shoes,adidas shoes"
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
**Response:**
|
|
336
|
+
|
|
337
|
+
```json
|
|
338
|
+
{
|
|
339
|
+
"ok": true,
|
|
340
|
+
"data": {
|
|
341
|
+
"historical_metrics": [
|
|
342
|
+
{
|
|
343
|
+
"keyword": "running shoes",
|
|
344
|
+
"avg_monthly_searches": "1000",
|
|
345
|
+
"competition": "LOW",
|
|
346
|
+
"competition_index": "4",
|
|
347
|
+
"low_top_of_page_bid_micros": 0,
|
|
348
|
+
"high_top_of_page_bid_micros": 0,
|
|
349
|
+
"monthly_search_volumes": [
|
|
350
|
+
{ "year": "2025", "month": "APRIL", "monthly_searches": "590" }
|
|
351
|
+
]
|
|
352
|
+
}
|
|
353
|
+
]
|
|
354
|
+
},
|
|
355
|
+
"fields": { ... }
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
**Flags:**
|
|
360
|
+
|
|
361
|
+
| Flag | Description |
|
|
362
|
+
|-----------------|-----------------------------------------------|
|
|
363
|
+
| `--customer-id` | Google Ads customer ID. Falls back to `BAKER_GOOGLE_ADS_CUSTOMER_ID` env var. |
|
|
364
|
+
| `--keywords` | Comma-separated keywords to analyze (max 200) |
|
|
365
|
+
| `--location` | Geo target ID (default: 2840 for US) |
|
|
366
|
+
| `--language` | Language ID (default: 1000 for English) |
|
|
367
|
+
| `--no-cache` | Skip cache (24h TTL) |
|
|
368
|
+
| `--output` | Format: `json` \| `csv` \| `jsonl` \| `md` |
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
### Caching
|
|
373
|
+
|
|
374
|
+
Google Ads data is cached at two levels:
|
|
375
|
+
|
|
376
|
+
**Server-side (ActionCache)** — shared across all CLI instances and agents for the same company:
|
|
377
|
+
|
|
378
|
+
| Data type | TTL | Cache name |
|
|
379
|
+
|-----------|-----|------------|
|
|
380
|
+
| Account list | 1 hour | `ads-accounts-v1` |
|
|
381
|
+
| Currency | 7 days | `ads-currency-v1` |
|
|
382
|
+
| GAQL queries | 1 hour | `ads-query-v1` |
|
|
383
|
+
| Keyword ideas | 1 day | `ads-keyword-ideas-v1` |
|
|
384
|
+
| Keyword metrics | 1 day | `ads-keyword-metrics-v1` |
|
|
385
|
+
|
|
386
|
+
**Client-side (local file cache)** — per-machine at `~/.baker/cache/ads/`:
|
|
387
|
+
|
|
388
|
+
| Data type | TTL | Reason |
|
|
389
|
+
|-----------|-----|--------|
|
|
390
|
+
| GAQL (LAST_30_DAYS, BETWEEN) | 6 hours | Historical data is immutable |
|
|
391
|
+
| GAQL (LAST_7_DAYS) | 1 hour | Recent data updates less frequently |
|
|
392
|
+
| GAQL (TODAY) | 15 minutes | Today's data changes in real-time |
|
|
393
|
+
|
|
394
|
+
Use `--no-cache` on any command to bypass **both** the local file cache and the server-side ActionCache, forcing a fresh API call.
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
### Google Ads Error Codes
|
|
399
|
+
|
|
400
|
+
| Code | Retryable | Meaning |
|
|
401
|
+
|------|-----------|---------|
|
|
402
|
+
| `FIELD_NOT_FOUND` | No | Invalid field in GAQL query |
|
|
403
|
+
| `WRONG_RESOURCE` | No | Field queried from wrong resource |
|
|
404
|
+
| `INVALID_OPERATOR` | No | Unsupported operator (e.g. CONTAINS) |
|
|
405
|
+
| `CUSTOMER_NOT_FOUND` | No | Invalid customer ID — run `baker ads google accounts` to find valid IDs |
|
|
406
|
+
| `MISSING_MANAGER_ID` | No | Account not accessible (may need MCC login-customer-id) |
|
|
407
|
+
| `INCOMPATIBLE_FIELDS` | No | Fields can't be in same query |
|
|
408
|
+
| `OPEN_ENDED_DATE` | No | Date range must be finite |
|
|
409
|
+
| `READ_ONLY` | No | Only SELECT queries allowed |
|
|
410
|
+
| `QUOTA_EXCEEDED` | Yes (30s) | API rate limit hit |
|
|
411
|
+
| `TIMEOUT` | Yes (5s) | Query too broad |
|
|
412
|
+
| `AUTH_ERROR` | No | Token expired or missing |
|
|
413
|
+
|
|
414
|
+
All errors include a `fix` object with `action`, `correctedCommand` (when applicable), and `explanation`.
|
|
415
|
+
|
|
416
|
+
---
|
|
417
|
+
|
|
418
|
+
### Competitive Intelligence (`baker research`)
|
|
419
|
+
|
|
420
|
+
Market and competitor research powered by DataForSEO. Shows who's competing for keywords, search intent classification, competitor keyword strategies, keyword gaps, and landing page performance.
|
|
421
|
+
|
|
422
|
+
All research responses include a `note` field indicating that data is estimated from third-party SERP scraping and should be used for directional insights, not precise measurement.
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
### `baker research advertisers "keyword"`
|
|
427
|
+
|
|
428
|
+
Find domains competing for a keyword in Google SERPs.
|
|
53
429
|
|
|
54
430
|
```bash
|
|
55
|
-
baker
|
|
56
|
-
|
|
431
|
+
baker research advertisers "running shoes"
|
|
432
|
+
baker research advertisers "crm software" --location uk --limit 10
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
**Response:**
|
|
436
|
+
|
|
437
|
+
```json
|
|
438
|
+
{
|
|
439
|
+
"ok": true,
|
|
440
|
+
"data": [
|
|
441
|
+
{ "domain": "www.adidas.com", "avg_position": 1, "rating": 99, "etv": 111872, "visibility": 1 }
|
|
442
|
+
],
|
|
443
|
+
"fields": {
|
|
444
|
+
"domain": "Competing domain",
|
|
445
|
+
"avg_position": "Average SERP position (1 = top)",
|
|
446
|
+
"rating": "Domain relevance rating (0-100)",
|
|
447
|
+
"etv": "Estimated traffic value (USD)",
|
|
448
|
+
"visibility": "SERP visibility score (0-1)"
|
|
449
|
+
}
|
|
450
|
+
}
|
|
57
451
|
```
|
|
58
452
|
|
|
453
|
+
**Flags:**
|
|
454
|
+
|
|
455
|
+
| Flag | Description |
|
|
456
|
+
|--------------|--------------------------------------|
|
|
457
|
+
| `--location` | Country code (us, uk, es, de...) or numeric code. Default: us |
|
|
458
|
+
| `--language` | Language code or name (en, spanish, french...). Default: en |
|
|
459
|
+
| `--limit` | Max results (default: 20) |
|
|
460
|
+
| `--no-cache` | Skip cache (6h TTL) |
|
|
461
|
+
| `--output` | Format: json\|csv\|md\|jsonl |
|
|
462
|
+
|
|
463
|
+
---
|
|
464
|
+
|
|
465
|
+
### `baker research intent "kw1,kw2,kw3"`
|
|
466
|
+
|
|
467
|
+
Classify Google Search intent for keywords.
|
|
468
|
+
|
|
469
|
+
```bash
|
|
470
|
+
baker research intent "buy running shoes,best running shoes 2026,how to tie shoes"
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
**Response:**
|
|
474
|
+
|
|
475
|
+
```json
|
|
476
|
+
{
|
|
477
|
+
"ok": true,
|
|
478
|
+
"data": [
|
|
479
|
+
{ "keyword": "buy running shoes", "intent": "transactional", "probability": 0.96 }
|
|
480
|
+
],
|
|
481
|
+
"fields": {
|
|
482
|
+
"keyword": "The keyword analyzed",
|
|
483
|
+
"intent": "Primary Google Search intent: informational, navigational, commercial, transactional",
|
|
484
|
+
"probability": "Confidence score 0.0-1.0"
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
**Flags:**
|
|
490
|
+
|
|
491
|
+
| Flag | Description |
|
|
492
|
+
|--------------|--------------------------------------|
|
|
493
|
+
| `--language` | Language code or name (en, spanish, french...). Default: en |
|
|
494
|
+
| `--no-cache` | Skip cache (7d TTL) |
|
|
495
|
+
| `--output` | Format: json\|csv\|md\|jsonl |
|
|
496
|
+
|
|
497
|
+
---
|
|
498
|
+
|
|
499
|
+
### `baker research keywords-for-site "domain.com"`
|
|
500
|
+
|
|
501
|
+
Get keywords a competitor targets. Use `--type paid` to see only paid keywords, `--type organic` for organic only.
|
|
502
|
+
|
|
503
|
+
```bash
|
|
504
|
+
baker research keywords-for-site "competitor.com"
|
|
505
|
+
baker research keywords-for-site "competitor.com" --type paid --limit 20
|
|
506
|
+
baker research keywords-for-site "competitor.com" --type organic --location uk
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
**Response:**
|
|
510
|
+
|
|
511
|
+
```json
|
|
512
|
+
{
|
|
513
|
+
"ok": true,
|
|
514
|
+
"data": [
|
|
515
|
+
{ "keyword": "running shoes online", "search_volume": 12000, "cpc": 1.85, "competition": "HIGH", "competition_index": 82 }
|
|
516
|
+
],
|
|
517
|
+
"fields": {
|
|
518
|
+
"keyword": "Keyword the site targets",
|
|
519
|
+
"search_volume": "Monthly search volume",
|
|
520
|
+
"cpc": "Cost per click in USD",
|
|
521
|
+
"competition": "LOW, MEDIUM, or HIGH",
|
|
522
|
+
"competition_index": "Competition score 0-100"
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
**Flags:**
|
|
528
|
+
|
|
529
|
+
| Flag | Description |
|
|
530
|
+
|--------------|----------------------------------------------------------|
|
|
531
|
+
| `--location` | Country code (us, uk, es, de...) or numeric code. Default: us |
|
|
532
|
+
| `--language` | Language code (default: en) |
|
|
533
|
+
| `--sort` | Sort: relevance, search_volume, competition, cpc |
|
|
534
|
+
| `--type` | Filter: paid, organic, all (default: all) |
|
|
535
|
+
| `--limit` | Max results (default: 50) |
|
|
536
|
+
| `--no-cache` | Skip cache (6h TTL) |
|
|
537
|
+
| `--output` | Format: json\|csv\|md\|jsonl |
|
|
538
|
+
|
|
539
|
+
---
|
|
540
|
+
|
|
541
|
+
### `baker research keyword-gap "them.com" "us.com"`
|
|
542
|
+
|
|
543
|
+
Keywords the competitor has that you don't.
|
|
544
|
+
|
|
545
|
+
```bash
|
|
546
|
+
baker research keyword-gap "competitor.com" "mysite.com"
|
|
547
|
+
baker research keyword-gap "competitor.com" "mysite.com" --type paid --limit 100
|
|
548
|
+
baker research keyword-gap "competitor.com" "mysite.com" --offset 50 --limit 50
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
**Response:**
|
|
552
|
+
|
|
553
|
+
```json
|
|
554
|
+
{
|
|
555
|
+
"ok": true,
|
|
556
|
+
"your_domain": "mysite.com",
|
|
557
|
+
"competitor_domain": "competitor.com",
|
|
558
|
+
"data": [
|
|
559
|
+
{ "keyword": "marathon shoes", "search_volume": 8500, "cpc": 2.10, "their_position": 2 }
|
|
560
|
+
],
|
|
561
|
+
"fields": {
|
|
562
|
+
"keyword": "Keyword in the gap (they rank, you don't)",
|
|
563
|
+
"search_volume": "Monthly search volume",
|
|
564
|
+
"cpc": "Cost per click USD",
|
|
565
|
+
"their_position": "Competitor's ranking position"
|
|
566
|
+
},
|
|
567
|
+
"note": "Estimates based on third-party SERP data — not exact figures. Use for directional insights, not precise measurement.",
|
|
568
|
+
"total_count": 342,
|
|
569
|
+
"pagination": {
|
|
570
|
+
"offset": 0,
|
|
571
|
+
"limit": 50,
|
|
572
|
+
"has_more": true,
|
|
573
|
+
"next_offset": 50
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
**Flags:**
|
|
579
|
+
|
|
580
|
+
| Flag | Description |
|
|
581
|
+
|--------------|--------------------------------------------|
|
|
582
|
+
| `--location` | Country code (us, uk, es, de...) or numeric code. Default: us |
|
|
583
|
+
| `--language` | Language code (default: en) |
|
|
584
|
+
| `--type` | Filter: paid, organic, all (default: all) |
|
|
585
|
+
| `--limit` | Max results (default: 50, max: 1000) |
|
|
586
|
+
| `--offset` | Pagination offset (default: 0) |
|
|
587
|
+
| `--no-cache` | Skip cache (6h TTL) |
|
|
588
|
+
| `--output` | Format: json\|csv\|md\|jsonl |
|
|
589
|
+
|
|
590
|
+
---
|
|
591
|
+
|
|
592
|
+
### `baker research lighthouse "https://url"`
|
|
593
|
+
|
|
594
|
+
Landing page performance audit. Metrics affecting Google Ads Quality Score.
|
|
595
|
+
|
|
596
|
+
```bash
|
|
597
|
+
baker research lighthouse "https://example.com/landing"
|
|
598
|
+
baker research lighthouse "https://example.com" --mobile false
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
**Response:**
|
|
602
|
+
|
|
603
|
+
```json
|
|
604
|
+
{
|
|
605
|
+
"ok": true,
|
|
606
|
+
"data": {
|
|
607
|
+
"url": "https://example.com/landing",
|
|
608
|
+
"performance_score": 72,
|
|
609
|
+
"fcp_ms": 1200,
|
|
610
|
+
"lcp_ms": 2800,
|
|
611
|
+
"cls": 0.05,
|
|
612
|
+
"speed_index_ms": 3200,
|
|
613
|
+
"interactive_ms": 4500
|
|
614
|
+
},
|
|
615
|
+
"fields": {
|
|
616
|
+
"url": "URL that was audited",
|
|
617
|
+
"performance_score": "Lighthouse performance score 0-100 (aim for 90+)",
|
|
618
|
+
"fcp_ms": "First Contentful Paint in ms (good: < 1800)",
|
|
619
|
+
"lcp_ms": "Largest Contentful Paint in ms (good: < 2500)",
|
|
620
|
+
"cls": "Cumulative Layout Shift (good: < 0.1)",
|
|
621
|
+
"speed_index_ms": "Speed Index in ms (good: < 3400)",
|
|
622
|
+
"interactive_ms": "Time to Interactive in ms (good: < 3800)"
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
**Flags:**
|
|
628
|
+
|
|
629
|
+
| Flag | Description |
|
|
630
|
+
|--------------|--------------------------------------|
|
|
631
|
+
| `--mobile` | Test as mobile (default: true) |
|
|
632
|
+
| `--output` | Format: json\|csv\|md\|jsonl |
|
|
633
|
+
| `--no-cache` | Skip cache (24h TTL) |
|
|
634
|
+
|
|
635
|
+
---
|
|
636
|
+
|
|
637
|
+
### `baker research countries`
|
|
638
|
+
|
|
639
|
+
List all supported country codes for `--location` flag.
|
|
640
|
+
|
|
641
|
+
```bash
|
|
642
|
+
baker research countries
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
**Response:**
|
|
646
|
+
|
|
647
|
+
```json
|
|
648
|
+
{
|
|
649
|
+
"ok": true,
|
|
650
|
+
"data": [
|
|
651
|
+
{ "code": "us", "name": "United States" },
|
|
652
|
+
{ "code": "uk", "name": "United Kingdom" },
|
|
653
|
+
{ "code": "es", "name": "Spain" }
|
|
654
|
+
],
|
|
655
|
+
"fields": {
|
|
656
|
+
"code": "Country code to pass as --location",
|
|
657
|
+
"name": "Country name"
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
---
|
|
663
|
+
|
|
664
|
+
### `baker research languages`
|
|
665
|
+
|
|
666
|
+
List all supported language codes for `--language` flag.
|
|
667
|
+
|
|
668
|
+
```bash
|
|
669
|
+
baker research languages
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
**Response:**
|
|
673
|
+
|
|
674
|
+
```json
|
|
675
|
+
{
|
|
676
|
+
"ok": true,
|
|
677
|
+
"data": [
|
|
678
|
+
{ "code": "en", "name": "english" },
|
|
679
|
+
{ "code": "es", "name": "spanish" }
|
|
680
|
+
],
|
|
681
|
+
"fields": {
|
|
682
|
+
"code": "Language code to pass as --language",
|
|
683
|
+
"name": "Language name (also accepted by --language)"
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
---
|
|
689
|
+
|
|
690
|
+
### Research Caching
|
|
691
|
+
|
|
692
|
+
Research data is cached server-side (shared across all callers). No local cache files. Use `--no-cache` on any research command to bypass the server cache and force a fresh API call.
|
|
693
|
+
|
|
694
|
+
| Command | TTL | Reason |
|
|
695
|
+
|-------------------|---------|-------------------------------------|
|
|
696
|
+
| advertisers | 6 hours | SERP landscape changes slowly |
|
|
697
|
+
| intent | 7 days | Intent classification is very stable |
|
|
698
|
+
| keywords-for-site | 6 hours | Keyword targeting changes weekly |
|
|
699
|
+
| keyword-gap | 6 hours | Same |
|
|
700
|
+
| lighthouse | 24 hours| Page performance stable day-to-day |
|
|
701
|
+
|
|
702
|
+
---
|
|
703
|
+
|
|
704
|
+
### Assets (`baker images`, `baker videos`, `baker testimonials`)
|
|
705
|
+
|
|
59
706
|
### `baker images search <query>`
|
|
60
707
|
|
|
61
708
|
Semantic search using hybrid BM25 + vector + reranking. Only returns ready images.
|
|
62
709
|
|
|
63
710
|
```bash
|
|
64
|
-
# Basic search
|
|
65
711
|
baker images search "hero banner"
|
|
66
|
-
|
|
67
|
-
# Filter by aspect ratio and tags
|
|
68
712
|
baker images search "logo" --aspect-ratio 1:1 --tags logo
|
|
69
|
-
|
|
70
|
-
# Limit results and set minimum relevance
|
|
71
713
|
baker images search "team photo" --limit 5 --min-score 0.3
|
|
72
|
-
|
|
73
|
-
# Full metadata with markdown output
|
|
74
|
-
baker images search "product shot" --full --output md
|
|
75
714
|
```
|
|
76
715
|
|
|
77
716
|
**Flags:**
|
|
@@ -92,49 +731,19 @@ Get a single image by ID.
|
|
|
92
731
|
|
|
93
732
|
```bash
|
|
94
733
|
baker images get j571abc123def
|
|
95
|
-
|
|
96
|
-
# With full metadata
|
|
97
734
|
baker images get j571abc123def --full
|
|
98
|
-
|
|
99
|
-
# Alternative flag syntax
|
|
100
|
-
baker images get --image-id j571abc123def
|
|
101
735
|
```
|
|
102
736
|
|
|
103
|
-
**Flags:**
|
|
104
|
-
|
|
105
|
-
| Flag | Description |
|
|
106
|
-
|--------------|----------------------------------------------|
|
|
107
|
-
| `--image-id` | Image ID (alternative to positional arg) |
|
|
108
|
-
| `--output` | Output format: `json` \| `files` \| `md` |
|
|
109
|
-
| `--fields` | Comma-separated field names to include |
|
|
110
|
-
| `--full` | Include full metadata |
|
|
111
|
-
|
|
112
737
|
### `baker images upload <file>`
|
|
113
738
|
|
|
114
|
-
Upload an image file.
|
|
739
|
+
Upload an image file.
|
|
115
740
|
|
|
116
741
|
```bash
|
|
117
|
-
# Upload with auto-detected content type
|
|
118
742
|
baker images upload ./logo.png
|
|
119
|
-
|
|
120
|
-
# Specify source
|
|
121
743
|
baker images upload ./banner.jpg --source uploaded
|
|
122
|
-
|
|
123
|
-
# Override content type
|
|
124
|
-
baker images upload ./image.bin --content-type image/webp
|
|
125
|
-
|
|
126
|
-
# Preview what would happen without uploading
|
|
127
744
|
baker images upload ./logo.png --dry-run
|
|
128
745
|
```
|
|
129
746
|
|
|
130
|
-
**Flags:**
|
|
131
|
-
|
|
132
|
-
| Flag | Description |
|
|
133
|
-
|------------------|------------------------------------------------|
|
|
134
|
-
| `--source` | Source identifier |
|
|
135
|
-
| `--content-type` | MIME type (auto-detected from extension) |
|
|
136
|
-
| `--dry-run` | Preview the operation without executing |
|
|
137
|
-
|
|
138
747
|
Supported extensions: `.png`, `.jpg`, `.jpeg`, `.gif`, `.webp`, `.svg`, `.avif`
|
|
139
748
|
|
|
140
749
|
### `baker images delete <id>`
|
|
@@ -142,168 +751,115 @@ Supported extensions: `.png`, `.jpg`, `.jpeg`, `.gif`, `.webp`, `.svg`, `.avif`
|
|
|
142
751
|
Delete an image by ID.
|
|
143
752
|
|
|
144
753
|
```bash
|
|
145
|
-
# Preview deletion
|
|
146
754
|
baker images delete j571abc123def --dry-run
|
|
147
|
-
# { "ok": true, "dryRun": true, "operation": "images.delete", "params": { "id": "j571abc123def" } }
|
|
148
|
-
|
|
149
|
-
# Execute deletion
|
|
150
755
|
baker images delete j571abc123def
|
|
151
756
|
```
|
|
152
757
|
|
|
153
|
-
**Flags:**
|
|
154
|
-
|
|
155
|
-
| Flag | Description |
|
|
156
|
-
|--------------|----------------------------------------------|
|
|
157
|
-
| `--image-id` | Image ID (alternative to positional arg) |
|
|
158
|
-
| `--dry-run` | Preview the operation without executing |
|
|
159
|
-
|
|
160
758
|
### `baker videos search <query>`
|
|
161
759
|
|
|
162
|
-
Semantic search videos
|
|
760
|
+
Semantic search videos.
|
|
163
761
|
|
|
164
762
|
```bash
|
|
165
|
-
# Basic search
|
|
166
763
|
baker videos search "product demo"
|
|
167
|
-
|
|
168
|
-
# Filter by tags and limit results
|
|
169
764
|
baker videos search "tutorial" --tags explainer,ugc --limit 5
|
|
170
|
-
|
|
171
|
-
# Full metadata with markdown output
|
|
172
|
-
baker videos search "testimonial" --full --output md
|
|
173
765
|
```
|
|
174
766
|
|
|
175
|
-
**Flags:**
|
|
176
|
-
|
|
177
|
-
| Flag | Description |
|
|
178
|
-
|------------|------------------------------------------|
|
|
179
|
-
| `--limit` | Max results (default 20) |
|
|
180
|
-
| `--tags` | Comma-separated tags to filter by |
|
|
181
|
-
| `--output` | Output format: `json` \| `files` \| `md` |
|
|
182
|
-
| `--fields` | Comma-separated field names to include |
|
|
183
|
-
| `--full` | Include full metadata |
|
|
184
|
-
|
|
185
767
|
### `baker videos get <id>`
|
|
186
768
|
|
|
187
769
|
Get a single video by ID.
|
|
188
770
|
|
|
189
|
-
```bash
|
|
190
|
-
baker videos get j571abc123def
|
|
191
|
-
|
|
192
|
-
# With full metadata
|
|
193
|
-
baker videos get j571abc123def --full
|
|
194
|
-
|
|
195
|
-
# Alternative flag syntax
|
|
196
|
-
baker videos get --video-id j571abc123def
|
|
197
|
-
```
|
|
198
|
-
|
|
199
771
|
### `baker videos upload <file>`
|
|
200
772
|
|
|
201
|
-
Upload a video file via Mux direct upload.
|
|
773
|
+
Upload a video file via Mux direct upload.
|
|
202
774
|
|
|
203
775
|
```bash
|
|
204
|
-
# Upload with auto-detected content type
|
|
205
776
|
baker videos upload ./demo.mp4
|
|
206
|
-
|
|
207
|
-
# Override content type
|
|
208
|
-
baker videos upload ./video.bin --content-type video/mp4
|
|
209
|
-
|
|
210
|
-
# Preview what would happen without uploading
|
|
211
777
|
baker videos upload ./demo.mp4 --dry-run
|
|
212
778
|
```
|
|
213
779
|
|
|
214
|
-
**Flags:**
|
|
215
|
-
|
|
216
|
-
| Flag | Description |
|
|
217
|
-
|------------------|------------------------------------------------|
|
|
218
|
-
| `--content-type` | MIME type (auto-detected from extension) |
|
|
219
|
-
| `--dry-run` | Preview the operation without executing |
|
|
220
|
-
|
|
221
780
|
Supported extensions: `.mp4`, `.mov`, `.webm`, `.avi`, `.mkv`
|
|
222
781
|
|
|
223
782
|
### `baker videos delete <id>`
|
|
224
783
|
|
|
225
784
|
Delete a video by ID.
|
|
226
785
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
786
|
+
### `baker testimonials search <query>`
|
|
787
|
+
|
|
788
|
+
Semantic search testimonials.
|
|
230
789
|
|
|
231
|
-
|
|
232
|
-
baker
|
|
790
|
+
```bash
|
|
791
|
+
baker testimonials search "great service"
|
|
792
|
+
baker testimonials search "fast delivery" --rating-min 4 --tags quality
|
|
233
793
|
```
|
|
234
794
|
|
|
235
|
-
|
|
795
|
+
### `baker testimonials get <id>`
|
|
796
|
+
|
|
797
|
+
Get a single testimonial by ID.
|
|
798
|
+
|
|
799
|
+
### `baker testimonials list`
|
|
236
800
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
801
|
+
List testimonials with optional filters.
|
|
802
|
+
|
|
803
|
+
```bash
|
|
804
|
+
baker testimonials list --source google --sentiment positive --limit 20
|
|
805
|
+
```
|
|
806
|
+
|
|
807
|
+
---
|
|
240
808
|
|
|
241
809
|
### `baker schema [command]`
|
|
242
810
|
|
|
243
811
|
Inspect command argument schemas for AI agent introspection.
|
|
244
812
|
|
|
245
813
|
```bash
|
|
246
|
-
# List all
|
|
247
|
-
baker schema
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
# Get schema for a specific command
|
|
251
|
-
baker schema images.search
|
|
252
|
-
# { "ok": true, "data": { "command": "images.search", "args": { ... } } }
|
|
814
|
+
baker schema # List all commands
|
|
815
|
+
baker schema ads.google.query # Get query command schema
|
|
816
|
+
baker schema images.search # Get image search schema
|
|
253
817
|
```
|
|
254
818
|
|
|
255
|
-
##
|
|
819
|
+
## Help & Discovery
|
|
256
820
|
|
|
257
|
-
|
|
821
|
+
Every command supports `--help` for usage info:
|
|
258
822
|
|
|
259
|
-
|
|
823
|
+
```bash
|
|
824
|
+
baker --help # All top-level commands
|
|
825
|
+
baker ads --help # Available platforms
|
|
826
|
+
baker ads google --help # All Google Ads subcommands
|
|
827
|
+
baker ads google query --help # All flags for the query command
|
|
828
|
+
```
|
|
260
829
|
|
|
261
|
-
|
|
262
|
-
|-----------|------------------------------------------------------------|
|
|
263
|
-
| Default | `_id`, `name`, `imageUrl`, `description`, `tags` |
|
|
264
|
-
| `--full` | All fields: width, height, aspectRatio, dominantColor, imagePalette, source, createdAt |
|
|
830
|
+
For machine-readable introspection, use `baker schema` (see below).
|
|
265
831
|
|
|
266
|
-
|
|
832
|
+
## For AI Agents
|
|
267
833
|
|
|
268
|
-
|
|
269
|
-
|-----------|-------------------------------------------|
|
|
270
|
-
| Default | `_id`, `name`, `thumbnailUrl`, `description`, `tags`, `status` |
|
|
271
|
-
| `--full` | All fields: duration, muxPlaybackId, source, timestamps |
|
|
834
|
+
This CLI is designed for AI agent consumption. Key patterns:
|
|
272
835
|
|
|
273
|
-
|
|
836
|
+
1. **Start with `baker ads google accounts`** to discover available Google Ads accounts
|
|
837
|
+
2. **Use `baker ads google query --list-presets`** to see available query templates (saves tokens)
|
|
838
|
+
3. **Use presets** (`--preset campaign-performance`) instead of writing full GAQL when possible
|
|
839
|
+
4. **Read the `fields` object** in responses to understand what each column means
|
|
840
|
+
5. **Check `fix.correctedCommand`** on errors — copy-paste it to retry
|
|
841
|
+
6. **Use `--all --out file.csv`** for large exports to avoid filling context window
|
|
842
|
+
7. **Use `--no-cache`** when you need guaranteed fresh data
|
|
843
|
+
8. **Start with `baker schema`** to discover all available commands and their arguments
|
|
844
|
+
9. **Use `--dry-run`** on mutations to preview before executing
|
|
845
|
+
10. **Parse the JSON envelope** — check `ok` field before accessing `data`
|
|
274
846
|
|
|
275
|
-
|
|
276
|
-
|--------------------|--------------------------------------|
|
|
277
|
-
| `UNAUTHORIZED` | Invalid or missing API key |
|
|
278
|
-
| `NOT_FOUND` | Resource not found |
|
|
279
|
-
| `VALIDATION_ERROR` | Invalid input (bad ID, missing args) |
|
|
280
|
-
| `RATE_LIMITED` | Too many requests |
|
|
281
|
-
| `NETWORK_ERROR` | Connection failed |
|
|
282
|
-
| `INTERNAL_ERROR` | Unexpected server error |
|
|
847
|
+
## Publishing
|
|
283
848
|
|
|
284
|
-
|
|
849
|
+
### Auto-publish (CI)
|
|
285
850
|
|
|
286
|
-
|
|
851
|
+
Pushing to `main` with changes in `packages/cli/` triggers the GitHub Actions workflow, which publishes to npm with the `latest` tag.
|
|
287
852
|
|
|
288
|
-
|
|
289
|
-
|--------------------|--------------------------------------------------------------|
|
|
290
|
-
| `logo` | Singular company, product, or organizational logo |
|
|
291
|
-
| `profile-picture` | Portrait-style image featuring a person's face |
|
|
292
|
-
| `illustration` | Stylized, drawn, or vector artwork |
|
|
293
|
-
| `software` | UI, dashboards, app interfaces, or software captures |
|
|
294
|
-
| `product-shot` | Focused depiction of a tangible product |
|
|
295
|
-
| `team-photo` | Group of people posed together, such as company team imagery |
|
|
296
|
-
| `environment` | Backgrounds or scenes showcasing locations, offices, spaces |
|
|
297
|
-
| `iconography` | Icons, symbols, or small graphical elements |
|
|
298
|
-
| `textures` | Patterns, textures, or abstract visual surfaces |
|
|
853
|
+
### Manual publish
|
|
299
854
|
|
|
300
|
-
|
|
855
|
+
```bash
|
|
856
|
+
./scripts/publish-package.sh cli # Publish as @latest
|
|
857
|
+
./scripts/publish-package.sh cli next # Publish as @next (pre-release)
|
|
858
|
+
```
|
|
301
859
|
|
|
302
|
-
|
|
860
|
+
### Testing a pre-release in sandboxes
|
|
303
861
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
5. **Use `--output files`** for compact, pipe-friendly output
|
|
309
|
-
6. **Check `baker status`** first to verify connectivity
|
|
862
|
+
```bash
|
|
863
|
+
npx convex env set BAKER_CLI_VERSION <version> # Override sandbox version
|
|
864
|
+
npx convex env remove BAKER_CLI_VERSION # Clean up after testing
|
|
865
|
+
```
|