Improve first-run and channel setup for non-technical users: detect newer Gemini key formats, pin Node 22.22.3, add Control Panel Telegram approve flow, and keep channels/models when config is rewritten. Persist uclaw wizard state via uclaw-meta.json so restarts skip language/persona prompts. Co-authored-by: Cursor <cursoragent@cursor.com>
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-id>/SKILL.md
manifest.json
{
"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.
node lib/install-skills.mjs --target <dir> [--locale en] [--persona general] [--dry-run] [--list]
It resolves content in this order:
skills/next to the script (repo checkout and USB builds)--source <dir>if given- Download from GitHub at the pinned ref (one-line remote installers, which have no repo on disk)
Adding a skill
- Create
skills/en/<id>/SKILL.mdwith the standard front matter - Add an entry to
manifest.jsonwithstatus: "shipping" - Run
node --test tests/—tests/skills-manifest.test.mjschecks 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.