chore: version packages - #222
Open
github-actions[bot] wants to merge 1 commit into
Open
Conversation
github-actions
Bot
force-pushed
the
changeset-release/main
branch
27 times, most recently
from
September 2, 2026 19:27
2259061 to
fe2bff8
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
from
September 2, 2026 19:57
fe2bff8 to
01349c4
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.1
Compare with v0.11.0
Patch Changes
c323180: A delivered file set now defines what a rule directory contains, rather than being merged into it. Writing a rule removes any file the set does not name, so
check's repair of a drifted rule no longer leaves behind a stray capture that reconcile never reported and the repair never replaced. Test fixtures under.tests/are kept: nothing there reaches an engine, and the CLI writes fixtures there itself that no delivered set names. Neither half of that write acts through a symlink: a link standing where a delivered file belongs is unlinked rather than written through, and a rule directory that is itself a link is refused. A file the purge cannot remove is now named in the error instead of silently ending the pass.0a9c8b9: The deprecated-path guard now skips
generated/at any depth.typeScriptSourcesexcluded only a top-levelsrc/generated, so a nestedgenerated directory would have had every deprecated path in its transcript
reported as a call site. The exclusion exists because a generated directory is
the schema's own transcript rather than a call site, and that reasoning does not
depend on how deep it sits.
386ca1d:
taskless rule deletenow resolves which engine holds a rule instead ofassuming ast-grep.
deleteRuleFileshardcoded.taskless/rules/sg/<id>/, which was invisiblewhile ast-grep was the only engine a rule could be delivered for. A Vale or
runtime rule could be written and then not removed, and
deletereported"not found" for a rule plainly on disk. The failure message named an
sg/path that a non-ast-grep rule was never going to be at.Also corrects seven comments describing the pre-
0005layout(
.taskless/<engine>/rules/) rather than the current.taskless/rules/<engine>/. One of them is intypes/runtime-rule.ts, whichdefines the harness contract and is where a reader goes to be sure.
Publishes the rule layout table as
@taskless/cli/layout.ENGINES,ENGINE_LAYOUTS,RULES_DIRECTORY,RULE_TESTS_DIRECTORYandisKnownEngineare now importable as data, from an entry that reaches nofilesystem, network, telemetry or command tree — so a Worker can load it. A
service building a rule payload can validate against the table the CLI itself
dispatches on rather than transcribing it.
The build enforces the constraint:
assert-library-graphswalks each libraryentry's resolved chunk graph and refuses to emit one that imports a host
capability or reaches the CLI entry.
tsconfig.prompts.jsonbecomestsconfig.public.json, since it now supplies declarations for both publicsubpath exports.
Refuse a runtime capture rule whose
matchmode this build does notimplement, instead of silently treating it as
anchor.The two modes scan different things:
anchoris a syntactic narrow,broada whole-language enumerator. Defaulting an unrecognized third mode to
anchordid not degrade the capture, it reinterpreted it — the capture ran,matched a fraction of what it was written for, and reported the shortfall as
a clean pass.
Discovery now refuses the capture, per file rather than per rule, so one
unimplemented mode cannot take a rule's other narrows down with it.
verifynames the file, the offending value, and the valid modes, so a capture
dropping out of the run is explained rather than left looking like a rule
that found nothing.
Every reason a runtime capture rule is refused is now explained by
verify.Discovery dropped a capture silently for six distinct reasons — not a YAML
mapping, no
metadata.tasklessblock, akindother thanruntime, anon-string
language,nameorid— and a dropped capture makes a rulereport nothing, which is indistinguishable from a rule that passed.
verifynow names the file and the reason for each.
Discovery and
verifyshare one assessor, so "verify says the rule is fine"and "the run silently skipped that capture" cannot come apart.
A capture declaring a
metadata.taskless.versionthis build does notimplement is now refused rather than read as if it were version 1.
A runtime rule now has exactly one executable file, enforced rather than
assumed.
Only
check.tsis signed; the capture*.ymlare inert data the reconcilegate neither signs nor reports. A second module beside
check.tswould becode reachable from a blessed entry point without being blessed itself — one
relative import away — so tampering with it bypasses the gate while
check.tsstill matches its blessed digest. Such a rule is refused, and
verifynamesthe file.
Every extension a check could import is covered, not only
.ts, and thesearch is recursive: "one import away" is not "one directory away", so a
nested directory would otherwise carry unsigned code straight past the check.
A rule's
.tests/fixtures are excluded at any depth, since a check readsreal files under a root and a fixture that is itself TypeScript is ordinary.
A generated rule can arrive as a file set.
files: [{ path, content }], each path relative to.taskless/rules/<engine>/<id>/, validated againstENGINE_LAYOUTS— so"is this a complete rule" is answered from the table the CLI dispatches on
rather than from per-engine prose.
filesandcontentare mutuallyexclusive, and the legacy single-
contentpayload every published CLIreceives keeps working unchanged.
Completeness is enforced because every missing piece fails silently: a
runtime rule with no
check.tsis never blessed and is held, and a Vale rulewith no
.vale.inihas no matcher enabling it and never fires. Both leavecheckexiting 0.Delivered paths are refused before anything is written: absolute paths,
..segments, backslashes, unnormalized segments, duplicates (including two paths
differing only in case, which are one file on a case-insensitive filesystem),
and one path being an ancestor of another. The whole set is assessed as a
unit, so a refused delivery leaves no directory behind rather than a
half-written rule that verifies as broken two steps from the cause.
The generated API types now carry the delivery union, and the client narrows
on it.
rulesis published asSingleContent | Sg | Vale | Runtimerather than oneshape with optional fields, so a runtime file set states
signatureasrequired. Reading
contentortestsoff a rule no longer type-checkswithout asking which variant arrived, which is the property doing its job:
the client cannot treat an unsigned runtime rule as deliverable.
It also closes a case that reached the filesystem. A payload carrying neither
filesnorcontentfell through to the single-content branch and handedyaml.stringifyanundefined, which returns the string"undefined"rather than throwing. The rule file was created and its contents were that
word. It is now refused before the directory exists.
A rule the service blessed is now repaired, instead of only reported.
checkused to parse reconcile'sunsafe,unknownandmissingverdictsand read none of them.
unsafe(bytes that drifted from what the serverblessed) and
missing(a rule the server expected and this disk never had)are now re-fetched from
POST /cli/api/rule/{ruleId}/restore.unknownisnot, because a file the service never issued has nothing to fetch; it gets an
explanation instead, since "on your disk, never issued" is ordinary and read
as an unexplained skip.
Restored bytes are verified against the signature reconcile ALREADY sent,
not against the one the restore response carries. Checking a response against
itself proves only that the service is internally consistent, which it would
also be if it returned a newer generation of the rule. Restore repairs a rule;
it does not upgrade one, and that is now a property with a test rather than a
promise.
Nothing repaired runs in the pass that repaired it. Restore rewrites the
working tree and promotes nothing into the current run, so an
unsaferulestays withheld; the next
checkreports the repaired signature and is blessedthrough the ordinary path. A repair that cannot happen is a notice, never a
failed
check, because a rule that was not repaired stays withheld and thatis already the safe state.
a1ba72f: Reclaim a reference stub whose recovery instruction names a CLI build you are no longer running.
Every stub outside
.tasklessends with the line that makes a missing canonical file recoverable: "If<path>does not exist, run<command>from the project root to restore it, then read it." That command was frozen at whichever build wrote the stub. Install a nightly once and go back to the released CLI and every install afterwards reported "up to date" while the line kept pointing atnpx @taskless/cli-nightly@<pinned>— a version that may no longer be published, in exactly the situation where the reader has nothing else to fall back on.An install now rewrites a stub whose recovery command names a build other than its own, with one exception: the released, version-free
npx @taskless/cli initis left alone by every build. It resolves for any reader, so a nightly has no reason to replace it, and the released and nightly builds do not rewrite each other's stubs on repeat installs. Stub bytes written by a released build are unchanged.319afda: Rule repair now takes a drifted rule's id from the reconcile entry that reports it, rather than parsing it out of the reported
check.tspath. The server sendsruleIdon everyunsafeentry, so the parse and its fallback are gone. The parse tied repair to a filesystem layout that has moved twice, and a further move would have broken it silently: a wrong id, a 404 from restore, and a rule left unrepaired and unexecuted with nothing reported.A reconcile entry that arrives without a usable
ruleIdis now skipped with a notice instead of becoming a request. The service's schema requires the field, but the CLI decodes the response with a cast rather than a schema, so a rollback or a regression could previously send the CLI to/cli/api/request/undefined/restore. This coversmissingas well asunsafe; the rule stays withheld, which is already the safe state, and the notice reaches the--jsonenvelope so a CI run can see it.2f8016b:
check,verifyandtestno longer migrate.taskless/as a side effect ofreading it.
Migration
0005moves and deletes tracked files, and these three commandsperformed it on the way to doing their real work. So a command whose whole job
is to report rewrote the repository, with nothing on the human path to say so:
the diff landed in whatever commit came next, and in CI it ran on every
checkout.
It also made a migration impossible to verify. Comparing findings before and
after cannot be done when asking the question performs the change, so a
migration that silently dropped a rule could not be caught by the one check
that would catch it.
These commands now refuse a project whose scaffold is behind, name
taskless initas the fix, and leave the working tree untouched. The refusalcarries
SCAFFOLD_MIGRATION_REQUIREDon the--jsonenvelope, distinct fromthe existing
SCAFFOLD_VERSION_MISMATCH, which is the opposite direction andasks the caller to upgrade the CLI instead.
The cost is a wall the user meets once after an upgrade, where before they met
nothing. That is the visible version of the same event.
init --jsonis new, and carries themigratedfield thatcheck,verifyand
testused to report. The field followed the behaviour rather than beingdropped: a CI script still needs to know the working tree was rewritten and
what moved. It is gone from those three envelopes, where it can no longer
occur; it was always optional and conditional, so nothing that read it
correctly breaks.
56d00a6: Calls the rule service's renamed
/cli/api/requestpaths instead of thedeprecated
/cli/api/rulefamily.The id was never a rule id.
POSTreturns a ticket,GETreturns N rules eachcarrying their own
id, and the service's own spec, itsmeta.ticketIdfieldand its SQL all called it a ticket — the route was the outlier. Both identifiers
still ride every response and the legacy paths still serve, so nothing changes
for anyone; this moves the CLI's calls before the deprecation window closes.
generate:apinow vendors the API's OpenAPI document tosrc/generated/api.schema.jsonalongside the generated types, so a contractchange arrives as a readable diff rather than only as regenerated declarations,
and a test reads that document to fail if any source file still calls a path the
API marks deprecated.
42c0574:
initnow prints a banner when an install moves the CLI version, telling you toreload skills or start a new session.
An AI tool reads its skill and command listing once, at session start, so a
session that is open during an upgrade keeps serving the previous copy for the
rest of its life. Nothing errors. Because a Taskless recipe is embedded in the
bundle at build time rather than fetched, a stale skill names a stale CLI
invocation and serves a stale recipe, so the answer is wrong rather than
missing.
The banner fires on a version move in either direction, which covers an upgrade,
a downgrade, and a stable/nightly swap. A first install is not a move and stays
quiet, as does re-running an install on the version already recorded.
8f4df96:
taskless rule metanow says why it has no data, instead of reporting the rule as missing.The
.taskless/rule-metadata/<id>.ymlsidecar is written from themetablock of a rule status response, and the rule service does not populate that block. No sidecar has ever been written, sorule metafailed withRULE_NOT_FOUNDfor every id, including rules plainly on disk. It now fails with the newRULE_META_UNAVAILABLEcode and an explanation, and points at the ticket id that actually drives iteration.rule improvenow reportsRULE_NOT_FOUNDwhen the service has no such ticket id, instead of folding that 404 intoNETWORK_ERROR. The two ask for different things: one says re-check the id, the other says retry.The
improve-rulerecipe no longer routes throughrule meta. It takes the ticket id from theruleIdfield ofrule create --json, which is the id the iterate endpoint is addressed by, and falls back to the local-only flow when nobody has it.rule-meta,rule,delete-rule,create-remote-rule, andcreate-sg-rulewere corrected where they described the sidecar as something that exists.37b49e1: Document where a runtime rule's test fixtures go.
create-runtime-ruledescribed a rule directory ascaptures/*.ymlpluscheck.tsand said nothing about.tests/, so an agent authoring a runtimerule had no statement of the fixture layout at all.
verify-rulereportedruntime tests as "not run" without saying what was not being run.
Both now state it: cases live in
.tests/pass/and.tests/fail/, and acase is a directory whose path is the
rootthe harness hands thecheck, so it may hold as many files as the case needs. That last part is
load-bearing rather than incidental — a runtime rule exists because its
evidence spans more than one file, so a layout allowing one file per case
could not express the rules the tier is for.
63634d1: The installed
.taskless/README.mdand Taskless skill no longer describe alayout two migrations old.
Both named
rule-tests/, a directory0005deletes, and the README describedrules as living under
sg/rules/andvale/rules/rather than the currentrules/<engine>/<id>/. The skill line is the one that mattered most: it is atrigger description, so it taught an agent to look in a directory the migration
had removed.
0001writes the README on every run and says it "overwrites stale contentfrom older versions", which is true and not sufficient. Migrations only run
above the recorded version, so a project already at 5 never ran
0001againand kept its stale copy permanently. Migration
0006rewrites it, so anexisting project gets a correct description rather than only new installs.
The README's layout section is now derived from the rule layout table instead
of described beside it, so the words cannot disagree with the directories they
describe.
LATEST_SCHEMA_VERSIONis exported for the same reason: testshardcoded the current version in ten places, and the version matrix listed
prior versions literally, so each new migration silently stopped covering the
version it had just made prior.
af1045e: A terminal
unsupportednow says why, instead of always blaming the plan.The message was hardcoded to an entitlement explanation and ignored the
errorthe service sends with the status. That was accurate while the onlyway to reach
unsupportedwas an account lacking a capability. The servicenow also terminates a request as unsupported when the CLI is below the floor
a runtime rule needs, and a user on an older CLI was being told to upgrade
their plan: they would ask an administrator for a capability they already
had, and the one command that would have fixed it was never mentioned.
The service's reason now wins whenever it sends one. The entitlement text
remains the fallback for an
unsupportedthat arrives without a reason, anda blank reason counts as none rather than printing a heading with nothing
under it.
41eb0fb: Vale moves to 3.19.0.
Elixir (
.ex,.exs) gained comment and@docextraction, so it leavesthe plaintext fallback for the comment tier. This narrows what a Vale rule
matching Elixir reports: the code body is no longer prose, and findings that
came from it disappear silently.
taskless agent updateexplains the drop andwhere to take a rule that was relying on it.
MDX gained coverage in the other direction — a JSX element's children are read
as the Markdown they are, so prose inside a wrapping component such as
<Steps>or<Aside>is linted where it previously was skipped, and carriesthe component name as a
text.class.<name>scope a rule can target.Every other row of the format-tier table was re-probed against the 3.19.0
binary and none of them moved.
Build Info
npx @taskless/cli-nightly@0.11.1-20260902195904x0a9c8b9Built from: 0a9c8b9
Built at: 2026-09-02 19:59:04