felo-ai 0.2.47 → 0.2.49

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.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: felo-superAgent
3
- description: "Felo SuperAgent API: AI conversation with real-time SSE streaming on a persistent LiveDoc canvas. Use when users want SuperAgent chat, continuous conversation, tweet writing, logo/branding design, or e-commerce product images. Explicit commands: /felo-superagent."
3
+ description: "Felo SuperAgent API: AI conversation with real-time SSE streaming on a persistent LiveDoc canvas. Use when users want SuperAgent chat, continuous conversation, logo/branding design, or e-commerce product images. Do NOT use for tweet/X post writing — use felo-twitter-writer instead. Explicit commands: /felo-superagent."
4
4
  ---
5
5
 
6
6
  # Felo SuperAgent Skill
@@ -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
 
@@ -46,7 +57,6 @@ Trigger this skill when users want:
46
57
 
47
58
  - **SuperAgent conversation:** AI conversation with Felo SuperAgent, with real-time streaming output
48
59
  - **Continuous conversation:** Multi-turn Q&A on a persistent LiveDoc canvas
49
- - **Tweet writing:** Compose or post tweets (auto-selects `twitter-writer` skill)
50
60
  - **Logo & branding:** Create logos or brand designs (auto-selects `logo-and-branding` skill)
51
61
  - **E-commerce images:** Generate product images (auto-selects `ecommerce-product-image` skill)
52
62
  - **Tool-augmented answers:** Responses that may include image generation, document creation, PPT generation, or Twitter/X search
@@ -54,15 +64,16 @@ Trigger this skill when users want:
54
64
 
55
65
  **Trigger words:**
56
66
 
57
- - English: superagent, super agent, stream chat, streaming conversation, livedoc conversation, continuous chat, follow-up question, write a tweet, post a tweet, create a logo, brand design, product image, e-commerce image
58
- - Simplified Chinese (pinyin): chao ji zhu shou, liu shi dui hua, lian xu dui hua, zhui wen, fa tui wen, xie tui wen, she ji logo, pin pai she ji, dian shang tu pian
59
- - Traditional Chinese (pinyin): chao ji zhu shou, liu shi dui hua, lian xu dui hua, zhui wen, fa tui wen, xie tui wen, she ji logo, pin pai she ji, dian shang tu pian
60
- - Japanese (romaji): suupaa eejento, sutoriimingu kaiwa, keizoku kaiwa, tsuiito wo kaku, rogo sakusei, shouhin gazou
67
+ - English: superagent, super agent, stream chat, streaming conversation, livedoc conversation, continuous chat, follow-up question, create a logo, brand design, product image, e-commerce image
68
+ - Simplified Chinese (pinyin): chao ji zhu shou, liu shi dui hua, lian xu dui hua, zhui wen, she ji logo, pin pai she ji, dian shang tu pian
69
+ - Traditional Chinese (pinyin): chao ji zhu shou, liu shi dui hua, lian xu dui hua, zhui wen, she ji logo, pin pai she ji, dian shang tu pian
70
+ - Japanese (romaji): suupaa eejento, sutoriimingu kaiwa, keizoku kaiwa, rogo sakusei, shouhin gazou
61
71
 
62
72
  **Explicit commands:** `/felo-superagent`, "use felo superagent", "felo superagent"
63
73
 
64
74
  **Do NOT use for:**
65
75
 
76
+ - Tweet/X post writing of any kind (use `felo-twitter-writer` instead)
66
77
  - Simple one-off Q&A or real-time information queries (prefer `felo-search`)
67
78
  - Web page content fetching only (use `felo-web-fetch`)
68
79
  - PPT/slide generation only (use `felo-slides`)
@@ -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/`.
@@ -132,7 +147,7 @@ Skip to Step 3. Reuse the same ID. Sources include: a previous SuperAgent call's
132
147
  node felo-livedoc/scripts/run_livedoc.mjs list --json
133
148
  ```
134
149
 
135
- Parse the JSON output. The response contains `data.items` — an array of LiveDoc objects sorted by modification time. Pick the first item's `short_id` as your `live_doc_id`.
150
+ Parse the JSON output. The response contains `data.items` — an array of LiveDoc objects sorted by modification time descending. Find the **first item where `is_shared === false`** and use its `short_id` as your `live_doc_id`. **NEVER pick an item where `is_shared === true`** — shared LiveDocs belong to other projects and will cause a 502 error.
136
151
 
137
152
  Example response:
138
153
  ```json
@@ -141,16 +156,17 @@ Example response:
141
156
  "data": {
142
157
  "total": 3,
143
158
  "items": [
144
- { "short_id": "QPetunwpGnkKuZHStP7gwt", "name": "My Workspace", "modified_at": "..." },
159
+ { "short_id": "abc123", "name": "Shared Project", "is_shared": true, "modified_at": "..." },
160
+ { "short_id": "QPetunwpGnkKuZHStP7gwt", "name": "My Workspace", "is_shared": false, "modified_at": "..." },
145
161
  ...
146
162
  ]
147
163
  }
148
164
  }
149
165
  ```
150
166
 
151
- Use: `live_doc_id = items[0].short_id`
167
+ Use: `live_doc_id = data.items.find(i => !i.is_shared)?.short_id`
152
168
 
153
- **2c. If the list is empty (no LiveDocs exist) — create one:**
169
+ **2c. If no `is_shared === false` item exists (or list is empty) — create one:**
154
170
 
155
171
  ```bash
156
172
  node felo-livedoc/scripts/run_livedoc.mjs create --name "SuperAgent Workspace" --json
@@ -204,9 +220,93 @@ If this is a new conversation (no `--thread-id`), analyze the user's intent:
204
220
 
205
221
  If this is a follow-up (`--thread-id` is set), skip this step entirely. `--skill-id` is ignored in follow-up mode.
206
222
 
223
+ ### Step 4.5: Fetch and Select Brand Style (New Skill Conversations Only)
224
+
225
+ **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.
226
+
227
+ **Category mapping:**
228
+ | Skill ID | Style category |
229
+ |---|---|
230
+ | `twitter-writer` | `TWITTER` |
231
+ | `logo-and-branding` | `IMAGE` |
232
+ | `ecommerce-product-image` | `IMAGE` |
233
+
234
+ **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.
235
+
236
+ **4.5b. Fetch the style list:**
237
+
238
+ Use the category that matches the skill:
239
+
240
+ | Skill ID | `--category` |
241
+ |---|---|
242
+ | `twitter-writer` | `TWITTER` |
243
+ | `logo-and-branding` | `IMAGE` |
244
+ | `ecommerce-product-image` | `IMAGE` |
245
+
246
+ Pass `--accept-language` matching the user's language (same value used for SuperAgent).
247
+
248
+ ```bash
249
+ # For twitter-writer
250
+ node felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language en
251
+
252
+ # For logo-and-branding or ecommerce-product-image
253
+ node felo-superAgent/scripts/run_style_library.mjs --category IMAGE --accept-language en
254
+ ```
255
+
256
+ The output lists styles in this format, one block per style separated by a blank line:
257
+
258
+ ```
259
+ Style name: darioamodei
260
+ Style labels: Thoughtful long-form essays
261
+ Style DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA
262
+ ...(full content)
263
+
264
+ Style name: Casual & Witty
265
+ Style labels: humor, relatable
266
+ Style DNA: ...(full content)
267
+ Cover file ID: file_abc123
268
+ ```
269
+
270
+ Notes:
271
+ - `Style labels` is omitted if no labels exist for this entry.
272
+ - `Style DNA` is the full text of `content.styleDna` (TWITTER type). Do NOT truncate it.
273
+ - `Cover file ID` is omitted if the value is null/empty.
274
+
275
+ User-created styles appear first, followed by recommended styles.
276
+
277
+ **4.5c. Present the styles to the user and ask them to choose:**
278
+
279
+ Show the list (style names only is sufficient) and ask which one to use. Wait for the user's selection before proceeding.
280
+
281
+ Example prompt to user:
282
+ > Here are the available Twitter writing styles. Which one would you like to use?
283
+ > 1. Casual & Witty (your style)
284
+ > 2. Professional Thought Leader (recommended)
285
+ > 3. No style preference — use default
286
+
287
+ If the user picks "no preference" or the list is empty, proceed to Step 5 without `--ext`.
288
+
289
+ **4.5d. Build the `--ext` value:**
290
+
291
+ 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:
292
+
293
+ Example style block output:
294
+ ```
295
+ Style name: darioamodei
296
+ Style labels: Thoughtful long-form essays
297
+ Style DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA\n\n## 风格速写\nDario writes like a serious intellectual...
298
+ ```
299
+
300
+ Serialized as `--ext`:
301
+ ```bash
302
+ --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..."}'
303
+ ```
304
+
305
+ **Important:** Pass the `brand_style_requirement` value completely and verbatim — do NOT truncate `Style DNA`. Partial style content will degrade output quality.
306
+
207
307
  ### Step 5: Run the Script
208
308
 
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.
309
+ 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
310
 
211
311
  **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
312
 
@@ -225,21 +325,34 @@ Examples:
225
325
  - User says "再来一张" → `--query "请再生成一张类似风格的无线耳机产品图,白色背景"`
226
326
  - User says "帮我改改" → `--query "请修改上面生成的推文,语气更轻松一些,加一些emoji"`
227
327
 
228
- **New conversation (first question):**
328
+ **New conversation (first question, no skill):**
229
329
  ```bash
230
330
  node felo-superAgent/scripts/run_superagent.mjs \
231
331
  --query "USER_QUERY_HERE" \
232
332
  --live-doc-id "LIVE_DOC_ID" \
233
- --accept-language en
333
+ --accept-language en \
334
+ --json
335
+ ```
336
+
337
+ **New conversation with skill ID, no style selected:**
338
+ ```bash
339
+ node felo-superAgent/scripts/run_superagent.mjs \
340
+ --query "Write a tweet about the latest AI trends" \
341
+ --live-doc-id "LIVE_DOC_ID" \
342
+ --skill-id twitter-writer \
343
+ --accept-language en \
344
+ --json
234
345
  ```
235
346
 
236
- **New conversation with skill ID (e.g., tweet writing):**
347
+ **New conversation with skill ID and brand style (from Step 4.5):**
237
348
  ```bash
238
349
  node felo-superAgent/scripts/run_superagent.mjs \
239
350
  --query "Write a tweet about the latest AI trends" \
240
351
  --live-doc-id "LIVE_DOC_ID" \
241
352
  --skill-id twitter-writer \
242
- --accept-language en
353
+ --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)"}' \
354
+ --accept-language en \
355
+ --json
243
356
  ```
244
357
 
245
358
  **Follow-up question (DEFAULT for 2nd+ messages):**
@@ -247,23 +360,31 @@ node felo-superAgent/scripts/run_superagent.mjs \
247
360
  node felo-superAgent/scripts/run_superagent.mjs \
248
361
  --query "USER_FOLLOW_UP_QUERY" \
249
362
  --thread-id "THREAD_SHORT_ID_FROM_PREVIOUS" \
250
- --live-doc-id "LIVE_DOC_ID"
363
+ --live-doc-id "LIVE_DOC_ID" \
364
+ --json
251
365
  ```
252
366
 
253
- ### Step 6: Extract State from stderr (Do NOT Re-output the Answer)
367
+ ### Step 6: Extract State and Output the Answer
254
368
 
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.**
369
+ After the script finishes, parse the JSON output:
256
370
 
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
371
+ ```json
372
+ {
373
+ "status": "ok",
374
+ "data": {
375
+ "answer": "...",
376
+ "thread_short_id": "CmYpuGwBgCnrUdDx5ZtmxA",
377
+ "live_doc_short_id": "QPetunwpGnkKuZHStP7gwt",
378
+ "live_doc_url": "https://felo.ai/livedoc/QPetunwpGnkKuZHStP7gwt"
379
+ }
380
+ }
261
381
  ```
262
382
 
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.
383
+ 1. **Output `data.answer` verbatim** as your response text print it exactly as-is so the user sees the full content.
384
+ 2. **Extract and save** `data.thread_short_id` and `data.live_doc_short_id` you MUST use these in the next call.
385
+ 3. **Optionally show** `data.live_doc_url` so the user can view the LiveDoc canvas in a browser.
265
386
 
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.
387
+ Do NOT show `thread_short_id` or `live_doc_short_id` to the user unless they ask for it.
267
388
 
268
389
  ## Complete Workflow Examples
269
390
 
@@ -281,9 +402,10 @@ User: "What is quantum computing?"
281
402
  node felo-superAgent/scripts/run_superagent.mjs \
282
403
  --query "What is quantum computing?" \
283
404
  --live-doc-id "QPetunwpGnkKuZHStP7gwt" \
284
- --accept-language en
405
+ --accept-language en \
406
+ --json
285
407
  ```
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.
408
+ **Step 6:** Parse JSON output. Output `data.answer` verbatim as your response. Save `thread_short_id = "CmYpuGwBgCnrUdDx5ZtmxA"`, `live_doc_id = "QPetunwpGnkKuZHStP7gwt"` from `data`.
287
409
 
288
410
  ```
289
411
  User: "What are its practical applications?"
@@ -296,9 +418,10 @@ User: "What are its practical applications?"
296
418
  node felo-superAgent/scripts/run_superagent.mjs \
297
419
  --query "What are its practical applications?" \
298
420
  --thread-id "CmYpuGwBgCnrUdDx5ZtmxA" \
299
- --live-doc-id "QPetunwpGnkKuZHStP7gwt"
421
+ --live-doc-id "QPetunwpGnkKuZHStP7gwt" \
422
+ --json
300
423
  ```
301
- **Step 6:** Answer already streamed. Extract updated `thread_short_id` from stderr `[state]` line (may be the same), keep `live_doc_id`.
424
+ **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
425
 
303
426
  ```
304
427
  User: "Tell me more about quantum error correction"
@@ -307,68 +430,113 @@ User: "Tell me more about quantum error correction"
307
430
  **Step 3:** Still follow-up (same topic) → use saved `thread_short_id`
308
431
  **Step 5:** Same pattern as above with new query
309
432
 
310
- ### Example B: Tweet Writing
433
+ ### Example B: Tweet Writing with Style Selection
311
434
 
312
435
  ```
313
436
  User: "Help me write a tweet about AI trends"
314
437
  ```
315
438
 
316
439
  **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
440
+ **Step 3:** New conversation
318
441
  **Step 4:** User intent matches "write a tweet" → `--skill-id twitter-writer`
442
+ **Step 4.5:** Fetch TWITTER styles (pass `--accept-language` matching user's language):
443
+ ```bash
444
+ node felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language en
445
+ ```
446
+ Output:
447
+ ```
448
+ Style name: My Bold Voice
449
+ Style labels: bold, provocative
450
+ Style DNA: # My Bold Voice Style DNA
451
+ ...(full content)
452
+
453
+ Style name: darioamodei
454
+ Style labels: Thoughtful long-form essays
455
+ Style DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA
456
+ ...(full content)
457
+ ```
458
+ Present to user: "Which writing style would you like? 1. My Bold Voice (yours) 2. darioamodei (recommended) 3. No preference"
459
+
460
+ User selects: "1. My Bold Voice"
461
+
319
462
  **Step 5:**
320
463
  ```bash
321
464
  node felo-superAgent/scripts/run_superagent.mjs \
322
465
  --query "Help me write a tweet about AI trends" \
323
466
  --live-doc-id "QPetunwpGnkKuZHStP7gwt" \
324
467
  --skill-id twitter-writer \
325
- --accept-language en
468
+ --ext '{"brand_style_requirement":"Style name: My Bold Voice\nStyle labels: bold, provocative\nStyle DNA: # My Bold Voice Style DNA\n...(full content)"}' \
469
+ --accept-language en \
470
+ --json
326
471
  ```
327
- **Step 6:** Answer already streamed. Extract new `thread_short_id` from stderr `[state]` line, keep same `live_doc_id`.
472
+ **Step 6:** Parse JSON output. Output `data.answer` verbatim. Save new `thread_short_id` from `data`, keep same `live_doc_id`.
328
473
 
329
474
  ```
330
475
  User: "Make it more casual and add some emojis"
331
476
  ```
332
477
 
333
- **Step 3:** Follow-up → use saved `thread_short_id`
478
+ **Step 3:** Follow-up → use saved `thread_short_id` (do NOT pass `--ext` again)
334
479
  **Step 5:**
335
480
  ```bash
336
481
  node felo-superAgent/scripts/run_superagent.mjs \
337
482
  --query "Make it more casual and add some emojis" \
338
483
  --thread-id "NEW_THREAD_FROM_TWEET" \
339
- --live-doc-id "QPetunwpGnkKuZHStP7gwt"
484
+ --live-doc-id "QPetunwpGnkKuZHStP7gwt" \
485
+ --json
340
486
  ```
341
487
 
342
- ### Example C: Logo Design
488
+ ### Example C: Logo Design with Style Selection
343
489
 
344
490
  ```
345
491
  User: "Design a logo for my coffee shop called Bean & Brew"
346
492
  ```
347
493
 
348
494
  **Step 4:** Detected "design a logo" → `--skill-id logo-and-branding`
495
+ **Step 4.5:** Fetch IMAGE styles:
496
+ ```bash
497
+ node felo-superAgent/scripts/run_style_library.mjs --category IMAGE --accept-language en
498
+ ```
499
+ Output example:
500
+ ```
501
+ Style name: Minimalist Modern
502
+ Style labels: clean, monochrome
503
+ Style DNA: ...(full content)
504
+ Cover file ID: file_333
505
+ ```
506
+ Present styles to user and wait for selection. Suppose user picks "Minimalist Modern":
507
+
349
508
  **Step 5:**
350
509
  ```bash
351
510
  node felo-superAgent/scripts/run_superagent.mjs \
352
511
  --query "Design a logo for my coffee shop called Bean & Brew" \
353
512
  --live-doc-id "QPetunwpGnkKuZHStP7gwt" \
354
513
  --skill-id logo-and-branding \
355
- --accept-language en
514
+ --ext '{"brand_style_requirement":"Style name: Minimalist Modern\nStyle labels: clean, monochrome\nStyle DNA: ...(full content)\nCover file ID: file_333"}' \
515
+ --accept-language en \
516
+ --json
356
517
  ```
357
518
 
358
- ### Example D: E-commerce Product Image
519
+ ### Example D: E-commerce Product Image with Style Selection
359
520
 
360
521
  ```
361
522
  User: "Generate a product image for a wireless headphone on white background"
362
523
  ```
363
524
 
364
525
  **Step 4:** Detected "product image" → `--skill-id ecommerce-product-image`
365
- **Step 5:**
526
+ **Step 4.5:** Fetch IMAGE styles:
527
+ ```bash
528
+ node felo-superAgent/scripts/run_style_library.mjs --category IMAGE --accept-language en
529
+ ```
530
+ Present styles to user. Suppose user picks "No preference":
531
+
532
+ **Step 5:** (no `--ext` since user chose no preference)
366
533
  ```bash
367
534
  node felo-superAgent/scripts/run_superagent.mjs \
368
535
  --query "Generate a product image for a wireless headphone on white background" \
369
536
  --live-doc-id "QPetunwpGnkKuZHStP7gwt" \
370
537
  --skill-id ecommerce-product-image \
371
- --accept-language en
538
+ --accept-language en \
539
+ --json
372
540
  ```
373
541
 
374
542
  ### Example E: User Requests a New Canvas
@@ -383,6 +551,30 @@ node felo-livedoc/scripts/run_livedoc.mjs create --name "New Project" --json
383
551
  ```
384
552
  Extract new `live_doc_id`. Discard the old one. All subsequent calls use the new ID.
385
553
 
554
+ ### Example F: User Specifies Style Directly
555
+
556
+ ```
557
+ User: "Write a tweet about AI trends using the 'darioamodei' style"
558
+ ```
559
+
560
+ **Step 4:** `--skill-id twitter-writer`
561
+ **Step 4.5a:** User already named the style → fetch the list to get the full block:
562
+ ```bash
563
+ node felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language en
564
+ ```
565
+ Find the entry with `Style name: darioamodei`, extract its full block verbatim. No need to ask the user again.
566
+
567
+ **Step 5:**
568
+ ```bash
569
+ node felo-superAgent/scripts/run_superagent.mjs \
570
+ --query "Write a tweet about AI trends" \
571
+ --live-doc-id "QPetunwpGnkKuZHStP7gwt" \
572
+ --skill-id twitter-writer \
573
+ --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)"}' \
574
+ --accept-language en \
575
+ --json
576
+ ```
577
+
386
578
  ## Available Script Options
387
579
 
388
580
  **Core parameters:**
@@ -391,12 +583,14 @@ Extract new `live_doc_id`. Discard the old one. All subsequent calls use the new
391
583
  - `--thread-id <id>` — Thread ID from previous response, for follow-up conversations
392
584
 
393
585
  **Skill parameters (new conversations only, ignored in follow-up):**
394
- - `--skill-id <id>` — Skill ID (see Constraint #8 for available skill IDs)
586
+ - `--skill-id <id>` — Skill ID (see Constraint #9 for available skill IDs)
395
587
  - `--selected-resource-ids <ids>` — Comma-separated resource IDs to include
396
- - `--ext <json>` — Extra parameters as JSON object
588
+ - `--ext <json>` — Extra parameters as JSON object. For skill-based conversations, pass brand style as:
589
+ `--ext '{"brand_style_requirement":"Style name: <name>\nStyle labels: <labels>\nStyle DNA: <full styleDna text>\nCover file ID: <id>"}'`
590
+ Fields present depend on category type. `Cover file ID` is omitted when null. Do NOT truncate `Style DNA`.
397
591
 
398
592
  **Output control:**
399
- - `--json` / `-j` — Output JSON format with full metadata (DO NOT use in this skillit suppresses streaming output)
593
+ - `--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
594
  - `--verbose` / `-v` — Log stream connection details to stderr (for debugging only, not needed for normal use)
401
595
  - `--accept-language <lang>` — Language preference (e.g., en, ja, ko)
402
596
 
@@ -505,8 +699,8 @@ To use this skill, you need to set up your Felo API Key:
505
699
  ## Important Notes
506
700
 
507
701
  - 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
702
+ - **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
703
+ - **ALWAYS output `data.answer` verbatim** — print it exactly as-is as your response text so the user sees the full content
510
704
  - After create, the script connects to the stream **immediately** — the `stream_key` has a limited validity period
511
705
  - Use the bundled Node script to consume SSE; do not assume `jq` or other tools for parsing SSE
512
706
  - Same API key as other Felo skills (`FELO_API_KEY`)
@@ -524,7 +718,7 @@ User sends a message
524
718
  v
525
719
  Have live_doc_id from ANY source?
526
720
  NO --> Step 2b: fetch list --> got items?
527
- YES --> use items[0].short_id as live_doc_id
721
+ YES --> use data.items[0].short_id as live_doc_id
528
722
  NO --> Step 2c: create new LiveDoc
529
723
  YES --> continue (reuse it, do NOT fetch list)
530
724
  |
@@ -532,15 +726,24 @@ Have live_doc_id from ANY source?
532
726
  Have thread_short_id from previous call?
533
727
  NO --> This is a NEW conversation
534
728
  --> Step 4: determine skill-id by analyzing user intent
535
- --> Step 5: run WITHOUT --thread-id
729
+ --> skill-id found (twitter-writer / logo-and-branding / ecommerce-product-image)?
730
+ YES --> Step 4.5: fetch style library for matching category
731
+ --> styles available?
732
+ YES --> present to user, wait for selection
733
+ --> user picked a style?
734
+ YES --> build --ext '{"brand_style_requirement":"..."}'
735
+ NO --> no --ext
736
+ NO --> no --ext
737
+ NO --> no --ext, no --skill-id
738
+ --> Step 5: run WITHOUT --thread-id (with --skill-id and --ext if determined above)
536
739
  YES --> Does user's intent require a skill-id not matching current thread?
537
- YES --> NEW conversation (same live-doc-id, with --skill-id)
740
+ YES --> NEW conversation (same live-doc-id, with --skill-id, repeat Step 4.5)
538
741
  NO --> Is user explicitly starting a new topic?
539
742
  YES --> NEW conversation (same live-doc-id, no --thread-id)
540
- NO --> FOLLOW-UP (pass --thread-id)
743
+ NO --> FOLLOW-UP (pass --thread-id, NO --ext)
541
744
  |
542
745
  v
543
- Run script (NO --json, Bash timeout >= 600000ms) --> answer streams directly to user
746
+ Run script (WITH --json, Bash timeout >= 600000ms) --> parse JSON, output data.answer verbatim
544
747
  |
545
748
  v
546
749
  Extract thread_short_id + live_doc_id from stderr [state] line
@@ -549,6 +752,38 @@ Extract thread_short_id + live_doc_id from stderr [state] line
549
752
  Do NOT repeat or summarize the answer (already shown)
550
753
  ```
551
754
 
755
+ ## Style Library Script (`run_style_library.mjs`)
756
+
757
+ Fetch the style library list for a given category. Returns user styles first, then recommended styles.
758
+
759
+ ```bash
760
+ node felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language en
761
+ ```
762
+
763
+ **Options:**
764
+ - `--category <category>` (REQUIRED) — One of: `TWITTER`, `INSTAGRAM`, `LEMON8`, `NOTECOM`, `WEBSITE`, `IMAGE`
765
+ - `--accept-language <lang>` — Language for labels/tags (e.g. `en`, `zh-Hans`, `ja`). Default: `en`. Always pass this to match the user's language.
766
+ - `--json` / `-j` — Output raw JSON
767
+ - `--timeout <seconds>` — Request timeout (default 60)
768
+
769
+ **Default text output format (one block per style, blank line between):**
770
+
771
+ For TWITTER category:
772
+ ```
773
+ Style name: darioamodei
774
+ Style labels: Thoughtful long-form essays
775
+ Style DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA
776
+ ...(full styleDna content)
777
+ ```
778
+
779
+ Fields included per entry (fields with null/empty values are omitted):
780
+ - `Style name` — always present (`name` field)
781
+ - `Style labels` — from `content.labels` (TWITTER) or `content.tags` (other categories), in the requested language, comma-separated; omitted if not present
782
+ - `Style DNA` — from `content.styleDna` (TWITTER type); omitted if not present
783
+ - `Cover file ID` — from `coverFileId`; omitted if null/empty
784
+
785
+ User-created styles appear before recommended styles.
786
+
552
787
  ## References
553
788
 
554
789
  - [SuperAgent API (Felo Open Platform)](https://openapi.felo.ai/docs/api-reference/v2/superagent.html)