import type { ToolDefinition } from "./types.js"; /** * `POST /api/v1/repositories` as a tool — shipped today in the platform * (`specguard/config/routes.rb`, `Api::V1::UserRepositoriesController#create`). * * == The first tool here that WRITES, and what that changed * * Everything before this read. The registry's standing rule is that a tool in * `tools/list` is a promise an agent will act on, and this endpoint has existed * on the platform for some time — what was missing was on THIS side: `getJson` * hardcoded `method: "GET"` and took no body. `tools/index.ts` and * `list-repositories.ts` both said so, and said the transport should land with * the first write tool so it could be designed against a real request body and a * real 4xx surface rather than invented for a caller that did not exist. This is * that tool, and `postJson`/`postJsonObject` are that transport. * * == The request body is top-level, because the caller is an agent * * `{"github_full_name": "org/repo"}`, not `{"repository": {…}}`. The controller * permits it that way and says why: this is a JSON API being driven by an agent, * not a Rails form being submitted by a browser, and the top-level shape is what * a caller writing curl by hand will send. * * == The format is NOT re-validated here, deliberately * * `Repository` validates `org/repo` itself, and a refusal now arrives through * the 400 branch in `describeFailure` in SpecGuard's own words. A second format * rule on this side is exactly what "a thin client that reshapes its upstream is * not thin" forbids — it would be a rule with no owner, free to drift from the * one that actually decides, and its divergence would surface as this bridge * refusing a name the platform would have accepted. Checking that `full_name` is * a present, non-blank string is the whole of the bridge's business: that is a * shape check, which is why it is `requireString` from `args.ts` and not a * hand-rolled one here. * * == The MODAL first answer is a 400, and it is the useful one * * `RepositoryRegistration::GrantVerifier` fails closed on a grant that is * missing or stale, which is every person who has not opened SpecGuard in a * browser since this shipped — the controller records that this is "an ordinary * state and not an error". The sentence that comes back names the operator's * exact next move (sign in, reconnect GitHub, retry), and reaching the agent * intact is what the 400 branch in `specguard-api.ts` is for. * * == Why the description carries a hazard paragraph * * `types.ts` calls the description "prompt material, not documentation … the * entire basis on which a model decides whether to call the tool". This tool is * NOT idempotent and its 201 carries a reveal-once token, so an agent that * learns those facts by hitting them has already lost the token. They are stated * where they are read BEFORE the call is committed to, rather than left to be * discovered from a failure. */ declare const addRepository: ToolDefinition; export default addRepository;