Skip to content

chore(deps): Bump the bowire group with 6 updates - #33

Closed
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/nuget/harbor-demo/src/Kuestenlogik.Bowire.Samples.Amqp/bowire-b316666265
Closed

dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/nuget/harbor-demo/src/Kuestenlogik.Bowire.Samples.Amqp/bowire-b316666265

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Jul 5, 2026 •

Copy link
Copy Markdown
Contributor

Updated Kuestenlogik.Bowire.Protocol.Amqp from 0.2.1 to 1.0.1.

Release notes

Sourced from Kuestenlogik.Bowire.Protocol.Amqp's releases.

1.0.1

What's Changed

New Contributors

Full Changelog: Kuestenlogik/Bowire.Protocol.Amqp@v1.0.0...v1.0.1

1.0.0

Full Changelog: Kuestenlogik/Bowire.Protocol.Amqp@v0.2.2...v1.0.0

1.0.0-rc.3

Full Changelog: Kuestenlogik/Bowire.Protocol.Amqp@v1.0.0-rc.2...v1.0.0-rc.3

1.0.0-rc.2

Full Changelog: Kuestenlogik/Bowire.Protocol.Amqp@v1.0.0-rc.1...v1.0.0-rc.2

1.0.0-rc.1

Full Changelog: Kuestenlogik/Bowire.Protocol.Amqp@v0.2.2...v1.0.0-rc.1

0.2.2

What's Changed

New Contributors

Full Changelog: Kuestenlogik/Bowire.Protocol.Amqp@v0.2.0...v0.2.2

Commits viewable in compare view.

Updated Kuestenlogik.Bowire.Protocol.Grpc from 1.6.0 to 2.1.1.

Release notes

Sourced from Kuestenlogik.Bowire.Protocol.Grpc's releases.

2.1.1

<One-sentence frame for what 2.1 is about. Replaces this placeholder
the moment the first 2.1 work lands.>

Highlights

Bowire as a transparent in-process interceptor — app.UseBowireInterceptor() (#​153)

The new interceptor middleware extends Bowire from "the operator drove a call" to "every request flowing through the host." app.UseBowireInterceptor() registers a pass-through middleware that records method / path / headers / request body / response status / response headers / response body / latency for every request the host receives — from any client, with zero client-side setup, no cert trust, no separate process. Captured flows land in the workbench's new Intercepted rail (sister to the standalone Proxy rail) live over SSE. When the operator starts a recording in the workbench, intercepted flows auto-append as recording steps — point any client at the host, click stop, replay. Standalone reverse-proxy mode (Phase C) and mock injection (Phase D) ship in later releases.

MCP-over-MCP forwarder — bowire mcp serve --attach (#​286)

A thin Bowire process can now relay every incoming MCP tool call to a heavier Bowire running on the operator's workstation. bowire mcp serve --attach localhost:5198 --port 5199 boots a forwarder that surfaces no local tools — tools/list, tools/call, prompts, resources, and resource templates are all marshalled to the parent and the parent's response is relayed verbatim. Useful when an LLM agent on a CI runner / container should drive the workstation Bowire without sharing the parent's MCP socket directly. The parent gains a matching --token <secret> bearer-auth gate (--bind http only); the child passes the secret with --attach-token <secret>.

Workspace-delete Undo decoupled from Trash (W2a)

The action-log entry for workspace-delete is now self-contained: it carries the full snapshot (workspace, data, originalIdx) inline so Undo reads from the entry itself instead of looking the entry up in workspacesTrash at undo-time. This gives the two surfaces independent retention models:

  • Trash drawer — operator-curated retention via bowire_trash_retention_days (W2).
  • Action log — sliding window of the last 200 entries.

Hard-delete (W2 mode) now writes ONLY the action-log snapshot — there's no trash entry to consult. Soft-delete writes both. Entries persisted BEFORE this change still resolve via the legacy Trash-lookup path (a one-shot console.info flags the fallback so the migration window is visible).

The other entity-delete resolvers (recording-delete, flow-delete, env-delete) were audited and already carry their entity payload inline — only workspace-delete had the Trash coupling.

Settings tree organized by scope; Configure + Plugins merged (#​325)

The Settings dialog now exposes scope through the parent-node names: This machine (localStorage / install-scoped) and Workspace… (.bww-scoped, travels with the workspace file). The per-page disclaimer that used to repeat the scope copy on every sub-page ("These settings stay on this machine — they don't travel with the workspace file (.bww).") is gone — the tree's grouping carries that information unambiguously. The standalone Plugins lifecycle leaf is gone; it has merged with Configure into a single Plugins node whose six sub-pages (Protocols / UI Widgets / Modules / Formats / Tools / Discovery providers) now render the inline per-plugin settings AND the lifecycle button cluster (Restart / Unload / Reset storage, wired to the existing POST /api/plugins/{id}/lifecycle/{action} 501-stub) per row, plus Install + Check-for-updates at the top of the Protocols sub-page. A new empty-state Workspace… → Per-Workspace overrides page surfaces every machine-scoped setting that the active workspace has overridden (today: the AI provider config, when the workspace has its own ai-config.<workspaceId>.json); saved deep-links from v2.1 (configure-protocols, plugin-<id>, extension-<id>) keep working unchanged, and any saved value pointing at the dropped plugins lifecycle id migrates to configure-protocols.

Breaking changes

Mocks + Traffic rails merged into a single Intercept rail

The Mocks rail and the Traffic rail (which itself unified the earlier Proxy + Intercepted rails) have collapsed into one Intercept rail with four sub-tabs in a locked order:

  • Captured — passive observation of flows captured by UseBowireInterceptor() (was Traffic → "Flows").
  • Live overrides — selective response substitution inside the interceptor pipeline (was Traffic → "Mock Rules").
  • Mock servers — standalone mock-server-from-recording hosts (was the entire Mocks rail).
  • Settings — interceptor / proxy config (was Traffic → "Settings"); adapts to Standalone vs Embedded deployment.

The merge eliminates the previous Phase-3 rail bloat where Mocks + Traffic + the already-hidden Intercepted + Proxy descriptors competed for the same conceptual surface ("what do I do with live traffic"). It also disambiguates "Flows" — the orchestration rail keeps the name; what Traffic used to call "Flows" is now "Captured".

Migration is automatic at first paint (idempotent). On boot, prologue.js:
... (truncated)

2.1.0

v2.1 turns Bowire from a discovery + invoke workbench into a real composition surface. The new Compose rail carries a Hoppscotch-style request builder with a protocol picker, per-protocol layouts, history persistence, binary uploads, and full Collections + Presets integration. Underneath, the workbench is now pluggable: rails and modules ship as package contributions, so the standalone Tool, embedded MapBowire(), and operator-built distributions can pick exactly the surface they want. The new interceptor middleware lets a host hand Bowire every inbound request without client setup. A MapLibre extension + a stand-alone TacticalApi sample demo coordinate-bearing payloads on a live map with bi-directional JSON↔map sync. Streaming subscriptions are now legible, the JSON viewer reaches Hoppscotch parity, and the guided tour walks first-time operators through every rail.

300+ commits since v2.0.1. Three packaging breaking changes for embedded hosts: the standalone Kuestenlogik.Bowire.Rail.Collections package is retired, the whole Rail. package prefix dropped (e.g. Rail.Compose → Compose, Rail.Benchmarks → Benchmarking), and the interceptor surface (Proxy + Intercepted + Traffic rails + the middleware that lived in Core) consolidated into a single Kuestenlogik.Bowire.Interceptor package. See Breaking changes below for the one-to-one mapping table. Existing workspaces, collections, recordings, benchmarks load identically; operator-saved railMode / enabled-rails state migrates on first boot.

Highlights

Compose rail (#​293, #​289, #​290, #​291, #​295)

The old Design rail is rebranded and rebuilt as Compose — a single-line Hoppscotch-style request bar at the top, per-protocol layout below, history + collections + presets on the side. The protocol picker switches the layout in place: REST gets a URL + KV-table chrome, gRPC gets service / method / JSON body, MCP gets tool / arguments, MQTT gets topic / QoS, WebSocket / SSE get connect / subscribe shells. History persists across reloads, binary uploads ride a base64 side-channel through the wire, and benchmarks can re-run any historical request directly. A Compose tab supports right-click → Duplicate tab so you can fan out a request without losing the original. The toolbar lives where you'd expect (no toolbar in Raw mode, of course).

Pluggable workbench — rails + modules as package contributions (#​294)

Bundle.Workbench is now a meta-package: every rail, every module, every extension is a separate project that registers itself via [BowirePlugin] / [BowireExtension] attributes. The standalone Tool depends on Bundle.Workbench; embedded hosts can drop the bundle and pick per-package references for a smaller surface (e.g. just REST + Compose without the AI module). Bundle.Minimal carries the Core + Home + Discover only — useful for "tiny embedded probe" deployments. Settings → Plugins now lists every loaded protocol AND every UI extension with kind / capability chips so the operator can see what's installed at a glance.

Transparent in-process interceptor (#​153)

app.UseBowireInterceptor() registers a pass-through middleware that records method / path / headers / request body / response status / response headers / response body / latency for every request the host receives — from any client, with zero client-side setup, no cert trust, no separate process. Captured flows land in the workbench's new Intercepted rail live over SSE. When the operator starts a recording, intercepted flows auto-append as recording steps — point any client at the host, click stop, replay.

MapLibre extension + TacticalApi integration (#new)

A new Kuestenlogik.Bowire.Map extension auto-mounts a MapLibre GL JS viewer whenever a response carries the coordinate.wgs84 semantic kind. The Wgs84CoordinateDetector picks up {lat, lon}, {latitude, longitude}, AND {latitudeCoordinate, longitudeCoordinate} shapes (TacticalAPI naming) anchored by anchored case-insensitive regex. Bidirectional sync: hover on a JSON {lat,lon} block highlights the matching map pin; hover on a pin highlights the JSON. Click on a pin scrolls the JSON to the line and auto-expands collapsed ancestors. Right-click on a coordinate offers Center on map; double-click on either side copies the path to clipboard. A right-side gutter hint surfaces the semantic kind on hover (wgs84 coordinate).

The new Sample.TacticalApi server (separate samples/ project) hosts Rheinmetall's Situation gRPC service with eight NATO-phonetic-callsign tactical entities (Alpha-1 Recon UAV, Bravo-2 Air Defence Btry, …) drifting on a per-object sine-wave so subscriptions feel live. Bundle.Workbench ships the Kuestenlogik.Bowire.Protocol.TacticalApi plugin out of the box.

Streaming subscriptions, finally legible (#new)

The action button adapts to the active method type: Execute for unary, Subscribe for server-streaming (changes to Stop while a stream is live), Connect / Disconnect for bidirectional and client-streaming. A live state badge in the response pane shows ● Subscribed — 0 msgs → ● Receiving — 42 msgs → ○ Idle — 42 msgs after 5 s without a frame → ○ Closed on stop → × Error on stream failure. A statusbar pill lists every active subscription across methods; click → dropdown with switch / stop / copy-path / "stop all". The action button keeps a stable footprint so layout doesn't jitter when methods change.

Hoppscotch-parity JSON response viewer + toolbar (#​302, #new)

The response viewer renders one JSON line per row with a sticky left gutter carrying line numbers AND the collapse chevron — chevrons line up on the same vertical column regardless of indent depth. Click anywhere on an opener line OR the gutter chevron to toggle. Click = toggle, double-click = Copy path, right-click = unified menu with Copy ${response.X}, Copy path, plus extension-contributed items (Center on map when the map plugin resolves the target). A dedicated JSON toolbar — Expand all, Collapse all, Wrap long lines, Search (Ctrl/Cmd+F), Copy response, Download — sits above the viewer and only renders when the JSON tab is active in tab mode (so the map widget gets its own toolbar real estate). Expand / Collapse rebuild the viewer in place — no full render, so the map's WebGL canvas survives.

Tab ↔ Split layout for response viewers (#new)

Server-streaming and unary response panes get a tab-strip with JSON + per-extension widget tab + a layout toggle. Click the toggle → split-pane with JSON on one side, widget on the other; click again → tabs. Per-method layout persists in localStorage so the operator's preference for each method is remembered. The split-layout decision is extension-driven — Core asks the framework preferredSplitExtensionForMethod(svc, method) rather than hard-coding the coordinate.wgs84 kind. Layering stays clean: Map-specific code in Kuestenlogik.Bowire.Map, Core stays generic.

Guided tour — page-navigation, alternative paths, per-rail empties (#​281, #​303)

A spotlight-overlay tour engine walks first-time operators through every rail: workspace creation, source-URL add, method invoke, recording, collection composition, flow building, traffic capture, security scan. Each rail's empty state surfaces its own secondary tour. The tour engine handles dialog-modal yields, alternative paths (e.g. operator already has a workspace), advance modes (on-cta / on-event / next-button), saved-once dismissal, and reusable fragment includes (_createWorkspaceSteps). Six rail-specific tours land: bowireStartCaptureRecordingTour, bowireStartBuildCollectionTour, bowireStartBuildFlowTour, bowireStartComposeRequestTour, bowireStartCaptureTrafficTour, bowireStartSecurityScanTour.

REST auto-probing of well-known OpenAPI paths

When the operator types a bare URL like http://localhost:5181, the REST plugin now probes a short list of well-known OpenAPI document paths: /openapi.json, /openapi/v1.json, /swagger/v1/swagger.json, /swagger.json, /v3/api-docs, /v3/api-docs.yaml, /api-docs, /openapi.yaml. First valid OpenAPI document wins; the resolved spec URL is cached per origin for the next call. Services are tagged with the operator-supplied URL (not the probed spec URL) so the Discover sidebar groups everything under the URL the operator typed. Skips probing when the supplied URL already looks like a spec URL.

Discovery self-origin gate for SSE / WebSocket / SignalR

Three protocol plugins (SSE, WebSocket, SignalR) used to scan the workbench host's own EndpointDataSource and return locally-registered endpoints regardless of the source URL the operator asked about. With the Tool's --enable-mcp-adapter flag, the workbench's own /mcp route leaked into every external serverUrl the operator added — read as a phantom "SSE Endpoints" service tagged to the wrong source. The new SelfOriginCheck.IsSelfOrigin(serverUrl, sp) helper compares against IServer.Features.IServerAddressesFeature (with loopback aliases + Kestrel wildcards). Each protocol's discovery now gates its local scan on this check — operator-registered endpoints keep working in both directions.

Catalogue plugin — provider seam (#​136)

... (truncated)

2.0.1

v2.0.1 is a patch release driven by operator feedback during real workbench use against discovery-enabled targets. The headline work is the complete rewrite of the Freeform Request Builder so it shares chrome with the discovered-method pane, the new self-contained-vs-source URL semantic for collection items, the foundation plumbing for optional rail modules (no default-flip on upgrade), and a stack of critical fixes around error reporting and pane re-rendering. No breaking changes — existing workspaces, collections, recordings, and benchmarks load identically; only the freeform builder + the console error format change visibly.

Highlights

Freeform Request Builder rebuilt on the discovered-method skeleton (#​40, #​245, #​246, #​252)

The Freeform Request Builder is now end-to-end consistent with a discovered-method pane: same .bowire-header chrome at the top, same .bowire-content[data-split] request/response panes with the draggable divider, same .bowire-action-bar at the bottom with Execute. Service + method become editable inputs inside the standard header info column; protocol is a compact icon-popover in the header's right cluster, and the method type lives as a segmented button bar right next to it. URL was lifted out of the Payload/Metadata/Mock tab strip into an identity-level row because the URL determines which tabs make sense — it isn't a payload part. The previous chrome layered freeform-specific overrides on top of the shared classes; those are retired so the padding, font weights, spacing all match exactly.

The Execute-button dropdown gains an As new request entry on every discovered method. Clicking it snapshots the current request shape — URL, method, body, metadata, auth, methodType — into the freeform builder pre-filled, with a cloned: <svc>/<method> lineage hint riding on the Cancel tooltip and the default save name. The discovered service tree stays untouched; the operator edits the clone in place, executes one-shot, or persists it via the header's + Add to… collection picker. Switching to another method tab and back preserves the clone — freeformRequest is now per-tab session state rather than a singleton that died on the first tab switch.

Self-contained vs source-bound URLs in collection items (#​252)

Collection items learn a urlMode discriminator: inline (URL lives verbatim on the item, no central reference) or source (URL is bound to one of the workspace's centrally-managed Source URLs). The freeform builder URL row grows a two-state segmented toggle to pick mode at save time; switching from Inline to Source with a typed-but-unsaved URL prompts to either persist as a new Source then switch, or discard. On replay, items saved with urlMode='source' re-resolve their URL against the current Source list — a rename / retirement propagates to every bound item without manual touch-up. Items saved before this release default to urlMode='inline', which preserves their old behaviour exactly.

Two compose entry-points land alongside the toggle: Compose new request on the Home rail Quick Actions tile (self-contained URL, the most common case) and New from source… which opens a Source-URL picker before dropping into the builder. Both also surface in the command palette under the new New group, matching against compose, new, request, freeform, ad-hoc. The previous + New button retired from the Discover toolbar — Discover's job is browsing the discovered tree, not composing, so the action moved to where ad-hoc work actually starts.

Rich error detail in the console (#​243)

Failed REST / gRPC invocations used to surface as a bare Error chip with no body — the actual signal (status code, response body, exception, stack frame) lived on the BowireInvokeResult object but was dropped by problemTitle. The console-entry path now uses richErrorDetail, which assembles a multi-line block carrying the title, problem+json status code and reason, detail line, response body (truncated to 4 KB), exception type + message, and the first three non-framework stack frames. Server-side problem+json fields (type, instance, numeric status) are now picked up correctly — earlier regressions where the helper only looked for statusCode / httpStatus aliases are fixed so the Status: 502 line lands as expected. Network errors (no response received) still carry the exception text directly.

Optional rail modules — plumbing (#​248 Phase 1)

Settings → Rail modes editor adds a new section under My preferences where the operator can hide non-essential rails (Recordings, Mocks, Flows, Proxy, Benchmarks, Security) without losing access — disabled rails stay reachable via the command palette and deep links, only the rail icon disappears. Always-on rails (Home, Discover, Workspaces) are hard-coded and can't be toggled. Existing workspaces ship with every rail enabled on upgrade, so no operator sees a surprise hide; the opt-out is explicit. Per-user storage lives in bowire_enabled_rails; per-workspace overrides land later.

This is Phase 1 — pure plumbing, no default-flip. v2.1 (Test pillar) + v2.3 (Security pillar) can ship their new rails as opt-in from day one instead of forcing the always-on assumption, and v2.4's Schema Designer (#​247) lands as the first default-OFF module on top of the mechanic this release ships.

User-defined workspace templates (#​242)

The Workspaces rail's create-workspace dialog grows a Your templates section between the built-in templates and the last-picked default. The active workspace's "Save as template…" tool button snapshots the current URLs, env vars, collection, global vars, and plugin pins into a localStorage-backed bowire_user_workspace_templates record. Templates show as click-to-pick entries with a hover-revealed delete (no accidental purges). Rename and delete affordances live next to each row; the user-template apply(wsId) adapter writes into the new workspace's wsKey buckets exactly the way built-in templates do, so the create-workspace flow is single-pass for both kinds.

The default URLs for the built-in templates also change: REST moves from httpbin.org (no OpenAPI = 0 services) to petstore.swagger.io/v2 (discovers a full Pet/Store/User tree on first connect), gRPC moves from grpc.postman-echo.com:443 (HTTP 502) to grpcs@​grpcb.in:443 (server-reflection enabled), and Mock + Multi-protocol templates pick up the same discovery-enabled endpoints.

Bug fixes

  • Rail force-home clicks: clicking a non-home rail from the no-workspace empty state used to leave the DOM showing the new rail as active while the module state silently reset to home, blocking the next click. Force-home now runs at the top of render() before the rail paints (9a91940).
  • Env load wiped on every boot: loadEnvironmentsFromDisk ran even for browser-only workspaces and clobbered the localStorage seed on first paint. Skip path added for non-disk-mode workspaces (e501ad8).
  • setUrlMeta TDZ-style boot race: urlMeta was referenced from a render handler before its assignment; the getter/setter pair now type-guards the variable so a boot-time ensureAliasForUrl doesn't throw (30a0974).
  • REST OpenApiUploadStore test pollution: parallel test isolation fix; the discover-empty test now brackets OpenApiUploadStore.Clear() so sibling tests can't leak fixtures (30a0974).
  • MapLibre extension assembly-load race: assembly forcibly loaded via typeof(MapLibreExtension).Assembly.FullName + per-test belt-and-suspenders helper (30a0974).
  • CoverageTo95Tests.MapBowireTestAppFactory ContentRoot race: pinned to AppContext.BaseDirectory so CI's Environment.CurrentDirectory toggling can't flip the test app's content root mid-run (30a0974).
  • Discover toolbar + retire-day crash: the protocol-filter button's insertBefore(_, newBtnWrapper) failed after #​244 retired newBtnWrapper; switched to appendChild (b8e1ac3).
  • As new request no longer flips [+]-tab behaviour: selectedMethod / selectedService are preserved when entering the freeform builder so the [+]-tab keeps its "pin current method" behaviour after a clone (62485f9).

Polish

  • Console toolbar — three distinct icons replace the X-glyph duplication: selectionClear (dashed rectangle + X) for Clear selection, trash for Clear all, close for Close console (1eb4022, b656a36).
  • Freeform protocol dropdown — min-width 220px so the option labels stay readable after the button shrank to icon-only in the editable header (8b9c116).

Coverage

... (truncated)

2.0.0

v2.0 is the cut where every optional surface gets pulled out of the core, the workbench shell gets re-architected end-to-end, and a couple of API-level decisions get unwound now that they have stable replacements. Embedded hosts that vendored Kuestenlogik.Bowire directly will need a small set of explicit changes — see Breaking changes at the bottom.

Highlights

Workbench shell re-architected (#​115)

The workbench surface that ships in bowire and embedded hosts was redrawn from the structural level up — Topbar carries identity + workspace context, the left rail holds mode switching, the sidebar holds per-mode lists, the main pane holds the editor, the new statusbar holds system state. Tabs cohere visually into their panes, empty-states are uniform across every surface, and a shared renderDrawer primitive backs Assistant / Help / Tests / Activity / future Inspector — drawer chrome is no longer hand-rolled per surface. Single-Accent + Protocol-Glyph is the only colour encoding; sharper radii (2/4/6 px) come from CSS custom properties. Sidebar means navigation; URL/Schema-Files/AI-Settings became their own surfaces.

Workspace = project folder (#​147–#​151 + #​196 Phase 2)

bowire workspace init / export / import / migrate-format makes a workspace a real directory you can commit. Per-entity files (one JSON per request / environment / collection / recording) survive merges; secrets live in a sibling secrets/ tree that's .gitignored by default. The Kuestenlogik.Bowire.Workspace.Git runtime (shipped in this release) plumbs the per-entity layout through the workbench at read + write time, watches the directory for external edits via FileSystemWatcher + SSE so the workbench reload-toast fires when a teammate commits over your shoulder, merges <env>.json with its <env>.secrets.json sibling at resolve-time so the secret split stays a load-time concern instead of a save-time worry, and gates concurrent edits across two open Bowire instances via a stale-pid-aware .bowire.lock. For disk-mode workspaces (recordings / collections / scripts live on disk rather than in localStorage) the new workspace export <file.json> + workspace import CLI verbs capture every per-entity file in a single archive — .bww-style state download stays available for browser-mode workspaces.

Workspace integrity — plugin pins + scope-split settings (#​193)

A workspace can now pin the protocol plugins it expects (workspace.pluginPins: { rest: ">=2.0", grpc: "*", mqtt: "5.x" }). When a team member opens the workspace, a banner fires if any pinned plugin isn't loaded — with "Install all" and "Open editor" actions instead of cryptic "no such protocol" errors at first request. The pin editor lives in the workspace's own Settings tab, so pins ride the workspace into git instead of getting buried in per-user state. The Settings dialog itself grows a scope-split tree: "My preferences" (per-user — Assistant config, theme, shortcuts, plugins) vs "This project" (per-workspace — pins, sources, env-inclusion, AI override). The Assistant tab supports per-workspace overrides directly: a scope chip in Settings, a matching reminder chip on the workspace surface, and one-click "Use global instead" to drop the override.

Optional packages live outside core

Core Kuestenlogik.Bowire ships with zero PackageReference entries — only the Microsoft.AspNetCore.App framework reference. Embedded hosts add only what they actually use:

  • Kuestenlogik.Bowire.Extension.MapLibre → Kuestenlogik.Bowire.Map — the v1.3.0-rc.1 of the MapLibre extension will be deprecated + unlisted on nuget.org after 2.0 ships (#​197).
  • OpenTelemetry extracted into Kuestenlogik.Bowire.Telemetry — embedded hosts that don't want self-observability no longer pull the OTel transitive weight. The standalone CLI keeps --telemetry working because the tool transitively references it.
  • .Ai, .Help stay opt-in as before. Standalone bowire bundles them.

Naming convention going forward — optional first-party packages are Kuestenlogik.Bowire.<feature> (.Ai, .Help, .Telemetry, .Map) or Kuestenlogik.Bowire.<area>.<backend> (e.g. Kuestenlogik.Bowire.Workspace.Git, shipped in this release). The legacy .Extension.* prefix isn't used for new packages.

OpenAPI library decoupled via adapter packages

REST plugin no longer takes a hard dependency on Microsoft.OpenApi. A new IBowireOpenApiAdapter seam in Kuestenlogik.Bowire.Protocol.Rest lets the consumer pick the library version:

  • Kuestenlogik.Bowire.Protocol.Rest.OpenApi2 — pins Microsoft.OpenApi 2.x, matches what ASP.NET Core 10's AddOpenApi() transitively pulls. Standalone bowire bundles this one.
  • Kuestenlogik.Bowire.Protocol.Rest.OpenApi3 — pins Microsoft.OpenApi 3.x for hosts that want the modern grammar.

Both can be loaded side-by-side; the adapter registry auto-picks the one matching the runtime's Microsoft.OpenApi major. Resolves the OpenAPI-DLL-version conflict reported on .NET 10 hosts running side-by-side with ASP.NET's bundled discovery.

Across-the-pane omnibox (#​124 / #​162)

Cmd/Ctrl+K opens a single search line that ranks methods, recordings, collections, settings, and ?-prefixed AI prompts uniformly. Replaces the per-surface searches that used to live in the sidebar, drawer, and method picker.

Action log + Ctrl+Z (#​168) and hint dismiss (#​169)

Every destructive action (delete recording, delete collection, delete workspace, swap environment scope) is reversible from the Activity drawer or via Ctrl+Z. Hints carry a permanent dismiss key that lands them in Settings → Hints and warnings so the user can restore one without restarting.

Workspaces tree + per-plugin DisplayName (#​192 / #​167)

Sources, collections, recordings, and environments all live as nodes under the Workspaces tree on the left rail. Plugin Settings reads each plugin's DisplayName from its registration so the row labels match what the plugin author calls itself (no more raw assembly-name fallback).

Recordings as portable artefacts — .bwr format + bowire mock <recording.bwr> (#​210 / #​211)

Recordings get a standalone, self-contained file format. A .bwr is a single JSON archive that carries every step of a captured session — protocol metadata, request/response pairs, content-addressed bodies, timing — without depending on a workspace it was authored in. Drop one on a colleague's machine and it loads cleanly even when their workspace pins a different plugin set.
... (truncated)

1.9.0

Highlights — Tier 4 of the security roadmap lands

Bowire's product positioning has been "Burp Suite for the non-HTTP protocols, with schema-awareness, self-hosted, with AI-assisted threat modeling via MCP." v1.9 closes the AI-assisted half of that promise — every discovered API surface in the workbench can now be analyzed by an LLM that grounds itself in the actual schema + traffic, not generic web knowledge.

  • AI threat-model (#​59) — rank every discovered endpoint by attack-surface risk. The model reads the API's input/output shapes, auth posture, and recent traffic, and returns a sorted list with reasoning per endpoint. Sets the scan order for everything that follows.
  • AI Nuclei-template suggestion (#​60) — per endpoint, generate Nuclei templates targeting the identified risks. Bowire feeds the model the OpenAPI / proto / GraphQL schema; the model returns YAML that drops straight into the Nuclei runner.
  • AI findings triage (#​61) — every Nuclei hit gets a real-vs-false-positive verdict + a concrete fix suggestion. Cuts triage time per finding by an order of magnitude on a noisy scan.
  • AI schema-aware fuzz values (#​62) — boundary inputs per field, derived from the schema's types + constraints. Composes with the existing fuzz harness.
  • AI Settings UI (#​63) — pick the provider (Ollama, LM Studio, BYOK cloud) + endpoint + model directly from the workbench's Settings dialog. No appsettings.json edits, no restart.

The roadmap calls this Tier 4. Tiers 1–3 (record-as-attack, fuzz UI, MITM proxy) shipped through v1.4.x; Tier 5 (auto-exploit / proof-of-vulnerability) is its own framing and a different risk posture, deliberately out of scope here.

Also in this release

The 94 commits since v1.8.0 carry a lot more than the marquee. Highlights of the supporting work:

Security as a first-class drawer, with a tier that doesn't need AI (#​111 + #​112)

  • Separate Security drawer. Threat-Model + Nuclei template suggestion left the AI drawer for their own surface (shield icon in the topbar, Ctrl/Cmd+Shift+S). The AI drawer stays focused on conversational assistance (hints + chat). Mental model: AI = assistant, Security = scanner / analysis.
  • Heuristic ranking tier — no AI required. Default ranking is now a deterministic rule engine (ThreatHeuristic in core): verb-based mutation scoring, BOLA-pattern detection on path params, admin / auth / PII path matching, anonymous-auth bumps, sensitive-field-name detection in the input shape. Sub-millisecond per endpoint. Each ranked row carries a ruleTrace so users can audit which rules fired against which endpoint.
  • AI tier becomes opt-in. A tier toggle in the drawer lets the operator switch to AI-assisted ranking when they want semantic adjustments on top of the heuristic. Default heuristic → security tooling works on installs that don't have or don't want AI.

AI assistant — full MCP-style tool calling (#​89, #​108, #​109)

  • Phase 1: chat grounding. Every chat send prepends a workbench-state snapshot (loaded URLs + service names + selected method's full schema + recent calls) as a system prompt. The model answers from real data instead of generic web knowledge.
  • Phase 2: read-only tools (#​108). Three Microsoft.Extensions.AI AIFunctions available on every chat request: bowire_list_services, bowire_describe_method, bowire_recent_history. The model calls them mid-conversation to drill in. The Ollama path is wrapped in FunctionInvokingChatClient so the tool-call loop actually round-trips. Tool calls render as visible "Consulted X" steps in the chat transcript with collapsible args.
  • Phase 3: invoke tool (#​109). Opt-in via the "Allow AI to invoke methods" toggle in the drawer header. When OFF (default), bowire_invoke isn't even registered — the model literally cannot try. When ON, the AI dispatches through protocol.InvokeAsync (same path /api/invoke uses) and every call writes a JSONL row to ~/.bowire/.ai-actions.jsonl for audit. Toggle is session-only — never persisted to localStorage.
  • Phase 4: UI navigation (#​109). bowire_open_method tool lets the AI navigate the workbench to the right method ("Show me pet.findPetsByStatus" → workbench opens the request pane on it). Always available, no side effects beyond UI state.
  • "Thinking…" feedback in the drawer. Local models with tool calling take 15-45 s per turn. The chat now shows a live (N s) counter with a pulsing accent dot + a Cancel button that aborts the fetch — no more wondering whether the request hung.

Workbench UX

  • AI side panel moves into a right-side drawer (#​90) with a topbar toggle + Ctrl/Cmd+Shift+A shortcut. Persists across method/service switches. Was a peer of Response/Logs/Code in the response-pane tab strip, which forced you to choose between seeing the AI and seeing the response.
  • Connection-state pill in the topbar (#​93). Aggregate state for every configured discovery URL — green when all connected, amber when partial / connecting, red when any failed. Hover for a per-URL breakdown with service counts + the failure message.
  • Body sub-tabs (#​85). GraphQL Body now splits Query / Variables / Selection-set into a sub-tab strip; REST / gRPC / JSON-RPC get protocol-aware Form / JSON pair labels (gRPC: Message / JSON; JSON-RPC: Params / JSON; REST: Form / Body). Was a vertical stack of three surfaces; now one surface at a time.
  • Filter services by discovery URL in the sidebar's filter popup. Multi-URL setups can narrow to one origin.
  • Theme toggle dropped its visible label — tooltip still carries the state + next action; the topbar right cluster reads cleaner.

API conventions

  • RFC 7807 ProblemDetails (#​88) is the new shape for every API error response. application/problem+json with stable type URNs (urn:bowire:ai:model-not-found, urn:bowire:discovery:no-match, …), structured detail, and typed extensions per error class. Backward-compatible: every body still carries an error field set to the title so legacy readers degrade gracefully.
  • AI 404 errors now actionable (#​87). Missing model surfaces as "Model 'X' isn't available — pull it with ollama pull X or pick a different model in Settings → AI", with a links: [{rel: configure}] extension pointing back at the settings page.

Bug fixes

  • #​65 — URL input in the sidebar was read-only despite lockServerUrl=false. el() helper coerced undefined attribute values to the literal string "undefined", which the browser treats as truthy.
  • #​66 — Settings → Plugins tab was in a fetch/render infinite loop; the plugins-tab fetches now fire once per tab-open instead of once per render.
  • #​81 — Standalone CLI without --url was falling back to embedded UI mode because the heuristic checked serverUrls.length instead of trusting config.embeddedMode.
  • #​82 — Standalone CLI's discovery endpoint short-circuited to [] even when a runtime URL was passed via the sidebar.
  • #​83 — Plugin discovery probes ran sequentially (12 plugins × ~2-3 s ≈ 30 s) and the frontend timed out at 12 s. Now parallel with Task.WhenAll + a 8 s per-probe ceiling.
  • #​84 — Standalone discovery without a URL fell back to the workbench's own URL, which the JSON-RPC plugin matched with a phantom "Methods" stub.
  • #​86 — gRPC/HTTP transcoding toggle rendered on every REST method because the predicate didn't check method.source === 'grpc'.

Docs

  • New Topbar UI Guide page documenting the brand + command palette + connection pill + env selector + AI drawer.
    ... (truncated)

1.8.0

Highlights

AI side-panel (#​25 — Phase 1 + Phase 2)
The workbench learned to think. Phase 1 ships a deterministic hint engine that runs entirely without an LLM — fifteen rules that read live workbench state (selected method, last response, recordings, protocol, mock count) and surface contextual hints in a new side-panel slot. Phase 2 ships the optional Kuestenlogik.Bowire.Ai NuGet: a Microsoft.Extensions.AI IChatClient seam backed by OllamaSharp, auto-detect for Ollama on 127.0.0.1:11434 + LM Studio on :1234, three endpoints (GET /api/ai/probe-local, GET /api/ai/status, POST /api/ai/chat), and CLI flags --ai-provider / --ai-endpoint / --ai-model. The standalone bowire CLI bundles the package; embedded hosts opt in by adding it. AI Settings UI (#​63) lands the in-workbench picker for provider / endpoint / model — switching providers no longer needs a restart, persistence rides on IBowireUserStore, and embedded hosts that supply their own IChatClient win cleanly with a "host-managed" status badge. Findings triage (#​61) adds a ? button next to every Vulnerable row in the fuzz panel that asks the model "is this real, and how do I fix it?" — colour-coded confidence score, suggested fix, in-memory cache. Outbound calls stay opt-in (probe only touches loopback, chat only goes where you point it).

Workbench mocks (#​56 + #​57)
Mocks finally have a UI. The new MockRegistry + /api/mocks surface lets the workbench start mocks from any recording with one click, list them in the sidebar, and stop them without dropping to a terminal. #​57 adds a per-mock request log: every inbound call lands in a bounded ring buffer that the workbench tails live, so you can see exactly which step matched which incoming request and which ones missed. Backed by an IMockRequestObserver SPI so external observers (metrics emitters, tracers) can plug in.

Auth seam (#​28 Phase A + #​28 Phase B + #​31 + #​32)
The first real multi-user foundation. #​31 adds the IBowireAuthProvider SPI so plugins can wire authentication schemes + a default authorization policy, and adds a Configure(IApplicationBuilder) hook + the UseBowireAuth() middleware so providers can mount callback paths / claims-transformation. #​32 ships the OIDC plugin's required-claim filter and session-token forwarding for downstream service calls. #​28 Phase A + B introduce the IBowireUserStore seam and migrate every per-user store onto it (EnvironmentStore, RecordingStore, CollectionStore, FlowStore, PluginManager, PluginUpdateCheckService, schema-hints, the new AI config file) — single-user installs keep the legacy flat ~/.bowire/ layout, multi-tenant deployments swap in a per-identity resolver once SCIM lands.

Self-telemetry (#​29 — Phase 1 + Phase 2)
Bowire can now observe itself. Phase 1 ships the BowireTelemetry seam — a canonical ActivitySource + Meter on Kuestenlogik.Bowire with pre-declared instruments (bowire.invoke.count, bowire.invoke.duration, bowire.discover.count, bowire.plugin.load, bowire.mock.requests) — plus an opt-in AddBowireTelemetry() that wires OpenTelemetry against them. Phase 2 plumbs the instruments through the discovery loop (per-protocol probe counts + outcomes), the plugin scan (loaded vs disabled), and the mock pipeline (per-request counter with method / outcome / status tags). Operators opt in via --telemetry / Bowire:Telemetry:Enabled=true; OTLP endpoint / headers come from standard OTEL_EXPORTER_OTLP_* env vars. Bowire.Samples ships a Grafana 11 dashboard (Bowire.Samples/dashboards/bowire-overview.json) that reads non-zero panels from day one.

Collections (#​30)
Postman-style named groups of saved requests, sequenced against the active environment. Backend persistence routes through the new CollectionStore (single-user installs land at ~/.bowire/collections.json, multi-tenant routes per identity via IBowireUserStore), and the new flow-to-collection export turns any saved flow into a runnable test suite.

Plugin lifecycle in the workbench (#​27)
The plugins panel got an Inspect button + modal so you can see version, metadata, and recent activity for any installed plugin from the workbench instead of running bowire plugin list in a terminal. Pre-release support flows through the daily update check + the install path.

Multi-repo release cascade
The release pipeline now discovers sibling repos dynamically by querying the Kuestenlogik org for repos carrying the bowire-cascade GitHub topic — adding a new sibling to the cascade is now opt-in via that repo's own Settings → Topics, no PR against the main release workflow required. Cascade templates live in .github/sibling-templates/. Auto-PR + auto-merge use the org's rebase-only convention.


Maintenance

  • New post-release-floor-bump.yml workflow auto-bumps Directory.Build.props to <just-released>-dev after every successful release, opens a PR, no hand edit required.
  • Coverlet runsettings extended with GeneratedRegex on ExcludeByAttribute so the source-generator-emitted Regex partials no longer drag the line-coverage denominator.
  • 1209 new unit + integration tests added across the v1.8 cycle: solution-wide line coverage at 92.7 %, branch 79.2 %, method 95.4 % (up from 90.9 / 78.1 / 93.2 at v1.7.0). Notable jumps: CollectionStore, MockRequestLog, MockRegistry, EnvironmentStore, AsyncApi binding resolvers, BowireAiRuntime — all now ≥ 95 % line.
  • CodeQL cs/log-forging alert closed (#​40) — defensive CR/LF scrub before logging mock IDs / recording display names.
  • Marketing site (bowire.io): sharper headings across 5 solution pages, fixed an invisible <code> in the dev-loop-debugging hero, fixed the protocol-search input stacking the tag prefix, refreshed stale "planned" marks on the MCP comparison.
  • Roadmap-sync workflow consolidated onto BOWIRE_DISPATCH_TOKEN.

Full Changelog: Kuestenlogik/Bowire@v1.7.0...v1.8.0

1.7.0

Highlights

Four new protocol plugins

gRPC: Connect Phase 2
Server-streaming over application/connect+proto is in. Connect-Web clients now talk to a Connect-mode Bowire workbench for streaming methods, not just unary.

Mock-as-stand-in
Recordings now carry the source schema verbatim. bowire mock --recording <file> re-emits /openapi.json (REST) and /asyncapi.yaml (messaging) so peer Bowires pointed at the mock discover the full original contract, not just the replayed slice. bowire export ... --recording <file> annotates each operation with x-bowire-coverage: { recorded, stepCount } so consumers see the replay gap explicitly.

bowire export CLI
New openapi / asyncapi subcommands that materialise the discovered contract as a YAML / JSON file on disk — useful for diff-against-prod and contract-test pipelines, especially for messaging protocols where hosts don't render an /asyncapi.yaml themselves.

AsyncAPI
AsyncApiDocumentBuilder emits AsyncAPI 3.0 from any discovery result. NatsBindingResolver dispatches bindings.nats operations to the NATS wire plugin.

Tool I/O refactor (Phases 1-3 complete)
Every CLI command path now flows through the BowireCliIo type instead of direct Console.Out writes. Output is structured, testable, and pipe-friendly — bowire scan --json | jq works the way you'd expect on every subcommand.

Bootcamp launched on bowire.io
The Bowire Bootcamp — six units plus a capstone — is wired into bowire.io. Two parallel setup tracks (CLI / Embedded), then shared lessons on recording / mocking / MCP / plugin authoring / CI. The capstone weaves the lot into a single end-to-end Harbor-Tour scenario.


Maintenance

What's Changed

Full Changelog: Kuestenlogik/Bowire@v1.6.1...v1.7.0

1.6.1

Highlights

  • OIDC auth plugin. New IBowireAuthProvider SPI plus an OIDC provider implementation (roadmap "Up next #​1").
  • MCP resources + prompts. Both halves of the MCP adapter now expose resources and prompts, with BowireMcpResources and BowireMcpPrompts implementations and matching coverage.
  • Opt-in update check. Background plugin-update check with a sidebar badge — disabled by default, opt-in only.
  • Docs refresh. New "Updating Bowire and its plugins" setup page; docs aligned with the v1.5/1.6 CLI split, mock-emit, and lifecycle UI; PDF cover-page polish.

Notes

The plugin-update check is opt-in: outbound network calls remain off until you flip the setting on. Auth-provider plugins implement the new IBowireAuthProvider SPI; the bundled OIDC provider is the reference implementation.

Full Changelog: Kuestenlogik/Bowire@v1.6.0...v1.6.1

Commits viewable in compare view.

Updated Kuestenlogik.Bowire.Protocol.Rest from 1.6.0 to 2.1.1.

Release notes

Sourced from Kuestenlogik.Bowire.Protocol.Rest's releases.

2.1.1

<One-sentence frame for what 2.1 is about. Replaces this placeholder
the moment the first 2.1 work lands.>

Highlights

Bowire as a transparent in-process interceptor — app.UseBowireInterceptor() (#​153)

The new interceptor middleware extends Bowire from "the operator drove a call" to "every request flowing through the host." app.UseBowireInterceptor() registers a pass-through middleware that records method / path / headers / request body / response status / response headers / response body / latency for every request the host receives — from any client, with zero client-side setup, no cert trust, no separate process. Captured flows land in the workbench's new Intercepted rail (sister to the standalone Proxy rail) live over SSE. When the operator starts a recording in the workbench, intercepted flows auto-append as recording steps — point any client at the host, click stop, replay. Standalone reverse-proxy mode (Phase C) and mock injection (Phase D) ship in later releases.

MCP-over-MCP forwarder — bowire mcp serve --attach (#​286)

A thin Bowire process can now relay every incoming MCP tool call to a heavier Bowire running on the operator's workstation. bowire mcp serve --attach localhost:5198 --port 5199 boots a forwarder that surfaces no local tools — tools/list, tools/call, prompts, resources, and resource templates are all marshalled to the parent and the parent's response is relayed verbatim. Useful when an LLM agent on a CI runner / container should drive the workstation Bowire without sharing the parent's MCP socket directly. The parent gains a matching --token <secret> bearer-auth gate (--bind http only); the child passes the secret with --attach-token <secret>.

Workspace-delete Undo decoupled from Trash (W2a)

The action-log entry for workspace-delete is now self-contained: it carries the full snapshot (workspace, data, originalIdx) inline so Undo reads from the entry itself instead of looking the entry up in workspacesTrash at undo-time. This gives the two surfaces independent retention models:

  • Trash drawer — operator-curated retention via bowire_trash_retention_days (W2).
  • Action log — sliding window of the last 200 entries.

Hard-delete (W2 mode) now writes ONLY the action-log snapshot — there's no trash entry to consult. Soft-delete writes both. Entries persisted BEFORE this change still resolve via the legacy Trash-lookup path (a one-shot console.info flags the fallback so the migration window is visible).

The other entity-delete resolvers (recording-delete, flow-delete, env-delete) were audited and already carry their entity payload inline — only workspace-delete had the Trash coupling.

Settings tree organized by scope; Configure + Plugins merged (#​325)

The Settings dialog now exposes scope through the parent-node names: This machine (localStorage / install-scoped) and Workspace… (.bww-scoped, travels with the workspace file). The per-page disclaimer that used to repeat the scope copy on every sub-page ("These settings stay on this machine — they don't travel with the workspace file (.bww).") is gone — the tree's grouping carries that information unambiguously. The standalone Plugins lifecycle leaf is gone; it has merged with Configure into a single Plugins node whose six sub-pages (Protocols / UI Widgets / Modules / Formats / Tools / Discovery providers) now render the inline per-plugin settings AND the lifecycle button cluster (Restart / Unload / Reset storage, wired to the existing POST /api/plugins/{id}/lifecycle/{action} 501-stub) per row, plus Install + Check-for-updates at the top of the Protocols sub-page. A new empty-state Workspace… → Per-Workspace overrides page surfaces every machine-scoped setting that the active workspace has overridden (today: the AI provider config, when the workspace has its own ai-config.<workspaceId>.json); saved deep-links from v2.1 (configure-protocols, plugin-<id>, extension-<id>) keep working unchanged, and any saved value pointing at the dropped plugins lifecycle id migrates to configure-protocols.

Breaking changes

Mocks + Traffic rails merged into a single Intercept rail

The Mocks rail and the Traffic rail (which itself unified the earlier Proxy + Intercepted rails) have collapsed into one Intercept rail with four sub-tabs in a locked order:

  • Captured — passive observation of flows captured by UseBowireInterceptor() (was Traffic → "Flows").
  • Live overrides — selective response substitution inside the interceptor pipeline (was Traffic → "Mock Rules").
  • Mock servers — standalone mock-server-from-recording hosts (was the entire Mocks rail).
  • Settings — interceptor / proxy config (was Traffic → "Settings"); adapts to Standalone vs Embedded deployment.

The merge eliminates the previous Phase-3 rail bloat where Mocks + Traffic + the already-hidden Intercepted + Proxy descriptors competed for the same conceptual surface ("what do I do with live traffic"). It also disambiguates "Flows" — the orchestration rail keeps the name; what Traffic used to call "Flows" is now "Captured".

Migration is automatic at first paint (idempotent). On boot, prologue.js:
... (truncated)

2.1.0

v2.1 turns Bowire from a discovery + invoke workbench into a real composition surface. The new Compose rail carries a Hoppscotch-style request builder with a protocol picker, per-protocol layouts, history persistence, binary uploads, and full Collections + Presets integration. Underneath, the workbench is now pluggable: rails and modules ship as package contributions, so the standalone Tool, embedded MapBowire(), and operator-built distributions can pick exactly the surface they want. The new interceptor middleware lets a host hand Bowire every inbound request without client setup. A MapLibre extension + a stand-alone TacticalApi sample demo coordinate-bearing payloads on a live map with bi-directional JSON↔map sync. Streaming subscriptions are now legible, the JSON viewer reaches Hoppscotch parity, and the guided tour walks first-time operators through every rail.

300+ commits since v2.0.1. Three packaging breaking changes for embedded hosts: the standalone Kuestenlogik.Bowire.Rail.Collections package is retired, the whole Rail. package prefix dropped (e.g. Rail.Compose → Compose, Rail.Benchmarks → Benchmarking), and the interceptor surface (Proxy + Intercepted + Traffic rails + the middleware that lived in Core) consolidated into a single Kuestenlogik.Bowire.Interceptor package. See Breaking changes below for the one-to-one mapping table. Existing workspaces, collections, recordings, benchmarks load identically; operator-saved railMode / enabled-rails state migrates on first boot.

Highlights

Compose rail (#​293, #​289, #​290, #​291, #​295)

The old Design rail is rebranded and rebuilt as Compose — a single-line Hoppscotch-style request bar at the top, per-protocol layout below, history + collections + presets on the side. The protocol picker switches the layout in place: REST gets a URL + KV-table chrome, gRPC gets service / method / JSON body, MCP gets tool / arguments, MQTT gets topic / QoS, WebSocket / SSE get connect / subscribe shells. History persists across reloads, binary uploads ride a base64 side-channel through the wire, and benchmarks can re-run any historical request directly. A Compose tab supports right-click → Duplicate tab so you can fan out a request without losing the original. The toolbar lives where you'd expect (no toolbar in Raw mode, of course).

Pluggable workbench — rails + modules as package contributions (#​294)

Bundle.Workbench is now a meta-package: every rail, every module, every extension is a separate project that registers itself via [BowirePlugin] / [BowireExtension] attributes. The standalone Tool depends on Bundle.Workbench; embedded hosts can drop the bundle and pick per-package references for a smaller surface (e.g. just REST + Compose without the AI module). Bundle.Minimal carries the Core + Home + Discover only — useful for "tiny embedded probe" deployments. Settings → Plugins now lists every loaded protocol AND every UI extension with kind / capability chips so the operator can see what's installed at a glance.

Transparent in-process interceptor (#​153)

app.UseBowireInterceptor() registers a pass-through middleware that records method / path / headers / request body / response status / response headers / response body / latency for every request the host receives — from any client, with zero client-side setup, no cert trust, no separate process. Captured flows land in the workbench's new Intercepted rail live over SSE. When the operator starts a recording, intercepted flows auto-append as recording steps — point any client at the host, click stop, replay.

MapLibre extension + TacticalApi integration (#new)

A new Kuestenlogik.Bowire.Map extension auto-mounts a MapLibre GL JS viewer whenever a response carries the coordinate.wgs84 semantic kind. The Wgs84CoordinateDetector picks up {lat, lon}, {latitude, longitude}, AND {latitudeCoordinate, longitudeCoordinate} shapes (TacticalAPI naming) anchored by anchored case-insensitive regex. Bidirectional sync: hover on a JSON {lat,lon} block highlights the matching map pin; hover on a pin highlights the JSON. Click on a pin scrolls the JSON to the line and auto-expands collapsed ancestors. Right-click on a coordinate offers Center on map; double-click on either side copies the path to clipboard. A right-side gutter hint surfaces the semantic kind on hover (wgs84 coordinate).

The new Sample.TacticalApi server (separate samples/ project) hosts Rheinmetall's Situation gRPC service with eight NATO-phonetic-callsign tactical entities (Alpha-1 Recon UAV, Bravo-2 Air Defence Btry, …) drifting on a per-object sine-wave so subscriptions feel live. Bundle.Workbench ships the Kuestenlogik.Bowire.Protocol.TacticalApi plugin out of the box.

Streaming subscriptions, finally legible (#new)

The action button adapts to the active method type: Execute for unary, Subscribe for server-streaming (changes to Stop while a stream is live), Connect / Disconnect for bidirectional and client-streaming. A live state badge in the response pane shows ● Subscribed — 0 msgs → ● Receiving — 42 msgs → ○ Idle — 42 msgs after 5 s without a frame → ○ Closed on stop → × Error on stream failure. A statusbar pill lists every active subscription across methods; click → dropdown with switch / stop / copy-path / "stop all". The action button keeps a stable footprint so layout doesn't jitter when methods change.

Hoppscotch-parity JSON response viewer + toolbar (#​302, #new)

The response viewer renders one JSON line per row with a sticky left gutter carrying line numbers AND the collapse chevron — chevrons line up on the same vertical column regardless of indent depth. Click anywhere on an opener line OR the gutter chevron to toggle. Click = toggle, double-click = Copy path, right-click = unified menu with Copy ${response.X}, Copy path, plus extension-contributed items (Center on map when the map plugin resolves the target). A dedicated JSON toolbar — Expand all, Collapse all, Wrap long lines, Search (Ctrl/Cmd+F), Copy response, Download — sits above the viewer and only renders when the JSON tab is active in tab mode (so the map widget gets its own toolbar real estate). Expand / Collapse rebuild the viewer in place — no full render, so the map's WebGL canvas survives.

Tab ↔ Split layout for response viewers (#new)

Server-streaming and unary response panes get a tab-strip with JSON + per-extension widget tab + a layout toggle. Click the toggle → split-pane with JSON on one side, widget on the other; click again → tabs. Per-method layout persists in localStorage so the operator's preference for each method is remembered. The split-layout decision is extension-driven — Core asks the framework preferredSplitExtensionForMethod(svc, method) rather than hard-coding the coordinate.wgs84 kind. Layering stays clean: Map-specific code in Kuestenlogik.Bowire.Map, Core stays generic.

Guided tour — page-navigation, alternative paths, per-rail empties (#​281, #​303)

A spotlight-overlay tour engine walks first-time operators through every rail: workspace creation, source-URL add, method invoke, recording, collection composition, flow building, traffic capture, security scan. Each rail's empty state surfaces its own secondary tour. The tour engine handles dialog-modal yields, alternative paths (e.g. operator already has a workspace), advance modes (on-cta / on-event / next-button), ...

Description has been truncated

Bumps Kuestenlogik.Bowire.Protocol.Amqp from 0.2.1 to 1.0.1
Bumps Kuestenlogik.Bowire.Protocol.Grpc from 1.6.0 to 2.1.1
Bumps Kuestenlogik.Bowire.Protocol.Rest from 1.6.0 to 2.1.1
Bumps Kuestenlogik.Bowire.Protocol.SignalR from 1.6.0 to 2.1.1
Bumps Kuestenlogik.Bowire.Protocol.Sse from 1.6.0 to 2.1.1
Bumps Kuestenlogik.Bowire.Protocol.WebSocket from 1.6.0 to 2.1.1

---
updated-dependencies:
- dependency-name: Kuestenlogik.Bowire.Protocol.Amqp
  dependency-version: 1.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: bowire
- dependency-name: Kuestenlogik.Bowire.Protocol.Grpc
  dependency-version: 2.1.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: bowire
- dependency-name: Kuestenlogik.Bowire.Protocol.Grpc
  dependency-version: 2.1.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: bowire
- dependency-name: Kuestenlogik.Bowire.Protocol.Rest
  dependency-version: 2.1.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: bowire
- dependency-name: Kuestenlogik.Bowire.Protocol.Rest
  dependency-version: 2.1.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: bowire
- dependency-name: Kuestenlogik.Bowire.Protocol.SignalR
  dependency-version: 2.1.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: bowire
- dependency-name: Kuestenlogik.Bowire.Protocol.SignalR
  dependency-version: 2.1.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: bowire
- dependency-name: Kuestenlogik.Bowire.Protocol.Sse
  dependency-version: 2.1.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: bowire
- dependency-name: Kuestenlogik.Bowire.Protocol.Sse
  dependency-version: 2.1.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: bowire
- dependency-name: Kuestenlogik.Bowire.Protocol.WebSocket
  dependency-version: 2.1.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: bowire
- dependency-name: Kuestenlogik.Bowire.Protocol.WebSocket
  dependency-version: 2.1.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: bowire
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added the dependencies Pull requests that update a dependency file label Jul 5, 2026
@dependabot @github

dependabot Bot commented on behalf of github Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

Labels

The following labels could not be found: nuget. Please create it before Dependabot can add it to a pull request.

Please fix the above issues or remove invalid values from dependabot.yml.

@dependabot @github

dependabot Bot commented on behalf of github Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

Dependabot could not find a dependency.. Because of this, Dependabot cannot update this pull request.

1 similar comment
@dependabot @github

dependabot Bot commented on behalf of github Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

Dependabot could not find a dependency.. Because of this, Dependabot cannot update this pull request.

@dependabot @github

dependabot Bot commented on behalf of github Jul 12, 2026

Copy link
Copy Markdown
Contributor Author

Looks like these dependencies are updatable in another way, so this is no longer needed.

@dependabot dependabot Bot closed this Jul 12, 2026
@dependabot
dependabot Bot deleted the dependabot/nuget/harbor-demo/src/Kuestenlogik.Bowire.Samples.Amqp/bowire-b316666265 branch July 12, 2026 12:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants