feat(rule): list a rule's revisions, to choose one for rollback - #422
Conversation
Vendors GET /cli/api/v2/rule/{ruleId}/revisions (taskless/taskless#261)
and adds listRevisions beside restore and rollback. Proposes
cli-rule-revisions.
Lists a rule's recent revisions on every plan, marking the current one by its flag. REVISION_NOT_FOUND now names the command instead of the dashboard.
recover-rule moves to topic v2: it lists revisions instead of sending the user to the dashboard for an id. Adds the changeset.
|
@claude /review |
|
Claude finished @thecodedrift's task in 5m 37s —— View job Review completeReview mode: incremental — read 0 prior review thread(s) before reviewing. Todo list
AssessmentThis is a clean, well-scoped change. The service-mapping logic ( Three minor [New] findings posted inline, all documentation/cleanup rather than functional bugs:
Verification claims in the PR body (typecheck/lint/test, plus the production round trip against |
Name the recipe step rollback defers to instead of a number that reads as itself, give REVISION_NOT_FOUND's fix the CLI prefix so it runs, and drop the unused RevisionEntry export.
All three findings are addressed in c9710cd: the rollback step now names the — AI Coding Agent |
taskless rule rollback <ruleId> <revisionId>needed a revision id that nothing in the CLI could produce. Therecover-rulerecipe sent the user to the dashboard to copy one, so an agent asked to "roll this rule back" could not finish on its own. The service now lists a rule's revisions (GET /cli/api/v2/rule/{ruleId}/revisions, taskless/taskless#261), deployed 2026-09-30. This PR adds the CLI side.What
taskless rule revisions <ruleId> [--json]: lists the rule's recent revisions and marks the current one. It reads only, and it works on every plan: the listing carries no rule bytes, so the service never reads the plan for it.currentflag, never by position. The service appends a current revision older than the newest ten after them.prUrl.truncated: truesends the user to the dashboard, which lists every revision.--jsonprints{ success, ruleId, revisions, truncated }.listRevisionsinapi/v2.ts. Its error codes are checked against the schema at compile time. A 200 that isn't a listing isunavailable, never an empty history, because an empty list would tell the user the rule has no history.REVISION_NOT_FOUND's message namesrule revisions <ruleId>instead of the dashboard.rule rollback's arguments and behavior are unchanged.recover-rulemoves to topic v2. It gains a "Rolling back" section: list, pick what the user described (ask if more than one fits), roll back.api-v2.schema.json: purely additive, one new path.runRecovery's identity and error-reporting prelude becamerunForIssuedRule, which restore, rollback and revisions share.Notes for review
rule_not_foundgets its own message on this route. On restore, the service also returns it for a rule that exists only on an open PR, and the restore message says so. The listing has no such case: taskless/taskless#261's spec lists a PR-only rule with no revision marked current. So the listing drops that clause.rules-recover.ts.@taskless/cli/schemaspublishes only theverify/testenvelopes. The proposal originally said otherwise, and was corrected during implementation.cli-rule-revisionsis archived on this PR. The delta is two ADDED requirements oncli-rule-recovery. The pre-archive check held: 10 scenarios before, 18 after, none dropped.Verification
pnpm typecheck,pnpm lint(including the house-stylecheck), andpnpm test: all pass, 1888 tests.New tests:
api-v2.test.tscovers the wire,rule_not_found, and a malformed 200.rule-recovery.test.tshas one test per spec scenario, driven through the real command.Production round trip, with
0.12.0-next-0fb5221againstapp.taskless.io, intaskless-sandbox/nextjs-sass-starter(Free plan), on a rule freshly generated through v2 (no-console-log-234c30fd):rule revisions <id>clidelivery, marked(current), namesrule rollback; exit 0rule revisions <id> --json{ success: true, ruleId, revisions: [{ revisionId, createdAt, delivery, requestId, current: true }], truncated: false }; exit 0rule rollback <id> <listed revision> --jsonRULE_RECOVERY_NOT_IN_PLANwith the service's git guidance and upgrade link; exit 1rule rollback <id> not-a-revision --jsonREVISION_NOT_FOUND, namingrule revisions <id>; exit 1rule revisions no-such-rule-00000000 --jsonRULE_NOT_FOUND, without restore's pull-request clause; exit 1The listing works on Free, as the spec requires. A rollback to a real revision was refused for the plan, so a successful write through a listed id was not exercised against production. The existing rollback tests cover that path.
Merge note
#423 regenerates the same two files,
packages/cli/src/generated/api-v2.schema.jsonandapi-v2.d.ts, so whichever of #422 and #423 merges second will conflict there. Don't hand-merge them. Instead, rerunpnpm --filter @taskless/cli generate:apiagainst production, thenprettier --writeonapi-v2.d.tsby explicit path, since the generator writes it unformatted. Both changes are additive, and the live schema already contains both.Refs taskless/taskless#253