@brimveyn/aimux 1.9.3 → 1.9.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/package.json +2 -2
  2. package/src/app-runtime/side-effects.ts +29 -0
  3. package/src/app.tsx +4 -5
  4. package/src/input/modes/types.ts +2 -0
  5. package/src/pty/terminal-snapshot.ts +7 -7
  6. package/src/state/reducers/git-mode-state.ts +33 -1
  7. package/src/state/types.ts +1 -0
  8. package/src/ui/components/git/diff-renderer/build-rows.ts +21 -0
  9. package/src/ui/components/git/diff-renderer/fold-strip.tsx +7 -7
  10. package/src/ui/components/git/diff-renderer/pierre-diff.tsx +3 -3
  11. package/src/ui/components/git/diff-renderer/split-view.tsx +18 -17
  12. package/src/ui/components/git/diff-renderer/stacked-view.tsx +13 -13
  13. package/src/ui/components/git/git-panel.tsx +42 -39
  14. package/src/ui/components/git/git-view.tsx +20 -20
  15. package/src/ui/components/layout/session-bar.tsx +13 -13
  16. package/src/ui/components/layout/sidebar/sidebar.tsx +26 -28
  17. package/src/ui/components/layout/sidebar/tab-item.tsx +21 -21
  18. package/src/ui/components/layout/split-layout.tsx +2 -2
  19. package/src/ui/components/layout/status-bar.tsx +12 -12
  20. package/src/ui/components/layout/terminal-pane.tsx +19 -31
  21. package/src/ui/components/modals/app/ai-usage-modal.tsx +21 -21
  22. package/src/ui/components/modals/app/help-modal.tsx +5 -6
  23. package/src/ui/components/modals/app/update-available-modal.tsx +3 -3
  24. package/src/ui/components/modals/git/git-commit-modal.tsx +17 -17
  25. package/src/ui/components/modals/sessions/create-session-modal.tsx +8 -8
  26. package/src/ui/components/modals/sessions/session-picker-modal.tsx +6 -6
  27. package/src/ui/components/modals/shared/form.tsx +4 -4
  28. package/src/ui/components/modals/shared/modal-keybinds-overlay.tsx +4 -4
  29. package/src/ui/components/modals/shared/modal-shell.tsx +6 -6
  30. package/src/ui/components/modals/shared/picker.tsx +6 -6
  31. package/src/ui/components/modals/snippets/snippet-picker-modal.tsx +5 -5
  32. package/src/ui/components/modals/tabs/new-tab-modal.tsx +6 -6
  33. package/src/ui/components/modals/themes/theme-picker-modal.tsx +17 -20
  34. package/src/ui/components/overlays/ai-usage/ai-usage-indicator.tsx +12 -12
  35. package/src/ui/components/overlays/context-menu/context-menu-overlay.tsx +6 -6
  36. package/src/ui/components/overlays/pending-chord-overlay.tsx +5 -5
  37. package/src/ui/components/primitives/bare-input.tsx +5 -5
  38. package/src/ui/components/primitives/input-field.tsx +5 -5
  39. package/src/ui/components/primitives/list-item.tsx +27 -22
  40. package/src/ui/components/primitives/surface.tsx +12 -9
  41. package/src/ui/filter-themes.ts +9 -8
  42. package/src/ui/root.tsx +5 -4
  43. package/src/ui/shiki.ts +8 -11
  44. package/src/ui/theme-store.ts +48 -118
  45. package/src/ui/theme.ts +8 -8
  46. package/src/ui/themes.ts +9 -20
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brimveyn/aimux",
3
- "version": "1.9.3",
3
+ "version": "1.9.6",
4
4
  "description": "A terminal multiplexer for AI CLIs. Run Claude, Codex, OpenCode side-by-side with tabbed navigation, split panes, and persistent sessions.",
5
5
  "keywords": [
6
6
  "ai",
@@ -60,7 +60,7 @@
60
60
  "bump": "bun run scripts/bump.ts"
61
61
  },
62
62
  "dependencies": {
63
- "@brimveyn/aimux-config": "0.5.3",
63
+ "@brimveyn/aimux-config": "0.5.5",
64
64
  "@opentui/core": "^0.1.90",
65
65
  "@opentui/react": "^0.1.90",
66
66
  "@xterm/headless": "^6.0.0",
@@ -548,6 +548,16 @@ export function executeSideEffect(effect: SideEffect, ctx: SideEffectContext): v
548
548
  )
549
549
  return
550
550
  }
551
+ case 'git-stage-all': {
552
+ const paths = ctx.state.gitPanel.files.map((f) => f.path)
553
+ void enqueueGitOp(() => runGitActionAll(ctx, ['add', '-A'], paths))
554
+ return
555
+ }
556
+ case 'git-unstage-all': {
557
+ const paths = ctx.state.gitPanel.files.map((f) => f.path)
558
+ void enqueueGitOp(() => runGitActionAll(ctx, ['reset'], paths))
559
+ return
560
+ }
551
561
  case 'git-restore': {
552
562
  void enqueueGitOp(() => runGitAction(ctx, ['restore', '--', effect.path], effect.path))
553
563
  return
@@ -670,6 +680,25 @@ async function runGitAction(
670
680
  }
671
681
  }
672
682
 
683
+ async function runGitActionAll(
684
+ ctx: SideEffectContext,
685
+ args: string[],
686
+ pathsToInvalidate: string[]
687
+ ): Promise<void> {
688
+ const cwd = ctx.getCurrentSessionProjectPath()
689
+ if (!cwd) return
690
+ const result = await $`git -C ${cwd} ${args}`.quiet().nothrow()
691
+ if (result.exitCode !== 0) {
692
+ const stderr = result.stderr.toString().trim()
693
+ ctx.dispatch({ message: stderr || 'git action failed', type: 'git-mode-set-message' })
694
+ return
695
+ }
696
+ ctx.dispatch({ message: null, type: 'git-mode-set-message' })
697
+ if (pathsToInvalidate.length > 0) {
698
+ ctx.dispatch({ paths: pathsToInvalidate, type: 'git-mode-invalidate-diffs' })
699
+ }
700
+ }
701
+
673
702
  async function runGitRm(ctx: SideEffectContext, path: string): Promise<void> {
674
703
  const repoPath = ctx.state.gitPanel.files.find((f) => f.path === path)?.repoPath
675
704
  const cwd = repoPath ?? ctx.getCurrentSessionProjectPath()
package/src/app.tsx CHANGED
@@ -35,7 +35,7 @@ import { loadSnippetCatalog } from './state/snippet-catalog'
35
35
  import { createInitialState } from './state/store'
36
36
  import { KeymapContext } from './ui/keymap-context'
37
37
  import { RootView } from './ui/root'
38
- import { applyTheme, setTransparent } from './ui/theme'
38
+ import { applyTheme, setMode, setTransparent } from './ui/theme'
39
39
  import { isKnownThemeId, type ThemeId } from './ui/themes'
40
40
  import {
41
41
  fetchLatestNpmVersion,
@@ -71,10 +71,9 @@ export function App({
71
71
  const [themeId, setThemeId] = useState<ThemeId>(() => {
72
72
  const config = loadConfig()
73
73
  const persisted = config.themeId && isKnownThemeId(config.themeId) ? config.themeId : undefined
74
- const fromConfig: ThemeId =
75
- resolvedConfig.theme?.initialMode === 'light' ? 'aimux-light' : 'aimux-dark'
76
- const initial: ThemeId = persisted ?? fromConfig
77
- applyTheme(initial, resolvedConfig.theme?.paletteOverrides)
74
+ const initial: ThemeId = persisted ?? resolvedConfig.theme?.initialId ?? 'aimux'
75
+ applyTheme(initial)
76
+ if (resolvedConfig.theme?.initialMode) setMode(resolvedConfig.theme.initialMode)
78
77
  setTransparent(config.themeTransparent ?? false)
79
78
  return initial
80
79
  })
@@ -55,6 +55,8 @@ export type SideEffect =
55
55
  | { type: 'persist-git-tree-compaction'; enabled: boolean }
56
56
  | { type: 'git-stage'; path: string }
57
57
  | { type: 'git-unstage'; path: string }
58
+ | { type: 'git-stage-all' }
59
+ | { type: 'git-unstage-all' }
58
60
  | { type: 'git-restore'; path: string }
59
61
  | { type: 'git-rm'; path: string }
60
62
  | { type: 'git-commit'; title: string; body: string }
@@ -2,7 +2,7 @@ import type { Terminal } from '@xterm/headless'
2
2
 
3
3
  import type { TerminalLine, TerminalSnapshot, TerminalSpan } from '../state/types'
4
4
 
5
- import { getCurrentTokens } from '../ui/theme'
5
+ import { getCurrentTheme } from '../ui/theme'
6
6
 
7
7
  const SNAPSHOT_TAIL_LINE_COUNT = 10
8
8
 
@@ -115,17 +115,17 @@ function buildLine(
115
115
  let bg = getColorHex(current.getBgColor(), bgMode)
116
116
 
117
117
  if (current.isInverse()) {
118
- const tokens = getCurrentTokens()
119
- const resolvedFg = fg ?? tokens.palette.ink
120
- const resolvedBg = bg ?? tokens.bg
118
+ const tokens = getCurrentTheme()
119
+ const resolvedFg = fg ?? tokens.text
120
+ const resolvedBg = bg ?? tokens.background
121
121
  ;[fg, bg] = [resolvedBg, resolvedFg]
122
122
  }
123
123
 
124
124
  const isCursorCell = cursorVisible && cursorColumn === column
125
125
  if (isCursorCell) {
126
- const tokens = getCurrentTokens()
127
- const resolvedFg = fg ?? tokens.palette.ink
128
- const resolvedBg = bg ?? tokens.bg
126
+ const tokens = getCurrentTheme()
127
+ const resolvedFg = fg ?? tokens.text
128
+ const resolvedBg = bg ?? tokens.background
129
129
  ;[fg, bg] = [resolvedBg, resolvedFg]
130
130
  }
131
131
 
@@ -1,5 +1,6 @@
1
- import type { AppAction, AppState, FoldState, GitFileEntry, GitModeState } from '../types'
1
+ import type { PreparedParsedDiff } from '../../ui/components/git/diff-renderer/prepare-diff'
2
2
 
3
+ import { collectFoldables } from '../../ui/components/git/diff-renderer/build-rows'
3
4
  import {
4
5
  getSelectedGitRow,
5
6
  gitFileKey,
@@ -7,6 +8,14 @@ import {
7
8
  moveGitSelection,
8
9
  reconcileSelectedGitEntryKey,
9
10
  } from '../git-tree'
11
+ import {
12
+ type AppAction,
13
+ type AppState,
14
+ type FoldState,
15
+ getParsedPayload,
16
+ type GitFileEntry,
17
+ type GitModeState,
18
+ } from '../types'
10
19
  import { clearDiffCacheForPath, clearDiffCacheForPaths } from './diff-cache'
11
20
  import { sortFilesBySection } from './git-panel-state'
12
21
 
@@ -439,6 +448,29 @@ export function reduceGitModeState(state: AppState, action: AppAction): AppState
439
448
  const bottom = Math.max(0, action.bottom)
440
449
  return applyFold(state, action.key, action.foldId, { bottom, top })
441
450
  }
451
+ case 'git-mode-fold-toggle-all': {
452
+ const parsed = getParsedPayload<PreparedParsedDiff>(state.gitMode.parsedFiles[action.key])
453
+ const file = parsed?.file
454
+ if (!file || !Array.isArray(file.hunks)) return state
455
+ const foldables = collectFoldables(file)
456
+ if (foldables.length === 0) return state
457
+ const current = state.gitMode.folds[action.key] ?? {}
458
+ const allExpanded = foldables.every(({ foldId, middle }) => {
459
+ const fs = current[foldId] ?? { bottom: 0, top: 0 }
460
+ return fs.top + fs.bottom >= middle
461
+ })
462
+ const nextFolds = { ...state.gitMode.folds }
463
+ if (allExpanded) {
464
+ delete nextFolds[action.key]
465
+ } else {
466
+ const perPath: Record<string, FoldState> = {}
467
+ for (const { foldId, middle } of foldables) {
468
+ perPath[foldId] = { bottom: 0, top: middle }
469
+ }
470
+ nextFolds[action.key] = perPath
471
+ }
472
+ return { ...state, gitMode: { ...state.gitMode, folds: nextFolds } }
473
+ }
442
474
  case 'git-mode-optimistic-move': {
443
475
  const currentKey = state.gitMode.selectedEntryKey
444
476
  const files = state.gitPanel.files
@@ -650,6 +650,7 @@ export type GitModeAction =
650
650
  delta: number
651
651
  }
652
652
  | { type: 'git-mode-fold-set'; key: string; foldId: string; top: number; bottom: number }
653
+ | { type: 'git-mode-fold-toggle-all'; key: string }
653
654
  | {
654
655
  type: 'git-mode-optimistic-move'
655
656
  path: string
@@ -181,6 +181,27 @@ function contextNeighbors(
181
181
  return { hasChangeAfter, hasChangeBefore }
182
182
  }
183
183
 
184
+ export interface Foldable {
185
+ foldId: string
186
+ middle: number
187
+ }
188
+
189
+ export function collectFoldables(file: FileDiffMetadata): Foldable[] {
190
+ const result: Foldable[] = []
191
+ for (const [hIdx, hunk] of file.hunks.entries()) {
192
+ for (const [cIdx, content] of hunk.hunkContent.entries()) {
193
+ if (content.type !== 'context') continue
194
+ const { hasChangeAfter, hasChangeBefore } = contextNeighbors(hunk.hunkContent, cIdx)
195
+ const preKeep = hasChangeBefore ? Math.min(KEEP_CONTEXT, content.lines) : 0
196
+ const postKeep = hasChangeAfter ? Math.min(KEEP_CONTEXT, content.lines - preKeep) : 0
197
+ const middle = content.lines - preKeep - postKeep
198
+ if (middle < MIN_FOLD_SIZE) continue
199
+ result.push({ foldId: `${hIdx}:${cIdx}`, middle })
200
+ }
201
+ }
202
+ return result
203
+ }
204
+
184
205
  export function buildDiffSegments(file: FileDiffMetadata, folds: FoldMap = {}): DiffSegmentBuild {
185
206
  const segments: DiffSegment[] = []
186
207
  let offset = 0
@@ -1,4 +1,4 @@
1
- import { useBg, useTokens } from '../../../theme'
1
+ import { useTheme } from '../../../theme'
2
2
  import { FOLD_STEP, type FoldInfo } from './build-rows'
3
3
  import { type FoldDispatch } from './pierre-diff'
4
4
 
@@ -8,11 +8,11 @@ interface Props {
8
8
  }
9
9
 
10
10
  function Button({ label, onPress }: { label: string; onPress: () => void }) {
11
- const t = useTokens()
12
- const bg = useBg('elevated')
11
+ const t = useTheme()
12
+ const bg = t.diffContextBg
13
13
  return (
14
14
  <box paddingLeft={1} paddingRight={1} backgroundColor={bg} onMouseDown={onPress}>
15
- <text fg={t.palette.primary}>{label}</text>
15
+ <text fg={t.primary}>{label}</text>
16
16
  </box>
17
17
  )
18
18
  }
@@ -22,8 +22,8 @@ function Spacer() {
22
22
  }
23
23
 
24
24
  export function FoldStrip({ dispatch, fold }: Props) {
25
- const t = useTokens()
26
- const headerBg = useBg('elevated')
25
+ const t = useTheme()
26
+ const headerBg = t.diffContextBg
27
27
  const { bottomExpanded, foldId, hidden, topExpanded, total } = fold
28
28
  const stepUp = Math.min(FOLD_STEP, hidden)
29
29
  const stepDown = Math.min(FOLD_STEP, hidden)
@@ -71,7 +71,7 @@ export function FoldStrip({ dispatch, fold }: Props) {
71
71
 
72
72
  return (
73
73
  <box flexDirection="row" backgroundColor={headerBg} paddingLeft={1} paddingRight={1}>
74
- <text fg={t.muted}>{`⋯ ${hidden} hidden `}</text>
74
+ <text fg={t.textMuted}>{`⋯ ${hidden} hidden `}</text>
75
75
  {controls}
76
76
  </box>
77
77
  )
@@ -8,7 +8,7 @@ import type { ThemeId } from '../../../themes'
8
8
  import { useAppStore } from '../../../../state/app-store'
9
9
  import { dispatchGlobal } from '../../../../state/dispatch-ref'
10
10
  import { type FoldState } from '../../../../state/types'
11
- import { useTokens } from '../../../theme'
11
+ import { useTheme } from '../../../theme'
12
12
  import { buildDiffSegments, firstChangeSegmentOffset, gutterWidth } from './build-rows'
13
13
  import { SplitView, type SplitViewHandle } from './split-view'
14
14
  import { StackedView, type StackedViewHandle } from './stacked-view'
@@ -45,7 +45,7 @@ export const PierreDiff = forwardRef<PierreDiffHandle, Props>(function PierreDif
45
45
  { cacheKey, diff, path, themeId, view },
46
46
  ref
47
47
  ) {
48
- const t = useTokens()
48
+ const t = useTheme()
49
49
  const preparation = useDiffPreparation(cacheKey, diff, path, themeId)
50
50
  const file = preparation.file ?? undefined
51
51
  const highlights: DiffHighlights = preparation.highlights
@@ -123,7 +123,7 @@ export const PierreDiff = forwardRef<PierreDiffHandle, Props>(function PierreDif
123
123
  if (!file) {
124
124
  return (
125
125
  <box flexGrow={1} padding={1}>
126
- <text fg={t.muted}>
126
+ <text fg={t.textMuted}>
127
127
  {preparation.preparing ? 'Preparing diff…' : '(could not parse diff)'}
128
128
  </text>
129
129
  </box>
@@ -20,7 +20,7 @@ import type { DiffHighlights, FoldDispatch } from './pierre-diff'
20
20
 
21
21
  import { getScrollViewportDelta } from '../../../../app-runtime/terminal-mouse-adapter'
22
22
  import { scrollGitDiff } from '../../../git-view-controls'
23
- import { useBg, useTokens, useTransparent } from '../../../theme'
23
+ import { useTheme, useTransparent } from '../../../theme'
24
24
  import {
25
25
  type DiffSegment,
26
26
  estimatedSegmentHeight,
@@ -67,7 +67,8 @@ export const SplitView = forwardRef<SplitViewHandle, Props>(function SplitView(
67
67
  { contentWidth, file, foldDispatch, highlights, requestSegmentHighlights, segments },
68
68
  ref
69
69
  ) {
70
- const separatorBg = useBg('base')
70
+ const t = useTheme()
71
+ const separatorBg = t.background
71
72
  const leftRef = useRef<ScrollBoxRenderable | null>(null)
72
73
  const rightRef = useRef<ScrollBoxRenderable | null>(null)
73
74
  const measuredHeightsRef = useRef<Record<string, number>>({})
@@ -224,12 +225,12 @@ function SideRow({
224
225
  }
225
226
 
226
227
  function HunkHeaderRow({ row }: { row: Extract<SplitRowOrHeader, { type: 'hunk-header' }> }) {
227
- const t = useTokens()
228
- const headerBg = useBg('elevated')
228
+ const t = useTheme()
229
+ const headerBg = t.diffContextBg
229
230
  return (
230
231
  <box flexDirection="row" backgroundColor={headerBg} paddingLeft={1} paddingRight={1}>
231
- <text fg={t.muted}>{row.spec}</text>
232
- {row.context ? <text fg={t.hover}> {row.context}</text> : null}
232
+ <text fg={t.text}>{row.spec}</text>
233
+ {row.context ? <text fg={t.textMuted}> {row.context}</text> : null}
233
234
  </box>
234
235
  )
235
236
  }
@@ -245,29 +246,29 @@ function HalfRow({
245
246
  height: number
246
247
  tokens: ThemedToken[][]
247
248
  }) {
248
- const t = useTokens()
249
- const headerBg = useBg('elevated')
249
+ const t = useTheme()
250
+ const headerBg = t.diffContextBg
250
251
  const transparent = useTransparent()
251
252
  if (cell.type === 'filler') {
252
253
  return <box backgroundColor={headerBg} height={height} />
253
254
  }
254
255
  let bg: string | undefined
255
256
  let sign = ' '
256
- let signColor = t.muted
257
+ let signColor = t.textMuted
257
258
  if (cell.type === 'addition') {
258
- bg = t.diffAddBg
259
+ bg = t.diffAddedBg
259
260
  sign = '+'
260
- signColor = t.palette.success
261
+ signColor = t.diffAdded
261
262
  } else if (cell.type === 'deletion') {
262
- bg = t.diffDeleteBg
263
+ bg = t.diffRemovedBg
263
264
  sign = '-'
264
- signColor = t.palette.error
265
+ signColor = t.diffRemoved
265
266
  }
266
267
  const num = String(cell.lineNumber).padStart(gw, ' ')
267
268
  const lineTokens = tokens[cell.lineIdx]
268
269
  return (
269
270
  <box flexDirection="row" backgroundColor={transparent ? undefined : bg} height={height}>
270
- <text fg={t.muted}>{` ${num} `}</text>
271
+ <text fg={t.textMuted}>{` ${num} `}</text>
271
272
  <text fg={signColor}>{`${sign} `}</text>
272
273
  <LineContent content={cell.content} tokens={lineTokens} />
273
274
  </box>
@@ -275,9 +276,9 @@ function HalfRow({
275
276
  }
276
277
 
277
278
  function LineContent({ content, tokens }: { content: string; tokens: ThemedToken[] | undefined }) {
278
- const t = useTokens()
279
+ const t = useTheme()
279
280
  if (!tokens || tokens.length === 0) {
280
- return <text fg={t.palette.ink}>{content}</text>
281
+ return <text fg={t.text}>{content}</text>
281
282
  }
282
283
  return (
283
284
  <text>
@@ -288,7 +289,7 @@ function LineContent({ content, tokens }: { content: string; tokens: ThemedToken
288
289
  if (s.italic) attributes |= TextAttributes.ITALIC
289
290
  if (s.underline) attributes |= TextAttributes.UNDERLINE
290
291
  return (
291
- <span key={i} fg={s.fg ?? t.palette.ink} attributes={attributes}>
292
+ <span key={i} fg={s.fg ?? t.text} attributes={attributes}>
292
293
  {s.text}
293
294
  </span>
294
295
  )
@@ -20,7 +20,7 @@ import type { DiffHighlights, FoldDispatch } from './pierre-diff'
20
20
 
21
21
  import { getScrollViewportDelta } from '../../../../app-runtime/terminal-mouse-adapter'
22
22
  import { scrollGitDiff } from '../../../git-view-controls'
23
- import { useBg, useTokens, useTransparent } from '../../../theme'
23
+ import { useTheme, useTransparent } from '../../../theme'
24
24
  import {
25
25
  type DiffSegment,
26
26
  estimatedSegmentHeight,
@@ -179,14 +179,14 @@ function UnifiedRowRender({
179
179
  highlights: DiffHighlights
180
180
  row: UnifiedRowOrHeader
181
181
  }) {
182
- const t = useTokens()
183
- const headerBg = useBg('elevated')
182
+ const t = useTheme()
183
+ const headerBg = t.diffContextBg
184
184
  const transparent = useTransparent()
185
185
  if (row.type === 'hunk-header') {
186
186
  return (
187
187
  <box flexDirection="row" backgroundColor={headerBg} paddingLeft={1} paddingRight={1}>
188
- <text fg={t.muted}>{row.spec}</text>
189
- {row.context ? <text fg={t.hover}> {row.context}</text> : null}
188
+ <text fg={t.text}>{row.spec}</text>
189
+ {row.context ? <text fg={t.textMuted}> {row.context}</text> : null}
190
190
  </box>
191
191
  )
192
192
  }
@@ -199,21 +199,21 @@ function UnifiedRowRender({
199
199
  const tokens = highlights.add[row.lineIdx]
200
200
  return (
201
201
  <box flexDirection="row" height={row.height}>
202
- <text fg={t.muted}>{` ${pad(row.delLineNumber)} ${pad(row.addLineNumber)} `}</text>
203
- <text fg={t.palette.ink}> </text>
202
+ <text fg={t.textMuted}>{` ${pad(row.delLineNumber)} ${pad(row.addLineNumber)} `}</text>
203
+ <text fg={t.text}> </text>
204
204
  <LineContent content={row.content} tokens={tokens} />
205
205
  </box>
206
206
  )
207
207
  }
208
- const bg = row.type === 'addition' ? t.diffAddBg : t.diffDeleteBg
208
+ const bg = row.type === 'addition' ? t.diffAddedBg : t.diffRemovedBg
209
209
  const sign = row.type === 'addition' ? '+' : '-'
210
- const signColor = row.type === 'addition' ? t.palette.success : t.palette.error
210
+ const signColor = row.type === 'addition' ? t.diffAdded : t.diffRemoved
211
211
  const delNum = row.type === 'deletion' ? row.lineNumber : undefined
212
212
  const addNum = row.type === 'addition' ? row.lineNumber : undefined
213
213
  const tokens = row.type === 'addition' ? highlights.add[row.lineIdx] : highlights.del[row.lineIdx]
214
214
  return (
215
215
  <box flexDirection="row" backgroundColor={transparent ? undefined : bg} height={row.height}>
216
- <text fg={t.muted}>{` ${pad(delNum)} ${pad(addNum)} `}</text>
216
+ <text fg={t.textMuted}>{` ${pad(delNum)} ${pad(addNum)} `}</text>
217
217
  <text fg={signColor}>{`${sign} `}</text>
218
218
  <LineContent content={row.content} tokens={tokens} />
219
219
  </box>
@@ -221,9 +221,9 @@ function UnifiedRowRender({
221
221
  }
222
222
 
223
223
  function LineContent({ content, tokens }: { content: string; tokens: ThemedToken[] | undefined }) {
224
- const t = useTokens()
224
+ const t = useTheme()
225
225
  if (!tokens || tokens.length === 0) {
226
- return <text fg={t.palette.ink}>{content}</text>
226
+ return <text fg={t.text}>{content}</text>
227
227
  }
228
228
  return (
229
229
  <text>
@@ -234,7 +234,7 @@ function LineContent({ content, tokens }: { content: string; tokens: ThemedToken
234
234
  if (s.italic) attributes |= TextAttributes.ITALIC
235
235
  if (s.underline) attributes |= TextAttributes.UNDERLINE
236
236
  return (
237
- <span key={i} fg={s.fg ?? t.palette.ink} attributes={attributes}>
237
+ <span key={i} fg={s.fg ?? t.text} attributes={attributes}>
238
238
  {s.text}
239
239
  </span>
240
240
  )