New from the DevTools team: Stresseur, the AI test engineer for APIs →
DevTools

Changelog

Product updates, new features, and improvements to Dev Tools.

cli@1.6.1

cli@1.6.1
View on GitHub

1.6.1 (2026-10-11)

🩹 Fixes

  • form_data and urlencoded fields keep their YAML order. ([](https://github.com/the-dev-tools/dev-tools/commit/))

cli@1.6.0

cli@1.6.0
View on GitHub

1.6.0 (2026-10-11)

🚀 Features

  • Onboarding fixes for flows run against local apps: (baead616)
  • Secure cookies are now sent to http://localhost, 127.0.0.1, ::1 and *.localhost, as browsers do, so a local dev server's Secure session cookie keeps the session alive. Other http:// hosts still never get them.
  • follow_redirects: false on a request step returns the 30x as is, so the redirect itself can be asserted. Every response now has response.url (the final URL after redirects) and response.redirects, e.g. '!(response.url contains "/login")'. The option survives YAML export; the desktop app doesn't store it yet.
  • {{ now() }} now writes an RFC 3339 timestamp (2026-10-11T15:59:15.978+03:00) instead of Go's internal time format. uuid(), ulid(), now().Unix() and faker.* are documented in the YAML README.
  • flow run reads ./.env and the flow file's directory's .env for {{ #env:NAME }} (the process environment wins), and before running lists every missing #env: name in one error instead of failing at the first step that reads one.

🩹 Fixes

  • AI checks: with no judge provider configured, the judge uses OpenAI when OPENAI_API_KEY is the only key set (a configured provider, model, base_url or api_key_env still decides), and the no-key notice names both keys. A failing token check reports the budget that failed, not the first one, and ci summaries print > instead of ≤ when the p95 latency or max tokens is over its limit. (76e47463)

cli@1.5.0

cli@1.5.0
View on GitHub

1.5.0 (2026-10-10)

🚀 Features

  • devtools import har detects streaming responses. An entry whose response is text/event-stream becomes a streaming request, with its stream: preset (openai, anthropic, vercel-ai or sse) picked from the first recorded event, as Stresseur recordings do. Plain-text, base64 and missing bodies are handled (no body means sse), the import prints a per-preset summary, and exporting the workspace writes stream: <preset>. (d951f9de)

stream:, stream_timeout_ms, expect: and the flow's judge:, quality: and iterations: are now stored with the workspace instead of being dropped on import, so they survive import → export. File-level settings are written back on each flow.

WebSocket flows no longer lose their connection: a ws_connection stayed open only until its step finished, so a later ws_send could fail with "use of closed network connection" and messages stopped being read. The connection now lasts for the whole flow, and its handshake has its own 30 s limit.

cli@1.4.0

cli@1.4.0
View on GitHub

1.4.0 (2026-10-10)

🚀 Features

  • AI checks are now part of the engine. A request or graphql step's expect: block (the Stresseur syntax, unchanged) is validated on import and evaluated by devtools flow run after the flow's steps finish, so it never counts in step timings. Results are printed under the flow's table and written to the JSON report as each step's checks[] (kind, passed, score, reason, judge_model, cached, value, limit). (4b494b2f)
  • Checks: schema/schema_at, max_latency_ms, the new max_ttft_ms, token budgets from usage, and a G-Eval judge (Anthropic or any OpenAI-compatible API). The judge uses injection-resistant prompting, logprob weighting or borderline re-sampling, and runs in parallel.
  • Judge key: STRESSEUR_JUDGE_API_KEY, ANTHROPIC_API_KEY or OPENAI_API_KEY, from the environment or ./.env. Without one, judge checks are skipped with a notice.
  • Cache: verdicts are cached in --judge-cache, default .devtools/judge-cache.json.
  • Exit code: failed checks fail a flow only with quality: { fail_below: … }.

Server-Sent Events responses are now read as they arrive. A text/event-stream response streams automatically; a request step's stream: openai | anthropic | vercel-ai | sse picks the preset that assembles the text, and stream_timeout_ms bounds an open stream (default 30 s). Assertions, expect: and later steps can read response.text, response.events, response.event_count, response.ttft_ms and the streamed response.usage.

cli@1.3.1

cli@1.3.1
View on GitHub

1.3.1 (2026-10-10)

🩹 Fixes

  • Fix four flow-engine bugs that could let a run pass when it should fail, or slow it down: (28a953f1)
  • response.duration in assertions: is now the measured request time in ms. It was always 0, so response.duration < N never failed.
  • A failed assertion now shows each value it checked, e.g. (got response.duration = 5120) or (got response.body.name = "Outdoor"), instead of only the status code. Values under names like token or password are redacted. When a body field is compared on a non-JSON response, such as a 404 HTML page, the error now names the status and content type instead of only invalid operation: int(string).
  • JS steps no longer add a fixed ~3 s per run. The worker is polled every 25 ms and is ready in about 0.1 s.
  • Import now rejects a step that reads another step's output, such as {{ Ask.response.body.answer }}, without depending on that step. The error names the step and the missing depends_on. Before, such a step ran at flow start with the template unfilled, and the flow still passed.

cli@1.3.0

cli@1.3.0
View on GitHub

1.3.0 (2026-10-09)

🚀 Features

  • Load mode grows from constant-vus to four executors: ramping-vus (stages with graceful ramp-down), and the open-model constant-arrival-rate and ramping-arrival-rate, which start iterations on schedule whatever the response time and report dropped iterations once max_vus are busy. A load: entry can add think_time, thresholds (e.g. p95: <300ms, errors: <1%, per step under steps:), checked at the end and failing the run with exit code 99, and abort rules evaluated every metrics frame that stop a run early with exit code 108. --report frames:<url> streams every metrics frame, with per-step HDR histograms, and the final report to an HTTP endpoint (bearer token from DEVTOOLS_FRAMES_TOKEN, retried in the background, and the run stops if the endpoint is unreachable for 60s); --vus-scale/--rate-scale split one profile across machines, --load-file reads scenarios from a separate file with the same schema, and the summary now shows the request count it is based on. (c5002b3d)

cli@1.2.2

cli@1.2.2
View on GitHub

1.2.2 (2026-10-07)

🩹 Fixes

  • The CLI no longer prints "Config file not found, creating default config file" or writes a default ~/.devtools.yaml on first run; a config file is still read when present. (1dff1083)

cli@1.2.1

cli@1.2.1
View on GitHub

1.2.1 (2026-10-07)

🩹 Fixes

  • The CLI can be embedded in another Go program: cmd.Root() returns its root command, and each release publishes devtools-go-src-<version>.tar.gz, the Go source of the CLI and the modules it imports with the generated code included, to build against. (03382c8b)

cli@1.2.0

cli@1.2.0
View on GitHub

1.2.0 (2026-10-07)

🚀 Features

  • Flows can now declare cleanup: steps that always run after the flow's normal steps, whether they passed or failed, so data a test creates is deleted even when a step in the middle fails and the next run starts from the same state. Cleanup steps are request or graphql steps that can read earlier outputs ({{ PostProducts.response.body.id }}); they run in listed order (depends_on may reorder them among themselves), a step that reads a step which never ran is reported as skipped, and a failing cleanup step fails an otherwise passing flow while an earlier failure stays the reported error. Cleanup steps appear after the normal steps in the console table and in JSON and JUnit reports, and run after every iteration in load runs without being measured. (f204ce9e)
  • Flows can read the cookies they've received: {{ cookies.csrftoken }}, or {{ cookies["XSRF-TOKEN"] }} for names that aren't identifiers. This makes double-submit CSRF protection (Django, Laravel, Angular, many Express apps) testable: copy the CSRF cookie into the header the server checks. Values are URL-decoded the way client code reads them, the latest value of each cookie wins, and a flow variable named cookies takes precedence. (60054c5f)

cli@1.1.3

cli@1.1.3
View on GitHub

1.1.3 (2026-10-07)

🩹 Fixes

  • A failing assertion now prints one line that shows what the server answered: Error: assertion failed: response.status == 200 (got 401: {"error":"Invalid credentials"}). Non-2xx responses include a short body excerpt; 2xx bodies are left out because they can carry tokens. The flag reference no longer prints under a failing flow, and the error no longer repeats four times. (c8520dd6)

cli@1.1.2

cli@1.1.2
View on GitHub

1.1.2 (2026-10-07)

🩹 Fixes

  • Load runs now work for flows whose steps use an earlier step's response, such as a login token passed to the next request. Lean mode used to drop every response body, so those steps failed on every iteration and the run reported the target as unreachable. Bodies a later step reads are now kept; the rest are still dropped to keep memory flat. (83a2a5b4)
  • Assertions and conditions can now compare numbers from JSON responses: response.body.qty == 3, response.body.price > 100 and arithmetic work. Response numbers used to compare as text, so equality was always false and >/< failed with a type error. Values copied into later requests with {{ }} keep their exact original text, as before. (3cd2d960)

desktop@1.1.3

desktop@1.1.3
View on GitHub

Heads up: on October 13, 2026, DevTools Studio becomes Stresseur Studio. It's the same app with the same flows, and it's still free, open source and local. You don't need to do anything.

Details: https://dev.tools/blog/devtools-studio-becomes-stresseur-studio/

desktop@1.1.2

desktop@1.1.2
View on GitHub

Heads up: on October 13, 2026, DevTools Studio becomes Stresseur Studio. It's the same app with the same flows, and it's still free, open source and local. You don't need to do anything.

Details: https://dev.tools/blog/devtools-studio-becomes-stresseur-studio/

desktop@1.1.1

desktop@1.1.1
View on GitHub

Heads up: on October 13, 2026, DevTools Studio becomes Stresseur Studio. It's the same app with the same flows, and it's still free, open source and local. You don't need to do anything.

Details: https://dev.tools/blog/devtools-studio-becomes-stresseur-studio/

cli@1.1.1

cli@1.1.1
View on GitHub

1.1.1 (2026-08-09)

🩹 Fixes

  • Fix Windows release builds: platform variables now resolve shell-agnostically, so win32-x64 and win32-ia32 binaries build and cross-compile correctly. Republishes all six CLI platform binaries. (ad36e8dc)

desktop@1.1.0

desktop@1.1.0
View on GitHub

Heads up: on October 13, 2026, DevTools Studio becomes Stresseur Studio. It's the same app with the same flows, and it's still free, open source and local. You don't need to do anything.

Details: https://dev.tools/blog/devtools-studio-becomes-stresseur-studio/

---

1.1.0 (2026-08-08)

🚀 Features

  • Load testing foundations: local load mode (flow run --vus/--duration and load: scenarios with percentile tables + load_report JSON), versioned yamlflow schema (version: 2), HTTP assertions in yamlflow files now enforced on import (previously silently dropped), run: blocks execute in dependency order with strict failure modes (failed dependencies skip-and-continue instead of aborting the run), run-flows GitHub Action for CI, and real build-version reporting in devtools version. (9a3152a3)

cli@1.1.0

cli@1.1.0
View on GitHub

1.1.0 (2026-08-08)

🚀 Features

  • Load testing foundations: local load mode (flow run --vus/--duration and load: scenarios with percentile tables + load_report JSON), versioned yamlflow schema (version: 2), HTTP assertions in yamlflow files now enforced on import (previously silently dropped), run: blocks execute in dependency order with strict failure modes (failed dependencies skip-and-continue instead of aborting the run), run-flows GitHub Action for CI, and real build-version reporting in devtools version. (9a3152a3)

desktop@1.0.3

desktop@1.0.3
View on GitHub

1.0.3 (2026-07-05)

🩹 Fixes

  • Windows builds restored. A stale @nx/eslint patch made dependency installation fail hard on Windows CI, so 1.0.2 shipped without Windows (and, due to an expired Apple agreement, macOS) artifacts. The dead patch is removed; this release ships installers for all platforms again. Includes everything from 1.0.2, notably the fix for workspaces going blank after many file reorders (#44).

desktop@1.0.2

desktop@1.0.2
View on GitHub

1.0.2 (2026-07-05)

🩹 Fixes

  • ### Bug fixes (#44)
  • Workspaces no longer go blank after many file reorders. File append/reorder used the midpoint between the last position and float32 MAX to generate display_order, converging to the float32 limit after a few dozen inserts — at which point every file in the workspace disappeared from the UI and new flows could not be created. Order generation now uses fixed steps, and a startup migration repacks existing display_order values to small sequential numbers (preserving your current order), so previously broken workspaces recover automatically. (#44)

cli@1.0.3

cli@1.0.3
View on GitHub

1.0.3 (2026-07-05)

🩹 Fixes

  • Windows binaries restored. A stale @nx/eslint patch made dependency installation fail hard on Windows CI, so 1.0.2 shipped without win32-x64/win32-ia32 binaries. The dead patch is removed; this release ships all platforms again. Includes the file display_order repair migration from 1.0.2 (#44).

cli@1.0.2

cli@1.0.2
View on GitHub

1.0.2 (2026-07-05)

🩹 Fixes

  • ### Bug fixes (#44)
  • Startup migration repairs pathological file ordering. The embedded server now repacks files.display_order values that converged to float32 MAX (a bug in desktop order generation) back to small sequential numbers, preserving relative order. Databases shared with a broken desktop workspace recover automatically. (#44)

desktop@1.0.1

desktop@1.0.1
View on GitHub

1.0.1 (2026-05-05)

🩹 Fixes

  • ### Bug fixes (#42)
  • Loop break condition now sees inner-node outputs. For/ForEach break expressions are evaluated after each iteration's children run, so they can reference values produced during that iteration (e.g. {{ http_1.response.body.done }}). Previously the check ran before children, so any expression referencing a not-yet-written variable failed the entire flow on the first iteration. Missing identifiers are now treated as "don't break" (loops are still bounded by iteration count). ForEach semantics also aligned with For: an expression that evaluates true exits the loop. (#42)
  • YAML imports no longer fail with a foreign-key error. Workspace YAML imports were storing HTTP requests before their parent folder file in StoreUnifiedResults, so SQLite rejected the row with FOREIGN KEY constraint failed (787) whenever GenerateFiles=true. Files are now stored first, and HTTP folder_id references are remapped before insertion.
  • Imported workspaces show up in the UI immediately. The import path now publishes mutation events for newly created flows, flow nodes, per-type node configs (For, ForEach, JS, Condition, AI), edges, flow variables, and HTTP requests, so the desktop's TanStack DB collections refresh in real time instead of waiting for a manual reload. Previously, imported For nodes appeared with Iterations: 0 and an empty break expression until you closed and reopened the workspace.

Other

  • New break_condition field on for / for_each steps in YAML workspaces, mirroring the desktop UI's "Break If" setting.

cli@1.0.1

cli@1.0.1
View on GitHub

1.0.1 (2026-05-05)

🩹 Fixes

  • ### Bug fixes (#42)
  • Loop break condition now sees inner-node outputs. For/ForEach break expressions are evaluated after each iteration's children run, so they can reference values produced during that iteration (e.g. {{ http_1.response.body.done }}). Previously the check ran before children, so any expression referencing a not-yet-written variable failed the entire flow on the first iteration. Missing identifiers are now treated as "don't break" (loops are still bounded by iteration count). ForEach semantics also aligned with For: an expression that evaluates true exits the loop. (#42)

Other

  • New break_condition field on for / for_each steps in YAML workspaces, so loops in CLI-driven flows can exit on a runtime predicate without needing the UI.

desktop@1.0.0

desktop@1.0.0
View on GitHub

# 1.0.0 (2026-04-24)

🚀 Features

New protocols and flow nodes

  • GraphQL requests: full request editor with query/variables, dark theme tokens, CLI support, YAML export/import, response history, and delta overrides with assertions.
  • WebSocket: connection and send flow nodes, request panel, and tables for persisting messages and headers.
  • Wait node: pause flow execution for a configurable duration.
  • Sub-flow: new Run Sub Flow node plus SubFlowTrigger and SubFlowReturn, enabling flows to invoke other flows with typed inputs/outputs.

Flow engine

  • Flow runner overhaul with improved node execution and error propagation.
  • Flow-level error field and node ID mapping for more precise failure attribution.
  • Copy/paste support extended to GraphQL, WebSocket, and sub-flow nodes.

Expression editor

  • Autocomplete for built-in functions inside {{ }}: uuid(), uuid("v4"), uuid("v7"), ulid(), now().
  • Dot-chain completion on now(): .Unix(), .UnixMilli(), .UnixMicro(), .UnixNano().
  • New faker namespace for fake data — type faker. to browse 35 generators including name(), email(), phoneNumber(), url(), ipv4(), ipv6(), macAddress(), username(), password(), word(), sentence(), paragraph(), date(), timestamp(), uuid(), randomInt(min, max).

Delta system

  • GraphQL delta support with snapshot/override semantics for name, URL, query, variables, description, headers, and assertions.

cli@1.0.0

cli@1.0.0
View on GitHub

# 1.0.0 (2026-04-24)

🚀 Features

New protocols and flow nodes

  • GraphQL requests: query/variables, assertions, response history, YAML export/import.
  • WebSocket: connection and send flow nodes with message capture.
  • Wait node: pause flow execution for a configurable duration.
  • Sub-flow: Run Sub Flow node plus Sub-Flow Trigger and Sub-Flow Return for composing flows.

Flow engine

  • Flow runner overhaul with improved node execution and error propagation.
  • Flow-level error field and node ID mapping for more precise failure attribution.

Expression editor

  • Built-in uuid(), uuid("v4"), uuid("v7"), ulid(), now() helpers inside {{ }}.
  • Dot-chain on now(): .Unix(), .UnixMilli(), .UnixMicro(), .UnixNano().
  • faker.* namespace (35 generators — name(), email(), phoneNumber(), url(), ipv4(), word(), sentence(), paragraph(), date(), timestamp(), uuid(), randomInt(min, max), ...) for fake test data.

AI

  • AI agent with tool execution, streaming, and multi-provider support (OpenAI, Anthropic, Gemini), credential vault encryption, and variable introspection.

desktop@0.5.0

desktop@0.5.0
View on GitHub

0.5.0 (2026-03-04)

🚀 Features

  • Add flow node copy/paste and canvas undo/redo support. (28f2da05)

desktop@0.4.0

desktop@0.4.0
View on GitHub

0.4.0 (2026-03-03)

🚀 Features

  • Add AI agent feature with tool execution, streaming, and provider settings. Add flow error display, fix version history ordering, and fix execution state display on flow versions. (156c82ca)

desktop@0.3.2

desktop@0.3.2
View on GitHub

0.3.2 (2026-03-03)

🩹 Fixes

  • Fix startup reliability and data migration for upgrading users. Migrate database from old data directories (DevTools, DevTools Studio). Catch protocol handler errors during server startup. Cap health check retry backoff. Add branded loading screen and error recovery UI. Fix migration FK reference to prevent folder hierarchy flattening. Make telemetry non-blocking. (a7de9ad6)

desktop@0.3.1

desktop@0.3.1
View on GitHub

0.3.1 (2026-03-02)

🩹 Fixes

  • Fix CodeMirror crash caused by duplicate @codemirror/state instances. Fix server lint by broadening dbtest build tag and removing dead code. (05ca2a7a)

desktop@0.3.0

desktop@0.3.0
View on GitHub

0.3.0 (2026-02-26)

🚀 Features

🩹 Fixes

  • Fix AI node export and credential env var name sanitization (36fd3671)
  • Optimise package size (0da13cbe)
View all releases on GitHub