# Skills Single source of truth for skill content and distribution. ## Why this directory exists Skill content used to be inlined as heredocs inside `install/install.sh` and as here-strings inside `install/install.ps1`, with a third copy on disk under `portable/skills-cn/`. The three drifted: | Source | Skills | Typical length | |---|---|---| | `portable/skills-cn/` | 17 | full | | `install/install.sh` | 10 | ~40% of full | | `install/install.ps1` | 10 | ~17% of full | Seven skills (`excel-helper`, `word-writer`, `ppt-designer`, `pdf-toolkit`, `image-compress`, `qrcode-maker`, `web-to-markdown`) existed **only** on the USB build — anyone who used the one-line installer never got them. `tests/windows-launchers.test.mjs` also requires customer-facing `.bat` launchers to be pure ASCII, because Chinese Windows `cmd.exe` reads non-ASCII bytes as GBK and mis-parses the script. That constraint is what pushed the `.ps1` copies into being truncated in the first place. Separating content from distribution removes all of this: the installers carry no skill text at all. ## Layout ``` skills/ manifest.json # the only thing installers read en/ /SKILL.md ``` ## manifest.json ```jsonc { "schemaVersion": 1, "personas": [ { "id": "developer", "tier": "expert" }, ... ], "skills": [ { "id": "excel-helper", "status": "shipping", // "shipping" | "planned" "locales": ["en"], // which locales have a SKILL.md on disk "categories": ["office"], "personas": ["admin", "finance"], "emoji": "📊" } ] } ``` `status: "planned"` entries have no content yet. They are listed so the roadmap lives next to the code — installers skip them. `replaces` records which retired skill an entry supersedes. ## Installing `lib/install-skills.mjs` is the only installer. It reads the manifest, filters by locale and persona, and writes to the target directory. ```bash node lib/install-skills.mjs --target [--locale en] [--persona general] [--dry-run] [--list] ``` It resolves content in this order: 1. `skills/` next to the script (repo checkout and USB builds) 2. `--source ` if given 3. Download from GitHub at the pinned ref (one-line remote installers, which have no repo on disk) ## Adding a skill 1. Create `skills/en//SKILL.md` with the standard front matter 2. Add an entry to `manifest.json` with `status: "shipping"` 3. Run `node --test tests/` — `tests/skills-manifest.test.mjs` checks that every shipping skill has content, that front matter matches the manifest, and that the shell and PowerShell installers agree on the resulting skill list Do not add skill text to any `.sh`, `.ps1` or `.bat` file. The parity test fails if the two installers disagree, and the ASCII test fails if non-ASCII ends up in a `.bat`.