Rename FreeFlow to Fluent and document efficiency improvements#16
Conversation
Rebrand the entire project from FreeFlow to Fluent across Swift sources, Info.plist, Makefile, entitlements, GitHub workflows, the release skill, and the website. Update the bundle identifier to com.inhaq.fluent and all repository/site links to inhaq/fluent. Rewrite the README and add a CHANGELOG entry to explain that Fluent is a faster, more token-efficient fork of Free Flow: plain dictation skips screenshot capture, screenshots are smaller and compressed when used, and the default cleanup model runs with low reasoning effort. Co-authored-by: Inzimam Ul Haq <27832433+inhaq@users.noreply.github.com>
📝 WalkthroughWalkthroughThe PR rebrands the app, release tooling, workflows, website, and documentation from FreeFlow to Fluent. It also updates build tags, bundle identifiers, logging and queue labels, updater paths, and release asset names to match Fluent artifacts. ChangesFluent rebrand and release plumbing
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Sources/KeychainStorage.swift (1)
5-15: 🗄️ Data Integrity & Integration | 🟠 MajorAdd a migration from the old FreeFlow identity
AppName.displayNamenow resolves toFluent, so the settings file moves fromApplication Support/FreeFlow/.settingstoApplication Support/Fluent/.settings.migrateFromKeychainIfNeededonly reads the current bundle ID (com.inhaq.fluent), so existing keychain items undercom.zachlatta.freefloware never picked up.- Add a first-launch migration for the legacy settings path and keychain service, or in-place upgrades will lose saved API keys/preferences.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/KeychainStorage.swift` around lines 5 - 15, The storage migration is incomplete because KeychainStorage now uses the Fluent app name and current bundle ID, but existing FreeFlow settings and keychain items are still left behind. Update the startup/migration flow in KeychainStorage and migrateFromKeychainIfNeeded to detect and import legacy data from the old Application Support/FreeFlow settings location and the old keychain service identifier com.zachlatta.freeflow before switching to the new AppName.displayName and bundleID values. Make this a first-launch or upgrade migration so saved API keys and preferences are preserved in place.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.agents/skills/fluent-release/scripts/fluent-release-check.sh:
- Around line 50-67: The release check script is using a predictable temporary
path for changelog output, which can be raced or pre-created by another local
process. Update the logic around the changelog extraction in the fluent-release
check flow to create and use a unique temp file per run, then reuse that same
generated path for the emptiness and heading checks as well as the final cat
output. Keep the existing validation behavior in the script’s changelog handling
block, but avoid any hardcoded shared temp filename.
In `@README.md`:
- Line 43: The quick-start link text in the README is vague and should be made
descriptive for accessibility and searchability. Update the download CTA in the
README content where the Fluent.dmg link is referenced so it clearly describes
what is being downloaded, using the existing link target but replacing the
generic “click here” text with meaningful wording.
- Around line 58-60: The privacy section overstates network behavior by saying
the only outbound traffic is transcription and LLM API calls, but update
checking via UpdateManager also makes GitHub release requests. Soften the
wording in README.md to scope the claim to user content or explicitly mention
update-related traffic, and apply the same revised phrasing in the website copy
so the privacy message is consistent.
In `@website/index.html`:
- Around line 986-988: The “Custom cleanup” card currently links to the
repository top-level README instead of the actual prompt section. Update the
anchor in the card markup within the related HTML snippet so it points directly
to the “Custom Cleanup” section anchor in the README, using the existing card
text and link element as the place to fix it.
---
Outside diff comments:
In `@Sources/KeychainStorage.swift`:
- Around line 5-15: The storage migration is incomplete because KeychainStorage
now uses the Fluent app name and current bundle ID, but existing FreeFlow
settings and keychain items are still left behind. Update the startup/migration
flow in KeychainStorage and migrateFromKeychainIfNeeded to detect and import
legacy data from the old Application Support/FreeFlow settings location and the
old keychain service identifier com.zachlatta.freeflow before switching to the
new AppName.displayName and bundleID values. Make this a first-launch or upgrade
migration so saved API keys and preferences are preserved in place.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: a0db9ad5-90fc-4875-a710-f55bb36a919a
📒 Files selected for processing (30)
.agents/skills/fluent-release/SKILL.md.agents/skills/fluent-release/agents/openai.yaml.agents/skills/fluent-release/scripts/fluent-release-check.sh.agents/skills/freeflow-release/agents/openai.yaml.github/workflows/dev-release.yml.github/workflows/release.ymlCHANGELOG.mdFluent.entitlementsInfo.plistMakefileREADME.mdSources/App.swiftSources/AppName.swiftSources/AppState.swiftSources/AudioRecorder.swiftSources/GlobalShortcutBackend.swiftSources/KeychainStorage.swiftSources/NetworkMonitor.swiftSources/PipelineSignpost.swiftSources/RealtimeTranscriptionService.swiftSources/SettingsView.swiftSources/StreamingMultipartBody.swiftSources/TestCaseExporter.swiftSources/TranscriptionService.swiftSources/UpdateManager.swiftwebsite/README.mdwebsite/index.htmlwebsite/llms.txtwebsite/robots.txtwebsite/sitemap.xml
💤 Files with no reviewable changes (1)
- .agents/skills/freeflow-release/agents/openai.yaml
| if ! .github/scripts/changelog-section.sh "$version" >/tmp/fluent-release-notes.md; then | ||
| echo "Could not extract CHANGELOG.md section for $version" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [[ ! -s /tmp/freeflow-release-notes.md ]]; then | ||
| if [[ ! -s /tmp/fluent-release-notes.md ]]; then | ||
| echo "Extracted changelog section is empty for $version" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| if ! grep -q "^## \\[$version\\]" /tmp/freeflow-release-notes.md; then | ||
| if ! grep -q "^## \\[$version\\]" /tmp/fluent-release-notes.md; then | ||
| echo "Extracted changelog section has an unexpected heading." >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "Release checks passed for $tag" | ||
| echo | ||
| cat /tmp/freeflow-release-notes.md | ||
| cat /tmp/fluent-release-notes.md |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Use a unique temp file here.
/tmp/fluent-release-notes.md is predictable, so another local process can pre-create or symlink it and race this checker. That can corrupt the release precheck on shared machines.
🔧 Suggested fix
+tmp_notes="$(mktemp)"
+trap 'rm -f "$tmp_notes"' EXIT🧰 Tools
🪛 ast-grep (0.44.0)
[warning] 59-59: Writing to or reading from a hardcoded, predictable path under /tmp is vulnerable to symlink and TOCTOU attacks: a local attacker can pre-create the file (or a symlink pointing elsewhere) and hijack or corrupt the contents. Generate a unique, unpredictable temporary file with mktemp instead, e.g. tmpfile="$(mktemp)" (or mktemp -d for directories) and reference "$tmpfile".
Context: /tmp/fluent-release-notes.md
Note: [CWE-377] Insecure Temporary File.
(predictable-tmp-file-bash)
[warning] 66-66: Writing to or reading from a hardcoded, predictable path under /tmp is vulnerable to symlink and TOCTOU attacks: a local attacker can pre-create the file (or a symlink pointing elsewhere) and hijack or corrupt the contents. Generate a unique, unpredictable temporary file with mktemp instead, e.g. tmpfile="$(mktemp)" (or mktemp -d for directories) and reference "$tmpfile".
Context: /tmp/fluent-release-notes.md
Note: [CWE-377] Insecure Temporary File.
(predictable-tmp-file-bash)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.agents/skills/fluent-release/scripts/fluent-release-check.sh around lines
50 - 67, The release check script is using a predictable temporary path for
changelog output, which can be raced or pre-created by another local process.
Update the logic around the changelog extraction in the fluent-release check
flow to create and use a unique temp file per run, then reuse that same
generated path for the emptiness and heading checks as well as the final cat
output. Keep the existing validation behavior in the script’s changelog handling
block, but avoid any hardcoded shared temp filename.
Source: Linters/SAST tools
| ## Quick Start | ||
|
|
||
| 1. Download the app from above or [click here](https://github.com/zachlatta/freeflow/releases/latest/download/FreeFlow.dmg) | ||
| 1. Download the app from above or [click here](https://github.com/inhaq/fluent/releases/latest/download/Fluent.dmg) |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Use descriptive quick-start link text.
click here is vague for screen readers and search indexing; make the CTA describe the download target instead.
Suggested fix
-1. Download the app from above or [click here](https://github.com/inhaq/fluent/releases/latest/download/Fluent.dmg)
+1. Download the app from above or [download Fluent.dmg](https://github.com/inhaq/fluent/releases/latest/download/Fluent.dmg)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| 1. Download the app from above or [click here](https://github.com/inhaq/fluent/releases/latest/download/Fluent.dmg) | |
| 1. Download the app from above or [download Fluent.dmg](https://github.com/inhaq/fluent/releases/latest/download/Fluent.dmg) |
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 43-43: Link text should be descriptive
(MD059, descriptive-link-text)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@README.md` at line 43, The quick-start link text in the README is vague and
should be made descriptive for accessibility and searchability. Update the
download CTA in the README content where the Fluent.dmg link is referenced so it
clearly describes what is being downloaded, using the existing link target but
replacing the generic “click here” text with meaningful wording.
Source: Linters/SAST tools
| ## Privacy | ||
|
|
||
| There is no FreeFlow server, so FreeFlow does not store or retain your data. The only information that leaves your computer are API calls to your configured transcription and LLM provider. | ||
| There is no Fluent server, so Fluent does not store or retain your data. The only information that leaves your computer are API calls to your configured transcription and LLM provider. |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
Narrow the privacy claim.
Sources/UpdateManager.swift still makes GitHub release requests for update checks, so “the only information that leaves your computer” overstates the app’s network behavior. Please scope this to user content or mention update traffic explicitly, and mirror the softened wording in the website copy too.
Suggested fix
-There is no Fluent server, so Fluent does not store or retain your data. The only information that leaves your computer are API calls to your configured transcription and LLM provider.
+There is no Fluent server, so Fluent does not store or retain your data. Fluent also makes update-check requests, and user content only leaves your computer via your configured transcription and LLM provider.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ## Privacy | |
| There is no FreeFlow server, so FreeFlow does not store or retain your data. The only information that leaves your computer are API calls to your configured transcription and LLM provider. | |
| There is no Fluent server, so Fluent does not store or retain your data. The only information that leaves your computer are API calls to your configured transcription and LLM provider. | |
| ## Privacy | |
| There is no Fluent server, so Fluent does not store or retain your data. Fluent also makes update-check requests, and user content only leaves your computer via your configured transcription and LLM provider. |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@README.md` around lines 58 - 60, The privacy section overstates network
behavior by saying the only outbound traffic is transcription and LLM API calls,
but update checking via UpdateManager also makes GitHub release requests. Soften
the wording in README.md to scope the claim to user content or explicitly
mention update-related traffic, and apply the same revised phrasing in the
website copy so the privacy message is consistent.
| <div class="card-head"><span class="card-icon"><svg viewBox="0 0 36 36" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 10h26M5 18h26M5 26h26"/><circle cx="14" cy="10" r="3"/><circle cx="23" cy="18" r="3"/><circle cx="12" cy="26" r="3"/></svg></span><h3>Custom cleanup</h3></div> | ||
| <p>Prefer a more literal cleanup? Use a simpler prompt in the custom system prompt setting.</p> | ||
| <a href="https://github.com/zachlatta/freeflow#readme">View simple prompt →</a> | ||
| <a href="https://github.com/inhaq/fluent#readme">View simple prompt →</a> |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Point the card at the prompt section.
#readme only lands on the repo page top, so users still have to hunt for the custom-cleanup prompt. Link directly to the Custom Cleanup anchor.
Suggested fix
-<a href="https://github.com/inhaq/fluent#readme">View simple prompt →</a>
+<a href="https://github.com/inhaq/fluent#custom-cleanup">View simple prompt →</a>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <div class="card-head"><span class="card-icon"><svg viewBox="0 0 36 36" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 10h26M5 18h26M5 26h26"/><circle cx="14" cy="10" r="3"/><circle cx="23" cy="18" r="3"/><circle cx="12" cy="26" r="3"/></svg></span><h3>Custom cleanup</h3></div> | |
| <p>Prefer a more literal cleanup? Use a simpler prompt in the custom system prompt setting.</p> | |
| <a href="https://github.com/zachlatta/freeflow#readme">View simple prompt →</a> | |
| <a href="https://github.com/inhaq/fluent#readme">View simple prompt →</a> | |
| <div class="card-head"><span class="card-icon"><svg viewBox="0 0 36 36" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 10h26M5 18h26M5 26h26"/><circle cx="14" cy="10" r="3"/><circle cx="23" cy="18" r="3"/><circle cx="12" cy="26" r="3"/></svg></span><h3>Custom cleanup</h3></div> | |
| <p>Prefer a more literal cleanup? Use a simpler prompt in the custom system prompt setting.</p> | |
| <a href="https://github.com/inhaq/fluent#custom-cleanup">View simple prompt →</a> |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@website/index.html` around lines 986 - 988, The “Custom cleanup” card
currently links to the repository top-level README instead of the actual prompt
section. Update the anchor in the card markup within the related HTML snippet so
it points directly to the “Custom Cleanup” section anchor in the README, using
the existing card text and link element as the place to fix it.
This pull request was created by @kiro-agent on behalf of @inhaq 👻
Comment with /kiro fix to address specific feedback or /kiro all to address everything.
Learn about Kiro Web
Summary
Rebrands the project from FreeFlow to Fluent across the entire repository and rewrites the docs to reflect the post-fork direction: more efficient, fewer tokens per dictation, and faster.
Info.plist,Makefile, entitlements (FreeFlow.entitlements->Fluent.entitlements), GitHub workflows, and the release skill (.agents/skills/fluent-release/). Bundle identifier is nowcom.inhaq.fluent, the@mainapp isFluentApp, and all repo/site links point toinhaq/fluent(freeflow.zachlatta.com->fluent.inhaq.com).defaultscommands tocom.inhaq.fluentand added a Credits section attributing upstream Free Flow.[1.2.0]changelog entry describing the rebrand and efficiency work;llms.txtandindex.htmlupdated with the new positioning.Notes / assumptions
com.inhaq.fluentand the site domainfluent.inhaq.comfrom yourinhaq.comemail/ownership. Adjust if you use different values.freeflow/zachlattareferences are intentional attribution links to the upstream Free Flow repo.Resources/AppIcon-Source.pngplaceholder; swap in the new Fluent logo when you share it.Tested
Summary by CodeRabbit
New Features
Bug Fixes