Skip to content

refactor: continue trivial wrapper cleanup#335

Open
Nek-12 wants to merge 15 commits into
mainfrom
fix/workflow-editor-protocol-prompts
Open

refactor: continue trivial wrapper cleanup#335
Nek-12 wants to merge 15 commits into
mainfrom
fix/workflow-editor-protocol-prompts

Conversation

@Nek-12

@Nek-12 Nek-12 commented Jun 8, 2026

Copy link
Copy Markdown
Member

Summary

  • Continue removing and inlining trivial Go wrappers after PR fix: harden workflow editor protocol prompts #334 merged.
  • Reduce the strict audit exported bucket from 644 at resumed-goal handoff to 599.
  • Inline internal app/TUI helper wrappers, test-only getters, and forwarding methods while preserving behavior.

Verification

  • go test ./...
  • targeted package tests for cli/app, cli/tui, cli/builder, server/runtimecontrol, and affected internal packages

Summary by CodeRabbit

  • Refactor

    • Leaner internal flows for auth, session, runtime and onboarding for more consistent sign-in and session transitions.
    • Command registration now preserves prompt-history drafts for common slash commands.
    • Selection/navigation streamlined across worktree/project pickers for more predictable cursor movement.
    • Native streaming and rendering paths consolidated for more stable resize/commit behavior.
  • Style

    • Unified UI text and header styling to use consistent theme foreground intents.
  • Bug Fixes

    • Improved interruption detection, transcript sync handling, and more deterministic pending-tool spinner timing.

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR inlines many small helper functions across CLI, TUI, and server code: auth predicates, runtime reducers, UI/TUI rendering and role serialization, onboarding normalization, worktree/session validation, command registry changes, prompt-event wiring, native streaming tail/update behavior, and various service-side helpers. Tests updated where they depended on removed helpers or accessors.

Changes

Helper function removal and logic inlining

Layer / File(s) Summary
Auth policy & gate
cli/app/internal/authinteraction/policy.go, cli/app/auth_gate.go, cli/app/internal/authinteraction/policy_test.go
Auth-interaction predicates were consolidated; interactor NeedsInteraction logic is rewritten inline and the env-conflict predicate is kept as the exported helper.
Runtime reducers & sync
cli/app/internal/runtimestate/runtime_events.go, cli/app/ui_runtime_event_reduction.go, cli/app/ui_runtime_adapter.go
Lifecycle and sync helper APIs removed; reducers and adapter now use direct submission-state constants and Reason-based transcript-sync checks.
TUI role & rendering consolidation
cli/tui/transcript_intents.go, cli/tui/model_rendering.go, cli/tui/model_rendering_entries.go, cli/tui/transcript_projection.go, cli/tui/*
Role-to-wire helpers removed; roles are passed as strings and decoded via TranscriptRoleFromWire at render boundaries; flattening unified to meta+symbol flatteners with inline width/prefix logic.
UI model accessors and tests
cli/app/ui.go, cli/app/*_test.go
Removed uiModel accessors (Action, TerminalFocused/Known); tests now read fields directly (exitAction, terminalFocus) and command tests use RegisterWithOptions.
Worktree/session helper inlining
cli/app/internal/worktreecreate/*, cli/app/internal/worktreedelete/*, cli/app/internal/sessiontarget/*, cli/app/ui_worktree_*
ValidateTarget, UsesBaseRef, ResolveToken, and similar helpers removed; validation, base-ref behavior, delete previews, and token resolution inlined or implemented client-side.
Project picker & binding flow
cli/app/internal/projectpicker/picker.go, cli/app/project_binding_flow.go
Item-count/first-row helpers removed; visible rows, group headers, and project-index mapping compute offsets inline with AllowCreate-aware itemCount; header/notice styling uses ApplyThemeStyleIntents.
Commands registry changes
cli/app/commands/commands.go, cli/app/commands/prompt_commands.go
Registry.Register removed; default commands use RegisterWithOptions with PreservePromptHistoryDraft enabled; tests adjusted accordingly.
Submission interruption checks
cli/app/internal/submissionerror/errors.go, cli/app/ui_input_*.go
IsInterrupted helper removed; error handlers now use errors.Is for ErrInterrupted and context.Canceled.
Native streaming controller
cli/app/ui_native_stream_controller.go, cli/app/ui_native_history.go, cli/app/ui_window_reducer.go
FinalizeSource/Resize/Tail removed; controller Configure/ApplySource/Finalize used and native streaming tail is rebuilt from rendered projections after width changes.
Prompt events & lease id
cli/app/prompt_events.go
promptEventEmitter.channel and currentControllerLeaseID removed; callers cast emitter.out and read leaseManager.Value() with nil checks inline.
Misc inlines & formatting
cli/actions/registry.go, cli/app/internal/status/status.go, cli/builder/*, server/runtimecontrol/service.go, cli/tui/ansi_style_transform.go
Handler lookup, cache-key, stdout/stderr assembly, timeout/default selection, and goal-response/error construction inlined; ApplyThemeDefaultForeground removed and callers switched to ApplyThemeStyleIntents.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • respawn-llc/builder#328: Overlaps on runtime transcript synchronization and UI control-flow refactors; may conflict with sync/reducer logic changes.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/workflow-editor-protocol-prompts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fef5820af3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

m.nativeStreamingController.Configure(m.nativeStreamingController.theme, msg.Width)
m.nativeStreamingWidth = msg.Width
m.nativeStreamingTail = cloneNativeStreamProjectionLines(m.nativeStreamingController.Tail())
m.nativeStreamingTail = cloneNativeStreamProjectionLines(m.nativeStreamingController.rendered[m.nativeStreamingController.enqueuedStableLineCount:])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Guard resized stream tail before slicing

When an assistant stream has already promoted stable lines at a narrow width, widening the terminal can make the re-rendered projection shorter than enqueuedStableLineCount. Configure marks invalidatedByResize for exactly this case, but this slice runs before the invalidation branch, so a WindowSizeMsg during streaming can panic with a slice-bounds error instead of replaying the stream. Check invalidatedByResize or clamp the index before slicing.

Useful? React with 👍 / 👎.

}
m.nativeStreamingStableFlushSequence = 0
m.nativeStreamingTail = m.nativeStreamingController.Tail()
m.nativeStreamingTail = cloneNativeStreamProjectionLines(m.nativeStreamingController.rendered[m.nativeStreamingController.enqueuedStableLineCount:])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle invalidated stream before ack slicing

If a stable streaming flush is awaiting ack and the terminal is resized, the controller may be invalidated and re-rendered to fewer lines than the old enqueuedStableLineCount. This ack path now slices before checking invalidatedByResize, so the next flush ack can still panic even if the resize handler is fixed; use the invalidated full-tail path or clamp before taking the suffix.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
cli/app/ui_native_stream_controller.go (1)

64-79: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Clamp stable-line index after resize re-render to prevent slice panics.

Configure can shrink c.rendered on width/theme changes while leaving c.enqueuedStableLineCount larger than the new rendered length. The next stable/tail slice can panic at runtime.

Proposed fix
func (c *nativeAssistantStreamController) Configure(theme string, width int) {
    width = normalizedNativeStreamWidth(width)
    if theme == "" {
        theme = "dark"
    }
    if width == c.width && theme == c.theme {
        return
    }
    hadStable := c.enqueuedStableLineCount > 0
    c.width = width
    c.theme = theme
    if c.source != "" {
        c.invalidatedByResize = c.invalidatedByResize || hadStable
        c.rendered = tui.RenderAssistantMarkdownProjection(c.source, c.theme, c.width)
+       if c.enqueuedStableLineCount > len(c.rendered) {
+           c.enqueuedStableLineCount = len(c.rendered)
+       }
    }
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/app/ui_native_stream_controller.go` around lines 64 - 79, Configure can
shrink c.rendered when theme/width changes while c.enqueuedStableLineCount may
still be larger than the new rendered length, causing later slices to panic;
after you set c.rendered in nativeAssistantStreamController.Configure (the block
where you call tui.RenderAssistantMarkdownProjection and assign c.rendered),
clamp c.enqueuedStableLineCount to at most len(c.rendered) (e.g., set
c.enqueuedStableLineCount = min(c.enqueuedStableLineCount, len(c.rendered))) and
adjust any related invalidation flags if needed so subsequent stable/tail
slicing cannot index past the slice.
cli/app/ui_native_stream_controller_test.go (1)

120-135: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add a resize reflow regression case where rendered lines decrease.

This test validates invalidation, but it does not exercise the boundary where Configure reduces rendered line count below previously promoted stable lines. Please add that case and assert no panic through subsequent update/ack flow.

As per coding guidelines, "**/*_test.go: All business logic covered by tests. Production code is written to be unit-testable."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/app/ui_native_stream_controller_test.go` around lines 120 - 135, Add a
regression test that exercises the boundary where Configure reduces the rendered
line count below already-promoted stable lines: create a controller with
newNativeAssistantStreamController(..., 72), Append enough lines to cause
promotion to update.stable, then call Configure(controller.theme, 24) to shrink
rendered lines, then Append another line and call the subsequent ack/update flow
(use controller.Append and controller.Ack or the existing ack path) and assert
no panic occurs and the update indicates promotion was invalidated
(update.stable is empty), the live tail (update.tail) contains the new content,
and update.needsReplay is true; reference the
TestNativeAssistantStreamControllerResizeInvalidatesFurtherPromotion test,
Configure, Append, Ack, update.stable, update.tail, and update.needsReplay when
adding the case.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cli/app/internal/runtimestate/runtime_events_test.go`:
- Around line 34-35: The test currently only asserts that
update.PendingInput.State.Submission is not InputSubmissionLocked; instead
assert it equals the explicit unlocked value to prevent regressions to
zero-value. Update the assertion around update.PendingInput.State.Submission in
the runtime_events_test (the block using InputSubmissionLocked) to compare
against InputSubmissionUnlocked (the expected constant) so the test enforces the
stronger post-condition.

In `@cli/tui/model_rendering.go`:
- Line 134: The detail-rendering closures for reasoning/streaming are discarding
the provided symbolOverride by passing a hardcoded "" into
flattenEntryWithMetaAndSymbol; update each closure that currently calls
model.flattenEntryWithMetaAndSymbol(RenderIntentReasoning, thinkingText, false,
nil, "") (and the similar calls at the other noted sites) to forward the local
symbolOverride variable instead of the empty string so non-default symbol
rendering is preserved.

---

Outside diff comments:
In `@cli/app/ui_native_stream_controller_test.go`:
- Around line 120-135: Add a regression test that exercises the boundary where
Configure reduces the rendered line count below already-promoted stable lines:
create a controller with newNativeAssistantStreamController(..., 72), Append
enough lines to cause promotion to update.stable, then call
Configure(controller.theme, 24) to shrink rendered lines, then Append another
line and call the subsequent ack/update flow (use controller.Append and
controller.Ack or the existing ack path) and assert no panic occurs and the
update indicates promotion was invalidated (update.stable is empty), the live
tail (update.tail) contains the new content, and update.needsReplay is true;
reference the
TestNativeAssistantStreamControllerResizeInvalidatesFurtherPromotion test,
Configure, Append, Ack, update.stable, update.tail, and update.needsReplay when
adding the case.

In `@cli/app/ui_native_stream_controller.go`:
- Around line 64-79: Configure can shrink c.rendered when theme/width changes
while c.enqueuedStableLineCount may still be larger than the new rendered
length, causing later slices to panic; after you set c.rendered in
nativeAssistantStreamController.Configure (the block where you call
tui.RenderAssistantMarkdownProjection and assign c.rendered), clamp
c.enqueuedStableLineCount to at most len(c.rendered) (e.g., set
c.enqueuedStableLineCount = min(c.enqueuedStableLineCount, len(c.rendered))) and
adjust any related invalidation flags if needed so subsequent stable/tail
slicing cannot index past the slice.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7f40cf61-9ffc-45a6-be9c-30ed4d9f60c6

📥 Commits

Reviewing files that changed from the base of the PR and between 6586413 and fbb17dc.

📒 Files selected for processing (75)
  • cli/actions/registry.go
  • cli/app/auth_gate.go
  • cli/app/auth_picker.go
  • cli/app/internal/authinteraction/policy.go
  • cli/app/internal/authinteraction/policy_test.go
  • cli/app/internal/onboardingimportgenerated/generated.go
  • cli/app/internal/onboardingimportskills/skills.go
  • cli/app/internal/onboardingimportskills/skills_test.go
  • cli/app/internal/projectpicker/picker.go
  • cli/app/internal/projectpicker/picker_test.go
  • cli/app/internal/runtimestate/runtime_events.go
  • cli/app/internal/runtimestate/runtime_events_test.go
  • cli/app/internal/sessiontarget/target.go
  • cli/app/internal/sessiontarget/target_test.go
  • cli/app/internal/status/status.go
  • cli/app/internal/submissionerror/errors.go
  • cli/app/internal/submissionerror/errors_test.go
  • cli/app/internal/worktreecreate/create.go
  • cli/app/internal/worktreecreate/create_test.go
  • cli/app/internal/worktreecreateform/form.go
  • cli/app/internal/worktreecreateform/form_test.go
  • cli/app/internal/worktreecreateresolve/resolve.go
  • cli/app/internal/worktreedelete/delete.go
  • cli/app/internal/worktreeselection/selection.go
  • cli/app/onboarding_imports.go
  • cli/app/onboarding_test.go
  • cli/app/project_binding_flow.go
  • cli/app/project_name_prompt.go
  • cli/app/session_lifecycle_test.go
  • cli/app/session_server_target.go
  • cli/app/ui.go
  • cli/app/ui_focus_test.go
  • cli/app/ui_input_resume.go
  • cli/app/ui_input_submission.go
  • cli/app/ui_layout.go
  • cli/app/ui_lifecycle_state.go
  • cli/app/ui_native_history.go
  • cli/app/ui_native_history_projection.go
  • cli/app/ui_native_stream_controller.go
  • cli/app/ui_native_stream_controller_test.go
  • cli/app/ui_part2_test.go
  • cli/app/ui_part6_test.go
  • cli/app/ui_part7_test.go
  • cli/app/ui_part8_test.go
  • cli/app/ui_pending_tools.go
  • cli/app/ui_runtime_adapter.go
  • cli/app/ui_runtime_event_reduction.go
  • cli/app/ui_runtime_status.go
  • cli/app/ui_slash_command_picker_test.go
  • cli/app/ui_status.go
  • cli/app/ui_transcript_entries.go
  • cli/app/ui_transcript_mode.go
  • cli/app/ui_transcript_pager.go
  • cli/app/ui_window_reducer.go
  • cli/app/ui_worktree_commands_test.go
  • cli/app/ui_worktree_create_controller.go
  • cli/app/ui_worktree_list_controller.go
  • cli/app/ui_worktree_render.go
  • cli/builder/service_backend_darwin.go
  • cli/builder/service_backend_windows.go
  • cli/builder/service_types.go
  • cli/tui/ansi_style_transform.go
  • cli/tui/detail_rendering.go
  • cli/tui/model_reducer.go
  • cli/tui/model_rendering.go
  • cli/tui/model_rendering_entries.go
  • cli/tui/model_rendering_entries_test.go
  • cli/tui/model_rendering_style.go
  • cli/tui/model_rendering_tools.go
  • cli/tui/pending_snapshot.go
  • cli/tui/roles.go
  • cli/tui/transcript_intents.go
  • cli/tui/transcript_intents_test.go
  • cli/tui/transcript_projection.go
  • server/runtimecontrol/service.go
💤 Files with no reviewable changes (12)
  • cli/app/internal/submissionerror/errors_test.go
  • cli/app/internal/worktreeselection/selection.go
  • cli/app/internal/status/status.go
  • cli/tui/ansi_style_transform.go
  • cli/app/internal/authinteraction/policy.go
  • cli/app/ui.go
  • cli/app/internal/onboardingimportskills/skills_test.go
  • cli/app/internal/sessiontarget/target.go
  • cli/tui/transcript_intents.go
  • cli/app/internal/sessiontarget/target_test.go
  • cli/app/internal/projectpicker/picker_test.go
  • cli/app/internal/worktreecreateform/form_test.go

Comment on lines +34 to 35
if update.PendingInput.State.Submission == InputSubmissionLocked {
t.Fatal("expected input submit lock cleared")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Assert the explicit unlocked state here.

Line 34 only proves the reducer didn't leave Submission as InputSubmissionLocked. After this refactor, the contract is stronger: it should become InputSubmissionUnlocked. As written, a regression to the zero value ("") would still pass.

As per coding guidelines, "All business logic covered by tests. Production code is written to be unit-testable."

Suggested test tightening
-	if update.PendingInput.State.Submission == InputSubmissionLocked {
-		t.Fatal("expected input submit lock cleared")
+	if update.PendingInput.State.Submission != InputSubmissionUnlocked {
+		t.Fatalf("expected input submit lock cleared to %q, got %q", InputSubmissionUnlocked, update.PendingInput.State.Submission)
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/app/internal/runtimestate/runtime_events_test.go` around lines 34 - 35,
The test currently only asserts that update.PendingInput.State.Submission is not
InputSubmissionLocked; instead assert it equals the explicit unlocked value to
prevent regressions to zero-value. Update the assertion around
update.PendingInput.State.Submission in the runtime_events_test (the block using
InputSubmissionLocked) to compare against InputSubmissionUnlocked (the expected
constant) so the test enforces the stronger post-condition.

Source: Coding guidelines

Comment thread cli/tui/model_rendering.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
cli/app/onboarding_render.go (1)

300-304: ⚡ Quick win

Consider extracting duplicated normalization logic.

The theme summary formatting (lines 300-304), verbosity normalization (lines 319-322), and reviewer frequency normalization (lines 333-336) duplicate logic from onboarding_flow.go lines 167-170, 188-191, and 196-199 respectively. Extracting these to small helper functions would provide a single source of truth and simplify future updates.

♻️ Example extraction for theme summary
// In onboarding_flow.go or a shared location
func formatThemeSummary(settingsTheme string) string {
	themeSummary := theme.Auto + " (" + theme.Resolve(settingsTheme) + ")"
	if theme.IsExplicit(settingsTheme) {
		themeSummary = theme.Resolve(settingsTheme)
	}
	return themeSummary
}

Then use formatThemeSummary(state.settings.Theme) in both files.

Also applies to: 319-322, 333-336

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/app/onboarding_render.go` around lines 300 - 304, Extract the duplicated
normalization/formatting logic into shared helper functions and call them from
both onboarding_render.go and onboarding_flow.go: create
formatThemeSummary(settingsTheme string) that encapsulates the sharedtheme.Auto
+ " (" + sharedtheme.Resolve(...) + ")" and the sharedtheme.IsExplicit(...)
branch (used where themeSummary is built for appendRow), create
formatVerbositySummary(settingsVerbosity string) to centralize the verbosity
normalization used around the verbosity appendRow, and create
formatReviewerFrequencySummary(settingsFreq string) for the reviewer frequency
normalization; replace the inline logic in onboarding_render.go (where
themeSummary, verbosity, and reviewer frequency are computed) with calls to
these helpers so both files use a single source of truth.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@cli/app/onboarding_render.go`:
- Around line 300-304: Extract the duplicated normalization/formatting logic
into shared helper functions and call them from both onboarding_render.go and
onboarding_flow.go: create formatThemeSummary(settingsTheme string) that
encapsulates the sharedtheme.Auto + " (" + sharedtheme.Resolve(...) + ")" and
the sharedtheme.IsExplicit(...) branch (used where themeSummary is built for
appendRow), create formatVerbositySummary(settingsVerbosity string) to
centralize the verbosity normalization used around the verbosity appendRow, and
create formatReviewerFrequencySummary(settingsFreq string) for the reviewer
frequency normalization; replace the inline logic in onboarding_render.go (where
themeSummary, verbosity, and reviewer frequency are computed) with calls to
these helpers so both files use a single source of truth.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bca94b53-13a3-439b-9e0a-6976ac40b68d

📥 Commits

Reviewing files that changed from the base of the PR and between f8413c9 and 4c22c88.

📒 Files selected for processing (9)
  • cli/app/internal/worktreemutation/service.go
  • cli/app/onboarding_flow.go
  • cli/app/onboarding_imports.go
  • cli/app/onboarding_render.go
  • cli/app/onboarding_workflow.go
  • cli/app/ui_layout_rendering_status_overlay.go
  • cli/app/ui_native_scrollback_integration_part5_test.go
  • cli/app/ui_status.go
  • cli/app/ui_worktree_commands.go
💤 Files with no reviewable changes (2)
  • cli/app/onboarding_imports.go
  • cli/app/ui_status.go

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant