felo-ai 0.2.46 → 0.2.48

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.
@@ -9,9 +9,9 @@ description: "Felo SuperAgent API: AI conversation with real-time SSE streaming
9
9
 
10
10
  These rules are mandatory. Violating any of them will produce incorrect behavior.
11
11
 
12
- 1. **NEVER use `--json` flag.** The script MUST run in default (streaming) mode so that SuperAgent's answer is printed directly to stdout in real time. The `--json` flag suppresses all streaming output and is forbidden. State IDs are extracted from the `[state]` line in stderr instead.
12
+ 1. **ALWAYS use `--json` flag.** The script MUST run in JSON mode (`--json`). In Claude Code's Bash tool, stdout is always captured — it never streams directly to the user. JSON mode returns the full answer in a structured response that Claude can then output as text. State IDs are extracted from the JSON response fields `thread_short_id` and `live_doc_short_id`.
13
13
 
14
- 2. **NEVER summarize, rewrite, or re-output the script's stdout.** The script already streams the full answer and tool results directly to the user. After the script finishes, do NOT repeat, paraphrase, or summarize the answer. Only output supplementary information (LiveDoc URL, session state notes) if needed.
14
+ 2. **ALWAYS output the answer directly as text.** After the script finishes, read `data.answer` from the JSON output and print it verbatim as your response text. Do NOT summarize, paraphrase, or add commentary around it. Output it exactly as-is so the user sees the full content.
15
15
 
16
16
  3. **`--live-doc-id` is REQUIRED when creating a conversation.** Never call `run_superagent.mjs` without `--live-doc-id`. If you do not have one yet, obtain it first (see Step 2 below).
17
17
 
@@ -38,7 +38,18 @@ These rules are mandatory. Violating any of them will produce incorrect behavior
38
38
  - If none of the above match, do NOT pass `--skill-id` (general conversation mode)
39
39
  - `--skill-id` is only effective when creating a new conversation. It is ignored in follow-up mode (`--thread-id`).
40
40
 
41
- 9. **Never create a new LiveDoc casually.** Reuse the existing one. The only exception is an explicit user request for a new canvas/workspace.
41
+ 9. **Brand style selection for skill-based new conversations.** When starting a NEW conversation that uses a skill ID (`twitter-writer`, `logo-and-branding`, `ecommerce-product-image`), you MUST fetch the style library and let the user choose a style BEFORE calling `run_superagent.mjs`. The chosen style is passed via `--ext '{"brand_style_requirement":"<style_string>"}'`. See Step 4.5 for the full procedure.
42
+
43
+ - The style string is the exact text block output by `run_style_library.mjs` for that entry. Fields vary by category:
44
+ - **TWITTER**: `Style name` + `Style labels` (language-aware) + `Style DNA` + `Cover file ID` (omitted if null)
45
+ - **IMAGE**: `Style name` + `Style labels` + `Style DNA` or `Cover file ID` depending on what is present
46
+ - Use the category that matches the skill: `TWITTER` for `twitter-writer`, `IMAGE` for `logo-and-branding` and `ecommerce-product-image`.
47
+ - Always pass `--accept-language` to `run_style_library.mjs` so labels are returned in the user's language.
48
+ - If the user has already specified a style (by name or by pasting the style block), skip the fetch and use their choice directly.
49
+ - If the style library returns no entries, proceed without `--ext`.
50
+ - `--ext` is only valid for new conversations. Never pass it in follow-up mode (`--thread-id`).
51
+
52
+ 10. **Never create a new LiveDoc casually.** Reuse the existing one. The only exception is an explicit user request for a new canvas/workspace.
42
53
 
43
54
  ## When to Use
44
55
 
@@ -81,13 +92,19 @@ Trigger this skill when users want:
81
92
 
82
93
  ### 2. Configure API Key
83
94
 
84
- Set the `FELO_API_KEY` environment variable:
95
+ The scripts (`run_superagent.mjs`, `run_style_library.mjs`) read the API key **only from the `FELO_API_KEY` environment variable**. The `felo config set` CLI command writes to `~/.felo/config.json` which these scripts do NOT read — environment variable is the only supported method.
85
96
 
86
97
  **Linux/macOS:**
87
98
  ```bash
88
99
  export FELO_API_KEY="your-api-key-here"
89
100
  ```
90
101
 
102
+ For permanent configuration, add to your shell profile (`~/.bashrc` or `~/.zshrc`):
103
+ ```bash
104
+ echo 'export FELO_API_KEY="your-api-key-here"' >> ~/.zshrc
105
+ source ~/.zshrc
106
+ ```
107
+
91
108
  **Windows (PowerShell):**
92
109
  ```powershell
93
110
  $env:FELO_API_KEY="your-api-key-here"
@@ -98,8 +115,6 @@ $env:FELO_API_KEY="your-api-key-here"
98
115
  set FELO_API_KEY=your-api-key-here
99
116
  ```
100
117
 
101
- For permanent configuration, add it to your shell profile (~/.bashrc, ~/.zshrc) or system environment variables.
102
-
103
118
  ### 3. Dependency: felo-livedoc
104
119
 
105
120
  This skill depends on the `felo-livedoc` skill to obtain and create LiveDocs. Ensure `felo-livedoc/scripts/run_livedoc.mjs` is available at the same level as `felo-superAgent/`.
@@ -148,7 +163,7 @@ Example response:
148
163
  }
149
164
  ```
150
165
 
151
- Use: `live_doc_id = items[0].short_id`
166
+ Use: `live_doc_id = data.items[0].short_id`
152
167
 
153
168
  **2c. If the list is empty (no LiveDocs exist) — create one:**
154
169
 
@@ -204,9 +219,93 @@ If this is a new conversation (no `--thread-id`), analyze the user's intent:
204
219
 
205
220
  If this is a follow-up (`--thread-id` is set), skip this step entirely. `--skill-id` is ignored in follow-up mode.
206
221
 
222
+ ### Step 4.5: Fetch and Select Brand Style (New Skill Conversations Only)
223
+
224
+ **When to run this step:** Only when this is a NEW conversation AND a skill ID was determined in Step 4 (`twitter-writer`, `logo-and-branding`, or `ecommerce-product-image`). Skip entirely for follow-up conversations or general (no skill) conversations.
225
+
226
+ **Category mapping:**
227
+ | Skill ID | Style category |
228
+ |---|---|
229
+ | `twitter-writer` | `TWITTER` |
230
+ | `logo-and-branding` | `IMAGE` |
231
+ | `ecommerce-product-image` | `IMAGE` |
232
+
233
+ **4.5a. If the user has already specified a style** (by name, or by pasting a style block), use it directly — skip to 4.5d.
234
+
235
+ **4.5b. Fetch the style list:**
236
+
237
+ Use the category that matches the skill:
238
+
239
+ | Skill ID | `--category` |
240
+ |---|---|
241
+ | `twitter-writer` | `TWITTER` |
242
+ | `logo-and-branding` | `IMAGE` |
243
+ | `ecommerce-product-image` | `IMAGE` |
244
+
245
+ Pass `--accept-language` matching the user's language (same value used for SuperAgent).
246
+
247
+ ```bash
248
+ # For twitter-writer
249
+ node felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language en
250
+
251
+ # For logo-and-branding or ecommerce-product-image
252
+ node felo-superAgent/scripts/run_style_library.mjs --category IMAGE --accept-language en
253
+ ```
254
+
255
+ The output lists styles in this format, one block per style separated by a blank line:
256
+
257
+ ```
258
+ Style name: darioamodei
259
+ Style labels: Thoughtful long-form essays
260
+ Style DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA
261
+ ...(full content)
262
+
263
+ Style name: Casual & Witty
264
+ Style labels: humor, relatable
265
+ Style DNA: ...(full content)
266
+ Cover file ID: file_abc123
267
+ ```
268
+
269
+ Notes:
270
+ - `Style labels` is omitted if no labels exist for this entry.
271
+ - `Style DNA` is the full text of `content.styleDna` (TWITTER type). Do NOT truncate it.
272
+ - `Cover file ID` is omitted if the value is null/empty.
273
+
274
+ User-created styles appear first, followed by recommended styles.
275
+
276
+ **4.5c. Present the styles to the user and ask them to choose:**
277
+
278
+ Show the list (style names only is sufficient) and ask which one to use. Wait for the user's selection before proceeding.
279
+
280
+ Example prompt to user:
281
+ > Here are the available Twitter writing styles. Which one would you like to use?
282
+ > 1. Casual & Witty (your style)
283
+ > 2. Professional Thought Leader (recommended)
284
+ > 3. No style preference — use default
285
+
286
+ If the user picks "no preference" or the list is empty, proceed to Step 5 without `--ext`.
287
+
288
+ **4.5d. Build the `--ext` value:**
289
+
290
+ Take the full text block for the chosen style (exactly as output by the script) and use it as the value of `brand_style_requirement`. The block may contain multiple lines — serialize them into a single JSON string with `\n` for newlines and `\"` for any double quotes inside field values:
291
+
292
+ Example style block output:
293
+ ```
294
+ Style name: darioamodei
295
+ Style labels: Thoughtful long-form essays
296
+ Style DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA\n\n## 风格速写\nDario writes like a serious intellectual...
297
+ ```
298
+
299
+ Serialized as `--ext`:
300
+ ```bash
301
+ --ext '{"brand_style_requirement":"Style name: darioamodei\nStyle labels: Thoughtful long-form essays\nStyle DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA\n\n## 风格速写\nDario writes like a serious intellectual..."}'
302
+ ```
303
+
304
+ **Important:** Pass the `brand_style_requirement` value completely and verbatim — do NOT truncate `Style DNA`. Partial style content will degrade output quality.
305
+
207
306
  ### Step 5: Run the Script
208
307
 
209
- Construct and execute the command. **NEVER use `--json`** — the script must run in default streaming mode so the answer is printed directly to the user in real time.
308
+ Construct and execute the command. **ALWAYS use `--json`** — in Claude Code's Bash tool, stdout is captured, not streamed to the user. JSON mode returns the full answer in a structured response.
210
309
 
211
310
  **IMPORTANT:** The SSE stream may take a long time (especially for image generation, research reports, etc.). You MUST set the Bash tool timeout to at least 600000ms (10 minutes) when executing the script to prevent premature termination.
212
311
 
@@ -225,21 +324,34 @@ Examples:
225
324
  - User says "再来一张" → `--query "请再生成一张类似风格的无线耳机产品图,白色背景"`
226
325
  - User says "帮我改改" → `--query "请修改上面生成的推文,语气更轻松一些,加一些emoji"`
227
326
 
228
- **New conversation (first question):**
327
+ **New conversation (first question, no skill):**
229
328
  ```bash
230
329
  node felo-superAgent/scripts/run_superagent.mjs \
231
330
  --query "USER_QUERY_HERE" \
232
331
  --live-doc-id "LIVE_DOC_ID" \
233
- --accept-language en
332
+ --accept-language en \
333
+ --json
334
+ ```
335
+
336
+ **New conversation with skill ID, no style selected:**
337
+ ```bash
338
+ node felo-superAgent/scripts/run_superagent.mjs \
339
+ --query "Write a tweet about the latest AI trends" \
340
+ --live-doc-id "LIVE_DOC_ID" \
341
+ --skill-id twitter-writer \
342
+ --accept-language en \
343
+ --json
234
344
  ```
235
345
 
236
- **New conversation with skill ID (e.g., tweet writing):**
346
+ **New conversation with skill ID and brand style (from Step 4.5):**
237
347
  ```bash
238
348
  node felo-superAgent/scripts/run_superagent.mjs \
239
349
  --query "Write a tweet about the latest AI trends" \
240
350
  --live-doc-id "LIVE_DOC_ID" \
241
351
  --skill-id twitter-writer \
242
- --accept-language en
352
+ --ext '{"brand_style_requirement":"Style name: darioamodei\nStyle labels: Thoughtful long-form essays\nStyle DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA\n\n## 风格速写\nDario writes like a serious intellectual...(full content)"}' \
353
+ --accept-language en \
354
+ --json
243
355
  ```
244
356
 
245
357
  **Follow-up question (DEFAULT for 2nd+ messages):**
@@ -247,23 +359,31 @@ node felo-superAgent/scripts/run_superagent.mjs \
247
359
  node felo-superAgent/scripts/run_superagent.mjs \
248
360
  --query "USER_FOLLOW_UP_QUERY" \
249
361
  --thread-id "THREAD_SHORT_ID_FROM_PREVIOUS" \
250
- --live-doc-id "LIVE_DOC_ID"
362
+ --live-doc-id "LIVE_DOC_ID" \
363
+ --json
251
364
  ```
252
365
 
253
- ### Step 6: Extract State from stderr (Do NOT Re-output the Answer)
366
+ ### Step 6: Extract State and Output the Answer
254
367
 
255
- The script has already streamed the full answer and tool results directly to stdout. **Do NOT repeat, summarize, or rewrite any of that content.**
368
+ After the script finishes, parse the JSON output:
256
369
 
257
- After the script finishes, look for the `[state]` line in stderr output:
258
-
259
- ```
260
- [state] thread_short_id=CmYpuGwBgCnrUdDx5ZtmxA live_doc_short_id=QPetunwpGnkKuZHStP7gwt live_doc_url=https://felo.ai/livedoc/QPetunwpGnkKuZHStP7gwt
370
+ ```json
371
+ {
372
+ "status": "ok",
373
+ "data": {
374
+ "answer": "...",
375
+ "thread_short_id": "CmYpuGwBgCnrUdDx5ZtmxA",
376
+ "live_doc_short_id": "QPetunwpGnkKuZHStP7gwt",
377
+ "live_doc_url": "https://felo.ai/livedoc/QPetunwpGnkKuZHStP7gwt"
378
+ }
379
+ }
261
380
  ```
262
381
 
263
- 1. **Extract and save** `thread_short_id` and `live_doc_id` (from the `live_doc_short_id` field in the `[state]` line) you MUST use these in the next call.
264
- 2. **Optionally show** the `live_doc_url` link to the user so they can view the LiveDoc canvas in a browser.
382
+ 1. **Output `data.answer` verbatim** as your response text print it exactly as-is so the user sees the full content.
383
+ 2. **Extract and save** `data.thread_short_id` and `data.live_doc_short_id` you MUST use these in the next call.
384
+ 3. **Optionally show** `data.live_doc_url` so the user can view the LiveDoc canvas in a browser.
265
385
 
266
- Do NOT show `thread_short_id` or `live_doc_id` to the user unless they ask for it. These are internal state for the skill to manage.
386
+ Do NOT show `thread_short_id` or `live_doc_short_id` to the user unless they ask for it.
267
387
 
268
388
  ## Complete Workflow Examples
269
389
 
@@ -281,9 +401,10 @@ User: "What is quantum computing?"
281
401
  node felo-superAgent/scripts/run_superagent.mjs \
282
402
  --query "What is quantum computing?" \
283
403
  --live-doc-id "QPetunwpGnkKuZHStP7gwt" \
284
- --accept-language en
404
+ --accept-language en \
405
+ --json
285
406
  ```
286
- **Step 6:** The answer is already streamed to the user. Extract from stderr `[state]` line: `thread_short_id = "CmYpuGwBgCnrUdDx5ZtmxA"`, `live_doc_id = "QPetunwpGnkKuZHStP7gwt"`. Do NOT repeat the answer.
407
+ **Step 6:** Parse JSON output. Output `data.answer` verbatim as your response. Save `thread_short_id = "CmYpuGwBgCnrUdDx5ZtmxA"`, `live_doc_id = "QPetunwpGnkKuZHStP7gwt"` from `data`.
287
408
 
288
409
  ```
289
410
  User: "What are its practical applications?"
@@ -296,9 +417,10 @@ User: "What are its practical applications?"
296
417
  node felo-superAgent/scripts/run_superagent.mjs \
297
418
  --query "What are its practical applications?" \
298
419
  --thread-id "CmYpuGwBgCnrUdDx5ZtmxA" \
299
- --live-doc-id "QPetunwpGnkKuZHStP7gwt"
420
+ --live-doc-id "QPetunwpGnkKuZHStP7gwt" \
421
+ --json
300
422
  ```
301
- **Step 6:** Answer already streamed. Extract updated `thread_short_id` from stderr `[state]` line (may be the same), keep `live_doc_id`.
423
+ **Step 6:** Parse JSON output. Output `data.answer` verbatim. Save updated `thread_short_id` from `data` (may be the same), keep `live_doc_id`.
302
424
 
303
425
  ```
304
426
  User: "Tell me more about quantum error correction"
@@ -307,68 +429,113 @@ User: "Tell me more about quantum error correction"
307
429
  **Step 3:** Still follow-up (same topic) → use saved `thread_short_id`
308
430
  **Step 5:** Same pattern as above with new query
309
431
 
310
- ### Example B: Tweet Writing
432
+ ### Example B: Tweet Writing with Style Selection
311
433
 
312
434
  ```
313
435
  User: "Help me write a tweet about AI trends"
314
436
  ```
315
437
 
316
438
  **Step 2a:** Already have `live_doc_id` → reuse
317
- **Step 3:** New conversation — `--skill-id twitter-writer` is required, which only takes effect in new conversations
439
+ **Step 3:** New conversation
318
440
  **Step 4:** User intent matches "write a tweet" → `--skill-id twitter-writer`
441
+ **Step 4.5:** Fetch TWITTER styles (pass `--accept-language` matching user's language):
442
+ ```bash
443
+ node felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language en
444
+ ```
445
+ Output:
446
+ ```
447
+ Style name: My Bold Voice
448
+ Style labels: bold, provocative
449
+ Style DNA: # My Bold Voice Style DNA
450
+ ...(full content)
451
+
452
+ Style name: darioamodei
453
+ Style labels: Thoughtful long-form essays
454
+ Style DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA
455
+ ...(full content)
456
+ ```
457
+ Present to user: "Which writing style would you like? 1. My Bold Voice (yours) 2. darioamodei (recommended) 3. No preference"
458
+
459
+ User selects: "1. My Bold Voice"
460
+
319
461
  **Step 5:**
320
462
  ```bash
321
463
  node felo-superAgent/scripts/run_superagent.mjs \
322
464
  --query "Help me write a tweet about AI trends" \
323
465
  --live-doc-id "QPetunwpGnkKuZHStP7gwt" \
324
466
  --skill-id twitter-writer \
325
- --accept-language en
467
+ --ext '{"brand_style_requirement":"Style name: My Bold Voice\nStyle labels: bold, provocative\nStyle DNA: # My Bold Voice Style DNA\n...(full content)"}' \
468
+ --accept-language en \
469
+ --json
326
470
  ```
327
- **Step 6:** Answer already streamed. Extract new `thread_short_id` from stderr `[state]` line, keep same `live_doc_id`.
471
+ **Step 6:** Parse JSON output. Output `data.answer` verbatim. Save new `thread_short_id` from `data`, keep same `live_doc_id`.
328
472
 
329
473
  ```
330
474
  User: "Make it more casual and add some emojis"
331
475
  ```
332
476
 
333
- **Step 3:** Follow-up → use saved `thread_short_id`
477
+ **Step 3:** Follow-up → use saved `thread_short_id` (do NOT pass `--ext` again)
334
478
  **Step 5:**
335
479
  ```bash
336
480
  node felo-superAgent/scripts/run_superagent.mjs \
337
481
  --query "Make it more casual and add some emojis" \
338
482
  --thread-id "NEW_THREAD_FROM_TWEET" \
339
- --live-doc-id "QPetunwpGnkKuZHStP7gwt"
483
+ --live-doc-id "QPetunwpGnkKuZHStP7gwt" \
484
+ --json
340
485
  ```
341
486
 
342
- ### Example C: Logo Design
487
+ ### Example C: Logo Design with Style Selection
343
488
 
344
489
  ```
345
490
  User: "Design a logo for my coffee shop called Bean & Brew"
346
491
  ```
347
492
 
348
493
  **Step 4:** Detected "design a logo" → `--skill-id logo-and-branding`
494
+ **Step 4.5:** Fetch IMAGE styles:
495
+ ```bash
496
+ node felo-superAgent/scripts/run_style_library.mjs --category IMAGE --accept-language en
497
+ ```
498
+ Output example:
499
+ ```
500
+ Style name: Minimalist Modern
501
+ Style labels: clean, monochrome
502
+ Style DNA: ...(full content)
503
+ Cover file ID: file_333
504
+ ```
505
+ Present styles to user and wait for selection. Suppose user picks "Minimalist Modern":
506
+
349
507
  **Step 5:**
350
508
  ```bash
351
509
  node felo-superAgent/scripts/run_superagent.mjs \
352
510
  --query "Design a logo for my coffee shop called Bean & Brew" \
353
511
  --live-doc-id "QPetunwpGnkKuZHStP7gwt" \
354
512
  --skill-id logo-and-branding \
355
- --accept-language en
513
+ --ext '{"brand_style_requirement":"Style name: Minimalist Modern\nStyle labels: clean, monochrome\nStyle DNA: ...(full content)\nCover file ID: file_333"}' \
514
+ --accept-language en \
515
+ --json
356
516
  ```
357
517
 
358
- ### Example D: E-commerce Product Image
518
+ ### Example D: E-commerce Product Image with Style Selection
359
519
 
360
520
  ```
361
521
  User: "Generate a product image for a wireless headphone on white background"
362
522
  ```
363
523
 
364
524
  **Step 4:** Detected "product image" → `--skill-id ecommerce-product-image`
365
- **Step 5:**
525
+ **Step 4.5:** Fetch IMAGE styles:
526
+ ```bash
527
+ node felo-superAgent/scripts/run_style_library.mjs --category IMAGE --accept-language en
528
+ ```
529
+ Present styles to user. Suppose user picks "No preference":
530
+
531
+ **Step 5:** (no `--ext` since user chose no preference)
366
532
  ```bash
367
533
  node felo-superAgent/scripts/run_superagent.mjs \
368
534
  --query "Generate a product image for a wireless headphone on white background" \
369
535
  --live-doc-id "QPetunwpGnkKuZHStP7gwt" \
370
536
  --skill-id ecommerce-product-image \
371
- --accept-language en
537
+ --accept-language en \
538
+ --json
372
539
  ```
373
540
 
374
541
  ### Example E: User Requests a New Canvas
@@ -383,6 +550,30 @@ node felo-livedoc/scripts/run_livedoc.mjs create --name "New Project" --json
383
550
  ```
384
551
  Extract new `live_doc_id`. Discard the old one. All subsequent calls use the new ID.
385
552
 
553
+ ### Example F: User Specifies Style Directly
554
+
555
+ ```
556
+ User: "Write a tweet about AI trends using the 'darioamodei' style"
557
+ ```
558
+
559
+ **Step 4:** `--skill-id twitter-writer`
560
+ **Step 4.5a:** User already named the style → fetch the list to get the full block:
561
+ ```bash
562
+ node felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language en
563
+ ```
564
+ Find the entry with `Style name: darioamodei`, extract its full block verbatim. No need to ask the user again.
565
+
566
+ **Step 5:**
567
+ ```bash
568
+ node felo-superAgent/scripts/run_superagent.mjs \
569
+ --query "Write a tweet about AI trends" \
570
+ --live-doc-id "QPetunwpGnkKuZHStP7gwt" \
571
+ --skill-id twitter-writer \
572
+ --ext '{"brand_style_requirement":"Style name: darioamodei\nStyle labels: Thoughtful long-form essays\nStyle DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA\n\n## 风格速写\nDario writes like a serious intellectual...(full content, do NOT truncate)"}' \
573
+ --accept-language en \
574
+ --json
575
+ ```
576
+
386
577
  ## Available Script Options
387
578
 
388
579
  **Core parameters:**
@@ -391,12 +582,14 @@ Extract new `live_doc_id`. Discard the old one. All subsequent calls use the new
391
582
  - `--thread-id <id>` — Thread ID from previous response, for follow-up conversations
392
583
 
393
584
  **Skill parameters (new conversations only, ignored in follow-up):**
394
- - `--skill-id <id>` — Skill ID (see Constraint #8 for available skill IDs)
585
+ - `--skill-id <id>` — Skill ID (see Constraint #9 for available skill IDs)
395
586
  - `--selected-resource-ids <ids>` — Comma-separated resource IDs to include
396
- - `--ext <json>` — Extra parameters as JSON object
587
+ - `--ext <json>` — Extra parameters as JSON object. For skill-based conversations, pass brand style as:
588
+ `--ext '{"brand_style_requirement":"Style name: <name>\nStyle labels: <labels>\nStyle DNA: <full styleDna text>\nCover file ID: <id>"}'`
589
+ Fields present depend on category type. `Cover file ID` is omitted when null. Do NOT truncate `Style DNA`.
397
590
 
398
591
  **Output control:**
399
- - `--json` / `-j` — Output JSON format with full metadata (DO NOT use in this skillit suppresses streaming output)
592
+ - `--json` / `-j` — Output JSON format with full metadata (ALWAYS use this in Claude Codestdout is captured by the Bash tool, not streamed to the user)
400
593
  - `--verbose` / `-v` — Log stream connection details to stderr (for debugging only, not needed for normal use)
401
594
  - `--accept-language <lang>` — Language preference (e.g., en, ja, ko)
402
595
 
@@ -505,8 +698,8 @@ To use this skill, you need to set up your Felo API Key:
505
698
  ## Important Notes
506
699
 
507
700
  - Execute this skill immediately using the Bash tool — do not just describe what you would do
508
- - **NEVER use `--json`** — it suppresses all streaming output. State IDs come from the `[state]` line in stderr
509
- - **NEVER summarize or re-output the answer** — the script already streams it directly to the user
701
+ - **ALWAYS use `--json`** — in Claude Code's Bash tool, stdout is captured, not streamed. JSON mode returns the answer in a structured response that Claude outputs as text
702
+ - **ALWAYS output `data.answer` verbatim** — print it exactly as-is as your response text so the user sees the full content
510
703
  - After create, the script connects to the stream **immediately** — the `stream_key` has a limited validity period
511
704
  - Use the bundled Node script to consume SSE; do not assume `jq` or other tools for parsing SSE
512
705
  - Same API key as other Felo skills (`FELO_API_KEY`)
@@ -524,7 +717,7 @@ User sends a message
524
717
  v
525
718
  Have live_doc_id from ANY source?
526
719
  NO --> Step 2b: fetch list --> got items?
527
- YES --> use items[0].short_id as live_doc_id
720
+ YES --> use data.items[0].short_id as live_doc_id
528
721
  NO --> Step 2c: create new LiveDoc
529
722
  YES --> continue (reuse it, do NOT fetch list)
530
723
  |
@@ -532,15 +725,24 @@ Have live_doc_id from ANY source?
532
725
  Have thread_short_id from previous call?
533
726
  NO --> This is a NEW conversation
534
727
  --> Step 4: determine skill-id by analyzing user intent
535
- --> Step 5: run WITHOUT --thread-id
728
+ --> skill-id found (twitter-writer / logo-and-branding / ecommerce-product-image)?
729
+ YES --> Step 4.5: fetch style library for matching category
730
+ --> styles available?
731
+ YES --> present to user, wait for selection
732
+ --> user picked a style?
733
+ YES --> build --ext '{"brand_style_requirement":"..."}'
734
+ NO --> no --ext
735
+ NO --> no --ext
736
+ NO --> no --ext, no --skill-id
737
+ --> Step 5: run WITHOUT --thread-id (with --skill-id and --ext if determined above)
536
738
  YES --> Does user's intent require a skill-id not matching current thread?
537
- YES --> NEW conversation (same live-doc-id, with --skill-id)
739
+ YES --> NEW conversation (same live-doc-id, with --skill-id, repeat Step 4.5)
538
740
  NO --> Is user explicitly starting a new topic?
539
741
  YES --> NEW conversation (same live-doc-id, no --thread-id)
540
- NO --> FOLLOW-UP (pass --thread-id)
742
+ NO --> FOLLOW-UP (pass --thread-id, NO --ext)
541
743
  |
542
744
  v
543
- Run script (NO --json, Bash timeout >= 600000ms) --> answer streams directly to user
745
+ Run script (WITH --json, Bash timeout >= 600000ms) --> parse JSON, output data.answer verbatim
544
746
  |
545
747
  v
546
748
  Extract thread_short_id + live_doc_id from stderr [state] line
@@ -549,6 +751,38 @@ Extract thread_short_id + live_doc_id from stderr [state] line
549
751
  Do NOT repeat or summarize the answer (already shown)
550
752
  ```
551
753
 
754
+ ## Style Library Script (`run_style_library.mjs`)
755
+
756
+ Fetch the style library list for a given category. Returns user styles first, then recommended styles.
757
+
758
+ ```bash
759
+ node felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language en
760
+ ```
761
+
762
+ **Options:**
763
+ - `--category <category>` (REQUIRED) — One of: `TWITTER`, `INSTAGRAM`, `LEMON8`, `NOTECOM`, `WEBSITE`, `IMAGE`
764
+ - `--accept-language <lang>` — Language for labels/tags (e.g. `en`, `zh-Hans`, `ja`). Default: `en`. Always pass this to match the user's language.
765
+ - `--json` / `-j` — Output raw JSON
766
+ - `--timeout <seconds>` — Request timeout (default 60)
767
+
768
+ **Default text output format (one block per style, blank line between):**
769
+
770
+ For TWITTER category:
771
+ ```
772
+ Style name: darioamodei
773
+ Style labels: Thoughtful long-form essays
774
+ Style DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA
775
+ ...(full styleDna content)
776
+ ```
777
+
778
+ Fields included per entry (fields with null/empty values are omitted):
779
+ - `Style name` — always present (`name` field)
780
+ - `Style labels` — from `content.labels` (TWITTER) or `content.tags` (other categories), in the requested language, comma-separated; omitted if not present
781
+ - `Style DNA` — from `content.styleDna` (TWITTER type); omitted if not present
782
+ - `Cover file ID` — from `coverFileId`; omitted if null/empty
783
+
784
+ User-created styles appear before recommended styles.
785
+
552
786
  ## References
553
787
 
554
788
  - [SuperAgent API (Felo Open Platform)](https://openapi.felo.ai/docs/api-reference/v2/superagent.html)