Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,14 @@ git clone https://github.com/perkfly/ex-skill ~/.claude/skills/create-ex
git clone https://github.com/perkfly/ex-skill ~/.openclaw/workspace/skills/create-ex
```

### 依赖(可选)
### 依赖

```bash
pip3 install -r requirements.txt
```

> ⚠️ 使用**中文昵称**时 `pypinyin` 为必需依赖:未安装时无法从中文昵称生成 slug,工具会明确报错并提示。仅使用英文昵称可跳过安装。

---

## 使用
Expand Down
4 changes: 3 additions & 1 deletion README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,14 @@ git clone https://github.com/perkfly/ex-skill .claude/skills/create-ex
git clone https://github.com/perkfly/ex-skill ~/.claude/skills/create-ex
```

### Dependencies (optional)
### Dependencies

```bash
pip3 install -r requirements.txt
```

> ⚠️ `pypinyin` is **required for Chinese nicknames** — without it no slug can be generated from a Chinese name (the tool fails with a clear error instead of silently colliding). Optional if you only use ASCII nicknames.

---

## Usage
Expand Down
4 changes: 4 additions & 0 deletions SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ Persona 摘要:

用户确认后,执行以下写入操作:

**0. 检查 slug 冲突**:若 `exes/{slug}` 目录已存在,**停止写入**,询问用户是换一个 slug 还是确认覆盖(覆盖前先用 `version_manager.py --action backup` 存档)。不要静默覆盖已有前任的数据。

**1. 创建目录结构**(用 Bash):
```bash
mkdir -p exes/{slug}/versions
Expand Down Expand Up @@ -551,6 +553,8 @@ Confirm generation? Or need adjustments?

After user confirmation, execute the following:

**0. Check for slug collision**: if `exes/{slug}` already exists, **stop** and ask the user to pick a different slug or explicitly confirm overwriting (archive first via `version_manager.py --action backup`). Never silently overwrite an existing ex.

**1. Create directory structure** (Bash):
```bash
mkdir -p exes/{slug}/versions
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Optional: Chinese name → slug conversion
# Required for Chinese nicknames (slug generation); optional for ASCII-only names
# 中文昵称必需(用于生成 slug);纯英文昵称可不装
pypinyin>=0.48.0

# Optional: Better EXIF support for more image formats (HEIC, TIFF, etc.)
Expand Down
26 changes: 22 additions & 4 deletions tools/skill_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ def slugify(name: str) -> str:
"""
将姓名转为 slug。
优先尝试 pypinyin(如已安装),否则 fallback 到简单处理。
无法生成有效 slug 时返回空字符串(例如:中文昵称 + 未安装 pypinyin),
由调用方决定如何处理,避免不同昵称静默撞车。
"""
try:
from pypinyin import lazy_pinyin
Expand All @@ -86,7 +88,7 @@ def slugify(name: str) -> str:

import re
slug = re.sub(r"_+", "_", slug).strip("_")
return slug if slug else "ex"
return slug


def build_identity_string(meta: dict) -> str:
Expand Down Expand Up @@ -125,9 +127,14 @@ def create_skill(
memories_content: str,
persona_content: str,
) -> Path:
"""创建新的前任 Skill 目录结构"""
"""创建新的前任 Skill 目录结构。目标目录已存在时抛出 FileExistsError,防止静默覆盖。"""

skill_dir = base_dir / slug
if skill_dir.exists():
raise FileExistsError(
f"{skill_dir} 已存在。请换一个 slug,"
f"或先用 version_manager.py 存档/手动备份后再删除,避免静默覆盖导致数据丢失"
)
skill_dir.mkdir(parents=True, exist_ok=True)

# 创建子目录
Expand Down Expand Up @@ -343,7 +350,14 @@ def main() -> None:
if args.name:
meta["name"] = args.name

slug = args.slug or slugify(meta.get("name", "ex"))
slug = args.slug or slugify(meta.get("name", ""))
if not slug:
print(
"错误:无法从昵称生成 slug(中文昵称需要安装 pypinyin:pip3 install pypinyin),"
"或请显式传入 --slug",
file=sys.stderr,
)
sys.exit(1)

memories_content = ""
if args.memories:
Expand All @@ -353,7 +367,11 @@ def main() -> None:
if args.persona:
persona_content = Path(args.persona).read_text(encoding="utf-8")

skill_dir = create_skill(base_dir, slug, meta, memories_content, persona_content)
try:
skill_dir = create_skill(base_dir, slug, meta, memories_content, persona_content)
except FileExistsError as e:
print(f"错误:{e}", file=sys.stderr)
sys.exit(1)
print(f"✅ Skill 已创建:{skill_dir}")
print(f" 触发词:/{slug}")

Expand Down