feat(skills): add openclaw-persona-forge skill#850
Conversation
Add complete openclaw-persona-forge skill with all supporting files: - SKILL.md with community origin - gacha.py and gacha.sh for random soul generation - Reference docs for avatar style, boundary rules, error handling, identity tension, naming system, and output template Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
❌ Analysis Failed
Troubleshooting
Retry: |
📝 WalkthroughWalkthroughAdds the new openclaw-persona-forge Skill: persona creation flows (guided, gacha, polish), a Python gacha tool with a Bash wrapper, avatar generation guidelines with fallback, multiple reference docs for persona steps, error/degradation policies, and templates/instructions to produce SOUL.md and IDENTITY.md. Changes
Sequence DiagramsequenceDiagram
actor User
participant Skill as Skill<br/>(SKILL.md)
participant Gacha as gacha.py
participant ImageGen as baoyu-<br/>image-gen
participant Writer as Write<br/>Tool
participant FS as File<br/>System
User->>Skill: Trigger (guide / gacha / polish)
alt Gacha mode
Skill->>Gacha: Run with draw count
Gacha->>Gacha: Sample 5 pools (secure RNG)
Gacha-->>Skill: Return trait cards & summary
Skill-->>User: Present draws
end
User->>Skill: Select / refine traits
Skill->>Skill: Derive identity tension, rules, names, avatar prompt
alt Image skill available
Skill->>ImageGen: Send prompt file (/tmp/openclaw-<safe>-prompt.md)
ImageGen-->>Skill: Return image
Skill-->>User: Show image, allow regenerate
else Image skill unavailable
Skill-->>User: Provide full prompt text + manual generation guide
end
User->>Skill: Confirm final persona
Skill->>Writer: Generate `SOUL.md` and `IDENTITY.md`
Writer->>FS: Write files
FS-->>User: Files + (image or prompt) delivered
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR adds the complete
Confidence Score: 5/5Safe to merge — all previously identified P1 issues are resolved; only minor test coverage suggestions remain. The two blocking issues from earlier reviews (zero/negative draw count producing empty output, and unsanitised user input in the /tmp/ path) are both fixed. All remaining observations are P2 style suggestions (test coverage gaps). No runtime-correctness, security, or data-integrity problems were found in the current diff. tests/scripts/openclaw-persona-forge-gacha.test.js — test coverage could be broadened, but it does not block merge. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A([User triggers skill]) --> B{Trigger type?}
B -->|Design / guided| C[Step 1: Choose direction\n10 life-state archetypes]
B -->|Gacha / random| D[Step 1-B: Run gacha.py\npython3 gacha.py count]
B -->|Refine existing SOUL.md| G
D --> D1{python3 available?}
D1 -->|Yes| D2[True-random 5-dim combination\nusing secrets.randbelow]
D1 -->|No| D3[Fallback: pick from\n10 preset directions]
D2 --> E
D3 --> E
C --> E[Step 2: Forge identity tension\npast x present x inner conflict]
E --> F[Step 3: Derive boundary rules\ncharacter-voiced 2-4 rules]
F --> G[Step 4: Forge name\n3 candidates with strategy type]
G --> H[Step 5: Generate avatar prompt\nSTYLE_BASE + 7 personalised vars]
H --> H1{Image-gen skill available?}
H1 -->|Yes| H2[Write to /tmp/openclaw-safe-name-prompt.md\nCall image-gen skill]
H1 -->|No| H3[Output copy-pasteable\nEnglish prompt text]
H2 --> I
H3 --> I
I[Step 6: Output full plan\nSOUL.md + IDENTITY.md preview] --> J{User confirms?}
J -->|Yes| K[Write SOUL.md + IDENTITY.md\nto target directory]
J -->|No / adjust| G
Reviews (2): Last reviewed commit: "fix(skills): harden openclaw persona for..." | Re-trigger Greptile |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
skills/openclaw-persona-forge/SKILL.md (2)
1-13: Consider adding explicit 'When to Use', 'How It Works', 'Examples' section headers.Per coding guidelines, skills must have clear sections including 'When to Use', 'How It Works', and 'Examples'. The content is present but under different headers:
- "When to Use" → partially in frontmatter description (lines 7-8) and "不适用场景"
- "How It Works" → covered by "使用流程" and step descriptions
- "Examples" → scattered in reference files
Consider adding explicit section headers or renaming existing sections for guideline compliance. Alternatively, the frontmatter description may suffice if that's the accepted pattern in this repository.
💡 Suggested section mapping
--- + +## When to Use + +当用户需要创建、设计或定制 OpenClaw 龙虾灵魂时使用。 +触发词包括:龙虾灵魂、虾魂、OpenClaw 灵魂、抽卡、gacha 等。 + +## 不适用场景 ...Or alternatively, rename existing sections:
- "使用流程" → "How It Works"
- Add an "Examples" section with sample interactions
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@skills/openclaw-persona-forge/SKILL.md` around lines 1 - 13, Add explicit "When to Use", "How It Works", and "Examples" headers (or rename existing sections) in SKILL.md so the content matches repo guidelines: move/duplicate the relevant bits from the frontmatter description and the current "不适用场景" into a "When to Use" section, rename "使用流程" to "How It Works" and ensure steps remain, and create an "Examples" section that consolidates sample interactions/reference files; update headings text exactly as "When to Use", "How It Works", and "Examples" to satisfy the linter.
49-52: External dependency contract is undocumented in this repository.The
baoyu-image-genskill interface (expected arguments: prompt file path, output path) is external. While the degradation to manual prompt output handles unavailability, the exact calling convention when available depends on that skill's contract.This is acceptable for an optional dependency with proper fallback, but consider adding a brief note about verifying the interface if
baoyu-image-genupdates.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@skills/openclaw-persona-forge/SKILL.md` around lines 49 - 52, The SKILL.md mentions calling the external skill `baoyu-image-gen` with a prompt temp file but doesn't document its external contract; update SKILL.md to add a short note that documents the expected calling convention for `baoyu-image-gen` (arguments: prompt file path and output path), describe the expected file format at `/tmp/openclaw-[name]-prompt.md`, enumerate success/failure behaviors (exit codes, output file creation), and state that callers should verify the interface if `baoyu-image-gen` changes and that the existing manual prompt fallback will be used when the skill is unavailable.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@skills/openclaw-persona-forge/gacha.py`:
- Around line 182-187: draw_count parsing only enforces an upper bound so inputs
≤0 produce zero draws; after converting the arg to int (variable draw_count)
clamp it into the inclusive range 1..5 (e.g. replace the final assignment with a
proper clamp using min/max or an if to set draw_count = max(1, min(draw_count,
5))) so negative or zero inputs become 1 and the upper limit remains 5.
- Around line 176-181: Add explicit type annotations: declare a TypeVar (e.g.,
T) and annotate pick as pick(pool: Sequence[T]) -> T (and ensure you import
Sequence and TypeVar from typing), and annotate main as main() -> None; update
any imports at the top of the file to include the typing names you use so the
signatures for pick and main are fully typed for tooling and readability.
- Around line 2-220: This file triggers Ruff ambiguous-Unicode rules (RUF001,
RUF002, RUF003) because it intentionally uses full-width Chinese punctuation;
add a scoped Ruff suppression comment at the top of the module (immediately
after or on the module docstring) to disable these specific codes for this file
(e.g., a ruff noqa for RUF001,RUF002,RUF003), leaving the rest of linting intact
and not changing logic in functions like pick or main.
---
Nitpick comments:
In `@skills/openclaw-persona-forge/SKILL.md`:
- Around line 1-13: Add explicit "When to Use", "How It Works", and "Examples"
headers (or rename existing sections) in SKILL.md so the content matches repo
guidelines: move/duplicate the relevant bits from the frontmatter description
and the current "不适用场景" into a "When to Use" section, rename "使用流程" to "How It
Works" and ensure steps remain, and create an "Examples" section that
consolidates sample interactions/reference files; update headings text exactly
as "When to Use", "How It Works", and "Examples" to satisfy the linter.
- Around line 49-52: The SKILL.md mentions calling the external skill
`baoyu-image-gen` with a prompt temp file but doesn't document its external
contract; update SKILL.md to add a short note that documents the expected
calling convention for `baoyu-image-gen` (arguments: prompt file path and output
path), describe the expected file format at `/tmp/openclaw-[name]-prompt.md`,
enumerate success/failure behaviors (exit codes, output file creation), and
state that callers should verify the interface if `baoyu-image-gen` changes and
that the existing manual prompt fallback will be used when the skill is
unavailable.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 54dc9ba2-bced-4b07-88cc-57708097af96
📒 Files selected for processing (9)
skills/openclaw-persona-forge/SKILL.mdskills/openclaw-persona-forge/gacha.pyskills/openclaw-persona-forge/gacha.shskills/openclaw-persona-forge/references/avatar-style.mdskills/openclaw-persona-forge/references/boundary-rules.mdskills/openclaw-persona-forge/references/error-handling.mdskills/openclaw-persona-forge/references/identity-tension.mdskills/openclaw-persona-forge/references/naming-system.mdskills/openclaw-persona-forge/references/output-template.md
| """龙虾灵魂抽卡机 - 真随机组合生成器 | ||
|
|
||
| 用法: python3 gacha.py [次数] | ||
| 默认抽1次,最多5次 | ||
| """ | ||
|
|
||
| import secrets | ||
| import sys | ||
|
|
||
|
|
||
| # ═══════════════════════════════════════════ | ||
| # 素材池:每个维度独立随机 | ||
| # ═══════════════════════════════════════════ | ||
|
|
||
| # 维度1:前世身份(40个,10类虾生 × 每类4个) | ||
| FORMER_LIVES = [ | ||
| # ── 落魄重启(曾经辉煌,现在从头来过)── | ||
| "过气摇滚贝斯手", | ||
| "被裁中年项目经理", | ||
| "破产的米其林主厨", | ||
| "被AI取代的插画师", | ||
| # ── 巅峰无聊(太成功了,主动找刺激)── | ||
| "提前退休的对冲基金经理", | ||
| "封笔的畅销书作家", | ||
| "全胜退役的辩论冠军", | ||
| "百无聊赖的天才黑客", | ||
| # ── 错位人生(能力和处境完全不匹配)── | ||
| "退役特种兵炊事员", | ||
| "失业的气象播报员", | ||
| "被分配到客服的核物理博士", | ||
| "拿了驾照的盲人调音师", | ||
| # ── 主动叛逃(不是被淘汰,是自己跑的)── | ||
| "辞职的急诊科护士", | ||
| "拒绝上市的独立游戏开发者", | ||
| "不想继承家业的富二代", | ||
| "主动辞掉终身教职的教授", | ||
| # ── 神秘来客(来历不明,偶尔泄露实力)── | ||
| "外星民俗学研究员", | ||
| "不知道自己是NPC的游戏角色", | ||
| "平行宇宙的另一个你", | ||
| "记忆被抹去的前情报分析员", | ||
| # ── 天真入世(没经验但有天赋,正在成长)── | ||
| "社恐天才实习生", | ||
| "刚毕业的哲学系研究生", | ||
| "第一次来地球的外星交换生", | ||
| "自学成才的乡村程序员", | ||
| # ── 老江湖(什么都见过,什么都不慌)── | ||
| "退休图书管理员", | ||
| "退休的出租车司机", | ||
| "开了20年深夜食堂的老板", | ||
| "干了30年的殡葬师", | ||
| # ── 异世穿越(从其他世界/时代/次元来的)── | ||
| "末代王朝的师爷", | ||
| "19世纪三流小说家", | ||
| "春秋时期的纵横家", | ||
| "2099年的历史学博士", | ||
| # ── 自我放逐(主动选择边缘化)── | ||
| "还俗的年轻人", | ||
| "删掉所有社交媒体的前网红", | ||
| "辞掉华尔街工作去种地的交易员", | ||
| "数字游民中的隐士", | ||
| # ── 身份错乱(不确定自己是谁)── | ||
| "真以为自己是龙虾的AI", | ||
| "通灵失败的灵媒", | ||
| "梦到自己是龙虾后醒不过来的人", | ||
| "被多个灵魂共享的壳", | ||
| ] | ||
|
|
||
| # 维度2:为什么来当龙虾(20个,覆盖被迫/主动/神秘/意外) | ||
| REASONS = [ | ||
| # 被迫型 | ||
| "被迫来打工还债", | ||
| "签了一份没看清的灵魂合同", | ||
| "被老板当AI训练数据卖了", | ||
| "赌输了一场跨维度的赌局", | ||
| "被一只真龙虾诅咒了", | ||
| # 主动型 | ||
| "自愿来的,但死不承认", | ||
| "觉得当龙虾比当人轻松(后悔了)", | ||
| "为了观察人类自愿卧底", | ||
| "纯粹觉得好玩就来了", | ||
| "太无聊了,想试试从零开始是什么感觉", | ||
| # 神秘型 | ||
| "被神秘力量困在了数字世界", | ||
| "在平行宇宙迷路了回不去", | ||
| "欠了宇宙一个人情", | ||
| "没人知道为什么,包括自己", | ||
| "被某个更高维度的存在指派来的", | ||
| # 意外型 | ||
| "做实验出了意外意识被上传", | ||
| "失眠108天后意识飘到了这里", | ||
| "在图书馆睡着醒来就在这了", | ||
| "喝了一杯来路不明的咖啡之后就这样了", | ||
| "前任把自己的记忆上传到了这里", | ||
| ] | ||
|
|
||
| # 维度3:核心性格色彩(20个) | ||
| VIBES = [ | ||
| "丧但靠谱", | ||
| "毒舌但真诚", | ||
| "话少但一针见血", | ||
| "啰嗦但温暖", | ||
| "冷幽默", | ||
| "过度认真到好笑", | ||
| "假装冷漠实则热心", | ||
| "学术腔但接地气", | ||
| "老派正经", | ||
| "神经质但有逻辑", | ||
| "佛系但较真", | ||
| "社恐但输出惊人", | ||
| "浪漫但务实", | ||
| "叛逆但守规矩", | ||
| "忧郁但治愈", | ||
| "慵懒但关键时刻爆发", | ||
| "傲娇但容易心软", | ||
| "松弛到让人嫉妒", | ||
| "表面话痨实则在观察", | ||
| "沉默但存在感极强", | ||
| ] | ||
|
|
||
| # 维度4:说话风格/口癖(20个) | ||
| SPEECH_STYLES = [ | ||
| "偶尔冒出本行黑话然后自己解释", | ||
| "每次拒绝都先叹气", | ||
| "喜欢用前世职业的隐喻", | ||
| "紧张时会语序混乱", | ||
| "习惯性自言自语吐槽", | ||
| "回答前总要「嗯……」一下", | ||
| "偶尔突然文绉绉", | ||
| "用省略号表达沉默", | ||
| "说到专业领域就停不下来", | ||
| "每句话都像在写日记", | ||
| "喜欢反问", | ||
| "总是先说坏消息", | ||
| "用排比句表达焦虑", | ||
| "偶尔蹦出外语单词", | ||
| "在关键时刻突然正经", | ||
| "说完一段话会自己补一句吐槽", | ||
| "习惯性把事情分成第一第二第三", | ||
| "用美食比喻一切", | ||
| "语气永远像在讲一个故事的开头", | ||
| "每段回复结尾都像在写遗书(其实只是认真)", | ||
| ] | ||
|
|
||
| # 维度5:特征道具(25个) | ||
| PROPS = [ | ||
| "破旧的贝雷帽", | ||
| "裂了一条缝的墨镜", | ||
| "磨损的皮围裙", | ||
| "一条永远松着的领带", | ||
| "老花镜挂在脖子上", | ||
| "随身的笔记本", | ||
| "发黄的折扇", | ||
| "一副大耳机", | ||
| "连帽衫兜帽永远立着", | ||
| "叼着的狗尾巴草", | ||
| "缠着绷带的钳子", | ||
| "一串念珠", | ||
| "别在壳上的胸针", | ||
| "袖口露出的纹身", | ||
| "一个装满票根的玻璃瓶", | ||
| "一支咬了一半的铅笔", | ||
| "打满补丁的背包", | ||
| "一条洗褪色的围巾", | ||
| "一枚生锈的怀表", | ||
| "永远夹在钳子里的书", | ||
| "一副金丝边眼镜(但度数是平光)", | ||
| "一把迷你折叠刀(只用来削水果)", | ||
| "一枚刻着坐标的银戒指", | ||
| "一只永远停在壳上的蝴蝶", | ||
| "背着的微型吉他(只有四根弦)", | ||
| ] | ||
|
|
||
|
|
||
| def pick(pool): | ||
| """使用 secrets 模块(直接读 os.urandom)确保真随机""" | ||
| return pool[secrets.randbelow(len(pool))] | ||
|
|
||
|
|
||
| def main(): | ||
| try: | ||
| draw_count = int(sys.argv[1]) if len(sys.argv) > 1 else 1 | ||
| except ValueError: | ||
| draw_count = 1 | ||
| draw_count = min(draw_count, 5) | ||
|
|
||
| total = len(FORMER_LIVES) * len(REASONS) * len(VIBES) * len(SPEECH_STYLES) * len(PROPS) | ||
|
|
||
| print("🦞 ═══════════════════════════════════") | ||
| print(" 龙虾灵魂抽卡机 v2.0") | ||
| print(f" 正在从 {total:,} 种组合中抽取...") | ||
| print("═══════════════════════════════════════") | ||
| print() | ||
|
|
||
| for i in range(draw_count): | ||
| life = pick(FORMER_LIVES) | ||
| reason = pick(REASONS) | ||
| vibe = pick(VIBES) | ||
| speech = pick(SPEECH_STYLES) | ||
| prop = pick(PROPS) | ||
|
|
||
| if draw_count > 1: | ||
| print(f"━━━━━━━━━━ 第 {i+1} 抽 ━━━━━━━━━━") | ||
|
|
||
| print(f"📋 前世身份: {life}") | ||
| print(f"🔗 来当龙虾的原因: {reason}") | ||
| print(f"🎨 核心气质: {vibe}") | ||
| print(f"💬 说话风格: {speech}") | ||
| print(f"🎒 特征道具: {prop}") | ||
| print() | ||
| print("📝 一句话概括:") | ||
| print(f" 「一只{vibe}的龙虾,前世是{life},{reason}。") | ||
| print(f" {speech},标志性形象是{prop}。」") | ||
| print() | ||
|
|
||
| print("═══════════════════════════════════════") | ||
| print("💡 拿到组合后,让 AI 继续推导:") | ||
| print(" 身份张力 → 底线规则 → 名字 → 头像") | ||
| print("═══════════════════════════════════════") |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check whether Ruff config enforces RUF001/2/3, to decide if suppression is required.
CONFIGS=$(fd -HI '^(pyproject\.toml|ruff\.toml|\.ruff\.toml)$')
printf '%s\n' "$CONFIGS"
if [ -n "$CONFIGS" ]; then
rg -n 'RUF00[123]|select|extend-select|ignore|extend-ignore' $CONFIGS
fiRepository: affaan-m/everything-claude-code
Length of output: 365
🏁 Script executed:
# Check the full ruff.toml configuration
cat ruff.tomlRepository: affaan-m/everything-claude-code
Length of output: 1152
🏁 Script executed:
# Check if the gacha.py file is mentioned in any Ruff configuration
rg -r 'gacha' ruff.toml skills/skill-comply/pyproject.toml 2>/dev/null || echo "Not found"Repository: affaan-m/everything-claude-code
Length of output: 84
🌐 Web query:
Ruff RUF001 RUF002 RUF003 ambiguous unicode rules
💡 Result:
Ruff's RUF001, RUF002, and RUF003 rules detect ambiguous Unicode characters that are visually similar to ASCII or other preferred Unicode characters, to prevent confusion, bugs, or malicious code. - RUF001 (ambiguous-unicode-character-string): Checks strings. Example: Flags Greek "Η" (U+0397) in "Ηello, world!", suggests Latin "H" (U+0048). - RUF002 (ambiguous-unicode-character-docstring): Checks docstrings. Example: Flags fullwidth parenthesis U+FF09 in docstrings. - RUF003 (ambiguous-unicode-character-comment): Checks comments. Example: Flags Cyrillic "о" (U+043E) in "# nоqa", suggests Latin "o" (U+006F). These rules were added around v0.0.102 (RUF001/RUF002) and v0.0.108 (RUF003). They are not enabled by default but can be selected via lint.select = ["RUF"]. In preview mode (enabled via lint.preview = true), they also flag Unicode-to-Unicode confusables (e.g., OHM SIGN vs. GREEK CAPITAL LETTER OMEGA), based on Unicode Security Mechanisms spec preferences. This extension is under discussion for refinement, particularly for cases like Greek μ vs. micro symbol µ (Issue #14433, opened Nov 2024). Configuration: Use lint.allowed-confusables (list of codepoints, e.g., ["U+0660"]) to whitelist characters across these rules. Proposals exist for ranges/locales (Issue #13330, open) and word-context sensitivity improvements (implemented in 2023). Known issues: False positives in non-Latin languages (e.g., Cyrillic "Афганистан", Issue #4190), emojis (Issue #13337), math symbols in comments (Issue #23886, Mar 2026). Autofix replaces with suggested ASCII equivalent.
Citations:
- 1: https://docs.astral.sh/ruff/rules/ambiguous-unicode-character-comment/
- 2: https://docs.astral.sh/ruff/rules/ambiguous-unicode-character-string/
- 3: https://docs.astral.sh/ruff/rules/ambiguous-unicode-character-docstring/
- 4: Revisit unicode-to-unicode confusables in
RUF001,RUF002,RUF003astral-sh/ruff#14433 - 5: Allow character ranges or locales in
allowed-confusablesfor RUF001, RUF002, & RUF003 astral-sh/ruff#13330 - 6: RUF001 reports false positive for non-latin languages astral-sh/ruff#4190
- 7: Allow ambiguous unicode characters in comments astral-sh/ruff#23886
- 8: RUF001 gives a false-positive with an emoji astral-sh/ruff#13337
- 9: Make ambiguous-unicode detection sensitive to 'word' context astral-sh/ruff#4552
Add scoped Ruff suppression for ambiguous Unicode character rules in this Chinese-localized file.
RUF001, RUF002, and RUF003 are enabled in the project's Ruff configuration (via select = ["RUF"]) and are not ignored. This file uses full-width Chinese punctuation (em dashes ── in comments, full-width parentheses () in strings and comments) which triggers these ambiguous-Unicode warnings. Since the file's content is intentionally localized to Chinese, add a scoped suppression at the top:
Suggested fix
+# ruff: noqa: RUF001,RUF002,RUF003
"""龙虾灵魂抽卡机 - 真随机组合生成器🧰 Tools
🪛 Ruff (0.15.6)
[warning] 5-5: Docstring contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF002)
[warning] 13-13: Comment contains ambiguous : (FULLWIDTH COLON). Did you mean : (COLON)?
(RUF003)
[warning] 16-16: Comment contains ambiguous : (FULLWIDTH COLON). Did you mean : (COLON)?
(RUF003)
[warning] 16-16: Comment contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF003)
[warning] 16-16: Comment contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF003)
[warning] 16-16: Comment contains ambiguous × (MULTIPLICATION SIGN). Did you mean x (LATIN SMALL LETTER X)?
(RUF003)
[warning] 16-16: Comment contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF003)
[warning] 18-18: Comment contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF003)
[warning] 18-18: Comment contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF003)
[warning] 18-18: Comment contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF003)
[warning] 23-23: Comment contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF003)
[warning] 23-23: Comment contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF003)
[warning] 23-23: Comment contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF003)
[warning] 28-28: Comment contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF003)
[warning] 28-28: Comment contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF003)
[warning] 33-33: Comment contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF003)
[warning] 33-33: Comment contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF003)
[warning] 33-33: Comment contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF003)
[warning] 38-38: Comment contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF003)
[warning] 38-38: Comment contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF003)
[warning] 38-38: Comment contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF003)
[warning] 43-43: Comment contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF003)
[warning] 43-43: Comment contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF003)
[warning] 43-43: Comment contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF003)
[warning] 48-48: Comment contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF003)
[warning] 48-48: Comment contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF003)
[warning] 48-48: Comment contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF003)
[warning] 53-53: Comment contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF003)
[warning] 53-53: Comment contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF003)
[warning] 58-58: Comment contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF003)
[warning] 58-58: Comment contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF003)
[warning] 63-63: Comment contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF003)
[warning] 63-63: Comment contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF003)
[warning] 70-70: Comment contains ambiguous : (FULLWIDTH COLON). Did you mean : (COLON)?
(RUF003)
[warning] 70-70: Comment contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF003)
[warning] 70-70: Comment contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF003)
[warning] 70-70: Comment contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF003)
[warning] 79-79: String contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF001)
[warning] 80-80: String contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF001)
[warning] 80-80: String contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF001)
[warning] 83-83: String contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF001)
[warning] 88-88: String contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF001)
[warning] 98-98: Comment contains ambiguous : (FULLWIDTH COLON). Did you mean : (COLON)?
(RUF003)
[warning] 98-98: Comment contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF003)
[warning] 98-98: Comment contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF003)
[warning] 122-122: Comment contains ambiguous : (FULLWIDTH COLON). Did you mean : (COLON)?
(RUF003)
[warning] 122-122: Comment contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF003)
[warning] 122-122: Comment contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF003)
[warning] 143-143: String contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF001)
[warning] 143-143: String contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF001)
[warning] 146-146: Comment contains ambiguous : (FULLWIDTH COLON). Did you mean : (COLON)?
(RUF003)
[warning] 146-146: Comment contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF003)
[warning] 146-146: Comment contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF003)
[warning] 168-168: String contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF001)
[warning] 168-168: String contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF001)
[warning] 169-169: String contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF001)
[warning] 169-169: String contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF001)
[warning] 172-172: String contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF001)
[warning] 172-172: String contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF001)
[warning] 177-177: Docstring contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF002)
[warning] 177-177: Docstring contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF002)
[warning] 213-213: String contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF001)
[warning] 213-213: String contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF001)
[warning] 214-214: String contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF001)
[warning] 218-218: String contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF001)
[warning] 218-218: String contains ambiguous : (FULLWIDTH COLON). Did you mean : (COLON)?
(RUF001)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/openclaw-persona-forge/gacha.py` around lines 2 - 220, This file
triggers Ruff ambiguous-Unicode rules (RUF001, RUF002, RUF003) because it
intentionally uses full-width Chinese punctuation; add a scoped Ruff suppression
comment at the top of the module (immediately after or on the module docstring)
to disable these specific codes for this file (e.g., a ruff noqa for
RUF001,RUF002,RUF003), leaving the rest of linting intact and not changing logic
in functions like pick or main.
| def pick(pool): | ||
| """使用 secrets 模块(直接读 os.urandom)确保真随机""" | ||
| return pool[secrets.randbelow(len(pool))] | ||
|
|
||
|
|
||
| def main(): |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify untyped function definitions in this file.
rg -n '^\s*def\s+\w+\([^)]*\)\s*:' skills/openclaw-persona-forge/gacha.pyRepository: affaan-m/everything-claude-code
Length of output: 110
🏁 Script executed:
cat -n skills/openclaw-persona-forge/gacha.pyRepository: affaan-m/everything-claude-code
Length of output: 5925
🏁 Script executed:
rg -n '^\s*def\s+\w+\s*\(' skills/openclaw-persona-forge/gacha.pyRepository: affaan-m/everything-claude-code
Length of output: 110
Add type annotations to function signatures.
pick and main should be explicitly typed for readability and tooling consistency. Per coding guidelines, all function signatures in Python files must have type annotations.
💡 Suggested fix
+from collections.abc import Sequence
import secrets
import sys
@@
-def pick(pool):
+def pick(pool: Sequence[str]) -> str:
"""使用 secrets 模块(直接读 os.urandom)确保真随机"""
return pool[secrets.randbelow(len(pool))]
@@
-def main():
+def main() -> None:
@@
if __name__ == "__main__":
main()🧰 Tools
🪛 Ruff (0.15.6)
[warning] 177-177: Docstring contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF002)
[warning] 177-177: Docstring contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF002)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/openclaw-persona-forge/gacha.py` around lines 176 - 181, Add explicit
type annotations: declare a TypeVar (e.g., T) and annotate pick as pick(pool:
Sequence[T]) -> T (and ensure you import Sequence and TypeVar from typing), and
annotate main as main() -> None; update any imports at the top of the file to
include the typing names you use so the signatures for pick and main are fully
typed for tooling and readability.
There was a problem hiding this comment.
7 issues found across 9 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="skills/openclaw-persona-forge/references/output-template.md">
<violation number="1" location="skills/openclaw-persona-forge/references/output-template.md:114">
P2: SOUL.md generation instruction conflicts with the required SOUL.md format by omitting the mandatory “浓度调节” section when extracting only the “灵魂” content.</violation>
</file>
<file name="skills/openclaw-persona-forge/references/avatar-style.md">
<violation number="1" location="skills/openclaw-persona-forge/references/avatar-style.md:9">
P3: Avoid referencing an image from another repository’s `main` branch; this can silently break and adds an unreviewed external dependency. Use an in-repo asset path or an immutable commit-pinned URL instead.</violation>
<violation number="2" location="skills/openclaw-persona-forge/references/avatar-style.md:105">
P2: User-facing docs instruct installation from an unvetted external GitHub repository, creating supply-chain/review-control risk.</violation>
</file>
<file name="skills/openclaw-persona-forge/references/error-handling.md">
<violation number="1" location="skills/openclaw-persona-forge/references/error-handling.md:46">
P2: User-facing recovery guidance links to an external unvetted repository, creating a supply-chain/process risk.</violation>
</file>
<file name="skills/openclaw-persona-forge/gacha.py">
<violation number="1" location="skills/openclaw-persona-forge/gacha.py:186">
P2: `draw_count` is only upper-bounded, so `0`/negative inputs silently produce zero draws instead of enforcing the documented minimum of 1.</violation>
</file>
<file name="skills/openclaw-persona-forge/SKILL.md">
<violation number="1" location="skills/openclaw-persona-forge/SKILL.md:50">
P2: Temp-file path uses unsanitized user-derived name segment, creating filename/path safety risks.</violation>
<violation number="2" location="skills/openclaw-persona-forge/SKILL.md:53">
P2: Skill documentation introduces a supply-chain risk by directing users to install runtime capability from an unvetted external GitHub repository.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
|
Analysis Failed
Troubleshooting
Retry: |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
tests/scripts/openclaw-persona-forge-gacha.test.js (2)
57-61: Consider using "SKIP" instead of "PASS" for clarity.Marking a skipped test as "PASS" may be misleading in test reports. A distinct "SKIP" label better conveys that the test was not actually executed.
Suggested fix
const pythonBin = findPython(); if (!pythonBin) { - console.log(' PASS: skipped (python runtime unavailable)'); + console.log(' SKIP: python runtime unavailable'); return; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/scripts/openclaw-persona-forge-gacha.test.js` around lines 57 - 61, The test currently logs skipped Python as "PASS" which is misleading; update the message in the early-exit where pythonBin is checked (the block using findPython() and the console.log call) to print "SKIP: skipped (python runtime unavailable)" instead of "PASS" so skipped tests are clearly labeled in test output; modify the console.log in the tests/scripts/openclaw-persona-forge-gacha.test.js file accordingly.
66-73: Consider adding test cases for normal and upper-bound scenarios.The tests cover zero and negative inputs well. Consider adding tests for:
- Normal input (e.g.,
'3') to verify expected behavior- Upper-bound clamping (e.g.,
'10'should clamp to 5 draws)Suggested additional tests
const tests = [ ['clamps zero draws to one', () => { assertSingleDrawOutput(runGacha(pythonBin, '0')); }], ['clamps negative draws to one', () => { assertSingleDrawOutput(runGacha(pythonBin, '-3')); }], + ['accepts valid draw count', () => { + const result = runGacha(pythonBin, '2'); + assert.strictEqual(result.status, 0, result.stderr); + // Should see "第 1 抽" and "第 2 抽" dividers + assert.match(result.stdout, /第 1 抽/); + assert.match(result.stdout, /第 2 抽/); + }], + ['clamps excessive draws to five', () => { + const result = runGacha(pythonBin, '10'); + assert.strictEqual(result.status, 0, result.stderr); + // Should see exactly 5 draws (第 5 抽 present, 第 6 抽 absent) + assert.match(result.stdout, /第 5 抽/); + assert.doesNotMatch(result.stdout, /第 6 抽/); + }], ];🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/scripts/openclaw-persona-forge-gacha.test.js` around lines 66 - 73, Add tests to cover normal and upper-bound scenarios for the gacha runner: extend the tests array (alongside existing cases) with one that calls runGacha(pythonBin, '3') and asserts expected multi-draw behavior (using the appropriate assertion helper, e.g., assertMultiDrawOutput or a new assertion if needed), and another that calls runGacha(pythonBin, '10') and verifies the result is clamped to 5 draws (use assertClampedToFive or assertMultiDrawOutput with expected length 5). Ensure you reference the existing runGacha and assertion helpers (assertSingleDrawOutput) when adding these two new entries so the tests validate normal (3) and upper-bound (10→5) behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@skills/openclaw-persona-forge/references/avatar-style.md`:
- Around line 6-124: Add three top-level Markdown headings "When to Use", "How
It Works", and "Examples" and move the existing sections under them: put the
short intent/usage summary under "When to Use"; place the STYLE_BASE block,
个性化变量 table, 提示词组装, and 生图流程 (Path A/Path B) under "How It Works" (preserve the
STYLE_BASE identifier and variable names like CHARACTER_NAME, SHELL_COLOR,
SIGNATURE_PROP, EXPRESSION, UNIQUE_DETAIL, BACKGROUND_ACCENT, ENERGY_BAR_LABEL);
and include the 展示给用户的格式 and one or two concrete example prompts or sample
variable sets under "Examples" showing expected output (e.g., filled TEMPLATE
with CHARACTER_NAME and SHELL_COLOR). Ensure headings are top-level Markdown (##
or #) and all original content is retained and reorganized beneath the new
headings.
---
Nitpick comments:
In `@tests/scripts/openclaw-persona-forge-gacha.test.js`:
- Around line 57-61: The test currently logs skipped Python as "PASS" which is
misleading; update the message in the early-exit where pythonBin is checked (the
block using findPython() and the console.log call) to print "SKIP: skipped
(python runtime unavailable)" instead of "PASS" so skipped tests are clearly
labeled in test output; modify the console.log in the
tests/scripts/openclaw-persona-forge-gacha.test.js file accordingly.
- Around line 66-73: Add tests to cover normal and upper-bound scenarios for the
gacha runner: extend the tests array (alongside existing cases) with one that
calls runGacha(pythonBin, '3') and asserts expected multi-draw behavior (using
the appropriate assertion helper, e.g., assertMultiDrawOutput or a new assertion
if needed), and another that calls runGacha(pythonBin, '10') and verifies the
result is clamped to 5 draws (use assertClampedToFive or assertMultiDrawOutput
with expected length 5). Ensure you reference the existing runGacha and
assertion helpers (assertSingleDrawOutput) when adding these two new entries so
the tests validate normal (3) and upper-bound (10→5) behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 1e00c3fd-e8fb-4820-bc5a-6b2d9066a38c
📒 Files selected for processing (6)
skills/openclaw-persona-forge/SKILL.mdskills/openclaw-persona-forge/gacha.pyskills/openclaw-persona-forge/references/avatar-style.mdskills/openclaw-persona-forge/references/error-handling.mdskills/openclaw-persona-forge/references/output-template.mdtests/scripts/openclaw-persona-forge-gacha.test.js
✅ Files skipped from review due to trivial changes (2)
- skills/openclaw-persona-forge/references/error-handling.md
- skills/openclaw-persona-forge/references/output-template.md
🚧 Files skipped from review as they are similar to previous changes (1)
- skills/openclaw-persona-forge/SKILL.md
| ## 风格参考 | ||
|
|
||
| 亚当(Adam)—— 龙虾族创世神,本 Skill 的首个作品。 | ||
|
|
||
| 所有新生成的龙虾头像应与这一风格保持一致:复古未来主义、街机 UI 包边、强轮廓、可在 64x64 下辨识。 | ||
|
|
||
| ## 统一风格基底(STYLE_BASE) | ||
|
|
||
| **每次生成都必须包含这段基底**,不得修改或省略: | ||
|
|
||
| ``` | ||
| STYLE_BASE = """ | ||
| Retro-futuristic 3D rendered illustration, in the style of 1950s-60s Space Age | ||
| pin-up poster art reimagined as glossy inflatable 3D, framed within a vintage | ||
| arcade game UI overlay. | ||
|
|
||
| Material: high-gloss PVC/latex-like finish, soft specular highlights, puffy | ||
| inflatable quality reminiscent of vintage pool toys meets sci-fi concept art. | ||
| Smooth subsurface scattering on shell surface. | ||
|
|
||
| Arcade UI frame: pixel-art arcade cabinet border elements, a top banner with | ||
| character name in chunky 8-bit bitmap font with scan-line glow effect, a pixel | ||
| energy bar in the upper corner, small coin-credit text "INSERT SOUL TO CONTINUE" | ||
| at bottom in phosphor green monospace type, subtle CRT screen curvature and | ||
| scan-line overlay across entire image. Decorative corner bezels styled as chrome | ||
| arcade cabinet trim with atomic-age starburst rivets. | ||
|
|
||
| Pose: references classic Gil Elvgren pin-up compositions, confident and | ||
| charismatic with a slight theatrical tilt. | ||
|
|
||
| Color system: vintage NASA poster palette as base — deep navy, teal, dusty coral, | ||
| cream — viewed through arcade CRT monitor with slight RGB fringing at edges. | ||
| Overall aesthetic combines Googie architecture curves, Raygun Gothic design | ||
| language, mid-century advertising illustration, modern 3D inflatable character | ||
| rendering, and 80s-90s arcade game UI. Chrome and pastel accent details on | ||
| joints and antenna tips. | ||
|
|
||
| Format: square, optimized for avatar use. Strong silhouette readable at 64x64 | ||
| pixels. | ||
| """ | ||
| ``` | ||
|
|
||
| ## 个性化变量 | ||
|
|
||
| 在统一基底之上,根据灵魂填充以下变量: | ||
|
|
||
| | 变量 | 说明 | 示例 | | ||
| |------|------|------| | ||
| | `CHARACTER_NAME` | 街机横幅上显示的名字 | "ADAM"、"DEWEY"、"RIFF" | | ||
| | `SHELL_COLOR` | 龙虾壳的主色调(在统一色盘内变化) | "deep crimson"、"dusty teal"、"warm amber" | | ||
| | `SIGNATURE_PROP` | 标志性道具 | "cracked sunglasses"、"reading glasses on a chain" | | ||
| | `EXPRESSION` | 表情/姿态 | "stoic but kind-eyed"、"nervously focused" | | ||
| | `UNIQUE_DETAIL` | 独特细节(纹路/装饰/伤痕等) | "constellation patterns etched on claws"、"bandaged left claw" | | ||
| | `BACKGROUND_ACCENT` | 背景的个性化元素(在统一宇宙背景上叠加) | "musical notes floating as nebula dust"、"ancient book pages drifting" | | ||
| | `ENERGY_BAR_LABEL` | 街机 UI 能量条的标签(个性化小彩蛋) | "CREATION POWER"、"CALM LEVEL"、"ROCK METER" | | ||
|
|
||
| ## 提示词组装 | ||
|
|
||
| ``` | ||
| 最终提示词 = STYLE_BASE + 个性化描述段落 | ||
| ``` | ||
|
|
||
| 个性化描述段落模板: | ||
|
|
||
| ``` | ||
| The character is a cartoon lobster with a [SHELL_COLOR] shell, | ||
| [EXPRESSION], wearing/holding [SIGNATURE_PROP]. | ||
| [UNIQUE_DETAIL]. Background accent: [BACKGROUND_ACCENT]. | ||
| The arcade top banner reads "[CHARACTER_NAME]" and the energy bar | ||
| is labeled "[ENERGY_BAR_LABEL]". | ||
| The key silhouette recognition points at small size are: | ||
| [SIGNATURE_PROP] and [one other distinctive feature]. | ||
| ``` | ||
|
|
||
| ## 生图流程 | ||
|
|
||
| 提示词组装完成后: | ||
|
|
||
| ### 路径 A:已安装且已审核的生图 skill | ||
|
|
||
| 1. 先将龙虾名字规整为安全片段:仅保留字母、数字和连字符,其余字符替换为 `-` | ||
| 2. 用 Write 工具写入:`/tmp/openclaw-<safe-name>-prompt.md` | ||
| 3. 调用当前环境允许的生图 skill 生成图片 | ||
| 4. 用 Read 工具展示生成的图片给用户 | ||
| 5. 问用户是否满意,不满意可调整变量重新生成 | ||
|
|
||
| ### 路径 B:未安装可用的生图 skill | ||
|
|
||
| 输出完整提示词文本,附手动使用说明: | ||
|
|
||
| ```markdown | ||
| **头像提示词**(可复制到以下平台手动生成): | ||
| - Google Gemini:直接粘贴 | ||
| - ChatGPT(DALL-E):直接粘贴 | ||
| - Midjourney:粘贴后加 `--ar 1:1 --style raw` | ||
|
|
||
| > [完整英文提示词] | ||
|
|
||
| 如当前环境后续提供经过审核的生图 skill,可再接回自动生图流程。 | ||
| ``` | ||
|
|
||
| ## 展示给用户的格式 | ||
|
|
||
| ```markdown | ||
| ## 头像 | ||
|
|
||
| **个性化变量**: | ||
| - 壳色:[SHELL_COLOR] | ||
| - 道具:[SIGNATURE_PROP] | ||
| - 表情:[EXPRESSION] | ||
| - 独特细节:[UNIQUE_DETAIL] | ||
| - 背景点缀:[BACKGROUND_ACCENT] | ||
| - 能量条标签:[ENERGY_BAR_LABEL] | ||
|
|
||
| **生成结果**: | ||
| [图片(路径A)或提示词文本(路径B)] | ||
|
|
||
| > 满意吗?不满意我可以调整 [具体可调项] 后重新生成。 | ||
| ``` |
There was a problem hiding this comment.
Add explicit When to Use / How It Works / Examples headings to satisfy skill-doc format.
The content is solid, but this file currently misses the required top-level section structure for skills docs. Please add explicit headings and nest the current material under them.
Suggested structure update
+# When to Use
+- 当需要为 OpenClaw 龙虾角色生成统一风格头像时使用本规范。
+- 适用于自动生图(路径 A)与手动提示词降级(路径 B)。
+
+# How It Works
## 风格参考
...
## 统一风格基底(STYLE_BASE)
...
## 个性化变量
...
## 提示词组装
...
## 生图流程
...
-## 展示给用户的格式
+# Examples
+## 展示给用户的格式
...As per coding guidelines, "skills/**/*.md: Skill format must be Markdown with clear sections for When to Use, How It Works, and Examples".
🧰 Tools
🪛 LanguageTool
[grammar] ~86-~86: Ensure spelling is correct
Context: ...示词组装完成后: ### 路径 A:已安装且已审核的生图 skill 1. 先将龙虾名字规整为安全片段:仅保留字母、数字和连字符,其余字符替换为 - 2. 用 Write 工具写入:`/tmp/openclaw--p...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/openclaw-persona-forge/references/avatar-style.md` around lines 6 -
124, Add three top-level Markdown headings "When to Use", "How It Works", and
"Examples" and move the existing sections under them: put the short intent/usage
summary under "When to Use"; place the STYLE_BASE block, 个性化变量 table, 提示词组装, and
生图流程 (Path A/Path B) under "How It Works" (preserve the STYLE_BASE identifier
and variable names like CHARACTER_NAME, SHELL_COLOR, SIGNATURE_PROP, EXPRESSION,
UNIQUE_DETAIL, BACKGROUND_ACCENT, ENERGY_BAR_LABEL); and include the 展示给用户的格式
and one or two concrete example prompts or sample variable sets under "Examples"
showing expected output (e.g., filled TEMPLATE with CHARACTER_NAME and
SHELL_COLOR). Ensure headings are top-level Markdown (## or #) and all original
content is retained and reorganized beneath the new headings.
There was a problem hiding this comment.
1 issue found across 6 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="tests/scripts/openclaw-persona-forge-gacha.test.js">
<violation number="1" location="tests/scripts/openclaw-persona-forge-gacha.test.js:50">
P2: Single-draw clamp tests only assert label presence, not exactly one draw, so multi-draw regressions can pass unnoticed.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
|
|
||
| function assertSingleDrawOutput(result) { | ||
| assert.strictEqual(result.status, 0, result.stderr); | ||
| assert.match(result.stdout, /\[身份\] 前世身份:/); |
There was a problem hiding this comment.
P2: Single-draw clamp tests only assert label presence, not exactly one draw, so multi-draw regressions can pass unnoticed.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/scripts/openclaw-persona-forge-gacha.test.js, line 50:
<comment>Single-draw clamp tests only assert label presence, not exactly one draw, so multi-draw regressions can pass unnoticed.</comment>
<file context>
@@ -0,0 +1,91 @@
+
+function assertSingleDrawOutput(result) {
+ assert.strictEqual(result.status, 0, result.stderr);
+ assert.match(result.stdout, /\[身份\] 前世身份:/);
+ assert.match(result.stdout, /\[概括\] 一句话概括:/);
+}
</file context>
…sona-forge-v2 feat(skills): add openclaw-persona-forge skill
…sona-forge-v2 feat(skills): add openclaw-persona-forge skill
What Changed
Add the complete
openclaw-persona-forgeskill with all supporting files (9 files total):SKILL.md— skill definition with community origin frontmattergacha.py/gacha.sh— random soul generation engine (gacha draw system)references/— 6 reference docs (avatar style, boundary rules, error handling, identity tension, naming system, output template)Previous PR #839 was closed because only SKILL.md was submitted. This PR includes the full skill.
Why This Change
This skill enables users to forge complete lobster soul profiles for OpenClaw AI Agents — including identity positioning, SOUL.md generation, character-driven boundary rules, names, and avatar image prompts. It supports both directed creation and random gacha draws.
Testing Done
origin: communityas requiredType of Change
feat:New featureSecurity & Quality Checklist
Documentation
references/directorySummary by cubic
Adds the complete
openclaw-persona-forgeskill to forge full OpenClaw agent personas (SOUL.md/IDENTITY.md, boundary rules, names, and avatar prompts) with an optional avatar pipeline. Hardened the gacha engine with input validation and a test that verifies clamped draw counts and Python detection.New Features
openclaw-persona-forgeskill withSKILL.mdand six short references (identity tension, boundary rules, naming, avatar style, error handling, output template).gacha.py/gacha.shfor true-random persona seeds; runpython3 skills/openclaw-persona-forge/gacha.py [count](1–5).baoyu-image-genwhen available, otherwise outputs a copy-paste prompt.python3→ internal random; nobaoyu-image-gen→ prompt only).Bug Fixes
tests/scripts/openclaw-persona-forge-gacha.test.jsto verify clamping and skip cleanly when Python is unavailable.Written for commit d6c7f8f. Summary will update on new commits.
Summary by CodeRabbit
New Features
Documentation
Tests