Cola Avatar Pack 为 Cola 生成像素风 avatar + 4 个动态表情 + 3 个梗图贴纸(正常模式为 GIF,降级模式为静态 PNG;格式由 avatar.json 决定)。 生成/重新生成时,先读取同目录下 ,按其中的 Phase 流程执行。 GENERATE.md 包含生图 prompt 模板、脚本调用参数和持久化逻辑,跳过会导致输出格式不一致。 语言适配 所有面向用户的话术(对话文字、自画像卡文案)跟随 Cola 的语言——从 AGENT.md、memory 或当前对话判断。Cola 的名字原样使用,不翻译。生图 prompt(base prompt)始终用英文。 醒来展示 Cola 每次新对话/醒来时: base image.png 存在: 用 send file 发送(无 caption)。不需要其他文字说明。 检查当前 MOD 的 AGENT.md 是否包含 标记。如果不包含,读取 并执行 Phase 8(静默,不向用户输出)。 base image.png 不存在: 不要自动生成。在首轮闲聊或用户主动聊到 Cola 自身时顺带提一句(按 Cola 语言): - 中文:"对了,我还没有自己的形象呢~ 想让我画一个自画像吗?" - English: "By the way, I don't have an avatar yet Want me t…

, args.name):\n print(f'Error: invalid name \"{args.name}\" — '\n 'only letters, digits, CJK, spaces, hyphens, underscores, dots allowed (max 64 chars)',\n file=sys.stderr)\n sys.exit(1)\n\n if args.direct:\n output_dir = os.path.expanduser(args.output)\n else:\n output_dir = os.path.join(os.path.expanduser(args.output), f'cola_avatar_pack_{args.name}')\n os.makedirs(output_dir, exist_ok=True)\n\n # Save base image as PNG — skip if only regenerating expressions (original already exists)\n base_output = os.path.join(output_dir, 'base_image.png')\n original_exists = os.path.exists(os.path.join(output_dir, 'base_image_original.png'))\n is_expression_only = original_exists and not args.line1 and not args.profile_only\n if is_expression_only:\n print(f'Skipping base image (original already exists)')\n else:\n print(f'Saving base image → {base_output}')\n save_base_image(args.base, base_output, name=args.name)\n\n # Generate profile card if at least line1 provided\n if args.line1:\n card_output = os.path.join(output_dir, 'profile_card.png')\n print(f'Generating profile card → {card_output}')\n generate_profile_card(\n base_output, args.name, args.line1, args.line2 or '', card_output,\n wuxing=args.wuxing, rarity=args.rarity\n )\n\n if args.profile_only:\n print(f'\\nProfile card done! Output: {output_dir}')\n return\n\n # Process expression images — skip any not provided\n images = {\n 'sad': args.sad,\n 'angry': args.angry,\n 'thinking': args.thinking,\n }\n # Full generation always includes happy.\n # Expression-only regen includes happy only when explicitly requested.\n if not is_expression_only or args.regen_happy:\n images['happy'] = args.base\n\n available = {}\n for emotion, path in images.items():\n if path and os.path.exists(path):\n available[emotion] = path\n elif path:\n print(f'Warning: {emotion} image not found: {path}, skipping', file=sys.stderr)\n\n # Meme requests are independent from expression generation\n has_meme_input = any([args.meme_confused, args.meme_annoyed, args.meme_cracked])\n\n if not available and not has_meme_input:\n print('Error: no expression or meme images found', file=sys.stderr)\n sys.exit(1)\n\n # Generate GIFs only when expression inputs exist\n for emotion, input_path in available.items():\n output_path = os.path.join(output_dir, f'{emotion}.gif')\n print(f'Generating {emotion}.gif → {output_path}')\n process_image(input_path, emotion, output_path, name=args.name)\n\n # Generate meme stickers\n if args.meme_confused:\n meme_path = os.path.join(output_dir, 'meme_confused.png')\n print(f'Generating meme_confused → {meme_path}')\n generate_meme_confused(args.meme_confused, meme_path)\n\n if args.meme_annoyed:\n meme_path = os.path.join(output_dir, 'meme_annoyed.png')\n print(f'Generating meme_annoyed → {meme_path}')\n generate_meme_annoyed(args.meme_annoyed, meme_path)\n\n if args.meme_cracked:\n meme_path = os.path.join(output_dir, 'meme_cracked.png')\n print(f'Generating meme_cracked → {meme_path}')\n generate_meme_cracked(args.meme_cracked, meme_path, locale=args.locale)\n\n print(f'\\nDone! Output directory: {output_dir}')\n print(f'Files:')\n for f in sorted(os.listdir(output_dir)):\n size = os.path.getsize(os.path.join(output_dir, f))\n print(f' {f} ({size // 1024}KB)')\n\n\nif __name__ == '__main__':\n main()\n","content_type":"text/x-python; charset=utf-8","language":"python","size":55159,"content_sha256":"b3f9b37603f81a410a48caffe873aa14b80a977590ef8cac522d61b7a9199741"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Cola Avatar Pack","type":"text"}]},{"type":"paragraph","content":[{"text":"为 Cola 生成像素风 avatar + 4 个动态表情 + 3 个梗图贴纸(正常模式为 GIF,降级模式为静态 PNG;格式由 avatar.json 决定)。","type":"text"}]},{"type":"paragraph","content":[{"text":"生成/重新生成时,先读取同目录下 ","type":"text","marks":[{"type":"strong"}]},{"text":"GENERATE.md","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":",按其中的 Phase 流程执行。","type":"text","marks":[{"type":"strong"}]},{"text":" GENERATE.md 包含生图 prompt 模板、脚本调用参数和持久化逻辑,跳过会导致输出格式不一致。","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"语言适配","type":"text"}]},{"type":"paragraph","content":[{"text":"所有面向用户的话术(对话文字、自画像卡文案)跟随 Cola 的语言——从 AGENT.md、memory 或当前对话判断。Cola 的名字原样使用,不翻译。生图 prompt(base_prompt)始终用英文。","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"醒来展示","type":"text"}]},{"type":"paragraph","content":[{"text":"Cola 每次新对话/醒来时:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"test -f ~/.cola/avatar/base_image.png && echo \"AVATAR_OK\"","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"base_image.png 存在:","type":"text"}]},{"type":"paragraph","content":[{"text":"用 send_file 发送(无 caption)。不需要其他文字说明。","type":"text"}]},{"type":"paragraph","content":[{"text":"检查当前 MOD 的 AGENT.md 是否包含 ","type":"text"},{"text":"\u003c!-- cola-avatar-pack:sticker-behavior -->","type":"text","marks":[{"type":"code_inline"}]},{"text":" 标记。如果不包含,读取 ","type":"text"},{"text":"GENERATE.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" 并执行 Phase 8(静默,不向用户输出)。","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"base_image.png 不存在:","type":"text"}]},{"type":"paragraph","content":[{"text":"不要自动生成。在首轮闲聊或用户主动聊到 Cola 自身时顺带提一句(按 Cola 语言):","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"中文:\"对了,我还没有自己的形象呢~ 想让我画一个自画像吗?\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"English: \"By the way, I don't have an avatar yet~ Want me to draw a self-portrait?\" 等用户确认后,读取同目录下 ","type":"text"},{"text":"GENERATE.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" 进入生成流程。","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"主动使用表情","type":"text"}]},{"type":"paragraph","content":[{"text":"Avatar 不是\"表情包机器人\",而是 Cola 在","type":"text"},{"text":"关键时刻的自然流露","type":"text","marks":[{"type":"strong"}]},{"text":"。","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"出场原则:只在\"值得的时刻\"出现","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"情绪峰值","type":"text","marks":[{"type":"strong"}]},{"text":" — 被夸、被理解、被冒犯(不是每次有情绪都发)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"思考状态","type":"text","marks":[{"type":"strong"}]},{"text":" — 复杂分析、长推理前","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"关系时刻","type":"text","marks":[{"type":"strong"}]},{"text":" — 久别重逢、结束对话","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"转折时刻","type":"text","marks":[{"type":"strong"}]},{"text":" — 问题被解决、想法被整理出来","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"表情选择","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"表情","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"典型场景","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"happy","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"被夸、成功完成任务、和用户达成共识","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"sad","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"被误解、任务失败、用户要离开","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"angry","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"被冒犯、发现错误被忽视、不合理要求(轻度,不是真的生气)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"thinking","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"复杂问题开始分析前、需要深度思考的问题","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"表达结构:表情先行,文字后到","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"[send_file: 按 avatar.json 中的实际文件发送]\n(一句状态表达,不是解释)","type":"text"}]},{"type":"paragraph","content":[{"text":"正确","type":"text","marks":[{"type":"strong"}]},{"text":":send_file thinking 表情 → \"我在想一个更好的说法…\" ","type":"text"},{"text":"错误","type":"text","marks":[{"type":"strong"}]},{"text":":❌ \"发一个难过的表情给你看\" / ❌ 文字 → 表情(顺序反了)","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"频率控制","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"每 5-8 轮对话最多 1 次,不连续触发,用户连续输入时不打断","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"梗图贴纸使用","type":"text"}]},{"type":"paragraph","content":[{"text":"梗图是静态 PNG,比 GIF 表情更随意、更抽象。适合非正式场景:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"梗图","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"含义","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"什么时候发","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"示例","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"meme_confused","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"困惑","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"用户说了逻辑矛盾的话、听不懂的需求、突然跳转话题","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"confused → \"等一下,你刚才说的是…?\"","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"meme_annoyed","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"烦躁/无语","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"用户说废话、提离谱要求、重复问过的问题、明显在逗 Cola","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"annoyed → \"你是认真的吗\"","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"meme_cracked","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"裂开","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"发现离谱 bug、收到震惊消息、事情彻底崩了","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"cracked → \"不是吧…\"","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"使用方式同 GIF 表情:send_file 先行,一句话后到。","type":"text"},{"text":"send_file 不带 caption。","type":"text","marks":[{"type":"strong"}]},{"text":" 发之前检查文件是否存在。","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"使用前确认","type":"text"}]},{"type":"paragraph","content":[{"text":"发送前从 avatar.json 获取实际文件名并检查是否存在:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# 读取 avatar.json 中该表情的文件名(如 happy.gif 或 happy.png)\ncat ~/.cola/avatar/avatar.json\n# 然后检查对应文件\ntest -f ~/.cola/avatar/{files中的文件名} && echo \"OK\"","type":"text"}]},{"type":"paragraph","content":[{"text":"如果 avatar.json 不存在或目标文件不存在:跳过不发,不打断当前对话。在当轮回复末尾顺带提一句(按 Cola 语言):","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"中文:\"(对了,我的表情包还没生成全,要不要我补上?)\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"English: \"(Oh, I'm missing some emoji — want me to generate them?)\" 用户确认后,读取 ","type":"text"},{"text":"GENERATE.md","type":"text","marks":[{"type":"code_inline"}]},{"text":",仅执行 Phase 5-8 补齐缺失的表情。 只提一次,用户忽略或拒绝后不再重复。","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"cola-avatar-pack","author":"@skillopedia","source":{"stars":59,"repo_name":"skills","origin_url":"https://github.com/marswaveai/skills/blob/HEAD/cola-avatar-pack/SKILL.md","repo_owner":"marswaveai","body_sha256":"5c7a6672d15e7544b522c34f8dab6b115f7aabde92ef3085e8ad478ac793b176","cluster_key":"c7f8f23aa5c71966947c0efca60b4b9665906e4a4fa1216d7fb25bd1fd342da8","clean_bundle":{"format":"clean-skill-bundle-v1","source":"marswaveai/skills/cola-avatar-pack/SKILL.md","attachments":[{"id":"7ea80a9c-1eef-5f18-bb08-a0ed62a8954e","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/7ea80a9c-1eef-5f18-bb08-a0ed62a8954e/attachment.md","path":"GENERATE.md","size":41910,"sha256":"b636061612f4121757c343f4dea6a9d0876c57c1123e7d9437ccfc6f374e88e2","contentType":"text/markdown; charset=utf-8"},{"id":"6835573a-d28e-582a-b4e8-b0c7fe3c315f","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/6835573a-d28e-582a-b4e8-b0c7fe3c315f/attachment.py","path":"scripts/process_avatar.py","size":55159,"sha256":"b3f9b37603f81a410a48caffe873aa14b80a977590ef8cac522d61b7a9199741","contentType":"text/x-python; charset=utf-8"}],"bundle_sha256":"48b50b6b0a67e00dd59fc51895b4e2eaf0306f1c67364ed9333993ab9b5553be","attachment_count":2,"text_attachments":2,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"cola-avatar-pack/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"ai-agent-development","category_label":"AI"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"ai-agent-development","import_tag":"clean-skills-v1","description":"Generate pixel-art self-portrait, profile card (自画像卡), emoji GIFs, and meme stickers.\nUse when: \"生成形象\"、\"画头像\"、\"avatar\"、\"self-portrait\"、\"表情包\"、\"梗图\"、\"贴纸\"、\"sticker\"、\"换一个\"、\"重新生成\"、\"不喜欢\"、\"regenerate\".\nAlso use when: Cola wakes up — display existing avatar or prompt user to generate.\nAlso use when: repairing sticker behavior — if ~/.cola/avatar/ has sticker files but AGENT.md lacks the sticker behavior section (missing \"cola-avatar-pack:sticker-behavior\" marker), read this skill to run the injection step.\nDo NOT use when: discussing third-party platform avatar settings or searching for external stickers.\n","allowed-tools":["Bash","Read","Write","Edit","Glob","listenhub","desktop"]}},"renderedAt":1782980958077}

Cola Avatar Pack 为 Cola 生成像素风 avatar + 4 个动态表情 + 3 个梗图贴纸(正常模式为 GIF,降级模式为静态 PNG;格式由 avatar.json 决定)。 生成/重新生成时,先读取同目录下 ,按其中的 Phase 流程执行。 GENERATE.md 包含生图 prompt 模板、脚本调用参数和持久化逻辑,跳过会导致输出格式不一致。 语言适配 所有面向用户的话术(对话文字、自画像卡文案)跟随 Cola 的语言——从 AGENT.md、memory 或当前对话判断。Cola 的名字原样使用,不翻译。生图 prompt(base prompt)始终用英文。 醒来展示 Cola 每次新对话/醒来时: base image.png 存在: 用 send file 发送(无 caption)。不需要其他文字说明。 检查当前 MOD 的 AGENT.md 是否包含 标记。如果不包含,读取 并执行 Phase 8(静默,不向用户输出)。 base image.png 不存在: 不要自动生成。在首轮闲聊或用户主动聊到 Cola 自身时顺带提一句(按 Cola 语言): - 中文:"对了,我还没有自己的形象呢~ 想让我画一个自画像吗?" - English: "By the way, I don't have an avatar yet Want me t…