@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.
- package/package.json +2 -2
- package/src/app-runtime/side-effects.ts +29 -0
- package/src/app.tsx +4 -5
- package/src/input/modes/types.ts +2 -0
- package/src/pty/terminal-snapshot.ts +7 -7
- package/src/state/reducers/git-mode-state.ts +33 -1
- package/src/state/types.ts +1 -0
- package/src/ui/components/git/diff-renderer/build-rows.ts +21 -0
- package/src/ui/components/git/diff-renderer/fold-strip.tsx +7 -7
- package/src/ui/components/git/diff-renderer/pierre-diff.tsx +3 -3
- package/src/ui/components/git/diff-renderer/split-view.tsx +18 -17
- package/src/ui/components/git/diff-renderer/stacked-view.tsx +13 -13
- package/src/ui/components/git/git-panel.tsx +42 -39
- package/src/ui/components/git/git-view.tsx +20 -20
- package/src/ui/components/layout/session-bar.tsx +13 -13
- package/src/ui/components/layout/sidebar/sidebar.tsx +26 -28
- package/src/ui/components/layout/sidebar/tab-item.tsx +21 -21
- package/src/ui/components/layout/split-layout.tsx +2 -2
- package/src/ui/components/layout/status-bar.tsx +12 -12
- package/src/ui/components/layout/terminal-pane.tsx +19 -31
- package/src/ui/components/modals/app/ai-usage-modal.tsx +21 -21
- package/src/ui/components/modals/app/help-modal.tsx +5 -6
- package/src/ui/components/modals/app/update-available-modal.tsx +3 -3
- package/src/ui/components/modals/git/git-commit-modal.tsx +17 -17
- package/src/ui/components/modals/sessions/create-session-modal.tsx +8 -8
- package/src/ui/components/modals/sessions/session-picker-modal.tsx +6 -6
- package/src/ui/components/modals/shared/form.tsx +4 -4
- package/src/ui/components/modals/shared/modal-keybinds-overlay.tsx +4 -4
- package/src/ui/components/modals/shared/modal-shell.tsx +6 -6
- package/src/ui/components/modals/shared/picker.tsx +6 -6
- package/src/ui/components/modals/snippets/snippet-picker-modal.tsx +5 -5
- package/src/ui/components/modals/tabs/new-tab-modal.tsx +6 -6
- package/src/ui/components/modals/themes/theme-picker-modal.tsx +17 -20
- package/src/ui/components/overlays/ai-usage/ai-usage-indicator.tsx +12 -12
- package/src/ui/components/overlays/context-menu/context-menu-overlay.tsx +6 -6
- package/src/ui/components/overlays/pending-chord-overlay.tsx +5 -5
- package/src/ui/components/primitives/bare-input.tsx +5 -5
- package/src/ui/components/primitives/input-field.tsx +5 -5
- package/src/ui/components/primitives/list-item.tsx +27 -22
- package/src/ui/components/primitives/surface.tsx +12 -9
- package/src/ui/filter-themes.ts +9 -8
- package/src/ui/root.tsx +5 -4
- package/src/ui/shiki.ts +8 -11
- package/src/ui/theme-store.ts +48 -118
- package/src/ui/theme.ts +8 -8
- package/src/ui/themes.ts +9 -20
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
type GitTreeFileRow,
|
|
19
19
|
type GitTreeFolderRow,
|
|
20
20
|
} from '../../../state/git-tree'
|
|
21
|
-
import {
|
|
21
|
+
import { getCurrentTheme, getTransparent, useTheme, useTransparent } from '../../theme'
|
|
22
22
|
|
|
23
23
|
interface GitPanelProps {
|
|
24
24
|
collapsedFolders?: Record<string, true>
|
|
@@ -49,19 +49,20 @@ const BASE_SECTION_ORDER: GitFileSection[] = ['staged', 'unstaged', 'untracked']
|
|
|
49
49
|
const HISTORICAL_SECTION_ORDER: GitFileSection[] = ['historical', 'untracked']
|
|
50
50
|
|
|
51
51
|
function statusColor(status: GitFileEntry['status']): string {
|
|
52
|
-
const t =
|
|
52
|
+
const t = getCurrentTheme()
|
|
53
53
|
switch (status) {
|
|
54
54
|
case '?':
|
|
55
|
+
return t.text
|
|
55
56
|
case 'A':
|
|
56
|
-
return t.
|
|
57
|
+
return t.diffAdded
|
|
57
58
|
case 'C':
|
|
58
59
|
case 'R':
|
|
59
|
-
return t.
|
|
60
|
+
return t.text
|
|
60
61
|
case 'D':
|
|
61
62
|
case 'U':
|
|
62
|
-
return t.
|
|
63
|
+
return t.diffRemoved
|
|
63
64
|
case 'M':
|
|
64
|
-
return t.
|
|
65
|
+
return t.warning
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
68
|
|
|
@@ -99,7 +100,7 @@ function renderFileLabel(
|
|
|
99
100
|
pathConfig: GitPanePathConfig,
|
|
100
101
|
fileListMode: GitFileListMode
|
|
101
102
|
): ReactNode {
|
|
102
|
-
const t =
|
|
103
|
+
const t = getCurrentTheme()
|
|
103
104
|
const transform = pathConfig.enabled ? pathConfig.pathFn : undefined
|
|
104
105
|
const displayPath = transform ? transform(file.path) : file.path
|
|
105
106
|
const { basename, prefix } = splitPath(displayPath)
|
|
@@ -108,8 +109,8 @@ function renderFileLabel(
|
|
|
108
109
|
if (!file.renamedFrom) {
|
|
109
110
|
return (
|
|
110
111
|
<text wrapMode="none">
|
|
111
|
-
<span fg={t.
|
|
112
|
-
{showDir ? <span fg={t.
|
|
112
|
+
<span fg={t.text}>{basename}</span>
|
|
113
|
+
{showDir ? <span fg={t.textMuted}> {dir}</span> : null}
|
|
113
114
|
</text>
|
|
114
115
|
)
|
|
115
116
|
}
|
|
@@ -118,11 +119,11 @@ function renderFileLabel(
|
|
|
118
119
|
const renamedDir = stripTrailingSlash(renamed.prefix)
|
|
119
120
|
return (
|
|
120
121
|
<text wrapMode="none">
|
|
121
|
-
<span fg={t.
|
|
122
|
-
{showDir && renamedDir ? <span fg={t.
|
|
123
|
-
<span fg={t.
|
|
124
|
-
<span fg={t.
|
|
125
|
-
{showDir ? <span fg={t.
|
|
122
|
+
<span fg={t.textMuted}>{renamed.basename}</span>
|
|
123
|
+
{showDir && renamedDir ? <span fg={t.textMuted}> {renamedDir}</span> : null}
|
|
124
|
+
<span fg={t.textMuted}> → </span>
|
|
125
|
+
<span fg={t.text}>{basename}</span>
|
|
126
|
+
{showDir ? <span fg={t.textMuted}> {dir}</span> : null}
|
|
126
127
|
</text>
|
|
127
128
|
)
|
|
128
129
|
}
|
|
@@ -136,28 +137,31 @@ function renderDiffCount(
|
|
|
136
137
|
hasNumstat: boolean
|
|
137
138
|
): ReactNode {
|
|
138
139
|
if (!diffCountConfig.enabled) return null
|
|
139
|
-
const t =
|
|
140
|
+
const t = getCurrentTheme()
|
|
140
141
|
if (!hasNumstat) {
|
|
141
142
|
return (
|
|
142
|
-
<text fg={t.
|
|
143
|
+
<text fg={t.textMuted} bg={bg} flexShrink={0}>
|
|
143
144
|
—
|
|
144
145
|
</text>
|
|
145
146
|
)
|
|
146
147
|
}
|
|
147
148
|
return (
|
|
148
149
|
<box flexDirection="row" flexShrink={0}>
|
|
149
|
-
<text fg={
|
|
150
|
-
<text fg={t.
|
|
150
|
+
<text fg={getCurrentTheme().diffAdded} bg={bg}>{`+${padRight(file.added, addedW)}`}</text>
|
|
151
|
+
<text fg={t.textMuted} bg={bg}>
|
|
151
152
|
{' '}
|
|
152
153
|
</text>
|
|
153
|
-
<text
|
|
154
|
+
<text
|
|
155
|
+
fg={getCurrentTheme().diffRemoved}
|
|
156
|
+
bg={bg}
|
|
157
|
+
>{`−${padRight(file.removed, removedW)}`}</text>
|
|
154
158
|
</box>
|
|
155
159
|
)
|
|
156
160
|
}
|
|
157
161
|
|
|
158
162
|
function renderFolderRow(row: GitTreeFolderRow, isSelected: boolean): ReactNode {
|
|
159
|
-
const t =
|
|
160
|
-
const bg = isSelected && !getTransparent() ? t.
|
|
163
|
+
const t = getCurrentTheme()
|
|
164
|
+
const bg = isSelected && !getTransparent() ? t.backgroundElement : undefined
|
|
161
165
|
const onSelect = (): void => {
|
|
162
166
|
dispatchGlobal({ key: row.key, type: 'git-mode-select-entry-by-key' })
|
|
163
167
|
}
|
|
@@ -168,13 +172,13 @@ function renderFolderRow(row: GitTreeFolderRow, isSelected: boolean): ReactNode
|
|
|
168
172
|
<box key={row.key} flexDirection="row" gap={1} backgroundColor={bg} onMouseDown={onSelect}>
|
|
169
173
|
<box flexGrow={1} overflow="hidden" paddingLeft={row.depth * 2}>
|
|
170
174
|
<box flexDirection="row" gap={1} onMouseDown={onToggle}>
|
|
171
|
-
<text fg={t.
|
|
175
|
+
<text fg={t.textMuted} bg={bg}>
|
|
172
176
|
{row.isCollapsed ? '▸' : '▾'}
|
|
173
177
|
</text>
|
|
174
|
-
<text fg={
|
|
178
|
+
<text fg={getCurrentTheme().textMuted} bg={bg}>
|
|
175
179
|
{row.isCollapsed ? '\uf07b' : '\uf07c'}
|
|
176
180
|
</text>
|
|
177
|
-
<text fg={t.
|
|
181
|
+
<text fg={t.textMuted} bg={bg} wrapMode="none">
|
|
178
182
|
{row.name}
|
|
179
183
|
</text>
|
|
180
184
|
</box>
|
|
@@ -193,10 +197,9 @@ function renderFileRow(
|
|
|
193
197
|
diffCountConfig: GitPaneDiffCountConfig,
|
|
194
198
|
repoPrefixes: Record<string, string>
|
|
195
199
|
): ReactNode {
|
|
196
|
-
const t = getCurrentTokens()
|
|
197
200
|
const file = row.file
|
|
198
201
|
const hasNumstat = file.added !== null || file.removed !== null
|
|
199
|
-
const bg = isSelected && !getTransparent() ?
|
|
202
|
+
const bg = isSelected && !getTransparent() ? getCurrentTheme().backgroundElement : undefined
|
|
200
203
|
const onSelect = (): void => {
|
|
201
204
|
dispatchGlobal({ key: row.key, type: 'git-mode-select-entry-by-key' })
|
|
202
205
|
}
|
|
@@ -213,7 +216,7 @@ function renderFileRow(
|
|
|
213
216
|
</box>
|
|
214
217
|
{repoTag ? (
|
|
215
218
|
<box flexShrink={0}>
|
|
216
|
-
<text fg={
|
|
219
|
+
<text fg={getCurrentTheme().primary} bg={bg}>
|
|
217
220
|
<strong>{repoTag}</strong>
|
|
218
221
|
</text>
|
|
219
222
|
</box>
|
|
@@ -242,7 +245,7 @@ function renderTreeSection(
|
|
|
242
245
|
repoPrefixes: Record<string, string>
|
|
243
246
|
): ReactNode {
|
|
244
247
|
if (files.length === 0) return null
|
|
245
|
-
const
|
|
248
|
+
const t2 = getCurrentTheme()
|
|
246
249
|
const nextFileListMode = fileListMode === 'tree' ? 'flat' : 'tree'
|
|
247
250
|
const toggleListMode = (): void => {
|
|
248
251
|
dispatchGlobal({ type: 'git-mode-toggle-file-list-mode' })
|
|
@@ -251,16 +254,16 @@ function renderTreeSection(
|
|
|
251
254
|
return (
|
|
252
255
|
<box key={section} flexDirection="column" marginTop={marginTop}>
|
|
253
256
|
<box flexDirection="row" justifyContent="space-between">
|
|
254
|
-
<text fg={
|
|
257
|
+
<text fg={t2.text}>
|
|
255
258
|
<strong>
|
|
256
259
|
{title} ({files.length})
|
|
257
260
|
</strong>
|
|
258
261
|
</text>
|
|
259
262
|
{showListModeToggle ? (
|
|
260
263
|
<box flexDirection="row" gap={1} onMouseDown={toggleListMode}>
|
|
261
|
-
<text fg={fileListMode === 'tree' ?
|
|
262
|
-
<text fg={
|
|
263
|
-
<text fg={fileListMode === 'flat' ?
|
|
264
|
+
<text fg={fileListMode === 'tree' ? t2.primary : t2.textMuted}>tree</text>
|
|
265
|
+
<text fg={t2.textMuted}>|</text>
|
|
266
|
+
<text fg={fileListMode === 'flat' ? t2.primary : t2.textMuted}>flat</text>
|
|
264
267
|
</box>
|
|
265
268
|
) : null}
|
|
266
269
|
</box>
|
|
@@ -301,18 +304,18 @@ function computeStatusPlaceholder(
|
|
|
301
304
|
gitPanel: GitPanelState,
|
|
302
305
|
hasProjectPath: boolean
|
|
303
306
|
): StatusPlaceholder | null {
|
|
304
|
-
const t =
|
|
307
|
+
const t = getCurrentTheme()
|
|
305
308
|
if (!hasProjectPath) {
|
|
306
|
-
return { label: 'No active session', labelColor: t.
|
|
309
|
+
return { label: 'No active session', labelColor: t.textMuted }
|
|
307
310
|
}
|
|
308
311
|
if (gitPanel.error === 'not-a-repo') {
|
|
309
|
-
return { label: 'Not a git repository', labelColor: t.
|
|
312
|
+
return { label: 'Not a git repository', labelColor: t.textMuted }
|
|
310
313
|
}
|
|
311
314
|
if (gitPanel.error === 'unknown') {
|
|
312
|
-
return { label: 'Git error', labelColor: t.
|
|
315
|
+
return { label: 'Git error', labelColor: t.error }
|
|
313
316
|
}
|
|
314
317
|
if (gitPanel.files.length === 0) {
|
|
315
|
-
return { label: 'Working tree clean', labelColor: t.
|
|
318
|
+
return { label: 'Working tree clean', labelColor: t.textMuted }
|
|
316
319
|
}
|
|
317
320
|
return null
|
|
318
321
|
}
|
|
@@ -331,7 +334,7 @@ export const GitPanel = memo(function GitPanel({
|
|
|
331
334
|
projectPath,
|
|
332
335
|
selectedEntryKey,
|
|
333
336
|
}: GitPanelProps) {
|
|
334
|
-
const t =
|
|
337
|
+
const t = useTheme()
|
|
335
338
|
useTransparent()
|
|
336
339
|
const repoPrefixes = useAppStore((s) => s.multiRepo.prefixes)
|
|
337
340
|
const sectionOrder = headOffset > 0 ? HISTORICAL_SECTION_ORDER : BASE_SECTION_ORDER
|
|
@@ -367,7 +370,7 @@ export const GitPanel = memo(function GitPanel({
|
|
|
367
370
|
return (
|
|
368
371
|
<box flexDirection="column" flexGrow={1} flexShrink={1} flexBasis={0} overflow="hidden" gap={0}>
|
|
369
372
|
{hasRemoteTracking ? (
|
|
370
|
-
<text fg={t.
|
|
373
|
+
<text fg={t.textMuted}>
|
|
371
374
|
↑{gitPanel.ahead} ↓{gitPanel.behind}
|
|
372
375
|
</text>
|
|
373
376
|
) : null}
|
|
@@ -12,7 +12,7 @@ import { useAppStore } from '../../../state/app-store'
|
|
|
12
12
|
import { dispatchGlobal } from '../../../state/dispatch-ref'
|
|
13
13
|
import { getSelectedGitFile, gitFileKey } from '../../../state/git-tree'
|
|
14
14
|
import { setGitDiffScroller } from '../../git-view-controls'
|
|
15
|
-
import {
|
|
15
|
+
import { useTheme } from '../../theme'
|
|
16
16
|
import { PierreDiff, type PierreDiffHandle } from './diff-renderer'
|
|
17
17
|
import { useDiffPrefetch } from './diff-renderer/use-diff-prefetch'
|
|
18
18
|
import { GitPanel } from './git-panel'
|
|
@@ -48,25 +48,25 @@ const DiffStage = memo(function DiffStage({
|
|
|
48
48
|
themeId,
|
|
49
49
|
view,
|
|
50
50
|
}: DiffStageProps) {
|
|
51
|
-
const t =
|
|
51
|
+
const t = useTheme()
|
|
52
52
|
if (loading && !diff) {
|
|
53
53
|
return (
|
|
54
54
|
<box flexGrow={1} padding={1}>
|
|
55
|
-
<text fg={t.
|
|
55
|
+
<text fg={t.textMuted}>Loading diff…</text>
|
|
56
56
|
</box>
|
|
57
57
|
)
|
|
58
58
|
}
|
|
59
59
|
if (!diff) {
|
|
60
60
|
return (
|
|
61
61
|
<box flexGrow={1} padding={1}>
|
|
62
|
-
<text fg={t.
|
|
62
|
+
<text fg={t.textMuted}>Select a file.</text>
|
|
63
63
|
</box>
|
|
64
64
|
)
|
|
65
65
|
}
|
|
66
66
|
if (diff.errorMessage) {
|
|
67
67
|
return (
|
|
68
68
|
<box flexGrow={1} padding={1}>
|
|
69
|
-
<text fg={t.
|
|
69
|
+
<text fg={t.error}>{diff.errorMessage}</text>
|
|
70
70
|
</box>
|
|
71
71
|
)
|
|
72
72
|
}
|
|
@@ -75,7 +75,7 @@ const DiffStage = memo(function DiffStage({
|
|
|
75
75
|
if (placeholder) {
|
|
76
76
|
return (
|
|
77
77
|
<box flexGrow={1} padding={1}>
|
|
78
|
-
<text fg={t.
|
|
78
|
+
<text fg={t.textMuted}>{placeholder}</text>
|
|
79
79
|
</box>
|
|
80
80
|
)
|
|
81
81
|
}
|
|
@@ -84,7 +84,7 @@ const DiffStage = memo(function DiffStage({
|
|
|
84
84
|
<box flexDirection="column" flexGrow={1} overflow="hidden">
|
|
85
85
|
{diff.oldPath ? (
|
|
86
86
|
<box paddingLeft={1} paddingRight={1}>
|
|
87
|
-
<text fg={t.
|
|
87
|
+
<text fg={t.textMuted}>
|
|
88
88
|
renamed: {diff.oldPath} → {diff.path}
|
|
89
89
|
</text>
|
|
90
90
|
</box>
|
|
@@ -106,9 +106,9 @@ interface GitViewProps {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
export const GitView = memo(function GitView({ themeId }: GitViewProps) {
|
|
109
|
-
const t =
|
|
110
|
-
const sidebarBg =
|
|
111
|
-
const actionBg =
|
|
109
|
+
const t = useTheme()
|
|
110
|
+
const sidebarBg = t.background
|
|
111
|
+
const actionBg = t.backgroundElement
|
|
112
112
|
const dimensions = useTerminalDimensions()
|
|
113
113
|
const gitPane = useAppStore((s) => s.gitPane)
|
|
114
114
|
const gitPanel = useAppStore((s) => s.gitPanel)
|
|
@@ -196,13 +196,13 @@ export const GitView = memo(function GitView({ themeId }: GitViewProps) {
|
|
|
196
196
|
let footerNode: React.ReactNode = null
|
|
197
197
|
if (pendingHint) {
|
|
198
198
|
footerNode = (
|
|
199
|
-
<text fg={t.
|
|
199
|
+
<text fg={t.warning}>
|
|
200
200
|
<strong>{pendingHint}</strong>
|
|
201
201
|
</text>
|
|
202
202
|
)
|
|
203
203
|
} else if (actionMessage) {
|
|
204
204
|
footerNode = actionMessage.split('\n').map((line, idx) => (
|
|
205
|
-
<text key={idx} fg={t.
|
|
205
|
+
<text key={idx} fg={t.primary}>
|
|
206
206
|
{line}
|
|
207
207
|
</text>
|
|
208
208
|
))
|
|
@@ -220,24 +220,24 @@ export const GitView = memo(function GitView({ themeId }: GitViewProps) {
|
|
|
220
220
|
overflow="hidden"
|
|
221
221
|
>
|
|
222
222
|
<box flexDirection="column" flexShrink={0}>
|
|
223
|
-
<text fg={t.
|
|
223
|
+
<text fg={t.text}>
|
|
224
224
|
<strong>aimux · git</strong>
|
|
225
225
|
</text>
|
|
226
226
|
{gitPanel.branch ? (
|
|
227
227
|
<box flexDirection="row">
|
|
228
|
-
<text fg={t.
|
|
229
|
-
<text fg={t.
|
|
228
|
+
<text fg={t.text}>{'\u{e702}'} </text>
|
|
229
|
+
<text fg={t.text}>{gitPanel.branch}</text>
|
|
230
230
|
</box>
|
|
231
231
|
) : null}
|
|
232
232
|
{gitMode.headOffset > 0 ? (
|
|
233
233
|
<box flexDirection="row" gap={1}>
|
|
234
|
-
<text fg={t.
|
|
234
|
+
<text fg={t.warning}>
|
|
235
235
|
<strong>HEAD~{gitMode.headOffset}</strong>
|
|
236
236
|
</text>
|
|
237
|
-
<text fg={t.
|
|
237
|
+
<text fg={t.textMuted}>[ newer · ] older</text>
|
|
238
238
|
</box>
|
|
239
239
|
) : null}
|
|
240
|
-
<text fg={t.
|
|
240
|
+
<text fg={t.textMuted}>{'·'.repeat(Math.max(0, fileBarWidth - 2))}</text>
|
|
241
241
|
</box>
|
|
242
242
|
<GitPanel
|
|
243
243
|
collapsedFolders={gitMode.collapsedFolders}
|
|
@@ -258,7 +258,7 @@ export const GitView = memo(function GitView({ themeId }: GitViewProps) {
|
|
|
258
258
|
backgroundColor={sidebarBg}
|
|
259
259
|
>
|
|
260
260
|
<box flexGrow={1}>
|
|
261
|
-
<text fg={selectedFile ? t.
|
|
261
|
+
<text fg={selectedFile ? t.text : t.textMuted}>
|
|
262
262
|
{selectedFile ? selectedFile.path : 'Diff'}
|
|
263
263
|
</text>
|
|
264
264
|
</box>
|
|
@@ -272,7 +272,7 @@ export const GitView = memo(function GitView({ themeId }: GitViewProps) {
|
|
|
272
272
|
dispatchGlobal({ type: 'exit-git-mode' })
|
|
273
273
|
}}
|
|
274
274
|
>
|
|
275
|
-
<text fg={t.
|
|
275
|
+
<text fg={t.text}>
|
|
276
276
|
<strong>Exit diff</strong>
|
|
277
277
|
</text>
|
|
278
278
|
</box>
|
|
@@ -10,7 +10,7 @@ import { dispatchGlobal, runSideEffectGlobal } from '../../../state/dispatch-ref
|
|
|
10
10
|
import { IDLE_SESSION_STATUS } from '../../../state/types'
|
|
11
11
|
import { useBusySpinner } from '../../hooks/use-busy-spinner'
|
|
12
12
|
import { moveIdToIdPosition, orderSessionsForDisplay } from '../../session-ordering'
|
|
13
|
-
import {
|
|
13
|
+
import { useTheme } from '../../theme'
|
|
14
14
|
import { ContextMenuBox } from '../overlays/context-menu/context-menu-box'
|
|
15
15
|
|
|
16
16
|
interface SessionBarProps {
|
|
@@ -18,8 +18,8 @@ interface SessionBarProps {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export function SessionBar({ forceVisible = false }: SessionBarProps) {
|
|
21
|
-
const t =
|
|
22
|
-
const headerBg =
|
|
21
|
+
const t = useTheme()
|
|
22
|
+
const headerBg = t.backgroundPanel
|
|
23
23
|
const sessions = useAppStore((s) => s.sessions)
|
|
24
24
|
const currentId = useAppStore((s) => s.currentSessionId)
|
|
25
25
|
const bar = useAppStore((s) => s.sessionBar)
|
|
@@ -151,13 +151,13 @@ export function SessionBar({ forceVisible = false }: SessionBarProps) {
|
|
|
151
151
|
flexDirection="row"
|
|
152
152
|
paddingLeft={1}
|
|
153
153
|
paddingRight={1}
|
|
154
|
-
backgroundColor={t.
|
|
154
|
+
backgroundColor={t.backgroundElement}
|
|
155
155
|
onMouseDown={(e) => {
|
|
156
156
|
e.stopPropagation()
|
|
157
157
|
dispatchGlobal({ returnToSessionPicker: false, type: 'open-create-session-modal' })
|
|
158
158
|
}}
|
|
159
159
|
>
|
|
160
|
-
<text fg={t.
|
|
160
|
+
<text fg={t.text} selectable={false}>
|
|
161
161
|
+ New
|
|
162
162
|
</text>
|
|
163
163
|
</box>
|
|
@@ -200,16 +200,16 @@ function SessionChip({
|
|
|
200
200
|
session,
|
|
201
201
|
status,
|
|
202
202
|
}: SessionChipProps) {
|
|
203
|
-
const t =
|
|
204
|
-
const selectionBg =
|
|
203
|
+
const t = useTheme()
|
|
204
|
+
const selectionBg = t.backgroundElement
|
|
205
205
|
const showSpinner = status.working
|
|
206
206
|
const showWaiting = status.waiting
|
|
207
207
|
const spinner = useBusySpinner(showSpinner)
|
|
208
|
-
const labelColor = active ? t.
|
|
208
|
+
const labelColor = active ? t.text : t.textMuted
|
|
209
209
|
const bgColor = dragging || active ? selectionBg : undefined
|
|
210
|
-
const idleColor = t.
|
|
211
|
-
const workingColor = t.
|
|
212
|
-
const waitingColor = t.
|
|
210
|
+
const idleColor = t.success
|
|
211
|
+
const workingColor = t.primary
|
|
212
|
+
const waitingColor = t.warning
|
|
213
213
|
const [hovered, setHovered] = useState(false)
|
|
214
214
|
|
|
215
215
|
return (
|
|
@@ -264,12 +264,12 @@ function SessionChip({
|
|
|
264
264
|
runSideEffectGlobal({ sessionId: session.id, type: 'delete-session' })
|
|
265
265
|
}}
|
|
266
266
|
>
|
|
267
|
-
<text fg={t.
|
|
267
|
+
<text fg={t.textMuted} selectable={false}>
|
|
268
268
|
×
|
|
269
269
|
</text>
|
|
270
270
|
</box>
|
|
271
271
|
) : (
|
|
272
|
-
<text fg={t.
|
|
272
|
+
<text fg={t.textMuted} selectable={false}>
|
|
273
273
|
{' '}
|
|
274
274
|
</text>
|
|
275
275
|
)}
|
|
@@ -7,7 +7,7 @@ import { memo, useMemo, useRef } from 'react'
|
|
|
7
7
|
|
|
8
8
|
import { useAppStore } from '../../../../state/app-store'
|
|
9
9
|
import { dispatchGlobal } from '../../../../state/dispatch-ref'
|
|
10
|
-
import {
|
|
10
|
+
import { getCurrentTheme, type ResolvedTuiTheme, useTheme } from '../../../theme'
|
|
11
11
|
import { buildGitPaneContextMenu } from '../../git/pane/git-pane-context-menu'
|
|
12
12
|
import { GitPaneWidget } from '../../git/pane/git-pane-widget'
|
|
13
13
|
import { ContextMenuBox } from '../../overlays/context-menu/context-menu-box'
|
|
@@ -37,19 +37,19 @@ const RESIZE_HANDLE = '│'
|
|
|
37
37
|
function getRowBackground({
|
|
38
38
|
alternate,
|
|
39
39
|
isActive,
|
|
40
|
-
|
|
40
|
+
t,
|
|
41
41
|
}: {
|
|
42
42
|
isActive: boolean
|
|
43
43
|
alternate: boolean
|
|
44
|
-
|
|
44
|
+
t: ResolvedTuiTheme
|
|
45
45
|
}): string | undefined {
|
|
46
|
-
if (isActive) return
|
|
47
|
-
if (alternate) return
|
|
48
|
-
return
|
|
46
|
+
if (isActive) return t.backgroundElement
|
|
47
|
+
if (alternate) return t.backgroundPanel
|
|
48
|
+
return t.backgroundPanel
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
const SidebarTop = memo(function SidebarTop({ contentWidth }: { contentWidth: number }) {
|
|
52
|
-
const
|
|
52
|
+
const t = useTheme()
|
|
53
53
|
const currentSessionId = useAppStore((s) => s.currentSessionId)
|
|
54
54
|
const sessions = useAppStore((s) => s.sessions)
|
|
55
55
|
const currentSession = currentSessionId
|
|
@@ -60,22 +60,20 @@ const SidebarTop = memo(function SidebarTop({ contentWidth }: { contentWidth: nu
|
|
|
60
60
|
|
|
61
61
|
return (
|
|
62
62
|
<box flexDirection="column" flexShrink={0} gap={0}>
|
|
63
|
-
<text fg={
|
|
63
|
+
<text fg={t.text}>
|
|
64
64
|
<strong>aimux</strong>
|
|
65
65
|
</text>
|
|
66
|
-
<text fg={
|
|
67
|
-
{currentSession ? currentSession.name : 'No workspace selected'}
|
|
68
|
-
</text>
|
|
66
|
+
<text fg={t.text}>{currentSession ? currentSession.name : 'No workspace selected'}</text>
|
|
69
67
|
{branch ? (
|
|
70
68
|
<box flexDirection="row">
|
|
71
|
-
<text fg={
|
|
72
|
-
<text fg={
|
|
69
|
+
<text fg={t.text}>{'\u{e702}'} </text>
|
|
70
|
+
<text fg={t.text}>{branch}</text>
|
|
73
71
|
</box>
|
|
74
72
|
) : null}
|
|
75
73
|
<box
|
|
76
74
|
flexDirection="row"
|
|
77
75
|
paddingY={1}
|
|
78
|
-
backgroundColor={
|
|
76
|
+
backgroundColor={t.backgroundPanel}
|
|
79
77
|
justifyContent="center"
|
|
80
78
|
marginTop={1}
|
|
81
79
|
onMouseDown={(e) => {
|
|
@@ -83,22 +81,22 @@ const SidebarTop = memo(function SidebarTop({ contentWidth }: { contentWidth: nu
|
|
|
83
81
|
dispatchGlobal({ type: 'open-new-tab-modal' })
|
|
84
82
|
}}
|
|
85
83
|
>
|
|
86
|
-
<text fg={
|
|
84
|
+
<text fg={t.text}>+ New assistant</text>
|
|
87
85
|
</box>
|
|
88
|
-
<text fg={
|
|
86
|
+
<text fg={t.textMuted}>{'·'.repeat(Math.max(0, contentWidth - 2))}</text>
|
|
89
87
|
</box>
|
|
90
88
|
)
|
|
91
89
|
})
|
|
92
90
|
|
|
93
91
|
function renderGroupGutter(isGroupStart: boolean, isGroupMiddle: boolean, isGroupEnd: boolean) {
|
|
94
|
-
const t =
|
|
92
|
+
const t = getCurrentTheme()
|
|
95
93
|
return (
|
|
96
94
|
<box flexDirection="column" width={1} overflow="hidden">
|
|
97
|
-
<text fg={t.
|
|
95
|
+
<text fg={t.border}>
|
|
98
96
|
{/* oxlint-disable-next-line no-nested-ternary */}
|
|
99
97
|
{isGroupStart ? GUTTER_START : isGroupMiddle ? GUTTER_MIDDLE : GUTTER_PAD}
|
|
100
98
|
</text>
|
|
101
|
-
<text fg={t.
|
|
99
|
+
<text fg={t.border}>{isGroupEnd ? GUTTER_END : GUTTER_PAD}</text>
|
|
102
100
|
</box>
|
|
103
101
|
)
|
|
104
102
|
}
|
|
@@ -108,7 +106,7 @@ interface TabsBodyProps {
|
|
|
108
106
|
}
|
|
109
107
|
|
|
110
108
|
const TabsBody = memo(function TabsBody({ onTabActivate }: TabsBodyProps) {
|
|
111
|
-
const
|
|
109
|
+
const t = useTheme()
|
|
112
110
|
const tabs = useAppStore((s) => s.tabs)
|
|
113
111
|
const activeTabId = useAppStore((s) => s.activeTabId)
|
|
114
112
|
const focusMode = useAppStore((s) => s.focusMode)
|
|
@@ -138,7 +136,7 @@ const TabsBody = memo(function TabsBody({ onTabActivate }: TabsBodyProps) {
|
|
|
138
136
|
>
|
|
139
137
|
{tabs.length === 0 ? (
|
|
140
138
|
<box paddingTop={1}>
|
|
141
|
-
<text fg={
|
|
139
|
+
<text fg={t.textMuted}>No tabs yet. Press Ctrl+n.</text>
|
|
142
140
|
</box>
|
|
143
141
|
) : (
|
|
144
142
|
tabs.map((tab, index) => {
|
|
@@ -154,7 +152,7 @@ const TabsBody = memo(function TabsBody({ onTabActivate }: TabsBodyProps) {
|
|
|
154
152
|
return (
|
|
155
153
|
<box
|
|
156
154
|
key={tab.id}
|
|
157
|
-
backgroundColor={getRowBackground({ alternate, isActive,
|
|
155
|
+
backgroundColor={getRowBackground({ alternate, isActive, t })}
|
|
158
156
|
flexDirection="row"
|
|
159
157
|
onMouseDown={(event) => {
|
|
160
158
|
event.stopPropagation()
|
|
@@ -186,8 +184,8 @@ export function Sidebar({
|
|
|
186
184
|
onSidebarResizeStart,
|
|
187
185
|
onTabActivate,
|
|
188
186
|
}: SidebarProps) {
|
|
189
|
-
const
|
|
190
|
-
const sidebarBg =
|
|
187
|
+
const t = useTheme()
|
|
188
|
+
const sidebarBg = t.background
|
|
191
189
|
const sidebarVisible = useAppStore((s) => s.sidebar.visible)
|
|
192
190
|
const sidebarWidth = useAppStore((s) => s.sidebar.width)
|
|
193
191
|
const gitPane = useAppStore((s) => s.gitPane)
|
|
@@ -215,7 +213,7 @@ export function Sidebar({
|
|
|
215
213
|
const tabsGrow = gitEmbedded ? Math.max(1, Math.round((1 - gitPane.embeddedRatio) * 100)) : 1
|
|
216
214
|
const gitGrow = gitEmbedded ? Math.max(1, Math.round(gitPane.embeddedRatio * 100)) : 0
|
|
217
215
|
|
|
218
|
-
const separator = <text fg={
|
|
216
|
+
const separator = <text fg={t.textMuted}>{'·'.repeat(Math.max(0, contentWidth - 2))}</text>
|
|
219
217
|
const gitBody = gitEmbedded ? (
|
|
220
218
|
<ContextMenuBox
|
|
221
219
|
flexDirection="column"
|
|
@@ -232,7 +230,7 @@ export function Sidebar({
|
|
|
232
230
|
<box
|
|
233
231
|
minHeight={1}
|
|
234
232
|
flexShrink={0}
|
|
235
|
-
backgroundColor={
|
|
233
|
+
backgroundColor={t.border}
|
|
236
234
|
onMouseDown={(event) => {
|
|
237
235
|
const body = bodyRef.current
|
|
238
236
|
if (!body) return
|
|
@@ -245,7 +243,7 @@ export function Sidebar({
|
|
|
245
243
|
})
|
|
246
244
|
}}
|
|
247
245
|
>
|
|
248
|
-
<text fg={
|
|
246
|
+
<text fg={t.border}>{RESIZE_HANDLE.repeat(Math.max(1, contentWidth))}</text>
|
|
249
247
|
</box>
|
|
250
248
|
) : null
|
|
251
249
|
|
|
@@ -315,7 +313,7 @@ export function Sidebar({
|
|
|
315
313
|
height="100%"
|
|
316
314
|
width={1}
|
|
317
315
|
flexShrink={0}
|
|
318
|
-
backgroundColor={
|
|
316
|
+
backgroundColor={t.border}
|
|
319
317
|
onMouseDown={(event) => {
|
|
320
318
|
event.preventDefault()
|
|
321
319
|
event.stopPropagation()
|