Skip to content

chore: version packages - #222

Open
github-actions[bot] wants to merge 1 commit into
mainfrom
changeset-release/main
Open

chore: version packages#222
github-actions[bot] wants to merge 1 commit into
mainfrom
changeset-release/main

Conversation

@github-actions

@github-actions github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

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.

    typeScriptSources excluded only a top-level src/generated, so a nested
    generated 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 delete now resolves which engine holds a rule instead of
    assuming ast-grep.

    deleteRuleFiles hardcoded .taskless/rules/sg/<id>/, which was invisible
    while 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 delete reported
    "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-0005 layout
    (.taskless/<engine>/rules/) rather than the current
    .taskless/rules/<engine>/. One of them is in types/runtime-rule.ts, which
    defines 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_DIRECTORY and
    isKnownEngine are now importable as data, from an entry that reaches no
    filesystem, 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-graphs walks each library
    entry's resolved chunk graph and refuses to emit one that imports a host
    capability or reaches the CLI entry. tsconfig.prompts.json becomes
    tsconfig.public.json, since it now supplies declarations for both public
    subpath exports.

    Refuse a runtime capture rule whose match mode this build does not
    implement, instead of silently treating it as anchor.

    The two modes scan different things: anchor is a syntactic narrow, broad
    a whole-language enumerator. Defaulting an unrecognized third mode to
    anchor did 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. verify
    names 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.taskless block, a kind other than runtime, a
    non-string language, name or id — and a dropped capture makes a rule
    report nothing, which is indistinguishable from a rule that passed. verify
    now names the file and the reason for each.

    Discovery and verify share 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.version this build does not
    implement 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.ts is signed; the capture *.yml are inert data the reconcile
    gate neither signs nor reports. A second module beside check.ts would be
    code reachable from a blessed entry point without being blessed itself — one
    relative import away — so tampering with it bypasses the gate while check.ts
    still matches its blessed digest. Such a rule is refused, and verify names
    the file.

    Every extension a check could import is covered, not only .ts, and the
    search 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 reads
    real 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 against ENGINE_LAYOUTS — so
    "is this a complete rule" is answered from the table the CLI dispatches on
    rather than from per-engine prose. files and content are mutually
    exclusive, and the legacy single-content payload every published CLI
    receives keeps working unchanged.

    Completeness is enforced because every missing piece fails silently: a
    runtime rule with no check.ts is never blessed and is held, and a Vale rule
    with no .vale.ini has no matcher enabling it and never fires. Both leave
    check exiting 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.

    rules is published as SingleContent | Sg | Vale | Runtime rather than one
    shape with optional fields, so a runtime file set states signature as
    required. Reading content or tests off a rule no longer type-checks
    without 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
    files nor content fell through to the single-content branch and handed
    yaml.stringify an undefined, 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.

    check used to parse reconcile's unsafe, unknown and missing verdicts
    and read none of them. unsafe (bytes that drifted from what the server
    blessed) and missing (a rule the server expected and this disk never had)
    are now re-fetched from POST /cli/api/rule/{ruleId}/restore. unknown is
    not, 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 unsafe rule
    stays withheld; the next check reports the repaired signature and is blessed
    through 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 that
    is already the safe state.

  • a1ba72f: Reclaim a reference stub whose recovery instruction names a CLI build you are no longer running.

    Every stub outside .taskless ends 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 at npx @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 init is 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.ts path. The server sends ruleId on every unsafe entry, 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 ruleId is 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 covers missing as well as unsafe; the rule stays withheld, which is already the safe state, and the notice reaches the --json envelope so a CI run can see it.

  • 2f8016b: check, verify and test no longer migrate .taskless/ as a side effect of
    reading it.

    Migration 0005 moves and deletes tracked files, and these three commands
    performed 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 init as the fix, and leave the working tree untouched. The refusal
    carries SCAFFOLD_MIGRATION_REQUIRED on the --json envelope, distinct from
    the existing SCAFFOLD_VERSION_MISMATCH, which is the opposite direction and
    asks 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 --json is new, and carries the migrated field that check, verify
    and test used to report. The field followed the behaviour rather than being
    dropped: 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/request paths instead of the
    deprecated /cli/api/rule family.

    The id was never a rule id. POST returns a ticket, GET returns N rules each
    carrying their own id, and the service's own spec, its meta.ticketId field
    and 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:api now vendors the API's OpenAPI document to
    src/generated/api.schema.json alongside the generated types, so a contract
    change 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: init now prints a banner when an install moves the CLI version, telling you to
    reload 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 meta now says why it has no data, instead of reporting the rule as missing.

    The .taskless/rule-metadata/<id>.yml sidecar is written from the meta block of a rule status response, and the rule service does not populate that block. No sidecar has ever been written, so rule meta failed with RULE_NOT_FOUND for every id, including rules plainly on disk. It now fails with the new RULE_META_UNAVAILABLE code and an explanation, and points at the ticket id that actually drives iteration.

    rule improve now reports RULE_NOT_FOUND when the service has no such ticket id, instead of folding that 404 into NETWORK_ERROR. The two ask for different things: one says re-check the id, the other says retry.

    The improve-rule recipe no longer routes through rule meta. It takes the ticket id from the ruleId field of rule 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, and create-sg-rule were corrected where they described the sidecar as something that exists.

  • 37b49e1: Document where a runtime rule's test fixtures go.

    create-runtime-rule described a rule directory as captures/*.yml plus
    check.ts and said nothing about .tests/, so an agent authoring a runtime
    rule had no statement of the fixture layout at all. verify-rule reported
    runtime tests as "not run" without saying what was not being run.

    Both now state it: cases live in .tests/pass/ and .tests/fail/, and a
    case is a directory whose path is the root the harness hands the
    check, 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.md and Taskless skill no longer describe a
    layout two migrations old.

    Both named rule-tests/, a directory 0005 deletes, and the README described
    rules as living under sg/rules/ and vale/rules/ rather than the current
    rules/<engine>/<id>/. The skill line is the one that mattered most: it is a
    trigger description, so it taught an agent to look in a directory the migration
    had removed.

    0001 writes the README on every run and says it "overwrites stale content
    from older versions", which is true and not sufficient. Migrations only run
    above the recorded version, so a project already at 5 never ran 0001 again
    and kept its stale copy permanently. Migration 0006 rewrites it, so an
    existing 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_VERSION is exported for the same reason: tests
    hardcoded 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 unsupported now says why, instead of always blaming the plan.

    The message was hardcoded to an entitlement explanation and ignored the
    error the service sends with the status. That was accurate while the only
    way to reach unsupported was an account lacking a capability. The service
    now 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 unsupported that arrives without a reason, and
    a 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 @doc extraction, so it leaves
    the 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 update explains the drop and
    where 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 carries
    the 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-20260902195904x0a9c8b9

Built from: 0a9c8b9
Built at: 2026-09-02 19:59:04

@github-actions
github-actions Bot force-pushed the changeset-release/main branch 27 times, most recently from 2259061 to fe2bff8 Compare September 2, 2026 19:27
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from fe2bff8 to 01349c4 Compare September 2, 2026 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants