@brimveyn/aimux 1.7.0 → 1.7.2

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 (57) hide show
  1. package/package.json +3 -4
  2. package/src/app-runtime/pty-write.ts +8 -3
  3. package/src/app-runtime/side-effects.ts +10 -2
  4. package/src/app-runtime/use-renderer-bindings.ts +2 -1
  5. package/src/app.tsx +5 -8
  6. package/src/config.ts +2 -10
  7. package/src/input/modes/bridge.ts +1 -1
  8. package/src/input/modes/types.ts +6 -1
  9. package/src/input/raw-input-handler.ts +12 -3
  10. package/src/ipc/manager-protocol.ts +2 -2
  11. package/src/ipc/protocol.ts +2 -2
  12. package/src/pty/terminal-snapshot.ts +4 -4
  13. package/src/session-backend/bootstrap.ts +21 -1
  14. package/src/state/reducers/modal-state.ts +3 -2
  15. package/src/state/reducers/session-state.ts +0 -7
  16. package/src/state/types.ts +7 -1
  17. package/src/ui/components/bare-input.tsx +5 -5
  18. package/src/ui/components/context-menu-box.tsx +21 -0
  19. package/src/ui/components/context-menu-overlay.tsx +114 -0
  20. package/src/ui/components/create-session-modal.tsx +12 -41
  21. package/src/ui/components/diff-renderer/fold-strip.tsx +7 -7
  22. package/src/ui/components/diff-renderer/highlight.ts +6 -10
  23. package/src/ui/components/diff-renderer/pierre-diff.tsx +3 -3
  24. package/src/ui/components/diff-renderer/prepare-diff.ts +2 -3
  25. package/src/ui/components/diff-renderer/split-view.tsx +22 -29
  26. package/src/ui/components/diff-renderer/stacked-view.tsx +18 -31
  27. package/src/ui/components/diff-renderer/use-diff-prefetch.ts +0 -1
  28. package/src/ui/components/diff-renderer/use-diff-preparation.ts +1 -1
  29. package/src/ui/components/git-commit-modal.tsx +4 -16
  30. package/src/ui/components/git-panel.tsx +37 -73
  31. package/src/ui/components/git-view.tsx +17 -19
  32. package/src/ui/components/help-modal.tsx +5 -13
  33. package/src/ui/components/input-field.tsx +5 -7
  34. package/src/ui/components/list-item.tsx +3 -11
  35. package/src/ui/components/modal-keybinds-overlay.tsx +4 -4
  36. package/src/ui/components/modal-shell.tsx +6 -11
  37. package/src/ui/components/new-tab-modal.tsx +7 -15
  38. package/src/ui/components/pending-chord-overlay.tsx +5 -5
  39. package/src/ui/components/picker.tsx +6 -6
  40. package/src/ui/components/session-bar.tsx +34 -20
  41. package/src/ui/components/session-picker-modal.tsx +7 -20
  42. package/src/ui/components/sidebar.tsx +36 -35
  43. package/src/ui/components/snippet-editor-modal.tsx +4 -18
  44. package/src/ui/components/snippet-picker-modal.tsx +5 -9
  45. package/src/ui/components/split-layout.tsx +3 -3
  46. package/src/ui/components/status-bar.tsx +12 -13
  47. package/src/ui/components/surface.tsx +8 -11
  48. package/src/ui/components/tab-item.tsx +54 -29
  49. package/src/ui/components/terminal-pane.tsx +59 -25
  50. package/src/ui/components/theme-picker-modal.tsx +7 -21
  51. package/src/ui/components/update-available-modal.tsx +3 -13
  52. package/src/ui/context-menu/controller.ts +34 -0
  53. package/src/ui/root.tsx +5 -2
  54. package/src/ui/shiki.ts +29 -21
  55. package/src/ui/theme-store.ts +110 -21
  56. package/src/ui/theme.ts +6 -3
  57. package/src/ui/themes.ts +18 -13
@@ -1,39 +1,108 @@
1
1
  import { useStore } from 'zustand'
2
2
  import { createStore } from 'zustand/vanilla'
3
3
 
4
- import { type Theme, type ThemeColorMap, type ThemeId, THEMES } from './themes'
4
+ import {
5
+ accent,
6
+ type AimuxPalette,
7
+ type AimuxTheme,
8
+ border,
9
+ diffAddBg,
10
+ diffDeleteBg,
11
+ elevated,
12
+ extendPalette,
13
+ faint,
14
+ hover,
15
+ muted,
16
+ selected,
17
+ type ThemeId,
18
+ THEMES,
19
+ } from './themes'
20
+
21
+ export interface ThemeTokens {
22
+ /** `accent` with `primary` fallback. */
23
+ accent: string
24
+ /** Subtle border between panels. */
25
+ border: string
26
+ /** Background tint for inserted diff lines. */
27
+ diffAddBg: string
28
+ /** Background tint for removed diff lines. */
29
+ diffDeleteBg: string
30
+ /** Surface a notch above the base background — sidebars, headers. */
31
+ elevated: string
32
+ /** Fainter still — line numbers, placeholders, disabled. */
33
+ faint: string
34
+ /** Hover/highlight surface (line highlight, list hover). */
35
+ hover: string
36
+ /** Half-way between background and ink — labels, captions, paths. */
37
+ muted: string
38
+ palette: AimuxPalette
39
+ /** Selected/active row surface. */
40
+ selected: string
41
+ }
42
+
43
+ function computeTokens(palette: AimuxPalette): ThemeTokens {
44
+ return {
45
+ accent: accent(palette),
46
+ border: border(palette),
47
+ diffAddBg: diffAddBg(palette),
48
+ diffDeleteBg: diffDeleteBg(palette),
49
+ elevated: elevated(palette),
50
+ faint: faint(palette),
51
+ hover: hover(palette),
52
+ muted: muted(palette),
53
+ palette,
54
+ selected: selected(palette),
55
+ }
56
+ }
57
+
58
+ // Memoize by palette reference so `useStore` selectors return stable objects.
59
+ let cachedPalette: AimuxPalette | null = null
60
+ let cachedTokens: ThemeTokens | null = null
61
+
62
+ function deriveTokens(palette: AimuxPalette): ThemeTokens {
63
+ if (cachedPalette === palette && cachedTokens) return cachedTokens
64
+ cachedPalette = palette
65
+ cachedTokens = computeTokens(palette)
66
+ return cachedTokens
67
+ }
5
68
 
6
69
  interface ThemeStore {
7
- theme: Theme
70
+ theme: AimuxTheme
8
71
  transparent: boolean
9
72
  }
10
73
 
11
- const DEFAULT = THEMES['aimux']
74
+ const DEFAULT = THEMES['aimux-dark']
12
75
  if (!DEFAULT) throw new Error('default theme missing')
13
76
 
14
77
  const themeStore = createStore<ThemeStore>(() => ({ theme: DEFAULT, transparent: false }))
15
78
 
16
- /**
17
- * Subscribe to the active theme. Pass a selector to subscribe to a narrower
18
- * slice (`useTheme(t => t.colors['editor.foreground'])`) or call with no
19
- * arguments to get the whole theme.
20
- */
21
- export function useTheme(): Theme
22
- export function useTheme<T>(selector: (theme: Theme) => T): T
23
- export function useTheme<T>(selector?: (theme: Theme) => T): T | Theme {
24
- return useStore(themeStore, (s) => (selector ? selector(s.theme) : s.theme))
79
+ /** Subscribe to the active palette plus precomputed derived shades. */
80
+ export function useTokens(): ThemeTokens {
81
+ return useStore(themeStore, (s) => deriveTokens(s.theme.palette))
82
+ }
83
+
84
+ /** Synchronous tokens for non-React callers. */
85
+ export function getCurrentTokens(): ThemeTokens {
86
+ return deriveTokens(themeStore.getState().theme.palette)
25
87
  }
26
88
 
27
89
  /** Synchronous snapshot for non-React callers (reducers, side effects). */
28
- export function getCurrentTheme(): Theme {
90
+ export function getCurrentTheme(): AimuxTheme {
29
91
  return themeStore.getState().theme
30
92
  }
31
93
 
32
- /** Swap the active theme. Triggers re-renders on every `useTheme` subscriber. */
33
- export function applyTheme(id: ThemeId): void {
94
+ /** Swap the active theme by id, optionally merging palette overrides. */
95
+ export function applyTheme(id: ThemeId, paletteOverrides?: Partial<AimuxPalette>): void {
34
96
  const entry = THEMES[id]
35
97
  if (!entry) return
36
- themeStore.setState({ theme: entry })
98
+ const palette = extendPalette(entry.palette, paletteOverrides)
99
+ const merged: AimuxTheme = {
100
+ ...entry,
101
+ bg: palette.neutral,
102
+ fg: palette.ink,
103
+ palette,
104
+ }
105
+ themeStore.setState({ theme: merged })
37
106
  }
38
107
 
39
108
  /** Subscribe to the transparent-mode flag. */
@@ -50,11 +119,31 @@ export function setTransparent(value: boolean): void {
50
119
  themeStore.setState({ transparent: value })
51
120
  }
52
121
 
122
+ export type SurfaceToken = 'base' | 'elevated' | 'hover' | 'selected' | 'border'
123
+
124
+ function resolveSurface(palette: AimuxPalette, token: SurfaceToken): string {
125
+ switch (token) {
126
+ case 'base':
127
+ return palette.neutral
128
+ case 'elevated':
129
+ return elevated(palette)
130
+ case 'hover':
131
+ return hover(palette)
132
+ case 'selected':
133
+ return selected(palette)
134
+ case 'border':
135
+ return border(palette)
136
+ }
137
+ }
138
+
53
139
  /**
54
- * Resolve a background color through the transparent-mode flag. Returns
55
- * `undefined` when transparent mode is on, letting the terminal emulator's
56
- * own background show through.
140
+ * Resolve a surface color through the transparent-mode flag. Returns
141
+ * `undefined` for the base surface when transparent mode is on, letting the
142
+ * terminal emulator's own background show through.
57
143
  */
58
- export function useBg(key: keyof ThemeColorMap): string | undefined {
59
- return useStore(themeStore, (s) => (s.transparent ? undefined : s.theme.colors[key]))
144
+ export function useBg(token: SurfaceToken): string | undefined {
145
+ return useStore(themeStore, (s) => {
146
+ if (s.transparent && token === 'base') return undefined
147
+ return resolveSurface(s.theme.palette, token)
148
+ })
60
149
  }
package/src/ui/theme.ts CHANGED
@@ -1,13 +1,16 @@
1
1
  // Back-compat shim: the theme singleton has been replaced with a Zustand store.
2
- // React components should import `useTheme` from `./theme-store`; non-React
3
- // callers use `getCurrentTheme()`. `applyTheme` moved to the store module.
2
+ // React components use `useTokens` for derived shades; non-React callers use
3
+ // `getCurrentTheme()` / `getCurrentTokens()`.
4
4
 
5
5
  export {
6
6
  applyTheme,
7
7
  getCurrentTheme,
8
+ getCurrentTokens,
8
9
  getTransparent,
9
10
  setTransparent,
11
+ type SurfaceToken,
12
+ type ThemeTokens,
10
13
  useBg,
11
- useTheme,
14
+ useTokens,
12
15
  useTransparent,
13
16
  } from './theme-store'
package/src/ui/themes.ts CHANGED
@@ -1,25 +1,30 @@
1
- // Thin runtime re-export. Theme data, types, normalization, and registration
2
- // all live in `@brimveyn/aimux-config` so the dependency-free config package is
3
- // the single source of truth. The mutable theme singleton + `applyTheme` stay
4
- // in `./theme.ts` since they're UI-layer concerns.
1
+ // Thin runtime re-export. Theme data, types, palette utilities, and the
2
+ // palette-to-Shiki generator all live in `@brimveyn/aimux-config`.
5
3
 
6
4
  export type {
7
- AimuxColorKey,
8
- NamedTheme,
9
- NamedThemeDefinition,
5
+ AimuxPalette,
6
+ AimuxTheme,
7
+ AimuxThemeConfig,
10
8
  Theme,
11
- ThemeColorMap,
12
9
  ThemeId,
13
- ThemeSettings,
14
- ThemeTokenRule,
10
+ ThemeMode,
15
11
  } from '@brimveyn/aimux-config'
16
12
 
17
13
  export {
18
- AIMUX_COLOR_KEYS,
14
+ accent,
15
+ border,
16
+ diffAddBg,
17
+ diffDeleteBg,
18
+ elevated,
19
+ extendPalette,
20
+ faint,
21
+ hover,
19
22
  isKnownThemeId,
20
23
  migrateThemeId,
21
- normalizeTheme,
22
- registerUserThemes,
24
+ mix,
25
+ muted,
26
+ paletteToShikiTheme,
27
+ selected,
23
28
  THEME_IDS,
24
29
  THEMES,
25
30
  } from '@brimveyn/aimux-config'