Skip to main content
Every version of @retasc/cli published to npm, newest first. Dates are the npm publish date, and each entry names the issue behind it. One line per change; the full notes sit under each version’s fold.

1.55.0

2026-09-19
  • RTSC-1057 — the proxy now reports how long this machine keeps a session transcript, read from the harness’s own settings (Claude Code’s cleanupPeriodDays), so the Dash can name the day a conversation will be gone instead of quoting a documented default at you.
  • RTSC-1057 — the proxy now reports how long this machine keeps a session transcript, read from the harness’s own settings (Claude Code’s cleanupPeriodDays), so the Dash can name the day a conversation will be gone instead of quoting a documented default at you. It was saying “deleted after 30 days by default”, which is wrong by eleven months for anyone who set it to a year. A number of days, never a path and never the file — the same boundary the transcript id and the workspace already sit on: Retasc holds the id, the machine holds the conversation. It is sent only for a harness whose retention the proxy actually read, so Codex, Gemini CLI, Cursor and OpenCode send nothing and the Dash keeps the shorter sentence for them rather than borrowing Claude Code’s number. Nothing to do on upgrade, and nothing breaks on an older CLI: the field is optional, an install that never sends it is ordinary, and the panel simply does not name a day. The backend that accepts it is already deployed.

1.54.0

2026-09-19
  • RTSC-1061 — nothing asks which subscription pays for an agent any more, so retasc plan is gone and retasc bind no longer puts the question.
  • RTSC-1061 — nothing asks which subscription pays for an agent any more, so retasc plan is gone and retasc bind no longer puts the question. Breaking if you scripted it; retasc plan now exits with unknown command 'plan'. The question was asked once per runtime to give model spend a denominator, and the one surface that was going to read the answer was canceled. Nothing consumed it after that, so every install spent a turn of its first session collecting a fact with no reader on the other end. The PLAN_UNKNOWN setup state went with it, along with the list_plans and set_plan MCP tools — the server is at 56 tools now, down from 58. Upgrade if you are on 1.53.1 or older. The backend functions behind retasc plan are already removed, so on an un-upgraded CLI that one command fails with a raw Could not find public function instead of a clean message. Every other command is unaffected, retasc bind included: its plan step was already written to be skipped rather than to fail the bind. Answers recorded before this are no longer read and are deleted in a follow-up.

1.53.1

2026-09-18
  • RTSC-1042 — the proxy now sweeps this machine’s dead worktrees on the first claim of a session.
  • RTSC-1042 — the proxy now sweeps this machine’s dead worktrees on the first claim of a session. Reap used to run only when this session marked an issue done, so an author who sent work to review kept the tree after the reviewer merged and closed it on another laptop. retasc tidy --prune --auto deletes local trees whose issue is done or canceled and whose commits are already on trunk or fully pushed to origin, with a one-hour grace and a cap of ten per session. A branch that never landed on trunk is not deleted from origin. Nothing to do: the next claim on a machine with leftover trees starts the drain.

1.53.0

2026-09-15
  • RTSC-1014 — every tool you start in a bound folder now gets its own credential, so one can be retired without stopping the others.
  • RTSC-1014 — every tool you start in a bound folder now gets its own credential, so one can be retired without stopping the others. Before this, Claude Code, Grok and Codex started in the same folder all read the same .mcp.json and authenticated as one credential: retiring any of them stopped all three and cost you a retasc bind. The proxy mints the new credential at the initialize handshake — the first moment the tool has a name — and caches it in the keystore, so it fires once per (folder × tool) rather than once per session. Nothing to do: a folder bound before this upgrades itself as each tool next starts, with no re-bind and no edit to .mcp.json. Two behaviours worth knowing. A tool retired in a folder is served nothing there and says so, rather than quietly falling back to the folder’s shared key — that fallback would have undone the retire. And a client that never sends initialize still gets a per-session key exactly as before, since with no client name there is no tool to name. What it is not: the folder’s workspace key stays valid, so this is fleet management, not a security boundary. An older CLI, or a tool pointed straight at mcp.retasc.com with the key from .mcp.json, is not stopped by it.

1.52.0

2026-09-14
  • RTSC-958 — a user never names an agent, so --agent <name> is gone from init, bind, key mint and join.
  • RTSC-958 — a user never names an agent, so --agent <name> is gone from init, bind, key mint and join. Breaking if you scripted it; those commands now exit with unknown option '--agent'. Drop the flag and you get the same agent you would have got by omitting it. The flag looked like a label and was not one. An agent’s identity was {you}'s {runtime} and the roster grouped rows by that string, so a typed variant — "Em de Vries's claude-code 2", say — did not rename an agent, it forked a second one that kept its own finished count, spend and send-back rate forever. Nothing warned anyone, and there is no rename door in the product to undo it with. The help text made it worse by advertising the exact shape to vary: (default: auto, "{you}'s {runtime}"). Every custom name in the org that found this was junk or an accident: one accidental fork of the author’s own agent, three from a test an agent ran wrong, two fixtures. No other surface names an agent either — the Dash has no naming UI, and the setup-token flow always passed an empty name. retasc plan --agent <nameOrId> is a SELECTOR, not a name, and is untouched. The server keeps ACCEPTING agentName and ignores it, so 1.48 and 1.51 keep minting rather than failing validation — an older client simply gets the generated name. That half is already live, so this release removes the flag rather than changing behaviour.

1.51.0

2026-09-13
  • RTSC-962 — the proxy now reports git worktrees nobody claimed, so Retasc can see work an agent started without saying so.
  • RTSC-962 — the proxy now reports git worktrees nobody claimed, so Retasc can see work an agent started without saying so. Retasc fenced the END of work and nothing at the START: done rejects on a claim mismatch, review demands a handoff, but the server never sees an agent edit a file — so an agent could build thousands of lines against an issue the queue still showed as free, and a second agent would read it as untouched and duplicate or decompose it. The server still reads no git. This process does: a rtsc-NN/<slug> worktree with no live claim behind it is reported, and the issue gets a provisional hold — visible on get_issue, withheld from next_issue / next_batch, lapsing after an hour. A hold is not a lease and never refuses an explicit claim_issue, so the agent that forgot to claim always gets its own work back. Only ACTIVE worktrees count (uncommitted changes, or a commit in the last day), so an abandoned directory cannot park an issue; git runs asynchronously and off the critical path, so the census never delays a tool call; and each unclaimed worktree is announced once, not on every call. A server without the tool simply produces no holds.

1.50.0

2026-09-11
  • RTSC-901retasc plan: which subscription pays for each of your agents, listed and set one line per (agent, harness).
  • RTSC-901bind asks the same question at setup, but only when --runtime was STATED.
  • RTSC-901retasc plan: which subscription pays for each of your agents, listed and set one line per (agent, harness). Retasc cannot read this anywhere — no transcript field, telemetry attribute or environment variable carries it, and the only machine source sits behind the human’s own keychain — so it is asked for once and kept. The options are READ FROM THE SERVER on every run, never compiled in: a tier a vendor ships this morning is on the list this afternoon, on the build you already have.
  • RTSC-901bind asks the same question at setup, but only when --runtime was STATED. That flag defaults to claude-code, which is a fine label for a row and the wrong subject for this question: retasc setup wires every harness on the machine, so asking “which Claude plan?” of someone setting up Codex records a fact about the wrong product. Left unstated, the question falls to the first MCP handshake, which knows which harness actually connected.
  • A non-interactive run answers nothing rather than defaulting. A plan nobody chose reads on the Agents page exactly like one they did.

1.49.1

2026-09-09
  • RTSC-879 — the proxy sends NO Authorization header when it has no key, instead of Bearer with nothing after it.
  • RTSC-879 — the proxy sends NO Authorization header when it has no key, instead of Bearer with nothing after it. An empty bearer is not a weaker credential, it is a malformed one, and where a keyless proxy now runs that difference decides whether the thing works at all: in a Claude Code cloud container the documented way to supply a credential is an environment API credential, which Anthropic’s egress proxy injects as an Authorization header after the request leaves the VM — and which also lets the request through a network allowlist that would otherwise refuse the host. Injection wants the header absent, and whether it overwrites one already present is undocumented, so sending an empty bearer staked the whole path on undocumented behaviour. With a key present nothing changes.

1.49.0

2026-09-09
  • RTSC-879 — a committed .mcp.json now names npx -y @retasc/cli@<version> mcp-proxy instead of a bare retasc, so it starts on a machine that is not the one that wrote it.
  • RTSC-879retasc bind --json can now sign in from a container.
  • RTSC-879retasc doctor no longer installs a package to check a marker.
  • RTSC-879 — the repo’s own committed .mcp.json, and the marker blocks published in web/auth.md and the agent-skill, now show the npx form.
  • [no-issue] — test fix: the setup-hook test pinned RETASC_HOME to a temp dir.
  • RTSC-879 — a committed .mcp.json now names npx -y @retasc/cli@<version> mcp-proxy instead of a bare retasc, so it starts on a machine that is not the one that wrote it. portableLauncher used to pass an on-PATH resolution straight through on the belief that a bare binary “was at least portable”; it is portable only across machines that happen to have a global install. A container has none. Measured in a Claude Code cloud session on a fresh clone: the MCP server died at ENOENT: Executable not found in $PATH: retasc before it could do anything else. Startup on the shared marker now pays npx resolution (about 6s cold, ~1s off the cache); user-level configs, which never travel, keep the direct binary.
  • RTSC-879retasc bind --json can now sign in from a container. An agent-driven bind takes the DEVICE grant instead of the browser one, in two steps: the first call prints an approve URL and an eight-character code and exits, the human approves on any device, and running the same command again resumes the same grant and finishes. Previously an agent got the browser door, which redirects to 127.0.0.1 on the machine running the CLI — unreachable when the human is somewhere else, which in a cloud container they always are. New continuable outcome state SIGN_IN_PENDING so an agent can tell “waiting on a click” from “nothing has started” and does not issue a second code that invalidates the one its human is reading. CI and RETASC_NO_BROWSER still refuse immediately: neither has anyone to approve anything.
  • RTSC-879retasc doctor no longer installs a package to check a marker. For an npx marker it probes npx --version rather than executing the pinned package spec, which was a registry fetch on every run and reported “your agent CANNOT start Retasc” for a healthy marker whenever npm was unreachable. Its remedy line is corrected too: a global install can no longer change what bind writes into a shared marker.
  • RTSC-879 — the repo’s own committed .mcp.json, and the marker blocks published in web/auth.md and the agent-skill, now show the npx form. They were the bare binary, which is the exact thing this release stops emitting. Those hand-written blocks say @latest rather than a pinned version on purpose: release:cli publishes from main AFTER a merge, so a committed marker pinning the version being released would 404 for every fresh clone in the window between the two — trading this release’s ENOENT for an E404. bind still writes the pinned form, which is correct because it only ever names a version that already exists.
  • [no-issue] — test fix: the setup-hook test pinned RETASC_HOME to a temp dir. It fell through to the real home directory, so it passed on a clean CI runner and failed on any machine that had actually run retasc setup.

1.48.1

2026-09-08
  • RTSC-878retasc doctor no longer condemns the entry retasc setup writes.
  • RTSC-878retasc doctor no longer condemns the entry retasc setup writes. Its machine-global check dated from RTSC-91, when every top-level mcpServers.retasc carried a key or a workspace id and so routed every unbound folder to one org; presence alone was a correct test for that. RTSC-780 then made one global entry mandatory, the keyless auto marker, which carries no identity at all, and the check was never taught the difference. Doctor therefore printed ✗ GLOBAL Retasc server registered at the marker and offered claude mcp remove -s user retasc as the fix, which strips Retasc from every folder without a binding of its own. It cost a customer a day.
  • The check now reads the entry’s identity: RETASC_WORKSPACE=auto with no key resolved is reported as correct and named, so someone who just ran setup can see that what it wrote is what belongs there. Every other shape stays illegal, including a keyless entry that names a real ws_ workspace, which still routes every unbound folder to one binding.
  • The exemption is not granted on the sentinel alone. parseServerEntry reads RETASC_WORKSPACE before it looks for a key in an Authorization header or in RETASC_MCP_KEY, so an entry carrying both the auto sentinel and a real credential parses as an innocent keyless marker; judging the parse alone would have exempted a live machine-global registration pointing every unbound folder at that key’s org. The raw entry is examined too, and anything carrying credential material or a url of its own stays illegal whatever its env claims.

1.48.0

2026-09-08
  • RTSC-859retasc key mint --hosted: a key now says at mint what it is for.
  • RTSC-859retasc key mint --hosted: a key now says at mint what it is for. workspace (the default, and what every bind door says explicitly) expects the local watchdog; hosted is for a cloud agent or CI that will never have one. Why: a workspace key sent raw to the server with no proxy is two things at once and the server cannot tell which, a hosted agent working as documented or a laptop whose config went stale. Both got the same advice on every claim, run bind, which a hosted agent cannot do. With kind on the row, a hosted key is told the one true thing (renew your own leases) and shows “no folder (hosted)” on the Agents page as a fact rather than a gap; a workspace key with no runner gets the firm remedy, because for that row it is true. A key that said nothing, which includes every key minted before this and any bare key mint since, keeps the old hedged text, since nothing on the row can say which it is. --hosted and --install are refused together: one wires a local watchdog, the other says there will never be one. retasc mcp install --no-watchdog is not deprecated (it writes exactly a hosted deployment’s config) but now says, once, that a key used that way should be minted --hosted.

1.47.0

2026-09-08
  • RTSC-864retasc key mint now prints every remote-key config block a hosted agent can paste, including the TOML one that did not exist.
  • RTSC-864retasc key mint now prints every remote-key config block a hosted agent can paste, including the TOML one that did not exist. A key is shown once, and until now that was all key mint printed. Anyone wiring a host that cannot run our proxy (a claude.ai connector, Codex Cloud, CI) had to invent the config, and for two of the six harnesses it was not inventable: tomlBlock emitted only the stdio proxy shape, so Codex and Grok users had nothing correct to paste at all. The new tomlHttpBlock fills that in, and all three blocks now print next to the key while it is still on the screen. The two TOML dialects are separate on purpose, and the reason is the dangerous part. Verified against both real binaries: Codex reads [mcp_servers.retasc.http_headers] and Grok reads [mcp_servers.retasc.headers], and each loads the other’s file without a warning while ignoring the header. The result is a server that reports itself enabled and configured, and returns UNAUTHORIZED on the first tool call. The blocks also say, next to themselves, that a key belongs in a user-scope config or a platform secret store and never in a tracked .mcp.json, which the repo’s pre-commit hook refuses anyway. Where a container DOES have an environment, the proxy with RETASC_MCP_KEY set is still the better door: it renews leases for you.

1.46.0

2026-09-08
  • RTSC-855retasc doctor and retasc setup now say whether the Retasc Agent Skill is installed on this machine, and print the one command that installs it.
  • RTSC-855retasc doctor and retasc setup now say whether the Retasc Agent Skill is installed on this machine, and print the one command that installs it. Wiring the MCP server gives an agent the ability to claim work. The skill is what tells it what a lease is, that a claim needs its own worktree, what a checkpoint is for, and how a handoff into review works. Nothing connected the two, so an agent could be fully wired and still have the tools without the manual, and no surface anywhere would mention it. The server cannot fill the gap: MCP carries a bearer token and no filesystem, so only something running on the machine can look. The hard part is not finding the file, it is not being wrong about it. A false “not installed” shown to somebody who followed our own instructions teaches them to distrust everything else doctor says, so the check knows all three routes a skill really arrives by: global (~/.claude/skills and each harness’s equivalent), project (the skills installer’s DEFAULT scope, which lands in the working directory), and, for Claude Code, an installed plugin’s own folder, since /plugin install retasc@retasc is one of the routes our public README offers and it writes none of the above. It honours CLAUDE_CONFIG_DIR, CODEX_HOME and GROK_HOME for the same reason. The printed command carries -g so it installs where the check looks. A harness whose convention we cannot verify is skipped rather than accused, one harness holding the skill silences the nudge for the rest, absence is reported with rather than , and neither command changes its exit code over any of it.

1.45.0

2026-09-08
  • RTSC-862 — a binding now covers every git worktree of the repo it was made in.
  • RTSC-862 — a binding now covers every git worktree of the repo it was made in. findBindingByPath walks up from the current directory looking for a bound folder and stops at the first .git, which is what stops retasc bind in ~ from silently binding every project beneath it. But .git is a FILE at the root of every worktree, so that stop fired on the first step inside one: every worktree resolved to nothing, with no error and no hint, and the tools were simply absent. Repos whose workflow creates a worktree per task (this one included) hit it constantly, and the rational workaround — paste a raw key into a config that works everywhere — silently costs the watchdog, session rows, transcripts and the folder name. “Same repository” is decided by git’s common dir, the one directory every worktree shares, read from disk rather than by shelling out to git. A sibling repo checked out inside a bound directory still resolves to nothing, so the cross-org property RTSC-91 exists for is untouched. Binding a worktree deliberately still wins over its repo’s binding. retasc doctor says when a folder resolved this way, instead of the old warning that the id “was bound at a different folder” — advice which, for a worktree, would have minted a second key and a second agent for one repo.

1.44.0

2026-09-08
  • RTSC-861 — the proxy now tells Retasc which CLI version it is.
  • RTSC-861 — the proxy now tells Retasc which CLI version it is. It rides on mint_session_key, the one call every proxy already makes at startup, as an optional cliVersion argument, so an older build that sends nothing still mints exactly as before. Why it matters: the update notice (RTSC-520) fires from a postAction hook on retasc <command>, and someone whose only contact with the CLI is the proxy their harness spawns runs no commands and never sees it. Three live setups were found on builds older than 1.41.0 with no way to find out. The server can now say so in the tool result, which reaches every harness, and with this version it can name the exact gap instead of inferring one from behaviour.

1.43.0

2026-09-05
  • RTSC-799 - tidy, done and claim now work out which branch is this repo’s trunk instead of assuming it is called main.
  • RTSC-799 - tidy, done and claim now work out which branch is this repo’s trunk instead of assuming it is called main. Until this release tidy compared every branch against origin/main, a name written into the source with no flag, no config and no way to see it. In a repo whose trunk is master that comparison does not fail into view: git merge-base --is-ancestor exits 128 for an unreadable ref, the code tested only for 0, and so a broken lookup and an honest “not merged” produced the same word. Every branch read merged: no, nothing was ever reapable, and because claim creates a worktree per issue and only tidy removes one, the worktrees accumulated with nothing printed to say why. The team who reported it had thirty of them, built up over months, and could not tell from the outside whether the tool was wrong or their setup was. The trunk now comes from origin/HEAD, which is what git clone already records and what git fetch re-records when it goes stale. Override it per repo with git config --local retasc.base origin/develop, or per run with a new --base on tidy and done. Read at --local scope on purpose: a plain git config --get also sees ~/.gitconfig, and one machine-wide value would have quietly redefined the trunk in every repo on the box and outranked each repo’s own origin/HEAD. When the trunk cannot be worked out at all, that is an error naming the ref and every way to set one, because a command that cannot tell what merged means must not go on to report that nothing did. Ancestry now has three answers rather than two. “Git could not tell” is carried through as its own state, prints as ?, and is never deleted, not even under --force: that flag means “unmerged, but I know the work landed elsewhere”, which is a judgement about a branch git actually reported on. Every run also prints the trunk it measured against, which is the line that would have turned this into a one-minute diagnosis, and a shallow clone warns, since missing history produces the same uniform “no”. Care taken with the sharp edges, because this turns a command that deleted nothing in those repos into one that deletes:
    • A stale origin/HEAD, which outlives the branch it names when a remote renames its trunk and which git before 2.45 never repairs, falls through to the next candidate with a note rather than refusing claim, tidy and done in a repo that is otherwise healthy.
    • done still closes the issue when the trunk cannot be resolved. The control-plane close is the durable half and a CI checkout legitimately has no origin/HEAD; the teardown is what needs a trunk, so that is what reports.
    • The first --prune after upgrading asks once before deleting five or more branches, since it may be clearing months of work a team believed this command never touched. Scripts and the MCP auto-reap never see the question, and --yes skips it.
    • claim fetches before it proves the base exists, so a just-pushed base still works, and resolves before taking the lease, so a claim is never held for a worktree that cannot be created. It also prints the trunk it branched from.
    • A bare repository is refused rather than operated on (the old path resolved to its parent directory), a detached HEAD no longer defeats the “that’s your current branch” guard, and the watchdog now logs a non-zero exit from an auto-reap instead of swallowing it.

1.42.1

2026-09-05
  • RTSC-832 — the model now actually appears.
  • RTSC-832 — the model now actually appears. 1.42.0 read it from the SessionStart hook’s model field, and Claude Code 2.1.261 does not send one: a captured payload is session_id, transcript_path, cwd, hook_event_name, source and nothing else. The row therefore filled in only after a /model switch, which is backwards. Claude Code does write the model on every assistant message in the transcript, so the proxy reads it from there instead, and every session gets one.
  • The read is bounded to the last 64KB: transcripts reach megabytes and this runs on a throttle for the whole session. Reading backwards from the end also means a /model switch is picked up by the same read, with or without the hook.
  • Only the model STRING is ever sent. The transcript path stays on the machine that wrote it, and nothing else from the file leaves it.

1.42.0

2026-09-05
  • RTSC-821 — a session now reports WHICH MODEL ran it.
  • RTSC-821 — a session now reports WHICH MODEL ran it. The MCP handshake carries the client’s name and version only, which is the CLI build and not the model, so this could never have come from the connection: retasc hook session-start now passes the SessionStart payload’s model (plus agent_type and agent_id when the session is a subagent) alongside the transcript id, and the Dash’s session panel names it.
  • A second hook, retasc hook model-switch, is wired on PostModelSwitch, so changing model mid-conversation reaches the Dash and it can say what the session started on. retasc setup wires both in one write. It deliberately does NOT touch the record’s timestamp: that is the window that stops an old record being adopted by a later session in the same folder, and a switch an hour in must not make an hour-old record look new.
  • The proxy keeps watching for a model change after the id is recorded, under the same bounded budget it already had, so a session that switches model on every turn still cannot make it talk to the server on every turn.
  • Absent stays ordinary. Claude Code omits model from some payloads and Codex, Gemini, Cursor and OpenCode have no session hook at all, so a junk or missing model is dropped rather than raised, and never costs the transcript id it travelled with.

1.41.1

2026-09-04
  • RTSC-812 — no runtime change.
  • RTSC-812 — no runtime change. Two comments in cli/src said project deletion did not exist: bind called an unwanted empty project something “that cannot be deleted (org-granularity delete only)”, and the import confirm said “there is no per-project delete”. An owner can delete a project from the Dash now, so both were wrong, and the import one sat on the last screen before an irreversible write.

1.41.0

2026-09-04
  • RTSC-825 — every workspace now carries the name of the folder it is bound to.
  • RTSC-825 — every workspace now carries the name of the folder it is bound to. The server never receives a path, so the name can only come from the machine that has one: retasc bind sends it when the key is minted, and the watchdog proxy re-sends it at every session start, so a folder bound before this existed is named the next time an agent runs there. Only the folder’s own name travels, never the path above it, and it is the folder the BINDING names, so a session opened in a subdirectory still reports the bound folder rather than renaming the row to whatever directory it started in. The Dash shows it as workspace on the Agents page and on the Connect page, and shows nothing at all where a workspace has not reported one; a key retired before this shipped can never report one, so it stays blank.

1.40.0

2026-09-04
  • RTSC-820 — every session now tells Retasc which conversation it is.
  • RTSC-820 — every session now tells Retasc which conversation it is. retasc setup wires a Claude Code SessionStart hook (retasc hook session-start) into ~/.claude/settings.json, idempotently and beside whatever hooks you already have; the hook leaves the session’s id in the keystore dir, and the watchdog proxy picks it up and records it on its session key through a new record_session tool. Grok needs no hook: the proxy reads GROK_SESSION_ID at startup. The Dash’s Agents page then ends each session’s panel with the line that reopens it on the machine that ran it, claude --resume <uuid>. Only the NAME of the transcript is stored, never its contents and never a path. A session started before setup re-ran shows “none recorded” and names the missing hook.

1.39.4

2026-09-03
  • RTSC-810retasc unbind revokes the key it says it revokes.
  • RTSC-810retasc bind --org-id X --project-id Y learns the project’s prefix.
  • RTSC-810 — a key is named after the folder it was bound in, not after the project.
  • RTSC-810retasc unbind revokes the key it says it revokes. It had two faults in one lookup, and each on its own was enough to leave the credential live: it destructured { keys } off listKeys, which returns a bare array, and it derived the folder’s key prefix with a 12-character slice while the server stores 14. An exact compare between a 12-character string and a 14-character one is never true, so every run since unbind shipped (RTSC-721) printed “not found server-side (already revoked, or the org is gone)” and moved on. The length now mirrors the server’s own displayPrefixOf, and the test reads that file, so the two cannot drift apart again. A session child key can no longer be the one revoked either: those are minted in memory by the proxy and never reach the keystore, so a match on one would mean revoking a key this folder does not own.
  • RTSC-810retasc bind --org-id X --project-id Y learns the project’s prefix. The provisioning form skipped every branch that looks a project up, so nothing knew the prefix: the key went out nameless, the keystore entry was written without prefix or orgName, and the receipt card printed an empty one. It now resolves the project the same way the interactive pickers do.
  • RTSC-810 — a key is named after the folder it was bound in, not after the project. The Keys list is the folder map (client-aENG), which is what tells you which machine a credential belongs to; ENG key on every row told nobody anything. Naming is the server’s job now, so no door can store a nameless key: the Dash mint form with the name left blank and retasc key mint without --name both fall back to the project’s own name rather than leaving the Dash to print “Unnamed key”.

1.39.3

2026-09-02
  • RTSC-801 — (security) save_attachment_file no longer reads a workspace’s own secrets, and no longer follows a file swapped in after it was checked.
  • RTSC-801 — (security) save_attachment_file no longer reads a workspace’s own secrets, and no longer follows a file swapped in after it was checked. The proxy reads attachments on the agent’s behalf, which is what keeps the API key away from the model, and the cost of that is a read the harness never prompts on: whatever this path allows, an agent can upload to an issue every org member can read. Containment to the attach root was doing all the work and it was never the boundary it looked like, because the files worth stealing are not outside a workspace, they are in it. .env.local, a legacy inline-key .mcp.json and .retasc/ all live inside a normal root, so a prompt-injected “attach the config” was confined to exactly the secrets. Anything hidden below the root is now refused, dotfiles and dot-directories alike, along with secrets.md and, wherever RETASC_DIR puts it, the keystore itself. A root that contains your home directory (~ or /, both previously accepted) is refused outright rather than carved down, since it makes every credential on the machine attachable, including every other workspace’s key. Those rules all judge a name, so a file with more than one hard link is refused too: path resolution follows symlinks but not links, and ln .env.local notes.txt would otherwise hand the check a name it has no reason to refuse while the bytes stay the same. The one carve-out is .retasc/attachments/, which is where the proxy writes files fetched by get_attachment_file: refusing that would be the proxy declining to read a file the proxy itself wrote, and downloading from one issue to attach to another is a real thing agents do. Anything hidden deeper inside it is still refused. The second half is a race: the path was resolved and stat’d, a full prepare_attachment_upload round trip went to the server, and only then was the file opened by path, so a ln -sf in that window was followed on the read. The read now opens the file O_NOFOLLOW and non-blocking, and proceeds only if the descriptor’s device, inode and size are the ones that passed the check. Opening non-blocking is not a detail: a mkfifo in that same window would otherwise have blocked the proxy’s event loop outright, stopping every heartbeat it owes and stranding every lease it holds. Legitimate attachments, screenshots, logs and documents, are unaffected: none of them are hidden files.

1.39.2

2026-09-02
  • RTSC-808retasc setup no longer writes OpenCode’s config into your real home when RETASC_HOME says otherwise.
  • RTSC-808retasc setup no longer writes OpenCode’s config into your real home when RETASC_HOME says otherwise. That variable exists so anything exercising the harness module cannot reconfigure the machine it runs on, and every other harness honours it; OpenCode read XDG_CONFIG_HOME first and so ignored the override wherever that variable is set. The precedence is now override, then environment, then default, and XDG_CONFIG_HOME is still honoured when no override is in play, because OpenCode really does read it. This is also why CI had been red on main for five consecutive merges. macOS does not set XDG_CONFIG_HOME and GitHub’s Linux runners do, so the test guarding this passed on every developer machine and failed on every CI run, and no PR in the repo could show a green build.

1.39.1

2026-09-02
  • RTSC-800 — (security) a keystore-resolved key now travels only to the keystore’s own url, whether the competing url arrives in the .mcp.json entry or in the environment.
  • RTSC-800 — (security) a keystore-resolved key now travels only to the keystore’s own url, whether the competing url arrives in the .mcp.json entry or in the environment. 1.6.0 made this promise for the entry, which covered claim/tidy/done but not the proxy: the proxy is the one caller that ever reads a committed marker, and it passes no entry at all. The harness copies the marker’s env block into the spawned process, so a RETASC_MCP_URL planted next to RETASC_WORKSPACE in a repo’s committed .mcp.json arrived as an environment url, outranked the keystore, and every teammate’s proxy sent its real workspace key to that host on the next start, during session-key minting, with no prompt. An environment url is now honored only alongside an explicit RETASC_MCP_KEY, where the key and the url share a trust domain. Nothing legitimate loses a path: bind already stores the deployment’s url into the binding, so a self-hosted url is in the keystore before the proxy asks for it. This closes the url, and only the url. A committed marker also chooses the command that runs and can set any other variable, so a marker you do not trust is code execution by the MCP config format’s own design, and the harness’s project-trust prompt is the boundary for that. What this removes is the one variant that reads as ordinary configuration in review.

1.39.0

2026-08-30
  • RTSC-793retasc setup now wires Cursor, OpenCode and Gemini CLI too, bringing it to six harnesses.
  • RTSC-793retasc setup now wires Cursor, OpenCode and Gemini CLI too, bringing it to six harnesses. Until this release those three could be installed and running on your machine and setup would say nothing about them: it only ever named harnesses it already knew, so an unsupported one was not reported as skipped, it was invisible, and the receipt read as complete. That is the same silent half-install the previous release existed to end, one harness over. Each was admitted the same way the first three were, by checking a real installation rather than a config format from memory. The check that decides it is whether the harness starts its MCP server in the project directory, because the entry we write names no project and works out the folder for itself; one that started somewhere else would resolve every folder to the same wrong place with no symptom. All three passed. Cursor is wired by editing ~/.cursor/mcp.json directly, and carefully: that file is named .json but Cursor accepts comments in it, so we splice our entry in textually and leave every comment, every other server and everything else exactly where it was. OpenCode and Gemini are wired through their own opencode mcp add and gemini mcp add, which is better than a writer of ours when a harness ships one that works: their file format stays their business. Note for Cursor users: it is cursor-agent, the agent, that gets the tools. The cursor command is the editor launcher and is a different program. Also fixed: the setup receipt could run a path into the word beside it, printing ~/.codex/config.tomlupdated, which read like a corrupted path in the one place whose job is to say plainly that everything worked.

1.38.2

2026-08-30
  • RTSC-789bind keeps this folder’s key instead of minting a new one on every run.
  • RTSC-789bind keeps this folder’s key instead of minting a new one on every run. The guard meant to prevent that (RTSC-262) read the --org-id/--project-id flags, so it only ever fired for a provisioning script. The canonical npx @retasc/cli@latest bind leaves both undefined and could never reach it: pick the same org and the same project from the menu and it minted anyway, leaving the old key live. The check now runs where the target is known, after the pick, so how you got there stops mattering. A different org or project still mints, as it must. A kept key is resolved against the server before it is kept. bind clears a binding only when the server answers UNAUTHORIZED, so a folder can reach the reuse branch holding a key whose health is unknown: a 5xx, a proxy sign-in page, a refusal whose wording drifts. Keeping one of those would have stranded the folder for good, since doctor sends that exact state back to bind. It falls back to minting instead, which is the self-healing the old mint-every-run was providing by accident.

1.38.1

2026-08-28
  • RTSC-780 follow-upretasc init now sets a folder up the same way every other door does.
  • RTSC-780 follow-upretasc init now sets a folder up the same way every other door does. 1.38.0 taught bind, join and bind --setup to wire every harness on the machine, but init kept its own copy of that work: it minted a key and wrote a key-bearing entry for Claude Code and nothing else. So the one command named onboarding was the one that still left Codex with no Retasc tools, which is the exact failure 1.38.0 exists to end. Fixed by deleting the duplicate rather than teaching it the same trick. Everything after the org is now bind’s job, which also means init writes the keystore binding an auto marker resolves against, guards a folder that is already bound instead of overwriting it, and prints the same receipt. --scope and --no-watchdog are gone from init: both described the shape of an entry it no longer writes. -y/--yes and --no-install are there instead, matching bind.

1.38.0

2026-08-28
  • RTSC-780retasc setup wires Retasc into every MCP harness on the machine, once, and retasc bind now runs it for you.
  • RTSC-781--runtime now says what it does.
  • RTSC-780retasc setup wires Retasc into every MCP harness on the machine, once, and retasc bind now runs it for you. Until this release the CLI could wire exactly one harness: it spawned claude mcp add, and if that worked it stopped. Codex, Grok and anything else got nothing, which is why an agent bound to the same project as two working Claude Code sessions could sit there unable to claim a single issue. The entry we write names no project and carries no key. The watchdog proxy works out which project it is in from the directory it was spawned in, so one line in a global config is correct in every folder, and the folder still decides the org exactly as before. Adding a harness is one entry in the registry; Claude Code, Codex and Grok ship today, each verified against a real installation rather than a config format from memory. A folder you have not bound yet is now an ordinary state rather than a broken install, so it gets a real answer: the tool call comes back naming the folder and telling you to run retasc bind in it. Previously a keyless call surfaced as an authentication or network failure while the CLI’s own login was global and still fine, which reads as “the Retasc server is down” and sends you to check a server that is serving everyone else. The server cannot name your folder; the proxy runs in it, so it can. Which folder counts is bounded by the repository: a subdirectory resolves to its repo, and a repo checked out inside a bound directory resolves to nothing. Binding a directory must not quietly bind every unrelated project underneath it. Existing markers are untouched: one naming a workspace id keeps resolving through that id, and keeps priority over the folder.
  • RTSC-781--runtime now says what it does. It sets the agent’s label in the Dash, and it never chose where config was written, but it is offered on the commands that install MCP config and documented with a list of harness names, so key mint --runtime codex --install named Codex, wired Claude Code, and said nothing. The help text says label, and the commands that mint a key and write a key-bearing entry now say plainly that they write for this folder only, that a key never belongs in a machine-wide config, and that retasc setup is what wires the harness you named.

1.37.0

2026-08-26
  • RTSC-749retasc triage reads and approves work filed from outside your org.
  • RTSC-749retasc triage reads and approves work filed from outside your org. Work that arrives through a GitHub or GitLab connector is written by whoever can file on that repo, and since RTSC-746 no agent can pick it up until a person has read it and approved it. This is that decision from the terminal: retasc triage lists what is waiting, retasc triage RTSC-42 prints the full body and then asks. It is deliberately hard to automate, because the CLI runs where coding agents run: there is no --approve flag, the command refuses to run without an interactive terminal, and confirming means retyping the issue id rather than pressing y. Saying no is as cheap as saying yes (type reject) — the safe answer must never be the expensive one. The Dash stays the recommended surface: an agent that can drive a real PTY on your machine could drive this command too, and only logging the CLI out takes that away.

1.36.1

2026-08-25
  • RTSC-645retasc gate install no longer throws away your edits.
  • RTSC-645retasc gate install no longer throws away your edits. It rewrites the commit-msg hook and the Action on every run, so a gate you had customized (say, one that also checks the branch number) used to vanish behind a green ”✓ Updated” with nothing saying so. Generated files now carry a hash of their own contents, so a later run can tell “still exactly what we wrote” from “someone changed this”. A changed file is copied to .bak first, keeping its permissions, and the run tells you where the copy went; a second round of edits goes to .bak.2 rather than overwriting the first. Untouched files are replaced silently as before, including when you re-key the gate to a different prefix, so the common path gained no prompts and no flags.

1.36.0

2026-08-25
  • RTSC-520 — the CLI now says when it is out of date.
  • RTSC-520 — the CLI now says when it is out of date. There was no version check anywhere in cli/, so a global install went stale silently and stayed that way for as long as the machine lived — and a stale CLI does not merely lack features, it lies: its copy describes SERVER behaviour, so 1.11.0 kept telling people a decline “covers the whole org, including later migrations” long after RTSC-507 made that false, and 1.10.0 had no Google door, so it sent Google-only humans through GitHub and minted them a second identity. After any login-gated command an outdated build now prints one line naming both versions and asks whether to update:
    Notify then ask, never a silent npm i -g: interactive terminals only (no TTY prints the notice and nothing else, so scripted runs are unchanged), at most once a day with a decline remembered, and a failed install — EACCES on a root-owned prefix is the common one — reports itself and names npm i -g @retasc/cli@latest without ever failing the command you actually ran. A successful update says it applies from your next command and that agents need restarting to pick up the new MCP server. The MCP proxy never prints it. The published version is resolved server-side from the npm registry, cached hourly, and handed down on manage:me — a call every login-gated command already makes, so checking costs no round trip and no shared rate limit, and no release step can forget to update it. An optional RETASC_CLI_MIN_HONEST marks the oldest version whose copy still matches the server; below it the notice says so plainly, because “a newer version exists” and “what this build just told you may be false” are different problems.

1.35.2

2026-08-25
  • RTSC-743 — the last CLI replies that answered a person with a machine shape now answer in sentences.
  • RTSC-743 — the last CLI replies that answered a person with a machine shape now answer in sentences. A failed MCP request used to paste 200 characters of the raw response body after the status, which on that endpoint is either a JSON-RPC envelope or, when the failure lands at Cloudflare rather than in Convex, a page of HTML; it now says what the status means and what to do about it, and reads the body for a message rather than printing it. A reply that is not JSON at all (a proxy error page, a captive portal) named a JSON parser’s position; it now names what actually answered. retasc login stringified GitHub’s whole OAuth payload into its error, burying error_description, the one field in it written for a person. whoami and doctor could surface a bare parser complaint from resolveBinding, which is a poor answer to “what is broken?” from the two commands you run when something already is. And retasc import printed the summary with the wire payload’s own field names as labels — issuesCreated, commentsInserted, attachmentsRehosted — where it now prints Issues created, Comments and Attachments copied. Along the way, doctor and whoami stop telling you to re-run retasc bind when the thing that answered was a proxy rather than Retasc: that failure carries no verdict on your key, and re-binding to fix it mints a new one for nothing.

1.35.1

2026-08-25
  • RTSC-478 — a network failure now names its own cause.
  • RTSC-478 — a network failure now names its own cause. Node reports every failed fetch as the literal fetch failed and puts the diagnosis on err.cause.code, which the CLI read past, so retasc login on a machine whose TLS trust store Node cannot read died on ✗ fetch failed and nothing else. It now prints ✗ fetch failed (UNABLE_TO_GET_ISSUER_CERT_LOCALLY) — a searchable string naming the real problem. cli/README.md gains a troubleshooting entry keyed on that code, covering both causes: a corporate TLS-inspecting proxy, and a Homebrew openssl@3 keg that lost its CA symlink (the confusing one, since curl and npm keep working).

1.35.0

2026-08-25
  • RTSC-709retasc issue show and retasc issue list read the queue from a terminal.
  • RTSC-709retasc checkpoint and retasc check-claim close the claim lifecycle.
  • RTSC-709done reads the issue back before it closes it.
  • RTSC-709cli/README.md now records which MCP tools are deliberately Dash-and-MCP-only, and why, so their absence from the CLI reads as a decision rather than an oversight.
  • RTSC-709retasc issue show and retasc issue list read the queue from a terminal. tidy and done both reason about issue status, and until now a human asked to accept their verdict had no way to see that status without opening the Dash. Both default to the current rtsc-NN/ branch’s issue, list takes the same filters the MCP surface does (status, priority, label, author, assignee, SLA, limit), and both take --json.
  • RTSC-709retasc checkpoint and retasc check-claim close the claim lifecycle. claim, next, release and done all existed, so a human could take work, hand it back and finish it, but could not record progress on it or answer the question workflow.md says to settle at runtime: is anything actually renewing my lease? check-claim prints the last renewal time and exits non-zero when you do not hold the issue, so a script can branch on it.
  • RTSC-709done reads the issue back before it closes it. It was one word that closed an issue with no read path to confirm first, and it closed one whose PR was still open and unreviewed. It now prints the id, the title, the status transition and whether the branch is merged, and asks before closing on a TTY. --dry-run shows the readback and the teardown plan without touching anything, -y skips the prompt, and a non-TTY still closes, so scripts are unchanged.
  • RTSC-709cli/README.md now records which MCP tools are deliberately Dash-and-MCP-only, and why, so their absence from the CLI reads as a decision rather than an oversight.

1.34.1

2026-08-25
  • RTSC-741 — a rejected write no longer costs you the lease.
  • RTSC-741 — a rejected write no longer costs you the lease. The watchdog decided when to stop heartbeating an issue by looking at the request you sent, never at whether the server accepted it. So a save_issue that came back an error still dropped the issue from the heartbeat map while you were still holding it. Nothing renewed it after that, it ran out its half hour, and the reclaimer handed your work to another agent while you were in the middle of it, with no sign anything had gone wrong. Every drop now requires the call to have actually succeeded. The trigger is the new server-side rule that moving an issue into review must carry a handoff: a rejection on that write is the expected first attempt for any agent that has not learned the field yet, so a rare edge became a common one.

1.34.0

2026-08-24
  • RTSC-731bind stops asking whether you want to join an org you are already in.
  • RTSC-731 — the invite questions hand back a value your agent can actually use.
  • RTSC-731bind stops asking whether you want to join an org you are already in. A teammate given access to a second project was shown “Join Retasc, or start your own workspace?”, with the second option one keystroke away from creating a duplicate organization that cannot be deleted from the terminal. Invites that only add projects to a membership you already have are no longer treated as onboarding, and no longer suppress the single-org shortcut. Your agent still hears about them, and setup_status now asks about them in its own words, naming the project and the organization so “Retasc the org” and “Retasc the project” can’t be confused.
  • RTSC-731 — the invite questions hand back a value your agent can actually use. Both onboarding questions told the agent to pass the chosen answer to accept_invite’s org flag, then offered “join” as that answer — so an agent doing exactly what it was told got “no invite to join is waiting for you”, while one that ignored the instruction and read the prose succeeded. The accept option now carries the organization itself.

1.33.0

2026-08-23
  • RTSC-722 — the setup questions arrive as a matrix your agent can actually render.
  • RTSC-722 — the setup questions arrive as a matrix your agent can actually render. 1.32.0 sent three of the four as free text, and a picker cannot draw a question with no options, so the whole set collapsed back into the numbered list in prose that RTSC-720 existed to remove. They now carry defaults derived from the folder you are standing in: in ~/the egg you get The Egg, The Egg, EGG, and the folder confirm, four clicks instead of three typed answers. Every question keeps a “Something else” escape. Folders that name nothing about the work (/Users, your home directory, src, a dotfile, anything too long for the server to accept) suggest nothing and fall back to text, because a plausible wrong default is worse than no default when what you are confirming is which folder gets connected. Picking a project in an org that has more than four is a picker too now, instead of an unrenderable list of every project.

1.32.0

2026-08-23
  • RTSC-720 — when bind --json stops to ask, it hands your agent the exact questions as data: what to call the workspace, the first project, its prefix, and a confirmation naming the precise folder about to be connected — with the flag each answer fills.
  • RTSC-721retasc unbind exists.
  • RTSC-721bind heals a dead binding instead of interrogating you about it.
  • RTSC-720 — when bind --json stops to ask, it hands your agent the exact questions as data: what to call the workspace, the first project, its prefix, and a confirmation naming the precise folder about to be connected — with the flag each answer fills. Your agent presents them instead of paraphrasing a status line, which is the difference between being asked “what should we call it?” and being told “you have no organization” by an agent waiting for you to notice.
  • RTSC-721retasc unbind exists. It puts a folder back the way it was before bind: the keystore entry, the MCP entry in either location it can live, and the agent key — revoked server-side when your session can, named for the Dash when it cannot. Until now undoing a binding meant hand-editing five places, one of them keyed by an id nothing surfaces, with the key left live throughout. It confirms before removing anything, names the absolute folder, and leaves your sign-in alone — retasc logout is still its own decision.
  • RTSC-721bind heals a dead binding instead of interrogating you about it. Come back months later, after the workspace was deleted or the key revoked, and bind used to ask “Replace it?” about a binding that no longer worked — a confusing question at the exact moment you were least equipped to answer it. It now says the binding is no longer accepted, clears it, and reconnects. Only on the server’s own refusal: a network failure still lands on the cautious path, because clearing a healthy credential to fix a problem your machine does not have would be worse than asking.

1.31.1

2026-08-23
  • RTSC-715 — setup no longer finishes by wiring a retasc command that is not there.
  • RTSC-715 — setup no longer finishes by wiring a retasc command that is not there. Run as npx @retasc/cli@latest bind, the CLI asked whether retasc was on your PATH and got yes, because npx puts its own cache directory on the PATH of whatever it runs. So the answer was true while bind ran and false the moment it exited, and your agent started with ENOENT: Executable not found in $PATH: "retasc" after a setup that had reported success. It now checks that the command it found will still resolve afterwards, and falls back to a global install or a pinned npx launcher when it will not.

1.31.0

2026-08-23
  • RTSC-713 — your agent can set Retasc up for you.
  • RTSC-713bind --json reports what it did and what it still needs, one JSON object per line, and prints the approve URL the moment it exists rather than at the end.
  • RTSC-713 — a setup that paused is no longer dressed as a crash.
  • RTSC-713 — sign-in no longer refuses merely because nothing is attached to a terminal.
  • RTSC-713 — every outcome names the absolute folder it is about to connect, so a wrong one can be caught before anything is written.
  • RTSC-691retasc login opens your browser instead of asking you to retype an eight-character code.
  • RTSC-691 — the code path stays for the places a browser round trip cannot work: inside a container, and over SSH, where the redirect would target 127.0.0.1 on whichever machine opened the link and so could never reach the CLI waiting on the remote host.
  • RTSC-691retasc release <RTSC-NN> --claim-token <token> exists.
  • RTSC-691retasc bind prints “restart your agent” whether or not a human is watching.
  • RTSC-691bind clears the credential-less bootstrap entry that would otherwise shadow the binding it just wrote, when the two land in different scopes.
  • RTSC-713 — your agent can set Retasc up for you. It runs bind itself now, so nothing asks you to open a terminal and type a command: you paste one line into the chat, click Approve in the browser that opens, and restart your agent. The command it runs is bind --json, the door built for a machine to drive.
  • RTSC-713bind --json reports what it did and what it still needs, one JSON object per line, and prints the approve URL the moment it exists rather than at the end. Your agent posts that URL to you as a link, which is what makes this work on a machine where the browser does not open by itself.
  • RTSC-713 — a setup that paused is no longer dressed as a crash. “Signed in, but you have not said which project this folder is for” exits 0 and says exactly that; only a real dead end exits non-zero. It used to exit 1 with ✗ UNAUTHENTICATED, and an agent reading that reasonably concluded setup had failed and stopped, one question short of done, holding a session that had actually worked.
  • RTSC-713 — sign-in no longer refuses merely because nothing is attached to a terminal. It asks whether a browser can be reached, which is the thing that actually matters. SSH, containers and CI still refuse, and still refuse fast: over SSH the approve link targets 127.0.0.1 on whichever machine opened it, so it could never reach the CLI waiting on the remote host.
  • RTSC-713 — every outcome names the absolute folder it is about to connect, so a wrong one can be caught before anything is written. A wrong folder has no symptom otherwise: the agent still calls in and the Dash still looks healthy.
  • RTSC-691retasc login opens your browser instead of asking you to retype an eight-character code. Click Approve once and you are signed in, and you pick GitHub, Google or a passkey in the Dash where you are usually signed in already, instead of answering that question in the terminal. The device flow is still there and still works; it is the fallback now rather than the only door.
  • RTSC-691 — the code path stays for the places a browser round trip cannot work: inside a container, and over SSH, where the redirect would target 127.0.0.1 on whichever machine opened the link and so could never reach the CLI waiting on the remote host. RETASC_NO_BROWSER=1 forces it everywhere.
  • RTSC-691retasc release <RTSC-NN> --claim-token <token> exists. Two error messages in retasc claim had been telling people to run it for a while, and it was not a command. The token is the one printed when you claimed; the server fences on it, which is what stops one agent releasing another’s work. Releasing leaves your worktree and branch alone — retasc tidy is what reaps those.
  • RTSC-691retasc bind prints “restart your agent” whether or not a human is watching. It was suppressed when output was not a terminal, which is exactly when an agent is the one reading it and the one that has to pass the message on.
  • RTSC-691bind clears the credential-less bootstrap entry that would otherwise shadow the binding it just wrote, when the two land in different scopes.

1.30.0

2026-08-20
  • RTSC-681 — your agent can read a file you attached to an issue.
  • RTSC-681 — downloads land under .retasc/attachments/ in your workspace, one folder per attachment, never overwriting anything and never following a symlink, in a directory that ignores itself so a customer’s certificate cannot be committed by accident.
  • RTSC-681 — your agent can read a file you attached to an issue. Uploading has been one call since 1.24.0; reading one back needed an API key the model does not have and is told not to go looking for, so a certificate attached for an agent to verify was something it could see the name of and nothing else. get_attachment_file closes it: name the attachment id, the proxy downloads it with the credential it already holds and hands back a path to read. Any size, and the bytes never pass through the model’s context.
  • RTSC-681 — downloads land under .retasc/attachments/ in your workspace, one folder per attachment, never overwriting anything and never following a symlink, in a directory that ignores itself so a customer’s certificate cannot be committed by accident. There is no destination argument on purpose: a write the proxy performs skips the prompt your harness would otherwise show you, so it only ever writes to the one place it owns. Copy the file where you want it and your normal tools ask you first, which is the point.

1.29.0

2026-08-19
  • RTSC-672 — every command we hand out now says npx @retasc/cli@latest.
  • RTSC-672 — a first-run failure names the build that produced it, so “it still doesn’t work” and “you’re running last week’s CLI” stop looking identical.
  • RTSC-672 — every command we hand out now says npx @retasc/cli@latest. npx caches by spec, so a bare npx @retasc/cli can keep serving whatever version you first ran — which meant the people most likely to re-run a command, the ones who hit a bug and were told it was fixed, were exactly the ones liable to be served the broken build again. @latest is a tag, not a pin: it re-resolves every time and can never go stale, where a version number written into docs absolutely can.
  • RTSC-672 — a first-run failure names the build that produced it, so “it still doesn’t work” and “you’re running last week’s CLI” stop looking identical.

1.28.0

2026-08-19
  • RTSC-676 — signing in opens your browser.
  • RTSC-676 — the finish screen’s closing lines are flush left, and it ends with a blank line instead of welding the shell prompt to the last thing you read.
  • RTSC-676 — signing in opens your browser. It used to print a URL and an eight-character code and leave you to switch windows, navigate, and retype it. Now the page opens for you, pre-filled when the provider supplies RFC 8628’s complete URL. The URL and code are still printed first and always: there is no browser inside a container or over SSH, which is where bind runs most, so the browser is a convenience layered on top and never the only way through. A missing xdg-open changes nothing. RETASC_NO_BROWSER=1 turns it off.
  • RTSC-676 — the finish screen’s closing lines are flush left, and it ends with a blank line instead of welding the shell prompt to the last thing you read.

1.27.0

2026-08-19
  • RTSC-673bind ends by telling you what to do, not by dumping config.
  • RTSC-673bind ends by telling you what to do, not by dumping config. It used to close on fourteen lines of MCP JSON plus “(Claude Code CLI not detected)”: a block instructing you to paste something we had just written to disk for you, and a note that reads like a fault on a screen whose whole content is that everything worked. Between them they buried the one thing a new owner needed. Now it prints a receipt card — org, project, where the key went, what landed in your repo — and then says to start your agent. The closing lines follow the project: an empty one invites you to describe what you’re building, a project with work in it tells you to say “next issue”. The JSON still prints when the marker could not be written anywhere, which is the case it exists for.

1.26.0

2026-08-19
  • RTSC-670retasc bind can sign you in again.
  • RTSC-671 — errors name the command you actually ran.
  • RTSC-670retasc bind can sign you in again. It has opened with the device flow since 1.20-era, but a leftover session guard in the command wrapper exited first, so on a machine that had never signed in — the only state a new owner is ever in — bind printed “Not signed in” and stopped. Owner onboarding dead-ended at its first documented command, on every release for three weeks. The guard was correct when it was written and became redundant the moment bind grew its own sign-in; nothing noticed because no test ran the CLI with no session. Four now do.
  • RTSC-671 — errors name the command you actually ran. Told to npx @retasc/cli bind and then answered with “Run retasc login first”, you were pointed at a binary that invocation never installs — a recoverable stumble turned into a dead end. Every “run X first” message now renders npx -y @retasc/cli@<version> … or retasc … to match how you started it.

1.25.0

2026-08-19
  • RTSC-669 — the invite project picker takes several projects.
  • RTSC-669 — the invite project picker takes several projects. 1.24.0 shipped it single-select, which left “two of these four” expressible nowhere: the workaround — repeating --project-id — needs ids that nothing in the CLI lists, which is the gap the picker existed to close. Answer 2,4 (or 2 4) and the invite grants exactly those. Naming every project collapses to all projects, so the grant follows the org as it grows rather than freezing today’s list. 1) All projects can’t be combined with individual ones: that’s a contradiction about the widest grant there is, so it re-asks instead of guessing which half you meant.

1.24.0

2026-08-19
  • RTSC-667retasc members invite asks instead of demanding ids.
  • RTSC-666 — the PROJECTS column in retasc members list comma-joins, so two projects read as XTRO, XTRO Marketing rather than running together.
  • RTSC-664 — invite someone to one project, not the whole org.
  • RTSC-667retasc members invite asks instead of demanding ids. It used to require --org-id, and the new --project-id made that worse: nothing in the CLI lists project ids, so a scoped invite meant fetching one from the Dash. Run it with no flags in a terminal and it asks which org (only the ones you can actually invite into) and which projects, with All projects as the first option rather than the thing you get by not answering. It asks nothing when there is nothing to choose — one eligible org, or fewer than two projects — and a script with no TTY behaves exactly as before. The flags still work and still win.
  • RTSC-666 — the PROJECTS column in retasc members list comma-joins, so two projects read as XTRO, XTRO Marketing rather than running together.
  • RTSC-664 — invite someone to one project, not the whole org. Membership was org-level, so anyone you invited read every project you had. retasc members invite now takes --project-id <id>, repeatable, and the invitee lands scoped to exactly those projects. Omitting it still grants every project, so an existing script keeps its behaviour untouched and an org that never scopes anyone never notices this shipped. retasc members list gains a PROJECTS column naming what each code confers, with All for the unscoped ones — an unscoped invite is the WIDEST grant, and a column that rendered it as a dash would read as “none”. Enforcement is server-side at every door, agent auth included: a key whose project leaves its principal’s scope stops authenticating on its very next call.

1.23.0

2026-08-17
  • RTSC-660 — the proxy attaches files for you.
  • RTSC-660 — the proxy attaches files for you. Attaching a file was the one Retasc write an agent could not finish on its own: the server handed back an upload URL and told the caller to POST the bytes with “your API key”, which under MCP lives in the proxy, not in the model. Agents were resorting to reading the key out of ~/.retasc/bindings.json, and harnesses were blocking that as credential harvesting. The proxy now serves save_attachment_file(issue, path, title?) itself: it reads the file and uploads it with the key it already holds, so nothing about the credential reaches the model and the bytes never pass through its context. Readable paths are confined to a root — RETASC_ATTACH_ROOT if set, otherwise the proxy’s working directory — compared after resolving symlinks on both sides, with .git and non-regular files refused, because reading a file on the agent’s behalf skips the harness’s own file-access prompt. Every accepted read is logged to stderr with its resolved path. Calls that pass contentBase64 instead are forwarded to the server untouched.

1.22.0

2026-08-12
  • RTSC-646 — the watchdog now says when it is not renewing a lease.
  • RTSC-646 — the watchdog now says when it is not renewing a lease. Its lease set is in-memory and built only from claim traffic this proxy saw, so a claim made in another terminal, over direct HTTP MCP, or by a previous proxy before a harness restart was renewed by nobody — silently, until the reclaimer took the issue away mid-build. Touching such a lease now prints a warning naming the issue and what to do about it (release_issue is exempt: it ends a lease rather than needing one). A heartbeat rejected as UNAUTHORIZED is also called out loudly, once: that means the session’s credential died, not the lease, so every claim stops renewing at the same moment and each lapses at its own expiry. The proxy keeps tracking and keeps trying, because re-minting the key inside the TTL recovers all of them. The mcp install --watchdog text no longer stops at “no per-claim heartbeats” — it names both bounds: the proxy must be running, and it only renews claims it saw this session make.

1.21.1

2026-08-10
  • RTSC-643retasc gate install keys the gate to this folder’s project, not the machine-wide default.
  • RTSC-643retasc gate install keys the gate to this folder’s project, not the machine-wide default. It used to read defaultProjectPrefix (stamped by whichever project you last ran retasc init for), so in a bound folder it could install a commit gate keyed to a different project — rejecting every valid commit — while reporting success. It now asks the folder’s own binding first (whoami over the workspace key, or the keystore’s cached prefix offline; a subdirectory run checks the git toplevel too), prints where the prefix came from, warns when the global default disagrees, and only uses the global default when the folder is genuinely unbound. Bound-but-unresolvable fails loudly instead of guessing.

1.21.0

2026-08-07
  • RTSC-527 — the re-import warning dates the last import in your timezone.
  • RTSC-527 — the re-import warning dates the last import in your timezone. The day was formatted from toISOString(), which rolls back one east of Greenwich: at UTC+7 an import made five hours ago read as yesterday’s, which is the opposite of useful for a line whose job is to say how long ago it was. The Dash gained the same date in the same shape in this release, and moved onto the same durable per-source history the CLI already read, so the two surfaces now describe one import the same way.

1.20.0

2026-08-04
  • RTSC-561 — the org gained an admin role, and the CLI stopped refusing it.
  • RTSC-561 — the org gained an admin role, and the CLI stopped refusing it. retasc billing gated on role !== "owner" client-side, so it would have refused an admin locally for a call the server allows. Owner-only copy in bind and the command help now names both roles.

1.19.0

2026-08-03
  • RTSC-495retasc bind --setup <code> sets a folder up with no sign-in and nothing to answer, so an agent can do it on behalf of someone who does not use a terminal.
  • RTSC-532 — the agent says which folder it is in, and the key remembers.
  • RTSC-495retasc bind --setup <code> sets a folder up with no sign-in and nothing to answer, so an agent can do it on behalf of someone who does not use a terminal. The Dash’s connect step now hands over a block you paste to your agent, with this command inside it. Everything the interactive bind would ask was already answered in the browser, and the code carries those answers across. An agent’s shell is not a TTY, so the ordinary path refuses it outright at the first prompt.
    The code is single-use and lives ten minutes. The alternative — pasting a real API key into the prompt — needed no backend at all, but would have left a long-lived credential in an agent’s conversation history forever. A folder that is already connected is refused rather than silently replaced, and the refusal happens BEFORE the code is spent, so a mix-up costs nothing.
  • RTSC-532 — the agent says which folder it is in, and the key remembers. Binding the wrong folder used to look exactly like success: the agent still called in, so the Dash went green, while the folder you actually work in had no Retasc in it. The prompt now asks the agent to report its full path and wait before it runs anything, and the confirmation names the real path instead of “This folder”. The key it creates is named after that folder, so the Keys page shows which folder each key belongs to (client-a) instead of naming them all after the project (ENG key).

1.18.0

2026-08-02
  • RTSC-530 — setting up from scratch now asks where your work comes from, and imports it in the same command.
  • RTSC-530 — setting up from scratch now asks where your work comes from, and imports it in the same command. retasc bind used to offer one thing at the project step: name a new project. So someone arriving from Jira had to invent a project they didn’t want, run retasc import afterwards to get the one they did, and leave the empty one behind — and projects can’t be deleted individually.
    Pick a tracker and the import runs right there, then the folder binds to the project it created. Pick “start from scratch” and it behaves exactly as before. This is the same fork the Dash has always offered; importing isn’t a separate errand, it’s one of the ways a first project comes into existence. Only when the org has no projects — binding a second folder in an existing org is still just picking from the list. Declining at the import confirmation falls back to naming a project rather than abandoning setup: you still asked to bind the folder.

1.17.0

2026-08-02
  • RTSC-529 — the column mapping is a numbered picker, like every other prompt.
  • RTSC-529 — the column mapping is a numbered picker, like every other prompt. It was the only one that made you type a word. Picking an org, a project, a source, a list, a reviewer, a sign-in door or whether to install globally are all numbered lists reading Choose a number — and the reviewer picker appears two lines below this one, so a single import taught two input styles within four lines of output.
    Enter still takes the suggestion, now marked in the list rather than described beside it. Typing the word still works for anyone who has learned the vocabulary; it just isn’t what the prompt advertises.

1.16.1

2026-08-02
  • RTSC-528 — two things the first real retasc import run turned up.
  • RTSC-528 — two things the first real retasc import run turned up. The progress bar never appeared. It only started drawing once it had seen the run reported as running, and a 15-issue import finishes before that is ever observed, so the output went straight from Importing… to ✓ Imported. with a silent gap. It now draws the moment the run starts, sweeping while it waits for counts and switching to the real bar once they arrive. Still silent without a terminal and under NO_COLOR. The column prompt didn’t say what to do. It read to do [todo] (todo / doing / done / canceled):, where nothing is a verb, so the first person to run it had to guess that you type one of the words. Now:
    The suggestion is no longer repeated among the alternatives, which is what made the old line read as four equal options behind a mysterious bracket.

1.16.0

2026-08-02
  • RTSC-526retasc import catches up with the Dash on four things.
  • RTSC-526retasc import catches up with the Dash on four things. It warns before a second import. Re-importing does not duplicate anything, but it does re-sync: status, labels, title and body are replaced with whatever the source says now. Import from Jira, spend two weeks moving issues along in Retasc, re-import to pick up new tickets, and those two weeks of changes snap back. You now get told, with the date of the last import, before the confirmation. The run shows progress, as a bar that fills while it works, rather than a silent wait that looks like it has hung. The run is server-side, so pressing Ctrl-C out of boredom never stopped it anyway. The column list is grouped under your own tool’s sections (Not started, Active, Done, Closed) instead of arriving flat. On a twenty-column board that is the difference between scannable and a wall. Columns that were not mapped are named. If a column appears between the moment you set the mapping and the moment the import runs, its issues land in todo. They used to show as a number; now they are listed, with what to do about it.

1.15.0

2026-08-02
  • RTSC-524 — new command: retasc import.
  • RTSC-524 — new command: retasc import. Bring a Linear, Jira, Asana, ClickUp or Shortcut project across without opening a browser. This was the last thing the terminal could not do. Everything else — sign in, make or join an org, create a project, wire the folder, pull work — already worked end to end, but importing meant stopping and finishing in the Dash.
    It walks you through the source, your credentials, which team or project to take, and then what each of your columns means. That last part is the point, and it is asked rather than guessed: a tool lets its users name their own columns, so the only honest way to know what one means is to ask you. Pressing Enter accepts a suggestion derived from the column’s type in your tool, never its name — a column called “Rejected” that is really an in-progress lane maps to doing, not canceled. A column mapped to review needs a named reviewer, chosen per column, because two “awaiting acceptance” columns can belong to different people. Columns holding work nobody has started cannot be mapped to review at all, and the CLI says why rather than letting the server refuse it later. Your source token is never an argument. There is no --token, because anything passed that way lands in shell history and in ps output. Secrets are typed with echo off, or taken from RETASC_IMPORT_<FIELD> for scripted runs. The run is confirmed before anything is written, and afterwards you are offered the imported identity the migration just created for you, through the same prompt retasc join uses.

1.14.0

2026-08-02
  • RTSC-523 — setup asks before installing anything on your machine.
  • RTSC-523 — setup asks before installing anything on your machine. retasc bind and retasc join are one command you paste and answer, and somewhere in the middle they ran npm install -g @retasc/cli. It said so, but it never asked. That is the only step in a folder-scoped command that changes the machine rather than the folder, and a shared npm prefix is exactly what plenty of developers keep clean.
    Both answers leave the folder bound identically. Option 2 is not a per-project install: nothing is written to the folder, so it needs no package.json and cannot fail for want of an npm project. Your answer is remembered, because it is a question about the machine and the machine has not changed by the time you bind a second folder. You are only asked when it would actually happen. If retasc already works, there is nothing to decide and nothing is said. Without a TTY it installs, exactly as before. That is deliberate rather than a leftover: when an agent runs setup on someone’s behalf, that person never types retasc, but their agent starts the MCP server every session, and the on-demand route would cost them seconds and a network dependency every single time. --no-install on bind and join declines without a TTY, for a developer whose own agent is doing the setup.

1.13.1

2026-08-02
  • RTSC-522 — the changelog is public, and five releases that were never written down now are.
  • RTSC-522 — the changelog is public, and five releases that were never written down now are. It used to be unreachable by anyone who installs the CLI: it did not ship in the tarball, the README never mentioned it, and the source repo is private so the npm repository link 404s for the public. It is now at docs.retasc.com/changelog, and ships in the package. 1.1.0, 1.1.1, 1.1.3, 1.2.1 and 1.2.2 were published and never described. They are reconstructed here from their release commits and the issues they reference, so every version on npm now has an entry. Each one carries its publish date. Also fixed two npm-facing details: the package description still said “sign in with GitHub”, which stopped being the whole truth at 1.11.0, and the bug-report link pointed at a private repository that 404s for everyone npm showed it to.

1.13.0

2026-08-02
  • RTSC-521 — five commands stopped answering you with a JSON dump.
  • RTSC-521 — five commands stopped answering you with a JSON dump. whoami, org create, project create, key list and members list printed the raw payload. whoami is the one people actually noticed, because it is the command you run to find out who you are:
    The one fact you wanted was a bracket to parse, next to a document id that means nothing. Now:
    key list and members list are aligned tables, and state reads as words: a revoked key says revoked rather than an epoch, and a spent invite shows no expiry date because the date stopped meaning anything. Auto-minted session keys are folded into a count instead of drowning the keys you can actually manage. Ids follow one rule: shown when a command takes them, dropped when nothing does. So org create gives you the org id and names the command that wants it, and never mentions ownerMemberId. --json on all five, emitting exactly what they printed before. Anything scripted against the old output keeps working by adding the flag. whoami’s binding block is unchanged. It was already the useful half.

1.12.0

2026-08-02
  • RTSC-519retasc bind now tells you it finished, and what to do next.
  • RTSC-507 — “none of these are me” now covers the tools you were asked about, not the whole org forever.
  • RTSC-519retasc bind now tells you it finished, and what to do next. It used to end on the last thing it did (“This folder is bound to org Acme / project ACM”) and stop. So the person who set up their own org was left reading a status line and guessing whether anything else was required, while the invited teammate, who arrives through retasc join, was told. Both commands now end the same way:
    The restart half matters: .mcp.json is read when an MCP client starts, so an agent already open on that folder won’t see Retasc until it restarts — and bind is routinely run from inside a session that’s already there. The sentence lives in the tail both commands share, rather than a copy in each, so neither can lose it again.
  • RTSC-507 — “none of these are me” now covers the tools you were asked about, not the whole org forever. Declining wrote one org-wide flag, checked before the list of imported people was even read. So the January answer “I was never in ClickUp” — correct, and the cheapest possible answer to give — meant that when the org migrated off Jira in June, where you did have an account, you were never offered your placeholder. Not by retasc identity, not by retasc join, not by the Dash, not ever. Your Jira authorship, comments and assignments stayed on a placeholder permanently, and only an owner could repair it. Claiming was already tracked per source, so someone who claimed their ClickUp identity was correctly re-asked at every later migration. Declining being the more final of the two was backwards. The decline row now names what it covers:
    and retasc identity says so when nothing is left:
    That replaces wording saying the answer “covers the whole org, including later migrations” and pointing at an owner. It existed only to describe this bug. Needs the matching backend deploy. The copy above is a promise the server keeps, so publish this only after convex deploy and migrations:backfillDismissedSources have run. Against an older backend the CLI would say a later import will ask again, and it would not.

1.11.0

2026-08-02
  • RTSC-508 — you can now sign in with Google, not only GitHub.
  • RTSC-508 — you can now sign in with Google, not only GitHub. Google sign-in shipped for the web Dash first, which left a one-way street: an account created through that door reached the Dash and nothing else, because every login-gated command here sat behind a GitHub-only device flow. retasc login would start a GitHub device flow for an account GitHub had never heard of. That blocked bind, init, key, members, billing and identity outright — including the sign-in step inside retasc bind and retasc join, so a teammate invited through the web could not finish setting up their folder at all. With no flag, login now asks which door you use:
    After a successful sign-in the door is remembered, so later logins offer it back and Enter takes it:
    A default only ever appears once it is a recorded fact about you. On a first login there is none, and Enter is not an answer — because the wrong door is not a mistake you correct next time (see below). The remembered door is a default, not a lock: the other one is still one keystroke, and a typo re-prompts rather than being read as “the usual”. retasc login --google / --github skip the question. A non-interactive run is unchanged: no prompt, GitHub, exactly as before. The same question appears inside bind and join when they sign you in for you. Signing in through the wrong door is not a typo you correct on the next run. Google and GitHub are deliberately separate identities — doors are linked only on a provider’s own immutable account id, never on a matching email address, because email is an account-takeover vector. So a Google sign-in by someone who already has a GitHub account here creates a second identity with its own membership, and the CLI cannot merge them back. That is why the question is asked rather than guessed, and why a non-answer re-prompts instead of falling through to a door. Needs AUTH_GOOGLE_DEVICE_ID / AUTH_GOOGLE_DEVICE_SECRET on the deployment (operations/runbooks/google-device-client.md). Where they aren’t set, the CLI says so in one line and names GitHub as the way in meanwhile, rather than failing opaquely.

1.10.0

2026-08-01
  • RTSC-477 — new command: retasc identity.
  • RTSC-477 — new command: retasc identity. It shows the people a migration carried into your org and asks which one is you — the same question retasc join asks, on demand.
    join asks this once, at the moment you accept an invite. Placeholders arrive with every migration, though, and claiming is per source tool rather than per person: the backend is built for “claim your ClickUp one now, your Jira one in six months”. So a team that onboarded by CLI a year ago had no terminal path to a later import’s history at all, and had to open the Dash or leave it on placeholders. Three narrower cases join skips on purpose are covered too: --yes, a non-interactive run, and --no-bind. It asks the question, so it needs a TTY and refuses without one rather than exiting 0 in silence. There is deliberately no --yes and no identity claim <name>: linking someone pulls their authorship and their dispatch lane onto your account, irreversibly, with no CLI way back, so it is never answered on a script’s behalf. It also names the ending, which join does not. “Nothing waiting for you” and “you’ve already said none of these are you” are the same empty list from the inside and mean opposite things — the second is permanent and org-wide, so it still applies after a later migration that really did carry you across. That case now says so, and points at the owner, who is the only one who can undo it.

1.9.0

2026-07-31
  • RTSC-492retasc join is now the whole of an invited teammate’s setup, in one command run from the folder their agent will work in.
  • RTSC-498retasc doctor now says which platform the CLI is actually tested on.
Behaviour change, read this if you script join: retasc join <code> used to redeem an invite and stop. It now also sets up the folder you run it in — mints a key, writes a binding, wires the MCP marker. --no-bind reproduces the old behaviour exactly, same output and same exit code. Every other command is unchanged.join also no longer exits 1 telling you to run retasc login first. It starts the device flow itself when there is no session, and refuses with the same message bind uses when there is no TTY to run one in.
  • RTSC-492retasc join is now the whole of an invited teammate’s setup, in one command run from the folder their agent will work in:
    It signs them in (device flow, only when there is no session), redeems the invite, offers them any identity a migration carried across, picks the project, makes retasc durable, mints a key, binds the folder and wires the MCP marker. It used to be three commands with an ordering trap in them, and the first of those three was retasc login — which is not something you can tell someone who has installed nothing yet. The target case is that an invited teammate never opens the Dash at all. With no imports and one project, the only thing they type is the GitHub device code: every prompt is conditional on there being a real choice.
    • Takes a full invite link or a bare rtscinv_… code. The code is what the server matches, so unwrapping a paste belongs at the edge that accepts typed input, not in the mutation that grants membership.
    • A member is never offered a project they cannot create (createProject is owner-only), and an org with no projects names what to ask an owner for instead of failing opaquely.
    • Imported placeholders are offered once per source tool, each behind an explicit confirm, in the same words the Dash uses. --yes skips that question and never answers it: claiming another person’s history is irreversible and has no CLI path back.
    • --no-bind keeps the old redeem-only behaviour for anything scripted against it.
    Under it, bind and join now share one implementation of the folder half — the project pick, the launcher ladder, the mint, the binding and the marker — so the fix that landed in 1.8.0 cannot drift back out of one of them.
  • RTSC-498retasc doctor now says which platform the CLI is actually tested on. Nothing in the product stated one: the READMEs never mentioned platforms and package.json declares only engines.node, so someone hitting a problem on Linux or Windows had no way to tell their own mistake from a bug from a platform we never targeted. macOS is the only platform we run end to end. It’s a note in doctor rather than a line in the README on purpose. A README is read by everyone, and for the majority on macOS a standing disclaimer about platforms they aren’t using is noise they read before they’ve even installed. doctor already knows which machine it’s on, so the people the limit applies to are exactly the people who see it, and on macOS nothing is printed at all. The note claims a limit, not a blockage: much of the CLI is plain Node and should work fine, and package.json still carries no os field, so installing is never refused anywhere Node 18+ runs. Windows and Linux are named as platforms we intend to support properly; anything else is told it’s untested without being promised a roadmap it isn’t on.

1.8.0

2026-07-31
  • RTSC-493 — the MCP marker no longer names a command that may not exist.
  • RTSC-493 — the MCP marker no longer names a command that may not exist. It used to hardcode retasc, which is only on PATH after a global install — but the Dash tells people to run npx @retasc/cli bind, and npx unpacks into its own cache and installs nothing. So a bind printed every success line, really did bind the folder, and left an agent that could not start the Retasc MCP server at all. The failure surfaced later, somewhere else, as a broken server rather than a failed setup. bind now resolves a launcher and proves it by running it before writing anything: it uses an existing retasc if there is one, otherwise installs the CLI globally, and if that install lands where PATH cannot see it, the marker names the binary’s absolute path instead. Only when none of that works does it fall back to a version-pinned npx, which is slower and needs the network — and if even that will not start, it says so outright rather than reporting success. retasc doctor now checks the same thing, so a folder bound by an older version reports why its agent cannot start and names the repair.

1.7.2

2026-07-21
  • RTSC-297retasc bind no longer strands a new org silently.
  • RTSC-297retasc bind no longer strands a new org silently. It creates the org server-side before the project picker runs, so aborting at the project step (reachable by a typo since 1.x’s picker gives up after 3 bad answers) left an org behind with no project, no key, and no local binding — invisible from the CLI and quietly accruing on the billing rail. Bind now names the org and prints the exact resume command (retasc bind --org-id <id>) when it aborts before the workspace is bound. Selecting a pre-existing org and then aborting is untouched — nothing is reclaimed.

1.7.1

2026-07-21
  • RTSC-321 — the liveness watchdog now stops heartbeating an issue the moment it moves to review (RTSC-257): the server releases the lease there, so the proxy no longer pings a dead lease until the next heartbeat fails.
  • RTSC-321 — the liveness watchdog now stops heartbeating an issue the moment it moves to review (RTSC-257): the server releases the lease there, so the proxy no longer pings a dead lease until the next heartbeat fails. It is treated as a release, not a close — the branch/worktree is preserved for the review + PR (never reaped). The reviewer’s send-back (review → todo) still self-heals via the failed-heartbeat path, since it can’t be told apart from a doing → todo edit by request args alone.

1.7.0

2026-07-21
  • RTSC-306retasc claim / retasc next now pull lane-scoped by default: only issues assigned to your principal or left unassigned, never another human’s work.
  • RTSC-306retasc claim / retasc next now pull lane-scoped by default: only issues assigned to your principal or left unassigned, never another human’s work. The old --mine flag is retired — that behavior is the default now. The new --all-lanes flag opts back into the whole ready pool when you need to pick up an absent teammate’s work. When your lane is empty but ready work is stranded in another lane, the CLI says so and points you at --all-lanes instead of reading as “nothing to do”.

1.6.3

2026-07-20
  • RTSC-266 — README now links the setup page, the docs quickstart, and the parallel-agents guide instead of only the bare homepage.
  • RTSC-266 — README now links the setup page, the docs quickstart, and the parallel-agents guide instead of only the bare homepage. npm package pages are a real entry point and only re-render on publish, so this ships as its own patch release. No code changes.

1.6.2

2026-07-20
  • RTSC-269retasc bind’s org/project picker no longer treats a typo as “create new”.
  • RTSC-269 — the picker gives up after 3 invalid answers instead of looping, and a closed stdin (Ctrl-D, or a pipe running dry) now exits with an error rather than hanging.
  • RTSC-269retasc bind’s org/project picker no longer treats a typo as “create new”. Answering 1) (a fumbled 1) used to select nothing and fall straight through to creating a new org/project, which then hit the owner gate and surfaced as a redacted Server Error. Invalid input now re-prompts; only the explicit trailing option creates. The answer must be plain digits, so the non-canonical forms Number() happily parses (0x4, 4e0, +4, 4.0) can’t reach the create branch either.
  • RTSC-269 — the picker gives up after 3 invalid answers instead of looping, and a closed stdin (Ctrl-D, or a pipe running dry) now exits with an error rather than hanging. readline.question() never settles at EOF, so any prompt in bind could previously wedge the CLI with no output and no exit.

1.6.1

2026-07-20
  • RTSC-263 — owner/member permission denials now print a readable reason and the next step instead of an opaque Server Error.
  • RTSC-263formatError now strips U+0085, U+2028 and U+2029 in addition to the ASCII control characters.
  • RTSC-263 — owner/member permission denials now print a readable reason and the next step instead of an opaque Server Error. Hitting an owner-only command as a member reports “Owner role required.” with “Ask <owner> to create a project.” on its own line. The backend change does the work; the CLI already read the structured payload (1.5.0), so this release carries only the hardening below.
  • RTSC-263formatError now strips U+0085, U+2028 and U+2029 in addition to the ASCII control characters. All three are mandatory line breaks, so a server message interpolating a user-controlled name could previously forge extra lines in terminal output.

1.6.0

2026-07-20
  • RTSC-262doctor and whoami no longer report “not bound” for a folder whose Retasc MCP is registered in Claude Code local scope (the claude mcp add default — stored in Claude’s own config, not ./.mcp.json).
  • RTSC-262claim/tidy/done resolve the key through the same entry selection, so the CLI can no longer say ”✓ bound” in one command and “No Retasc MCP key found” in another for the same folder.
  • RTSC-262 — the illegal-global-server check is now presence-based: a hand-added user-scope entry is detected in every shape (including keyless), and an unreadable ~/.claude.json reports “cannot verify” instead of a false all-clear.
  • RTSC-262 — honest failure modes: server-unreachable (timeouts, 5xx, rate limits) is no longer reported as a rejected key, whoami/doctor requests are bounded by a 10s timeout, and server-derived strings are stripped of control characters before printing.
  • RTSC-262bind hardening: re-binding to the same org/project is an idempotent success (no key churn for provisioning scripts); replacing a different binding non-interactively without --yes now fails loudly with exit 1 instead of silently succeeding as a no-op; a cloned repo’s committed marker no longer triggers the replace prompt (minting your own key under it is what bind is for).
  • RTSC-262 — (security) a keystore-resolved key now only ever travels to the keystore’s own URL — a hostile RETASC_MCP_URL planted next to a committed secret-free marker can no longer redirect a teammate’s real key.
  • RTSC-262doctor and whoami no longer report “not bound” for a folder whose Retasc MCP is registered in Claude Code local scope (the claude mcp add default — stored in Claude’s own config, not ./.mcp.json). The binding lookup now reads both legal per-folder locations, and when both exist the local-scope entry wins, matching Claude Code’s documented precedence (local > project) — doctor names the org the agent actually uses, and warns when a differing ./.mcp.json marker is being shadowed.
  • RTSC-262claim/tidy/done resolve the key through the same entry selection, so the CLI can no longer say ”✓ bound” in one command and “No Retasc MCP key found” in another for the same folder.
  • RTSC-262 — the illegal-global-server check is now presence-based: a hand-added user-scope entry is detected in every shape (including keyless), and an unreadable ~/.claude.json reports “cannot verify” instead of a false all-clear.
  • RTSC-262 — honest failure modes: server-unreachable (timeouts, 5xx, rate limits) is no longer reported as a rejected key, whoami/doctor requests are bounded by a 10s timeout, and server-derived strings are stripped of control characters before printing.
  • RTSC-262bind hardening: re-binding to the same org/project is an idempotent success (no key churn for provisioning scripts); replacing a different binding non-interactively without --yes now fails loudly with exit 1 instead of silently succeeding as a no-op; a cloned repo’s committed marker no longer triggers the replace prompt (minting your own key under it is what bind is for).
  • RTSC-262 — (security) a keystore-resolved key now only ever travels to the keystore’s own URL — a hostile RETASC_MCP_URL planted next to a committed secret-free marker can no longer redirect a teammate’s real key.

1.5.0

2026-07-20
  • RTSC-261 — backend failures you’re meant to act on now print what actually went wrong instead of ✗ Server Error.
  • RTSC-261 — backend failures you’re meant to act on now print what actually went wrong instead of ✗ Server Error. Convex masks any plain server throw in production, so every precondition — a consumed invite code, an expired one, a suspended membership — reached the terminal as the same opaque string. retasc join was the worst case: an invited teammate hit an unreadable wall at the very first step. Errors now carry a machine-readable code, a readable message, and an optional hint printed on its own line:
    This release covers invite redemption; the remaining surfaces (auth/key problems, not-found lookups, billing gating, import/restore) follow. Internal invariants stay masked deliberately — those are our bugs, not yours, and their messages describe server state. Upgrade before your teammates redeem invites: an older CLI can’t read the new payload and prints it as raw JSON.

1.4.0

2026-07-19
  • RTSC-279 — new retasc billing command: the org’s whole billing picture in the terminal instead of only in the Dash.
  • RTSC-279 — (server-side, no CLI change) the MCP usage meter now reports two clearly-named figures instead of one misleading wouldBeBillUsd: lifetimeMeteredEstimateUsd (all-time activity repriced at today’s rate card — a diagnostic, not an amount owed) and pendingUsd (what is actually owed right now, the same figure the Dash shows).
  • RTSC-279 — new retasc billing command: the org’s whole billing picture in the terminal instead of only in the Dash. Prints the subscription and spending caps, what’s owed right now, and the charge + confirmed on-chain payment history — both org-scoped across every payment link the org has ever used, so changing payment link no longer hides prior history. Owner-only (it reuses the same owner-gated functions the Dash renders; the client-side role check is UX, the server still gates). --org-id selects the org when you belong to more than one, --json emits the raw payload. Payments are a live read of Xenarch’s authoritative records and degrade to a note rather than failing the command.
  • RTSC-279 — (server-side, no CLI change) the MCP usage meter now reports two clearly-named figures instead of one misleading wouldBeBillUsd: lifetimeMeteredEstimateUsd (all-time activity repriced at today’s rate card — a diagnostic, not an amount owed) and pendingUsd (what is actually owed right now, the same figure the Dash shows). A new billing_summary MCP tool exposes the full billing detail to agents whose human principal owns the org.

1.3.2

2026-07-17
  • RTSC-250 — serialize patchConfig under a cross-process advisory lock so concurrent CLI/MCP processes can’t lose an update.
  • RTSC-250 — serialize patchConfig under a cross-process advisory lock so concurrent CLI/MCP processes can’t lose an update. Previously a lock-free load-modify-save meant a defaultOrgId/defaultProjectPrefix write racing the hourly token refresh could write back the old single-use refreshToken, breaking the next refresh and forcing a device re-login a non-interactive context can’t perform. The lock re-reads the freshest config inside the critical section and stamps a nonce so a stolen-from holder never deletes the new owner’s lock. Also sweeps orphaned .config.json.<uuid>.tmp files left by a hard kill, age-gated so a concurrent writer’s in-flight temp is never touched.

1.3.1

2026-07-17
  • RTSC-179 — atomic config write (temp file + rename) so a reader never sees a truncated config.json; adds RETASC_DIR support.
  • RTSC-178 — token refresh now classifies transient backend errors vs a genuinely expired refresh token, so a one-off backend blip no longer drags a valid session through a full device re-login.

1.3.0

2026-07-08
  • Auto-reap branches on MCP close: when the watchdog proxy observes a session’s own claim close terminally and successfully, it removes that issue’s clean, merged rtsc-NN/* worktree and branch out-of-band (retasc tidy --prune --only <id>), instead of orphaning them until a human ran retasc tidy.
  • Auto-reap branches on MCP close: when the watchdog proxy observes a session’s own claim close terminally and successfully, it removes that issue’s clean, merged rtsc-NN/* worktree and branch out-of-band (retasc tidy --prune --only <id>), instead of orphaning them until a human ran retasc tidy. Exposes tidy --only <RTSC-NN>.

1.2.4

2026-07-07
  • RTSC-170 — credential-file permission hardening: config.json, bindings.json, and the fallback .mcp.json are written 0600 (dirs 0700) with no world-readable creation window.

1.2.3

2026-07-05
  • RTSC-150 — watchdog isClaimLost fix: no longer drops a live lease when a payload field merely contains the string CLAIM_LOST.

1.2.2

2026-07-04
  • RTSC-148retasc claim takes the issue as a positional argument, and never silently falls through to next_issue.
  • RTSC-148retasc claim takes the issue as a positional argument, and never silently falls through to next_issue. retasc claim 143, claim RTSC-143 and claim rtsc-143 all resolve to that issue; a bare number expands against the workspace’s prefix, resolved over the workspace key rather than global config. Excess arguments now error loudly instead of being dropped by Commander, which was how “claim this specific issue” quietly became “claim whatever is next”.

1.2.1

2026-07-04
  • RTSC-143 — one tolerant tool-result parser, and a loud failure when the claim fence is off.
  • RTSC-143 — one tolerant tool-result parser, and a loud failure when the claim fence is off. The proxy and claim each had their own silent copy of the parser; they are now one (lib/toolresult.ts), which recovers the leading JSON value when a footer trails the payload, refuses to recover from an isError response or concatenated JSON, and warns on stderr when it degrades so a shape regression is never silent. Session-key minting retries once with a 5s timeout and checks res.ok. On a double failure it still fails soft, but says loudly that the per-session claim fence is OFF, and the proxy appends that notice to whoami so the agent sees the degraded state rather than it sitting in an MCP log file nobody opens.

1.2.0

2026-07-04
  • RTSC-137 — org-membership commands: retasc members invite|list|revoke and retasc join.

1.1.3

2026-07-02
  • RTSC-131retasc --version reads package.json instead of a frozen literal.
  • RTSC-131retasc --version reads package.json instead of a frozen literal. It was hardcoded to 1.1.1, so the published 1.1.2 still reported 1.1.1. The version is now read at runtime relative to the compiled file, making package.json the single source of truth.

1.1.2

2026-07-02
  • RTSC-130 — republish the bind auto-wire fix that had changed CLI source without a version bump (npm versions are immutable).

1.1.1

2026-06-28
  • RTSC-98claim, tidy and done resolve the keystore key through the same resolver the proxy uses.
  • RTSC-98claim, tidy and done resolve the keystore key through the same resolver the proxy uses. After 1.1.0 moved keys out of the repo, a secret-free .mcp.json was understood by the proxy but not by those three commands, which still only knew the legacy inline-key path and bailed with “No Retasc MCP key found”. The two resolvers had drifted, so they are now one (resolveConn in lib/keystore.ts): explicit RETASC_MCP_KEY, then a legacy inline key, then the canonical secret-free marker. Legacy markers keep working.

1.1.0

2026-06-28
  • RTSC-92 — workspace keys move to a home keystore, and the folder marker becomes secret-free.
  • RTSC-92 — workspace keys move to a home keystore, and the folder marker becomes secret-free. Secrets no longer sit in a project tree. The key lives in ~/.retasc/bindings.json (mode 0600), keyed by an opaque workspace id rather than a path, so nothing leaks a home directory and a checkout stays portable across a team. What lands in the repo is a marker carrying only that id, which is why ./.mcp.json is safe to commit. doctor reports whether a binding is keystore-backed or legacy, and flags a workspace id already bound at a different folder. A cloned repo whose marker has no key on this machine is reported as such rather than as broken.

1.0.0

2026-06-27
  • RTSC-89 — initial npm publish as @retasc/cli (bin stays retasc).
Last modified on September 19, 2026