一键导入
bruno
Bruno API client skill — .bru file format, JavaScript API reference, authentication patterns, testing with Chai.js, and Git-first collection management.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Bruno API client skill — .bru file format, JavaScript API reference, authentication patterns, testing with Chai.js, and Git-first collection management.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Trace the second-, third-, and nth-order consequences of a decision, change, or plan — the effects of the effects — so thinking doesn't stop at the obvious first-order outcome. Use when the user asks "what are the consequences of X", "think this through", "second-order effects", "n order consequences", "what could this cause downstream", or before committing to a significant decision (technical, product, organizational, personal).
Quiz the user on whether they actually understand a code change before it ships. Generates a short literate explainer of a diff, then administers five comprehension questions that test how the change works — not requirements, not trivia. Use before opening a PR, before merging, when reviewing someone else's PR, or when the user says "quiz me on this", "do I understand this change", "code quiz", "gate this PR", or wants to check comprehension of AI-written code.
Review feature code against DDD and hexagonal architecture principles. Validates domain entities, value objects, use cases, adapters, folder structure, file naming, and test placement.
Create Phase 0 documentation for a new feature. Generates docs folder structure with plan.md, glossary.md, business-logic.md, architecture.md, errors.md, questions.md, and adr/ folder. Use before any code is written.
Git operations enforcer - manages branches, commits, and pull requests with strict naming conventions and quality gates
Teaches Helix editor by analyzing the user's existing configuration, explaining keybindings and LSP setup, and answering questions. Use when the user asks about Helix, their helix config, keybindings, LSP setup, themes, or wants help setting up or learning Helix. Also triggers on "helix keybindings", "explain my helix config", "helix setup", "learn helix", or "hx config".
| name | bruno |
| description | Bruno API client skill — .bru file format, JavaScript API reference, authentication patterns, testing with Chai.js, and Git-first collection management. |
| user_invocable | false |
Bruno is an innovative API client that stores API collections directly in your filesystem using a plain text markup language (.bru files). It's designed as a Git-first, offline-only alternative to Postman, perfect for teams who want to version control their API tests alongside their code.
meta {
name: Get User Profile
type: http
seq: 1
}
get {
url: {{baseUrl}}/users/{{userId}}
body: none
auth: inherit
}
headers {
accept: application/json
user-agent: Bruno/1.0
}
script:pre-request {
// Set dynamic values
bru.setVar("timestamp", Date.now());
bru.setVar("userId", "123");
}
script:post-response {
// Extract response data
if (res.status === 200) {
bru.setVar("userName", res.body.name);
}
}
tests {
test("User profile retrieved successfully", function() {
expect(res.status).to.equal(200);
expect(res.body).to.have.property("name");
expect(res.body).to.have.property("email");
});
}
Bruno has two types of environments:
Stored as .bru files in an environments/ folder inside the collection directory. These are version-controlled.
vars {
baseUrl: https://api.example.com
apiVersion: v1
timeout: 5000
}
vars:secret [
apiKey,
clientSecret,
refreshToken
]
Managed by the Bruno desktop app, stored outside the collection repo as .yml files. See ENVIRONMENTS.md for storage location, format, available environments, and CLI usage.
{
"version": "1",
"name": "My API Collection",
"type": "collection",
"proxy": {
"enabled": false
},
"scripts": {
"moduleWhitelist": ["crypto", "buffer"]
}
}
req.getUrl() / req.setUrl(url) - Get/set request URLreq.getMethod() / req.setMethod(method) - Get/set HTTP methodreq.getHeader(name) / req.setHeader(name, value) - Manage headersreq.getBody() / req.setBody(body) - Manage request bodyreq.setTimeout(ms) - Set request timeoutreq.getName() - Get request namereq.getTags() - Get request tagsres.status - HTTP status coderes.statusText - HTTP status textres.headers - Response headers objectres.body - Parsed response bodyres.responseTime - Response time in millisecondsbru.setVar(key, value) / bru.getVar(key) - Runtime variablesbru.setEnvVar(key, value) / bru.getEnvVar(key) - Environment variablesbru.setNextRequest(name) - Chain requestsbru.sleep(ms) - Pause executionbru.interpolate(string) - Interpolate variables including dynamic onesbru.cookies.jar() - Cookie management{{$guid}}, {{$timestamp}}, {{$randomInt}}{{$randomEmail}}, {{$randomFirstName}}, {{$randomLastName}}{{$randomPhoneNumber}}, {{$randomCity}}, {{$randomCountry}}// Environment variables in .bru files
{{baseUrl}}/api/users
// Runtime variables in scripts
bru.setVar("userId", res.body.id);
const userId = bru.getVar("userId");
// Generate test data
const email = bru.interpolate('{{$randomEmail}}');
auth:bearer {
token: {{authToken}}
}
auth:basic {
username: {{username}}
password: {{password}}
}
auth:apikey {
key: x-api-key
value: {{apiKey}}
}
Variables can be interpolated directly inside JSON bodies, including entire objects:
# JSON with interpolated variable as a value
body:json {
{
"name": "{{userName}}",
"email": "{{userEmail}}"
}
}
# JSON with interpolated variable as an entire object
# Useful for replaying API payloads (e.g. webhook events)
body:json {
{
"type": "treasury.received_credit.created",
"data": {
"object": {{dataObject}}
}
}
}
Note: when using a variable as a full object ({{dataObject}}), do not wrap it in quotes — Bruno will interpolate it as raw JSON. Set the variable value via bru.setVar() in a pre-request script or pass it as a runtime variable.
# Standard JSON
body:json {
{
"name": "John Doe",
"email": "john@example.com"
}
}
# Form data
body:form-urlencoded {
username: john
password: secret
}
# XML
body:xml {
<?xml version="1.0"?>
<user>
<name>John</name>
</user>
}
// Set dynamic values
bru.setVar("timestamp", Date.now());
bru.setVar("requestId", `req_${Date.now()}`);
// Generate test data
const email = bru.interpolate("{{$randomEmail}}");
bru.setVar("testEmail", email);
// Validate required variables
if (!bru.getEnvVar("apiKey")) {
throw new Error("API key is required");
}
// Extract and store data
if (res.status === 200) {
bru.setVar("userId", res.body.id);
bru.setVar("authToken", res.body.token);
}
// Chain to next request
if (res.body.needsVerification) {
bru.setNextRequest("Verify Email");
}
test("Status code is 200", function () {
expect(res.status).to.equal(200);
});
test("Response structure is correct", function () {
expect(res.body).to.be.an("object");
expect(res.body).to.have.property("data");
});
test("Response time is acceptable", function () {
expect(res.responseTime).to.be.below(2000);
});
test("Data validation", function () {
expect(res.body.user.email).to.match(/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/);
});
const jar = bru.cookies.jar();
jar.setCookie("https://api.example.com", "sessionId", "abc123");
const cookie = await jar.getCookie("https://api.example.com", "sessionId");
vars:secret blocks, not in version controlbru.setNextRequest() for workflowsWhen working with Bruno, prioritize the plain text, Git-collaborative approach and always consider the offline-first philosophy.