uttrflow / uttrflow/uttrflow-swift
A terminal is formatted as a code editor, so a dictated line break reaches the shell and can run a half-finished command
- Dominant language
- Swift
- Stars
- 4
- Forks
- 17
- Avg merge
- 3h 32m
- Merged PRs (30d)
- 277
Description
## What happens
`AppKind.terminal` resolves to `.codeEditor` (`Sources/UttrflowCore/Models/AppKind.swift:17`). The code editor's formatter keeps line breaks as given:
```swift
// Sources/UttrflowCore/Models/DestinationFormatter.swift:131-134
.codeEditor: DestinationFormatter(
destination: .codeEditor, firstWord: .fromInsertionPoint, terminalStop: .never,
layout: .preserveNewlines, ...
```
`LayoutPolicy.preserveNewlines` is documented as "Line breaks are kept as given … as dictated code wants" (`DestinationFormatter.swift:82-83`). In an editor a newline is a new line. At an interactive shell prompt a newline is Return: everything before it is run.
A dictation reaches the terminal with a line break in several ways:
- the user says "new line" or "new paragraph" part-way through a command, meaning a visual break;
- the tidy step keeps any break the recogniser or the model produced, since `.preserveNewlines` is the policy.
Then it is inserted in one of two ways:
- **By the Accessibility write**, if the terminal accepts one. That is character input, so the shell's bracketed-paste protection never applies.
- **By the paste.** A shell with bracketed paste holds the text for review. The shell that ships as `/bin/bash` on macOS, many TUIs and REPLs, and remote shells over SSH may not have it on.
Nothing on either path collapses or refuses a line break for a terminal.
## Why it matters
In a terminal, a partial command running is not a formatting slip. `git reset --hard` followed by a break and the rest of a thought runs the first line.
## Needs a product decision
Pick one:
- **(a)** Terminals get their own formatter with `.singleLine`.
- **(b)** A dictation holding a line break into a terminal is inserted with the breaks replaced by spaces, and the user is told.
- **(c)** Multi-line dictation into a terminal is left on the clipboard with a notice.
## How to reproduce
Needs a real terminal (`help wanted` for the insertion half):
1. At a shell prompt without bracketed paste (for example `bash --norc` using the system bash), dictate "echo one new line echo two".
2. Record whether `echo one` runs before you press Return, and which insertion route `uttrflow-dev insert` takes in that terminal (`--via accessibility` versus `--via paste`).
The formatting half can be checked without a terminal: `uttrflow-dev clean --bundle-identifier …` on text holding a break.
## Acceptance criteria
- The chosen policy is a value in `DestinationFormatter.registry` (or a new `Destination`), not a special case in an insertion engine, so both the rules path and the model path read it (#231).
- Corpus cases in `Sources/UttrflowEval/EvaluationCorpus.swift` pin that a spoken break into a terminal never produces `\n` in the inserted text.
Contributor guide
Research direction
Start with AppKind.swift:17 and the formatter entries in DestinationFormatter.swift:82-83 and 131-134, then inspect the terminal identifier in DestinationRules.swift:35. Check the insertion route with the provided clean and insert commands. Done means the chosen terminal policy is represented in the formatter registry or a new Destination, and EvaluationCorpus.swift cases show dictated breaks never produce newline characters.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos, swift
- Domain
- accessibility, cli, desktop-dev
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100