From 144d2b33633447cc880eca35ef0c943fa5e07c33 Mon Sep 17 00:00:00 2001 From: iamtoruk Date: Sun, 12 Jul 2026 13:13:31 -0700 Subject: [PATCH] fix(app): strip prose em-dashes from UI copy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace em-dashes used as sentence punctuation (Plans, Settings, Compare, Overview, CliErrorPanel) with cleaner punctuation; keep the standalone "—" empty-value placeholders (a no-data convention). Update affected copy assertions. typecheck clean; 128/128 tests pass. --- app/renderer/components/CliErrorPanel.tsx | 2 +- app/renderer/sections/Compare.tsx | 4 ++-- app/renderer/sections/Overview.tsx | 2 +- app/renderer/sections/Plans.test.tsx | 6 +++--- app/renderer/sections/Plans.tsx | 4 ++-- app/renderer/sections/Settings.test.tsx | 4 ++-- app/renderer/sections/Settings.tsx | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/renderer/components/CliErrorPanel.tsx b/app/renderer/components/CliErrorPanel.tsx index b2525ca..9cf0805 100644 --- a/app/renderer/components/CliErrorPanel.tsx +++ b/app/renderer/components/CliErrorPanel.tsx @@ -16,7 +16,7 @@ export function cliErrorDisplay(error: CliError): { title: string; message: stri if (isPermissionCliError(error)) { return { title: 'Permission denied', - message: 'permission denied — grant Full Disk Access', + message: 'permission denied; grant Full Disk Access', tone: 'amber', } } diff --git a/app/renderer/sections/Compare.tsx b/app/renderer/sections/Compare.tsx index fe3a327..b559c2d 100644 --- a/app/renderer/sections/Compare.tsx +++ b/app/renderer/sections/Compare.tsx @@ -81,7 +81,7 @@ export function Compare({ if (next === modelB) setModelB(nudgeDistinct(next)) }} > - {modelRows.map(model => )} + {modelRows.map(model => )} vs {modelA && modelB && modelA !== modelB && ( diff --git a/app/renderer/sections/Overview.tsx b/app/renderer/sections/Overview.tsx index 885f5f0..cbd1617 100644 --- a/app/renderer/sections/Overview.tsx +++ b/app/renderer/sections/Overview.tsx @@ -171,7 +171,7 @@ function deriveAnomalies(data: MenubarPayload, now: Date): Anomaly[] { } if (data.current.cacheHitPercent < 50) { - anomalies.push({ lead: 'Cache hit is low (', value: `${Math.round(data.current.cacheHitPercent)}%`, tail: ') — more of your context is uncached.' }) + anomalies.push({ lead: 'Cache hit is low (', value: `${Math.round(data.current.cacheHitPercent)}%`, tail: '). More of your context is uncached.' }) } return anomalies.slice(0, 3) } diff --git a/app/renderer/sections/Plans.test.tsx b/app/renderer/sections/Plans.test.tsx index cc225f4..48e2429 100644 --- a/app/renderer/sections/Plans.test.tsx +++ b/app/renderer/sections/Plans.test.tsx @@ -95,7 +95,7 @@ describe('Plans', () => { expect(claudeFill).toHaveStyle({ width: '100%' }) expect(claudeFill).toHaveClass('over') - const hotPace = screen.getByText('On pace to exceed — projected $254.00 by Jul 14') + const hotPace = screen.getByText('On pace to exceed; projected $254.00 by Jul 14') expect(hotPace).toHaveClass('pace', 'hot') expect(screen.getByText('Cursor Pro')).toBeInTheDocument() @@ -135,7 +135,7 @@ describe('Plans', () => { render() - const pace = await screen.findByText('85% of budget used — projected $280.00 by Jul 14') + const pace = await screen.findByText('85% of budget used; projected $280.00 by Jul 14') expect(pace).toHaveClass('pace', 'hot') expect(screen.queryByText(/On pace to exceed/)).not.toBeInTheDocument() }) @@ -179,6 +179,6 @@ describe('Plans', () => { render() expect(await screen.findByText('Permission denied')).toBeInTheDocument() - expect(screen.getByText('permission denied — grant Full Disk Access')).toHaveStyle({ color: 'var(--amber)' }) + expect(screen.getByText('permission denied; grant Full Disk Access')).toHaveStyle({ color: 'var(--amber)' }) }) }) diff --git a/app/renderer/sections/Plans.tsx b/app/renderer/sections/Plans.tsx index 814a7fa..774ac06 100644 --- a/app/renderer/sections/Plans.tsx +++ b/app/renderer/sections/Plans.tsx @@ -154,14 +154,14 @@ function PaceLine({ plan }: { plan: JsonPlanSummary }) { if (plan.status === 'over' || plan.projectedMonthEnd > plan.budget) { return (
- On pace to exceed — projected {formatUsd(plan.projectedMonthEnd)} by {endLabel} + On pace to exceed; projected {formatUsd(plan.projectedMonthEnd)} by {endLabel}
) } if (plan.status === 'near') { return (
- {fmtPct(plan.percentUsed)} of budget used — projected {formatUsd(plan.projectedMonthEnd)} by {endLabel} + {fmtPct(plan.percentUsed)} of budget used; projected {formatUsd(plan.projectedMonthEnd)} by {endLabel}
) } diff --git a/app/renderer/sections/Settings.test.tsx b/app/renderer/sections/Settings.test.tsx index 0dc68b0..171e3c1 100644 --- a/app/renderer/sections/Settings.test.tsx +++ b/app/renderer/sections/Settings.test.tsx @@ -163,7 +163,7 @@ describe('Settings', () => { expect(await screen.findByText('toruk-mini')).toBeInTheDocument() expect(screen.getByText('34 sessions · $41.20 this month')).toBeInTheDocument() expect(screen.getByText('Visible')).toBeInTheDocument() - expect(screen.getByText(/pairing is interactive/)).toBeInTheDocument() + expect(screen.getByText(/Pairing is interactive/)).toBeInTheDocument() expect(screen.queryByText('Approve')).not.toBeInTheDocument() expect(screen.queryByText('Pull now')).not.toBeInTheDocument() await user.click(screen.getByRole('button', { name: 'Remove' })) @@ -190,6 +190,6 @@ describe('Settings', () => { render() await user.click(screen.getByRole('button', { name: 'Devices' })) await waitFor(() => expect(screen.getAllByText('Locate the codeburn CLI')).toHaveLength(2)) - expect(screen.getByText('permission denied — grant Full Disk Access')).toHaveStyle({ color: 'var(--amber)' }) + expect(screen.getByText('permission denied; grant Full Disk Access')).toHaveStyle({ color: 'var(--amber)' }) }) }) diff --git a/app/renderer/sections/Settings.tsx b/app/renderer/sections/Settings.tsx index e4f03b7..e01bbf5 100644 --- a/app/renderer/sections/Settings.tsx +++ b/app/renderer/sections/Settings.tsx @@ -142,7 +142,7 @@ function ProvidersPane({ period, refreshToken }: { period: Period; refreshToken: const overview = usePolled(() => codeburn.getOverview(period, 'all'), [period, refreshToken]) const providers = Object.entries(overview.data?.current.providers ?? {}) return
-

Providers

codeburn auto-detects coding tools from local session files — no setup needed.

+

Providers

codeburn auto-detects coding tools from local session files. No setup needed.

{overview.error ? : !overview.data ?

Loading detected providers…

: providers.length === 0 ?

No providers detected.

: providers.map(([name, cost]) =>
{name.charAt(0).toUpperCase() + name.slice(1)}Detected · {formatUsd(cost)}
)}
} @@ -278,7 +278,7 @@ function ThisDevicePanel({ identity, shareStatus }: { identity: ReturnType> }) { const found = scan.data?.found.filter(device => !device.paired) ?? [] - return {!scan.data && scan.error ? : !scan.data ?

listening…

: found.length === 0 ?

No nearby devices found.

: found.map(device =>
{device.name}fingerprint {shortFingerprint(device.fingerprint)}
)}

To pair a device, run codeburn devices add in a terminal — pairing is interactive (approve on the other device).

+ return {!scan.data && scan.error ? : !scan.data ?

listening…

: found.length === 0 ?

No nearby devices found.

: found.map(device =>
{device.name}fingerprint {shortFingerprint(device.fingerprint)}
)}

To pair a device, run codeburn devices add in a terminal. Pairing is interactive (approve on the other device).

} function PairedPanel({ devices, period, onRefresh }: { devices: ReturnType>; period: Period; onRefresh: () => void }) {