uttrflow / uttrflow/uttrflow-swift
The suggestion terminal list and the dictation destination table disagree: one terminal is spelled with the wrong root and three are missing from the other table
- Dominant language
- Swift
- Stars
- 4
- Forks
- 17
- Avg merge
- 3h 32m
- Merged PRs (30d)
- 277
Description
## What happens
Two lists decide "is this app a terminal", and they do not match.
**`TerminalApplications.bundleIdentifierPrefixes`** (`Sources/UttrflowPredict/AcceptKey.swift:64-74`) decides:
- the accept key: → instead of Tab, so shell completion keeps Tab;
- whether the shell prompt is stripped from the line (`FocusedFieldSnapshot.swift:110`);
- the prose gate (`:174`);
- capture's commit policy (`Sources/UttrflowPredictCapture/CommitPolicy.swift:30`).
**`DestinationRules.standard`**'s terminal row (`Sources/UttrflowCore/Models/DestinationRules.swift:33-40`) decides how a dictation is formatted.
The differences:
1. **One terminal has two different identifiers.** `AcceptKey.swift:69` spells it with an `io.` root. `DestinationRules.swift:36` spells it with `org.`, and so do the reproduction test at `Tests/UttrflowAITests/Issue203ReproductionTests.swift:20` and `Tests/UttrflowAITests/DestinationTableAgreementTests.swift:54`. The test that holds the tables together already records the entry as dead: `Tests/UttrflowCoreTests/OneAppTableTests.swift:32`, "ships as `org.…`, so this row reaches nothing". In that terminal, then:
- AI suggestions take **Tab**, which is the shell's completion key;
- the prompt is not stripped from the line the model is shown;
- capture's terminal commit rule does not apply.
2. **Three terminals are in the suggestion list and have no destination row:** `AcceptKey.swift:70`, `:72` and `:73`. Their app names are not in the row's `nameWords` either, so a dictation into them is classified `.plain`: full stop added, grammar repaired, paragraph and list layout. They are in `OneAppTableTests.owed` (`:28`, `:29`, `:33`), so the drift is known and allowed, but no issue tracks paying it.
3. The editor list has the same split. `AcceptKey.swift:48-58` includes two identifiers `DestinationRules` does not (`OneAppTableTests.swift:31`, `:34`).
#231 covers the `AppKind` / `DestinationRules` split in dictation. This is the other pair: the suggestion module's lists against the destination table.
## Why it matters
Pressing Tab for shell completion in that terminal inserts a model completion instead. That breaks the one thing a terminal user relies on Tab for, and `Docs/predict-accept.md` chose → for terminals precisely to avoid it.
## How to reproduce
- `AcceptKeys.standard.key(forBundleIdentifier:)` with the `org.`-rooted identifier from `DestinationRules.swift:36` returns `.tab`.
- `DestinationClassifier.classify(AppContext(bundleIdentifier:))` with each of the identifiers at `AcceptKey.swift:70`, `:72` and `:73` returns `.plain`.
## Acceptance criteria
- One list of terminal identifiers and one list of editor identifiers, owned by the module both sides can import, with `TerminalApplications` and `AcceptKeys.editors` derived from `DestinationRules` (or the reverse).
- The wrongly rooted entry is corrected, and `OneAppTableTests.owed` is empty.
- A test asserts that every identifier that makes `TerminalApplications.contains` true classifies as `.terminal` in the destination table, and the reverse.
Contributor guide
Research direction
Start with TerminalApplications.bundleIdentifierPrefixes and AcceptKeys.editors in Sources/UttrflowPredict/AcceptKey.swift, then compare them with DestinationRules.standard in Sources/UttrflowCore/Models/DestinationRules.swift. Read OneAppTableTests.swift and the agreement and reproduction tests to understand the existing drift checks. Done means the shared terminal and editor lists agree, the wrongly rooted identifier is corrected, owed is empty, and both directions of classification are tested.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100