chore: version packages - #74
Open
github-actions[bot] wants to merge 1 commit into
Open
Conversation
github-actions
Bot
force-pushed
the
changeset-release/main
branch
7 times, most recently
from
August 4, 2026 15:08
6083aac to
28c11bf
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
15 times, most recently
from
August 12, 2026 02:45
8d07d51 to
850c944
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
8 times, most recently
from
August 20, 2026 22:57
b263ba8 to
60a7925
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
5 times, most recently
from
August 21, 2026 00:24
1320dd7 to
6941b6e
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
from
August 21, 2026 02:52
6941b6e to
fd18682
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and publish to npm yourself or setup this action to publish automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@taskless/cli@0.11.0
Minor Changes
f7ee186: Partition
.taskless/by rule engine. Migration0004moves ast-grep rules tosg/rules/andsg/rule-tests/, the runtime tree toruntime/rules/andruntime/rule-tests/, and scaffolds an inertvale/. Files move byte-for-byte, so runtime rule signatures survive.The directory a rule sits in now is its engine: dispatch reads the path and never parses a rule file to decide who owns it.
checkruns ast-grep against the committed.taskless/sg/sgconfig.ymlinstead of generating an ephemeral config each run.A rule engine the CLI does not recognize is now rejected with a message instead of failing silently: an unsupported engine from the server previously exited 0 with no output, which read as success.
Runtime rules are discovered under
runtime/rules/rather than the pre-migrationruntime-rules/. Migration0004moves that tree byte-for-byte, so the signatures the server validates are unchanged.checkandrule verifyread the committed.taskless/sg/sgconfig.ymlrather than writing an ephemeral config on every run, so the config ast-grep uses is the one you can edit and review. A pre-migration rule set still gets a generated config, so an unmigrated project keeps running.Existing projects keep working without action. The pre-
0004.taskless/rules/still runs as ast-grep, and a delivered rule that names no engine is still treated as ast-grep — a rule engine this CLI does not recognize is rejected rather than guessed at. A migration that would have to merge a file into an engine directory now refuses up front withSCAFFOLD_CONFLICTrather than failing part-way.d4fca88: Add a
@taskless/cli/promptssubpath export exposing the CLI's knowledge prompts as importable, topic-keyed render functions.getPrompt(topic, options?)and thePROMPTSmap return fully rendered recipe text, with every%(KEY)splaceholder already resolved from values the package holds, so a consumer never handles a template dialect. Topic names are typed asPromptTopicand start atstatic, the one recipe a service-side consumer can act on; everything else stays internal until a consumer needs it.PromptOptionscovers the anonymous variant, apackageManagerDlxoverride, andheader: falsefor callers placing the text in an LLM system prompt, where the CLI version in the header would otherwise churn the prompt-cache key on every publish.The export is sourced from the same embedded recipes and the same render path
taskless help <topic>serves, so the two surfaces cannot drift, and it carries no CLI runtime, so a Worker can import it without pulling in the command tree.6b07695: Ship Vale as per-platform binary packages.
The CLI now declares
@taskless/vale-<os>-<cpu>asoptionalDependenciespinnedto an exact version, so installing it also brings down a verified Vale binary for
the host platform — no lifecycle script, and nothing to download at runtime. Only
the matching platform installs; unsupported hosts install cleanly with none
present and continue to fall back to a
valefound onPATH.0e03ee9: Add Vale as a second static-tier rule engine, give every engine one rule layout, and rename the agent-facing command.
checknow dispatches by engine and runs ast-grep, Vale, and runtime rulesconcurrently, merging their findings into one result set. An unavailable Vale
reports itself and the other engines still return. A Vale that times out or
rejects its config fails the check rather than passing as a clean run.
Every rule is now one directory,
.taskless/rules/<engine>/<id>/, holdingthe rule, any per-engine config, and its tests in
.tests/. Writing a rulemeans creating a directory and deleting one means
rm -rf. Nothing outside itis touched either way, so concurrent authors never collide on a shared file.
Vale rules carry their own
.vale.inideclaring which files they apply to.The single config Vale reads is assembled from those per-rule files on each
run, gitignored, and regenerated, so hand edits to it have no effect. ast-grep
keeps its
files/ignoresinside the rule and needs no second file.rule verifyis replaced by two path-addressed commands.verify <path>checks that a rule has the components its engine requires and needs no tests,
so it works while you're still authoring.
test <path>runs the rule's tests,after running
verifyand stopping if that fails. Both take a rule directory,an engine directory, or nothing at all for the whole project, and both report
one result per rule. Addressing by path rather than id removes the ambiguity
that arose when two engines held the same rule id.
Projects on an older layout migrate automatically on the next command.
BREAKING:
taskless help <topic>is nowtaskless agent <topic>. Thecommand is named for who reads it. Agents fetching a procedure are not asking
for help, and the old name is gone rather than aliased.
BREAKING: topics are addressed by a single token.
taskless help rule createbecomestaskless agent create-sg-rule; multiple positionals are nolonger joined into a topic key. A topic name is now a literal string an agent
copies rather than a phrase it can reorder. The renames:
rule createcreate-sg-rule/create-remote-rulerule improveimprove-rulerule deletedelete-rulerule verifyverify-rulerule metarule-metastaticcreate-sg-ruleexistingcreate-legacy-ruleengine-selectionrouteroutenow applies the engine reasoning itself and names a concretecreate-*-ruletopic, soengine-selectionis removed rather than renamed —its criterion is stated once, in
route. Every authoring recipe is rewrittenfor the rule-directory layout.
BREAKING for
@taskless/cli/promptsconsumers.engine-selectionis nolonger exported.
TOPICSis nowcreate-sg-rule,create-vale-rule, andcreate-runtime-rule, so a consumer that decides an engine can reach theprocedure for each destination. Because the export is a string union, a
consumer passing the removed name dynamically breaks on upgrade rather than at
build time.
Patch Changes
87abaf3: Fix the pass/fail counts reported when a rule's
ast-greptests fail.ast-grep testechoes the source of a failing test case, andverifyscrapedits counts with unanchored regexes over stdout and stderr combined — so a
fixture containing text like
'7 passed; 0 failed'was read as the summary andverifyreported✗ failed (7 passed, 0 failed)for a run that actually had 0passed and 1 failed. The counts are now read from the summary line itself
(
test result: ok./Error: test failed.), with ANSI colors stripped first.This only affected the reported numbers, never the pass/fail verdict, which
comes from the exit code — but those numbers are handed to the agent driving
improve-rule, where a wrong count can steer the next edit. Test output is alsonow decoded with a
StringDecoderper stream, so a multi-byte character splitacross a chunk boundary is no longer mangled.
f13d501: Stop corrupting non-ASCII characters in ast-grep's error output.
runAstGrepScanand the runtime narrow both decoded ast-grep's stderr onechunk at a time with
chunk.toString(). A multi-byte UTF-8 sequence splitacross a chunk boundary was decoded as two invalid sequences, and both halves
became replacement characters before the pieces were joined — the original
bytes unrecoverable by then. Each stream now uses a single
StringDecoder,flushed on close, matching what the Vale runner and
verifyalready do.The corrupted text only ever reached an error message, so no scan result was
ever wrong. But that message is the one a user reads when ast-grep rejects a
rule file, naming a rule id or a path — which is exactly where a non-ASCII
character turns up.
32da4f9: Stop the engine-partition migration from relocating a rules tree that is already partitioned.
A
.taskless/with notaskless.json— a manifest that was never committed, or was deleted — reads as version 0, so every migration runs against it. Migration0004then applied itsrules/→sg/rules/move to a tree already in the current layout, burying every rule at.taskless/sg/rules/sg/<id>/;0005scaffolded fresh empty engine directories over the gap. Nothing errored.checkscanned a tree with no rules in it and exited 0 on a clean report, so a project that had silently stopped being checked was indistinguishable from one that passes.0004now reads the shape of.taskless/rules/before moving it. A tree holding engine directories and no loose rule files is newer than the migration, not older, so it is left alone. A genuinely pre-0004tree of flatrules/<id>.ymlfiles still moves wholesale, as before. And a tree holding both — an already-partitioned layout with a strayrules/<id>.ymlbeside it, as a merge-conflict leftover produces — migrates only the stray files: moving the directory to collect them would carry the partitioned rules down with it, and0005never brings them back, which is the same silent clean pass by another route.0cc713e: Split the release pipeline so each workflow file carries one release design.
release.ymlheld two jobs with opposite trust properties behind one header.It is now
release-cli-changeset.yml— which reads contributor-authoredchangesets and opens the Version Packages PR holding no npm credential and no
OIDC identity — and
release-cli.yml, which keeps the credential-free"is this version already on npm?" gate together with the publish job it
protects, so an OIDC-capable job is never instantiated on an ordinary merge.
vale-binaries.ymlis renamedrelease-vale.ymlto match.The build and publish steps themselves are unchanged — same triggers, same
permissions: {}, same action pins, same OIDC trusted publishing behind thesame
npm-productionapproval. Two operational details do differ:checkandpublishno longer share therelease-*concurrency group, and the releasenow runs as two workflow runs instead of one, so its check contexts are
Release CLI Version PR / …andRelease CLI / …rather thanRelease / ….Neither is a required check.
The header comments also get one correction: they claimed
npm-productionhadno required reviewers, and it has had one all along, so a release has always
waited for a human approval that the file said was not there.
Publish unreleased work on
mainas@taskless/cli-nightly.Every push to
mainthat has changesets pending now publishes the CLI under asecond package name, stamped
<next-version>-<yyyymmddhhmmss>x<short-sha>— somerged-but-unreleased behavior is installable with
npx @taskless/cli-nightly.A nightly is the same build as the release it anticipates and keeps the
tasklessexecutable, so it is a drop-in; the rename happens at pack time, so@taskless/cli's own version history stays releases-only. Installing bothglobally collides on the binary and is unsupported.
Two credential-free gates decide whether anything is built — pending changesets
first (before any install), then whether the commit already has a nightly — so
the publishing job is never instantiated on an ordinary push, and the merge of a
Version Packages PR publishes the real release and no nightly with no rule
special-casing it.
A nightly now ships instructions for itself. The skills, commands, and recipes
a nightly installs name
npx @taskless/cli-nightly@<version>— pinned to thebuild being installed — instead of
npx @taskless/cli. Previously a nightlycarried the released CLI's text verbatim, so an agent following it ran the
released binary: no error, just instructions for a different package, on a
build installed precisely to exercise unreleased behavior. The version is
stamped once and passed to both the build and the pack, so the version the
instructions name is always the version on npm, and a nightly build without a
valid version fails rather than falling back.
The nightly's duplicate-suppression gate also now fails closed. An unreadable
registry response used to read as "this commit has no nightly", and since each
build stamps a fresh timestamp, a re-run after one would have published a
second nightly for the same commit successfully and silently.
a7ec7a1: Complete the
help→agentrename. The user-facing command was renamed in0.10.0, but the internals kept the old name: the recipe directory moved from
packages/cli/src/help/topackages/cli/src/agent/, thecli-helpOpenSpeccapability is now
cli-agent, and the shipped skill and/tsklcommand nolonger tell agents to run the removed
npx @taskless/cli help <topic>(theynow use
agent, with the single-token topic names —route,improve-rule,delete-rule,create-sg-rule, and siblings).Telemetry rename (hard cut, no dual-emit). The
cli_helpevent is renamedto
cli_agent. Thetopicproperty is unchanged. PostHog dashboards keyed oncli_helpwill need updating — nothing is emitted under the old name.db8adfa: Resolve the ast-grep binary without relying on an install-time step, and drop
the
@ast-grep/cliwrapper from what consumers install.devDependencies. The seven@ast-grep/cli-<platform>packages were already declared in
optionalDependencies, and the CLI alreadyresolved them by path — the wrapper was a leftover whose only job is a
postinstallthat hardlinks the binary into itself so itsbinentries work.Nothing here invoked those entries. Consumers now install only the platform
package matching their host, and the wrapper's
postinstall— which leaves aplaceholder text file where the binary should be under
pnpm dlx's strictisolation — is out of the shipped product entirely. It stays as a
devDependencybecausefetch-ast-grep-schemareads its version.0.41.0. They were carets, and thewrapper had been enforcing alignment implicitly by pinning its own
optionalDependencies; without it, two hosts could resolve different ast-grepversions against the same rules and disagree about findings. Held at
0.41.0rather than taking upstream's
0.45.0, so this change stays structural.the platform package,
node_modules/.bin, thensgandast-greponPATH,and throws naming what it tried. Previously it returned a bare
"sg"and letspawn'sENOENTbe the error, from a caller that could not say where it hadlooked.
Alpine improves as a side effect: upstream publishes no musl build and marks its
Linux packages
libc: ["glibc"], so today the wrapper'spostinstallresolves apackage that does not exist and exits 1, failing the install wherever dependency
scripts run. Installing now succeeds and resolution falls through to
PATH.