Skip to content

feat: add spoken formatting and 1.6.9 fixes - #848

Merged
altic-dev merged 5 commits into
mainfrom
B/pr-842-hardening
Aug 13, 2026
Merged

feat: add spoken formatting and 1.6.9 fixes#848
altic-dev merged 5 commits into
mainfrom
B/pr-842-hardening

Conversation

@altic-dev

@altic-dev altic-dev commented Aug 12, 2026

Copy link
Copy Markdown
Owner

Description

Adds a unified Spoken Formatting editor to Custom Dictionary with a shared start word, customizable action phrases, punctuation rules, and fixed actions for new lines, paragraphs, tabs, and spaces.

Also restores whitespace-only dictionary replacements from #842, groups existing text-formatting settings, and includes the microphone alert and clamshell wired-microphone fixes intended for 1.6.9.

Type of Change

  • 🐞 Bug fix
  • ✨ New feature
  • 💥 Breaking change
  • 🧹 Chore
  • 📝 Documentation update

Related Issue or Discussion

Closes #841.

Builds on #842. The original whitespace-replacement fix and authorship from @nsutcliffe are preserved in the branch history.

Testing

  • Tested on Intel Mac
  • Tested on Apple Silicon Mac
  • Tested on macOS version: 27.0
  • Ran linter locally: swiftlint --strict --config .swiftlint.yml Sources
  • Ran formatter locally: swiftformat --config .swiftformat Sources
  • Ran tests locally: 110 focused dictionary and dictation integration tests passed
  • Built, installed, and launched FluidVoice 1.6.9 with private Fluid Intelligence

Screenshots / Video

image
  • No UI/visual changes; screenshots/video are not applicable.

Notes

  • Duplicate spoken aliases are normalized deterministically; punctuation keeps precedence.
  • Legacy backups without formatting-action rules preserve the current configuration.
  • Resetting spoken formatting requires confirmation.
  • Overlay behavior is intentionally unchanged.

altic-dev and others added 4 commits August 11, 2026 17:06
…wline)

Commit 808a08d changed the manual-entry validation from trimming
.whitespaces to .whitespacesAndNewlines, so a replacement consisting of
a single pasted newline now trims to empty and the "Add Replacement"
button stays disabled. The replacement engine itself handles such
entries fine (escapedTemplate inserts them verbatim), so this was
purely a UI regression.

Introduce CustomDictionaryManualEntry.sanitizedReplacement: trim
surrounding whitespace as before, but keep a replacement that is
*entirely* whitespace verbatim — pasting a newline, space, or tab is a
deliberate payload, not accidental padding. Use it in the manual
composer and the edit sheet (which still used the pre-808a08d
.whitespaces trim, inconsistently).

Whitespace-only replacements render as blank text, so display them as
symbols (⏎ ␣ ⇥) in the composer preview, edit-sheet preview, and
dictionary entry rows via replacementDisplayText.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions github-actions Bot added the needs screenshots Pull request needs screenshot or video evidence. label Aug 12, 2026
@github-actions

Copy link
Copy Markdown

The PR Policy check is blocking this PR because required template information is missing.

Please update the PR description with:

  • Screenshots / Video

Visual files detected:

  • Sources/Fluid/Persistence/SettingsStore.swift
  • Sources/Fluid/Services/LocalAPI/DictionaryAPIController.swift
  • Sources/Fluid/UI/CustomDictionaryView.swift
  • Sources/Fluid/UI/SettingsView.swift
  • Sources/Fluid/Views/AutomaticDictionaryCorrectionOverlay.swift

Screenshots or video are required for UI, UX, settings, onboarding, overlay, menu bar, or visual behavior changes. If this PR has no visual changes, check the no-visual-change box in the template.

If this remains incomplete for 48 hours after opening, the PR may be closed.

@greptile-apps

greptile-apps Bot commented Aug 12, 2026

Copy link
Copy Markdown

Greptile Summary

Adds configurable spoken-formatting actions alongside punctuation rules and restores whitespace-only custom-dictionary replacements. It also persists the new settings, updates dictionary import/API paths and UI, and refines microphone alerts and wired-microphone selection in clamshell mode.

  • Adds configurable new-line, paragraph, tab, and space actions using the shared spoken-formatting prefix.
  • Preserves whitespace-only dictionary replacements across manual entry, transfer, API, backup, and ASR application paths.
  • Adds microphone-alert preferences and distinguishes wired external microphone sources on built-in audio transport.
  • Expands focused dictionary, formatting, and microphone-selection tests.

Confidence Score: 5/5

The PR appears safe to merge because no blocking failure remains within the eligible follow-up-review scope.

No blocking failure remains.

Reviews (2): Last reviewed commit: "test: split spoken formatting coverage" | Re-trigger Greptile

@github-actions github-actions Bot removed the needs screenshots Pull request needs screenshot or video evidence. label Aug 12, 2026

@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: 46dd7c84a5

ℹ️ 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".

Comment on lines +4230 to +4231
else {
return Self.defaultSpokenFormattingActionRules

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 Normalize default action aliases against punctuation rules

For existing installations without SpokenFormattingActionRules data, this fallback returns the defaults before applying removingDuplicateSpokenFormattingAliases. If a user already has a custom punctuation alias such as new line, next line, tab, or space, the formatter receives two rules for the same phrase and may execute either the existing punctuation rule or the new formatting action. Apply the same collision normalization to the fallback defaults so upgrades preserve customized punctuation behavior.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

there's no way for users to add a newline etc before this update. so very rare or not possible for this to happen.

@github-actions

Copy link
Copy Markdown

FluidVoice PR build ready

Download FluidVoice-PR-848-46dd7c84a5ba

The artifact contains the ad-hoc-signed app ZIP, Xcode archive, build manifest, and installation instructions. It expires 5 days after the build.

Install the app

  1. Extract the downloaded artifact, then extract FluidVoice-PR-848.app.zip.

  2. Move FluidVoice feat: add spoken formatting and 1.6.9 fixes #848.app into the /Applications folder.

  3. Open Terminal and remove the download quarantine marker:

    xattr -dr com.apple.quarantine "/Applications/FluidVoice #848.app"
    
  4. In Applications, Control-click FluidVoice feat: add spoken formatting and 1.6.9 fixes #848.app and choose Open.

  5. If macOS still blocks it, open System Settings → Privacy & Security, click Open Anyway, and confirm.

This build has its own app identity, so its permissions are separate from the release version of FluidVoice.

View workflow run

@altic-dev
altic-dev merged commit b7e95aa into main Aug 13, 2026
6 checks passed
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.

[BUG] Custom Dictionary: whitespace-only replacements (pasted newline) can no longer be added — regression from #153 workaround

2 participants