Skip to content

feat(ios): add a Words tab for key terms and text shortcuts - #232

Merged
alexkroman merged 2 commits into
jhe/sdk-text-shortcutsfrom
jhe/ios-words
Oct 15, 2026
Merged

alexkroman merged 2 commits into
jhe/sdk-text-shortcutsfrom
jhe/ios-words

Conversation

@he-james

@he-james he-james commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

What & why

Brings the blurt-ios Words tab to the iPhone app, built on the AssemblyAI SDK's KeyTerms and TextShortcut from #231.

  • Tabs: Dictate and Words under a brand tab bar, with mono labels and the selected tab in the accent. MainView owns what has to work on either tab: Settings from each tab's gear, the consent sheet, and shared key-term lists. A shared list switches to Words.
  • Key terms:
    • Shown as pills with ×, plus an inline field. Commas add several, duplicates of any case drop, and the list caps at the request's 100.
    • The card also shows the count, the contact names that come along, and Share.
    • They moved here from Settings, which now just points to Words.
  • Text shortcuts:
    • Rows show the phrase in mono accent over its replacement, with ×, plus an inline "When I say… / Type this" form. Re-adding a phrase replaces it, as in blurt-ios.
    • They're expanded on the phone and never sent.
  • BlurtDesign gains BrandTabBar, FlowLayout, brandInput() and brandFootnote(). Brand buttons now fade while disabled, as in blurt-ios. New tokens for these are in tokens.json.
  • The editing rules live in BlurtiOSCore (WordsEdit) and are tested.

iPhone only. Stacked on #231.

How it was tested

  • scripts/ios-check.sh: 137 tests (4 new for WordsEdit), BlurtiOSCore 96.69%, analyze, periphery and the probe build all pass.

  • design-sync.sh --check, check-invariants.sh and swiftlint --strict are clean.

  • Simulator, light and dark: switched tabs, added a shortcut and removed it, and checked the key-term pill and footnote.

  • scripts/check.sh passes (or CI will, if I'm not on a Mac)

  • I read AGENTS.md and this doesn't reintroduce anything deliberately removed

  • Docs updated if behavior changed

🤖 Generated with Claude Code

@he-james he-james mentioned this pull request Oct 2, 2026
3 tasks done
The app gets Dictate and Words tabs under a brand tab bar, as in the
blurt-ios prototype. MainView owns what works on either tab: Settings
from each tab's gear, the consent sheet and shared key-term lists.

Words, on the AssemblyAI SDK's KeyTerms and TextShortcut:
- Key terms as pills with an inline add field (commas add several,
  duplicates drop, capped at the request's 100), the contact-name
  count, and Share. They move here from Settings.
- Text shortcuts with an inline "When I say / Type this" form;
  re-adding a phrase replaces it. Expanded on the phone, never sent.

BlurtDesign gains BrandTabBar, FlowLayout, brandInput() and
brandFootnote(), and brand buttons fade while disabled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@alexkroman
alexkroman marked this pull request as ready for review October 15, 2026 00:05
@alexkroman
alexkroman merged commit 27cd67a into jhe/sdk-text-shortcuts Oct 15, 2026
1 check passed
@alexkroman
alexkroman deleted the jhe/ios-words branch October 15, 2026 00:05
alexkroman pushed a commit that referenced this pull request Oct 15, 2026
…SDK (#231)

* refactor(sdk): move key terms and text shortcuts into the AssemblyAI SDK

KeyTerms (parse a comma-separated list, fit it to keyterms_prompt's
caps; was KeytermsBoost plus KeyTermsStore.parse) and TextShortcut with
its on-device TextShortcutExpander now live in Sources/AssemblyAI, so
any app on the SDK gets them. BlurtEngine keeps Blurt's storage:
KeyTermsStore and TextShortcutStore, their UserDefaults keys and limits.

The iPhone's duplicate KeyTermList is replaced by KeyTerms. The Mac app
only gains an import; its behaviour and stored data are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* style(sdk): keep KeyTerms.join's doc comment on its declaration

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(ios): add a Words tab for key terms and text shortcuts (#232)

* feat(ios): add a Words tab for key terms and text shortcuts

The app gets Dictate and Words tabs under a brand tab bar, as in the
blurt-ios prototype. MainView owns what works on either tab: Settings
from each tab's gear, the consent sheet and shared key-term lists.

Words, on the AssemblyAI SDK's KeyTerms and TextShortcut:
- Key terms as pills with an inline add field (commas add several,
  duplicates drop, capped at the request's 100), the contact-name
  count, and Share. They move here from Settings.
- Text shortcuts with an inline "When I say / Type this" form;
  re-adding a phrase replaces it. Expanded on the phone, never sent.

BlurtDesign gains BrandTabBar, FlowLayout, brandInput() and
brandFootnote(), and brand buttons fade while disabled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ios): drop the Words tab pointer from Settings

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
alexkroman pushed a commit that referenced this pull request Oct 15, 2026
* refactor(sdk): move key terms and text shortcuts into the AssemblyAI SDK

KeyTerms (parse a comma-separated list, fit it to keyterms_prompt's
caps; was KeytermsBoost plus KeyTermsStore.parse) and TextShortcut with
its on-device TextShortcutExpander now live in Sources/AssemblyAI, so
any app on the SDK gets them. BlurtEngine keeps Blurt's storage:
KeyTermsStore and TextShortcutStore, their UserDefaults keys and limits.

The iPhone's duplicate KeyTermList is replaced by KeyTerms. The Mac app
only gains an import; its behaviour and stored data are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(ios): add a Words tab for key terms and text shortcuts

The app gets Dictate and Words tabs under a brand tab bar, as in the
blurt-ios prototype. MainView owns what works on either tab: Settings
from each tab's gear, the consent sheet and shared key-term lists.

Words, on the AssemblyAI SDK's KeyTerms and TextShortcut:
- Key terms as pills with an inline add field (commas add several,
  duplicates drop, capped at the request's 100), the contact-name
  count, and Share. They move here from Settings.
- Text shortcuts with an inline "When I say / Type this" form;
  re-adding a phrase replaces it. Expanded on the phone, never sent.

BlurtDesign gains BrandTabBar, FlowLayout, brandInput() and
brandFootnote(), and brand buttons fade while disabled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(ios): show lifetime dictation stats

A stats card at the top of the Dictate tab, as in the blurt-ios
prototype: dictations, words, and time saved against the 36 wpm phone
typing average, as serif numbers with mono units. Time saved shows in
full and moves to its own row past an hour; every value takes the
largest of four sizes that fits.

Every dictation counts, from the app or the keyboard. The coordinator
times the recording phase and records on the main actor when the
dictation's terminal phase renders, so the spoken time is the right
one and a reset can't race a record. Totals stay on the phone
(DictationStats, BlurtiOSCore); Settings › Data resets them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* style(sdk): keep KeyTerms.join's doc comment on its declaration

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ios): drop the Words tab pointer from Settings

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(ios): add the Easter Egg (#234)

* feat(ios): add the easter egg

A quiet "How fast can you type?" link at the foot of Settings opens a
30-second sprint over common words, ported from the blurt-ios
prototype: the clock starts on the first key, turns orange and thumps
through the last five seconds, and the result shows WPM, a rank,
accuracy, the best, and how talking at 150 wpm compares.

The latest result becomes the typing speed time saved is measured
against, in place of the 36 wpm phone average, with a "Reset to
average" link beside it. Scoring and the speed live in BlurtiOSCore
(TypingTest, TypingSpeed) and are tested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ios): present the Easter Egg once from Settings

The cover and the reset confirmation were attached to their sections,
and a section's modifiers apply to each of its rows, so the About
section's five rows each tried to present the Easter Egg at once. Both
now hang off the form.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* feat(ios): add a Words tab for key terms and text shortcuts (#232)

* feat(ios): add a Words tab for key terms and text shortcuts

The app gets Dictate and Words tabs under a brand tab bar, as in the
blurt-ios prototype. MainView owns what works on either tab: Settings
from each tab's gear, the consent sheet and shared key-term lists.

Words, on the AssemblyAI SDK's KeyTerms and TextShortcut:
- Key terms as pills with an inline add field (commas add several,
  duplicates drop, capped at the request's 100), the contact-name
  count, and Share. They move here from Settings.
- Text shortcuts with an inline "When I say / Type this" form;
  re-adding a phrase replaces it. Expanded on the phone, never sent.

BlurtDesign gains BrandTabBar, FlowLayout, brandInput() and
brandFootnote(), and brand buttons fade while disabled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ios): drop the Words tab pointer from Settings

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* feat(ios): open on a setup screen, then keep setup in Settings (#236)

* feat(ios): add the easter egg

A quiet "How fast can you type?" link at the foot of Settings opens a
30-second sprint over common words, ported from the blurt-ios
prototype: the clock starts on the first key, turns orange and thumps
through the last five seconds, and the result shows WPM, a rank,
accuracy, the best, and how talking at 150 wpm compares.

The latest result becomes the typing speed time saved is measured
against, in place of the 36 wpm phone average, with a "Reset to
average" link beside it. Scoring and the speed live in BlurtiOSCore
(TypingTest, TypingSpeed) and are tested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ios): present the Easter Egg once from Settings

The cover and the reset confirmation were attached to their sections,
and a section's modifiers apply to each of its rows, so the About
section's five rows each tried to present the Easter Egg at once. Both
now hang off the form.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(ios): open on a setup screen, then keep setup in Settings

As in the blurt-ios prototype, a first-run screen replaces the tabs
until Blurt is set up: the wordmark, a headline, and the numbered steps
in a card, with the API key pasted inline (Continue, Get a free key,
where the key and the audio go). Without a key it can't be left; with
one, Start dictating goes to the tabs and the microphone and keyboard
can wait. Whoever was already set up skips it.

The setup card leaves the Dictate tab. Settings › Setup keeps the
steps, hidden behind "Blurt is set up ✓ · Show steps" once everything
is done and open while anything isn't.

The rule is SetupProgress (BlurtiOSCore, tested); -BlurtNoKey shows a
fresh install's screen in debug builds without touching the Keychain.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.

3 participants