@mccaskie-labs/workbench-config 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @mccaskie-labs/workbench-config
2
2
 
3
+ ## 0.2.4
4
+
5
+ ### Patch Changes
6
+
7
+ - Client questions for AI, pictures and picture search (feature or content): a routing question, then who may use a visitor feature and its monthly cap, or drafts of content made once. `npx workbench-ai drafts text|image|search` and `pick` make and keep that content through the Gateway with the development key. A drafts skill with no development key now offers the client's own wording or picture as well as the standard version.
8
+
3
9
  ## 0.2.3
4
10
 
5
11
  ### Patch Changes
@@ -7,8 +7,7 @@
7
7
  "status": "built",
8
8
  "delivery": {
9
9
  "choice": "built_in",
10
- "intro": "Writing, summarising and answering questions with Claude, with a monthly spending cap.",
11
- "when": "The client wants the app to write, summarise, sort, answer questions or pull details out of text with AI, as a feature visitors use or as something made once for the site."
10
+ "intro": "Writing, summarising and answering questions with Claude, with a monthly spending cap."
12
11
  },
13
12
  "surfaces": {
14
13
  "gateway": ["POST /anthropic/v1/messages", "POST /anthropic/v1/messages/count_tokens"],
@@ -118,5 +117,186 @@
118
117
  { "id": "ai.voice", "half": "runtime", "expect": "pass", "cost_hint_usd": 0.004 },
119
118
  { "id": "ai.voice.unknown", "half": "runtime", "expect": "refused_as_expected", "refusal": "invalid_request", "cost_hint_usd": 0 },
120
119
  { "id": "ai.voice.cache-read", "half": "runtime", "expect": "pass", "cost_hint_usd": 0.008 }
121
- ]
120
+ ],
121
+ "offer": {
122
+ "pattern": "feature_or_content",
123
+ "when": "The client wants the app to write, summarise, sort, answer questions or pull details out of text with AI, as a feature visitors use, or wants wording for the site written once.",
124
+ "say": "I'll do this with Workbench AI, which uses Claude through Workbench, so the app holds no AI key and spending has a monthly cap.",
125
+ "answers_file": "workbench/ai/<name>.json",
126
+ "per": "feature or piece of wording",
127
+ "answers_format": "For a feature: `{ \"format\": 1, \"route\": \"feature\", \"name\", \"about\" (the client's words), \"who\", \"cap_usd\", \"keep\", \"job\" }`, where `job` is the `X-Workbench-Job` the feature's calls send (`<name>` with dots, such as `quotes.estimate`), so its spending shows on its own line in Control. Write it, then build the feature with the package. For wording made once: `npx workbench-ai pick <name> <round>-<draft>` writes it from the draft the client picked, with the round's request ids and cost; never write one from nothing. Then put the wording into the strings catalogue (the workbench-strings skill), keyed for where it is shown. Drafts and their previews stay in `workbench/ai/drafts/`, which isn't committed.",
128
+ "questions": [
129
+ {
130
+ "id": "ai.route",
131
+ "sets": "route",
132
+ "ask": "Is this something visitors use on the site, or something made once for the site?",
133
+ "style": "cards",
134
+ "answers": [
135
+ {
136
+ "label": "Visitors use it",
137
+ "value": "feature",
138
+ "means": "A feature on the site that calls the AI each time someone uses it, such as a question box or a summary of what they paste in."
139
+ },
140
+ {
141
+ "label": "Made once for the site",
142
+ "value": "content",
143
+ "means": "Wording for a page, written once and kept: an About page, a welcome, product descriptions."
144
+ }
145
+ ],
146
+ "must_ask": true,
147
+ "note": "Ask it even when the client's words seem to say, as a quick check: the two routes are built and paid for differently."
148
+ },
149
+ {
150
+ "id": "ai.who",
151
+ "sets": "feature.who",
152
+ "ask": "Who may use it?",
153
+ "style": "cards",
154
+ "answers": [
155
+ {
156
+ "label": "People who are signed in",
157
+ "value": "signed_in",
158
+ "means": "Anyone with an account. Each use is tied to a person, so misuse can be traced and stopped."
159
+ },
160
+ {
161
+ "label": "Admins only",
162
+ "value": "admins",
163
+ "means": "Only the business's own admins, for example a tool for writing their own posts."
164
+ },
165
+ {
166
+ "label": "Anyone visiting",
167
+ "value": "anyone",
168
+ "means": "No sign-in. The page checks for bots (Turnstile) and limits how often one visitor can use it."
169
+ }
170
+ ],
171
+ "when": {
172
+ "id": "ai.route",
173
+ "is": [
174
+ "feature"
175
+ ]
176
+ },
177
+ "note": "Signed in means `requireUser` and admins means `app_admins`, as the workbench-sign-in skill says. For anyone, check Turnstile on every use and keep a per-visitor limit; say plainly that strangers can run up the cost. Pass `subject` on every call so the Gateway can tell people apart: `user:<id>` for a signed-in person, and for anyone a random id kept in a cookie (`visitor:<id>`), never an email address or name."
178
+ },
179
+ {
180
+ "id": "ai.cap",
181
+ "sets": "feature.cap_usd",
182
+ "ask": "How much may it spend in a month, at most? When it's reached, the feature stops until next month.",
183
+ "style": "cards",
184
+ "answers": [
185
+ {
186
+ "label": "US$5 a month",
187
+ "value": 5,
188
+ "means": "A small trial, or light use."
189
+ },
190
+ {
191
+ "label": "US$20 a month",
192
+ "value": 20,
193
+ "means": "Steady use by a small business's visitors."
194
+ },
195
+ {
196
+ "label": "US$50 a month",
197
+ "value": 50,
198
+ "means": "Heavy use. It can be raised later."
199
+ }
200
+ ],
201
+ "other": {
202
+ "kind": "money",
203
+ "min": 1,
204
+ "max": 1000,
205
+ "description": "US dollars a month, whole or with cents."
206
+ },
207
+ "must_ask": true,
208
+ "when": {
209
+ "id": "ai.route",
210
+ "is": [
211
+ "feature"
212
+ ]
213
+ },
214
+ "note": "Say roughly what one use costs (usually a cent or two with claude-default) so the owner can judge. The cap is the project's production cap for the `ai` tool in the Gateway, shared by every feature that uses it: set it with Workbench Control's `gw_budget_set` (env production, tool ai, monthly_usd). Raising a cap waits for the owner's approval on Control's approval page. When it is reached, calls fail with `budget_exceeded`: the page says the feature is resting until next month, never an error."
215
+ },
216
+ {
217
+ "id": "ai.sensitive",
218
+ "sets": "feature.keep",
219
+ "ask": "Will people type in sensitive personal details, such as their health, religion, money troubles or someone else's private information?",
220
+ "style": "cards",
221
+ "answers": [
222
+ {
223
+ "label": "No",
224
+ "value": "no",
225
+ "means": "Workbench keeps what each call sent and got back, so a problem can be traced."
226
+ },
227
+ {
228
+ "label": "Yes",
229
+ "value": "yes",
230
+ "means": "This feature's calls are marked not to be kept: Workbench records only that each call happened and what it cost."
231
+ }
232
+ ],
233
+ "must_ask": true,
234
+ "when": {
235
+ "id": "ai.route",
236
+ "is": [
237
+ "feature"
238
+ ]
239
+ },
240
+ "note": "With yes, pass `keep: false` on this feature's calls. If most of the app handles such details, suggest switching keeping off for the whole project instead (Workbench Control's `gw_keep_set`, env production, on false). Record it as `keep` (true or false) in the answers file."
241
+ },
242
+ {
243
+ "id": "ai.what",
244
+ "sets": [
245
+ "content.name",
246
+ "content.about"
247
+ ],
248
+ "ask": "What wording do you need?",
249
+ "style": "cards",
250
+ "answers": [
251
+ {
252
+ "label": "A page's main text",
253
+ "value": "page_text",
254
+ "means": "Such as an About page or a services page."
255
+ },
256
+ {
257
+ "label": "A short blurb",
258
+ "value": "blurb",
259
+ "means": "A line or two for the top of a page or a card."
260
+ },
261
+ {
262
+ "label": "Descriptions",
263
+ "value": "descriptions",
264
+ "means": "For products or services."
265
+ }
266
+ ],
267
+ "other": {
268
+ "kind": "text",
269
+ "min": 3,
270
+ "max": 200,
271
+ "description": "What the wording is, in a few words."
272
+ },
273
+ "when": {
274
+ "id": "ai.route",
275
+ "is": [
276
+ "content"
277
+ ]
278
+ },
279
+ "note": "Name the piece after where it goes (about_us, home_blurb): lower case and underscores. The client's own words, with any facts they give (when they started, where they are), go in --about, because the drafts never invent facts and leave [gaps] for the owner instead."
280
+ }
281
+ ],
282
+ "not_asked": [
283
+ {
284
+ "sets": "model",
285
+ "why": "Features use claude-default unless the work needs more (claude-best) or speed matters more than depth (claude-fast). Choose from what the feature does; the client can't judge models."
286
+ },
287
+ {
288
+ "sets": "voice",
289
+ "why": "The tone comes from the project's voice and spelling, set once for the whole site."
290
+ }
291
+ ],
292
+ "drafts": {
293
+ "of": "wording",
294
+ "surface": "ai",
295
+ "alias": "claude-default",
296
+ "count": 3,
297
+ "max_rounds": 3,
298
+ "job": "ai.drafts",
299
+ "command": "npx workbench-ai drafts text <name> --about \"<what it is for, with the client's facts>\""
300
+ }
301
+ }
122
302
  }
@@ -7,8 +7,7 @@
7
7
  "status": "built",
8
8
  "delivery": {
9
9
  "choice": "built_in",
10
- "intro": "Finding existing pictures on the web.",
11
- "when": "The client wants to find existing pictures on the web, for the site itself or as a search visitors use."
10
+ "intro": "Finding existing pictures on the web."
12
11
  },
13
12
  "surfaces": {
14
13
  "gateway": [
@@ -131,5 +130,157 @@
131
130
  "smoke": true,
132
131
  "cost_hint_usd": 0.001
133
132
  }
134
- ]
133
+ ],
134
+ "offer": {
135
+ "pattern": "feature_or_content",
136
+ "when": "The client wants to find existing pictures on the web, for the site itself or as a search visitors use.",
137
+ "say": "I'll do this with Workbench picture search, which searches the web through Workbench, so the app holds no search key and spending has a monthly cap.",
138
+ "answers_file": "workbench/image-search/<name>.json",
139
+ "per": "feature or picture",
140
+ "answers_format": "For a feature: `{ \"format\": 1, \"route\": \"feature\", \"name\", \"about\" (the client's words), \"who\", \"cap_usd\", \"job\" }`, where `job` is the `X-Workbench-Job` the feature's calls send (`<name>` with dots, such as `quotes.estimate`), so its spending shows on its own line in Control. Write it, then build the feature with the package. For a picture found once: `npx workbench-ai pick <name> <round>-<draft> --licence \"<the owner's words>\"` downloads it to `public/images/<name>.jpg` (or .png) and writes the answers file with where it came from and the licence; never write one from nothing, and never pick one without the licence answer. Show the credit the licence asks for beside the picture. Drafts and their previews stay in `workbench/image-search/drafts/`, which isn't committed.",
141
+ "questions": [
142
+ {
143
+ "id": "image-search.route",
144
+ "sets": "route",
145
+ "ask": "Is this something visitors use on the site, or something made once for the site?",
146
+ "style": "cards",
147
+ "answers": [
148
+ {
149
+ "label": "Visitors use it",
150
+ "value": "feature",
151
+ "means": "A search on the site that finds pictures for whoever uses it."
152
+ },
153
+ {
154
+ "label": "Made once for the site",
155
+ "value": "content",
156
+ "means": "A picture for the site, found once and kept."
157
+ }
158
+ ],
159
+ "must_ask": true,
160
+ "note": "Ask it even when the client's words seem to say, as a quick check: the two routes are built and paid for differently."
161
+ },
162
+ {
163
+ "id": "image-search.who",
164
+ "sets": "feature.who",
165
+ "ask": "Who may use it?",
166
+ "style": "cards",
167
+ "answers": [
168
+ {
169
+ "label": "People who are signed in",
170
+ "value": "signed_in",
171
+ "means": "Anyone with an account. Each use is tied to a person, so misuse can be traced and stopped."
172
+ },
173
+ {
174
+ "label": "Admins only",
175
+ "value": "admins",
176
+ "means": "Only the business's own admins, for example a tool for writing their own posts."
177
+ },
178
+ {
179
+ "label": "Anyone visiting",
180
+ "value": "anyone",
181
+ "means": "No sign-in. The page checks for bots (Turnstile) and limits how often one visitor can use it."
182
+ }
183
+ ],
184
+ "when": {
185
+ "id": "image-search.route",
186
+ "is": [
187
+ "feature"
188
+ ]
189
+ },
190
+ "note": "Signed in means `requireUser` and admins means `app_admins`, as the workbench-sign-in skill says. For anyone, check Turnstile on every use and keep a per-visitor limit; say plainly that strangers can run up the cost. Pass `subject` on every call so the Gateway can tell people apart: `user:<id>` for a signed-in person, and for anyone a random id kept in a cookie (`visitor:<id>`), never an email address or name."
191
+ },
192
+ {
193
+ "id": "image-search.cap",
194
+ "sets": "feature.cap_usd",
195
+ "ask": "How much may it spend in a month, at most? When it's reached, the feature stops until next month.",
196
+ "style": "cards",
197
+ "answers": [
198
+ {
199
+ "label": "US$5 a month",
200
+ "value": 5,
201
+ "means": "A small trial, or light use."
202
+ },
203
+ {
204
+ "label": "US$20 a month",
205
+ "value": 20,
206
+ "means": "Steady use by a small business's visitors."
207
+ },
208
+ {
209
+ "label": "US$50 a month",
210
+ "value": 50,
211
+ "means": "Heavy use. It can be raised later."
212
+ }
213
+ ],
214
+ "other": {
215
+ "kind": "money",
216
+ "min": 1,
217
+ "max": 1000,
218
+ "description": "US dollars a month, whole or with cents."
219
+ },
220
+ "must_ask": true,
221
+ "when": {
222
+ "id": "image-search.route",
223
+ "is": [
224
+ "feature"
225
+ ]
226
+ },
227
+ "note": "Say roughly what one use costs (about a tenth of a cent a search) so the owner can judge. The cap is the project's production cap for the `search` tool in the Gateway, shared by every feature that uses it: set it with Workbench Control's `gw_budget_set` (env production, tool search, monthly_usd). Raising a cap waits for the owner's approval on Control's approval page. When it is reached, calls fail with `budget_exceeded`: the page says the feature is resting until next month, never an error."
228
+ },
229
+ {
230
+ "id": "image-search.licence",
231
+ "sets": "content.licence",
232
+ "ask": "Does the site have the right to use this picture?",
233
+ "style": "cards",
234
+ "answers": [
235
+ {
236
+ "label": "Yes, it's ours",
237
+ "value": "own",
238
+ "means": "The business took it or owns it."
239
+ },
240
+ {
241
+ "label": "Yes, it's free to use",
242
+ "value": "free",
243
+ "means": "Its page says so, with a licence such as CC BY. Say which."
244
+ },
245
+ {
246
+ "label": "No, find another",
247
+ "value": "none",
248
+ "means": "Pick another result, or make one with AI pictures instead."
249
+ }
250
+ ],
251
+ "other": {
252
+ "kind": "text",
253
+ "min": 3,
254
+ "max": 200,
255
+ "description": "What gives the site the right to use it."
256
+ },
257
+ "must_ask": true,
258
+ "when": {
259
+ "id": "image-search.route",
260
+ "is": [
261
+ "content"
262
+ ]
263
+ },
264
+ "note": "Ask after the client picks a result, showing its page link. A search result is a lead, not permission. Pass the client's words as --licence; with no, don't pick it."
265
+ }
266
+ ],
267
+ "not_asked": [
268
+ {
269
+ "sets": "query",
270
+ "why": "The client's description is the search: pass it as --about, shortened to the words that matter."
271
+ },
272
+ {
273
+ "sets": "filters",
274
+ "why": "Results narrower than 600 pixels are dropped; anything finer (shape, site) is for a feature to do in its own code."
275
+ }
276
+ ],
277
+ "drafts": {
278
+ "of": "found pictures",
279
+ "surface": "image-search",
280
+ "count": 4,
281
+ "max_rounds": 3,
282
+ "job": "image-search.drafts",
283
+ "command": "npx workbench-ai drafts search <name> --about \"<what to search for>\""
284
+ }
285
+ }
135
286
  }
@@ -7,8 +7,7 @@
7
7
  "status": "built",
8
8
  "delivery": {
9
9
  "choice": "built_in",
10
- "intro": "Pictures made by AI from a description.",
11
- "when": "The client wants a picture made by AI, such as an illustration, a hero image or a product mock-up, as a feature visitors use or once for the site."
10
+ "intro": "Pictures made by AI from a description."
12
11
  },
13
12
  "surfaces": {
14
13
  "gateway": [
@@ -209,5 +208,195 @@
209
208
  "refusal": "invalid_request",
210
209
  "cost_hint_usd": 0
211
210
  }
212
- ]
211
+ ],
212
+ "offer": {
213
+ "pattern": "feature_or_content",
214
+ "when": "The client wants a picture made by AI, such as an illustration, a hero image or a product mock-up, as a feature visitors use or once for the site.",
215
+ "say": "I'll make this with Workbench pictures, made by AI through Workbench, so the app holds no image key and spending has a monthly cap.",
216
+ "answers_file": "workbench/images/<name>.json",
217
+ "per": "feature or picture",
218
+ "answers_format": "For a feature: `{ \"format\": 1, \"route\": \"feature\", \"name\", \"about\" (the client's words), \"who\", \"cap_usd\", \"job\" }`, where `job` is the `X-Workbench-Job` the feature's calls send (`<name>` with dots, such as `quotes.estimate`), so its spending shows on its own line in Control. Write it, then build the feature with the package. For a picture made once: `npx workbench-ai pick <name> <round>-<draft>` copies the picked picture to `public/images/<name>.png` (or .jpg) and writes the answers file with its prompt, model, request id and cost; never write one from nothing. Show it on the page from `/images/<name>.png`, with alt text that says what it shows. Drafts and their previews stay in `workbench/images/drafts/`, which isn't committed.",
219
+ "questions": [
220
+ {
221
+ "id": "images.route",
222
+ "sets": "route",
223
+ "ask": "Is this something visitors use on the site, or something made once for the site?",
224
+ "style": "cards",
225
+ "answers": [
226
+ {
227
+ "label": "Visitors use it",
228
+ "value": "feature",
229
+ "means": "A feature that makes a new picture each time someone uses it, such as a mock-up of their own design."
230
+ },
231
+ {
232
+ "label": "Made once for the site",
233
+ "value": "content",
234
+ "means": "A picture for the site, made once and kept: a hero image, an illustration for a page."
235
+ }
236
+ ],
237
+ "must_ask": true,
238
+ "note": "Ask it even when the client's words seem to say, as a quick check: the two routes are built and paid for differently."
239
+ },
240
+ {
241
+ "id": "images.who",
242
+ "sets": "feature.who",
243
+ "ask": "Who may use it?",
244
+ "style": "cards",
245
+ "answers": [
246
+ {
247
+ "label": "People who are signed in",
248
+ "value": "signed_in",
249
+ "means": "Anyone with an account. Each use is tied to a person, so misuse can be traced and stopped."
250
+ },
251
+ {
252
+ "label": "Admins only",
253
+ "value": "admins",
254
+ "means": "Only the business's own admins, for example a tool for writing their own posts."
255
+ },
256
+ {
257
+ "label": "Anyone visiting",
258
+ "value": "anyone",
259
+ "means": "No sign-in. The page checks for bots (Turnstile) and limits how often one visitor can use it."
260
+ }
261
+ ],
262
+ "when": {
263
+ "id": "images.route",
264
+ "is": [
265
+ "feature"
266
+ ]
267
+ },
268
+ "note": "Signed in means `requireUser` and admins means `app_admins`, as the workbench-sign-in skill says. For anyone, check Turnstile on every use and keep a per-visitor limit; say plainly that strangers can run up the cost. Pass `subject` on every call so the Gateway can tell people apart: `user:<id>` for a signed-in person, and for anyone a random id kept in a cookie (`visitor:<id>`), never an email address or name."
269
+ },
270
+ {
271
+ "id": "images.cap",
272
+ "sets": "feature.cap_usd",
273
+ "ask": "How much may it spend in a month, at most? When it's reached, the feature stops until next month.",
274
+ "style": "cards",
275
+ "answers": [
276
+ {
277
+ "label": "US$5 a month",
278
+ "value": 5,
279
+ "means": "A small trial, or light use."
280
+ },
281
+ {
282
+ "label": "US$20 a month",
283
+ "value": 20,
284
+ "means": "Steady use by a small business's visitors."
285
+ },
286
+ {
287
+ "label": "US$50 a month",
288
+ "value": 50,
289
+ "means": "Heavy use. It can be raised later."
290
+ }
291
+ ],
292
+ "other": {
293
+ "kind": "money",
294
+ "min": 1,
295
+ "max": 1000,
296
+ "description": "US dollars a month, whole or with cents."
297
+ },
298
+ "must_ask": true,
299
+ "when": {
300
+ "id": "images.route",
301
+ "is": [
302
+ "feature"
303
+ ]
304
+ },
305
+ "note": "Say roughly what one use costs (about US$0.07 a picture with image-default) so the owner can judge. The cap is the project's production cap for the `images` tool in the Gateway, shared by every feature that uses it: set it with Workbench Control's `gw_budget_set` (env production, tool images, monthly_usd). Raising a cap waits for the owner's approval on Control's approval page. When it is reached, calls fail with `budget_exceeded`: the page says the feature is resting until next month, never an error."
306
+ },
307
+ {
308
+ "id": "images.what",
309
+ "sets": [
310
+ "content.name",
311
+ "content.about"
312
+ ],
313
+ "ask": "What picture do you need?",
314
+ "style": "cards",
315
+ "answers": [
316
+ {
317
+ "label": "A hero image",
318
+ "value": "hero",
319
+ "means": "The large picture across the top of a page."
320
+ },
321
+ {
322
+ "label": "An illustration",
323
+ "value": "illustration",
324
+ "means": "A drawing for a page or a section."
325
+ },
326
+ {
327
+ "label": "A product mock-up",
328
+ "value": "mockup",
329
+ "means": "A product shown in use or in a setting."
330
+ }
331
+ ],
332
+ "other": {
333
+ "kind": "text",
334
+ "min": 3,
335
+ "max": 200,
336
+ "description": "What the picture is, in a few words."
337
+ },
338
+ "when": {
339
+ "id": "images.route",
340
+ "is": [
341
+ "content"
342
+ ]
343
+ },
344
+ "note": "Name the picture after where it goes (home_hero): lower case and underscores. The client's own words about what it shows and the feel they want go in --about."
345
+ },
346
+ {
347
+ "id": "images.shape",
348
+ "sets": "content.aspect",
349
+ "ask": "What shape should it be?",
350
+ "style": "cards",
351
+ "answers": [
352
+ {
353
+ "label": "Landscape (3:2)",
354
+ "value": "3:2",
355
+ "means": "Wider than tall, the usual shape for a page."
356
+ },
357
+ {
358
+ "label": "Wide banner (16:9)",
359
+ "value": "16:9",
360
+ "means": "For a picture across the top of a page."
361
+ },
362
+ {
363
+ "label": "Square (1:1)",
364
+ "value": "1:1",
365
+ "means": "For cards and social posts."
366
+ },
367
+ {
368
+ "label": "Portrait (2:3)",
369
+ "value": "2:3",
370
+ "means": "Taller than wide."
371
+ }
372
+ ],
373
+ "when": {
374
+ "id": "images.route",
375
+ "is": [
376
+ "content"
377
+ ]
378
+ },
379
+ "note": "Recommend the banner for a hero image. Pass it to the drafts command as --aspect."
380
+ }
381
+ ],
382
+ "not_asked": [
383
+ {
384
+ "sets": "model",
385
+ "why": "Drafts and features use image-default. image-pro costs about twice as much for finer detail and image-openai is cheapest; suggest one only when the client asks about quality or cost."
386
+ },
387
+ {
388
+ "sets": "references",
389
+ "why": "A reference picture (to make something like it) is only for a feature that needs one, and works with Google aliases only; offer it when the client mentions one."
390
+ }
391
+ ],
392
+ "drafts": {
393
+ "of": "pictures",
394
+ "surface": "images",
395
+ "alias": "image-default",
396
+ "count": 3,
397
+ "max_rounds": 3,
398
+ "job": "images.drafts",
399
+ "command": "npx workbench-ai drafts image <name> --about \"<what it shows, in the client's words>\" --aspect <shape>"
400
+ }
401
+ }
213
402
  }