Features
Blame a file without a clone
knotless blame <url> <path> [--rev <rev>] prints who last changed each run of a file's lines, as git blame finds it, read from the cache mirror: the lines, the commit, its author, when it was written and its subject, tab-separated. The MCP server's blame tool answers the same as JSON, with the commit's parent and the file's path there, to blame again before it.
Reviews and merges say what they mean
merge --check lists each approval that does not count, and why, as an uncounted line (the MCP merge check as reviewsUncounted), and a merge refused for its reviews says so too. It says when the asker may not merge the pull, and counts a review written a moment ago. Over MCP, a refusal for reviews names the comment tool and merge with force rather than CLI commands; merge answers how it merged (method) and why it kept the head branch (kept); show_item gives handles beside reviewers' DIDs, marks reviews outdated, maintainer and uncounted, gives comments' mention facets, marks every comment of a resolved thread resolved, has a review's own comment name itself as review, and says draft: false; comment notes an approval that will not count; notifications says markedSeen.
Comment on a pull's lines, in threads you can resolve
knotless comment takes --line <path>:<n>[-<m>][:old] <text>, as many as you like, to comment on lines of a pull's diff, alone or as one review with --approve, --changes or a body, and prints the URI of each comment it wrote. Given a comment's URI, it answers that comment in its thread. knotless resolve and unresolve resolve a thread or open it again, and knotless show says which lines each comment is on and which answer which. Over MCP, comment takes lines and answers written too, set_state resolves a thread, and show_item gives each comment's line, reply, review and resolved. On the pages, the + beside a line of a pull's diff comments on it, or starts a review sent from the "Review changes" menu.
Delete all your knotless data
knotless delete-data <handle> lists what knotless keeps in your atproto account (your repositories, those others push to or read named, and the records of each kind), then, once you type your handle again (or pass --yes), deletes all of it: your private repositories' spaces, each public repository as knotless delete deletes one, then your pulls, issues, comments, stars, follows and the rest. knotless.dev then forgets you and logs you out. A run cut short carries on where it stopped when run again. Your atproto account, and other apps' records in it, stay. The delete_account_data MCP tool does the same, and the pages' account settings have a "Delete your knotless data" section. Logging in again asks to call dev.knotless.deleteAccountData.
Draft pulls and requested reviewers
knotless pull --draft opens a pull that neither merges nor queues until you mark it ready with knotless edit <url> <at-uri> --ready (--draft makes it one again); merge --check says draft and why. --reviewer <handle>, on pull and edit, asks someone to review your pull, and edit --no-reviewer stops asking: they hear of it as a review-requested notification once the pull is not a draft. knotless show lists both, and list -q takes is:draft, -is:draft and review-requested:<handle or @me>. MCP's open_pull and edit_item take draft and reviewers too. The pages mark drafts in the pulls list, show requested reviewers in the merge box, and let the author mark a draft ready there.
The gateway holds collaborators to required reviews and checks
Through the gateway, a collaborator moves a branch whose rule asks for reviews only by merging a pull reviewed as it asks, with its checks passed: a plain push or knotless commit to it is refused, saying to open a pull. In a repository that names runners, a collaborator's merge of a pull, pushed by any client, is refused until the pull's checks pass, as knotless merge refuses it.
Mentions
@handle in a pull's or an issue's title or body, or in a comment, now mentions that account: a full handle, with a dot, not in code or a link. Writing the record, from the command line, MCP or the pages, resolves each handle and keeps the account's DID in it as facets, so the mention still names the account after its handle changes. The pages link each mention to the account's profile, and the account hears of it with a new notification reason, mention, on unless turned off with knotless notifications settings --off mention, MCP's notification_settings or the settings page. On a private repository only those who can read it hear of a mention.
Organizations
Any account can be an organization. As that account, after delegating to a gateway (knotless delegate), knotless org add <handle> invites another account, and knotless org join <org> --public or --hidden accepts: from then on they push to each of the organization's repositories, made before or after, and read the private ones, until knotless org leave or knotless org remove. A public membership shows to anyone; a hidden one only to the organization's members, and on its public repositories a hidden member pushes and opens pulls while merging, closing and labelling take a public membership. Invitations lapse after 7 days. --admin makes an admin, who invites, removes and makes repositories as the organization from their own login (--org <org>, or knotless create knotless://<org>/<name>). knotless org members lists who is in (--public as anyone outside sees it), knotless org list which organizations an account is in, and knotless org delete --yes ends it. knotless members names an organization's members on each repository. The org MCP tool does the same, and so do the pages: Start an organization in your account menu, then a Members tab to invite, change roles, join, hide, leave and remove, and Delete organization in settings. An invitation shows in knotless notifications, MCP's notifications and the pages' notifications until it is answered or lapses, and the pages answer it there. Logging in again, and delegating again, asks to write dev.knotless.org, dev.knotless.orgMember and dev.knotless.orgAcceptance records and to call the organization methods.
knotless merge --check, and MCP's merge with check, tell a hidden member why they may not merge on an organization's public repositories: that it takes a public membership.
Pictures in pulls, issues and comments
Paste or drop a picture into a pull's, an issue's or a comment's box on the pages and it is uploaded to your account and linked where you put it, as GitHub does. From the command line, --image <file> on pull, issue, comment and edit does the same, and over MCP images on open_pull, open_issue, comment and edit_item. The record attaches each picture its body shows, so your PDS keeps it, and lets it go when an edit takes it out. A picture over 1 MB is made smaller rather than refused, and so is a profile picture, which may now be a WebP or GIF too.
A pull's diff over MCP numbers its lines
The MCP server's pull_diff tool now leads each line of a hunk with its line number in the old file and in the new, as comment's lines takes them: a + line is side: new at its new number, a - line side: old at its old number. An agent no longer counts lines from the @@ headers to comment on one.
Branches that take pulls only through the merge queue
knotless protect <url> <branch> --queue makes a branch take pulls only through the merge queue, as GitHub's "Require merge queue" does: knotless merge (and MCP merge) queues a pull into it instead of merging, saying so, and only the owner's --force merges at once. The gateway moves such a branch for no collaborator but the runner that lands the queue. knotless rules shows queue, MCP protect_branch takes it, and the repository settings' Branches page has a "Require the merge queue" checkbox for each protected branch, whose pulls' pages then offer only the queue.
Repositories show their releases
A repository's pages show what it publishes: its latest release and its packages under its name, and a Releases tab listing every version, with its notes, files and, for an image, the docker pull command. knotless-serve indexes dev.knotless.release records and answers dev.knotless.listReleases.
Repositories show their links
A repository can name up to five links, its website first, as a profile names its links: knotless create <url> --link <url> [--title <text>], and knotless describe <url> --link … to replace them, or --link '' to drop them. The MCP create_repo and update_repo tools take links, and its settings page has a Links field. Its pages show the first link under the description, before its latest release, with a count of any others that opens the list of them all. knotless describe prints a link: line for each.
Protected branches can require reviews, from code owners too
knotless protect <url> <branch> --reviews <n> makes a pull merge into the branch only once <n> of the owner and collaborators, other than its author, approve it, and while none of them has asked for changes. --code-owners also asks, for each path it changes that the branch's CODEOWNERS file (.knotless/CODEOWNERS, CODEOWNERS or .github/CODEOWNERS) gives owners, for one of them to approve it; --dismiss-stale counts only approvals of the pull's head as it is now. merge, merge --check (which lists what is missing, and CODEOWNERS lines it skipped), the merge queue, MCP protect_branch and merge, and the pages' branch settings and merge box all follow it. The owner's --force merges past it.
Revert a merged pull
knotless revert <url> <pull at-uri> [-m <reason>] undoes a merged pull as GitHub's Revert button does: one commit that undoes everything its merge brought in, on a new branch revert/<rkey> cut from its target branch, and a pull of that branch into it, titled Revert "<title>", its body linking the merged pull and saying why. It prints the new pull's URI; check and merge it, or queue it, like any pull. It stops on a conflict, naming the paths. The owner and collaborators may. The revert MCP tool does the same, and a merged pull's page has a Revert button.
Reviews stand as GitHub's do
Each reviewer's latest verdict is where they stand: a later --approve or --changes replaces an earlier one, and a comment without a verdict changes nothing. knotless show lists each reviewer as a review: line with the head they looked at, and the MCP list_items and show_item give an item's reviews in place of approvals. You can no longer review your own pull, or an issue. The pages show reviewers in a pull's merge box, and a review of a head the pull has since moved past as one of an earlier version.
Sharing for writing delegates first, and reviews say more
knotless share --write and MCP's share delegate your writes to the appview's gateway first when you have not, approved in the browser as delegate is, and say they did. Notifications name what each is about (the pull or issue, or for a star the repository) and its repository as handle/name; a review says how many line comments it holds and whether it mentions you. show_item gives each line comment its side and startLine, resolved only on threads, superseded on a review a later one replaced, and whether each requested review is still pending; list_items says draft: false too. A pull whose only code owner is its author says why it can never have that approval, and protect_branch and list_rules warn when you alone own a path.
Tag a commit without a clone
knotless tag <url> <name> [<from>] tags a commit, the default branch's or that of a branch, tag or commit, and prints it; --delete deletes a tag. The MCP server's create_tag and delete_tag tools do the same. Each release of knotless is now tagged v<version> at the commit it was built from.
The branch menu switches to tags too
On a repository's code, commits, file and blame pages, the menu that switches branches has a Tags tab beside Branches, as GitHub's does, to see the same page at a tag. Viewing a tag, the menu's button shows the tag icon and opens on Tags.
Fixes
Buttons show their action under way
On the pages, the button you pressed shows a spinner and says what it is doing, such as "Inviting…" or "Joining…", until the server answers. The rest wait, dimmed. This covers organizations and their invitations, notifications, merging, settings, labels, reactions and the rest.
Commands and MCP tools say when your login is out of date
While your login is older than what knotless asks for now, every command ends by saying so and naming the knotless login to run. An MCP tool a PDS refuses for want of scope tells the agent to have you sign in again, by reconnecting knotless in your assistant or running knotless login.
Deleting a repository leaves nothing of it
knotless delete, the delete_repo tool and the pages' Delete now also delete the repository's releases and reruns, and what you wrote about it yourself: your pulls, issues, comments, states, labels, hides, queue entries and blocks naming it, your star of it, and your reactions to those. The repository's own record goes last, so a delete cut short carries on when run again. knotless.dev drops what it kept of a deleted repository, its mirror included, and a runner drops its checks, caches and secrets grants. Logging in again asks to write dev.knotless.release records, which knotless publish needs with OAuth.
Organization changes take fewer round trips
Inviting, removing and leaving wait on fewer calls to a PDS. The gateway reads what it needs at once rather than one after another, and no longer tries to make the organization's space each time. On the pages, a change this server's gateway made is no longer indexed a second time.
Handle suggestions when inviting and sharing
On the pages, the fields that take someone else's handle suggest accounts as you type, as the login dialog does: inviting to an organization, adding a collaborator or a reader, and offering a repository to another account.
Say how to grant what a login lacks
A command a PDS refuses because your login is older than what knotless asks for now says so, and to run knotless login again. Logins now keep the scope they asked for, and the pages offer to log in again, or to delegate again, when knotless asks for more.
Collaborators and organization members hear of new pulls and issues
A pull or an issue opened on a repository is now a notification for its collaborators, and for the members of the organization that owns it, hidden members too, as it was for its owner.
Suggestions for @ while writing
Typing @ in a comment, a review, an edit or a new pull or issue on the pages suggests whom to mention: those in the thread, then whom you follow, then accounts whose handles match. Arrows choose, Enter or Tab picks, Escape closes. A mention an edit adds is heard of as of the edit, not as of when the record was first written.
A new repository never replaces one of the same name
create, fork, accept and rename refuse a name a repository of yours already has, public or private, with <url> already exists, before writing anything. On a PDS that took a create over an existing record as an update, creating a repository under a taken name replaced the old one's record and orphaned its history. The record is now written with a compare and swap that the PDS refuses when any record is there. On the web, the new repository form, the fork menu and the rename setting say as you type whether the name is free, and hold their button while it is taken.
Organization changes read at once
Joining, inviting, removing and ending an organization read what they need at the same time instead of one after another. They also read the organization's space once instead of two or three times.
Pasted pictures show in the preview
A picture pasted or dropped into a pull's, an issue's or a comment's box shows in its preview, and a profile picture picked shows before it is saved: the pages let a picture be drawn from what was pasted or picked.
Notification settings live with your other preferences
knotless notifications settings and the notification_settings MCP tool read and change which notifications you hear of through the appview's preferences (dev.knotless.getPreferences and putPreferences), which also keep the theme you choose on the pages. They behave as before, but need an appview at this version or later. Notification settings made before this were not carried over: everyone starts from hearing every reason, from anyone.
Say why a private repository can't be made yet
knotless create --private, and the create_repo MCP tool with private, on a PDS without spaces now say that your PDS can't hold private repositories yet, rather than passing on its UpstreamFailure or MethodNotImplemented. Nothing is made.
Notifications from private repositories reach members who never logged in to the appview
Members of a private repository who use only the command line or MCP now hear of what is said there: a mention, a comment on their issue, a reply. Writing a pull, an issue, a comment, a review or a state to a private repository, or sharing one, now shows the appview the repository with a delegation token, so its index has what was written. Sharing a private repository to read now names the account in the record's new readers, which the appview takes as the owner's word that they may hear of it. Someone mentioned there who is not a member still hears nothing.
A merged pull's diff once its branch is gone
The MCP pull_diff tool on a merged pull answers what its merge brought in, from the commits its merge recorded, rather than failing once merging deleted its branch.
Pushes through a gateway are credited to whoever made them
A push or commit a collaborator or runner makes through a gateway names them as pusher on the claims and refs it writes, and the feed and activity pages credit it to them rather than to the repository's owner, while the repository lists them as a collaborator or runner.
A reverted pull names its revert
Once a revert pull merges, the pull it undid names it: knotless show says reverted by, as do the MCP show_item (item.revertedBy) and the pull's page. A merged pull's compare in show_item is what its merge brought in, even once its branch is deleted, and the MCP diff tool says when there are no differences rather than answering nothing.
Usage keeps who did what for 30 days
knotless-serve's usage counts (--usage) delete the accounts they noted for MCP, the gateway and the pages' logins once 30 days have passed, keeping only counts. In knotless admin stats, an event's accounts are of the days asked, at most the last 30, and a funnel starts with an account that had not done its first step in the 30 days before.