Skip to content

v2.0.1 — Re-architected workbench shell + workspace = project folder

Latest

Choose a tag to compare

@thomas-stegemann thomas-stegemann released this 23 Jun 22:03
· 100 commits to main since this release

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

  • BowireMcpChatClient 81% → 93% line / 93% branch (6e8da96)
  • SidecarPluginManifest 79% → 100% line (647c8ad)

Acknowledgements

Operator feedback during real-workbench iteration drove the freeform builder layout work end-to-end. The clone-then-edit clarification ("as new request" should be an editable form, not an auto-save), the URL ownership semantics (inline vs source), and the tab-persistence requirement ("the clone has to survive a tab detour") all came from in-session use against the petstore + grpcb.in samples.


The full commit list, contributors, and compare-URL diff are auto-generated below.

What's Changed

Full Changelog: v2.0.0...v2.0.1