tss-skills
v0.4.0
Published
CLI to install/list/search/update/remove skills from the TSS skill registry.
Downloads
221
Maintainers
Readme
tss-skills
CLI for installing skills from the tss-skills registry into Claude Code (.claude/skills/) and/or Codex (.agents/skills/). Distributed via npm; run via npx without a global install.
npx tss-skills <command>Install a skill
Three target modes — pick whichever fits the run.
# Default: install into the current folder under .claude/skills/<slug>/
npx tss-skills install <slug>
# Install globally into ~/.claude/skills/<slug>/ (v0.1.x behaviour)
npx tss-skills install <slug> --global # or -g
# Install into an arbitrary directory; resolves to <dir>/<slug>/
npx tss-skills install <slug> --target ~/skills-stash
# Install for Codex (https://developers.openai.com/codex/skills)
# project → ./.agents/skills/<slug>, global → ~/.agents/skills/<slug>
npx tss-skills install <slug> --agent codex
npx tss-skills install <slug> --agent codex --global
# Install for both agents: one canonical copy in .agents/skills,
# .claude/skills/<slug> becomes a symlink to it.
npx tss-skills install <slug> --agent both
# Both mode, explicit link strategy:
# symlink (default) — .claude/skills/<slug> is a symlink to the .agents copy
# copy — two independent copies (may drift on update)
npx tss-skills install <slug> --agent both --link-mode symlink
npx tss-skills install <slug> --agent both --link-mode copyWithout --agent, the CLI defaults to Claude Code. When neither --global nor --target is passed:
- In an interactive terminal (stdin+stderr TTY, not CI): the CLI shows up to three sequential prompts (unless the corresponding flag is provided):
Install for which agent?— choices:Claude Code(default),Codex,Both (Claude Code + Codex)Install to:— choices: project (default), globalHow should the Claude Code copy be created?— choices:symlink(default),duplicate— only shown when agent is Both
- Non-interactive (stdin or stderr not a TTY, or CI=true): the CLI picks Claude Code + project-local without prompting and writes a
note:line to stderr.
--agent both is mutually exclusive with --target (since both implies a single canonical location in .agents/skills).
--global and --target are mutually exclusive.
--force (-f) overwrites an existing target in any of the three modes.
The final absolute install path is echoed to stdout as the canonical scriptable line:
installed <slug>@<sha12> to <abs-path> (<N> files)In --agent both mode, the line gains a (+N link) suffix showing the number of symlinks or copies created — for example, installed <slug>@<sha12> to <abs-path> (<N> files) (+1 link).
If a symlink cannot be created (e.g. Windows without developer mode), the CLI will emit a warn: message to stderr suggesting you re-run with --link-mode copy to install an independent duplicate instead of auto-copying silently.
Diagnostics (target:, note:, warn:) go to stderr.
Other commands
| Command | Status | Summary |
| --- | --- | --- |
| install | live | Install a skill (see above) |
| add | live | Alias of install |
| list | live | List skills in the registry |
| search | live | Search the skill registry |
| update | stub | Update an installed skill |
| remove | stub | Remove an installed skill |
Options
--help,-h— print usage and exit 0--version,-v— print version and exit 0
Install-only flags:
--agent <name>— target agent:claude(default),codex, orbothclaude→ install to./.claude/skills/<slug>(project) or~/.claude/skills/<slug>(global)codex→ install to./.agents/skills/<slug>(project) or~/.agents/skills/<slug>(global); compatible with--target(custom root wins)both→ installs to.agents/skills/<slug>(canonical) and links.claude/skills/<slug>; mutually exclusive with--target
--link-mode <m>— with--agent both:symlink(default —.claude/skills/<slug>is a symlink to the canonical copy) orcopy(two independent copies; may drift on update). On TTY without--link-modeand--agent both, the CLI prompts after the scope selector.-g,--global— install to the global agent-specific location (see--agent)--target <dir>— install to<dir>/<slug>(~expanded; mutually exclusive with--globaland--agent both)-f,--force— overwrite existing target--api <url>— override registry API base URL (defaults to the URL baked into the build; see Registry URL)
Registry URL
The CLI ships with a registry URL baked into the bundle at build time, so end users do not need to pass --api or set any environment variable to install skills.
- Default (npm-published bundle):
https://api.skills.totalspecificsolutions.ai - Per-build override (build time): set
AI_LAB_SKILLS_BUILD_TARGET=<url>beforepnpm --filter tss-skills buildto bake a different URL intodist/index.mjs. Used by CI to produce dev/staging bundles. - Per-invocation override (runtime): set
AI_LAB_SKILLS_API_URL=<url>or pass--api <url>to override the baked default for a single command. Useful for local development against a non-prod registry.
Override precedence (highest first): --api flag → AI_LAB_SKILLS_API_URL env → baked __API_BASE__.
Exit codes
| Code | Meaning |
| --- | --- |
| 0 | success |
| 1 | user error (bad args, target exists without --force) |
| 2 | network (DNS / timeout / connection) |
| 3 | server (5xx response) |
| 4 | integrity (SHA mismatch / tar safety reject) |
Environment
AI_LAB_SKILLS_API_URL— override the baked registry URL at runtime (single invocation).AI_LAB_SKILLS_BUILD_TARGET— set at build time to bake a different registry URL intodist/index.mjs. Only relevant when runningpnpm buildyourself.
Develop
pnpm --filter tss-skills build # bundle to dist/index.mjs
pnpm --filter tss-skills test # vitest
pnpm --filter tss-skills lint # eslint
pnpm --filter tss-skills typecheck # tsc --noEmit
node apps/cli/dist/index.mjs --version