WIP: Compose interaction mode#121
Draft
FuJacob wants to merge 4 commits into
Draft
Conversation
Builds on the Compose interaction mode foundation with additional service-layer plumbing, context normalization, prompt rendering, and overlay/insertion support for compose-style suggestions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolves all conflicts after the Tabby -> Cotabby rename, the MLX engine addition, full-suggestion acceptance keybind, and structured logging landed on main. Key resolutions: - `SuggestionSettingsSnapshot` keeps `selectedInteractionMode` and `userTags` from the branch, plus the new `debounceMilliseconds`, `focusPollIntervalMilliseconds`, and `mlxSwift` engine kind from main. - `SuggestionGenerating` now includes `generateCompose`; `Foundation`, `Llama`, `MLX`, and `Unavailable` engines all implement it. The router forwards Compose to llama only. - `SuggestionAvailabilityEvaluator` only requires Screen Recording in autocomplete mode so AX-only Compose context is not gated by it. - `InputSuppressionController.registerSyntheticInsertion` accumulates pending key counts and accepts a longer duration so chunked Compose typing reuses one suppression window. - `SuggestionInteractionState.validateSessionForAcceptance` checks the autocomplete session only (Compose uses its own accept flow). - `MenuBarView` adopts the new Mode picker; the broken word-count header binding from the branch is dropped in favor of main's Report button. - ComposeContextCollector moves to `Cotabby/Services/Context/` and `ComposeContextNormalizerTests` is registered in `Cotabby.xcodeproj`. - Existing test stubs (`FakeOverlayController`, `StubSuggestionEngine`) pick up the new protocol methods. Build, build-for-testing, and the full 260-test suite all pass.
Five new main commits landed during the first merge, including the multi-line completion toggle. Extends `SuggestionSettingsSnapshot` and its publisher with `isMultiLineEnabled` while preserving the Compose interaction-mode fields. Build, test build, and the full 274-test suite all pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Lands the foundation for Compose Mode: a new
SuggestionInteractionModethat gathers broader AX-tree context and prepares a full draft for deliberate review, alongside the existing inline-autocomplete path. This PR is the Phase 1 + Phase 2 slice fromrfc.md— mode plumbing, settings/UI surface, and the bounded AX tree walker — without the live Compose generation/typing flow.Status: WIP draft. The plumbing is in place end-to-end (mode setting → snapshot → router → prompt → context collector → overlay preview hook), but Compose generation is not yet triggered by
Taband the manual draft-typing controller has not been wired into the coordinator. Autocomplete behavior is unchanged.What landed in this branch:
SuggestionInteractionModeenum, persisted inSuggestionSettingsModeland carried inSuggestionSettingsSnapshot.ComposeContextCollector— bounded ancestor walk + DFS over the focused AX subtree with role allow/block lists, node and depth budgets, andTask.yield()cancellation points.ComposeContextNormalizer,ComposePromptRenderer,ComposeTextNormalizer,ComposeRequestFactory— pure helpers inCotabby/Support/.ComposeRequest/ComposeResult/ActiveComposeSessionvalue types;ActiveGenerationSessionsum type collapsing autocomplete + compose into one active slot.SuggestionGenerating.generateCompose(for:)added to the protocol; router forwards Compose to llama only and surfaces an unavailable state for Apple Intelligence + MLX.SuggestionOverlayControlling.showComposePreview+ComposePreviewViewfor a multiline preview surface distinct from inline ghost text.SuggestionInserter.typeDraft(_:shouldContinue:)for chunked synthetic Unicode typing with periodic cancellation checks.SuggestionAvailabilityEvaluatoris mode-aware: Compose does not require Screen Recording for AX-only context.LlamaRuntimeManager.generateUncachedso Compose's larger drafts cannot pollute the autocomplete KV cache.RuntimeModelCatalog.composeRequiredFilename+supportsCompose(filename:)for the plannedtabby-depth-1requirement.What is not yet in this branch (deliberate next-PR scope):
Tabdoes not yet kick off Compose generation; secondTabdoes not yet triggertypeDraft. The coordinator currently disables predictions with "Compose Mode is selected. Draft generation will be enabled after the Compose request pipeline is installed." when the mode is set.tabby-depth-1, surface download CTA when missing).Validation
New tests:
ComposeContextNormalizerTests(4 cases) — whitespace, dedupe, navigation noise, and line/context bounds.UI changes have not been exercised in a running build yet because Compose generation is not wired up; the Mode picker round-trips through
UserDefaultsbut selecting Compose currently surfaces the "pipeline not installed" disabled reason.Linked issues
Refs #66, #67, #68, #69, #70 — Compose Mode RFC issues.
Risk / rollout notes
tabby/→Cotabby/rename, the MLX engine addition, the full-suggestion acceptance keybind, structured logging, multi-line completion, and several other features). The merge took two passes —040e3baresolved the initial conflict set;071f9eare-merged five additional main commits that landed mid-merge (most notably the multi-line completion toggle, which addedisMultiLineEnabledto the snapshot). Reviewers should focus on:SuggestionSettingsModel.snapshotPublisher— Combine chain restructured to fan in the new mode + timing + multi-line fields cleanly.SuggestionEngineRouter.generateCompose— only routes to llama; Apple Intelligence and MLX throwunavailablerather than silently forwarding.SuggestionAvailabilityEvaluator.disabledReason— Screen Recording is now gated behindinteractionMode == .autocomplete.SuggestionInteractionState.validateSessionForAcceptance— restricted to the autocomplete session because Compose has its own accept flow.userTagsis a snapshot field reserved for Compose's prompt; it currently always emits[]until a tag editor lands. No persistence migration needed.ComposeContextNormalizerTests.swift). Source files auto-discover.