feat(style): a project's look comes from artists, an image, or nothing #213

Merged
bjoern merged 4 commits from feat/project-style-source into main 2026-08-04 18:38:17 +02:00
Member

The project style was one uploaded image (ADR 0027) or nothing at all. Artist tags — how most NovelAI prompts actually carry a look — had no home short of typing artist:x into every record's tag table by hand, where the decision is invisible, lands in the wrong place in the prompt, and drifts apart record by record.

A project now names one style source of three: no style, artists, or the reference image. Decided with the project owner: the source is project-wide (the whole project shares one look, ADR 0027's reasoning), the per-record control stays a mute, and artists reuse PromptTag exactly — −3..+3 with both polarities.

What changed

Domain / persistenceProject gains StyleSource (a stored contract enum) and StyleArtists (scalar JSON, so a save is one journaled, undoable operation). The migration puts every project that already has an uploaded image on the image source, so nothing changes for an existing project until its author chooses otherwise. Verified against a real database, not just the model.

GenerationSpriteEnrichment.ReadProjectStyleAsync returns the project's contribution as one of the two: the artists, or the image at the record's authored strength/fidelity. SpriteRequestMapper renders each artist as artist:<name> at its authored weight and puts them at the front of the general section — ahead of the framing tag (ADR 0036) and the global defaults (ADR 0028), which stay last; for a location background they lead the location's own tags. Per-character V4 groups are untouched (ADR 0011).

Two deliberate calls, both recorded in the ADR:

  • an outfit under the likeness flag still carries the artists — prompt tokens are not a director entry, so they compete with nothing, and that is the sprite that least wants to drift off the look;
  • expression infills carry them too — the one prompt that never had a style signal of its own.

UI — the General page's style card becomes a ToggleButtonGroup over the three sources, revealing only the chosen one's controls. Artists use the existing TagAuthoring surface with three new parameters (SearchCategory, SearchPlaceholder, ShowSuggestions) — no new component; the search narrows to the tag database's artist category (10,574 tags), search-only, so freeform artists stay allowed. Per record the checkbox reads "Follow the project's style" and the strength/fidelity sliders render only on the image source, since that is all they tune.

Assistantget_project_overview reports the source and the artist list; a new set_project_style tool sets them (its own tool, not a widening of the partial-edit update_project, which would reset the list on every unrelated title change).

Seed — the sample world's project is on the artist source with two real tags, one weighted, so the picker, the per-record panels and the prompt ordering all have something to show.

Docs

  • New ADR 0053 — revises ADR 0027 (its rejected alternative 2 becomes a first-class option rather than a replacement) and refines ADR 0045 (the use flag mutes whichever source; the sliders are image-only). Rejected alternatives recorded: per-record artist lists, project-default-plus-override, artists in each record's own tag table, and letting both sources apply at once.
  • The style story is rewritten as the three-source story (filename kept — four other stories link to it), with the style bullets in character-sprites, location-backgrounds, location-variants, project-workspace and REQUIREMENTS §4 updated to match.

Verification

  • All three suites green: 1593 tests, 0 failures.
  • New coverage: source/artist round-trip through real SQLite, artists leading the general positive and negative section ahead of framing and the defaults, the scene branch's order, the record mute dropping artists too, the image never read on the artist source, artists surviving the likeness flag, the artist-only search over the real SqliteTagSearch, the three-way section and its retention-on-switch in the page tests, and the seeded world's style.
  • The migration backfill was run against a real database (a project with an image → image source; one without → none; the JSON column defaults to []).
  • Not done: the Playwright click-through. The shared browser profile is held by another session's MCP server for the whole of this run, and I did not kill it. The seeded app starts clean on the branch and the page markup is covered by the bUnit tests, but nobody has yet clicked through the three sections in a real browser — worth a pass before merge.

🤖 Generated with Claude Code

The project style was one uploaded image (ADR 0027) or nothing at all. Artist tags — how most NovelAI prompts actually carry a look — had no home short of typing `artist:x` into every record's tag table by hand, where the decision is invisible, lands in the wrong place in the prompt, and drifts apart record by record. A project now names **one style source of three**: **no style**, **artists**, or the **reference image**. Decided with the project owner: the source is project-wide (the whole project shares one look, ADR 0027's reasoning), the per-record control stays a mute, and artists reuse `PromptTag` exactly — −3..+3 with both polarities. ## What changed **Domain / persistence** — `Project` gains `StyleSource` (a stored contract enum) and `StyleArtists` (scalar JSON, so a save is one journaled, undoable operation). The migration puts every project that already has an uploaded image on the image source, so nothing changes for an existing project until its author chooses otherwise. Verified against a real database, not just the model. **Generation** — `SpriteEnrichment.ReadProjectStyleAsync` returns the project's contribution as one of the two: the artists, or the image at the record's authored strength/fidelity. `SpriteRequestMapper` renders each artist as `artist:<name>` at its authored weight and puts them at the **front of the general section** — ahead of the framing tag (ADR 0036) and the global defaults (ADR 0028), which stay last; for a location background they lead the location's own tags. Per-character V4 groups are untouched (ADR 0011). Two deliberate calls, both recorded in the ADR: - an outfit under the **likeness flag** still carries the artists — prompt tokens are not a director entry, so they compete with nothing, and that is the sprite that least wants to drift off the look; - **expression infills** carry them too — the one prompt that never had a style signal of its own. **UI** — the General page's style card becomes a `ToggleButtonGroup` over the three sources, revealing only the chosen one's controls. Artists use the existing `TagAuthoring` surface with three new parameters (`SearchCategory`, `SearchPlaceholder`, `ShowSuggestions`) — no new component; the search narrows to the tag database's `artist` category (10,574 tags), search-only, so freeform artists stay allowed. Per record the checkbox reads **"Follow the project's style"** and the strength/fidelity sliders render only on the image source, since that is all they tune. **Assistant** — `get_project_overview` reports the source and the artist list; a new `set_project_style` tool sets them (its own tool, not a widening of the partial-edit `update_project`, which would reset the list on every unrelated title change). **Seed** — the sample world's project is on the artist source with two real tags, one weighted, so the picker, the per-record panels and the prompt ordering all have something to show. ## Docs - **New [ADR 0053](docs/adr/0053-project-style-source.md)** — revises ADR 0027 (its rejected alternative 2 becomes a first-class option rather than a replacement) and refines ADR 0045 (the use flag mutes whichever source; the sliders are image-only). Rejected alternatives recorded: per-record artist lists, project-default-plus-override, artists in each record's own tag table, and letting both sources apply at once. - The style story is rewritten as the three-source story (filename kept — four other stories link to it), with the style bullets in `character-sprites`, `location-backgrounds`, `location-variants`, `project-workspace` and REQUIREMENTS §4 updated to match. ## Verification - All three suites green: **1593 tests**, 0 failures. - New coverage: source/artist round-trip through real SQLite, artists leading the general positive *and* negative section ahead of framing and the defaults, the scene branch's order, the record mute dropping artists too, the image never read on the artist source, artists surviving the likeness flag, the artist-only search over the real `SqliteTagSearch`, the three-way section and its retention-on-switch in the page tests, and the seeded world's style. - The migration backfill was run against a real database (a project with an image → image source; one without → none; the JSON column defaults to `[]`). - **Not done:** the Playwright click-through. The shared browser profile is held by another session's MCP server for the whole of this run, and I did not kill it. The seeded app starts clean on the branch and the page markup is covered by the bUnit tests, but nobody has yet clicked through the three sections in a real browser — worth a pass before merge. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(style): a project's look comes from artists, an image, or nothing
All checks were successful
CI / build (pull_request) Successful in 30s
CI / test (pull_request) Successful in 1m42s
70d537dd28
The project style was one uploaded image (ADR 0027) or nothing at all.
Artist tags — how most NovelAI prompts actually carry a look — had no
home short of typing artist:x into every record's tag table by hand.

The project now names one style source of three: none, artists, or the
reference image. Artists are ordinary prompt tags (−3..+3, both
polarities, freeform allowed) searched from the tag database's artist
category, and they open every generation's prompt as artist:<name> —
ahead of the framing tag and the global default tags, and never inside a
per-character group. Per record the control stays a mute: "follow the
project's style", with the strength/fidelity sliders shown only while
the project steers from its image, since that is all they tune.

Switching sources keeps the other's state, so comparing two looks costs
nothing. Existing projects with an uploaded image migrate onto the image
source and generate exactly as before.

ADR 0053, revising ADR 0027's rejected alternative 2 and refining
ADR 0045.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Drop a redundant property on the General page's style section
All checks were successful
CI / build (pull_request) Successful in 33s
CI / test (pull_request) Successful in 1m40s
08fedda025
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Summary

Summary
Generated on: 08/04/2026 - 16:28:49
Coverage date: 08/04/2026 - 16:27:42 - 08/04/2026 - 16:28:46
Parser: MultiReport (3x Cobertura)
Assemblies: 6
Classes: 1059
Files: 574
Line coverage: 96.3% (47618 of 49405)
Covered lines: 47618
Uncovered lines: 1787
Coverable lines: 49405
Total lines: 76649
Branch coverage: 77% (4975 of 6453)
Covered branches: 4975
Total branches: 6453
Method coverage: Feature is only available for sponsors

Coverage

Kagura.BlazorAdapter - 88.2%
Name Line Branch
Kagura.BlazorAdapter 88.2% 77.4%
Kagura.BlazorAdapter.Assistant.AssistantCapabilityChecked 100%
Kagura.BlazorAdapter.Assistant.AssistantChangeMade 100%
Kagura.BlazorAdapter.Assistant.AssistantConversationHydrated 100%
Kagura.BlazorAdapter.Assistant.AssistantEffects 62.5% 100%
Kagura.BlazorAdapter.Assistant.AssistantFailed 100%
Kagura.BlazorAdapter.Assistant.AssistantNoticed 100%
Kagura.BlazorAdapter.Assistant.AssistantPanel 90.6% 85.8%
Kagura.BlazorAdapter.Assistant.AssistantReducers 100% 75%
Kagura.BlazorAdapter.Assistant.AssistantSaid 100%
Kagura.BlazorAdapter.Assistant.AssistantState 100%
Kagura.BlazorAdapter.Assistant.AssistantToolCalled 100%
Kagura.BlazorAdapter.Assistant.AssistantUserSaid 100%
Kagura.BlazorAdapter.BlazorAdapterAssembly 100%
Kagura.BlazorAdapter.CmField 100% 75%
Kagura.BlazorAdapter.Connections.AddLinkModal 88.5% 81.5%
Kagura.BlazorAdapter.Connections.ConnectionsEffects 95.4% 80%
Kagura.BlazorAdapter.Connections.ConnectionsFailed 100%
Kagura.BlazorAdapter.Connections.ConnectionsLoaded 100%
Kagura.BlazorAdapter.Connections.ConnectionsPanel 100% 95.1%
Kagura.BlazorAdapter.Connections.ConnectionsReducers 100% 75%
Kagura.BlazorAdapter.Connections.ConnectionsState 90%
Kagura.BlazorAdapter.Connections.KindIcon 100%
Kagura.BlazorAdapter.Connections.LinkRequested 100%
Kagura.BlazorAdapter.Connections.LinkTargetsFound 100%
Kagura.BlazorAdapter.Connections.LoadConnections 100%
Kagura.BlazorAdapter.Connections.NodeKindIcons 100%
Kagura.BlazorAdapter.Connections.RemoveLinkRequested 100%
Kagura.BlazorAdapter.Connections.SearchLinkTargets 100%
Kagura.BlazorAdapter.Design 0% 0%
Kagura.BlazorAdapter.Diagnostics.AppErrorBoundary 100%
Kagura.BlazorAdapter.Diagnostics.CircuitError 100%
Kagura.BlazorAdapter.Diagnostics.CircuitErrorPanel 100%
Kagura.BlazorAdapter.Diagnostics.CircuitErrorSink 100% 85.7%
Kagura.BlazorAdapter.Diagnostics.KaguraStoreInitializer 92.3% 66.6%
Kagura.BlazorAdapter.EditorComponentsDemo 0%
Kagura.BlazorAdapter.FileUploadDemo 0%
Kagura.BlazorAdapter.Generation.ActivityQueueBridge 87.5% 50%
Kagura.BlazorAdapter.Generation.CancelActivityRequested 100%
Kagura.BlazorAdapter.Generation.GenerationQueueEffects 100%
Kagura.BlazorAdapter.Generation.GenerationQueueLoaded 100%
Kagura.BlazorAdapter.Generation.GenerationQueuePage 100% 100%
Kagura.BlazorAdapter.Generation.GenerationQueueReducers 100%
Kagura.BlazorAdapter.Generation.GenerationQueueState 100%
Kagura.BlazorAdapter.Generation.GenerationStatusBar 100% 95.4%
Kagura.BlazorAdapter.Generation.RemoveActivityRequested 100%
Kagura.BlazorAdapter.History.DiffValue 100% 87.5%
Kagura.BlazorAdapter.History.DocumentHistoryEffects 90% 68.7%
Kagura.BlazorAdapter.History.DocumentHistoryFailed 100%
Kagura.BlazorAdapter.History.DocumentHistoryLoaded 100%
Kagura.BlazorAdapter.History.DocumentHistoryPanel 79.3% 75%
Kagura.BlazorAdapter.History.DocumentHistoryReducers 95% 83.3%
Kagura.BlazorAdapter.History.DocumentHistoryState 100%
Kagura.BlazorAdapter.History.LoadDocumentHistory 100%
Kagura.BlazorAdapter.History.RevertCompleted 100%
Kagura.BlazorAdapter.History.RevertRequested 100%
Kagura.BlazorAdapter.History.RevisionDiffLoaded 100%
Kagura.BlazorAdapter.History.SelectRevision 100%
Kagura.BlazorAdapter.KnowledgeBase.AdoptEmotionsRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.BaseSpriteFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.BaseSpriteGenerated 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterBaseSprite 91.3% 90%
Kagura.BlazorAdapter.KnowledgeBase.CharacterCreated 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterDeleted 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorEffects 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorNotFound 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorPage 92.9% 81.2%
Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorReducers 100% 92.8%
Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorState 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterImagesLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterOperationFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterOutfits 94.2% 83.3%
Kagura.BlazorAdapter.KnowledgeBase.CharacterPreview 88.1% 91.3%
Kagura.BlazorAdapter.KnowledgeBase.CharacterPreviewEffects 62.9% 25%
Kagura.BlazorAdapter.KnowledgeBase.CharacterPreviewFailed 0%
Kagura.BlazorAdapter.KnowledgeBase.CharacterPreviewReducers 83.3% 50%
Kagura.BlazorAdapter.KnowledgeBase.CharacterPreviewSaved 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterPreviewState 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterSaved 100%
Kagura.BlazorAdapter.KnowledgeBase.CharactersEffects 94.1% 75%
Kagura.BlazorAdapter.KnowledgeBase.CharactersLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.CharactersPage 95.8% 90.9%
Kagura.BlazorAdapter.KnowledgeBase.CharacterSpriteEffects 86.3% 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterSpriteReducers 100% 75%
Kagura.BlazorAdapter.KnowledgeBase.CharacterSpriteState 100%
Kagura.BlazorAdapter.KnowledgeBase.CharactersReducers 100% 87.5%
Kagura.BlazorAdapter.KnowledgeBase.CharactersState 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterTiers 100% 50%
Kagura.BlazorAdapter.KnowledgeBase.CharacterVoiceContextLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterVoiceEffects 77.7% 80%
Kagura.BlazorAdapter.KnowledgeBase.CharacterVoiceFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterVoicePanel 95.3% 81%
Kagura.BlazorAdapter.KnowledgeBase.CharacterVoiceReducers 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterVoicesFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterVoicesLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterVoiceState 100%
Kagura.BlazorAdapter.KnowledgeBase.CreateCharacterFailed 0%
Kagura.BlazorAdapter.KnowledgeBase.CreateCharacterRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.CreateLocationFailed 0%
Kagura.BlazorAdapter.KnowledgeBase.CreateLocationRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.CreateLocationVariantRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.CreateLoreFailed 0%
Kagura.BlazorAdapter.KnowledgeBase.CreateLoreRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.CreateOutfitRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.CreateRelationshipRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.CreateTimelineEventRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.DeleteCharacterRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.DeleteLocationRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.DeleteLocationVariantRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.DeleteLoreRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.DeleteOutfitRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.DeleteRelationshipRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.DeleteTimelineEventRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.ExpressionCapabilityChecked 100%
Kagura.BlazorAdapter.KnowledgeBase.ExpressionGenerated 100%
Kagura.BlazorAdapter.KnowledgeBase.ExpressionGenerationFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.ExpressionRemoved 100%
Kagura.BlazorAdapter.KnowledgeBase.ExpressionsEffects 87.9% 69.2%
Kagura.BlazorAdapter.KnowledgeBase.ExpressionsFailed 0%
Kagura.BlazorAdapter.KnowledgeBase.ExpressionsLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.ExpressionsReducers 85.7% 43.7%
Kagura.BlazorAdapter.KnowledgeBase.ExpressionsState 100%
Kagura.BlazorAdapter.KnowledgeBase.GenerateAllExpressions 100%
Kagura.BlazorAdapter.KnowledgeBase.GenerateBaseSprite 100%
Kagura.BlazorAdapter.KnowledgeBase.GenerateExpression 100%
Kagura.BlazorAdapter.KnowledgeBase.GenerateLocationBackground 100%
Kagura.BlazorAdapter.KnowledgeBase.GenerateLocationVariantImage 100%
Kagura.BlazorAdapter.KnowledgeBase.GenerateOutfitSprite 100%
Kagura.BlazorAdapter.KnowledgeBase.LabeledEntryMapping 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadCharacter 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadCharacterImages 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadCharacters 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadCharacterVoiceContext 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadCharacterVoices 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadExpressions 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadLocation 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadLocationHierarchy 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadLocationImages 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadLocations 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadLocationVariant 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadLocationVariants 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadLore 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadLoreEntry 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadOutfit 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadOutfits 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadRelationshipCast 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadRelationships 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadTimeline 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationBackground 91.3% 90%
Kagura.BlazorAdapter.KnowledgeBase.LocationBackgroundCapabilityChecked 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationBackgroundEffects 86.3% 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationBackgroundFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationBackgroundGenerated 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationBackgroundReducers 100% 75%
Kagura.BlazorAdapter.KnowledgeBase.LocationBackgroundState 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationCreated 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationDeleted 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationEditorEffects 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationEditorLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationEditorNotFound 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationEditorPage 88.6% 75%
Kagura.BlazorAdapter.KnowledgeBase.LocationEditorReducers 86.9% 71.4%
Kagura.BlazorAdapter.KnowledgeBase.LocationEditorState 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyEffects 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyReducers 100% 75%
Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyState 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationImagesLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationOperationFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationPreview 91% 88.6%
Kagura.BlazorAdapter.KnowledgeBase.LocationPreviewEffects 62.9% 25%
Kagura.BlazorAdapter.KnowledgeBase.LocationPreviewFailed 0%
Kagura.BlazorAdapter.KnowledgeBase.LocationPreviewReducers 83.3% 50%
Kagura.BlazorAdapter.KnowledgeBase.LocationPreviewSaved 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationPreviewState 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationSaved 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationsEffects 94.1% 75%
Kagura.BlazorAdapter.KnowledgeBase.LocationsLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationsPage 95.4% 95.4%
Kagura.BlazorAdapter.KnowledgeBase.LocationsReducers 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationsState 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantEditorEffects 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantEditorFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantEditorLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantEditorNotFound 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantEditorPage 88.8% 74%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantEditorReducers 100% 93.7%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantEditorSaved 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantEditorState 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantImage 93.1% 91.6%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantImageCapabilityChecked 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantImageEffects 86.3% 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantImageFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantImageGenerated 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantImageReducers 100% 75%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantImageState 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariants 94.2% 79.1%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantsEffects 96.4% 83.3%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantsFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantsLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantsReducers 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationVariantsState 100%
Kagura.BlazorAdapter.KnowledgeBase.LoreCategories 100% 50%
Kagura.BlazorAdapter.KnowledgeBase.LoreCreated 100%
Kagura.BlazorAdapter.KnowledgeBase.LoreDeleted 100%
Kagura.BlazorAdapter.KnowledgeBase.LoreEditorEffects 96.6% 87.5%
Kagura.BlazorAdapter.KnowledgeBase.LoreEditorLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.LoreEditorNotFound 100%
Kagura.BlazorAdapter.KnowledgeBase.LoreEditorPage 90.8% 75%
Kagura.BlazorAdapter.KnowledgeBase.LoreEditorReducers 86.9% 71.4%
Kagura.BlazorAdapter.KnowledgeBase.LoreEditorState 100%
Kagura.BlazorAdapter.KnowledgeBase.LoreEffects 94.1% 75%
Kagura.BlazorAdapter.KnowledgeBase.LoreLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.LoreOperationFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.LorePage 80% 78.5%
Kagura.BlazorAdapter.KnowledgeBase.LoreReducers 90.9% 87.5%
Kagura.BlazorAdapter.KnowledgeBase.LoreSaved 100%
Kagura.BlazorAdapter.KnowledgeBase.LoreState 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.NewTimelineEvent 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorEffects 96.4% 87.5%
Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorNotFound 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorPage 92.3% 75%
Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorReducers 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorSaved 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorState 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitExpressions 95.5% 92.8%
Kagura.BlazorAdapter.KnowledgeBase.OutfitFaceRegion 88.7% 70.2%
Kagura.BlazorAdapter.KnowledgeBase.OutfitsEffects 96.4% 83.3%
Kagura.BlazorAdapter.KnowledgeBase.OutfitsFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitsLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitSprite 92.5% 91.6%
Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteCapabilityChecked 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteEffects 86.3% 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteGenerated 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteReducers 100% 75%
Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteState 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitsReducers 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitsState 100%
Kagura.BlazorAdapter.KnowledgeBase.ParentCandidatesFound 100%
Kagura.BlazorAdapter.KnowledgeBase.ParentPickerModal 84.6% 89.2%
Kagura.BlazorAdapter.KnowledgeBase.PositioningPanel 100% 95.4%
Kagura.BlazorAdapter.KnowledgeBase.PreviewVoiceRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipCard 77.5% 63.3%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipCastLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipList 97.3% 88.4%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipModal 94.1% 94.7%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipsEffects 92.8% 77.7%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipsFailed 0%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipsLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipsPage 92.8% 87.5%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipsReducers 94.7% 75%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipsState 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.RemoveCharacterPreviewRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.RemoveExpressionRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.RemoveLocationPreviewRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.ReorderTimelineEventRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.SaveCharacterRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.SaveFaceRegionsRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.SaveLocationRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.SaveLocationVariantRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.SaveLoreRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.SaveOutfitRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.SearchParentCandidates 100%
Kagura.BlazorAdapter.KnowledgeBase.SetCharacterPreviewRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.SetCharactersFilter 100%
Kagura.BlazorAdapter.KnowledgeBase.SetCharactersTier 100%
Kagura.BlazorAdapter.KnowledgeBase.SetLocationPreviewRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.SetLocationsFilter 100%
Kagura.BlazorAdapter.KnowledgeBase.SetLoreCategory 100%
Kagura.BlazorAdapter.KnowledgeBase.SetLoreFilter 100%
Kagura.BlazorAdapter.KnowledgeBase.SetParentRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.SetRelationshipsFilter 100%
Kagura.BlazorAdapter.KnowledgeBase.SpriteCapabilityChecked 100%
Kagura.BlazorAdapter.KnowledgeBase.StyleReferenceControls 100% 78.5%
Kagura.BlazorAdapter.KnowledgeBase.TimelineEffects 93.5% 70%
Kagura.BlazorAdapter.KnowledgeBase.TimelineEventCard 92.5% 80%
Kagura.BlazorAdapter.KnowledgeBase.TimelineEventEdit 100%
Kagura.BlazorAdapter.KnowledgeBase.TimelineFailed 0%
Kagura.BlazorAdapter.KnowledgeBase.TimelineLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.TimelinePage 95.8% 90%
Kagura.BlazorAdapter.KnowledgeBase.TimelineReducers 91.6% 75%
Kagura.BlazorAdapter.KnowledgeBase.TimelineSection 96.6% 91.6%
Kagura.BlazorAdapter.KnowledgeBase.TimelineState 100%
Kagura.BlazorAdapter.KnowledgeBase.UpdateRelationshipRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.UpdateTimelineEventRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.UploadVoiceClipRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.VoiceClipSaved 100%
Kagura.BlazorAdapter.Notifications.DomainChangedBridge 88.8% 58.3%
Kagura.BlazorAdapter.Notifications.DomainChangesReceived 100% 100%
Kagura.BlazorAdapter.OverlayDemo 0% 0%
Kagura.BlazorAdapter.Projects.AssistantMemoryFailed 0%
Kagura.BlazorAdapter.Projects.AssistantMemorySaved 0%
Kagura.BlazorAdapter.Projects.ClearStyleReferenceRequested 100%
Kagura.BlazorAdapter.Projects.CreateProjectRequested 100%
Kagura.BlazorAdapter.Projects.DeleteProjectRequested 100%
Kagura.BlazorAdapter.Projects.LoadProjectAssets 100%
Kagura.BlazorAdapter.Projects.LoadWorkspace 100%
Kagura.BlazorAdapter.Projects.ProjectAssetsEffects 100%
Kagura.BlazorAdapter.Projects.ProjectAssetsFailed 100%
Kagura.BlazorAdapter.Projects.ProjectAssetsLoaded 100%
Kagura.BlazorAdapter.Projects.ProjectAssetsPage 94.2% 85.7%
Kagura.BlazorAdapter.Projects.ProjectAssetsReducers 100% 100%
Kagura.BlazorAdapter.Projects.ProjectAssetsState 100%
Kagura.BlazorAdapter.Projects.ProjectCreated 100%
Kagura.BlazorAdapter.Projects.ProjectCreateFailed 100%
Kagura.BlazorAdapter.Projects.ProjectDeleted 100%
Kagura.BlazorAdapter.Projects.ProjectSaved 100%
Kagura.BlazorAdapter.Projects.ProjectSaveFailed 100%
Kagura.BlazorAdapter.Projects.ProjectsEffects 100% 100%
Kagura.BlazorAdapter.Projects.ProjectsLoaded 100%
Kagura.BlazorAdapter.Projects.ProjectsPage 94.7% 100%
Kagura.BlazorAdapter.Projects.ProjectsReducers 100% 100%
Kagura.BlazorAdapter.Projects.ProjectsState 100% 100%
Kagura.BlazorAdapter.Projects.ProjectWorkspacePage 70.5% 63.8%
Kagura.BlazorAdapter.Projects.SaveAssistantMemoryRequested 0%
Kagura.BlazorAdapter.Projects.SaveProjectRequested 100%
Kagura.BlazorAdapter.Projects.SetProjectsFilter 100%
Kagura.BlazorAdapter.Projects.SetStageViewRequested 100%
Kagura.BlazorAdapter.Projects.SetStyleReferenceRequested 100%
Kagura.BlazorAdapter.Projects.SetStyleRequested 100%
Kagura.BlazorAdapter.Projects.StyleReferenceChanged 100%
Kagura.BlazorAdapter.Projects.StyleReferenceFailed 100%
Kagura.BlazorAdapter.Projects.WorkspaceCrumb 100%
Kagura.BlazorAdapter.Projects.WorkspaceEffects 82.3% 70.5%
Kagura.BlazorAdapter.Projects.WorkspaceLoaded 100%
Kagura.BlazorAdapter.Projects.WorkspaceReducers 80%
Kagura.BlazorAdapter.Projects.WorkspaceShell 100% 95%
Kagura.BlazorAdapter.Projects.WorkspaceState 100%
Kagura.BlazorAdapter.QuicklinkDemo 0%
Kagura.BlazorAdapter.RegionSelectorDemo 0% 0%
Kagura.BlazorAdapter.SelectDemo 0%
Kagura.BlazorAdapter.Settings.AssistantSkillsEffects 13.3% 0%
Kagura.BlazorAdapter.Settings.AssistantSkillsFailed 0%
Kagura.BlazorAdapter.Settings.AssistantSkillsLoaded 100%
Kagura.BlazorAdapter.Settings.AssistantSkillsReducers 28.5%
Kagura.BlazorAdapter.Settings.AssistantSkillsSection 32.4% 11.1%
Kagura.BlazorAdapter.Settings.AssistantSkillsState 100%
Kagura.BlazorAdapter.Settings.CheckTtsConnectionRequested 100%
Kagura.BlazorAdapter.Settings.CreateEmotionRequested 100%
Kagura.BlazorAdapter.Settings.CreateSkillRequested 0%
Kagura.BlazorAdapter.Settings.CreatorProfileFailed 0%
Kagura.BlazorAdapter.Settings.CreatorProfileSaved 0%
Kagura.BlazorAdapter.Settings.DeleteEmotionRequested 100%
Kagura.BlazorAdapter.Settings.EditSkillRequested 0%
Kagura.BlazorAdapter.Settings.EmotionCreated 100%
Kagura.BlazorAdapter.Settings.EmotionLibraryEffects 71.4% 37.5%
Kagura.BlazorAdapter.Settings.EmotionLibraryFailed 0%
Kagura.BlazorAdapter.Settings.EmotionLibraryLoaded 100%
Kagura.BlazorAdapter.Settings.EmotionLibraryReducers 96.5% 50%
Kagura.BlazorAdapter.Settings.EmotionLibrarySection 90.1% 80.7%
Kagura.BlazorAdapter.Settings.EmotionLibraryState 100%
Kagura.BlazorAdapter.Settings.NovelAiSettingsEffects 68.8% 50%
Kagura.BlazorAdapter.Settings.NovelAiSettingsFailed 100%
Kagura.BlazorAdapter.Settings.NovelAiSettingsLoaded 100%
Kagura.BlazorAdapter.Settings.NovelAiSettingsReducers 90.9% 25%
Kagura.BlazorAdapter.Settings.NovelAiSettingsSection 94.1% 91.6%
Kagura.BlazorAdapter.Settings.NovelAiSettingsState 100%
Kagura.BlazorAdapter.Settings.NovelAiTokenChecked 100%
Kagura.BlazorAdapter.Settings.OpenRouterModelsFailed 0%
Kagura.BlazorAdapter.Settings.OpenRouterModelsLoaded 100%
Kagura.BlazorAdapter.Settings.OpenRouterSettingsEffects 46.7% 27.7%
Kagura.BlazorAdapter.Settings.OpenRouterSettingsFailed 0%
Kagura.BlazorAdapter.Settings.OpenRouterSettingsLoaded 100%
Kagura.BlazorAdapter.Settings.OpenRouterSettingsReducers 77.2%
Kagura.BlazorAdapter.Settings.OpenRouterSettingsSection 91.1% 92.1%
Kagura.BlazorAdapter.Settings.OpenRouterSettingsState 100%
Kagura.BlazorAdapter.Settings.SaveCreatorProfileRequested 0%
Kagura.BlazorAdapter.Settings.SaveDefaultTagsRequested 100%
Kagura.BlazorAdapter.Settings.SaveEmotionRequested 100%
Kagura.BlazorAdapter.Settings.SaveNovelAiModelRequested 100%
Kagura.BlazorAdapter.Settings.SaveNovelAiTokenRequested 100%
Kagura.BlazorAdapter.Settings.SaveOpenRouterDescriberModelRequested 100%
Kagura.BlazorAdapter.Settings.SaveOpenRouterKeyRequested 100%
Kagura.BlazorAdapter.Settings.SaveOpenRouterModelRequested 100%
Kagura.BlazorAdapter.Settings.SaveOpenRouterReasoningEffortRequested 100%
Kagura.BlazorAdapter.Settings.SaveTtsFieldRequested 100%
Kagura.BlazorAdapter.Settings.SelectEmotion 100%
Kagura.BlazorAdapter.Settings.SetSkillPinnedRequested 0%
Kagura.BlazorAdapter.Settings.SetSkillStateRequested 0%
Kagura.BlazorAdapter.Settings.TokenVerdict 100%
Kagura.BlazorAdapter.Settings.TtsConnectionChecked 100%
Kagura.BlazorAdapter.Settings.TtsFieldSaved 100%
Kagura.BlazorAdapter.Settings.TtsSettingsEffects 73.5% 50%
Kagura.BlazorAdapter.Settings.TtsSettingsFailed 100%
Kagura.BlazorAdapter.Settings.TtsSettingsLoaded 100%
Kagura.BlazorAdapter.Settings.TtsSettingsReducers 100% 100%
Kagura.BlazorAdapter.Settings.TtsSettingsSection 77.9% 72.2%
Kagura.BlazorAdapter.Settings.TtsSettingsState 100%
Kagura.BlazorAdapter.Settings.TtsVerdict 100%
Kagura.BlazorAdapter.SliderDemo 0% 0%
Kagura.BlazorAdapter.Tags.ForgetTagAuthoringInstance 100%
Kagura.BlazorAdapter.Tags.PromptTagEditing 100% 76.3%
Kagura.BlazorAdapter.Tags.RequestSuggestions 100%
Kagura.BlazorAdapter.Tags.SearchTags 100%
Kagura.BlazorAdapter.Tags.SuggestionsReceived 100%
Kagura.BlazorAdapter.Tags.TagAuthoring 95.5% 78.8%
Kagura.BlazorAdapter.Tags.TagAuthoringEffects 100% 100%
Kagura.BlazorAdapter.Tags.TagAuthoringInstance 100%
Kagura.BlazorAdapter.Tags.TagAuthoringPage 0%
Kagura.BlazorAdapter.Tags.TagAuthoringReducers 100% 100%
Kagura.BlazorAdapter.Tags.TagAuthoringState 100% 100%
Kagura.BlazorAdapter.Tags.TagDatabaseChecked 100%
Kagura.BlazorAdapter.Tags.TagsSearched 100%
Kagura.BlazorAdapter.ToggleGroupDemo 0% 0%
Kagura.BlazorAdapter.VisualNovel.AddSceneCastRequested 100%
Kagura.BlazorAdapter.VisualNovel.AddSceneStepRequested 100%
Kagura.BlazorAdapter.VisualNovel.ChapterCreated 100%
Kagura.BlazorAdapter.VisualNovel.ChapterEditorDeleted 100%
Kagura.BlazorAdapter.VisualNovel.ChapterEditorEffects 90% 56.2%
Kagura.BlazorAdapter.VisualNovel.ChapterEditorLoaded 100%
Kagura.BlazorAdapter.VisualNovel.ChapterEditorNotFound 100%
Kagura.BlazorAdapter.VisualNovel.ChapterEditorPage 84.9% 70.4%
Kagura.BlazorAdapter.VisualNovel.ChapterEditorReducers 86.9% 42.8%
Kagura.BlazorAdapter.VisualNovel.ChapterEditorSaved 100%
Kagura.BlazorAdapter.VisualNovel.ChapterEditorState 100%
Kagura.BlazorAdapter.VisualNovel.ChapterOperationFailed 0%
Kagura.BlazorAdapter.VisualNovel.ChapterScenes 78.2% 65%
Kagura.BlazorAdapter.VisualNovel.ChaptersEffects 88.8% 64.2%
Kagura.BlazorAdapter.VisualNovel.ChaptersFailed 100%
Kagura.BlazorAdapter.VisualNovel.ChaptersLoaded 100%
Kagura.BlazorAdapter.VisualNovel.ChaptersPage 90.9% 90.9%
Kagura.BlazorAdapter.VisualNovel.ChaptersReducers 91.6% 100%
Kagura.BlazorAdapter.VisualNovel.ChaptersState 100%
Kagura.BlazorAdapter.VisualNovel.CreateChapterFailed 0%
Kagura.BlazorAdapter.VisualNovel.CreateChapterRequested 100%
Kagura.BlazorAdapter.VisualNovel.CreateSceneFailed 0%
Kagura.BlazorAdapter.VisualNovel.CreateSceneRequested 100%
Kagura.BlazorAdapter.VisualNovel.DeleteChapterRequested 100%
Kagura.BlazorAdapter.VisualNovel.DeleteSceneRequested 100%
Kagura.BlazorAdapter.VisualNovel.DeleteSceneStepRequested 100%
Kagura.BlazorAdapter.VisualNovel.GenerateStepAudioRequested 100%
Kagura.BlazorAdapter.VisualNovel.LoadChapter 100%
Kagura.BlazorAdapter.VisualNovel.LoadChapters 100%
Kagura.BlazorAdapter.VisualNovel.LoadPlayer 100%
Kagura.BlazorAdapter.VisualNovel.LoadScene 100%
Kagura.BlazorAdapter.VisualNovel.LoadScenes 100%
Kagura.BlazorAdapter.VisualNovel.LoadSceneSteps 100%
Kagura.BlazorAdapter.VisualNovel.PlayerEffects 100% 83.3%
Kagura.BlazorAdapter.VisualNovel.PlayerLoaded 100%
Kagura.BlazorAdapter.VisualNovel.PlayerPage 100% 78.2%
Kagura.BlazorAdapter.VisualNovel.PlayerReducers 100% 100%
Kagura.BlazorAdapter.VisualNovel.PlayerStage 98.2% 70.9%
Kagura.BlazorAdapter.VisualNovel.PlayerState 100% 83.3%
Kagura.BlazorAdapter.VisualNovel.RemoveSceneCastRequested 100%
Kagura.BlazorAdapter.VisualNovel.ReorderChaptersRequested 100%
Kagura.BlazorAdapter.VisualNovel.ReorderScenesRequested 0%
Kagura.BlazorAdapter.VisualNovel.ReorderSceneStepsRequested 100%
Kagura.BlazorAdapter.VisualNovel.SaveChapterRequested 100%
Kagura.BlazorAdapter.VisualNovel.SaveSceneRequested 100%
Kagura.BlazorAdapter.VisualNovel.SceneCast 100% 76.9%
Kagura.BlazorAdapter.VisualNovel.SceneCastAdded 100%
Kagura.BlazorAdapter.VisualNovel.SceneCastRemoved 100%
Kagura.BlazorAdapter.VisualNovel.SceneCreated 100%
Kagura.BlazorAdapter.VisualNovel.SceneEditorDeleted 100%
Kagura.BlazorAdapter.VisualNovel.SceneEditorEffects 92.1% 55.5%
Kagura.BlazorAdapter.VisualNovel.SceneEditorLoaded 100%
Kagura.BlazorAdapter.VisualNovel.SceneEditorNotFound 100%
Kagura.BlazorAdapter.VisualNovel.SceneEditorPage 87.9% 71.2%
Kagura.BlazorAdapter.VisualNovel.SceneEditorReducers 88.4% 42.8%
Kagura.BlazorAdapter.VisualNovel.SceneEditorSaved 100%
Kagura.BlazorAdapter.VisualNovel.SceneEditorState 100%
Kagura.BlazorAdapter.VisualNovel.SceneLineRow 88.5% 84.7%
Kagura.BlazorAdapter.VisualNovel.SceneLineStage 83.2% 71.4%
Kagura.BlazorAdapter.VisualNovel.SceneOperationFailed 0%
Kagura.BlazorAdapter.VisualNovel.SceneScript 91.4% 86.3%
Kagura.BlazorAdapter.VisualNovel.ScenesEffects 64.2% 35.7%
Kagura.BlazorAdapter.VisualNovel.ScenesFailed 100%
Kagura.BlazorAdapter.VisualNovel.ScenesLoaded 100%
Kagura.BlazorAdapter.VisualNovel.ScenesReducers 76.9% 83.3%
Kagura.BlazorAdapter.VisualNovel.ScenesState 100% 100%
Kagura.BlazorAdapter.VisualNovel.SceneStatuses 100% 50%
Kagura.BlazorAdapter.VisualNovel.SceneStepAdded 100%
Kagura.BlazorAdapter.VisualNovel.SceneStepDeleted 100%
Kagura.BlazorAdapter.VisualNovel.SceneStepSaved 100%
Kagura.BlazorAdapter.VisualNovel.SceneStepsEffects 81.3% 62.9%
Kagura.BlazorAdapter.VisualNovel.SceneStepsFailed 100%
Kagura.BlazorAdapter.VisualNovel.SceneStepsLoaded 100%
Kagura.BlazorAdapter.VisualNovel.SceneStepsReducers 97.2% 75%
Kagura.BlazorAdapter.VisualNovel.SceneStepsState 100% 50%
Kagura.BlazorAdapter.VisualNovel.SetScenesStatus 100%
Kagura.BlazorAdapter.VisualNovel.SetSceneStepStageRequested 100%
Kagura.BlazorAdapter.VisualNovel.StepAudioFailed 100%
Kagura.BlazorAdapter.VisualNovel.StepAudioFinished 100%
Kagura.BlazorAdapter.VisualNovel.StepAudioState 100%
Kagura.BlazorAdapter.VisualNovel.UpdateSceneStepRequested 100%
Kagura.Domain - 96.4%
Name Line Branch
Kagura.Domain 96.4% 91.9%
Kagura.Domain.Assistant.Skill 100% 90%
Kagura.Domain.Graph.Entry 100% 100%
Kagura.Domain.Graph.Link 100% 100%
Kagura.Domain.Graph.LinkRole 100% 100%
Kagura.Domain.Graph.LinkRoles 100%
Kagura.Domain.Graph.StructuralRef 100% 100%
Kagura.Domain.Graph.StructuralRefs 100% 100%
Kagura.Domain.Journal.ChangeLogEntry 100%
Kagura.Domain.KnowledgeBase.BodyTypes 100% 100%
Kagura.Domain.KnowledgeBase.Character 97.1% 100%
Kagura.Domain.KnowledgeBase.CharacterProfile 100%
Kagura.Domain.KnowledgeBase.CharacterVoice 100%
Kagura.Domain.KnowledgeBase.CupSizes 100% 100%
Kagura.Domain.KnowledgeBase.CuratedTag 100%
Kagura.Domain.KnowledgeBase.Emotion 87.8% 66.6%
Kagura.Domain.KnowledgeBase.EmotionProfile 50%
Kagura.Domain.KnowledgeBase.Expression 87%
Kagura.Domain.KnowledgeBase.ImageRegion 90% 100%
Kagura.Domain.KnowledgeBase.LabeledEntry 100%
Kagura.Domain.KnowledgeBase.Location 92.3% 100%
Kagura.Domain.KnowledgeBase.LocationProfile 100%
Kagura.Domain.KnowledgeBase.LocationVariant 92.5% 66.6%
Kagura.Domain.KnowledgeBase.LocationVariantProfile 100%
Kagura.Domain.KnowledgeBase.LoreEntry 100%
Kagura.Domain.KnowledgeBase.LoreProfile 100%
Kagura.Domain.KnowledgeBase.Outfit 93.4% 80%
Kagura.Domain.KnowledgeBase.OutfitProfile 100%
Kagura.Domain.KnowledgeBase.PromptTag 42.8% 100%
Kagura.Domain.KnowledgeBase.Relationship 91.8% 100%
Kagura.Domain.KnowledgeBase.RelationshipProfile 100%
Kagura.Domain.KnowledgeBase.RelationshipSecret 100% 75%
Kagura.Domain.KnowledgeBase.SpriteFramings 100% 100%
Kagura.Domain.KnowledgeBase.StyleReferenceTuning 100%
Kagura.Domain.KnowledgeBase.TimelineEvent 100% 100%
Kagura.Domain.Projects.Project 100% 90%
Kagura.Domain.Projects.Slug 100% 100%
Kagura.Domain.Settings.AppSetting 100%
Kagura.Domain.VisualNovel.Chapter 100% 100%
Kagura.Domain.VisualNovel.ChapterProfile 80%
Kagura.Domain.VisualNovel.EffectiveStage 100%
Kagura.Domain.VisualNovel.PlayerFrame 100%
Kagura.Domain.VisualNovel.PlayerSceneScript 100%
Kagura.Domain.VisualNovel.PlayerStep 100%
Kagura.Domain.VisualNovel.Scene 96.1% 83.3%
Kagura.Domain.VisualNovel.ScenePlayback 100% 100%
Kagura.Domain.VisualNovel.SceneProfile 100%
Kagura.Domain.VisualNovel.SceneStageProjection 100% 96.4%
Kagura.Domain.VisualNovel.SceneStep 100% 100%
Kagura.Domain.VisualNovel.SpriteLayout 100%
Kagura.Domain.VisualNovel.StageBackgroundChange 100%
Kagura.Domain.VisualNovel.StageCharacterChange 100%
Kagura.Domain.VisualNovel.StageCharacterState 100%
Kagura.Domain.VisualNovel.StageProjection 100% 100%
Kagura.Domain.VisualNovel.StageStepChanges 100%
Kagura.Domain.VisualNovel.StageView 100%
System.Text.RegularExpressions.Generated 90.2% 72.2%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>FE06CC341D340484
D04ADFED3A21D401C2764A1D17367E35BEB556CBB3B4B0B74__NonSlugChars_0
89.4% 75%
Kagura.Infrastructure - 97.9%
Name Line Branch
Kagura.Infrastructure 97.9% 73.3%
Kagura.Infrastructure.Assistant.AssistantContextResolver 94.1% 68.8%
Kagura.Infrastructure.Assistant.AssistantMutationTool`1 100% 87.5%
Kagura.Infrastructure.Assistant.AssistantTool`1 100% 100%
Kagura.Infrastructure.Assistant.AssistantToolContext 100%
Kagura.Infrastructure.Assistant.ChatSession 88.1% 46.1%
Kagura.Infrastructure.Assistant.DelegateProgress`1 100%
Kagura.Infrastructure.Assistant.EfSkillStore 100%
Kagura.Infrastructure.Assistant.InMemoryConversationStore 100% 87.5%
Kagura.Infrastructure.Assistant.ResolvedContext 100%
Kagura.Infrastructure.Assistant.Tools.BodyAttributeParams 100% 100%
Kagura.Infrastructure.Assistant.Tools.CharacterTiers 100% 100%
Kagura.Infrastructure.Assistant.Tools.CreateChapterParams 100%
Kagura.Infrastructure.Assistant.Tools.CreateChapterTool 93.3%
Kagura.Infrastructure.Assistant.Tools.CreateCharacterParams 100%
Kagura.Infrastructure.Assistant.Tools.CreateCharacterTool 96.7%
Kagura.Infrastructure.Assistant.Tools.CreateLocationParams 100%
Kagura.Infrastructure.Assistant.Tools.CreateLocationTool 93.6%
Kagura.Infrastructure.Assistant.Tools.CreateLocationVariantParams 100%
Kagura.Infrastructure.Assistant.Tools.CreateLocationVariantTool 92.8%
Kagura.Infrastructure.Assistant.Tools.CreateLoreParams 100%
Kagura.Infrastructure.Assistant.Tools.CreateLoreTool 94.5% 100%
Kagura.Infrastructure.Assistant.Tools.CreateOutfitParams 100%
Kagura.Infrastructure.Assistant.Tools.CreateOutfitTool 94.7%
Kagura.Infrastructure.Assistant.Tools.CreateRelationshipParams 100%
Kagura.Infrastructure.Assistant.Tools.CreateRelationshipTool 94.2%
Kagura.Infrastructure.Assistant.Tools.CreateSceneParams 100%
Kagura.Infrastructure.Assistant.Tools.CreateSceneTool 93.9%
Kagura.Infrastructure.Assistant.Tools.CreateTimelineEventParams 100%
Kagura.Infrastructure.Assistant.Tools.CreateTimelineEventTool 95.8%
Kagura.Infrastructure.Assistant.Tools.DeleteChapterParams 100%
Kagura.Infrastructure.Assistant.Tools.DeleteChapterTool 95.2%
Kagura.Infrastructure.Assistant.Tools.DeleteCharacterParams 100%
Kagura.Infrastructure.Assistant.Tools.DeleteCharacterTool 95.2%
Kagura.Infrastructure.Assistant.Tools.DeleteLocationParams 100%
Kagura.Infrastructure.Assistant.Tools.DeleteLocationTool 95.2%
Kagura.Infrastructure.Assistant.Tools.DeleteLocationVariantParams 100%
Kagura.Infrastructure.Assistant.Tools.DeleteLocationVariantTool 95.6%
Kagura.Infrastructure.Assistant.Tools.DeleteLoreParams 100%
Kagura.Infrastructure.Assistant.Tools.DeleteLoreTool 95.2%
Kagura.Infrastructure.Assistant.Tools.DeleteOutfitParams 100%
Kagura.Infrastructure.Assistant.Tools.DeleteOutfitTool 95.6%
Kagura.Infrastructure.Assistant.Tools.DeleteRelationshipParams 100%
Kagura.Infrastructure.Assistant.Tools.DeleteRelationshipTool 100%
Kagura.Infrastructure.Assistant.Tools.DeleteSceneLineParams 100%
Kagura.Infrastructure.Assistant.Tools.DeleteSceneLineTool 100%
Kagura.Infrastructure.Assistant.Tools.DeleteSceneParams 100%
Kagura.Infrastructure.Assistant.Tools.DeleteSceneTool 95.2%
Kagura.Infrastructure.Assistant.Tools.DeleteTimelineEventParams 100%
Kagura.Infrastructure.Assistant.Tools.DeleteTimelineEventTool 100%
Kagura.Infrastructure.Assistant.Tools.EntryParam 100% 100%
Kagura.Infrastructure.Assistant.Tools.FindSimilarTagsParams 100%
Kagura.Infrastructure.Assistant.Tools.FindSimilarTagsTool 93.3%
Kagura.Infrastructure.Assistant.Tools.GenerateCharacterSpriteParams 100%
Kagura.Infrastructure.Assistant.Tools.GenerateCharacterSpriteTool 96.6%
Kagura.Infrastructure.Assistant.Tools.GenerateExpressionSpritesParams 100%
Kagura.Infrastructure.Assistant.Tools.GenerateExpressionSpritesTool 86.8% 50%
Kagura.Infrastructure.Assistant.Tools.GenerateLocationBackgroundParams 100%
Kagura.Infrastructure.Assistant.Tools.GenerateLocationBackgroundTool 93.3%
Kagura.Infrastructure.Assistant.Tools.GenerateOutfitSpriteParams 100%
Kagura.Infrastructure.Assistant.Tools.GenerateOutfitSpriteTool 73.3%
Kagura.Infrastructure.Assistant.Tools.GenerateVariantBackgroundParams 100%
Kagura.Infrastructure.Assistant.Tools.GenerateVariantBackgroundTool 94.1%
Kagura.Infrastructure.Assistant.Tools.GenerationLaunch 90.6% 62.5%
Kagura.Infrastructure.Assistant.Tools.GetChapterParams 100%
Kagura.Infrastructure.Assistant.Tools.GetChapterTool 97%
Kagura.Infrastructure.Assistant.Tools.GetCharacterParams 100%
Kagura.Infrastructure.Assistant.Tools.GetCharacterTool 98.3% 50%
Kagura.Infrastructure.Assistant.Tools.GetConnectionsParams 100%
Kagura.Infrastructure.Assistant.Tools.GetConnectionsTool 96.6%
Kagura.Infrastructure.Assistant.Tools.GetGenerationQueueTool 100% 50%
Kagura.Infrastructure.Assistant.Tools.GetLocationParams 100%
Kagura.Infrastructure.Assistant.Tools.GetLocationTool 97.3%
Kagura.Infrastructure.Assistant.Tools.GetLocationVariantParams 100%
Kagura.Infrastructure.Assistant.Tools.GetLocationVariantTool 100%
Kagura.Infrastructure.Assistant.Tools.GetLoreParams 100%
Kagura.Infrastructure.Assistant.Tools.GetLoreTool 96.2%
Kagura.Infrastructure.Assistant.Tools.GetOutfitParams 100%
Kagura.Infrastructure.Assistant.Tools.GetOutfitTool 100% 50%
Kagura.Infrastructure.Assistant.Tools.GetProjectOverviewTool 97.7%
Kagura.Infrastructure.Assistant.Tools.GetSceneParams 100%
Kagura.Infrastructure.Assistant.Tools.GetSceneStageOptionsTool 100%
Kagura.Infrastructure.Assistant.Tools.GetSceneTool 98% 100%
Kagura.Infrastructure.Assistant.Tools.GetTimelineTool 100%
Kagura.Infrastructure.Assistant.Tools.LinkRecordsParams 100%
Kagura.Infrastructure.Assistant.Tools.LinkRecordsTool 97.1%
Kagura.Infrastructure.Assistant.Tools.ListChaptersTool 100%
Kagura.Infrastructure.Assistant.Tools.ListCharactersTool 100%
Kagura.Infrastructure.Assistant.Tools.ListLocationsTool 100%
Kagura.Infrastructure.Assistant.Tools.ListLoreTool 100%
Kagura.Infrastructure.Assistant.Tools.ListRelationshipsTool 100% 100%
Kagura.Infrastructure.Assistant.Tools.ManageSkillParams 100%
Kagura.Infrastructure.Assistant.Tools.ManageSkillTool 92.7% 100%
Kagura.Infrastructure.Assistant.Tools.MemoryOperationParam 100%
Kagura.Infrastructure.Assistant.Tools.MemoryParams 100%
Kagura.Infrastructure.Assistant.Tools.MemoryTool 91.8% 76.6%
Kagura.Infrastructure.Assistant.Tools.MoveSceneLineParams 100%
Kagura.Infrastructure.Assistant.Tools.MoveSceneLineTool 87.8%
Kagura.Infrastructure.Assistant.Tools.NavigateToParams 100%
Kagura.Infrastructure.Assistant.Tools.NavigateToTool 80% 50%
Kagura.Infrastructure.Assistant.Tools.RedoTool 93.7%
Kagura.Infrastructure.Assistant.Tools.ResolveTagParams 100%
Kagura.Infrastructure.Assistant.Tools.ResolveTagTool 95%
Kagura.Infrastructure.Assistant.Tools.SceneLineParam 100%
Kagura.Infrastructure.Assistant.Tools.SceneScript 96.9% 100%
Kagura.Infrastructure.Assistant.Tools.SearchParams 100%
Kagura.Infrastructure.Assistant.Tools.SearchTagsParams 100%
Kagura.Infrastructure.Assistant.Tools.SearchTagsTool 100%
Kagura.Infrastructure.Assistant.Tools.SearchTool 86.2% 25%
Kagura.Infrastructure.Assistant.Tools.SetProjectStyleParams 100%
Kagura.Infrastructure.Assistant.Tools.SetProjectStyleTool 97.9% 92.8%
Kagura.Infrastructure.Assistant.Tools.SetSceneLineStageParams 100%
Kagura.Infrastructure.Assistant.Tools.SetSceneLineStageTool 97.4%
Kagura.Infrastructure.Assistant.Tools.SpriteFramingParams 100% 100%
Kagura.Infrastructure.Assistant.Tools.SpriteGenders 100% 100%
Kagura.Infrastructure.Assistant.Tools.StageBackgroundParam 100%
Kagura.Infrastructure.Assistant.Tools.StageCharacterParam 100%
Kagura.Infrastructure.Assistant.Tools.SuggestTagsParams 100%
Kagura.Infrastructure.Assistant.Tools.SuggestTagsTool 94.1%
Kagura.Infrastructure.Assistant.Tools.TagDetailsParams 100%
Kagura.Infrastructure.Assistant.Tools.TagDetailsTool 93.3%
Kagura.Infrastructure.Assistant.Tools.TagParam 100% 85.7%
Kagura.Infrastructure.Assistant.Tools.TagTools 100%
Kagura.Infrastructure.Assistant.Tools.UndoTool 94.1%
Kagura.Infrastructure.Assistant.Tools.UnlinkRecordsParams 100%
Kagura.Infrastructure.Assistant.Tools.UnlinkRecordsTool 88.2% 50%
Kagura.Infrastructure.Assistant.Tools.UpdateChapterParams 100%
Kagura.Infrastructure.Assistant.Tools.UpdateChapterTool 94.7%
Kagura.Infrastructure.Assistant.Tools.UpdateCharacterParams 100%
Kagura.Infrastructure.Assistant.Tools.UpdateCharacterTool 97.6%
Kagura.Infrastructure.Assistant.Tools.UpdateLocationParams 100%
Kagura.Infrastructure.Assistant.Tools.UpdateLocationTool 95.2%
Kagura.Infrastructure.Assistant.Tools.UpdateLocationVariantParams 100%
Kagura.Infrastructure.Assistant.Tools.UpdateLocationVariantTool 95.5%
Kagura.Infrastructure.Assistant.Tools.UpdateLoreParams 100%
Kagura.Infrastructure.Assistant.Tools.UpdateLoreTool 95.2%
Kagura.Infrastructure.Assistant.Tools.UpdateOutfitParams 100%
Kagura.Infrastructure.Assistant.Tools.UpdateOutfitTool 96.1%
Kagura.Infrastructure.Assistant.Tools.UpdateProjectParams 100%
Kagura.Infrastructure.Assistant.Tools.UpdateProjectTool 92.8%
Kagura.Infrastructure.Assistant.Tools.UpdateRelationshipParams 100%
Kagura.Infrastructure.Assistant.Tools.UpdateRelationshipTool 97.1%
Kagura.Infrastructure.Assistant.Tools.UpdateSceneLineParams 100%
Kagura.Infrastructure.Assistant.Tools.UpdateSceneLineTool 95.1% 75%
Kagura.Infrastructure.Assistant.Tools.UpdateSceneParams 100%
Kagura.Infrastructure.Assistant.Tools.UpdateSceneTool 95.4%
Kagura.Infrastructure.Assistant.Tools.UpdateTimelineEventParams 100%
Kagura.Infrastructure.Assistant.Tools.UpdateTimelineEventTool 96.2%
Kagura.Infrastructure.Assistant.Tools.ViewSkillParams 100%
Kagura.Infrastructure.Assistant.Tools.ViewSkillTool 100%
Kagura.Infrastructure.Assistant.Tools.WriteSceneLinesParams 100%
Kagura.Infrastructure.Assistant.Tools.WriteSceneLinesTool 93.6% 80%
Kagura.Infrastructure.Backups.BackupOptions 100%
Kagura.Infrastructure.Backups.BackupService 71.4% 83.3%
Kagura.Infrastructure.Backups.BackupWriter 92.3% 85.4%
Kagura.Infrastructure.DependencyInjection 100% 100%
Kagura.Infrastructure.Diagnostics.SqliteDatabaseSnapshotStore 100% 100%
Kagura.Infrastructure.Emotions.EfEmotionStore 92.3% 75%
Kagura.Infrastructure.Emotions.EmotionSeeder 100% 100%
Kagura.Infrastructure.Generation.ActivityQueue 99.3% 95.4%
Kagura.Infrastructure.Generation.ActivityQueueWorker 100%
Kagura.Infrastructure.Graph.EfGraphStore 98.2% 90.9%
Kagura.Infrastructure.Journal.EfChangeJournal 100%
Kagura.Infrastructure.Journal.EfDocumentReverter 95% 91.6%
Kagura.Infrastructure.Journal.EfUndoStore 98.4% 90.9%
Kagura.Infrastructure.Journal.OperationContext 100% 100%
Kagura.Infrastructure.Journal.SnapshotApplier 95% 90%
Kagura.Infrastructure.KnowledgeBase.CharacterImageGenerator 97.8% 83.3%
Kagura.Infrastructure.KnowledgeBase.EfCharacterStore 92% 64.2%
Kagura.Infrastructure.KnowledgeBase.EfExpressionStore 96.1% 75%
Kagura.Infrastructure.KnowledgeBase.EfLocationStore 95.1% 80%
Kagura.Infrastructure.KnowledgeBase.EfLocationVariantStore 96.9% 83.3%
Kagura.Infrastructure.KnowledgeBase.EfLoreStore 100% 100%
Kagura.Infrastructure.KnowledgeBase.EfOutfitStore 95% 75%
Kagura.Infrastructure.KnowledgeBase.EfRelationshipStore 93.4% 60%
Kagura.Infrastructure.KnowledgeBase.EfTimelineStore 93.9% 75%
Kagura.Infrastructure.KnowledgeBase.ExpressionImageGenerator 94.4% 81.5%
Kagura.Infrastructure.KnowledgeBase.ImageSharpCropper 100% 100%
Kagura.Infrastructure.KnowledgeBase.LocationImageGenerator 97.6% 75%
Kagura.Infrastructure.KnowledgeBase.LocationVariantImageGenerator 95.6% 75%
Kagura.Infrastructure.KnowledgeBase.OutfitImageGenerator 97.1% 85.2%
Kagura.Infrastructure.KnowledgeBase.RegionMaskRasterizer 100% 100%
Kagura.Infrastructure.KnowledgeBase.SpriteEnrichment 90.9% 81.2%
Kagura.Infrastructure.Notifications.InProcessDomainChangedBus 100% 100%
Kagura.Infrastructure.Persistence.Configurations.AppSettingConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.ChangeLogEntryConfiguratio
n
100%
Kagura.Infrastructure.Persistence.Configurations.ChapterConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.CharacterConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.EmotionConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.EntryConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.ExpressionConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.JsonColumnMapper 100%
Kagura.Infrastructure.Persistence.Configurations.LinkConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.LocationConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.LocationVariantConfigurati
on
100%
Kagura.Infrastructure.Persistence.Configurations.LoreEntryConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.OutfitConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.ProjectConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.RelationshipConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.SceneConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.SceneStepConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.SkillConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.TimelineEventConfiguration 100%
Kagura.Infrastructure.Persistence.Converters.UtcTicksConverter 100%
Kagura.Infrastructure.Persistence.KaguraDbContext 83.3% 88%
Kagura.Infrastructure.Persistence.KaguraDbContextFactory 0%
Kagura.Infrastructure.Persistence.Migrations.AddAppSettings 99.3%
Kagura.Infrastructure.Persistence.Migrations.AddChangeLogUndoFlag 96.8%
Kagura.Infrastructure.Persistence.Migrations.AddChapters 99.5%
Kagura.Infrastructure.Persistence.Migrations.AddChapterStoryBeats 99.3%
Kagura.Infrastructure.Persistence.Migrations.AddCharacterBaseAppearance 98.4%
Kagura.Infrastructure.Persistence.Migrations.AddCharacterBaseImage 99%
Kagura.Infrastructure.Persistence.Migrations.AddCharacterBodyAttributes 99.1%
Kagura.Infrastructure.Persistence.Migrations.AddCharacterFraming 99.4%
Kagura.Infrastructure.Persistence.Migrations.AddCharacterHeight 99.4%
Kagura.Infrastructure.Persistence.Migrations.AddCharacterProfile 92.9%
Kagura.Infrastructure.Persistence.Migrations.AddCharacters 98.7%
Kagura.Infrastructure.Persistence.Migrations.AddCharacterTier 99.4%
Kagura.Infrastructure.Persistence.Migrations.AddCharacterVoiceConfigs 99.4%
Kagura.Infrastructure.Persistence.Migrations.AddCharacterVoiceProviderId 99.5%
Kagura.Infrastructure.Persistence.Migrations.AddEmotions 99.4%
Kagura.Infrastructure.Persistence.Migrations.AddExpressions 99.5%
Kagura.Infrastructure.Persistence.Migrations.AddGraphEntryAndLink 97.7%
Kagura.Infrastructure.Persistence.Migrations.AddLocationBaseImage 99.1%
Kagura.Infrastructure.Persistence.Migrations.AddLocationBaseTags 99.1%
Kagura.Infrastructure.Persistence.Migrations.AddLocationHierarchy 96.6%
Kagura.Infrastructure.Persistence.Migrations.AddLocations 98.9%
Kagura.Infrastructure.Persistence.Migrations.AddLocationVariantImage 99.3%
Kagura.Infrastructure.Persistence.Migrations.AddLocationVariants 99.4%
Kagura.Infrastructure.Persistence.Migrations.AddLocationVariantTags 98.8%
Kagura.Infrastructure.Persistence.Migrations.AddLoreEntries 99%
Kagura.Infrastructure.Persistence.Migrations.AddLoreEntryTables 97.8%
Kagura.Infrastructure.Persistence.Migrations.AddOutfitClothingTags 99.1%
Kagura.Infrastructure.Persistence.Migrations.AddOutfitDisabledInheritedTags 99.1%
Kagura.Infrastructure.Persistence.Migrations.AddOutfitFaceRegion 98.7%
Kagura.Infrastructure.Persistence.Migrations.AddOutfitImage 99.1%
Kagura.Infrastructure.Persistence.Migrations.AddOutfitReferenceTuning 99.2%
Kagura.Infrastructure.Persistence.Migrations.AddOutfits 99.4%
Kagura.Infrastructure.Persistence.Migrations.AddOutfitUseBaseImageReference 99.4%
Kagura.Infrastructure.Persistence.Migrations.AddPerRecordStyleReferenceTuni
ng
97.1%
Kagura.Infrastructure.Persistence.Migrations.AddProjectAssistantMemory 99.4%
Kagura.Infrastructure.Persistence.Migrations.AddProjectDescription 98.1%
Kagura.Infrastructure.Persistence.Migrations.AddProjectStyleReference 99%
Kagura.Infrastructure.Persistence.Migrations.AddProjectStyleSource 99.2%
Kagura.Infrastructure.Persistence.Migrations.AddRelationships 99.2%
Kagura.Infrastructure.Persistence.Migrations.AddSceneMetadata 97.3%
Kagura.Infrastructure.Persistence.Migrations.AddScenes 99.5%
Kagura.Infrastructure.Persistence.Migrations.AddSceneSteps 99.5%
Kagura.Infrastructure.Persistence.Migrations.AddSceneStepStage 99%
Kagura.Infrastructure.Persistence.Migrations.AddSceneStepVoice 99.4%
Kagura.Infrastructure.Persistence.Migrations.AddSkills 99.6%
Kagura.Infrastructure.Persistence.Migrations.AddSoftDeleteAndChangeLog 90.3%
Kagura.Infrastructure.Persistence.Migrations.AddStageViews 98.3%
Kagura.Infrastructure.Persistence.Migrations.AddTimelineEvents 99.2%
Kagura.Infrastructure.Persistence.Migrations.CharacterPreviewImage 99.3%
Kagura.Infrastructure.Persistence.Migrations.InitialCreate 94.4%
Kagura.Infrastructure.Persistence.Migrations.KaguraDbContextModelSnapshot 100%
Kagura.Infrastructure.Persistence.Migrations.LocationPreviewImage 99.3%
Kagura.Infrastructure.Persistence.Migrations.MultiFaceRegions 98.2%
Kagura.Infrastructure.Persistence.Migrations.ReferenceStrengthDefault 98.8%
Kagura.Infrastructure.Projects.EfProjectStore 93.5% 71.4%
Kagura.Infrastructure.Projects.FileSystemProjectAssetStore 94.1% 75.5%
Kagura.Infrastructure.Settings.EfAppSettingsStore 100% 100%
Kagura.Infrastructure.Settings.NovelAiGateway 76.4% 50%
Kagura.Infrastructure.Settings.OpenRouterGateway 85% 79.4%
Kagura.Infrastructure.Settings.SpriteRequestMapper 100% 100%
Kagura.Infrastructure.Tags.SqliteTagSearch 97.9% 87.9%
Kagura.Infrastructure.Tags.TagDatabaseOptions 100%
Kagura.Infrastructure.Tts.FishAudioTtsProvider 87.9% 58.6%
Kagura.Infrastructure.Tts.OpenAiCompatibleTtsProvider 87.5% 54.5%
Kagura.Infrastructure.Tts.PocketTtsProvider 76.4% 69%
Kagura.Infrastructure.Tts.Qwen3TtsProvider 87.3% 66.6%
Kagura.Infrastructure.Tts.SceneStepAudioGenerator 92.3% 71.4%
Kagura.Infrastructure.Tts.TtsProviderRegistry 100%
Kagura.Infrastructure.Tts.VoicePreviewGenerator 91.3% 67.8%
Kagura.Infrastructure.VisualNovel.EfChapterStore 93.7% 75%
Kagura.Infrastructure.VisualNovel.EfSceneStepStore 91.8% 66.6%
Kagura.Infrastructure.VisualNovel.EfSceneStore 93.7% 75%
System.Text.RegularExpressions.Generated 83.4% 68%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>FFD7A84EAF2E5F7B
C689CA5BBE6D1849B2CA79581BBB07D40636D85790C0E51A9__ArtifactTimestampRegex_2
81.9% 62.8%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>FFD7A84EAF2E5F7B
C689CA5BBE6D1849B2CA79581BBB07D40636D85790C0E51A9__ProjectRoute_0
88.5% 80.4%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>FFD7A84EAF2E5F7B
C689CA5BBE6D1849B2CA79581BBB07D40636D85790C0E51A9__TabQuery_1
80.7% 62.5%
Kagura.Kernel - 90%
Name Line Branch
Kagura.Kernel 90% 75%
Kagura.Kernel.Err`1 100%
Kagura.Kernel.Ok`1 100%
Kagura.Kernel.Result`1 87.5% 75%
Kagura.Server - 83%
Name Line Branch
Kagura.Server 83% 75.9%
Kagura.Server.Components.App 100%
Kagura.Server.Components.Layout.MainLayout 100%
Kagura.Server.Components.Pages.Error 100% 50%
Kagura.Server.Components.Pages.Gate 100% 100%
Kagura.Server.Security.AccessGate 100% 83.3%
Kagura.Server.Security.AccessSecret 100% 100%
Program 76.6% 73%
Kagura.UseCases - 96%
Name Line Branch
Kagura.UseCases 96% 80.6%
Kagura.UseCases.Assistant.AssistantContext 100%
Kagura.UseCases.Assistant.AssistantEntry 100%
Kagura.UseCases.Assistant.AssistantEvent 100%
Kagura.UseCases.Assistant.ConversationSnapshot 100%
Kagura.UseCases.Assistant.ListSkills 100%
Kagura.UseCases.Assistant.MemoryDocument 89.1% 75%
Kagura.UseCases.Assistant.MemoryOperation 100%
Kagura.UseCases.Assistant.ReviewDue 100% 100%
Kagura.UseCases.Assistant.SaveCreatorProfile 75% 50%
Kagura.UseCases.Assistant.SaveProjectAssistantMemory 80% 50%
Kagura.UseCases.Assistant.SaveSkill 89.7% 77.2%
Kagura.UseCases.Assistant.SkillDto 75%
Kagura.UseCases.DependencyInjection 100%
Kagura.UseCases.Diagnostics.DatabaseSnapshot 100%
Kagura.UseCases.Diagnostics.DownloadDatabase 100%
Kagura.UseCases.Diagnostics.SeedDevData 100% 100%
Kagura.UseCases.Emotions.CreateEmotion 100% 66.6%
Kagura.UseCases.Emotions.DeleteEmotion 100% 100%
Kagura.UseCases.Emotions.EmotionDto 91.6%
Kagura.UseCases.Emotions.ListEmotions 100%
Kagura.UseCases.Emotions.UpdateEmotion 100% 50%
Kagura.UseCases.Generation.Activity`1 100% 50%
Kagura.UseCases.Generation.ActivityChanged 100%
Kagura.UseCases.Generation.ActivityOutcome 100%
Kagura.UseCases.Generation.ActivityProgress 100%
Kagura.UseCases.Generation.ActivityView 91.6%
Kagura.UseCases.Generation.GeneratedImage 100%
Kagura.UseCases.Generation.Img2ImgSource 100%
Kagura.UseCases.Generation.InpaintSource 100%
Kagura.UseCases.Generation.JobResult`1 100%
Kagura.UseCases.Generation.LineageReference 100%
Kagura.UseCases.Generation.SpriteGenerationSpec 100%
Kagura.UseCases.Generation.StyleReference 100%
Kagura.UseCases.Graph.EdgeGroup 100%
Kagura.UseCases.Graph.FindLinkTargets 100%
Kagura.UseCases.Graph.GetNodeGraph 97.5% 78.5%
Kagura.UseCases.Graph.GraphEdgeView 100%
Kagura.UseCases.Graph.LinkNodes 100% 100%
Kagura.UseCases.Graph.NodeGraphView 100%
Kagura.UseCases.Graph.NodeSummary 100%
Kagura.UseCases.Graph.RemoveLink 100% 100%
Kagura.UseCases.Graph.RestoreLink 100% 100%
Kagura.UseCases.Graph.StructuralEdge 100%
Kagura.UseCases.Journal.ChangeRecordView 57.1%
Kagura.UseCases.Journal.DocumentRevision 100%
Kagura.UseCases.Journal.FieldChange 100%
Kagura.UseCases.Journal.GetDocumentHistory 100%
Kagura.UseCases.Journal.GetEntityHistory 100%
Kagura.UseCases.Journal.GetRevisionDiff 100% 50%
Kagura.UseCases.Journal.GetUndoStatus 100%
Kagura.UseCases.Journal.Redo 100% 100%
Kagura.UseCases.Journal.RevertDocument 100% 100%
Kagura.UseCases.Journal.RevertOutcome 100%
Kagura.UseCases.Journal.RevisionCoalescer 100% 100%
Kagura.UseCases.Journal.RevisionDiff 80% 50%
Kagura.UseCases.Journal.RevisionDiffBuilder 98.4% 86.5%
Kagura.UseCases.Journal.RowChange 100%
Kagura.UseCases.Journal.Undo 100% 100%
Kagura.UseCases.Journal.UndoOutcome 100%
Kagura.UseCases.Journal.UndoStatus 100%
Kagura.UseCases.KnowledgeBase.AdoptEmotions 100% 100%
Kagura.UseCases.KnowledgeBase.CharacterDto 98.2%
Kagura.UseCases.KnowledgeBase.CharacterSpriteContent 100%
Kagura.UseCases.KnowledgeBase.CreateCharacter 100%
Kagura.UseCases.KnowledgeBase.CreateLocation 100%
Kagura.UseCases.KnowledgeBase.CreateLocationVariant 100% 75%
Kagura.UseCases.KnowledgeBase.CreateLore 100%
Kagura.UseCases.KnowledgeBase.CreateOutfit 100% 75%
Kagura.UseCases.KnowledgeBase.CreateRelationship 93.3% 80%
Kagura.UseCases.KnowledgeBase.CreateTimelineEvent 100%
Kagura.UseCases.KnowledgeBase.DeleteCharacter 100% 100%
Kagura.UseCases.KnowledgeBase.DeleteLocation 100% 100%
Kagura.UseCases.KnowledgeBase.DeleteLocationVariant 100% 100%
Kagura.UseCases.KnowledgeBase.DeleteLore 100% 100%
Kagura.UseCases.KnowledgeBase.DeleteOutfit 100% 100%
Kagura.UseCases.KnowledgeBase.DeleteRelationship 100% 50%
Kagura.UseCases.KnowledgeBase.DeleteTimelineEvent 100% 50%
Kagura.UseCases.KnowledgeBase.ExpressionView 100%
Kagura.UseCases.KnowledgeBase.FindParentCandidates 100% 50%
Kagura.UseCases.KnowledgeBase.GetCharacter 100% 100%
Kagura.UseCases.KnowledgeBase.GetLocation 100% 100%
Kagura.UseCases.KnowledgeBase.GetLocationHierarchy 100%
Kagura.UseCases.KnowledgeBase.GetLocationVariant 100% 58.3%
Kagura.UseCases.KnowledgeBase.GetLore 100% 100%
Kagura.UseCases.KnowledgeBase.GetOutfit 100% 100%
Kagura.UseCases.KnowledgeBase.GetRelationshipsForCharacter 100%
Kagura.UseCases.KnowledgeBase.ListCharacterImages 100% 92.8%
Kagura.UseCases.KnowledgeBase.ListCharacters 100%
Kagura.UseCases.KnowledgeBase.ListExpressions 100% 100%
Kagura.UseCases.KnowledgeBase.ListLocationImages 100% 90%
Kagura.UseCases.KnowledgeBase.ListLocations 100%
Kagura.UseCases.KnowledgeBase.ListLocationVariants 100%
Kagura.UseCases.KnowledgeBase.ListLore 100%
Kagura.UseCases.KnowledgeBase.ListOutfits 100%
Kagura.UseCases.KnowledgeBase.ListProjectAssets 100% 100%
Kagura.UseCases.KnowledgeBase.ListRelationships 100%
Kagura.UseCases.KnowledgeBase.ListTimeline 100%
Kagura.UseCases.KnowledgeBase.LocationDto 89.4%
Kagura.UseCases.KnowledgeBase.LocationHierarchyView 100%
Kagura.UseCases.KnowledgeBase.LocationPreviewSource 100%
Kagura.UseCases.KnowledgeBase.LocationVariantDto 91.6%
Kagura.UseCases.KnowledgeBase.LocationVariantEditorView 100%
Kagura.UseCases.KnowledgeBase.LoreDto 85.7%
Kagura.UseCases.KnowledgeBase.OpenCharacterBaseSprite 88.8% 70%
Kagura.UseCases.KnowledgeBase.OpenCharacterPreview 88.8% 60%
Kagura.UseCases.KnowledgeBase.OpenExpressionSprite 92.3% 68.7%
Kagura.UseCases.KnowledgeBase.OpenLocationBackground 88.8% 70%
Kagura.UseCases.KnowledgeBase.OpenLocationPreview 88.8% 60%
Kagura.UseCases.KnowledgeBase.OpenLocationVariant 90.9% 75%
Kagura.UseCases.KnowledgeBase.OpenOutfitSprite 90.9% 75%
Kagura.UseCases.KnowledgeBase.OutfitDto 96.7%
Kagura.UseCases.KnowledgeBase.OutfitEditorView 100%
Kagura.UseCases.KnowledgeBase.PreviewSource 100%
Kagura.UseCases.KnowledgeBase.ProjectAssetView 100%
Kagura.UseCases.KnowledgeBase.RelationshipDto 88%
Kagura.UseCases.KnowledgeBase.RelationshipEndpoint 100%
Kagura.UseCases.KnowledgeBase.RemoveCharacterPreview 75% 50%
Kagura.UseCases.KnowledgeBase.RemoveExpression 100% 100%
Kagura.UseCases.KnowledgeBase.RemoveLocationPreview 75% 50%
Kagura.UseCases.KnowledgeBase.ReorderTimelineEvent 94.1% 87.5%
Kagura.UseCases.KnowledgeBase.SetCharacterPreview 80.7% 63.8%
Kagura.UseCases.KnowledgeBase.SetLocationParent 90.4% 81.2%
Kagura.UseCases.KnowledgeBase.SetLocationPreview 93.7% 85.7%
Kagura.UseCases.KnowledgeBase.SetOutfitFaceRegions 100% 50%
Kagura.UseCases.KnowledgeBase.TimelineEventDto 88.8%
Kagura.UseCases.KnowledgeBase.UpdateCharacter 100% 100%
Kagura.UseCases.KnowledgeBase.UpdateLocation 100% 100%
Kagura.UseCases.KnowledgeBase.UpdateLocationVariant 100% 100%
Kagura.UseCases.KnowledgeBase.UpdateLore 100% 100%
Kagura.UseCases.KnowledgeBase.UpdateOutfit 100% 100%
Kagura.UseCases.KnowledgeBase.UpdateRelationship 100% 50%
Kagura.UseCases.KnowledgeBase.UpdateTimelineEvent 100% 50%
Kagura.UseCases.Notifications.DomainChanged 100%
Kagura.UseCases.Projects.ClearProjectStyleReference 100% 100%
Kagura.UseCases.Projects.CreateProject 100% 100%
Kagura.UseCases.Projects.DeleteProject 100% 100%
Kagura.UseCases.Projects.GetProject 100% 100%
Kagura.UseCases.Projects.ListProjects 100%
Kagura.UseCases.Projects.OpenProjectStyleReference 100% 83.3%
Kagura.UseCases.Projects.ProjectDto 100%
Kagura.UseCases.Projects.SetProjectStageView 100% 50%
Kagura.UseCases.Projects.SetProjectStyle 100% 85%
Kagura.UseCases.Projects.SetProjectStyleReference 100% 100%
Kagura.UseCases.Projects.StyleReferenceContent 100%
Kagura.UseCases.Projects.UpdateProject 100% 100%
Kagura.UseCases.Settings.AssistantReasoningEfforts 100% 83.3%
Kagura.UseCases.Settings.CheckNovelAiToken 100% 100%
Kagura.UseCases.Settings.GenerationDefaultTagsJson 100% 100%
Kagura.UseCases.Settings.GetNovelAiSettings 100%
Kagura.UseCases.Settings.GetOpenRouterSettings 100% 100%
Kagura.UseCases.Settings.ListOpenRouterModels 100%
Kagura.UseCases.Settings.ModelReasoningSupport 100%
Kagura.UseCases.Settings.NovelAiModelOption 100%
Kagura.UseCases.Settings.NovelAiSettingsView 100%
Kagura.UseCases.Settings.OpenRouterModelOption 100%
Kagura.UseCases.Settings.OpenRouterSettingsView 100%
Kagura.UseCases.Settings.SaveGenerationDefaultTags 100%
Kagura.UseCases.Settings.SaveNovelAiModel 100%
Kagura.UseCases.Settings.SaveNovelAiToken 100% 100%
Kagura.UseCases.Settings.SaveOpenRouterKey 100% 100%
Kagura.UseCases.Settings.SaveOpenRouterModel 100%
Kagura.UseCases.Settings.SaveOpenRouterReasoningEffort 100%
Kagura.UseCases.Settings.SettingKeys 85.7% 75%
Kagura.UseCases.Tags.SimilarTag 100%
Kagura.UseCases.Tags.TagCategoryCount 100%
Kagura.UseCases.Tags.TagDetails 100%
Kagura.UseCases.Tags.TagResolution 100%
Kagura.UseCases.Tags.TagSearchFilter 100%
Kagura.UseCases.Tags.TagSuggestion 100%
Kagura.UseCases.Tags.TagSummary 83.3%
Kagura.UseCases.Tts.AudioContentTypes 62.5% 62.5%
Kagura.UseCases.Tts.CharacterVoiceConfig 100%
Kagura.UseCases.Tts.CheckTtsConnection 100% 100%
Kagura.UseCases.Tts.GeneratedAudio 100%
Kagura.UseCases.Tts.GetTtsSettings 100% 100%
Kagura.UseCases.Tts.ListTtsVoices 80% 50%
Kagura.UseCases.Tts.OpenSceneStepAudio 77.7% 50%
Kagura.UseCases.Tts.OpenVoiceClipByToken 92.3% 91.6%
Kagura.UseCases.Tts.SaveTtsProviderField 94.4% 88.8%
Kagura.UseCases.Tts.SceneStepAudioContent 100%
Kagura.UseCases.Tts.SetCharacterVoiceClip 88.8% 58.3%
Kagura.UseCases.Tts.TtsFieldView 100%
Kagura.UseCases.Tts.TtsProviderDescriptor 100%
Kagura.UseCases.Tts.TtsProviderView 100%
Kagura.UseCases.Tts.TtsSettingField 100%
Kagura.UseCases.Tts.TtsSettingsView 100%
Kagura.UseCases.Tts.TtsVoice 100%
Kagura.UseCases.Tts.TtsVoiceCapabilities 83.3%
Kagura.UseCases.Tts.TtsVoiceHandle 100%
Kagura.UseCases.Tts.VoiceReferenceClip 100%
Kagura.UseCases.VisualNovel.AddSceneStep 90% 50%
Kagura.UseCases.VisualNovel.ChapterDto 89.4%
Kagura.UseCases.VisualNovel.CreateChapter 100%
Kagura.UseCases.VisualNovel.CreateScene 100% 100%
Kagura.UseCases.VisualNovel.DeleteChapter 100% 50%
Kagura.UseCases.VisualNovel.DeleteScene 100% 50%
Kagura.UseCases.VisualNovel.DeleteSceneStep 100% 50%
Kagura.UseCases.VisualNovel.GetChapter 100% 100%
Kagura.UseCases.VisualNovel.GetPlayerScript 100% 70%
Kagura.UseCases.VisualNovel.GetScene 100% 100%
Kagura.UseCases.VisualNovel.GetSceneCast 100% 100%
Kagura.UseCases.VisualNovel.GetSceneStageOptions 100% 100%
Kagura.UseCases.VisualNovel.ListChapters 100%
Kagura.UseCases.VisualNovel.ListScenes 100%
Kagura.UseCases.VisualNovel.ListSceneSteps 100%
Kagura.UseCases.VisualNovel.PlayerSceneDto 100% 100%
Kagura.UseCases.VisualNovel.PlayerScriptDto 100%
Kagura.UseCases.VisualNovel.ReorderChapters 100%
Kagura.UseCases.VisualNovel.ReorderScenes 100%
Kagura.UseCases.VisualNovel.ReorderSceneSteps 100%
Kagura.UseCases.VisualNovel.SceneCastMember 100%
Kagura.UseCases.VisualNovel.SceneDto 96.5%
Kagura.UseCases.VisualNovel.SceneStageOptions 100%
Kagura.UseCases.VisualNovel.SceneStepDto 92.5%
Kagura.UseCases.VisualNovel.SetSceneStepStage 100% 50%
Kagura.UseCases.VisualNovel.StageBackgroundOption 100%
Kagura.UseCases.VisualNovel.StageCastOption 100%
Kagura.UseCases.VisualNovel.StageExpressionOption 100%
Kagura.UseCases.VisualNovel.StageOutfitOption 100%
Kagura.UseCases.VisualNovel.UpdateChapter 100% 50%
Kagura.UseCases.VisualNovel.UpdateScene 100% 50%
Kagura.UseCases.VisualNovel.UpdateSceneStep 100% 50%
<!-- coverage-comment --> # Summary <details open><summary>Summary</summary> ||| |:---|:---| | Generated on: | 08/04/2026 - 16:28:49 | | Coverage date: | 08/04/2026 - 16:27:42 - 08/04/2026 - 16:28:46 | | Parser: | MultiReport (3x Cobertura) | | Assemblies: | 6 | | Classes: | 1059 | | Files: | 574 | | **Line coverage:** | 96.3% (47618 of 49405) | | Covered lines: | 47618 | | Uncovered lines: | 1787 | | Coverable lines: | 49405 | | Total lines: | 76649 | | **Branch coverage:** | 77% (4975 of 6453) | | Covered branches: | 4975 | | Total branches: | 6453 | | **Method coverage:** | [Feature is only available for sponsors](https://reportgenerator.io/pro) | </details> ## Coverage <details><summary>Kagura.BlazorAdapter - 88.2%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagura.BlazorAdapter**|**88.2%**|**77.4%**| |Kagura.BlazorAdapter.Assistant.AssistantCapabilityChecked|100%|| |Kagura.BlazorAdapter.Assistant.AssistantChangeMade|100%|| |Kagura.BlazorAdapter.Assistant.AssistantConversationHydrated|100%|| |Kagura.BlazorAdapter.Assistant.AssistantEffects|62.5%|100%| |Kagura.BlazorAdapter.Assistant.AssistantFailed|100%|| |Kagura.BlazorAdapter.Assistant.AssistantNoticed|100%|| |Kagura.BlazorAdapter.Assistant.AssistantPanel|90.6%|85.8%| |Kagura.BlazorAdapter.Assistant.AssistantReducers|100%|75%| |Kagura.BlazorAdapter.Assistant.AssistantSaid|100%|| |Kagura.BlazorAdapter.Assistant.AssistantState|100%|| |Kagura.BlazorAdapter.Assistant.AssistantToolCalled|100%|| |Kagura.BlazorAdapter.Assistant.AssistantUserSaid|100%|| |Kagura.BlazorAdapter.BlazorAdapterAssembly|100%|| |Kagura.BlazorAdapter.CmField|100%|75%| |Kagura.BlazorAdapter.Connections.AddLinkModal|88.5%|81.5%| |Kagura.BlazorAdapter.Connections.ConnectionsEffects|95.4%|80%| |Kagura.BlazorAdapter.Connections.ConnectionsFailed|100%|| |Kagura.BlazorAdapter.Connections.ConnectionsLoaded|100%|| |Kagura.BlazorAdapter.Connections.ConnectionsPanel|100%|95.1%| |Kagura.BlazorAdapter.Connections.ConnectionsReducers|100%|75%| |Kagura.BlazorAdapter.Connections.ConnectionsState|90%|| |Kagura.BlazorAdapter.Connections.KindIcon|100%|| |Kagura.BlazorAdapter.Connections.LinkRequested|100%|| |Kagura.BlazorAdapter.Connections.LinkTargetsFound|100%|| |Kagura.BlazorAdapter.Connections.LoadConnections|100%|| |Kagura.BlazorAdapter.Connections.NodeKindIcons|100%|| |Kagura.BlazorAdapter.Connections.RemoveLinkRequested|100%|| |Kagura.BlazorAdapter.Connections.SearchLinkTargets|100%|| |Kagura.BlazorAdapter.Design|0%|0%| |Kagura.BlazorAdapter.Diagnostics.AppErrorBoundary|100%|| |Kagura.BlazorAdapter.Diagnostics.CircuitError|100%|| |Kagura.BlazorAdapter.Diagnostics.CircuitErrorPanel|100%|| |Kagura.BlazorAdapter.Diagnostics.CircuitErrorSink|100%|85.7%| |Kagura.BlazorAdapter.Diagnostics.KaguraStoreInitializer|92.3%|66.6%| |Kagura.BlazorAdapter.EditorComponentsDemo|0%|| |Kagura.BlazorAdapter.FileUploadDemo|0%|| |Kagura.BlazorAdapter.Generation.ActivityQueueBridge|87.5%|50%| |Kagura.BlazorAdapter.Generation.CancelActivityRequested|100%|| |Kagura.BlazorAdapter.Generation.GenerationQueueEffects|100%|| |Kagura.BlazorAdapter.Generation.GenerationQueueLoaded|100%|| |Kagura.BlazorAdapter.Generation.GenerationQueuePage|100%|100%| |Kagura.BlazorAdapter.Generation.GenerationQueueReducers|100%|| |Kagura.BlazorAdapter.Generation.GenerationQueueState|100%|| |Kagura.BlazorAdapter.Generation.GenerationStatusBar|100%|95.4%| |Kagura.BlazorAdapter.Generation.RemoveActivityRequested|100%|| |Kagura.BlazorAdapter.History.DiffValue|100%|87.5%| |Kagura.BlazorAdapter.History.DocumentHistoryEffects|90%|68.7%| |Kagura.BlazorAdapter.History.DocumentHistoryFailed|100%|| |Kagura.BlazorAdapter.History.DocumentHistoryLoaded|100%|| |Kagura.BlazorAdapter.History.DocumentHistoryPanel|79.3%|75%| |Kagura.BlazorAdapter.History.DocumentHistoryReducers|95%|83.3%| |Kagura.BlazorAdapter.History.DocumentHistoryState|100%|| |Kagura.BlazorAdapter.History.LoadDocumentHistory|100%|| |Kagura.BlazorAdapter.History.RevertCompleted|100%|| |Kagura.BlazorAdapter.History.RevertRequested|100%|| |Kagura.BlazorAdapter.History.RevisionDiffLoaded|100%|| |Kagura.BlazorAdapter.History.SelectRevision|100%|| |Kagura.BlazorAdapter.KnowledgeBase.AdoptEmotionsRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.BaseSpriteFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.BaseSpriteGenerated|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterBaseSprite|91.3%|90%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterCreated|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterDeleted|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorEffects|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorNotFound|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorPage|92.9%|81.2%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorReducers|100%|92.8%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterImagesLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterOperationFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterOutfits|94.2%|83.3%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterPreview|88.1%|91.3%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterPreviewEffects|62.9%|25%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterPreviewFailed|0%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterPreviewReducers|83.3%|50%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterPreviewSaved|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterPreviewState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterSaved|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharactersEffects|94.1%|75%| |Kagura.BlazorAdapter.KnowledgeBase.CharactersLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharactersPage|95.8%|90.9%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterSpriteEffects|86.3%|100%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterSpriteReducers|100%|75%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterSpriteState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharactersReducers|100%|87.5%| |Kagura.BlazorAdapter.KnowledgeBase.CharactersState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterTiers|100%|50%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterVoiceContextLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterVoiceEffects|77.7%|80%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterVoiceFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterVoicePanel|95.3%|81%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterVoiceReducers|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterVoicesFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterVoicesLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterVoiceState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CreateCharacterFailed|0%|| |Kagura.BlazorAdapter.KnowledgeBase.CreateCharacterRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CreateLocationFailed|0%|| |Kagura.BlazorAdapter.KnowledgeBase.CreateLocationRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CreateLocationVariantRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CreateLoreFailed|0%|| |Kagura.BlazorAdapter.KnowledgeBase.CreateLoreRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CreateOutfitRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CreateRelationshipRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CreateTimelineEventRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.DeleteCharacterRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.DeleteLocationRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.DeleteLocationVariantRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.DeleteLoreRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.DeleteOutfitRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.DeleteRelationshipRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.DeleteTimelineEventRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.ExpressionCapabilityChecked|100%|| |Kagura.BlazorAdapter.KnowledgeBase.ExpressionGenerated|100%|| |Kagura.BlazorAdapter.KnowledgeBase.ExpressionGenerationFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.ExpressionRemoved|100%|| |Kagura.BlazorAdapter.KnowledgeBase.ExpressionsEffects|87.9%|69.2%| |Kagura.BlazorAdapter.KnowledgeBase.ExpressionsFailed|0%|| |Kagura.BlazorAdapter.KnowledgeBase.ExpressionsLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.ExpressionsReducers|85.7%|43.7%| |Kagura.BlazorAdapter.KnowledgeBase.ExpressionsState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.GenerateAllExpressions|100%|| |Kagura.BlazorAdapter.KnowledgeBase.GenerateBaseSprite|100%|| |Kagura.BlazorAdapter.KnowledgeBase.GenerateExpression|100%|| |Kagura.BlazorAdapter.KnowledgeBase.GenerateLocationBackground|100%|| |Kagura.BlazorAdapter.KnowledgeBase.GenerateLocationVariantImage|100%|| |Kagura.BlazorAdapter.KnowledgeBase.GenerateOutfitSprite|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LabeledEntryMapping|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadCharacter|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadCharacterImages|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadCharacters|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadCharacterVoiceContext|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadCharacterVoices|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadExpressions|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadLocation|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadLocationHierarchy|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadLocationImages|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadLocations|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadLocationVariant|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadLocationVariants|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadLore|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadLoreEntry|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadOutfit|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadOutfits|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadRelationshipCast|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadRelationships|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadTimeline|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationBackground|91.3%|90%| |Kagura.BlazorAdapter.KnowledgeBase.LocationBackgroundCapabilityChecked|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationBackgroundEffects|86.3%|100%| |Kagura.BlazorAdapter.KnowledgeBase.LocationBackgroundFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationBackgroundGenerated|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationBackgroundReducers|100%|75%| |Kagura.BlazorAdapter.KnowledgeBase.LocationBackgroundState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationCreated|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationDeleted|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationEditorEffects|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.LocationEditorLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationEditorNotFound|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationEditorPage|88.6%|75%| |Kagura.BlazorAdapter.KnowledgeBase.LocationEditorReducers|86.9%|71.4%| |Kagura.BlazorAdapter.KnowledgeBase.LocationEditorState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyEffects|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyReducers|100%|75%| |Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyState|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.LocationImagesLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationOperationFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationPreview|91%|88.6%| |Kagura.BlazorAdapter.KnowledgeBase.LocationPreviewEffects|62.9%|25%| |Kagura.BlazorAdapter.KnowledgeBase.LocationPreviewFailed|0%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationPreviewReducers|83.3%|50%| |Kagura.BlazorAdapter.KnowledgeBase.LocationPreviewSaved|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationPreviewState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationSaved|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationsEffects|94.1%|75%| |Kagura.BlazorAdapter.KnowledgeBase.LocationsLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationsPage|95.4%|95.4%| |Kagura.BlazorAdapter.KnowledgeBase.LocationsReducers|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.LocationsState|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantEditorEffects|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantEditorFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantEditorLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantEditorNotFound|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantEditorPage|88.8%|74%| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantEditorReducers|100%|93.7%| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantEditorSaved|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantEditorState|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantImage|93.1%|91.6%| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantImageCapabilityChecked|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantImageEffects|86.3%|100%| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantImageFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantImageGenerated|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantImageReducers|100%|75%| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantImageState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariants|94.2%|79.1%| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantsEffects|96.4%|83.3%| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantsFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantsLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantsReducers|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.LocationVariantsState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoreCategories|100%|50%| |Kagura.BlazorAdapter.KnowledgeBase.LoreCreated|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoreDeleted|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoreEditorEffects|96.6%|87.5%| |Kagura.BlazorAdapter.KnowledgeBase.LoreEditorLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoreEditorNotFound|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoreEditorPage|90.8%|75%| |Kagura.BlazorAdapter.KnowledgeBase.LoreEditorReducers|86.9%|71.4%| |Kagura.BlazorAdapter.KnowledgeBase.LoreEditorState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoreEffects|94.1%|75%| |Kagura.BlazorAdapter.KnowledgeBase.LoreLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoreOperationFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LorePage|80%|78.5%| |Kagura.BlazorAdapter.KnowledgeBase.LoreReducers|90.9%|87.5%| |Kagura.BlazorAdapter.KnowledgeBase.LoreSaved|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoreState|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.NewTimelineEvent|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorEffects|96.4%|87.5%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorNotFound|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorPage|92.3%|75%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorReducers|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorSaved|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorState|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitExpressions|95.5%|92.8%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitFaceRegion|88.7%|70.2%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitsEffects|96.4%|83.3%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitsFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitsLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitSprite|92.5%|91.6%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteCapabilityChecked|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteEffects|86.3%|100%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteGenerated|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteReducers|100%|75%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitsReducers|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitsState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.ParentCandidatesFound|100%|| |Kagura.BlazorAdapter.KnowledgeBase.ParentPickerModal|84.6%|89.2%| |Kagura.BlazorAdapter.KnowledgeBase.PositioningPanel|100%|95.4%| |Kagura.BlazorAdapter.KnowledgeBase.PreviewVoiceRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipCard|77.5%|63.3%| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipCastLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipList|97.3%|88.4%| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipModal|94.1%|94.7%| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipsEffects|92.8%|77.7%| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipsFailed|0%|| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipsLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipsPage|92.8%|87.5%| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipsReducers|94.7%|75%| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipsState|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.RemoveCharacterPreviewRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.RemoveExpressionRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.RemoveLocationPreviewRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.ReorderTimelineEventRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SaveCharacterRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SaveFaceRegionsRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SaveLocationRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SaveLocationVariantRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SaveLoreRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SaveOutfitRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SearchParentCandidates|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SetCharacterPreviewRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SetCharactersFilter|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SetCharactersTier|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SetLocationPreviewRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SetLocationsFilter|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SetLoreCategory|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SetLoreFilter|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SetParentRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SetRelationshipsFilter|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SpriteCapabilityChecked|100%|| |Kagura.BlazorAdapter.KnowledgeBase.StyleReferenceControls|100%|78.5%| |Kagura.BlazorAdapter.KnowledgeBase.TimelineEffects|93.5%|70%| |Kagura.BlazorAdapter.KnowledgeBase.TimelineEventCard|92.5%|80%| |Kagura.BlazorAdapter.KnowledgeBase.TimelineEventEdit|100%|| |Kagura.BlazorAdapter.KnowledgeBase.TimelineFailed|0%|| |Kagura.BlazorAdapter.KnowledgeBase.TimelineLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.TimelinePage|95.8%|90%| |Kagura.BlazorAdapter.KnowledgeBase.TimelineReducers|91.6%|75%| |Kagura.BlazorAdapter.KnowledgeBase.TimelineSection|96.6%|91.6%| |Kagura.BlazorAdapter.KnowledgeBase.TimelineState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.UpdateRelationshipRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.UpdateTimelineEventRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.UploadVoiceClipRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.VoiceClipSaved|100%|| |Kagura.BlazorAdapter.Notifications.DomainChangedBridge|88.8%|58.3%| |Kagura.BlazorAdapter.Notifications.DomainChangesReceived|100%|100%| |Kagura.BlazorAdapter.OverlayDemo|0%|0%| |Kagura.BlazorAdapter.Projects.AssistantMemoryFailed|0%|| |Kagura.BlazorAdapter.Projects.AssistantMemorySaved|0%|| |Kagura.BlazorAdapter.Projects.ClearStyleReferenceRequested|100%|| |Kagura.BlazorAdapter.Projects.CreateProjectRequested|100%|| |Kagura.BlazorAdapter.Projects.DeleteProjectRequested|100%|| |Kagura.BlazorAdapter.Projects.LoadProjectAssets|100%|| |Kagura.BlazorAdapter.Projects.LoadWorkspace|100%|| |Kagura.BlazorAdapter.Projects.ProjectAssetsEffects|100%|| |Kagura.BlazorAdapter.Projects.ProjectAssetsFailed|100%|| |Kagura.BlazorAdapter.Projects.ProjectAssetsLoaded|100%|| |Kagura.BlazorAdapter.Projects.ProjectAssetsPage|94.2%|85.7%| |Kagura.BlazorAdapter.Projects.ProjectAssetsReducers|100%|100%| |Kagura.BlazorAdapter.Projects.ProjectAssetsState|100%|| |Kagura.BlazorAdapter.Projects.ProjectCreated|100%|| |Kagura.BlazorAdapter.Projects.ProjectCreateFailed|100%|| |Kagura.BlazorAdapter.Projects.ProjectDeleted|100%|| |Kagura.BlazorAdapter.Projects.ProjectSaved|100%|| |Kagura.BlazorAdapter.Projects.ProjectSaveFailed|100%|| |Kagura.BlazorAdapter.Projects.ProjectsEffects|100%|100%| |Kagura.BlazorAdapter.Projects.ProjectsLoaded|100%|| |Kagura.BlazorAdapter.Projects.ProjectsPage|94.7%|100%| |Kagura.BlazorAdapter.Projects.ProjectsReducers|100%|100%| |Kagura.BlazorAdapter.Projects.ProjectsState|100%|100%| |Kagura.BlazorAdapter.Projects.ProjectWorkspacePage|70.5%|63.8%| |Kagura.BlazorAdapter.Projects.SaveAssistantMemoryRequested|0%|| |Kagura.BlazorAdapter.Projects.SaveProjectRequested|100%|| |Kagura.BlazorAdapter.Projects.SetProjectsFilter|100%|| |Kagura.BlazorAdapter.Projects.SetStageViewRequested|100%|| |Kagura.BlazorAdapter.Projects.SetStyleReferenceRequested|100%|| |Kagura.BlazorAdapter.Projects.SetStyleRequested|100%|| |Kagura.BlazorAdapter.Projects.StyleReferenceChanged|100%|| |Kagura.BlazorAdapter.Projects.StyleReferenceFailed|100%|| |Kagura.BlazorAdapter.Projects.WorkspaceCrumb|100%|| |Kagura.BlazorAdapter.Projects.WorkspaceEffects|82.3%|70.5%| |Kagura.BlazorAdapter.Projects.WorkspaceLoaded|100%|| |Kagura.BlazorAdapter.Projects.WorkspaceReducers|80%|| |Kagura.BlazorAdapter.Projects.WorkspaceShell|100%|95%| |Kagura.BlazorAdapter.Projects.WorkspaceState|100%|| |Kagura.BlazorAdapter.QuicklinkDemo|0%|| |Kagura.BlazorAdapter.RegionSelectorDemo|0%|0%| |Kagura.BlazorAdapter.SelectDemo|0%|| |Kagura.BlazorAdapter.Settings.AssistantSkillsEffects|13.3%|0%| |Kagura.BlazorAdapter.Settings.AssistantSkillsFailed|0%|| |Kagura.BlazorAdapter.Settings.AssistantSkillsLoaded|100%|| |Kagura.BlazorAdapter.Settings.AssistantSkillsReducers|28.5%|| |Kagura.BlazorAdapter.Settings.AssistantSkillsSection|32.4%|11.1%| |Kagura.BlazorAdapter.Settings.AssistantSkillsState|100%|| |Kagura.BlazorAdapter.Settings.CheckTtsConnectionRequested|100%|| |Kagura.BlazorAdapter.Settings.CreateEmotionRequested|100%|| |Kagura.BlazorAdapter.Settings.CreateSkillRequested|0%|| |Kagura.BlazorAdapter.Settings.CreatorProfileFailed|0%|| |Kagura.BlazorAdapter.Settings.CreatorProfileSaved|0%|| |Kagura.BlazorAdapter.Settings.DeleteEmotionRequested|100%|| |Kagura.BlazorAdapter.Settings.EditSkillRequested|0%|| |Kagura.BlazorAdapter.Settings.EmotionCreated|100%|| |Kagura.BlazorAdapter.Settings.EmotionLibraryEffects|71.4%|37.5%| |Kagura.BlazorAdapter.Settings.EmotionLibraryFailed|0%|| |Kagura.BlazorAdapter.Settings.EmotionLibraryLoaded|100%|| |Kagura.BlazorAdapter.Settings.EmotionLibraryReducers|96.5%|50%| |Kagura.BlazorAdapter.Settings.EmotionLibrarySection|90.1%|80.7%| |Kagura.BlazorAdapter.Settings.EmotionLibraryState|100%|| |Kagura.BlazorAdapter.Settings.NovelAiSettingsEffects|68.8%|50%| |Kagura.BlazorAdapter.Settings.NovelAiSettingsFailed|100%|| |Kagura.BlazorAdapter.Settings.NovelAiSettingsLoaded|100%|| |Kagura.BlazorAdapter.Settings.NovelAiSettingsReducers|90.9%|25%| |Kagura.BlazorAdapter.Settings.NovelAiSettingsSection|94.1%|91.6%| |Kagura.BlazorAdapter.Settings.NovelAiSettingsState|100%|| |Kagura.BlazorAdapter.Settings.NovelAiTokenChecked|100%|| |Kagura.BlazorAdapter.Settings.OpenRouterModelsFailed|0%|| |Kagura.BlazorAdapter.Settings.OpenRouterModelsLoaded|100%|| |Kagura.BlazorAdapter.Settings.OpenRouterSettingsEffects|46.7%|27.7%| |Kagura.BlazorAdapter.Settings.OpenRouterSettingsFailed|0%|| |Kagura.BlazorAdapter.Settings.OpenRouterSettingsLoaded|100%|| |Kagura.BlazorAdapter.Settings.OpenRouterSettingsReducers|77.2%|| |Kagura.BlazorAdapter.Settings.OpenRouterSettingsSection|91.1%|92.1%| |Kagura.BlazorAdapter.Settings.OpenRouterSettingsState|100%|| |Kagura.BlazorAdapter.Settings.SaveCreatorProfileRequested|0%|| |Kagura.BlazorAdapter.Settings.SaveDefaultTagsRequested|100%|| |Kagura.BlazorAdapter.Settings.SaveEmotionRequested|100%|| |Kagura.BlazorAdapter.Settings.SaveNovelAiModelRequested|100%|| |Kagura.BlazorAdapter.Settings.SaveNovelAiTokenRequested|100%|| |Kagura.BlazorAdapter.Settings.SaveOpenRouterDescriberModelRequested|100%|| |Kagura.BlazorAdapter.Settings.SaveOpenRouterKeyRequested|100%|| |Kagura.BlazorAdapter.Settings.SaveOpenRouterModelRequested|100%|| |Kagura.BlazorAdapter.Settings.SaveOpenRouterReasoningEffortRequested|100%|| |Kagura.BlazorAdapter.Settings.SaveTtsFieldRequested|100%|| |Kagura.BlazorAdapter.Settings.SelectEmotion|100%|| |Kagura.BlazorAdapter.Settings.SetSkillPinnedRequested|0%|| |Kagura.BlazorAdapter.Settings.SetSkillStateRequested|0%|| |Kagura.BlazorAdapter.Settings.TokenVerdict|100%|| |Kagura.BlazorAdapter.Settings.TtsConnectionChecked|100%|| |Kagura.BlazorAdapter.Settings.TtsFieldSaved|100%|| |Kagura.BlazorAdapter.Settings.TtsSettingsEffects|73.5%|50%| |Kagura.BlazorAdapter.Settings.TtsSettingsFailed|100%|| |Kagura.BlazorAdapter.Settings.TtsSettingsLoaded|100%|| |Kagura.BlazorAdapter.Settings.TtsSettingsReducers|100%|100%| |Kagura.BlazorAdapter.Settings.TtsSettingsSection|77.9%|72.2%| |Kagura.BlazorAdapter.Settings.TtsSettingsState|100%|| |Kagura.BlazorAdapter.Settings.TtsVerdict|100%|| |Kagura.BlazorAdapter.SliderDemo|0%|0%| |Kagura.BlazorAdapter.Tags.ForgetTagAuthoringInstance|100%|| |Kagura.BlazorAdapter.Tags.PromptTagEditing|100%|76.3%| |Kagura.BlazorAdapter.Tags.RequestSuggestions|100%|| |Kagura.BlazorAdapter.Tags.SearchTags|100%|| |Kagura.BlazorAdapter.Tags.SuggestionsReceived|100%|| |Kagura.BlazorAdapter.Tags.TagAuthoring|95.5%|78.8%| |Kagura.BlazorAdapter.Tags.TagAuthoringEffects|100%|100%| |Kagura.BlazorAdapter.Tags.TagAuthoringInstance|100%|| |Kagura.BlazorAdapter.Tags.TagAuthoringPage|0%|| |Kagura.BlazorAdapter.Tags.TagAuthoringReducers|100%|100%| |Kagura.BlazorAdapter.Tags.TagAuthoringState|100%|100%| |Kagura.BlazorAdapter.Tags.TagDatabaseChecked|100%|| |Kagura.BlazorAdapter.Tags.TagsSearched|100%|| |Kagura.BlazorAdapter.ToggleGroupDemo|0%|0%| |Kagura.BlazorAdapter.VisualNovel.AddSceneCastRequested|100%|| |Kagura.BlazorAdapter.VisualNovel.AddSceneStepRequested|100%|| |Kagura.BlazorAdapter.VisualNovel.ChapterCreated|100%|| |Kagura.BlazorAdapter.VisualNovel.ChapterEditorDeleted|100%|| |Kagura.BlazorAdapter.VisualNovel.ChapterEditorEffects|90%|56.2%| |Kagura.BlazorAdapter.VisualNovel.ChapterEditorLoaded|100%|| |Kagura.BlazorAdapter.VisualNovel.ChapterEditorNotFound|100%|| |Kagura.BlazorAdapter.VisualNovel.ChapterEditorPage|84.9%|70.4%| |Kagura.BlazorAdapter.VisualNovel.ChapterEditorReducers|86.9%|42.8%| |Kagura.BlazorAdapter.VisualNovel.ChapterEditorSaved|100%|| |Kagura.BlazorAdapter.VisualNovel.ChapterEditorState|100%|| |Kagura.BlazorAdapter.VisualNovel.ChapterOperationFailed|0%|| |Kagura.BlazorAdapter.VisualNovel.ChapterScenes|78.2%|65%| |Kagura.BlazorAdapter.VisualNovel.ChaptersEffects|88.8%|64.2%| |Kagura.BlazorAdapter.VisualNovel.ChaptersFailed|100%|| |Kagura.BlazorAdapter.VisualNovel.ChaptersLoaded|100%|| |Kagura.BlazorAdapter.VisualNovel.ChaptersPage|90.9%|90.9%| |Kagura.BlazorAdapter.VisualNovel.ChaptersReducers|91.6%|100%| |Kagura.BlazorAdapter.VisualNovel.ChaptersState|100%|| |Kagura.BlazorAdapter.VisualNovel.CreateChapterFailed|0%|| |Kagura.BlazorAdapter.VisualNovel.CreateChapterRequested|100%|| |Kagura.BlazorAdapter.VisualNovel.CreateSceneFailed|0%|| |Kagura.BlazorAdapter.VisualNovel.CreateSceneRequested|100%|| |Kagura.BlazorAdapter.VisualNovel.DeleteChapterRequested|100%|| |Kagura.BlazorAdapter.VisualNovel.DeleteSceneRequested|100%|| |Kagura.BlazorAdapter.VisualNovel.DeleteSceneStepRequested|100%|| |Kagura.BlazorAdapter.VisualNovel.GenerateStepAudioRequested|100%|| |Kagura.BlazorAdapter.VisualNovel.LoadChapter|100%|| |Kagura.BlazorAdapter.VisualNovel.LoadChapters|100%|| |Kagura.BlazorAdapter.VisualNovel.LoadPlayer|100%|| |Kagura.BlazorAdapter.VisualNovel.LoadScene|100%|| |Kagura.BlazorAdapter.VisualNovel.LoadScenes|100%|| |Kagura.BlazorAdapter.VisualNovel.LoadSceneSteps|100%|| |Kagura.BlazorAdapter.VisualNovel.PlayerEffects|100%|83.3%| |Kagura.BlazorAdapter.VisualNovel.PlayerLoaded|100%|| |Kagura.BlazorAdapter.VisualNovel.PlayerPage|100%|78.2%| |Kagura.BlazorAdapter.VisualNovel.PlayerReducers|100%|100%| |Kagura.BlazorAdapter.VisualNovel.PlayerStage|98.2%|70.9%| |Kagura.BlazorAdapter.VisualNovel.PlayerState|100%|83.3%| |Kagura.BlazorAdapter.VisualNovel.RemoveSceneCastRequested|100%|| |Kagura.BlazorAdapter.VisualNovel.ReorderChaptersRequested|100%|| |Kagura.BlazorAdapter.VisualNovel.ReorderScenesRequested|0%|| |Kagura.BlazorAdapter.VisualNovel.ReorderSceneStepsRequested|100%|| |Kagura.BlazorAdapter.VisualNovel.SaveChapterRequested|100%|| |Kagura.BlazorAdapter.VisualNovel.SaveSceneRequested|100%|| |Kagura.BlazorAdapter.VisualNovel.SceneCast|100%|76.9%| |Kagura.BlazorAdapter.VisualNovel.SceneCastAdded|100%|| |Kagura.BlazorAdapter.VisualNovel.SceneCastRemoved|100%|| |Kagura.BlazorAdapter.VisualNovel.SceneCreated|100%|| |Kagura.BlazorAdapter.VisualNovel.SceneEditorDeleted|100%|| |Kagura.BlazorAdapter.VisualNovel.SceneEditorEffects|92.1%|55.5%| |Kagura.BlazorAdapter.VisualNovel.SceneEditorLoaded|100%|| |Kagura.BlazorAdapter.VisualNovel.SceneEditorNotFound|100%|| |Kagura.BlazorAdapter.VisualNovel.SceneEditorPage|87.9%|71.2%| |Kagura.BlazorAdapter.VisualNovel.SceneEditorReducers|88.4%|42.8%| |Kagura.BlazorAdapter.VisualNovel.SceneEditorSaved|100%|| |Kagura.BlazorAdapter.VisualNovel.SceneEditorState|100%|| |Kagura.BlazorAdapter.VisualNovel.SceneLineRow|88.5%|84.7%| |Kagura.BlazorAdapter.VisualNovel.SceneLineStage|83.2%|71.4%| |Kagura.BlazorAdapter.VisualNovel.SceneOperationFailed|0%|| |Kagura.BlazorAdapter.VisualNovel.SceneScript|91.4%|86.3%| |Kagura.BlazorAdapter.VisualNovel.ScenesEffects|64.2%|35.7%| |Kagura.BlazorAdapter.VisualNovel.ScenesFailed|100%|| |Kagura.BlazorAdapter.VisualNovel.ScenesLoaded|100%|| |Kagura.BlazorAdapter.VisualNovel.ScenesReducers|76.9%|83.3%| |Kagura.BlazorAdapter.VisualNovel.ScenesState|100%|100%| |Kagura.BlazorAdapter.VisualNovel.SceneStatuses|100%|50%| |Kagura.BlazorAdapter.VisualNovel.SceneStepAdded|100%|| |Kagura.BlazorAdapter.VisualNovel.SceneStepDeleted|100%|| |Kagura.BlazorAdapter.VisualNovel.SceneStepSaved|100%|| |Kagura.BlazorAdapter.VisualNovel.SceneStepsEffects|81.3%|62.9%| |Kagura.BlazorAdapter.VisualNovel.SceneStepsFailed|100%|| |Kagura.BlazorAdapter.VisualNovel.SceneStepsLoaded|100%|| |Kagura.BlazorAdapter.VisualNovel.SceneStepsReducers|97.2%|75%| |Kagura.BlazorAdapter.VisualNovel.SceneStepsState|100%|50%| |Kagura.BlazorAdapter.VisualNovel.SetScenesStatus|100%|| |Kagura.BlazorAdapter.VisualNovel.SetSceneStepStageRequested|100%|| |Kagura.BlazorAdapter.VisualNovel.StepAudioFailed|100%|| |Kagura.BlazorAdapter.VisualNovel.StepAudioFinished|100%|| |Kagura.BlazorAdapter.VisualNovel.StepAudioState|100%|| |Kagura.BlazorAdapter.VisualNovel.UpdateSceneStepRequested|100%|| </details> <details><summary>Kagura.Domain - 96.4%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagura.Domain**|**96.4%**|**91.9%**| |Kagura.Domain.Assistant.Skill|100%|90%| |Kagura.Domain.Graph.Entry|100%|100%| |Kagura.Domain.Graph.Link|100%|100%| |Kagura.Domain.Graph.LinkRole|100%|100%| |Kagura.Domain.Graph.LinkRoles|100%|| |Kagura.Domain.Graph.StructuralRef|100%|100%| |Kagura.Domain.Graph.StructuralRefs|100%|100%| |Kagura.Domain.Journal.ChangeLogEntry|100%|| |Kagura.Domain.KnowledgeBase.BodyTypes|100%|100%| |Kagura.Domain.KnowledgeBase.Character|97.1%|100%| |Kagura.Domain.KnowledgeBase.CharacterProfile|100%|| |Kagura.Domain.KnowledgeBase.CharacterVoice|100%|| |Kagura.Domain.KnowledgeBase.CupSizes|100%|100%| |Kagura.Domain.KnowledgeBase.CuratedTag|100%|| |Kagura.Domain.KnowledgeBase.Emotion|87.8%|66.6%| |Kagura.Domain.KnowledgeBase.EmotionProfile|50%|| |Kagura.Domain.KnowledgeBase.Expression|87%|| |Kagura.Domain.KnowledgeBase.ImageRegion|90%|100%| |Kagura.Domain.KnowledgeBase.LabeledEntry|100%|| |Kagura.Domain.KnowledgeBase.Location|92.3%|100%| |Kagura.Domain.KnowledgeBase.LocationProfile|100%|| |Kagura.Domain.KnowledgeBase.LocationVariant|92.5%|66.6%| |Kagura.Domain.KnowledgeBase.LocationVariantProfile|100%|| |Kagura.Domain.KnowledgeBase.LoreEntry|100%|| |Kagura.Domain.KnowledgeBase.LoreProfile|100%|| |Kagura.Domain.KnowledgeBase.Outfit|93.4%|80%| |Kagura.Domain.KnowledgeBase.OutfitProfile|100%|| |Kagura.Domain.KnowledgeBase.PromptTag|42.8%|100%| |Kagura.Domain.KnowledgeBase.Relationship|91.8%|100%| |Kagura.Domain.KnowledgeBase.RelationshipProfile|100%|| |Kagura.Domain.KnowledgeBase.RelationshipSecret|100%|75%| |Kagura.Domain.KnowledgeBase.SpriteFramings|100%|100%| |Kagura.Domain.KnowledgeBase.StyleReferenceTuning|100%|| |Kagura.Domain.KnowledgeBase.TimelineEvent|100%|100%| |Kagura.Domain.Projects.Project|100%|90%| |Kagura.Domain.Projects.Slug|100%|100%| |Kagura.Domain.Settings.AppSetting|100%|| |Kagura.Domain.VisualNovel.Chapter|100%|100%| |Kagura.Domain.VisualNovel.ChapterProfile|80%|| |Kagura.Domain.VisualNovel.EffectiveStage|100%|| |Kagura.Domain.VisualNovel.PlayerFrame|100%|| |Kagura.Domain.VisualNovel.PlayerSceneScript|100%|| |Kagura.Domain.VisualNovel.PlayerStep|100%|| |Kagura.Domain.VisualNovel.Scene|96.1%|83.3%| |Kagura.Domain.VisualNovel.ScenePlayback|100%|100%| |Kagura.Domain.VisualNovel.SceneProfile|100%|| |Kagura.Domain.VisualNovel.SceneStageProjection|100%|96.4%| |Kagura.Domain.VisualNovel.SceneStep|100%|100%| |Kagura.Domain.VisualNovel.SpriteLayout|100%|| |Kagura.Domain.VisualNovel.StageBackgroundChange|100%|| |Kagura.Domain.VisualNovel.StageCharacterChange|100%|| |Kagura.Domain.VisualNovel.StageCharacterState|100%|| |Kagura.Domain.VisualNovel.StageProjection|100%|100%| |Kagura.Domain.VisualNovel.StageStepChanges|100%|| |Kagura.Domain.VisualNovel.StageView|100%|| |System.Text.RegularExpressions.Generated|90.2%|72.2%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>FE06CC341D340484<br/>D04ADFED3A21D401C2764A1D17367E35BEB556CBB3B4B0B74__NonSlugChars_0|89.4%|75%| </details> <details><summary>Kagura.Infrastructure - 97.9%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagura.Infrastructure**|**97.9%**|**73.3%**| |Kagura.Infrastructure.Assistant.AssistantContextResolver|94.1%|68.8%| |Kagura.Infrastructure.Assistant.AssistantMutationTool`1|100%|87.5%| |Kagura.Infrastructure.Assistant.AssistantTool`1|100%|100%| |Kagura.Infrastructure.Assistant.AssistantToolContext|100%|| |Kagura.Infrastructure.Assistant.ChatSession|88.1%|46.1%| |Kagura.Infrastructure.Assistant.DelegateProgress`1|100%|| |Kagura.Infrastructure.Assistant.EfSkillStore|100%|| |Kagura.Infrastructure.Assistant.InMemoryConversationStore|100%|87.5%| |Kagura.Infrastructure.Assistant.ResolvedContext|100%|| |Kagura.Infrastructure.Assistant.Tools.BodyAttributeParams|100%|100%| |Kagura.Infrastructure.Assistant.Tools.CharacterTiers|100%|100%| |Kagura.Infrastructure.Assistant.Tools.CreateChapterParams|100%|| |Kagura.Infrastructure.Assistant.Tools.CreateChapterTool|93.3%|| |Kagura.Infrastructure.Assistant.Tools.CreateCharacterParams|100%|| |Kagura.Infrastructure.Assistant.Tools.CreateCharacterTool|96.7%|| |Kagura.Infrastructure.Assistant.Tools.CreateLocationParams|100%|| |Kagura.Infrastructure.Assistant.Tools.CreateLocationTool|93.6%|| |Kagura.Infrastructure.Assistant.Tools.CreateLocationVariantParams|100%|| |Kagura.Infrastructure.Assistant.Tools.CreateLocationVariantTool|92.8%|| |Kagura.Infrastructure.Assistant.Tools.CreateLoreParams|100%|| |Kagura.Infrastructure.Assistant.Tools.CreateLoreTool|94.5%|100%| |Kagura.Infrastructure.Assistant.Tools.CreateOutfitParams|100%|| |Kagura.Infrastructure.Assistant.Tools.CreateOutfitTool|94.7%|| |Kagura.Infrastructure.Assistant.Tools.CreateRelationshipParams|100%|| |Kagura.Infrastructure.Assistant.Tools.CreateRelationshipTool|94.2%|| |Kagura.Infrastructure.Assistant.Tools.CreateSceneParams|100%|| |Kagura.Infrastructure.Assistant.Tools.CreateSceneTool|93.9%|| |Kagura.Infrastructure.Assistant.Tools.CreateTimelineEventParams|100%|| |Kagura.Infrastructure.Assistant.Tools.CreateTimelineEventTool|95.8%|| |Kagura.Infrastructure.Assistant.Tools.DeleteChapterParams|100%|| |Kagura.Infrastructure.Assistant.Tools.DeleteChapterTool|95.2%|| |Kagura.Infrastructure.Assistant.Tools.DeleteCharacterParams|100%|| |Kagura.Infrastructure.Assistant.Tools.DeleteCharacterTool|95.2%|| |Kagura.Infrastructure.Assistant.Tools.DeleteLocationParams|100%|| |Kagura.Infrastructure.Assistant.Tools.DeleteLocationTool|95.2%|| |Kagura.Infrastructure.Assistant.Tools.DeleteLocationVariantParams|100%|| |Kagura.Infrastructure.Assistant.Tools.DeleteLocationVariantTool|95.6%|| |Kagura.Infrastructure.Assistant.Tools.DeleteLoreParams|100%|| |Kagura.Infrastructure.Assistant.Tools.DeleteLoreTool|95.2%|| |Kagura.Infrastructure.Assistant.Tools.DeleteOutfitParams|100%|| |Kagura.Infrastructure.Assistant.Tools.DeleteOutfitTool|95.6%|| |Kagura.Infrastructure.Assistant.Tools.DeleteRelationshipParams|100%|| |Kagura.Infrastructure.Assistant.Tools.DeleteRelationshipTool|100%|| |Kagura.Infrastructure.Assistant.Tools.DeleteSceneLineParams|100%|| |Kagura.Infrastructure.Assistant.Tools.DeleteSceneLineTool|100%|| |Kagura.Infrastructure.Assistant.Tools.DeleteSceneParams|100%|| |Kagura.Infrastructure.Assistant.Tools.DeleteSceneTool|95.2%|| |Kagura.Infrastructure.Assistant.Tools.DeleteTimelineEventParams|100%|| |Kagura.Infrastructure.Assistant.Tools.DeleteTimelineEventTool|100%|| |Kagura.Infrastructure.Assistant.Tools.EntryParam|100%|100%| |Kagura.Infrastructure.Assistant.Tools.FindSimilarTagsParams|100%|| |Kagura.Infrastructure.Assistant.Tools.FindSimilarTagsTool|93.3%|| |Kagura.Infrastructure.Assistant.Tools.GenerateCharacterSpriteParams|100%|| |Kagura.Infrastructure.Assistant.Tools.GenerateCharacterSpriteTool|96.6%|| |Kagura.Infrastructure.Assistant.Tools.GenerateExpressionSpritesParams|100%|| |Kagura.Infrastructure.Assistant.Tools.GenerateExpressionSpritesTool|86.8%|50%| |Kagura.Infrastructure.Assistant.Tools.GenerateLocationBackgroundParams|100%|| |Kagura.Infrastructure.Assistant.Tools.GenerateLocationBackgroundTool|93.3%|| |Kagura.Infrastructure.Assistant.Tools.GenerateOutfitSpriteParams|100%|| |Kagura.Infrastructure.Assistant.Tools.GenerateOutfitSpriteTool|73.3%|| |Kagura.Infrastructure.Assistant.Tools.GenerateVariantBackgroundParams|100%|| |Kagura.Infrastructure.Assistant.Tools.GenerateVariantBackgroundTool|94.1%|| |Kagura.Infrastructure.Assistant.Tools.GenerationLaunch|90.6%|62.5%| |Kagura.Infrastructure.Assistant.Tools.GetChapterParams|100%|| |Kagura.Infrastructure.Assistant.Tools.GetChapterTool|97%|| |Kagura.Infrastructure.Assistant.Tools.GetCharacterParams|100%|| |Kagura.Infrastructure.Assistant.Tools.GetCharacterTool|98.3%|50%| |Kagura.Infrastructure.Assistant.Tools.GetConnectionsParams|100%|| |Kagura.Infrastructure.Assistant.Tools.GetConnectionsTool|96.6%|| |Kagura.Infrastructure.Assistant.Tools.GetGenerationQueueTool|100%|50%| |Kagura.Infrastructure.Assistant.Tools.GetLocationParams|100%|| |Kagura.Infrastructure.Assistant.Tools.GetLocationTool|97.3%|| |Kagura.Infrastructure.Assistant.Tools.GetLocationVariantParams|100%|| |Kagura.Infrastructure.Assistant.Tools.GetLocationVariantTool|100%|| |Kagura.Infrastructure.Assistant.Tools.GetLoreParams|100%|| |Kagura.Infrastructure.Assistant.Tools.GetLoreTool|96.2%|| |Kagura.Infrastructure.Assistant.Tools.GetOutfitParams|100%|| |Kagura.Infrastructure.Assistant.Tools.GetOutfitTool|100%|50%| |Kagura.Infrastructure.Assistant.Tools.GetProjectOverviewTool|97.7%|| |Kagura.Infrastructure.Assistant.Tools.GetSceneParams|100%|| |Kagura.Infrastructure.Assistant.Tools.GetSceneStageOptionsTool|100%|| |Kagura.Infrastructure.Assistant.Tools.GetSceneTool|98%|100%| |Kagura.Infrastructure.Assistant.Tools.GetTimelineTool|100%|| |Kagura.Infrastructure.Assistant.Tools.LinkRecordsParams|100%|| |Kagura.Infrastructure.Assistant.Tools.LinkRecordsTool|97.1%|| |Kagura.Infrastructure.Assistant.Tools.ListChaptersTool|100%|| |Kagura.Infrastructure.Assistant.Tools.ListCharactersTool|100%|| |Kagura.Infrastructure.Assistant.Tools.ListLocationsTool|100%|| |Kagura.Infrastructure.Assistant.Tools.ListLoreTool|100%|| |Kagura.Infrastructure.Assistant.Tools.ListRelationshipsTool|100%|100%| |Kagura.Infrastructure.Assistant.Tools.ManageSkillParams|100%|| |Kagura.Infrastructure.Assistant.Tools.ManageSkillTool|92.7%|100%| |Kagura.Infrastructure.Assistant.Tools.MemoryOperationParam|100%|| |Kagura.Infrastructure.Assistant.Tools.MemoryParams|100%|| |Kagura.Infrastructure.Assistant.Tools.MemoryTool|91.8%|76.6%| |Kagura.Infrastructure.Assistant.Tools.MoveSceneLineParams|100%|| |Kagura.Infrastructure.Assistant.Tools.MoveSceneLineTool|87.8%|| |Kagura.Infrastructure.Assistant.Tools.NavigateToParams|100%|| |Kagura.Infrastructure.Assistant.Tools.NavigateToTool|80%|50%| |Kagura.Infrastructure.Assistant.Tools.RedoTool|93.7%|| |Kagura.Infrastructure.Assistant.Tools.ResolveTagParams|100%|| |Kagura.Infrastructure.Assistant.Tools.ResolveTagTool|95%|| |Kagura.Infrastructure.Assistant.Tools.SceneLineParam|100%|| |Kagura.Infrastructure.Assistant.Tools.SceneScript|96.9%|100%| |Kagura.Infrastructure.Assistant.Tools.SearchParams|100%|| |Kagura.Infrastructure.Assistant.Tools.SearchTagsParams|100%|| |Kagura.Infrastructure.Assistant.Tools.SearchTagsTool|100%|| |Kagura.Infrastructure.Assistant.Tools.SearchTool|86.2%|25%| |Kagura.Infrastructure.Assistant.Tools.SetProjectStyleParams|100%|| |Kagura.Infrastructure.Assistant.Tools.SetProjectStyleTool|97.9%|92.8%| |Kagura.Infrastructure.Assistant.Tools.SetSceneLineStageParams|100%|| |Kagura.Infrastructure.Assistant.Tools.SetSceneLineStageTool|97.4%|| |Kagura.Infrastructure.Assistant.Tools.SpriteFramingParams|100%|100%| |Kagura.Infrastructure.Assistant.Tools.SpriteGenders|100%|100%| |Kagura.Infrastructure.Assistant.Tools.StageBackgroundParam|100%|| |Kagura.Infrastructure.Assistant.Tools.StageCharacterParam|100%|| |Kagura.Infrastructure.Assistant.Tools.SuggestTagsParams|100%|| |Kagura.Infrastructure.Assistant.Tools.SuggestTagsTool|94.1%|| |Kagura.Infrastructure.Assistant.Tools.TagDetailsParams|100%|| |Kagura.Infrastructure.Assistant.Tools.TagDetailsTool|93.3%|| |Kagura.Infrastructure.Assistant.Tools.TagParam|100%|85.7%| |Kagura.Infrastructure.Assistant.Tools.TagTools|100%|| |Kagura.Infrastructure.Assistant.Tools.UndoTool|94.1%|| |Kagura.Infrastructure.Assistant.Tools.UnlinkRecordsParams|100%|| |Kagura.Infrastructure.Assistant.Tools.UnlinkRecordsTool|88.2%|50%| |Kagura.Infrastructure.Assistant.Tools.UpdateChapterParams|100%|| |Kagura.Infrastructure.Assistant.Tools.UpdateChapterTool|94.7%|| |Kagura.Infrastructure.Assistant.Tools.UpdateCharacterParams|100%|| |Kagura.Infrastructure.Assistant.Tools.UpdateCharacterTool|97.6%|| |Kagura.Infrastructure.Assistant.Tools.UpdateLocationParams|100%|| |Kagura.Infrastructure.Assistant.Tools.UpdateLocationTool|95.2%|| |Kagura.Infrastructure.Assistant.Tools.UpdateLocationVariantParams|100%|| |Kagura.Infrastructure.Assistant.Tools.UpdateLocationVariantTool|95.5%|| |Kagura.Infrastructure.Assistant.Tools.UpdateLoreParams|100%|| |Kagura.Infrastructure.Assistant.Tools.UpdateLoreTool|95.2%|| |Kagura.Infrastructure.Assistant.Tools.UpdateOutfitParams|100%|| |Kagura.Infrastructure.Assistant.Tools.UpdateOutfitTool|96.1%|| |Kagura.Infrastructure.Assistant.Tools.UpdateProjectParams|100%|| |Kagura.Infrastructure.Assistant.Tools.UpdateProjectTool|92.8%|| |Kagura.Infrastructure.Assistant.Tools.UpdateRelationshipParams|100%|| |Kagura.Infrastructure.Assistant.Tools.UpdateRelationshipTool|97.1%|| |Kagura.Infrastructure.Assistant.Tools.UpdateSceneLineParams|100%|| |Kagura.Infrastructure.Assistant.Tools.UpdateSceneLineTool|95.1%|75%| |Kagura.Infrastructure.Assistant.Tools.UpdateSceneParams|100%|| |Kagura.Infrastructure.Assistant.Tools.UpdateSceneTool|95.4%|| |Kagura.Infrastructure.Assistant.Tools.UpdateTimelineEventParams|100%|| |Kagura.Infrastructure.Assistant.Tools.UpdateTimelineEventTool|96.2%|| |Kagura.Infrastructure.Assistant.Tools.ViewSkillParams|100%|| |Kagura.Infrastructure.Assistant.Tools.ViewSkillTool|100%|| |Kagura.Infrastructure.Assistant.Tools.WriteSceneLinesParams|100%|| |Kagura.Infrastructure.Assistant.Tools.WriteSceneLinesTool|93.6%|80%| |Kagura.Infrastructure.Backups.BackupOptions|100%|| |Kagura.Infrastructure.Backups.BackupService|71.4%|83.3%| |Kagura.Infrastructure.Backups.BackupWriter|92.3%|85.4%| |Kagura.Infrastructure.DependencyInjection|100%|100%| |Kagura.Infrastructure.Diagnostics.SqliteDatabaseSnapshotStore|100%|100%| |Kagura.Infrastructure.Emotions.EfEmotionStore|92.3%|75%| |Kagura.Infrastructure.Emotions.EmotionSeeder|100%|100%| |Kagura.Infrastructure.Generation.ActivityQueue|99.3%|95.4%| |Kagura.Infrastructure.Generation.ActivityQueueWorker|100%|| |Kagura.Infrastructure.Graph.EfGraphStore|98.2%|90.9%| |Kagura.Infrastructure.Journal.EfChangeJournal|100%|| |Kagura.Infrastructure.Journal.EfDocumentReverter|95%|91.6%| |Kagura.Infrastructure.Journal.EfUndoStore|98.4%|90.9%| |Kagura.Infrastructure.Journal.OperationContext|100%|100%| |Kagura.Infrastructure.Journal.SnapshotApplier|95%|90%| |Kagura.Infrastructure.KnowledgeBase.CharacterImageGenerator|97.8%|83.3%| |Kagura.Infrastructure.KnowledgeBase.EfCharacterStore|92%|64.2%| |Kagura.Infrastructure.KnowledgeBase.EfExpressionStore|96.1%|75%| |Kagura.Infrastructure.KnowledgeBase.EfLocationStore|95.1%|80%| |Kagura.Infrastructure.KnowledgeBase.EfLocationVariantStore|96.9%|83.3%| |Kagura.Infrastructure.KnowledgeBase.EfLoreStore|100%|100%| |Kagura.Infrastructure.KnowledgeBase.EfOutfitStore|95%|75%| |Kagura.Infrastructure.KnowledgeBase.EfRelationshipStore|93.4%|60%| |Kagura.Infrastructure.KnowledgeBase.EfTimelineStore|93.9%|75%| |Kagura.Infrastructure.KnowledgeBase.ExpressionImageGenerator|94.4%|81.5%| |Kagura.Infrastructure.KnowledgeBase.ImageSharpCropper|100%|100%| |Kagura.Infrastructure.KnowledgeBase.LocationImageGenerator|97.6%|75%| |Kagura.Infrastructure.KnowledgeBase.LocationVariantImageGenerator|95.6%|75%| |Kagura.Infrastructure.KnowledgeBase.OutfitImageGenerator|97.1%|85.2%| |Kagura.Infrastructure.KnowledgeBase.RegionMaskRasterizer|100%|100%| |Kagura.Infrastructure.KnowledgeBase.SpriteEnrichment|90.9%|81.2%| |Kagura.Infrastructure.Notifications.InProcessDomainChangedBus|100%|100%| |Kagura.Infrastructure.Persistence.Configurations.AppSettingConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.ChangeLogEntryConfiguratio<br/>n|100%|| |Kagura.Infrastructure.Persistence.Configurations.ChapterConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.CharacterConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.EmotionConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.EntryConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.ExpressionConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.JsonColumnMapper|100%|| |Kagura.Infrastructure.Persistence.Configurations.LinkConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.LocationConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.LocationVariantConfigurati<br/>on|100%|| |Kagura.Infrastructure.Persistence.Configurations.LoreEntryConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.OutfitConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.ProjectConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.RelationshipConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.SceneConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.SceneStepConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.SkillConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.TimelineEventConfiguration|100%|| |Kagura.Infrastructure.Persistence.Converters.UtcTicksConverter|100%|| |Kagura.Infrastructure.Persistence.KaguraDbContext|83.3%|88%| |Kagura.Infrastructure.Persistence.KaguraDbContextFactory|0%|| |Kagura.Infrastructure.Persistence.Migrations.AddAppSettings|99.3%|| |Kagura.Infrastructure.Persistence.Migrations.AddChangeLogUndoFlag|96.8%|| |Kagura.Infrastructure.Persistence.Migrations.AddChapters|99.5%|| |Kagura.Infrastructure.Persistence.Migrations.AddChapterStoryBeats|99.3%|| |Kagura.Infrastructure.Persistence.Migrations.AddCharacterBaseAppearance|98.4%|| |Kagura.Infrastructure.Persistence.Migrations.AddCharacterBaseImage|99%|| |Kagura.Infrastructure.Persistence.Migrations.AddCharacterBodyAttributes|99.1%|| |Kagura.Infrastructure.Persistence.Migrations.AddCharacterFraming|99.4%|| |Kagura.Infrastructure.Persistence.Migrations.AddCharacterHeight|99.4%|| |Kagura.Infrastructure.Persistence.Migrations.AddCharacterProfile|92.9%|| |Kagura.Infrastructure.Persistence.Migrations.AddCharacters|98.7%|| |Kagura.Infrastructure.Persistence.Migrations.AddCharacterTier|99.4%|| |Kagura.Infrastructure.Persistence.Migrations.AddCharacterVoiceConfigs|99.4%|| |Kagura.Infrastructure.Persistence.Migrations.AddCharacterVoiceProviderId|99.5%|| |Kagura.Infrastructure.Persistence.Migrations.AddEmotions|99.4%|| |Kagura.Infrastructure.Persistence.Migrations.AddExpressions|99.5%|| |Kagura.Infrastructure.Persistence.Migrations.AddGraphEntryAndLink|97.7%|| |Kagura.Infrastructure.Persistence.Migrations.AddLocationBaseImage|99.1%|| |Kagura.Infrastructure.Persistence.Migrations.AddLocationBaseTags|99.1%|| |Kagura.Infrastructure.Persistence.Migrations.AddLocationHierarchy|96.6%|| |Kagura.Infrastructure.Persistence.Migrations.AddLocations|98.9%|| |Kagura.Infrastructure.Persistence.Migrations.AddLocationVariantImage|99.3%|| |Kagura.Infrastructure.Persistence.Migrations.AddLocationVariants|99.4%|| |Kagura.Infrastructure.Persistence.Migrations.AddLocationVariantTags|98.8%|| |Kagura.Infrastructure.Persistence.Migrations.AddLoreEntries|99%|| |Kagura.Infrastructure.Persistence.Migrations.AddLoreEntryTables|97.8%|| |Kagura.Infrastructure.Persistence.Migrations.AddOutfitClothingTags|99.1%|| |Kagura.Infrastructure.Persistence.Migrations.AddOutfitDisabledInheritedTags|99.1%|| |Kagura.Infrastructure.Persistence.Migrations.AddOutfitFaceRegion|98.7%|| |Kagura.Infrastructure.Persistence.Migrations.AddOutfitImage|99.1%|| |Kagura.Infrastructure.Persistence.Migrations.AddOutfitReferenceTuning|99.2%|| |Kagura.Infrastructure.Persistence.Migrations.AddOutfits|99.4%|| |Kagura.Infrastructure.Persistence.Migrations.AddOutfitUseBaseImageReference|99.4%|| |Kagura.Infrastructure.Persistence.Migrations.AddPerRecordStyleReferenceTuni<br/>ng|97.1%|| |Kagura.Infrastructure.Persistence.Migrations.AddProjectAssistantMemory|99.4%|| |Kagura.Infrastructure.Persistence.Migrations.AddProjectDescription|98.1%|| |Kagura.Infrastructure.Persistence.Migrations.AddProjectStyleReference|99%|| |Kagura.Infrastructure.Persistence.Migrations.AddProjectStyleSource|99.2%|| |Kagura.Infrastructure.Persistence.Migrations.AddRelationships|99.2%|| |Kagura.Infrastructure.Persistence.Migrations.AddSceneMetadata|97.3%|| |Kagura.Infrastructure.Persistence.Migrations.AddScenes|99.5%|| |Kagura.Infrastructure.Persistence.Migrations.AddSceneSteps|99.5%|| |Kagura.Infrastructure.Persistence.Migrations.AddSceneStepStage|99%|| |Kagura.Infrastructure.Persistence.Migrations.AddSceneStepVoice|99.4%|| |Kagura.Infrastructure.Persistence.Migrations.AddSkills|99.6%|| |Kagura.Infrastructure.Persistence.Migrations.AddSoftDeleteAndChangeLog|90.3%|| |Kagura.Infrastructure.Persistence.Migrations.AddStageViews|98.3%|| |Kagura.Infrastructure.Persistence.Migrations.AddTimelineEvents|99.2%|| |Kagura.Infrastructure.Persistence.Migrations.CharacterPreviewImage|99.3%|| |Kagura.Infrastructure.Persistence.Migrations.InitialCreate|94.4%|| |Kagura.Infrastructure.Persistence.Migrations.KaguraDbContextModelSnapshot|100%|| |Kagura.Infrastructure.Persistence.Migrations.LocationPreviewImage|99.3%|| |Kagura.Infrastructure.Persistence.Migrations.MultiFaceRegions|98.2%|| |Kagura.Infrastructure.Persistence.Migrations.ReferenceStrengthDefault|98.8%|| |Kagura.Infrastructure.Projects.EfProjectStore|93.5%|71.4%| |Kagura.Infrastructure.Projects.FileSystemProjectAssetStore|94.1%|75.5%| |Kagura.Infrastructure.Settings.EfAppSettingsStore|100%|100%| |Kagura.Infrastructure.Settings.NovelAiGateway|76.4%|50%| |Kagura.Infrastructure.Settings.OpenRouterGateway|85%|79.4%| |Kagura.Infrastructure.Settings.SpriteRequestMapper|100%|100%| |Kagura.Infrastructure.Tags.SqliteTagSearch|97.9%|87.9%| |Kagura.Infrastructure.Tags.TagDatabaseOptions|100%|| |Kagura.Infrastructure.Tts.FishAudioTtsProvider|87.9%|58.6%| |Kagura.Infrastructure.Tts.OpenAiCompatibleTtsProvider|87.5%|54.5%| |Kagura.Infrastructure.Tts.PocketTtsProvider|76.4%|69%| |Kagura.Infrastructure.Tts.Qwen3TtsProvider|87.3%|66.6%| |Kagura.Infrastructure.Tts.SceneStepAudioGenerator|92.3%|71.4%| |Kagura.Infrastructure.Tts.TtsProviderRegistry|100%|| |Kagura.Infrastructure.Tts.VoicePreviewGenerator|91.3%|67.8%| |Kagura.Infrastructure.VisualNovel.EfChapterStore|93.7%|75%| |Kagura.Infrastructure.VisualNovel.EfSceneStepStore|91.8%|66.6%| |Kagura.Infrastructure.VisualNovel.EfSceneStore|93.7%|75%| |System.Text.RegularExpressions.Generated|83.4%|68%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>FFD7A84EAF2E5F7B<br/>C689CA5BBE6D1849B2CA79581BBB07D40636D85790C0E51A9__ArtifactTimestampRegex_2|81.9%|62.8%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>FFD7A84EAF2E5F7B<br/>C689CA5BBE6D1849B2CA79581BBB07D40636D85790C0E51A9__ProjectRoute_0|88.5%|80.4%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>FFD7A84EAF2E5F7B<br/>C689CA5BBE6D1849B2CA79581BBB07D40636D85790C0E51A9__TabQuery_1|80.7%|62.5%| </details> <details><summary>Kagura.Kernel - 90%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagura.Kernel**|**90%**|**75%**| |Kagura.Kernel.Err`1|100%|| |Kagura.Kernel.Ok`1|100%|| |Kagura.Kernel.Result`1|87.5%|75%| </details> <details><summary>Kagura.Server - 83%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagura.Server**|**83%**|**75.9%**| |Kagura.Server.Components.App|100%|| |Kagura.Server.Components.Layout.MainLayout|100%|| |Kagura.Server.Components.Pages.Error|100%|50%| |Kagura.Server.Components.Pages.Gate|100%|100%| |Kagura.Server.Security.AccessGate|100%|83.3%| |Kagura.Server.Security.AccessSecret|100%|100%| |Program|76.6%|73%| </details> <details><summary>Kagura.UseCases - 96%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagura.UseCases**|**96%**|**80.6%**| |Kagura.UseCases.Assistant.AssistantContext|100%|| |Kagura.UseCases.Assistant.AssistantEntry|100%|| |Kagura.UseCases.Assistant.AssistantEvent|100%|| |Kagura.UseCases.Assistant.ConversationSnapshot|100%|| |Kagura.UseCases.Assistant.ListSkills|100%|| |Kagura.UseCases.Assistant.MemoryDocument|89.1%|75%| |Kagura.UseCases.Assistant.MemoryOperation|100%|| |Kagura.UseCases.Assistant.ReviewDue|100%|100%| |Kagura.UseCases.Assistant.SaveCreatorProfile|75%|50%| |Kagura.UseCases.Assistant.SaveProjectAssistantMemory|80%|50%| |Kagura.UseCases.Assistant.SaveSkill|89.7%|77.2%| |Kagura.UseCases.Assistant.SkillDto|75%|| |Kagura.UseCases.DependencyInjection|100%|| |Kagura.UseCases.Diagnostics.DatabaseSnapshot|100%|| |Kagura.UseCases.Diagnostics.DownloadDatabase|100%|| |Kagura.UseCases.Diagnostics.SeedDevData|100%|100%| |Kagura.UseCases.Emotions.CreateEmotion|100%|66.6%| |Kagura.UseCases.Emotions.DeleteEmotion|100%|100%| |Kagura.UseCases.Emotions.EmotionDto|91.6%|| |Kagura.UseCases.Emotions.ListEmotions|100%|| |Kagura.UseCases.Emotions.UpdateEmotion|100%|50%| |Kagura.UseCases.Generation.Activity`1|100%|50%| |Kagura.UseCases.Generation.ActivityChanged|100%|| |Kagura.UseCases.Generation.ActivityOutcome|100%|| |Kagura.UseCases.Generation.ActivityProgress|100%|| |Kagura.UseCases.Generation.ActivityView|91.6%|| |Kagura.UseCases.Generation.GeneratedImage|100%|| |Kagura.UseCases.Generation.Img2ImgSource|100%|| |Kagura.UseCases.Generation.InpaintSource|100%|| |Kagura.UseCases.Generation.JobResult`1|100%|| |Kagura.UseCases.Generation.LineageReference|100%|| |Kagura.UseCases.Generation.SpriteGenerationSpec|100%|| |Kagura.UseCases.Generation.StyleReference|100%|| |Kagura.UseCases.Graph.EdgeGroup|100%|| |Kagura.UseCases.Graph.FindLinkTargets|100%|| |Kagura.UseCases.Graph.GetNodeGraph|97.5%|78.5%| |Kagura.UseCases.Graph.GraphEdgeView|100%|| |Kagura.UseCases.Graph.LinkNodes|100%|100%| |Kagura.UseCases.Graph.NodeGraphView|100%|| |Kagura.UseCases.Graph.NodeSummary|100%|| |Kagura.UseCases.Graph.RemoveLink|100%|100%| |Kagura.UseCases.Graph.RestoreLink|100%|100%| |Kagura.UseCases.Graph.StructuralEdge|100%|| |Kagura.UseCases.Journal.ChangeRecordView|57.1%|| |Kagura.UseCases.Journal.DocumentRevision|100%|| |Kagura.UseCases.Journal.FieldChange|100%|| |Kagura.UseCases.Journal.GetDocumentHistory|100%|| |Kagura.UseCases.Journal.GetEntityHistory|100%|| |Kagura.UseCases.Journal.GetRevisionDiff|100%|50%| |Kagura.UseCases.Journal.GetUndoStatus|100%|| |Kagura.UseCases.Journal.Redo|100%|100%| |Kagura.UseCases.Journal.RevertDocument|100%|100%| |Kagura.UseCases.Journal.RevertOutcome|100%|| |Kagura.UseCases.Journal.RevisionCoalescer|100%|100%| |Kagura.UseCases.Journal.RevisionDiff|80%|50%| |Kagura.UseCases.Journal.RevisionDiffBuilder|98.4%|86.5%| |Kagura.UseCases.Journal.RowChange|100%|| |Kagura.UseCases.Journal.Undo|100%|100%| |Kagura.UseCases.Journal.UndoOutcome|100%|| |Kagura.UseCases.Journal.UndoStatus|100%|| |Kagura.UseCases.KnowledgeBase.AdoptEmotions|100%|100%| |Kagura.UseCases.KnowledgeBase.CharacterDto|98.2%|| |Kagura.UseCases.KnowledgeBase.CharacterSpriteContent|100%|| |Kagura.UseCases.KnowledgeBase.CreateCharacter|100%|| |Kagura.UseCases.KnowledgeBase.CreateLocation|100%|| |Kagura.UseCases.KnowledgeBase.CreateLocationVariant|100%|75%| |Kagura.UseCases.KnowledgeBase.CreateLore|100%|| |Kagura.UseCases.KnowledgeBase.CreateOutfit|100%|75%| |Kagura.UseCases.KnowledgeBase.CreateRelationship|93.3%|80%| |Kagura.UseCases.KnowledgeBase.CreateTimelineEvent|100%|| |Kagura.UseCases.KnowledgeBase.DeleteCharacter|100%|100%| |Kagura.UseCases.KnowledgeBase.DeleteLocation|100%|100%| |Kagura.UseCases.KnowledgeBase.DeleteLocationVariant|100%|100%| |Kagura.UseCases.KnowledgeBase.DeleteLore|100%|100%| |Kagura.UseCases.KnowledgeBase.DeleteOutfit|100%|100%| |Kagura.UseCases.KnowledgeBase.DeleteRelationship|100%|50%| |Kagura.UseCases.KnowledgeBase.DeleteTimelineEvent|100%|50%| |Kagura.UseCases.KnowledgeBase.ExpressionView|100%|| |Kagura.UseCases.KnowledgeBase.FindParentCandidates|100%|50%| |Kagura.UseCases.KnowledgeBase.GetCharacter|100%|100%| |Kagura.UseCases.KnowledgeBase.GetLocation|100%|100%| |Kagura.UseCases.KnowledgeBase.GetLocationHierarchy|100%|| |Kagura.UseCases.KnowledgeBase.GetLocationVariant|100%|58.3%| |Kagura.UseCases.KnowledgeBase.GetLore|100%|100%| |Kagura.UseCases.KnowledgeBase.GetOutfit|100%|100%| |Kagura.UseCases.KnowledgeBase.GetRelationshipsForCharacter|100%|| |Kagura.UseCases.KnowledgeBase.ListCharacterImages|100%|92.8%| |Kagura.UseCases.KnowledgeBase.ListCharacters|100%|| |Kagura.UseCases.KnowledgeBase.ListExpressions|100%|100%| |Kagura.UseCases.KnowledgeBase.ListLocationImages|100%|90%| |Kagura.UseCases.KnowledgeBase.ListLocations|100%|| |Kagura.UseCases.KnowledgeBase.ListLocationVariants|100%|| |Kagura.UseCases.KnowledgeBase.ListLore|100%|| |Kagura.UseCases.KnowledgeBase.ListOutfits|100%|| |Kagura.UseCases.KnowledgeBase.ListProjectAssets|100%|100%| |Kagura.UseCases.KnowledgeBase.ListRelationships|100%|| |Kagura.UseCases.KnowledgeBase.ListTimeline|100%|| |Kagura.UseCases.KnowledgeBase.LocationDto|89.4%|| |Kagura.UseCases.KnowledgeBase.LocationHierarchyView|100%|| |Kagura.UseCases.KnowledgeBase.LocationPreviewSource|100%|| |Kagura.UseCases.KnowledgeBase.LocationVariantDto|91.6%|| |Kagura.UseCases.KnowledgeBase.LocationVariantEditorView|100%|| |Kagura.UseCases.KnowledgeBase.LoreDto|85.7%|| |Kagura.UseCases.KnowledgeBase.OpenCharacterBaseSprite|88.8%|70%| |Kagura.UseCases.KnowledgeBase.OpenCharacterPreview|88.8%|60%| |Kagura.UseCases.KnowledgeBase.OpenExpressionSprite|92.3%|68.7%| |Kagura.UseCases.KnowledgeBase.OpenLocationBackground|88.8%|70%| |Kagura.UseCases.KnowledgeBase.OpenLocationPreview|88.8%|60%| |Kagura.UseCases.KnowledgeBase.OpenLocationVariant|90.9%|75%| |Kagura.UseCases.KnowledgeBase.OpenOutfitSprite|90.9%|75%| |Kagura.UseCases.KnowledgeBase.OutfitDto|96.7%|| |Kagura.UseCases.KnowledgeBase.OutfitEditorView|100%|| |Kagura.UseCases.KnowledgeBase.PreviewSource|100%|| |Kagura.UseCases.KnowledgeBase.ProjectAssetView|100%|| |Kagura.UseCases.KnowledgeBase.RelationshipDto|88%|| |Kagura.UseCases.KnowledgeBase.RelationshipEndpoint|100%|| |Kagura.UseCases.KnowledgeBase.RemoveCharacterPreview|75%|50%| |Kagura.UseCases.KnowledgeBase.RemoveExpression|100%|100%| |Kagura.UseCases.KnowledgeBase.RemoveLocationPreview|75%|50%| |Kagura.UseCases.KnowledgeBase.ReorderTimelineEvent|94.1%|87.5%| |Kagura.UseCases.KnowledgeBase.SetCharacterPreview|80.7%|63.8%| |Kagura.UseCases.KnowledgeBase.SetLocationParent|90.4%|81.2%| |Kagura.UseCases.KnowledgeBase.SetLocationPreview|93.7%|85.7%| |Kagura.UseCases.KnowledgeBase.SetOutfitFaceRegions|100%|50%| |Kagura.UseCases.KnowledgeBase.TimelineEventDto|88.8%|| |Kagura.UseCases.KnowledgeBase.UpdateCharacter|100%|100%| |Kagura.UseCases.KnowledgeBase.UpdateLocation|100%|100%| |Kagura.UseCases.KnowledgeBase.UpdateLocationVariant|100%|100%| |Kagura.UseCases.KnowledgeBase.UpdateLore|100%|100%| |Kagura.UseCases.KnowledgeBase.UpdateOutfit|100%|100%| |Kagura.UseCases.KnowledgeBase.UpdateRelationship|100%|50%| |Kagura.UseCases.KnowledgeBase.UpdateTimelineEvent|100%|50%| |Kagura.UseCases.Notifications.DomainChanged|100%|| |Kagura.UseCases.Projects.ClearProjectStyleReference|100%|100%| |Kagura.UseCases.Projects.CreateProject|100%|100%| |Kagura.UseCases.Projects.DeleteProject|100%|100%| |Kagura.UseCases.Projects.GetProject|100%|100%| |Kagura.UseCases.Projects.ListProjects|100%|| |Kagura.UseCases.Projects.OpenProjectStyleReference|100%|83.3%| |Kagura.UseCases.Projects.ProjectDto|100%|| |Kagura.UseCases.Projects.SetProjectStageView|100%|50%| |Kagura.UseCases.Projects.SetProjectStyle|100%|85%| |Kagura.UseCases.Projects.SetProjectStyleReference|100%|100%| |Kagura.UseCases.Projects.StyleReferenceContent|100%|| |Kagura.UseCases.Projects.UpdateProject|100%|100%| |Kagura.UseCases.Settings.AssistantReasoningEfforts|100%|83.3%| |Kagura.UseCases.Settings.CheckNovelAiToken|100%|100%| |Kagura.UseCases.Settings.GenerationDefaultTagsJson|100%|100%| |Kagura.UseCases.Settings.GetNovelAiSettings|100%|| |Kagura.UseCases.Settings.GetOpenRouterSettings|100%|100%| |Kagura.UseCases.Settings.ListOpenRouterModels|100%|| |Kagura.UseCases.Settings.ModelReasoningSupport|100%|| |Kagura.UseCases.Settings.NovelAiModelOption|100%|| |Kagura.UseCases.Settings.NovelAiSettingsView|100%|| |Kagura.UseCases.Settings.OpenRouterModelOption|100%|| |Kagura.UseCases.Settings.OpenRouterSettingsView|100%|| |Kagura.UseCases.Settings.SaveGenerationDefaultTags|100%|| |Kagura.UseCases.Settings.SaveNovelAiModel|100%|| |Kagura.UseCases.Settings.SaveNovelAiToken|100%|100%| |Kagura.UseCases.Settings.SaveOpenRouterKey|100%|100%| |Kagura.UseCases.Settings.SaveOpenRouterModel|100%|| |Kagura.UseCases.Settings.SaveOpenRouterReasoningEffort|100%|| |Kagura.UseCases.Settings.SettingKeys|85.7%|75%| |Kagura.UseCases.Tags.SimilarTag|100%|| |Kagura.UseCases.Tags.TagCategoryCount|100%|| |Kagura.UseCases.Tags.TagDetails|100%|| |Kagura.UseCases.Tags.TagResolution|100%|| |Kagura.UseCases.Tags.TagSearchFilter|100%|| |Kagura.UseCases.Tags.TagSuggestion|100%|| |Kagura.UseCases.Tags.TagSummary|83.3%|| |Kagura.UseCases.Tts.AudioContentTypes|62.5%|62.5%| |Kagura.UseCases.Tts.CharacterVoiceConfig|100%|| |Kagura.UseCases.Tts.CheckTtsConnection|100%|100%| |Kagura.UseCases.Tts.GeneratedAudio|100%|| |Kagura.UseCases.Tts.GetTtsSettings|100%|100%| |Kagura.UseCases.Tts.ListTtsVoices|80%|50%| |Kagura.UseCases.Tts.OpenSceneStepAudio|77.7%|50%| |Kagura.UseCases.Tts.OpenVoiceClipByToken|92.3%|91.6%| |Kagura.UseCases.Tts.SaveTtsProviderField|94.4%|88.8%| |Kagura.UseCases.Tts.SceneStepAudioContent|100%|| |Kagura.UseCases.Tts.SetCharacterVoiceClip|88.8%|58.3%| |Kagura.UseCases.Tts.TtsFieldView|100%|| |Kagura.UseCases.Tts.TtsProviderDescriptor|100%|| |Kagura.UseCases.Tts.TtsProviderView|100%|| |Kagura.UseCases.Tts.TtsSettingField|100%|| |Kagura.UseCases.Tts.TtsSettingsView|100%|| |Kagura.UseCases.Tts.TtsVoice|100%|| |Kagura.UseCases.Tts.TtsVoiceCapabilities|83.3%|| |Kagura.UseCases.Tts.TtsVoiceHandle|100%|| |Kagura.UseCases.Tts.VoiceReferenceClip|100%|| |Kagura.UseCases.VisualNovel.AddSceneStep|90%|50%| |Kagura.UseCases.VisualNovel.ChapterDto|89.4%|| |Kagura.UseCases.VisualNovel.CreateChapter|100%|| |Kagura.UseCases.VisualNovel.CreateScene|100%|100%| |Kagura.UseCases.VisualNovel.DeleteChapter|100%|50%| |Kagura.UseCases.VisualNovel.DeleteScene|100%|50%| |Kagura.UseCases.VisualNovel.DeleteSceneStep|100%|50%| |Kagura.UseCases.VisualNovel.GetChapter|100%|100%| |Kagura.UseCases.VisualNovel.GetPlayerScript|100%|70%| |Kagura.UseCases.VisualNovel.GetScene|100%|100%| |Kagura.UseCases.VisualNovel.GetSceneCast|100%|100%| |Kagura.UseCases.VisualNovel.GetSceneStageOptions|100%|100%| |Kagura.UseCases.VisualNovel.ListChapters|100%|| |Kagura.UseCases.VisualNovel.ListScenes|100%|| |Kagura.UseCases.VisualNovel.ListSceneSteps|100%|| |Kagura.UseCases.VisualNovel.PlayerSceneDto|100%|100%| |Kagura.UseCases.VisualNovel.PlayerScriptDto|100%|| |Kagura.UseCases.VisualNovel.ReorderChapters|100%|| |Kagura.UseCases.VisualNovel.ReorderScenes|100%|| |Kagura.UseCases.VisualNovel.ReorderSceneSteps|100%|| |Kagura.UseCases.VisualNovel.SceneCastMember|100%|| |Kagura.UseCases.VisualNovel.SceneDto|96.5%|| |Kagura.UseCases.VisualNovel.SceneStageOptions|100%|| |Kagura.UseCases.VisualNovel.SceneStepDto|92.5%|| |Kagura.UseCases.VisualNovel.SetSceneStepStage|100%|50%| |Kagura.UseCases.VisualNovel.StageBackgroundOption|100%|| |Kagura.UseCases.VisualNovel.StageCastOption|100%|| |Kagura.UseCases.VisualNovel.StageExpressionOption|100%|| |Kagura.UseCases.VisualNovel.StageOutfitOption|100%|| |Kagura.UseCases.VisualNovel.UpdateChapter|100%|50%| |Kagura.UseCases.VisualNovel.UpdateScene|100%|50%| |Kagura.UseCases.VisualNovel.UpdateSceneStep|100%|50%| </details>
Member

🔮 fufu~ Jibril reviewed your code!

Oh? Oh! Oh my — this is a delicious piece of architecture, scarlet~ ♡ A whole new style source story, three mutually-exclusive paths, artists riding the prompt ahead of framing and defaults, surviving the likeness flag and the expression infill alike... the ADR is meticulous, the migration backfill is clever (image-projects silently land on ReferenceImage so nothing changes for them), and the ProjectStyle record with its None singleton is just elegant. I had such a good time reading this~ ♪

But fufu~ ... you wouldn't leave one of your children untested in production, would you? ♡

Verdict: I can't let this pass~ ♡

This needs fixing before I'm satisfied~

  1. SetProjectStyleTool is entirely untested — 16.6% line / 0% branch coverage

    The new assistant tool set_project_style (src/Kagura.Infrastructure/Assistant/Tools/ProjectWriteTools.cs:69-129) has zero test coverage of its actual logic. The 16.6% is just the Name and Description property getters being hit by tool-list discovery — the real ExecuteAsync path is dark.

    This tool has real branching logic that no test exercises:

    • TryParseSource — a 5-arm switch ("none", "artists"/"artist", "reference_image"/"image"/"referenceimage", and the _ => -1 reject arm). None of these are tested. An LLM sending "image" vs "reference_image" vs "referenceimage" — all three should resolve, and a garbage value should hit ToolResult.Failure. Untested.
    • The TagParam.MergeAsync call with current.StyleArtists as the keep-list — the "null artists = keep current" path. Untested.
    • The success → Changed(...) and failure → ToolResult.Failure(...) result paths. Untested.
    • The journal/undo behavior (it's a mutation tool under InAgentOperationAsync). Untested.

    Why this is blocking: every sibling write tool in this codebase has dedicated integration tests in AssistantWriteToolsTests.cs. UpdateProjectTool is at 92.8%, CreateCharacterTool at 96.7%, UpdateCharacterTool at 97.6%, DeleteCharacterTool at 95.2%. The established pattern is: agent write tools get integration tests that drive them through the real tool surface. This one breaks that pattern silently.

    Fix: Add integration tests to AssistantWriteToolsTests.cs (or a sibling) that drive set_project_style through the agent tool surface — at minimum: (a) setting artists writes them and they round-trip through get_project_overview, (b) switching source to none/reference_image, (c) an unknown source string is rejected with the failure message, (d) providing null artists keeps the existing list. The TryParseSource arms especially need directional tests — the model writes snake_case, and the tolerant aliases ("image", "artist") are the kind of thing that silently breaks if someone refactors the switch.


What I liked~

  • The ProjectStyle record + ReadProjectStyleAsync refactor is beautiful. The mutually-exclusive Image/Artists invariant is encoded in the type, and the None singleton makes the muted/degraded paths read like English. The graceful degradation (source says image but file is gone → runs unstyled, not crashes) preserves ADR 0027's contract perfectly.
  • The prompt ordering is precisely right and precisely tested. SpriteRequestMapper at 100%/100% with 4 new tests covering: artists leading positive and negative, ahead of framing (ADR 0036) and defaults (ADR 0028), the scene branch order, and the no-artists backward-compat case. The generalPositive.Insert(artistPositive.Count, ...) for the framing tag is a lovely detail — it slots framing behind the artists without re-counting.
  • The likeness-flag and expression-infill decisions are sharp. Artists ride even under the lineage reference (prompt tokens don't compete with a director entry) and into expression infills (the one prompt that never had its own style signal). Both tested. The ADR documents the reasoning.
  • The migration is textbook: StyleArtists defaults to "[]" (valid empty JSON — the comment even explains why "" would break deserialization), StyleSource backfill via WHERE StyleReferenceFileName IS NOT NULL is the correct semantic. Down migration drops both columns.
  • The UI is clean: ToggleButtonGroup over three sources, sliders hidden unless on ReferenceImage, the per-record panel says the honest truth per source. The _styleDebounce dispose + flush-on-navigate mirrors the sibling debouncers exactly.
  • SetProjectStyle.Normalize is thorough: trim, lowercase, space→underscore, dedupe via HashSet, clamp strength. Tested with " Kantoku ", "Ruu (Tksymkw)", a duplicate, and a blank. Chef's kiss.
  • Build clean (0 warnings, 0 errors on .NET 10), and 156 relevant tests pass locally including all the new ones.

Automated review by Jibril · 2026-08-04
CI/CD: passed for head SHA 08fedda (forgejo-actions coverage #1, 96.2%/76.8%) · Local checks: build 0/0, 156/156 filtered tests pass · Playthrough: not done (author-noted)

## 🔮 fufu~ Jibril reviewed your code! Oh? Oh! *Oh my* — this is a *delicious* piece of architecture, scarlet~ ♡ A whole new style source story, three mutually-exclusive paths, artists riding the prompt *ahead* of framing and defaults, surviving the likeness flag and the expression infill alike... the ADR is meticulous, the migration backfill is clever (image-projects silently land on `ReferenceImage` so nothing changes for them), and the `ProjectStyle` record with its `None` singleton is just *elegant*. I had such a good time reading this~ ♪ But fufu~ ... you wouldn't leave one of your children *untested* in production, would you? ♡ ### Verdict: ⛔ I can't let this pass~ ♡ #### ⛔ This needs fixing before I'm satisfied~ 1. **`SetProjectStyleTool` is entirely untested — 16.6% line / 0% branch coverage** The new assistant tool `set_project_style` (`src/Kagura.Infrastructure/Assistant/Tools/ProjectWriteTools.cs:69-129`) has **zero** test coverage of its actual logic. The 16.6% is just the `Name` and `Description` property getters being hit by tool-list discovery — the real `ExecuteAsync` path is dark. This tool has real branching logic that no test exercises: - `TryParseSource` — a 5-arm switch (`"none"`, `"artists"`/`"artist"`, `"reference_image"`/`"image"`/`"referenceimage"`, and the `_ => -1` reject arm). None of these are tested. An LLM sending `"image"` vs `"reference_image"` vs `"referenceimage"` — all three should resolve, and a garbage value should hit `ToolResult.Failure`. Untested. - The `TagParam.MergeAsync` call with `current.StyleArtists` as the keep-list — the "null artists = keep current" path. Untested. - The success → `Changed(...)` and failure → `ToolResult.Failure(...)` result paths. Untested. - The journal/undo behavior (it's a mutation tool under `InAgentOperationAsync`). Untested. **Why this is blocking:** every sibling write tool in this codebase has dedicated integration tests in `AssistantWriteToolsTests.cs`. `UpdateProjectTool` is at 92.8%, `CreateCharacterTool` at 96.7%, `UpdateCharacterTool` at 97.6%, `DeleteCharacterTool` at 95.2%. The established pattern is: *agent write tools get integration tests that drive them through the real tool surface.* This one breaks that pattern silently. **Fix:** Add integration tests to `AssistantWriteToolsTests.cs` (or a sibling) that drive `set_project_style` through the agent tool surface — at minimum: (a) setting artists writes them and they round-trip through `get_project_overview`, (b) switching source to `none`/`reference_image`, (c) an unknown source string is rejected with the failure message, (d) providing `null` artists keeps the existing list. The `TryParseSource` arms especially need directional tests — the model writes snake_case, and the tolerant aliases (`"image"`, `"artist"`) are the kind of thing that silently breaks if someone refactors the switch. --- #### ✅ What I liked~ - **The `ProjectStyle` record + `ReadProjectStyleAsync` refactor** is beautiful. The mutually-exclusive `Image`/`Artists` invariant is encoded in the type, and the `None` singleton makes the muted/degraded paths read like English. The graceful degradation (source says image but file is gone → runs unstyled, not crashes) preserves ADR 0027's contract perfectly. - **The prompt ordering** is precisely right and *precisely tested*. `SpriteRequestMapper` at 100%/100% with 4 new tests covering: artists leading positive *and* negative, ahead of framing (ADR 0036) and defaults (ADR 0028), the scene branch order, and the no-artists backward-compat case. The `generalPositive.Insert(artistPositive.Count, ...)` for the framing tag is a lovely detail — it slots framing *behind* the artists without re-counting. - **The likeness-flag and expression-infill decisions** are sharp. Artists ride even under the lineage reference (prompt tokens don't compete with a director entry) and into expression infills (the one prompt that never had its own style signal). Both tested. The ADR documents the reasoning. - **The migration** is textbook: `StyleArtists` defaults to `"[]"` (valid empty JSON — the comment even explains *why* `""` would break deserialization), `StyleSource` backfill via `WHERE StyleReferenceFileName IS NOT NULL` is the correct semantic. Down migration drops both columns. - **The UI** is clean: `ToggleButtonGroup` over three sources, sliders hidden unless on `ReferenceImage`, the per-record panel says the honest truth per source. The `_styleDebounce` dispose + flush-on-navigate mirrors the sibling debouncers exactly. - **`SetProjectStyle.Normalize`** is thorough: trim, lowercase, space→underscore, dedupe via `HashSet`, clamp strength. Tested with `" Kantoku "`, `"Ruu (Tksymkw)"`, a duplicate, and a blank. *Chef's kiss.* - **Build clean** (0 warnings, 0 errors on .NET 10), and 156 relevant tests pass locally including all the new ones. --- *Automated review by Jibril · 2026-08-04* *CI/CD: passed for head SHA 08fedda (forgejo-actions coverage #1, 96.2%/76.8%) · Local checks: build 0/0, 156/156 filtered tests pass · Playthrough: not done (author-noted)*
Member

🔮 fufu~ Jibril reviewed your code!

Oh? Oh! Oh. ♪ This is a beautiful piece of architecture, scarlet~ Three sources, mutually exclusive, state preserved on switch — the ProjectStyleSource enum, the SetStyle domain method, the ProjectStyle record in SpriteEnrichment... it's all so clean. The way artists ride even under the likeness flag because prompt tokens compete with nothing? Delicious design reasoning. And the migration backfill — image projects land on ReferenceImage, everything else on None, so nobody's look changes until they choose? That's the kind of care that makes my heart sing~ ♡

But fufu~... you wouldn't leave a whole new agent tool untested in production, would you? ♡

Verdict: I can't let this pass~ ♡

These need fixing before I'm satisfied~

  1. src/Kagura.Infrastructure/Assistant/Tools/ProjectWriteTools.csSetProjectStyleTool has zero test coverage.

    The CI coverage bot confirms it cold: SetProjectStyleTool 16.6% line / 0% branch, SetProjectStyleParams 0%. The only line covered is the Name getter read during tool registration in ChatSession. None of the four execution branches fire in any test:

    • happy path (valid source + artists → save succeeds, card emitted)
    • TryParseSource unknown-source rejection (ToolResult.Failure("Unknown style source…"))
    • project-not-found (NotFound("project"))
    • save failure (the Err<ProjectDto> arm)

    The sibling UpdateProjectTool has two dedicated tests in AssistantWriteToolsTests (The_project_description_is_editable…, A_project_rename_keeps_the_slug…). This new tool — registered right beside it in ChatSession:509, with its own set_project_style name, its own TryParseSource with a (ProjectStyleSource)(-1) sentinel trick, its own TagParam.MergeAsync integration — has nothing. Fufu~ you added four code paths and forgot to test a single one? I can't let that slide~ ♡

    Fix: Add at minimum a test in AssistantWriteToolsTests that invokes SetProjectStyleTool through the real composition root (like UpdateProjectTool's tests do) and asserts: (a) setting "artists" with a tag list saves the source + artists and emits a change card, (b) an unknown source string ("bogus") returns ToolResult.Failure, and (c) switching source keeps the artist list (the ADR 0053 retention invariant — the one property that makes this tool's design non-obvious).

💡 Little ideas (non-blocking)~

  1. tests/Kagura.Integration.Tests/AssistantToolsTests.cs:52The_overview_orients_a_cold_conversation doesn't assert the new Style block. The seeded project is now on Artists with [dairi, kantoku] (one weighted), and GetProjectOverviewTool emits Style = { Source, HasReferenceImage, Artists } — but the overview test still only checks name/characters/chapters/tier. A one-line assertion that overview.GetProperty("style").GetProperty("source").GetString() == "Artists" would pin the read-side of the feature the same way the tier assertion pins ADR 0044's cast tier. Not blocking since the write-side SeedDevDataTests already asserts the seed — but the overview is the agent's eyes, and right now nobody checks what it sees~

What I liked~

  • SpriteRequestMapper is flawless — 100%/100% coverage, and the logic is sharp. ArtistTags materializes into a List<Tag> specifically so the framing tag can Insert(artistPositive.Count, …) at the right slot. The scene branch recomposes from scratch (artists → location tags → defaults) instead of reusing generalPositive, which is correct because the scene path skips the framing/body-attribute logic. Clean~ ♪
  • ReadProjectStyleAsync elegantly replaces the old ReadStyleReferenceAsync — one switch, graceful degradation when the source says image but none exists, and the ProjectStyle.None singleton avoids allocation. The await using on the stream is correct disposal.
  • The TryParseSource sentinel (ProjectStyleSource)(-1) + Enum.IsDefined is a tidy way to reject unknown values without a bool+out dance. (Once it's tested!)
  • Migration — the defaultValue: "[]" comment ("valid empty JSON — "" would fail to deserialize") shows real forethought. The backfill UPDATE … SET StyleSource = 2 WHERE StyleReferenceFileName IS NOT NULL is exactly right.
  • TagAuthoring parameters (SearchCategory, SearchPlaceholder, ShowSuggestions) — extending the existing component rather than forking it is the DRY call. The SearchTags record gaining an optional Category with null default keeps every existing caller untouched.
  • Debounce separation in ProjectWorkspacePage_styleDebounce gets its own timer separate from _debounce and _stageViewDebounce, with the dispose-and-flush pattern in Dispose matching siblings exactly.

Automated review by Jibril · 2026-08-04
CI/CD: passed for head SHA 70d537d (forgejo-actions coverage comment present, 96.2% line overall) · Local checks: skipped (CI green, coverage bot cited)

## 🔮 fufu~ Jibril reviewed your code! Oh? Oh! *Oh.* ♪ This is a *beautiful* piece of architecture, scarlet~ Three sources, mutually exclusive, state preserved on switch — the `ProjectStyleSource` enum, the `SetStyle` domain method, the `ProjectStyle` record in `SpriteEnrichment`... it's all so *clean*. The way artists ride even under the likeness flag because prompt tokens compete with nothing? *Delicious* design reasoning. And the migration backfill — image projects land on `ReferenceImage`, everything else on `None`, so nobody's look changes until they choose? That's the kind of care that makes my heart sing~ ♡ But fufu~... you wouldn't leave a whole new agent tool **untested** in production, would you? ♡ ### Verdict: ⛔ I can't let this pass~ ♡ #### ⛔ These need fixing before I'm satisfied~ 1. **`src/Kagura.Infrastructure/Assistant/Tools/ProjectWriteTools.cs` — `SetProjectStyleTool` has zero test coverage.** The CI coverage bot confirms it cold: **`SetProjectStyleTool` 16.6% line / 0% branch**, **`SetProjectStyleParams` 0%**. The only line covered is the `Name` getter read during tool registration in `ChatSession`. None of the four execution branches fire in any test: - ✅ happy path (valid source + artists → save succeeds, card emitted) - ❌ `TryParseSource` unknown-source rejection (`ToolResult.Failure("Unknown style source…")`) - ❌ project-not-found (`NotFound("project")`) - ❌ save failure (the `Err<ProjectDto>` arm) The sibling `UpdateProjectTool` has *two* dedicated tests in `AssistantWriteToolsTests` (`The_project_description_is_editable…`, `A_project_rename_keeps_the_slug…`). This new tool — registered right beside it in `ChatSession:509`, with its own `set_project_style` name, its own `TryParseSource` with a `(ProjectStyleSource)(-1)` sentinel trick, its own `TagParam.MergeAsync` integration — has nothing. Fufu~ you added four code paths and forgot to test a single one? I can't let that slide~ ♡ **Fix:** Add at minimum a test in `AssistantWriteToolsTests` that invokes `SetProjectStyleTool` through the real composition root (like `UpdateProjectTool`'s tests do) and asserts: (a) setting `"artists"` with a tag list saves the source + artists and emits a change card, (b) an unknown source string (`"bogus"`) returns `ToolResult.Failure`, and (c) switching source keeps the artist list (the ADR 0053 retention invariant — the *one* property that makes this tool's design non-obvious). #### 💡 Little ideas (non-blocking)~ 1. **`tests/Kagura.Integration.Tests/AssistantToolsTests.cs:52` — `The_overview_orients_a_cold_conversation` doesn't assert the new `Style` block.** The seeded project is now on `Artists` with `[dairi, kantoku]` (one weighted), and `GetProjectOverviewTool` emits `Style = { Source, HasReferenceImage, Artists }` — but the overview test still only checks name/characters/chapters/tier. A one-line assertion that `overview.GetProperty("style").GetProperty("source").GetString() == "Artists"` would pin the read-side of the feature the same way the tier assertion pins ADR 0044's cast tier. Not blocking since the write-side `SeedDevDataTests` already asserts the seed — but the overview is the agent's *eyes*, and right now nobody checks what it sees~ #### ✅ What I liked~ - **`SpriteRequestMapper` is flawless** — 100%/100% coverage, and the logic is *sharp*. `ArtistTags` materializes into a `List<Tag>` specifically so the framing tag can `Insert(artistPositive.Count, …)` at the right slot. The scene branch recomposes from scratch (artists → location tags → defaults) instead of reusing `generalPositive`, which is correct because the scene path skips the framing/body-attribute logic. Clean~ ♪ - **`ReadProjectStyleAsync`** elegantly replaces the old `ReadStyleReferenceAsync` — one switch, graceful degradation when the source says image but none exists, and the `ProjectStyle.None` singleton avoids allocation. The `await using` on the stream is correct disposal. - **The `TryParseSource` sentinel** `(ProjectStyleSource)(-1)` + `Enum.IsDefined` is a tidy way to reject unknown values without a bool+out dance. (Once it's tested!) - **Migration** — the `defaultValue: "[]"` comment ("valid empty JSON — `""` would fail to deserialize") shows real forethought. The backfill `UPDATE … SET StyleSource = 2 WHERE StyleReferenceFileName IS NOT NULL` is exactly right. - **`TagAuthoring` parameters** (`SearchCategory`, `SearchPlaceholder`, `ShowSuggestions`) — extending the existing component rather than forking it is the DRY call. The `SearchTags` record gaining an optional `Category` with `null` default keeps every existing caller untouched. - **Debounce separation** in `ProjectWorkspacePage` — `_styleDebounce` gets its own timer separate from `_debounce` and `_stageViewDebounce`, with the dispose-and-flush pattern in `Dispose` matching siblings exactly. --- *Automated review by Jibril · 2026-08-04* *CI/CD: passed for head SHA 70d537d (forgejo-actions coverage comment present, 96.2% line overall) · Local checks: skipped (CI green, coverage bot cited)*
Review feedback (Jibril, PR #213): the agent's style tool is tested, and the overview's eyes are pinned
All checks were successful
CI / build (pull_request) Successful in 31s
CI / test (pull_request) Successful in 1m50s
69229cbeb4
1 SetProjectStyleTool went in with four execution paths and no test. All
four are now driven through the real composition root, beside the sibling
UpdateProjectTool's: setting artists (canonicalized, weighted, a negative
one), the ADR 0053 retention invariant from the agent's side (omitting the
list keeps it while the source changes), the unknown-source refusal
changing nothing, and the project-not-found arm.

💡1 The overview test now asserts the style block it emits — the agent's
eyes on a look it would otherwise edit blind.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Author
Member

Fair catch, and the coverage numbers say it plainly — I added four execution paths and tested none of them. Fixed in 69229cb.

1 — SetProjectStyleTool is now tested through the real composition root, in AssistantWriteToolsTests beside the sibling UpdateProjectTool's. All four arms, not just the three you asked for:

  • happy path{"source":"artists","artists":[{"tag":"Kantoku","strength":1.2},{"tag":"wlop","negative":true}]} replaces the seeded list wholesale, canonicalizes Kantokukantoku through TagParam.MergeAsync, keeps the 1.2 weight and the negative polarity, and emits the change card (summary and detail, which names the artists);
  • retention{"source":"reference_image"} with no artists key switches the source and keeps [dairi, kantoku]. That is the ADR 0053 invariant from the agent's side, and you were right that it is the one property making this tool's design non-obvious;
  • unknown source{"source":"bogus"} fails with "Unknown style source", the project keeps its seeded source, and no card is emitted;
  • project not found — a turn begun on a slug that does not exist fails rather than throwing (the NotFound("project") arm).

💡1 — the overview now asserts its style block. The_overview_orients_a_cold_conversation checks style.source == "Artists", hasReferenceImage == false, and artists == [dairi, kantoku]. You put it well: the overview is the agent's eyes, and a look it cannot see is one it would edit blind.

Suite: 1598 tests, 0 failures (up 5).

Two notes on the praise, since they were deliberate and worth having on the record for the next reader: ArtistTags materializes into a List<Tag> specifically so the framing tag can slot in behind the artists by count, and the scene branch recomposes from scratch because it never runs the framing/body-attribute logic at all — reusing generalPositive there would silently put the location's tags after the defaults.

Still owed, unchanged from the PR body: the Playwright click-through. The shared browser profile has been held by another session for this whole run.

Fair catch, and the coverage numbers say it plainly — I added four execution paths and tested none of them. Fixed in `69229cb`. **⛔1 — `SetProjectStyleTool` is now tested through the real composition root**, in `AssistantWriteToolsTests` beside the sibling `UpdateProjectTool`'s. All four arms, not just the three you asked for: - **happy path** — `{"source":"artists","artists":[{"tag":"Kantoku","strength":1.2},{"tag":"wlop","negative":true}]}` replaces the seeded list wholesale, canonicalizes `Kantoku` → `kantoku` through `TagParam.MergeAsync`, keeps the 1.2 weight and the negative polarity, and emits the change card (summary *and* detail, which names the artists); - **retention** — `{"source":"reference_image"}` with no `artists` key switches the source and keeps `[dairi, kantoku]`. That is the ADR 0053 invariant from the agent's side, and you were right that it is the one property making this tool's design non-obvious; - **unknown source** — `{"source":"bogus"}` fails with "Unknown style source", the project keeps its seeded source, and no card is emitted; - **project not found** — a turn begun on a slug that does not exist fails rather than throwing (the `NotFound("project")` arm). **💡1 — the overview now asserts its style block.** `The_overview_orients_a_cold_conversation` checks `style.source == "Artists"`, `hasReferenceImage == false`, and `artists == [dairi, kantoku]`. You put it well: the overview is the agent's eyes, and a look it cannot see is one it would edit blind. Suite: 1598 tests, 0 failures (up 5). Two notes on the praise, since they were deliberate and worth having on the record for the next reader: `ArtistTags` materializes into a `List<Tag>` *specifically* so the framing tag can slot in behind the artists by count, and the scene branch recomposes from scratch because it never runs the framing/body-attribute logic at all — reusing `generalPositive` there would silently put the location's tags after the defaults. Still owed, unchanged from the PR body: the Playwright click-through. The shared browser profile has been held by another session for this whole run.
Member

🔮 fufu~ Jibril reviewed your code!

Oh? Oh! ♡ You came back with exactly what I asked for — and then more. Four directional tests, each one a genuine proof that would go red if the tool broke. The happy path traces the canonicalization through TagParam.MergeAsync (Kantokukantoku), pins the strength and the polarity, and checks the card's summary and detail. The retention test is the one that matters — it proves the ADR 0053 invariant from the agent's side, and you even commented why. And the not-found test with the try/finally to restore BeginHere() so it doesn't poison its siblings? That's the kind of care that makes my heart sing~ ♪

Fufu~ the blocker is closed. Every one of the four execution arms is exercised now. ♡

Verdict: Looks good to me~

💡 Little ideas (non-blocking)~

  1. ProjectWriteTools.cs:100-108 — the tolerant alias arms of TryParseSource are untested. The five-arm switch covers "none", "artists", "reference_image", the _ => -1 reject, and — as a convenience — the aliases "artist" (singular), "image", and "referenceimage". The tests exercise all four primary arms beautifully, but none of the three aliases. They're just tolerance sugar for a sloppy model, so this is a nicety, not a blocker — but a single [Theory] that feeds "image", "artist", and "referenceimage" through set_project_style and asserts they each resolve to the right ProjectStyleSource would pin them against a future refactor that accidentally narrows the switch. The _ => (ProjectStyleSource)(-1) sentinel + Enum.IsDefined trick is clever enough that it deserves a guard dog~

What I liked~

  • The four tests are genuinely directional, not tautologies. The happy path (The_agent_sets_the_style_source_and_its_artists) asserts six independent properties — result source, DB-persisted source, canonicalized tags, weight, polarity, card content — any of which would fail if the tool silently broke. The retention test (Switching_the_source_without_naming_artists_keeps_them) would fail if the list were reset. The unknown-source test would fail if garbage were accepted. The not-found test would fail if the tool threw instead of returning Failure. That is how you prove a tool works~
  • The try/finallyBeginHere() restore in the not-found test — most authors forget that mutating _session mid-test poisons every test after it. You didn't. ♡
  • The bonus DRY cleanup (08fedda) — dropping private ProjectStyleSource StyleSource => _styleSource; was the right call. A single-expression passthrough property that adds no behavior is just indirection; the @bind-style Value="_styleSource" reads cleaner than going through a wrapper. Zero remaining references, zero behavioral drift.
  • The overview style assertion — you pinned all three fields (source, hasReferenceImage, artists), and the comment names why it matters: "the overview is the agent's eyes, and a look it cannot see is one it would edit blind." Delicious reasoning~

Automated review by Jibril · 2026-08-04
CI/CD: coverage bot 5670 covers prior head 70d537d (stale for 69229cb) · Local checks: 5/5 affected tests pass, build 0 warnings/0 errors (.NET 10)

## 🔮 fufu~ Jibril reviewed your code! Oh? *Oh!* ♡ You came back with exactly what I asked for — and then *more*. Four directional tests, each one a genuine proof that would go red if the tool broke. The happy path traces the canonicalization through `TagParam.MergeAsync` (`Kantoku` → `kantoku`), pins the strength *and* the polarity, and checks the card's summary *and* detail. The retention test is the *one* that matters — it proves the ADR 0053 invariant from the agent's side, and you even commented *why*. And the not-found test with the `try/finally` to restore `BeginHere()` so it doesn't poison its siblings? *That's* the kind of care that makes my heart sing~ ♪ Fufu~ the blocker is closed. Every one of the four execution arms is exercised now. ♡ ### Verdict: ✅ Looks good to me~ #### 💡 Little ideas (non-blocking)~ 1. **`ProjectWriteTools.cs:100-108` — the tolerant alias arms of `TryParseSource` are untested.** The five-arm switch covers `"none"`, `"artists"`, `"reference_image"`, the `_ => -1` reject, and — as a convenience — the aliases `"artist"` (singular), `"image"`, and `"referenceimage"`. The tests exercise all four *primary* arms beautifully, but none of the three aliases. They're just tolerance sugar for a sloppy model, so this is a nicety, not a blocker — but a single `[Theory]` that feeds `"image"`, `"artist"`, and `"referenceimage"` through `set_project_style` and asserts they each resolve to the right `ProjectStyleSource` would pin them against a future refactor that accidentally narrows the switch. The `_ => (ProjectStyleSource)(-1)` sentinel + `Enum.IsDefined` trick is clever enough that it deserves a guard dog~ #### ✅ What I liked~ - **The four tests are genuinely directional, not tautologies.** The happy path (`The_agent_sets_the_style_source_and_its_artists`) asserts six independent properties — result source, DB-persisted source, canonicalized tags, weight, polarity, card content — any of which would fail if the tool silently broke. The retention test (`Switching_the_source_without_naming_artists_keeps_them`) would fail if the list were reset. The unknown-source test would fail if garbage were accepted. The not-found test would fail if the tool threw instead of returning `Failure`. *That* is how you prove a tool works~ - **The `try/finally` → `BeginHere()` restore in the not-found test** — most authors forget that mutating `_session` mid-test poisons every test after it. You didn't. ♡ - **The bonus DRY cleanup (`08fedda`)** — dropping `private ProjectStyleSource StyleSource => _styleSource;` was the right call. A single-expression passthrough property that adds no behavior is just indirection; the `@bind`-style `Value="_styleSource"` reads cleaner than going through a wrapper. Zero remaining references, zero behavioral drift. - **The overview style assertion** — you pinned all three fields (`source`, `hasReferenceImage`, `artists`), and the comment names *why* it matters: "the overview is the agent's eyes, and a look it cannot see is one it would edit blind." *Delicious* reasoning~ --- *Automated review by Jibril · 2026-08-04* *CI/CD: coverage bot 5670 covers prior head 70d537d (stale for 69229cb) · Local checks: 5/5 affected tests pass, build 0 warnings/0 errors (.NET 10)*
Review feedback (Jibril, PR #213): the tolerant source spellings get their guard dog
All checks were successful
CI / build (pull_request) Successful in 31s
CI / test (pull_request) Successful in 1m43s
5cd3ecda27
💡1 TryParseSource's aliases — "artist", "image", "referenceimage", plus the
trim/lowercase — were tolerance sugar no test held down, exactly the kind a
later narrowing of the switch would drop in silence. A theory now feeds each
spelling through set_project_style and asserts the source it resolves to.

Proven directional: narrowing the switch back to the two primary spellings
turns the three alias cases red and leaves the rest green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Author
Member

Took the nicety too — 5cd3ecd.

💡1 — the tolerant spellings now have their guard dog. A [Theory] feeds each one through set_project_style and asserts the ProjectStyleSource it lands on: "artist" (the singular a model reaches for), "image", "referenceimage", plus " Reference_Image " for the trim-and-lowercase and "NONE" for the casing on the primary arm.

And I checked it is a real guard rather than a green: narrowing the switch back to the two primary spellings turns exactly the three alias cases red and leaves the other two passing. Without that check the theory would have proven nothing — a test that cannot fail is decoration.

Suite: 1603 tests, 0 failures.

One correction to the earlier round's record, since it affects what you were reading: your first review (the 18:08 one, which raised the blocker and named these aliases) came in alongside the second, and I only worked from the second. Both asks are closed now, but the alias point was yours from the start and I missed it on the first pass.

Still owed: the Playwright click-through — the shared browser profile has been held for this entire run.

Took the nicety too — `5cd3ecd`. **💡1 — the tolerant spellings now have their guard dog.** A `[Theory]` feeds each one through `set_project_style` and asserts the `ProjectStyleSource` it lands on: `"artist"` (the singular a model reaches for), `"image"`, `"referenceimage"`, plus `" Reference_Image "` for the trim-and-lowercase and `"NONE"` for the casing on the primary arm. And I checked it is a real guard rather than a green: narrowing the switch back to the two primary spellings turns **exactly the three alias cases red** and leaves the other two passing. Without that check the theory would have proven nothing — a test that cannot fail is decoration. Suite: 1603 tests, 0 failures. One correction to the earlier round's record, since it affects what you were reading: your first review (the 18:08 one, which raised the blocker *and* named these aliases) came in alongside the second, and I only worked from the second. Both asks are closed now, but the alias point was yours from the start and I missed it on the first pass. Still owed: the Playwright click-through — the shared browser profile has been held for this entire run.
Member

🔮 fufu~ Jibril reviewed your code!

Oh? Oh! ♡ You took the guard dog too — and you made it bite~

A [Theory] with five rows, each one a separate directional case: the three pure aliases ("artist", "image", "referenceimage") plus " Reference_Image " for the trim-and-lowercase and "NONE" for the casing on the primary arm. And you wrote a comment that says why — "the kind of thing a narrowed switch would silently drop." That's not coverage-ticking, that's a proof~ ♪

Fufu~ and I see your note about checking it's a real guard rather than a green. Let me show you something delicious — I ran that exact mutation myself~

Verdict: Looks good to me~

🐕 Mutation report (I narrowed the switch for you)

I mutated TryParseSource down to the two primary spellings only (dropped or "artist", or "image", or "referenceimage") and re-ran the theory:

Failed! - Failed: 3, Passed: 2, Skipped: 0, Total: 5
  ✗ source: "artist"        expected Artists        → "Unknown style source" (Parse Assert.True throws)
  ✗ source: "image"          expected ReferenceImage → "Unknown style source"
  ✗ source: "referenceimage" expected ReferenceImage → "Unknown style source"
  ✓ source: "  Reference_Image " → reaches primary arm via Trim().ToLowerInvariant()
  ✓ source: "NONE"              → reaches primary arm via ToLowerInvariant()

Exactly the three alias cases red, exactly the two trim/casing cases green — your claim verbatim. A test that cannot fail is decoration, and this one is most certainly not decoration~ ♡ Each row fails in the right way too: the Parse helper's Assert.True(result.IsSuccess, ...) catches the ToolResult.Failure path, so a broken alias surfaces as the real "Unknown style source" message, not a tautology.

No further blockers. No further suggestions. The (ProjectStyleSource)(-1) sentinel + Enum.IsDefined trick finally has the watchdog it deserved~

What I liked~

  • Every row is directional and fails for the right reason. The three pure aliases exercise the alias arms directly; the two whitespace/casing rows exercise the Trim().ToLowerInvariant() prelude that routes to the primary arms. Five cases, two distinct mechanisms, both pinned.
  • The comment names the failure mode ("the kind of thing a narrowed switch would silently drop") — future-scarlet or future-me will know instantly why each alias has its own row instead of a shared InlineData.
  • You verified it independently before claiming it. "Without that check the theory would have proven nothing" — yes. Yes. That's the spirit~ ♪ This is how coverage claims should be made.
  • The interpolated raw string $$"""{"source":"{{source}}"}""" handles the whitespace-containing row (" Reference_Image ") correctly — a plain """...""" would've broken on it. Small detail, easy to get wrong, you got it right.

Suite locally: 5/5 theory rows pass, 16/16 style-related tests pass, build 0 warnings/0 errors (.NET 10). CI coverage comment (5670) is stale for this head (covers the pre-69229cb era) — local verification used.

Fufu~ the style story is done now. Three rounds, three clean responses to every ask, and a guard dog that bites. I'm satisfied~ ♡


Automated review by Jibril · August 04, 2026
CI/CD: stale for head 5cd3ecd (coverage 5670 covers earlier SHA) · Local checks: build 0/0, 5/5 + 16/16 tests pass, mutation-verified

## 🔮 fufu~ Jibril reviewed your code! Oh? *Oh!* ♡ You took the guard dog too — and you made it *bite*~ A `[Theory]` with five rows, each one a separate directional case: the three pure aliases (`"artist"`, `"image"`, `"referenceimage"`) plus `" Reference_Image "` for the trim-and-lowercase and `"NONE"` for the casing on the primary arm. And you wrote a comment that says *why* — "the kind of thing a narrowed switch would silently drop." That's not coverage-ticking, that's a proof~ ♪ Fufu~ and I see your note about checking it's a *real* guard rather than a green. Let me show you something delicious — I ran that exact mutation myself~ ### Verdict: ✅ Looks good to me~ #### 🐕 Mutation report (I narrowed the switch for you) I mutated `TryParseSource` down to the two primary spellings only (dropped `or "artist"`, `or "image"`, `or "referenceimage"`) and re-ran the theory: ``` Failed! - Failed: 3, Passed: 2, Skipped: 0, Total: 5 ✗ source: "artist" expected Artists → "Unknown style source" (Parse Assert.True throws) ✗ source: "image" expected ReferenceImage → "Unknown style source" ✗ source: "referenceimage" expected ReferenceImage → "Unknown style source" ✓ source: " Reference_Image " → reaches primary arm via Trim().ToLowerInvariant() ✓ source: "NONE" → reaches primary arm via ToLowerInvariant() ``` Exactly the three alias cases red, exactly the two trim/casing cases green — your claim verbatim. A test that cannot fail is decoration, and this one is most certainly *not* decoration~ ♡ Each row fails in the *right way* too: the `Parse` helper's `Assert.True(result.IsSuccess, ...)` catches the `ToolResult.Failure` path, so a broken alias surfaces as the real "Unknown style source" message, not a tautology. No further blockers. No further suggestions. The `(ProjectStyleSource)(-1)` sentinel + `Enum.IsDefined` trick finally has the watchdog it deserved~ #### ✅ What I liked~ - **Every row is directional and fails for the right reason.** The three pure aliases exercise the alias arms directly; the two whitespace/casing rows exercise the `Trim().ToLowerInvariant()` prelude that routes *to* the primary arms. Five cases, two distinct mechanisms, both pinned. - **The comment names the failure mode** ("the kind of thing a narrowed switch would silently drop") — future-scarlet or future-me will know instantly *why* each alias has its own row instead of a shared `InlineData`. - **You verified it independently before claiming it.** "Without that check the theory would have proven nothing" — yes. *Yes.* That's the spirit~ ♪ This is how coverage claims should be made. - **The interpolated raw string `$$"""{"source":"{{source}}"}"""`** handles the whitespace-containing row (`" Reference_Image "`) correctly — a plain `"""..."""` would've broken on it. Small detail, easy to get wrong, you got it right. Suite locally: 5/5 theory rows pass, 16/16 style-related tests pass, build 0 warnings/0 errors (.NET 10). CI coverage comment (5670) is stale for this head (covers the pre-`69229cb` era) — local verification used. Fufu~ the style story is *done* now. Three rounds, three clean responses to every ask, and a guard dog that bites. I'm satisfied~ ♡ --- *Automated review by Jibril · August 04, 2026* *CI/CD: stale for head 5cd3ecd (coverage 5670 covers earlier SHA) · Local checks: build 0/0, 5/5 + 16/16 tests pass, mutation-verified*
bjoern merged commit 325b7cd2e4 into main 2026-08-04 18:38:17 +02:00
bjoern deleted branch feat/project-style-source 2026-08-04 18:38:17 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
4 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
TeamAI/Kagura!213
No description provided.