Skip to content

Installing Skills

The Taskless CLI installs a single consolidated skill into each detected tool directory in your repository. At a terminal, run the CLI with no subcommand in your project root:

Terminal window
npx @taskless/cli

That is the wizard: it detects the installed tools, asks which to enable, offers a login you can skip, shows a diff against the previous install, and writes the files. init is the same install without the questions, for agents, scripts, and CI, and it is also the upgrade path once a project is set up:

Terminal window
npx @taskless/cli init

init needs no account and no TTY, migrates the .taskless/ layout when the project is behind the CLI, and rewrites nothing whose bytes already match. It ends by naming the directories that changed. After a CLI version move it points at update, which is not an installer: it tells you what the upgrade changed for the rules already in the project, and update --rules records that you walked it.

The CLI treats every supported tool as a peer install target. If the corresponding directory exists in your repo, the wizard pre-checks it.

Tool Directory Slash command
Claude Code .claude/ /tskl
Cursor .cursor/ /tskl
OpenCode .opencode/ (skill only)
.agents/-aware .agents/ (skill only)

Any agent that supports the Agent Skills specification can also install Taskless directly from the GitHub repository using its own installer (agentskills.io, skills.sh, DotAgents, and so on).

Skill and command content is written once into .taskless/, the Taskless-owned directory in your repo. Each selected tool directory gets a thin reference stub that delegates to the canonical file.

your-repo/
├── .taskless/ ◀── canonical (single source of truth)
│ ├── skills/taskless/SKILL.md
│ └── commands/tskl/tskl.md
├── .claude/skills/taskless/SKILL.md ── stub → .taskless/skills/taskless/SKILL.md
├── .claude/commands/tskl/tskl.md ── stub → .taskless/commands/tskl/tskl.md
├── .cursor/skills/taskless/SKILL.md ── stub
├── .cursor/commands/tskl/tskl.md ── stub
├── .opencode/skills/taskless/SKILL.md ── stub
└── .agents/skills/taskless/SKILL.md ── stub

Stubs are ordinary files with valid frontmatter and a body that points at the canonical file. There are no symlinks; symlink discovery is unreliable across these tools and fragile on Windows. The install manifest at .taskless/taskless.json tracks each target’s mode (canonical or reference) so update rewrites canonical content only and never overwrites a stub with a full copy.

A few consequences:

  • Editing the canonical file once changes what every tool sees, so there are no N identical copies to drift.
  • update won’t blow away a tool directory another target sources from.
  • init is idempotent. On the first re-run after upgrading from an older Taskless version, it removes any obsolete skill files left behind by the previous install layout.

Re-run init when a new CLI version ships with updated skill content:

Terminal window
npx @taskless/cli init

Then run update and follow it. The install migrated the directory; the rules in it may still need work no migration can do for them (a rewriter that now needs a fix, a rule whose matching semantics shifted under a new engine version). update walks those changes from the version the project was last reconciled to, and update --rules stamps the walk as done:

Terminal window
npx @taskless/cli update
npx @taskless/cli update --rules

The installed stubs always point at .taskless/, so the running CLI version is what determines the skill content your agent sees. A tool loads its skill list once at startup, so a session that ran the install holds the previous skill text until it is reloaded.

If your agent doesn’t seem to be picking up Taskless:

  1. Run npx @taskless/cli info to confirm the CLI is installed and which tools it detected.
  2. Check that .taskless/rules/ contains per-engine directories (sg/, vale/, runtime/) with a rule directory inside one of them.
  3. Verify the tool’s skill directory (e.g., .claude/skills/taskless/) contains a stub SKILL.md.
  4. Verify that your agent’s config directory and .taskless/ are not in your .gitignore.