mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-07-30 03:15:30 +00:00
fix(app): strip prose em-dashes from UI copy
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.
This commit is contained in:
parent
34333dc2c5
commit
144d2b3363
7 changed files with 13 additions and 13 deletions
|
|
@ -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',
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ export function Compare({
|
|||
if (next === modelB) setModelB(nudgeDistinct(next))
|
||||
}}
|
||||
>
|
||||
{modelRows.map(model => <option key={model.model} value={model.model}>{model.model} — {model.calls.toLocaleString()} calls</option>)}
|
||||
{modelRows.map(model => <option key={model.model} value={model.model}>{model.model} · {model.calls.toLocaleString()} calls</option>)}
|
||||
</select>
|
||||
<span className="cmp-vs">vs</span>
|
||||
<select
|
||||
|
|
@ -94,7 +94,7 @@ export function Compare({
|
|||
if (next === modelA) setModelA(nudgeDistinct(next))
|
||||
}}
|
||||
>
|
||||
{modelRows.map(model => <option key={model.model} value={model.model}>{model.model} — {model.calls.toLocaleString()} calls</option>)}
|
||||
{modelRows.map(model => <option key={model.model} value={model.model}>{model.model} · {model.calls.toLocaleString()} calls</option>)}
|
||||
</select>
|
||||
</div>
|
||||
{modelA && modelB && modelA !== modelB && (
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(<Plans period="30days" />)
|
||||
|
||||
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(<Plans period="week" />)
|
||||
|
||||
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)' })
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -154,14 +154,14 @@ function PaceLine({ plan }: { plan: JsonPlanSummary }) {
|
|||
if (plan.status === 'over' || plan.projectedMonthEnd > plan.budget) {
|
||||
return (
|
||||
<div className="pace hot">
|
||||
On pace to exceed — projected {formatUsd(plan.projectedMonthEnd)} by {endLabel}
|
||||
On pace to exceed; projected {formatUsd(plan.projectedMonthEnd)} by {endLabel}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if (plan.status === 'near') {
|
||||
return (
|
||||
<div className="pace hot">
|
||||
{fmtPct(plan.percentUsed)} of budget used — projected {formatUsd(plan.projectedMonthEnd)} by {endLabel}
|
||||
{fmtPct(plan.percentUsed)} of budget used; projected {formatUsd(plan.projectedMonthEnd)} by {endLabel}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(<Settings period="week" />)
|
||||
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)' })
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ function ProvidersPane({ period, refreshToken }: { period: Period; refreshToken:
|
|||
const overview = usePolled<MenubarPayload>(() => codeburn.getOverview(period, 'all'), [period, refreshToken])
|
||||
const providers = Object.entries(overview.data?.current.providers ?? {})
|
||||
return <section className="set-p on">
|
||||
<div><h3 className="set-h">Providers</h3><p className="set-sub">codeburn auto-detects coding tools from local session files — no setup needed.</p></div>
|
||||
<div><h3 className="set-h">Providers</h3><p className="set-sub">codeburn auto-detects coding tools from local session files. No setup needed.</p></div>
|
||||
{overview.error ? <SettingsErrorText error={overview.error} /> : !overview.data ? <p className="set-cap">Loading detected providers…</p> : providers.length === 0 ? <p className="set-cap">No providers detected.</p> : providers.map(([name, cost]) => <div className="card" key={name}><div className="set-prov-head"><ProviderLogo provider={name} /><span className="set-prov-name">{name.charAt(0).toUpperCase() + name.slice(1)}</span><span className="set-status"><span className="set-dot ok" />Detected · {formatUsd(cost)}</span></div></div>)}
|
||||
</section>
|
||||
}
|
||||
|
|
@ -278,7 +278,7 @@ function ThisDevicePanel({ identity, shareStatus }: { identity: ReturnType<typeo
|
|||
|
||||
function DiscoveredPanel({ scan }: { scan: ReturnType<typeof usePolled<DeviceScanResult>> }) {
|
||||
const found = scan.data?.found.filter(device => !device.paired) ?? []
|
||||
return <Panel title="Discovered nearby" right={scan.loading ? 'listening…' : undefined}>{!scan.data && scan.error ? <SettingsErrorText error={scan.error} /> : !scan.data ? <p className="set-cap">listening…</p> : found.length === 0 ? <p className="set-cap">No nearby devices found.</p> : found.map(device => <div className="li" key={`${device.host}:${device.port}:${device.fingerprint}`}><div className="lx"><b>{device.name}</b><span>fingerprint {shortFingerprint(device.fingerprint)}</span></div></div>)}<p className="set-cap set-device-caption">To pair a device, run <code>codeburn devices add</code> in a terminal — pairing is interactive (approve on the other device).</p></Panel>
|
||||
return <Panel title="Discovered nearby" right={scan.loading ? 'listening…' : undefined}>{!scan.data && scan.error ? <SettingsErrorText error={scan.error} /> : !scan.data ? <p className="set-cap">listening…</p> : found.length === 0 ? <p className="set-cap">No nearby devices found.</p> : found.map(device => <div className="li" key={`${device.host}:${device.port}:${device.fingerprint}`}><div className="lx"><b>{device.name}</b><span>fingerprint {shortFingerprint(device.fingerprint)}</span></div></div>)}<p className="set-cap set-device-caption">To pair a device, run <code>codeburn devices add</code> in a terminal. Pairing is interactive (approve on the other device).</p></Panel>
|
||||
}
|
||||
|
||||
function PairedPanel({ devices, period, onRefresh }: { devices: ReturnType<typeof usePolled<CombinedUsage>>; period: Period; onRefresh: () => void }) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue