agentsclimarketplace

Bruno

Skill punkaze/skills/plugin/skills/bruno

punkaze's Claude Code agent skills collection (plugin marketplace). Ships the bruno skill: author/generate/run Bruno .bru API collections.

Install
npx -y skills add punkaze/skills --skill bruno

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Bruno, the Git-friendly API client, and its CLI (bru). Use when authoring or editing .bru requests/collections, generating a collection from an OpenAPI spec or a codebase's routes, writing Bruno tests or scripts, managing environments and secrets, or running collections with `bru run` (local or CI).

SKILL.md

6.5 KB, as published. Nobody here has run it

Bruno — Author, Generate, and Run .bru Collections

Requires the Bruno CLI: npm install -g @usebruno/cli. Everything below is verified against bru 3.5.0 (bru --version).

Generating a collection — two paths

Path A — an OpenAPI/Swagger spec exists (preferred). Look for one first: openapi.yaml, swagger.json, a framework's swagger endpoint (Elysia, NestJS @nestjs/swagger, etc.). Then:

bru import openapi -s <spec.yaml|url> -o <out-dir> -n "My API" --collection-format bru -g path

--collection-format bru is required — the CLI default (opencollection) emits .yml files, not a .bru collection. -g picks folder grouping: path (by URL structure, usually what you want) or tags (by OpenAPI tags, the CLI default). Done when <out-dir> contains bruno.json and .bru files; an opencollection.yml there means the format flag was dropped.

Path B — no spec. Read the codebase and write a routes manifest (shape below), then run the bundled generator:

node "${CLAUDE_PLUGIN_ROOT}/skills/bruno/scripts/generate-bruno.mjs" --manifest routes.json --out ./api-collection

Flags: --force (overwrite existing files), --dry-run (preview, write nothing). Extract routes by reading the code — do not write a per-framework regex route scanner. Done when the generator reports wrote N file(s) and, with the API running, bru run . -r --env <env> from the output dir executes every request.

Routes manifest

Schema: ${CLAUDE_PLUGIN_ROOT}/skills/bruno/references/routes.schema.json — full example: ${CLAUDE_PLUGIN_ROOT}/skills/bruno/references/sample-manifest.json.

{
  "name": "My API",
  "baseUrl": "http://localhost:3000",
  "auth": { "type": "bearer" },
  "environments": [{ "name": "dev", "baseUrl": "http://localhost:3000", "secretVars": ["authToken"] }],
  "routes": [
    { "method": "POST", "path": "/auth/login", "name": "Login", "body": {"email":"","password":""},
      "auth": false, "script": "token-capture", "tests": ["status-2xx"] },
    { "method": "GET", "path": "/users/:id", "name": "Get User", "auth": true, "tests": ["status-200"] }
  ]
}
  • Manifest-level auth.type becomes collection-level auth in collection.bru; routes with auth: true inherit it.
  • Route auth: trueauth: inherit, falsenone, or an explicit "bearer"|"basic"|"inherit"|"none" per-request override.
  • Use :param in path for path params.
  • script: "token-capture" adds a post-response script that captures res.body.token into the runtime variable authToken.
  • tests accepts status-200, status-201, status-2xx.

.bru syntax (verified against Bruno 3.5.0)

meta {
  name: Get User
  type: http
  seq: 1
  tags: [smoke]
}

get {
  url: {{baseUrl}}/users/:id
  body: none
  auth: inherit
}

params:path {
  id: 1
}

params:query {
  expand: profile
}

headers {
  Accept: application/json
}

body:json {
  {
    "name": "John"
  }
}

script:post-response {
  if (res.status >= 200 && res.status < 300 && res.body && res.body.token) {
    bru.setVar("authToken", res.body.token);
  }
}

tests {
  test("status is 200", function() {
    expect(res.status).to.equal(200);
  });
}

docs {
  Retrieve a single user by id.
}

Critical syntax rules (these were wrong in other community skills):

  • Query params use params:query { } — NOT legacy query { }.
  • Path params: keep :param in the URL and add a params:path { } block — do NOT substitute {{param}}.
  • Child requests should use auth: inherit to reuse collection/folder auth; only emit auth:bearer { token } / auth:basic { ... } for an explicit per-request override.

Collection-level auth — collection.bru

auth: inherit resolves against collection.bru at the collection root (or a folder's folder.bru). Without it, "inherited" requests send no auth at all:

meta {
  name: My API
}

auth {
  mode: bearer
}

auth:bearer {
  token: {{authToken}}
}

Environments

vars {
  baseUrl: http://localhost:3000
}
vars:secret [
  authToken
]

Secret variable names go in vars:secret [ ]; their values are never written to disk — set them at runtime or via the GUI. Bruno also supports typed vars (@number, @boolean, @object) and multiline values with '''…'''.

Variables in scripts

  • bru.setVar(key, val) / bru.getVar(key) — runtime/in-memory, scoped to a single run, never written to disk. Use this for chaining secrets like auth tokens between requests.
  • bru.setEnvVar(key, val) / bru.getEnvVar(key) — environment variable. The Bruno GUI can save environment edits into the environment file — a secret set this way can end up committed to Git. Use setEnvVar only for non-secret config; prefer setVar for tokens.
  • Response: res.status, res.body, res.responseTime.

Running with bru run (CLI 3.5.0)

Run from the collection root (the directory containing bruno.json) — anywhere else fails with "You can run only at the root of a collection".

bru run . -r --env dev                            # run the whole collection recursively
bru run folder -r --env dev                       # run a folder recursively
bru run request.bru --env-file env.bru            # explicit env file
bru run . -r --env dev --env-var token=$TOK       # override one var from shell (no secret in history)
bru run . -r --reporter-junit results.xml --reporter-html report.html
bru run . -r --bail --tests-only                  # CI: stop on first failure, only requests with tests
bru run . -r --csv-file-path data.csv --parallel  # data-driven, parallel iterations
bru run . -r --tags smoke --exclude-tags wip      # filter by meta tags

Sandbox (v3 default changed): the CLI defaults to --sandbox safe — no filesystem access, no require() of external npm packages. Only pass --sandbox developer when you trust the collection and genuinely need fs/exec/ npm in scripts; it is dangerous with untrusted collections.

Secrets: prefer --env-file or --env-var KEY=$SHELL_VAR; never paste a live secret literal on the command line (it leaks into shell history).

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.