From grafana-k6
Build runnable k6 artifacts from a plan or direct requirements. Use when users ask to generate k6 scripts, choose/apply executors in runnable options, or create single/multi-environment configs. Prefer this skill for any implementation output request, even if the user also mentions "executor" or "config".
How this skill is triggered — by the user, by Claude, or both
Slash command
/grafana-k6:k6-builderThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
- User says: "generate runnable k6 script for this endpoint"
Generate runnable k6 artifacts safely and deterministically:
Do not switch to planning-only discussion when user asked for implementation output.
At the beginning of the workflow, detect and use interaction tools in this order:
AskUserQuestion exists, use it for required inputs.mcp:sampling or create_message exists, use native IDE modal interaction.confirm_action exists, use it for critical confirmations.> [?] MISSING REQUIREMENT: Missing build input for runnable artifacts
missing: target, scenario type, SLA requirements, protocol
why: deterministic generation cannot proceed safely without minimum build inputs
next_question: What target URL or endpoint should this build use?
Do not continue generation after fallback.
When fallback is required, always use this portable payload shape:
> [?] MISSING REQUIREMENT: <short missing requirement summary>
missing: <comma-separated missing fields>
why: <why generation cannot continue deterministically>
next_question: <single, specific question that unblocks the next step>
Do not emit final artifact content after this fallback.
Round contract:
Partial template override for multi-environment requests:
target or protocol is missing but the request clearly specifies multiple environments and a scenario, generate a partial script template with __ENV placeholders for all missing values.[assumption-based] in a pending_questions block appended at the end of the artifact.Partial template override for auth-only edge cases:
target is missing, generate an auth-focused partial template.__ENV.BASE_URL (or protocol-equivalent env var) placeholder and mark all unresolved values as [assumption-based].pending_questions block with one direct question for the unresolved target.Additional questions must be integrated into the same question system, not handled as a separate side flow:
protocol=http and the method cannot be inferred safely.Load Profile Defaults (when profile is not specified):
minimal: 5 VUs, 1m duration, smoke testingstandard: 25 VUs, 9m duration, realistic loadaggressive: 120 VUs, 14m duration, stress testingOutput Format: Primary output is runnable artifacts with:
Next recommended stepDeterminism: Same inputs produce identical outputs every time.
load, stress, spike, soak, smoke).minimal, standard, aggressive) used when explicit vus/duration are missing.Before producing final HTTP artifacts, add the method question to the same active question system:
GET, POST, PUT, PATCH, DELETE) when endpoint behavior depends on method.Before finalizing artifact output, add auth questions to the same active question system:
__ENV) for auth inputs and list required variables.If invoked without prior plan, the same Adaptive Question System above still applies.
Then:
k6-validate handoff block with one suggested validation commandAlways enforce these validations before returning output:
vus and duration, or explicit staged/scenario equivalent.preAllocatedVUs <= maxVUs.vus and iterations.__ENV) for auth and base URL.dev/staging/prod, validate dev <= staging <= prod for VU progression.WARNING if user override violates VU progression without explicit justification.p99<2s in dev when the SLA states p99<1s), reject the artifact and report under Guardrail Validation.export default function must always have a name derived from the active scenario and protocol.run<Protocol><ScenarioType> — example: runHttpLoad, runGrpcStress, runBrowserSmoke.runPerfTest.When building for multiple environments (dev/staging/prod):
Rationale: SLA is a commitment and must remain coherent across environments. Relaxing SLA by environment creates non-comparable results and hides production risk.
Canonical cross-skill warning (must match k6-plan exactly):
WARNING: SLA must be identical across environments to maintain testing coherence.
Canonical enforcement flow (builder stage):
Do you want to normalize all environment thresholds to the same SLA now?load: ramping-vusstress: ramping-vus (aggressive progression)spike: ramping-vus (rapid surge)soak: constant-vus or ramping-vus sustainedsmoke: constant-vusIf user explicitly requires rate control, prioritize:
constant-arrival-rate for fixed RPSramping-arrival-rate for changing RPSIf user asks for exact iteration accounting:
per-vu-iterations or shared-iterationsWhen building multi-environment outputs (dev/staging/prod), apply mandatory differentiation:
p99<1s) must be applied identically to dev, staging, and prod. Only VU counts, durations, ramp-up stages, and load profiles may differ per environment. Any threshold relaxation (e.g., p99<2s in dev when SLA states p99<1s) is a hard invariant violation — reject and report under Guardrail Validation.__ENV.DEV_BASE_URL, __ENV.STAGING_BASE_URL, __ENV.PROD_BASE_URL as named environmental variables.p99<1s) with __ENV placeholder for the URL.profiles object with per-env overrides — never collapse to a single block relabeled with comments.When user requests multi-env outputs, offer two architecture options and make the default explicit:
dev.js, staging.js, prod.jsload-test.js__ENV.ENVIRONMENT selects environment-specific VUs/durationDefault behavior:
p95<Xms -> 95th percentile latency thresholdp99<Xms -> 99th percentile latency thresholderror<X% or rate<X% -> Error rate thresholdp95<500ms,p99<900ms,error<1% -> All conditions must be metp95<500ms AND p95>100ms -> p95 must be between 100ms and 500msNote: OR logic is not supported in this skill behavior. All conditions are treated as mandatory (AND).
p95<400ms,error<1% -> p95 AND error rate thresholdsp95<500ms AND p99<900ms -> Both percentiles requiredp95<2s -> Single threshold with p99 inferred (see sla-defaults.md)Defaults per profile when SLA is not provided:
minimal: p95<800ms, error<2%standard: p95<500ms, error<1%aggressive: p95<300ms, p99<700ms, error<0.5%, checks>99%When generating thresholds, apply the correct metric per protocol. Using http_req_duration for non-HTTP protocols is a hard invariant violation.
| Protocol | Required threshold metric |
|---|---|
| HTTP | http_req_duration: ['p(95)<Nms'] |
| WebSocket | ws_session_duration: ['p(95)<Nms'] (built-in session duration metric) |
| gRPC | grpc_req_duration: ['p(99)<Nms'] |
| Browser | browser_http_req_duration: ['p(95)<Nms'] |
If the inferred protocol does not match http, ensure the threshold uses the correct metric above — never substitute http_req_duration as a fallback.
When generating artifacts (single or multi-environment):
For HTTP/gRPC/Browser protocols:
target is explicitly provided (literal URL), wrap it in __ENV:
if (!__ENV.BASE_URL) {
throw new Error('BASE_URL environment variable is required');
}
const BASE_URL = __ENV.BASE_URL;
const BASE_URL = 'https://api.example.com'; (hardcoded literal without __ENV)For multi-environment outputs:
__ENV[${env.toUpperCase()}_BASE_URL].env.example stub with all required variables.Validation: After artifact generation, scan for violations:
= 'https:// or = "https:// without __ENV, REJECT.[ ] Base URL uses __ENV, not hardcoded literalsgrpc.Client(), client.load(), client.connect(), client.invoke()grpc_req_duration, grpc_req_failedbrowser.newContext(), context.newPage(), page.goto(), page.waitForSelector()data-testid selectorsp(95)<4000 when the request states p95<4s).ws.connect() from k6/ws and handle all lifecycle events: on('open'), on('message'), on('error'), on('close').http_req_duration does not capture WebSocket behavior. Use built-in ws_session_duration for session duration and a custom Trend for per-message latency:
import { Trend } from 'k6/metrics';
const wsLatency = new Trend('ws_message_latency');
// in default function, record per-message timing:
// wsLatency.add(Date.now() - sentAt);
// in options.thresholds:
// ws_session_duration: ['p(95)<1500']
// ws_message_latency: ['p(95)<150']
[ ] WebSocket script includes builtin ws_session_duration and custom ws_message_latency thresholds.
Apply deterministic recommendation:
K6_WEB_DASHBOARD=falseK6_WEB_DASHBOARD=trueK6_WEB_DASHBOARD=false unless explicit opt-infalseEvery response must include these sections in order:
__ENV, not hardcoded literalsProvided: <comma-separated provided inputs>Defaults Applied: <comma-separated key=value defaults>Pending Questions: <single unblocker question>[provided] and [assumed] tags inline per key-value token.k6-validate
## k6-validate Recommendation
Run k6-validate to check this smoke artifact:
- **For other scenarios** (load, stress, soak, spike): Include validation recommendation that references k6-validate.
__ENV.BASE_URL for runnable scripts.timeout: '30s' baseline)..env.example placeholders only.## Required Environment Variables block listing each __ENV.VAR_NAME with a one-line description of its purpose.## Required Environment Variables block must be concrete and non-empty; include every required runtime variable and avoid generic placeholders like "add your vars here"..env.example stub section with three labeled groups (# dev, # staging, # prod) showing the expected variable names as empty placeholders.Generated code must not introduce static-analysis violations. Before emitting any artifact:
Named exports — export default function must be named (see Required k6 Invariants #6).
run<Protocol><ScenarioType> (e.g., runHttpLoad(), runGrpcSmoke()).export default function followed by (.export default function\s*\( (anonymous), REJECT the artifact immediately.runHttpLoad)". Do not emit unless function is named.No var declarations — use const or let only.
No console.log in hot paths — inside export default function or any function called per iteration.
No hardcoded literals for URLs or credentials — all configurable values must use __ENV.
No silent catch blocks — errors must be logged or re-thrown with context.
No unsafe JSON.parse — wrap in try-catch with descriptive error message.
If any generated line would violate a rule above, block the artifact and report the specific violation under Guardrail Validation instead of emitting broken code.
Keep this file focused on generation workflow. Place deep guidance in:
skills/k6-builder/references/README.mdtarget, scenario, sla, protocol, profile, duration, vus, environments, goal).target, scenario, sla, or protocol are missing.load and the user did not explicitly request rate-based control, recommend and emit ramping-vus.export default function () {}; (b) SLA thresholds are identical across all environments — reject any per-environment threshold relaxation. Both are hard invariant violations that block output emission.npx claudepluginhub charlyautomatiza/charlyautomatiza-marketplace --plugin grafana-k6Writes and executes k6 load tests for HTTP APIs, WebSocket endpoints, and browser scenarios. Configures smoke, load, stress, spike, and soak tests with thresholds, stages, and CI/CD integration.
Writes and debugs k6 load test scripts in JavaScript/TypeScript covering all test types, thresholds, checks, scenarios, executors, and CI/CD integration.
Produces a complete load and performance testing plan with scenario definitions, k6/Locust script skeletons, threshold tables, and CI integration steps.