From 0a7313d223cffbfe4f7afe773ac6c9fc1d327070 Mon Sep 17 00:00:00 2001 From: Jakob Heuser Date: Fri, 30 Oct 2026 08:47:35 -0700 Subject: [PATCH] docs: rewrite the root README around getting started and the repo's three parts Lead with what Taskless is and the docs.taskless.io quick start, then describe what the repo holds: the CLI, the Vale platform packages, and the canonical Taskless skill. Replace the stale manual release steps with the automated Changesets + OIDC flow, and drop init from the human path. --- README.md | 203 +++++++++++++++++++++++++++++------------------------- 1 file changed, 110 insertions(+), 93 deletions(-) diff --git a/README.md b/README.md index 15448fe3..6c4d1bfc 100644 --- a/README.md +++ b/README.md @@ -1,138 +1,155 @@ -# Taskless Skills +# Taskless -A skills repository for agentic workflows, built for [Claude Code](https://docs.anthropic.com/en/docs/claude-code) and other Agent capable systems. +Taskless turns the corrections you give your coding agent into rules that run on every change. Correct once. Enforced forever. -Includes a CLI that works with agentic systems (and humans too) at @taskless/cli. +## What Taskless is -## Structure +When you correct your coding agent, Taskless captures that correction as a rule: a real file in your repo, enforced by [ast-grep](https://ast-grep.github.io), [Vale](https://vale.sh), or a runtime check. The same rules run in your editor, for every agent, and in CI, with one command and one exit code. You can start without an account. +## Get started + +**1. Install the skill.** In a repository with a coding agent configured (a `.claude/`, `.cursor/`, `.opencode/`, or `.agents/` directory), run the installer: + +```bash +npx @taskless/cli ``` -skills/ - taskless/SKILL.md # Single consolidated router skill -packages/ - cli/ # @taskless/cli, recipes live in cli/src/agent/ -scripts/ - sync-skill-versions.ts # Syncs metadata.version to CLI version -.claude-plugin/ # Claude Code Plugin Marketplace manifest -``` -## Skill +It detects your agent tools and installs the Taskless skill into each of them. `pnpm dlx`, `bun x`, and `yarn dlx` work too. + +**2. Get onboarded.** Ask your agent to help you get started with Taskless. It reviews your codebase and history and helps you turn the strongest candidates into rules. -Taskless ships a **single consolidated skill** (`taskless`). The skill body is a small router; per-task instructions live behind `./.taskless/bin/cli.mjs agent ` (the project launcher `init` writes) and are fetched on demand. It handles any Taskless action (create rule, improve, delete, check, auth, CI) by fetching the canonical recipe for the user's intent and following it. +**3. Create a rule.** Describe it in plain language: -Available `taskless agent` topics: `route`, `create-sg-rule`, `create-vale-rule`, `create-runtime-rule`, `create-remote-rule`, `improve-rule`, `delete-rule`, `check`, `auth`, `ci`, `info`, `init`, `update`. Run `taskless agent` with no topic for the index. Append `--anonymous` for the local-only flow on improve. +> Create a taskless rule that catches direct fetch() calls without error handling. -## CLI +Rules are authored and validated locally, with no account and no API calls. Your agent tells you before it uses the Taskless service. -The `@taskless/cli` package provides a CLI agent for Taskless workflows. Install or upgrade a project with the `latest` tag: +**4. Check your code.** Ask your agent to run taskless check, or run it yourself through the project launcher the installer writes: ```bash -npx @taskless/cli@latest init +./.taskless/bin/cli.mjs check ``` -That records the CLI version in `.taskless/taskless.json` and writes a launcher that runs exactly that version. Every other command goes through the launcher, since any other version of the CLI refuses to run in the project: +Matches are reported with file, line, severity, and message. The command exits `1` on error-severity matches, so it drops straight into CI. Ask your agent to "add taskless to CI" to wire it into the CI system you already use. -```bash -./.taskless/bin/cli.mjs info -``` +A free [Taskless account](https://docs.taskless.io/getting-started/full-setup/) adds AI-powered rule generation with validation and test cases, plus a GitHub integration that turns PR comments and issues into rules. See the [Taskless docs](https://docs.taskless.io/getting-started/) for the full guide, including tips for writing better rules. -## Local development +## What's in this repository -The CLI bakes its own invocation string into the skill, command, and recipe -content it installs. Build targets pick that string, all driven by the -`TASKLESS_BUILD_TARGET` env var via Vite `define` (same source files, no edits): +This repository is the source for three things that ship together: -Each target also emits to its own directory so they never overwrite one another. -Prod → `dist/`, self → `dist-self/` (both gitignored): +1. **The Taskless CLI**, published to npm as [`@taskless/cli`](https://www.npmjs.com/package/@taskless/cli). +2. **The Vale platform packages**, `@taskless/vale-*`: the [Vale](https://vale.sh) executable for each supported OS and CPU, wrapped in an npm package so the CLI can run it with no download step. +3. **The canonical Taskless skill**, the `SKILL.md` that agents (Claude Code and others) load to work with Taskless, plus the recipes it routes to. -| Command | Output dir | Baked invocation | Use for | -| ----------------- | ------------ | -------------------------------------- | ------------------------------------------------------------------------------------ | -| `pnpm build` | `dist/` | `npx @taskless/cli` | Production / published builds (default). | -| `pnpm build:self` | `dist-self/` | `node packages/cli/dist-self/index.js` | Dogfooding **in this repo** (path is repo-root-relative; run the CLI from the root). | +All of them publish from GitHub Actions through npm trusted publishing (OIDC). No npm token is stored anywhere in this repository. -`pnpm build:self` builds the CLI with the relative invocation and then runs -`taskless init --no-interactive` to install into this repo, so `.claude` gets -real reference stubs that delegate to the canonical `.taskless/` content, exactly -like any other install. (This replaces the former raw-symlink `link-skills` -step, so local dogfooding always matches a true install.) +``` +packages/ + cli/ # @taskless/cli + src/agent/ # recipes served by `taskless agent ` + vale--/ # @taskless/vale-* platform packages (six of them) +skills/ + taskless/SKILL.md # the canonical Taskless skill +.claude-plugin/ # Claude Code Plugin Marketplace manifest +.github/ + scripts/vale-manifest.json # pinned Vale release and its SHA256 digests + workflows/ # release, nightly, Vale, and validation pipelines +scripts/ # version, changelog, and skill-metadata helpers +openspec/ # specs and in-flight change proposals +``` -> The `self` invocation is a local path and must never be published: only -> `pnpm build` (or `pnpm package`) produces a release artifact. It is also -> relative to this repo root, so no build target here yields a CLI you can run -> from another repository. That case is served by a published nightly. +## 1. The Taskless CLI -### Running the local build +`@taskless/cli` creates, checks, and manages Taskless rules in a project, for agents and for people. The installer pins the CLI version in `.taskless/taskless.json` and writes a launcher, `./.taskless/bin/cli.mjs`, that runs exactly that version. Run every command through the launcher. Any other CLI version refuses to run in the project. -The root `package.json` defines a `cli` script pointing at -`./packages/cli/dist/index.js`. That script runs the CLI built from this working -tree instead of a published release, which is what `AGENTS.md` points -contributors and agents at while they are working in this repo. Nothing rebuilds -`dist/` for you, so run `pnpm build` first when you want current behavior. +See [`packages/cli/README.md`](./packages/cli/README.md) for the full command reference. -This section names the script rather than spelling out its shell invocation, because -the `docs-npx-cli` rule keeps the local script out of every README, which is read -by people who do not have this repo checked out. The same rule allows npx and -`pnpm dlx` only to install or upgrade, and sends every other command through the -project launcher. +### Releases -## Releasing taskless/cli +Releases are automated with [Changesets](https://github.com/changesets/changesets): -Releases use [Changesets](https://github.com/changesets/changesets) with Turborepo for orchestration. +1. A pull request that changes the CLI adds a changeset (`pnpm changeset`). +2. On merge to `main`, `release-cli-changeset.yml` maintains a **Version Packages** pull request that folds pending changesets into the version and `CHANGELOG.md`. +3. Merging that pull request triggers `release-cli.yml`, which publishes `@taskless/cli` with provenance over OIDC and tags the released commit (`vX.Y.Z`). -### Release process +Tagging started at `v0.9.0`; earlier releases weren't tagged. -Start from a clean repo (no uncommitted changes), then: +### Nightly builds + +Everything merged to `main` publishes as **`@taskless/cli-nightly`**, so you can try unreleased changes without waiting for a release: ```bash -pnpm bump # Bump versions and sync skill metadata -pnpm build # Build CLI and generate commands -pnpm test # Run all tests, confirm no errors -git add -A # Stage all changes -git commit -m "chore: Releases vx.y.z" # Commit with new version number -git push origin main # Push the release commit -pnpm release # Dry run, prints publish command when ready -pnpm release:production # Publish to npm (prompts for 2FA OTP) +npx @taskless/cli-nightly@latest --version ``` -After publishing, tag the release commit so the published version is traceable -in git history: +The nightly's executable is also `taskless`, so it replaces the release when installed. Installing both globally collides on that binary, so install one or the other. -```bash -git tag -s vx.y.z -m "Release vx.y.z" # Signed tag on the release commit -git push origin vx.y.z -``` +See [CONTRIBUTING.md](./CONTRIBUTING.md) for how nightlies are versioned and published, and for how to test against one without disturbing a release you already have installed. -Tagging started at `v0.9.0`; earlier releases were not tagged. +## 2. The Vale platform packages -### Nightly builds +Taskless runs prose rules with [Vale](https://vale.sh). The CLI lists one npm package per platform as an optional dependency, and the package manager installs only the one matching the host. Nothing downloads at install time. -Work that has merged to `main` but is not yet released is published as -**`@taskless/cli-nightly`**, so unreleased behavior can be installed and -exercised without waiting for a release: +| Package | Platform | +| ----------------------------- | -------------------- | +| `@taskless/vale-darwin-arm64` | macOS, Apple silicon | +| `@taskless/vale-darwin-x64` | macOS, Intel | +| `@taskless/vale-linux-arm64` | Linux, 64-bit ARM | +| `@taskless/vale-linux-x64` | Linux, x86-64 | +| `@taskless/vale-win32-arm64` | Windows, 64-bit ARM | +| `@taskless/vale-win32-x64` | Windows, x86-64 | -```bash -npx @taskless/cli-nightly@latest --version -``` +Each package holds the upstream `vale` binary, its MIT `LICENSE`, a README, and `package.json`. It has no JavaScript and no install script, so it works under package managers that refuse dependency build scripts. + +The binaries aren't committed. The pipeline works in two halves: + +- **`release-vale.yml`** watches upstream Vale releases. When one appears it opens a pull request that pins the new version and its six archive digests in `.github/scripts/vale-manifest.json`. After a person reviews and merges it, the workflow downloads each archive, verifies it against the committed digest, and publishes the packages over OIDC as `-`. +- **`vale-upgrade.yml`** moves the CLI's pins onto the newly published set, as a separate pull request. + +The Vale packages are versioned outside Changesets, and publishing them changes nothing for a CLI user until the CLI's pins move. Each package's README covers versioning and provenance in detail. -The executable is `taskless`, the same as the release, so a nightly is a drop-in -for the release it anticipates rather than a companion to it. Installing both -globally collides on that binary and is not supported. +## 3. The Taskless skill -See [CONTRIBUTING.md](./CONTRIBUTING.md) for how nightlies are versioned and -published, and for how to test against one without disturbing a release you -already have installed. +[`skills/taskless/SKILL.md`](./skills/taskless/SKILL.md) is the canonical Taskless agent skill. It's a small router. For any Taskless action (create, improve, or delete a rule, run checks, authenticate, wire CI), it fetches the matching recipe with `taskless agent ` and follows it. `taskless agent` with no topic lists every topic. + +The recipes themselves live in [`packages/cli/src/agent/`](./packages/cli/src/agent/) and are embedded into the CLI bundle at build time, so a recipe always matches the CLI version that serves it. + +The skill reaches agents through these channels: + +- **The installer** (`npx @taskless/cli`) installs the skill to `.taskless/skills/taskless/` and a reference stub in each harness's skill directory, such as `.claude/skills/taskless/`. +- **Claude Code Plugin Marketplace** reads `.claude-plugin/marketplace.json` and `plugin.json`. +- **Vercel Skills CLI** (`npx skills add`) discovers skills from the `skills/` directory. + +The skill's `metadata.version` tracks the CLI version. `pnpm bump` syncs it, and the CLI build fails if the two disagree. ### Adding a new topic recipe -In v0.7+, new agent-facing instructions are added as **recipes**, not skills. To add a recipe: +Agent-facing instructions are **recipes** served by the one skill. To add a topic: + +1. Create `packages/cli/src/agent/.md` following the template the existing recipes use (Goal / Preconditions / Steps / Input schema / Errors / See Also). +2. For a topic with a substantively different local-only flow, add `.anonymous.md`. The `agent` command looks up the variant automatically. +3. Update the topic table in `skills/taskless/SKILL.md` so agents can discover the new topic. + +## Local development + +See [CONTRIBUTING.md](./CONTRIBUTING.md) for setup, checks, and the pull request process. + +The CLI bakes its own invocation string into the skill, command, and recipe content it installs. The build target picks that string through the `TASKLESS_BUILD_TARGET` env var and Vite `define`, from the same source files. Each target writes to its own gitignored directory, so the builds never overwrite each other: + +| Command | Output dir | Baked invocation | Use for | +| ----------------- | ------------ | -------------------------------------- | ------------------------------------------------------------------------------------ | +| `pnpm build` | `dist/` | `npx @taskless/cli` | Production / published builds (default). | +| `pnpm build:self` | `dist-self/` | `node packages/cli/dist-self/index.js` | Dogfooding **in this repo** (path is repo-root-relative; run the CLI from the root). | + +`pnpm build:self` builds the CLI with the relative invocation and then runs `taskless init --no-interactive` to install into this repo, so `.claude` gets real reference stubs that delegate to the canonical `.taskless/` content, exactly like any other install. + +> The `self` invocation is a local path and must never be published: only `pnpm build` produces a release artifact. It's also relative to this repo root, so no build target here yields a CLI you can run from another repository. Use a published nightly for that. + +### Running the local build -1. Create `packages/cli/src/agent/.txt` following the canonical template (Goal / Preconditions / Steps / Input schema / Errors / See Also). -2. Use `{{CLI_VERSION}}` and `{{INPUT_SCHEMA}}` placeholders for runtime interpolation. -3. For topics with a substantively different local-only flow, add `.anonymous.txt`. The `agent` command's variant lookup is automatic. -4. Update the topic table in `skills/taskless/SKILL.md` so agents can discover the new topic. +The root `package.json` defines a `cli` script pointing at `./packages/cli/dist/index.js`. That script runs the CLI built from this working tree instead of a published release, which is what `AGENTS.md` points contributors and agents at while they're working in this repo. Nothing rebuilds `dist/` for you, so run `pnpm build` first when you want current behavior. -### Distribution channels +## License -- **`taskless init`**: CLI installs the consolidated skill to `.taskless/skills/taskless/` and a reference stub to `.claude/skills/taskless/` -- **Claude Code Plugin Marketplace**: `.claude-plugin/marketplace.json` and `plugin.json` -- **Vercel Skills CLI**: `npx skills add` discovers skills from `skills/` directory +MIT. See [LICENSE](./LICENSE). The Vale binaries carry Vale's own MIT license, shipped unmodified in each platform package.