import type { ToolDefinition } from "./types.js"; /** * `GET /api/v1/repositories/registrable` as a tool — shipped today in the * platform (`specguard/config/routes.rb`, served by * `Api::V1::UserRepositoriesController#registrable`). * * == What it answers, and why `list_repositories` does not * * `list_repositories` reports what is already registered; this reports what * COULD be — the repositories the registration gate would consult, read out * loud in advance. It exists so an agent can pick a `full_name` for * `add_repository` from a real answer rather than by guessing, and so a * `has already been taken` refusal can be explained rather than merely * retried. * * == Two controller decisions the description carries, because both are * counter-intuitive and both are stated in the controller's own comments * * `registered` is asked of `Repository` GLOBALLY, not of what this person can * open. The controller says why: a repository somebody ELSE registered still * refuses this person's POST with `has already been taken`, so a reading * scoped to what they can see would mark it `registered: false` and send them * at a name that cannot be registered by anyone. An entry is therefore * MARKED, not excluded — `registered: true` is the answer to "why did my POST * say has already been taken". * * And a name appearing here is NOT a promise the write will succeed. This is * the set the gate would consult at the moment of the read; the repository may * be registered by someone else between the two calls. * * == The modal first answer is a 403, and that is why `describeFailure` grew * * `#registrable` fails closed on the two states `GrantVerifier` refuses on and * renders `status: :forbidden` — NOT the 400 path the other refusals use. A * nil grant is, in the controller's own words, "an ordinary state and not an * error: it is every person who has not opened SpecGuard in a browser since * this shipped" — so the 403 is the modal first answer this tool gives, and * the sentence it carries (sign in, reconnect GitHub, retry) reaches the agent * through the 403 branch in `specguard-api.ts`, which this tool is the reason * for. On refusal the body still carries `grant`: `null` when there never was * one, populated with `stale: true` when it lapsed — "yours lapsed four days * ago" is a different fact from "you never had one", and the tool description * is where an agent learns to branch on it. * * == No arguments, for the same reason `list_repositories` used to have none * * The credential is the whole of the scope. The endpoint takes no parameters, * and nothing an argument could select reaches this answer. (`list_repositories` * argued the same way and argued it the same amount — until its endpoint grew * the SPGD-940 narrowing asks and the tool grew the arguments that forward * them. This endpoint has grown no asks, so the argument-less shape here is * still the honest one, and the sentence above keeps saying so rather than * inheriting a reason that moved.) */ declare const registrableRepositories: ToolDefinition; export default registrableRepositories;