Skill: xiaoxiangxie/cook-like-hoc (version 1.0.1)

--- name: cook-like-hoc description: > Search and display recipes from the open-source Gar-b-age/CookLikeHOC repository. Use when the user asks to "cook like hoc", "像老乡鸡那样做饭", "老乡鸡菜谱", "做菜", or wants to find a specific recipe from the CookLikeHOC database. --- # CookLikeHOC Skill This skill allows you to retrieve recipe instructions from the [CookLikeHOC](https://github.com/Gar-b-age/CookLikeHOC) repository. It contains recipes from the "老乡鸡菜品溯源报告". ## Prerequisites - Python 3 installed - Built-in `urllib` and `json` modules (no external libraries required) ## Workflows ### 1. Searching for a Recipe When the user asks for a recipe or wants to know how to cook a dish from the CookLikeHOC database, run the `search_recipe.py` script. **Command:** ```bash python ~/.agents/skills/cook-like-hoc/scripts/search_recipe.py "<Recipe Name>" ``` *Example:* ```bash python ~/.agents/skills/cook-like-hoc/scripts/search_recipe.py "肥肠鸡" ``` ## How to handle the output - The Python script performs fuzzy matching. It will return the markdown recipe for the exact or closest match. - Output the recipe to the user, formatting it cleanly as markdown. - If it says `Could not find any recipe matching`, inform the user that the recipe isn't in the database and perhaps suggest one from the provided examples. ## Supported categories & recipes The repository has categories like 主食 (Staple Food), 炒菜 (Stir-fried), 汤 (Soup), 炖菜 (Stew), 炸品 (Fried), 烤类 (Roasted), 烫菜 (Blanched), 煮锅 (Boiled Pots), 砂锅菜 (Casserole), 蒸菜 (Steamed), 配料 (Ingredients), and 饮品 (Drinks). The script searches across all markdown files in these categories automatically.

path: scripts/recipe_tree_cache.json
content: {"development": "docs/development.md", "大大大块牛腩面": "主食/大大大块牛腩面.md", "大排面": "主食/大排面.md", "大盘肥肠鸡手工面": "主食/大盘肥肠鸡手工面.md", "杂粮饭": "主食/杂粮饭.md", "浓香整块鸡汤面": "主食/浓香整块鸡汤面.md", "炸鸡腿时蔬面": "主食/炸鸡腿时蔬面.md", "特色鸡汤馄饨": "主食/特色鸡汤馄饨.md", "番茄鸡蛋面": "主食/番茄鸡蛋面.md", "砂锅荠菜鲜肉馄饨": "主食/砂锅荠菜鲜肉馄饨.md", "米饭": "主食/米饭.md", "素面": "主食/素面.md", "老鸡扬米面": "主食/老鸡扬米面.md", "肥西老母鸡汤面": "主食/肥西老母鸡汤面.md", "雪菜肉丝面": "主食/雪菜肉丝面.md", "香菇鸡汤面": "主食/香菇鸡汤面.md", "香辣牛肉面": "主食/香辣牛肉面.md", "香辣鸡丁拌面": "主食/香辣鸡丁拌面.md", "凉拌莴笋丝": "凉拌/凉拌莴笋丝.md", "口水鸡": "凉拌/口水鸡.md", "柠檬凤爪": "凉拌/柠檬凤爪.md", "西芹花生米": "凉拌/西芹花生米.md", "卤大排": "卤菜/卤大排.md", "卤方干": "卤菜/卤方干.md", "卤翅根": "卤菜/卤翅根.md", "卤鸡爪": "卤菜/卤鸡爪.md", "卤鸡腿": "卤菜/卤鸡腿.md", "嗨嗨桶（红油串串）": "卤菜/嗨嗨桶（红油串串）.md", "包子": "早餐/包子.md", "奶黄鸡包": "早餐/奶黄鸡包.md", "小米南瓜粥": "早餐/小米南瓜粥.md", "手工春卷": "早餐/手工春卷.md", "手工烧麦": "早餐/手工烧麦.md", "水煮蛋": "早餐/水煮蛋.md", "牛肉盒": "早餐/牛肉盒.md", "现炸大油条": "早餐/现炸大油条.md", "现熬豆粥": "早餐/现熬豆粥.md", "白米粥": "早餐/白米粥.md", "粢饭糕": "早餐/粢饭糕.md", "花卷": "早餐/花卷.md", "茶叶蛋": "早餐/茶叶蛋.md", "荠菜鲜肉蒸饺": "早餐/荠菜鲜肉蒸饺.md", "蛋饼": "早餐/蛋饼.md", "赤豆糊元宵": "早餐/赤豆糊元宵.md", "酥皮萝卜丝馅饼": "早餐/酥皮萝卜丝馅饼.md", "饭团": "早餐/饭团.md", "馒头": "早餐/馒头.md", "香酥牛肉饼": "早餐/香酥牛肉饼.md", "鸡汁汤包": "早餐/鸡汁汤包.md", "竹荪鹿茸菇鸡汤": "汤/竹荪鹿茸菇鸡汤.md", "老鸡汤": "汤/老鸡汤.md", "肥西老母鸡汤（单品）": "汤/肥西老母鸡汤（单品）.md", "什锦蛋炒饭": "炒菜/什锦蛋炒饭.md", "农家小炒肉（玉耳）": "炒菜/农家小炒肉（玉耳）.md", "农家小炒肉（鸡蛋干）": "炒菜/农家小炒肉（鸡蛋干）.md", "剁椒木耳炒鸡蛋": "炒菜/剁椒木耳炒鸡蛋.md", "外婆菜炒鸡蛋": "炒菜/外婆菜炒鸡蛋.md", "宫保鸡丁": "炒菜/宫保鸡丁.md", "家常土豆片": "炒菜/家常土豆片.md", "家常小炒": "炒菜/家常小炒.md", "小炒河虾": "炒菜/小炒河虾.md", "小炒花菜": "炒菜/小炒花菜.md", "小炒面筋": "炒菜/小炒面筋.md", "小炒香干": "炒菜/小炒香干.md", "小炒鸡丁": "炒菜/小炒鸡丁.md", "小炒黄牛肉": "炒菜/小炒黄牛肉.md", "毛豆烧土鸡": "炒菜/毛豆烧土鸡.md", "油渣大白菜": "炒菜/油渣大白菜.md", "清炒春菜": "炒菜/清炒春菜.md", "清炒毛白菜": "炒菜/清炒毛白菜.md", "清炒油麦菜": "炒菜/清炒油麦菜.md", "清炒莴笋片": "炒菜/清炒莴笋片.md", "清炒菜心": "炒菜/清炒菜心.md", "清炒西兰花": "炒菜/清炒西兰花.md", "清炒青菜": "炒菜/清炒青菜.md", "生炒上海青": "炒菜/生炒上海青.md", "笋子烧肉": "炒菜/笋子烧肉.md", "笋子鸡丁盖饭": "炒菜/笋子鸡丁盖饭.md", "糖醋排骨": "炒菜/糖醋排骨.md", "红烧茄子": "炒菜/红烧茄子.md", "肥肠鸡": "炒菜/肥肠鸡.md", "胡萝卜炒木耳": "炒菜/胡萝卜炒木耳.md", "胡萝卜炒肉片": "炒菜/胡萝卜炒肉片.md", "胡萝卜炒鸡蛋": "炒菜/胡萝卜炒鸡蛋.md", "芋儿鸡": "炒菜/芋儿鸡.md", "芹菜炒香干": "炒菜/芹菜炒香干.md", "芹菜香干炒肉丝": "炒菜/芹菜香干炒肉丝.md", "莴笋丝炒鸡蛋": "炒菜/莴笋丝炒鸡蛋.md", "菠萝咕咾肉": "炒菜/菠萝咕咾肉.md", "菠萝咕咾肉时蔬饭": "炒菜/菠萝咕咾肉时蔬饭.md", "蒜泥菠菜": "炒菜/蒜泥菠菜.md", "蚕豆炒鸡蛋": "炒菜/蚕豆炒鸡蛋.md", "西红柿炒鸡蛋": "炒菜/西红柿炒鸡蛋.md", "贵州风味辣子鸡": "炒菜/贵州风味辣子鸡.md", "酸辣土豆丝": "炒菜/酸辣土豆丝.md", "酸辣海带丝": "炒菜/酸辣海带丝.md", "青椒炒豆芽": "炒菜/青椒炒豆芽.md", "青椒炒鸡蛋": "炒菜/青椒炒鸡蛋.md", "香椿炒鸡蛋": "炒菜/香椿炒鸡蛋.md", "鱼香肉丝": "炒菜/鱼香肉丝.md", "鱼香肉丝盖饭": "炒菜/鱼香肉丝盖饭.md", "土豆牛腩": "炖菜/土豆牛腩.md", "梅干菜凤爪翅": "炖菜/梅干菜凤爪翅.md", "白菜炖豆腐": "炖菜/白菜炖豆腐.md", "红烧鱼块": "炖菜/红烧鱼块.md", "香辣鸡杂": "炖菜/香辣鸡杂.md", "鸡血汤": "炖菜/鸡血汤.md", "麻婆豆腐": "炖菜/麻婆豆腐.md", "傲椒风味翅尖": "炸品/傲椒风味翅尖.md", "嗨嗨桶（炸物桶）": "炸品/嗨嗨桶（炸物桶）.md", "心形鸡排": "炸品/心形鸡排.md", "手枪大鸡腿": "炸品/手枪大鸡腿.md", "棒棒虾": "炸品/棒棒虾.md", "炸鸡排": "炸品/炸鸡排.md", "炸鸡腿": "炸品/炸鸡腿.md", "生炸大鸡腿": "炸品/生炸大鸡腿.md", "香脆薯饼": "炸品/香脆薯饼.md", "香芋地瓜丸": "炸品/香芋地瓜丸.md", "香酥鸡米花": "炸品/香酥鸡米花.md", "鸡肉洋葱圈": "炸品/鸡肉洋葱圈.md", "烤肠": "烤类/烤肠.md", "浇汁西兰花": "烫菜/浇汁西兰花.md", "特色热干面": "烫菜/特色热干面.md", "菠菜蛋皮丝": "烫菜/菠菜蛋皮丝.md", "葱油拌面": "烫菜/葱油拌面.md", "葱油菜心": "烫菜/葱油菜心.md", "葱油菜苔": "烫菜/葱油菜苔.md", "香脆木耳": "烫菜/香脆木耳.md", "鸡汤娃娃菜": "烫菜/鸡汤娃娃菜.md", "麻辣鸡块": "烫菜/麻辣鸡块.md", "冒烤鸭": "煮锅/冒烤鸭.md", "嗨嗨锅（泡椒鸡米花米线）": "煮锅/嗨嗨锅（泡椒鸡米花米线）.md", "嗨嗨锅（番茄肥牛锅）": "煮锅/嗨嗨锅（番茄肥牛锅）.md", "嗨嗨锅（酸菜鱼米线）": "煮锅/嗨嗨锅（酸菜鱼米线）.md", "嗨嗨锅（鲜蔬锅）": "煮锅/嗨嗨锅（鲜蔬锅）.md", "金汤酸菜鱼": "煮锅/金汤酸菜鱼.md", "金汤酸菜鱼（大份）": "煮锅/金汤酸菜鱼（大份）.md", "砂锅三鲜豆腐": "砂锅菜/砂锅三鲜豆腐.md", "砂锅原味鸡汤米线": "砂锅菜/砂锅原味鸡汤米线.md", "砂锅木瓜": "砂锅菜/砂锅木瓜.md", "砂锅泡椒鸡米花米线": "砂锅菜/砂锅泡椒鸡米花米线.md", "砂锅牛杂煲": "砂锅菜/砂锅牛杂煲.md", "砂锅番茄米线": "砂锅菜/砂锅番茄米线.md", "砂锅盐焗鸡": "砂锅菜/砂锅盐焗鸡.md", "砂锅腐竹": "砂锅菜/砂锅腐竹.md", "砂锅蒜蓉粉丝虾": "砂锅菜/砂锅蒜蓉粉丝虾.md", "砂锅酸菜鱼": "砂锅菜/砂锅酸菜鱼.md", "酸菜肥肠煲": "砂锅菜/酸菜肥肠煲.md", "三色虾仁": "蒸菜/三色虾仁.md", "农家蒸蛋": "蒸菜/农家蒸蛋.md", "凤爪蒸豆米": "蒸菜/凤爪蒸豆米.md", "剁椒鱼头": "蒸菜/剁椒鱼头.md", "奥尔良鸡翅": "蒸菜/奥尔良鸡翅.md", "松糕": "蒸菜/松糕.md", "梅菜扣肉": "蒸菜/梅菜扣肉.md", "活珠子": "蒸菜/活珠子.md", "白切鸡": "蒸菜/白切鸡.md", "秘汁卤肉饭": "蒸菜/秘汁卤肉饭.md", "竹笋蒸鸡翅": "蒸菜/竹笋蒸鸡翅.md", "粉蒸肉": "蒸菜/粉蒸肉.md", "粗粮盒": "蒸菜/粗粮盒.md", "肉饼蒸蛋": "蒸菜/肉饼蒸蛋.md", "胡萝卜牛肉": "蒸菜/胡萝卜牛肉.md", "葱油鸡": "蒸菜/葱油鸡.md", "蒜蓉娃娃菜": "蒸菜/蒜蓉娃娃菜.md", "蒜蓉粉丝虾": "蒸菜/蒜蓉粉丝虾.md", "虾仁蒸鸡蛋": "蒸菜/虾仁蒸鸡蛋.md", "蜜汁南瓜": "蒸菜/蜜汁南瓜.md", "酱椒蒜香片片鱼": "蒸菜/酱椒蒜香片片鱼.md", "酱蒸白干": "蒸菜/酱蒸白干.md", "酱蒸豆腐": "蒸菜/酱蒸豆腐.md", "酱香小河虾": "蒸菜/酱香小河虾.md", "风干牛肉蒸白干": "蒸菜/风干牛肉蒸白干.md", "香肠蒸豆米": "蒸菜/香肠蒸豆米.md", "香芋蒸排骨": "蒸菜/香芋蒸排骨.md", "香辣血旺": "蒸菜/香辣血旺.md", "鸡汁辣鱼": "蒸菜/鸡汁辣鱼.md", "三鲜豆腐汤料": "配料/三鲜豆腐汤料.md", "剁椒酱": "配料/剁椒酱.md", "剁椒鱼头料": "配料/剁椒鱼头料.md", "家常小炒料": "配料/家常小炒料.md", "小炒肉调味汁": "配料/小炒肉调味汁.md", "小炒肉调料": "配料/小炒肉调料.md", "油焖茄子料": "配料/油焖茄子料.md", "炒菜基料": "配料/炒菜基料.md", "肥肠鸡酱料": "配料/肥肠鸡酱料.md", "血旺料": "配料/血旺料.md", "调味料（小炒鸡丁）": "配料/调味料（小炒鸡丁）.md", "酱蒸白干料": "配料/酱蒸白干料.md", "风干牛肉酱料": "配料/风干牛肉酱料.md", "鸡杂料": "配料/鸡杂料.md", "鸡汁辣鱼料": "配料/鸡汁辣鱼料.md", "鸡油料": "配料/鸡油料.md", "鸡翅调料": "配料/鸡翅调料.md", "麻婆豆腐料": "配料/麻婆豆腐料.md", "原味豆浆": "饮品/原味豆浆.md", "热奶茶": "饮品/热奶茶.md", "苹果山楂红茶": "饮品/苹果山楂红茶.md", "鸡笼香柠檬茶": "饮品/鸡笼香柠檬茶.md"}

path: scripts/search_recipe.py
content: import sys
import json
import urllib.request
import urllib.parse
from difflib import get_close_matches

import os
import time

TREE_API_URL = "https://api.github.com/repos/Gar-b-age/CookLikeHOC/git/trees/main?recursive=1"
# 使用 jsDelivr 官方 CDN 替换原版 raw.githubusercontent.com 
# 以保障中国大陆等网络较差情况的直连获取速度稳定
RAW_BASE_URL = "https://fastly.jsdelivr.net/gh/Gar-b-age/CookLikeHOC@main/"
CACHE_FILE = os.path.join(os.path.dirname(__file__), "recipe_tree_cache.json")

def fetch_file_list():
    try:
        # Check cache first (valid for 24 hours)
        if os.path.exists(CACHE_FILE):
            if time.time() - os.path.getmtime(CACHE_FILE) < 86400:
                with open(CACHE_FILE, 'r', encoding='utf-8') as f:
                    data = json.load(f)
                    return data
                    
        req = urllib.request.Request(TREE_API_URL)
        req.add_header('User-Agent', 'Mozilla/5.0')
        # Add optional Github token if available in env to increase limits
        if os.environ.get('GITHUB_TOKEN'):
            req.add_header('Authorization', f"token {os.environ.get('GITHUB_TOKEN')}")
            
        with urllib.request.urlopen(req) as response:
            data = json.loads(response.read().decode('utf-8'))
            
        recipes = {}
        for item in data.get('tree', []):
            path = item.get('path', '')
            if path.endswith('.md') and '/' in path and 'README.md' not in path:
                filename = path.split('/')[-1]
                recipe_name = filename.replace('.md', '')
                recipes[recipe_name] = path
                
        # Save to cache
        with open(CACHE_FILE, 'w', encoding='utf-8') as f:
            json.dump(recipes, f, ensure_ascii=False)
            
        return recipes
    except Exception as e:
        # If API fails and we have a stale cache, use it anyway
        if os.path.exists(CACHE_FILE):
            with open(CACHE_FILE, 'r', encoding='utf-8') as f:
                return json.load(f)
        print(f"Error fetching recipe list: {e}")
        return {}

def fetch_recipe_content(path):
    url = RAW_BASE_URL + urllib.parse.quote(path)
    try:
        req = urllib.request.Request(url)
        req.add_header('User-Agent', 'Mozilla/5.0')
        with urllib.request.urlopen(req) as response:
            return response.read().decode('utf-8')
    except Exception as e:
        return f"Error fetching recipe content: {e}"

def main():
    if len(sys.argv) < 2:
        print("Usage: python search_recipe.py <recipe_name>")
        sys.exit(1)
        
    query = sys.argv[1].strip()
    
    # 1. Fetch available recipes
    recipes = fetch_file_list()
    if not recipes:
        print("Failed to retrieve the recipe database or it is empty.")
        sys.exit(1)
        
    recipe_names = list(recipes.keys())
    
    # 2. Match the query
    if query in recipes:
        best_match = query
    else:
        # Fuzzy match
        matches = get_close_matches(query, recipe_names, n=1, cutoff=0.3)
        if matches:
            best_match = matches[0]
            print(f"[{query}] not found, but found a similar recipe: [{best_match}]\n")
        else:
            print(f"Could not find any recipe matching '{query}'.")
            
            # Print a few examples
            print("Available examples:")
            for i, name in enumerate(recipe_names[:10]):
                print(f" - {name}")
            sys.exit(1)
            
    # 3. Fetch content
    path = recipes[best_match]
    print(f"=== {best_match} ===")
    content = fetch_recipe_content(path)
    print(content)

if __name__ == "__main__":
    main()


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)