@brimveyn/aimux 1.14.2 → 1.14.3

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brimveyn/aimux",
3
- "version": "1.14.2",
3
+ "version": "1.14.3",
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",
@@ -33,6 +33,10 @@ interface GitPanelProps {
33
33
  // ("vs <base>") rather than a HEAD~N history walk.
34
34
  baseLabel?: string
35
35
  compact?: boolean
36
+ // When false, suppress the inline tree|flat toggle on section headers and the
37
+ // top ↑n ↓m remote-tracking line so a wrapper can own them at panel level.
38
+ showFileListToggle?: boolean
39
+ showRemoteTracking?: boolean
36
40
  }
37
41
 
38
42
  function sectionTitle(section: GitFileSection, headOffset: number, baseLabel?: string): string {
@@ -389,6 +393,8 @@ export const GitPanel = memo(function GitPanel({
389
393
  pathConfig = DEFAULT_PATH_CONFIG,
390
394
  projectPath,
391
395
  selectedEntryKey,
396
+ showFileListToggle = true,
397
+ showRemoteTracking = true,
392
398
  }: GitPanelProps) {
393
399
  const t = useTheme()
394
400
  useTransparent()
@@ -407,12 +413,13 @@ export const GitPanel = memo(function GitPanel({
407
413
 
408
414
  const statusNode = renderStatus(gitPanel, !!(projectPath != null && projectPath !== ''))
409
415
 
410
- const hasRemoteTracking = gitPanel.ahead > 0 || gitPanel.behind > 0
411
- const toggleSection =
412
- tree.sections.find((section) => section.section === 'unstaged' && section.files.length > 0)
413
- ?.section ??
414
- tree.sections.find((section) => section.files.length > 0)?.section ??
415
- null
416
+ const hasRemoteTracking = showRemoteTracking && (gitPanel.ahead > 0 || gitPanel.behind > 0)
417
+ const toggleSection = showFileListToggle
418
+ ? (tree.sections.find((section) => section.section === 'unstaged' && section.files.length > 0)
419
+ ?.section ??
420
+ tree.sections.find((section) => section.files.length > 0)?.section ??
421
+ null)
422
+ : null
416
423
 
417
424
  useEffect(() => {
418
425
  const scrollbox = scrollRef.current
@@ -21,6 +21,7 @@ import { PierreDiff, type PierreDiffHandle } from './diff-renderer'
21
21
  import { useDiffPrefetch } from './diff-renderer/use-diff-prefetch'
22
22
  import { GitPanel } from './git-panel'
23
23
  import { ImageDiffView } from './image-diff'
24
+ import { GitPaneHeader } from './pane/git-pane-header'
24
25
 
25
26
  interface DiffStageProps {
26
27
  diff: DiffData | undefined
@@ -287,34 +288,12 @@ export const GitView = memo(function GitView({ themeId }: GitViewProps) {
287
288
  gap={0}
288
289
  overflow="hidden"
289
290
  >
290
- <box flexDirection="column" flexShrink={0}>
291
- <text fg={t.text}>
292
- <strong>aimux · git</strong>
293
- </text>
294
- {gitPanel.branch != null && gitPanel.branch !== '' ? (
295
- <box flexDirection="row">
296
- <text fg={t.text}>{'\u{e702}'} </text>
297
- <text fg={t.text}>{gitPanel.branch}</text>
298
- </box>
299
- ) : null}
300
- {gitMode.headOffset > 0 ? (
301
- <box flexDirection="row" gap={1}>
302
- <text fg={t.warning}>
303
- <strong>HEAD~{gitMode.headOffset}</strong>
304
- </text>
305
- <text fg={t.textMuted}>[ newer · ] older</text>
306
- </box>
307
- ) : null}
308
- {baseLabel != null ? (
309
- <box flexDirection="row" gap={1}>
310
- <text fg={t.primary}>
311
- <strong>{baseLabel}</strong>
312
- </text>
313
- <text fg={t.textMuted}>b: back</text>
314
- </box>
315
- ) : null}
316
- <text fg={t.textMuted}>{'·'.repeat(Math.max(0, fileBarWidth - 2))}</text>
317
- </box>
291
+ <GitPaneHeader
292
+ baseLabel={baseLabel}
293
+ gitPanel={gitPanel}
294
+ headOffset={gitMode.headOffset}
295
+ projectPath={projectPath}
296
+ />
318
297
  <GitPanel
319
298
  baseLabel={baseLabel}
320
299
  collapsedFolders={gitMode.collapsedFolders}
@@ -324,6 +303,8 @@ export const GitView = memo(function GitView({ themeId }: GitViewProps) {
324
303
  headOffset={gitMode.headOffset}
325
304
  projectPath={projectPath}
326
305
  selectedEntryKey={gitMode.selectedEntryKey}
306
+ showFileListToggle={false}
307
+ showRemoteTracking={false}
327
308
  />
328
309
  </box>
329
310
  <box flexDirection="column" flexGrow={1} overflow="hidden">
@@ -0,0 +1,127 @@
1
+ import { memo, useCallback } from 'react'
2
+
3
+ import type { GitPanelState } from '../../../../state/types'
4
+
5
+ import { useAppStore } from '../../../../state/app-store'
6
+ import { dispatchGlobal, runSideEffectGlobal } from '../../../../state/dispatch-ref'
7
+ import { useTheme } from '../../../theme'
8
+
9
+ interface GitPaneHeaderProps {
10
+ gitPanel: GitPanelState
11
+ projectPath: string | undefined
12
+ headOffset?: number
13
+ baseLabel?: string
14
+ }
15
+
16
+ export const GitPaneHeader = memo(function GitPaneHeader({
17
+ baseLabel,
18
+ gitPanel,
19
+ headOffset = 0,
20
+ projectPath,
21
+ }: GitPaneHeaderProps) {
22
+ const t = useTheme()
23
+ const fileListMode = useAppStore((s) => s.gitPane.fileListMode)
24
+ const nextFileListMode = fileListMode === 'tree' ? 'flat' : 'tree'
25
+ const toggleListMode = useCallback(() => {
26
+ dispatchGlobal({ type: 'git-mode-toggle-file-list-mode' })
27
+ runSideEffectGlobal({ mode: nextFileListMode, type: 'persist-git-file-list-mode' })
28
+ }, [nextFileListMode])
29
+
30
+ const hasProject = projectPath != null && projectPath !== ''
31
+ if (!hasProject) return null
32
+ if (gitPanel.error !== null) return null
33
+
34
+ const branch = gitPanel.branch
35
+ const branchLabel = branch != null && branch !== '' ? branch : 'detached'
36
+ const branchIsResolved = branch != null && branch !== ''
37
+
38
+ const ahead = gitPanel.ahead
39
+ const behind = gitPanel.behind
40
+ const showAhead = ahead > 0
41
+ const showBehind = behind > 0
42
+ const showTracking = showAhead || showBehind
43
+
44
+ const showToggle = gitPanel.files.length > 0
45
+ const showHistorical = headOffset > 0
46
+ const showReviewBase = baseLabel != null && baseLabel !== ''
47
+ const showScope = showHistorical || showReviewBase
48
+
49
+ return (
50
+ <box flexDirection="column" flexShrink={0} paddingBottom={1}>
51
+ <box flexDirection="row" justifyContent="space-between">
52
+ <box flexDirection="row" flexShrink={1} overflow="hidden">
53
+ <text selectable={false} fg={t.textMuted} wrapMode="none">
54
+ {'\u{e702}'}
55
+ </text>
56
+ <text selectable={false} fg={t.textMuted} wrapMode="none">
57
+ {' '}
58
+ </text>
59
+ <text selectable={false} fg={branchIsResolved ? t.text : t.textMuted} wrapMode="none">
60
+ {branchIsResolved ? <strong>{branchLabel}</strong> : branchLabel}
61
+ </text>
62
+ </box>
63
+ <box flexDirection="row" flexShrink={0} gap={2}>
64
+ {showTracking ? (
65
+ <box flexDirection="row" gap={1}>
66
+ {showAhead ? (
67
+ <text selectable={false} fg={t.textMuted} wrapMode="none">
68
+ {`↑${ahead}`}
69
+ </text>
70
+ ) : null}
71
+ {showBehind ? (
72
+ <text selectable={false} fg={t.textMuted} wrapMode="none">
73
+ {`↓${behind}`}
74
+ </text>
75
+ ) : null}
76
+ </box>
77
+ ) : null}
78
+ {showToggle ? (
79
+ <box flexDirection="row" gap={1} onMouseDown={toggleListMode}>
80
+ <text
81
+ selectable={false}
82
+ fg={fileListMode === 'tree' ? t.primary : t.textMuted}
83
+ wrapMode="none"
84
+ >
85
+ tree
86
+ </text>
87
+ <text selectable={false} fg={t.textMuted} wrapMode="none">
88
+ |
89
+ </text>
90
+ <text
91
+ selectable={false}
92
+ fg={fileListMode === 'flat' ? t.primary : t.textMuted}
93
+ wrapMode="none"
94
+ >
95
+ flat
96
+ </text>
97
+ </box>
98
+ ) : null}
99
+ </box>
100
+ </box>
101
+ {showScope ? (
102
+ <box flexDirection="row" gap={2}>
103
+ {showHistorical ? (
104
+ <text selectable={false} fg={t.warning} wrapMode="none">
105
+ <strong>HEAD~{headOffset}</strong>
106
+ </text>
107
+ ) : null}
108
+ {showHistorical ? (
109
+ <text selectable={false} fg={t.textMuted} wrapMode="none">
110
+ [ newer · ] older
111
+ </text>
112
+ ) : null}
113
+ {showReviewBase ? (
114
+ <text selectable={false} fg={t.primary} wrapMode="none">
115
+ <strong>{baseLabel}</strong>
116
+ </text>
117
+ ) : null}
118
+ {showReviewBase ? (
119
+ <text selectable={false} fg={t.textMuted} wrapMode="none">
120
+ b: back
121
+ </text>
122
+ ) : null}
123
+ </box>
124
+ ) : null}
125
+ </box>
126
+ )
127
+ })
@@ -7,6 +7,7 @@ import { useRepoDiscovery } from '../../../../git/use-repo-discovery'
7
7
  import { useAppStore } from '../../../../state/app-store'
8
8
  import { getSessionProjectPath } from '../../../../state/session-worktrees'
9
9
  import { GitPanel } from '../git-panel'
10
+ import { GitPaneHeader } from './git-pane-header'
10
11
 
11
12
  interface GitPaneWidgetProps {
12
13
  pollingEnabled: boolean
@@ -43,15 +44,20 @@ export const GitPaneWidget = memo(function GitPaneWidget({ pollingEnabled }: Git
43
44
  const display = lastGoodRef.current ?? gitPanel
44
45
 
45
46
  return (
46
- <GitPanel
47
- collapsedFolders={gitMode.collapsedFolders}
48
- compact={treeCompaction}
49
- diffCountConfig={diffCountConfig}
50
- fileListMode={gitFileListMode}
51
- gitPanel={display}
52
- pathConfig={pathConfig}
53
- projectPath={projectPath}
54
- selectedEntryKey={gitMode.selectedEntryKey}
55
- />
47
+ <box flexDirection="column" flexGrow={1} flexShrink={1} flexBasis={0} overflow="hidden">
48
+ <GitPaneHeader gitPanel={display} projectPath={projectPath} />
49
+ <GitPanel
50
+ collapsedFolders={gitMode.collapsedFolders}
51
+ compact={treeCompaction}
52
+ diffCountConfig={diffCountConfig}
53
+ fileListMode={gitFileListMode}
54
+ gitPanel={display}
55
+ pathConfig={pathConfig}
56
+ projectPath={projectPath}
57
+ selectedEntryKey={gitMode.selectedEntryKey}
58
+ showFileListToggle={false}
59
+ showRemoteTracking={false}
60
+ />
61
+ </box>
56
62
  )
57
63
  })