Namespace Kuestenlogik.Bowire.Workspace.Git
Classes
- BowireGitWorkspaceEndpoints
Endpoint surface for the git-backed workspace runtime — currently just the FS-watch SSE stream (#150). Hosts that called AddBowireGitWorkspace(IServiceCollection) at DI build call MapBowireGitWorkspaceEvents(IEndpointRouteBuilder, string) at endpoint-routing setup to mount the route.
- BowireGitWorkspaceExtension
Marker + activation type for the git-backed workspace runtime. The workbench checks for an BowireGitWorkspaceExtension resolved from DI; presence means "the operator wired the runtime, route per-workspace reads/writes through the per-entity layout when
workspace.storageRootis set". Absence keeps GetWorkspacePath(string, string?, string) on the legacy per-user fallback.
- BowireGitWorkspaceMigrationReport
Aggregate result of a single workspace migration. Carries the per-kind counts so callers can render a summary, plus a flag indicating whether any kind moved data on this run (useful for the CLI's idempotent "nothing to do" diagnostic).
- BowireGitWorkspaceMigrator
One-shot migration from the legacy per-user bundle layout — one
<entityKind>.jsonfile per kind, each carrying an array of entities — to the per-entity file layout the git-backed runtime reads through (#196 Phase 2.2).Used by the
bowire workspace migrate-formatCLI subcommand and exposed publicly so embedded hosts can run the migration from their own admin tooling. The migrator never deletes the legacy bundle outright — it renames each migrated file to<entityKind>.json.legacyso an operator can verify the per-entity files look right before binning the original.
- BowireGitWorkspaceServiceCollectionExtensions
DI entry-point for the git-backed workspace runtime. Embedded hosts that want the surface call
AddBowireGitWorkspace()afterAddBowire(); standaloneKuestenlogik.Bowire.Toolreferences the package and wires it fromBowireCli's host build so the CLI ships the runtime bundled.
- FileEntityStore
File-backed IBowireEntityStore implementation — one
.jsonper entity under<storageRoot>/<entityKind>/.Collections get an additional per-request layout: each entry that looks like an HTTP request (heuristic:
requestsarray on the document) writes a separate<request-id>.req.jsonsibling undercollections/<collection-id>/so OpenAPI-shaped collection diffs show one request per file in PR review — instead of the whole collection's request array exploding on every edit.JSON serialisation matches the workbench's bundle store: WriteIndented on, camelCase preserved (we don't reshape the document — we trust the caller's shape — but the pretty-print pass keeps diffs reviewable).
The store is robust against missing directories: every write creates the per-kind directory on demand, every read against a missing file returns
null, every delete against a missing target is a no-op. That lets the workbench's "save environment" path land without a separate "create the folder skeleton first" round-trip.
- LockHeldException
Thrown by AcquireAsync(string, string, CancellationToken) when another live writer holds the workspace lock. Carries the holder's metadata so the caller can surface a friendly "process <pid> on <host> started at <timestamp>" diagnostic without re-reading the file.
- SecretOverlayMerger
Merges
<env>.secrets.jsonoverlays on top of the committed<env>.jsonat load time. Implements the secret-separation convention shipped in Phase 1: the non-secret half is the reviewable, git-tracked half;.secrets.jsonsiblings carry tokens and are.gitignore'd at workspace init.
- WorkspaceLock
Cross-process workspace lockfile — guards concurrent writers against corrupting the per-entity layout. One holder per
storageRoot; second writer hitting an active lock surfaces the friendly "another process is editing this workspace" hint instead of overwriting state.
- WorkspaceWatcher
Singleton watcher fleet — keeps one FileSystemWatcher per watched
storageRootand fans events out to every subscriber listening on that root. The SSE endpoint (#150) gets a ChannelReader<T> per subscription so each connected browser tab consumes its own queue.
Structs
- BowireGitWorkspaceMigrationKindReport
Per-entity-kind migration outcome. Counts the entities written to the per-entity layout, plus a flag indicating whether the migration actually fired (false = nothing-to-do, kind absent on disk or already migrated).
- WorkspaceFileEvent
One file-system event surfaced by the workspace watcher. Emitted on the SSE stream the workbench subscribes to so it can react to external edits (a teammate's
git pull, an editor saving an environment file, etc.) without hammering the disk on a poll.
- WorkspaceLockInfo
Snapshot of a workspace lock holder's metadata — populated when AcquireAsync(string, string, CancellationToken) hits an active lock and surfaced on Holder, plus returned from Inspect(string) for diagnostic CLIs.
Interfaces
- IBowireEntityStore
Per-entity reader/writer the workbench routes through when a workspace's
storageRootis set (#196 Phase 2.2). Replaces the legacy single-bundle layout — environments, collections, recordings, scripts and flows each live in their own subdirectory under the checked-out workspace folder so PR diffs show one JSON document per edited entity rather than the entire bundle on every keystroke.