@brimveyn/aimux-config 0.1.0
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/LICENSE +21 -0
- package/README.md +155 -0
- package/package.json +40 -0
- package/src/actions.ts +368 -0
- package/src/backends.ts +23 -0
- package/src/defaults.ts +244 -0
- package/src/define-config.ts +20 -0
- package/src/index.ts +50 -0
- package/src/keymap-builder.ts +112 -0
- package/src/resolver.ts +76 -0
- package/src/themes.ts +252 -0
- package/src/types.ts +568 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
// -----------------------------------------------------------------------------
|
|
2
|
+
// Self-contained types for the aimux keymap/config surface.
|
|
3
|
+
// These are duplicated from the aimux CLI's internal types to keep this
|
|
4
|
+
// package dependency-free. They must stay structurally identical with the
|
|
5
|
+
// CLI types in `aimux`'s `src/state/types.ts`, `src/input/modes/types.ts`,
|
|
6
|
+
// `src/ui/themes.ts`, and `src/state/layout-tree.ts`.
|
|
7
|
+
// -----------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
// ─── Mode identifiers ─────────────────────────────────────────────────────────
|
|
10
|
+
|
|
11
|
+
export type ModeId =
|
|
12
|
+
| 'navigation'
|
|
13
|
+
| 'terminal-input'
|
|
14
|
+
| 'layout'
|
|
15
|
+
| 'modal.new-tab'
|
|
16
|
+
| 'modal.new-tab.command-edit'
|
|
17
|
+
| 'modal.session-picker'
|
|
18
|
+
| 'modal.session-picker.filtering'
|
|
19
|
+
| 'modal.session-name'
|
|
20
|
+
| 'modal.create-session'
|
|
21
|
+
| 'modal.rename-tab'
|
|
22
|
+
| 'modal.snippet-picker'
|
|
23
|
+
| 'modal.snippet-picker.filtering'
|
|
24
|
+
| 'modal.snippet-editor'
|
|
25
|
+
| 'modal.theme-picker'
|
|
26
|
+
| 'modal.help'
|
|
27
|
+
| 'modal.split-picker'
|
|
28
|
+
|
|
29
|
+
// ─── Primitive app types ──────────────────────────────────────────────────────
|
|
30
|
+
|
|
31
|
+
export type BuiltinAssistantId = 'claude' | 'codex' | 'opencode' | 'terminal'
|
|
32
|
+
export type AssistantId = BuiltinAssistantId | (string & {})
|
|
33
|
+
export type TabStatus = 'starting' | 'running' | 'disconnected' | 'exited' | 'error'
|
|
34
|
+
export type TabActivity = 'busy' | 'idle'
|
|
35
|
+
export type FocusMode = 'navigation' | 'terminal-input' | 'modal' | 'command-edit' | 'layout'
|
|
36
|
+
export type SplitDirection = 'horizontal' | 'vertical'
|
|
37
|
+
|
|
38
|
+
// ─── Terminal data shapes ─────────────────────────────────────────────────────
|
|
39
|
+
|
|
40
|
+
export interface TerminalSpan {
|
|
41
|
+
text: string
|
|
42
|
+
fg?: string
|
|
43
|
+
bg?: string
|
|
44
|
+
bold?: boolean
|
|
45
|
+
italic?: boolean
|
|
46
|
+
underline?: boolean
|
|
47
|
+
cursor?: boolean
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface TerminalLine {
|
|
51
|
+
spans: TerminalSpan[]
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface TerminalSnapshot {
|
|
55
|
+
lines: TerminalLine[]
|
|
56
|
+
viewportY: number
|
|
57
|
+
baseY: number
|
|
58
|
+
cursorVisible: boolean
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface TerminalModeState {
|
|
62
|
+
mouseTrackingMode: 'none' | 'x10' | 'vt200' | 'drag' | 'any'
|
|
63
|
+
sendFocusMode: boolean
|
|
64
|
+
alternateScrollMode: boolean
|
|
65
|
+
isAlternateBuffer: boolean
|
|
66
|
+
bracketedPasteMode: boolean
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ─── Layout ───────────────────────────────────────────────────────────────────
|
|
70
|
+
|
|
71
|
+
export type LayoutLeaf = { type: 'leaf'; tabId: string }
|
|
72
|
+
export type LayoutSplit = {
|
|
73
|
+
type: 'split'
|
|
74
|
+
direction: SplitDirection
|
|
75
|
+
ratio: number
|
|
76
|
+
first: LayoutNode
|
|
77
|
+
second: LayoutNode
|
|
78
|
+
}
|
|
79
|
+
export type LayoutNode = LayoutLeaf | LayoutSplit
|
|
80
|
+
|
|
81
|
+
// ─── Records ──────────────────────────────────────────────────────────────────
|
|
82
|
+
|
|
83
|
+
export interface PersistedTabSnapshot {
|
|
84
|
+
id: string
|
|
85
|
+
assistant: AssistantId
|
|
86
|
+
title: string
|
|
87
|
+
command: string
|
|
88
|
+
status: Exclude<TabStatus, 'disconnected'>
|
|
89
|
+
buffer: string
|
|
90
|
+
viewport?: TerminalSnapshot
|
|
91
|
+
terminalModes: TerminalModeState
|
|
92
|
+
errorMessage?: string
|
|
93
|
+
exitCode?: number
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface WorkspaceSnapshotV1 {
|
|
97
|
+
version: 1
|
|
98
|
+
savedAt: string
|
|
99
|
+
activeTabId: string | null
|
|
100
|
+
sidebar: {
|
|
101
|
+
visible: boolean
|
|
102
|
+
width: number
|
|
103
|
+
gitPanelVisible?: boolean
|
|
104
|
+
gitPanelRatio?: number
|
|
105
|
+
}
|
|
106
|
+
tabs: PersistedTabSnapshot[]
|
|
107
|
+
layoutTree?: LayoutNode
|
|
108
|
+
layoutTrees?: Record<string, LayoutNode>
|
|
109
|
+
tabGroupMap?: Record<string, string>
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface SessionRecord {
|
|
113
|
+
id: string
|
|
114
|
+
name: string
|
|
115
|
+
projectPath?: string
|
|
116
|
+
createdAt: string
|
|
117
|
+
updatedAt: string
|
|
118
|
+
lastOpenedAt: string
|
|
119
|
+
workspaceSnapshot?: WorkspaceSnapshotV1
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface TabSession {
|
|
123
|
+
id: string
|
|
124
|
+
assistant: AssistantId
|
|
125
|
+
title: string
|
|
126
|
+
status: TabStatus
|
|
127
|
+
activity?: TabActivity
|
|
128
|
+
buffer: string
|
|
129
|
+
viewport?: TerminalSnapshot
|
|
130
|
+
terminalModes: TerminalModeState
|
|
131
|
+
command: string
|
|
132
|
+
errorMessage?: string
|
|
133
|
+
exitCode?: number
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface SnippetRecord {
|
|
137
|
+
id: string
|
|
138
|
+
name: string
|
|
139
|
+
content: string
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export type DirectoryResultType = 'git-repo' | 'worktree' | 'workspace'
|
|
143
|
+
|
|
144
|
+
export interface DirectoryResult {
|
|
145
|
+
path: string
|
|
146
|
+
type: DirectoryResultType
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// ─── Sidebar / git panel / modal state (for ModeContext) ──────────────────────
|
|
150
|
+
|
|
151
|
+
export interface SidebarState {
|
|
152
|
+
visible: boolean
|
|
153
|
+
width: number
|
|
154
|
+
minWidth: number
|
|
155
|
+
maxWidth: number
|
|
156
|
+
gitPanelVisible: boolean
|
|
157
|
+
gitPanelRatio: number
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export type GitFileStatus = 'M' | 'A' | 'D' | 'R' | 'C' | 'U' | '?'
|
|
161
|
+
export type GitFileSection = 'staged' | 'unstaged' | 'untracked'
|
|
162
|
+
|
|
163
|
+
export interface GitFileEntry {
|
|
164
|
+
path: string
|
|
165
|
+
renamedFrom?: string
|
|
166
|
+
section: GitFileSection
|
|
167
|
+
status: GitFileStatus
|
|
168
|
+
added: number | null
|
|
169
|
+
removed: number | null
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export type GitPanelError = 'not-a-repo' | 'unknown'
|
|
173
|
+
|
|
174
|
+
export interface GitPanelState {
|
|
175
|
+
branch: string | null
|
|
176
|
+
ahead: number
|
|
177
|
+
behind: number
|
|
178
|
+
files: GitFileEntry[]
|
|
179
|
+
error: GitPanelError | null
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
interface ModalBase {
|
|
183
|
+
selectedIndex: number
|
|
184
|
+
editBuffer: string | null
|
|
185
|
+
sessionTargetId: string | null
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export interface ModalClosed extends ModalBase {
|
|
189
|
+
type: null
|
|
190
|
+
editBuffer: null
|
|
191
|
+
sessionTargetId: null
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export interface ModalNewTab extends ModalBase {
|
|
195
|
+
type: 'new-tab'
|
|
196
|
+
}
|
|
197
|
+
export interface ModalSessionPicker extends ModalBase {
|
|
198
|
+
type: 'session-picker'
|
|
199
|
+
}
|
|
200
|
+
export interface ModalSessionName extends ModalBase {
|
|
201
|
+
type: 'session-name'
|
|
202
|
+
}
|
|
203
|
+
export interface ModalRenameTab extends ModalBase {
|
|
204
|
+
type: 'rename-tab'
|
|
205
|
+
}
|
|
206
|
+
export interface ModalSnippetPicker extends ModalBase {
|
|
207
|
+
type: 'snippet-picker'
|
|
208
|
+
}
|
|
209
|
+
export interface ModalThemePicker extends ModalBase {
|
|
210
|
+
type: 'theme-picker'
|
|
211
|
+
}
|
|
212
|
+
export interface ModalHelp extends ModalBase {
|
|
213
|
+
type: 'help'
|
|
214
|
+
}
|
|
215
|
+
export interface ModalSplitPicker extends ModalBase {
|
|
216
|
+
type: 'split-picker'
|
|
217
|
+
splitDirection: SplitDirection
|
|
218
|
+
}
|
|
219
|
+
export interface ModalCreateSession extends ModalBase {
|
|
220
|
+
type: 'create-session'
|
|
221
|
+
directoryResults: DirectoryResult[]
|
|
222
|
+
pendingProjectPath: string | null
|
|
223
|
+
activeField: 'directory' | 'name'
|
|
224
|
+
nameBuffer: string
|
|
225
|
+
}
|
|
226
|
+
export interface ModalSnippetEditor extends ModalBase {
|
|
227
|
+
type: 'snippet-editor'
|
|
228
|
+
activeField: 'name' | 'content'
|
|
229
|
+
contentBuffer: string
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export type ModalState =
|
|
233
|
+
| ModalClosed
|
|
234
|
+
| ModalNewTab
|
|
235
|
+
| ModalSessionPicker
|
|
236
|
+
| ModalSessionName
|
|
237
|
+
| ModalRenameTab
|
|
238
|
+
| ModalSnippetPicker
|
|
239
|
+
| ModalThemePicker
|
|
240
|
+
| ModalHelp
|
|
241
|
+
| ModalSplitPicker
|
|
242
|
+
| ModalCreateSession
|
|
243
|
+
| ModalSnippetEditor
|
|
244
|
+
|
|
245
|
+
export interface LayoutState {
|
|
246
|
+
terminalCols: number
|
|
247
|
+
terminalRows: number
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export interface AppState {
|
|
251
|
+
tabs: TabSession[]
|
|
252
|
+
activeTabId: string | null
|
|
253
|
+
layoutTrees: Record<string, LayoutNode>
|
|
254
|
+
tabGroupMap: Record<string, string>
|
|
255
|
+
sessions: SessionRecord[]
|
|
256
|
+
currentSessionId: string | null
|
|
257
|
+
snippets: SnippetRecord[]
|
|
258
|
+
focusMode: FocusMode
|
|
259
|
+
sidebar: SidebarState
|
|
260
|
+
modal: ModalState
|
|
261
|
+
layout: LayoutState
|
|
262
|
+
customCommands: Record<AssistantId, string>
|
|
263
|
+
gitPanel: GitPanelState
|
|
264
|
+
pendingChords: string[] | null
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// ─── AppAction union ──────────────────────────────────────────────────────────
|
|
268
|
+
|
|
269
|
+
export type ModalAction =
|
|
270
|
+
| { type: 'open-new-tab-modal' }
|
|
271
|
+
| { type: 'open-help-modal' }
|
|
272
|
+
| { type: 'open-split-picker'; direction: SplitDirection }
|
|
273
|
+
| { type: 'open-session-picker' }
|
|
274
|
+
| { type: 'open-session-name-modal'; sessionTargetId?: string; initialName?: string }
|
|
275
|
+
| { type: 'close-modal' }
|
|
276
|
+
| { type: 'move-modal-selection'; delta: number }
|
|
277
|
+
| { type: 'begin-command-edit' }
|
|
278
|
+
| { type: 'update-command-edit'; char: string }
|
|
279
|
+
| { type: 'commit-command-edit' }
|
|
280
|
+
| { type: 'cancel-command-edit' }
|
|
281
|
+
| { type: 'open-create-session-modal' }
|
|
282
|
+
| { type: 'set-directory-results'; results: DirectoryResult[] }
|
|
283
|
+
| { type: 'switch-create-session-field' }
|
|
284
|
+
| { type: 'select-directory' }
|
|
285
|
+
| { type: 'begin-session-filter' }
|
|
286
|
+
| { type: 'open-rename-tab-modal' }
|
|
287
|
+
| { type: 'open-snippet-picker' }
|
|
288
|
+
| { type: 'open-snippet-editor'; snippetId?: string }
|
|
289
|
+
| { type: 'begin-snippet-filter' }
|
|
290
|
+
| { type: 'open-theme-picker' }
|
|
291
|
+
|
|
292
|
+
export type SessionAction =
|
|
293
|
+
| { type: 'load-session'; sessionId: string; workspaceSnapshot?: WorkspaceSnapshotV1 }
|
|
294
|
+
| { type: 'set-sessions'; sessions: SessionRecord[] }
|
|
295
|
+
| { type: 'create-session-record'; session: SessionRecord }
|
|
296
|
+
| { type: 'rename-session-record'; sessionId: string; name: string }
|
|
297
|
+
| { type: 'delete-session-record'; sessionId: string }
|
|
298
|
+
|
|
299
|
+
export type TabAction =
|
|
300
|
+
| { type: 'add-tab'; tab: TabSession }
|
|
301
|
+
| {
|
|
302
|
+
type: 'hydrate-workspace'
|
|
303
|
+
tabs: TabSession[]
|
|
304
|
+
activeTabId: string | null
|
|
305
|
+
layoutTree?: LayoutNode | null
|
|
306
|
+
layoutTrees?: Record<string, LayoutNode>
|
|
307
|
+
tabGroupMap?: Record<string, string>
|
|
308
|
+
}
|
|
309
|
+
| { type: 'close-tab'; tabId: string }
|
|
310
|
+
| { type: 'close-active-tab' }
|
|
311
|
+
| { type: 'set-active-tab'; tabId: string }
|
|
312
|
+
| { type: 'move-active-tab'; delta: number }
|
|
313
|
+
| { type: 'reorder-active-tab'; delta: number }
|
|
314
|
+
| { type: 'reset-tab-session'; tabId: string }
|
|
315
|
+
| { type: 'rename-tab'; tabId: string; title: string }
|
|
316
|
+
| { type: 'append-tab-buffer'; tabId: string; chunk: string }
|
|
317
|
+
| {
|
|
318
|
+
type: 'replace-tab-viewport'
|
|
319
|
+
tabId: string
|
|
320
|
+
viewport: TerminalSnapshot
|
|
321
|
+
terminalModes: TerminalModeState
|
|
322
|
+
}
|
|
323
|
+
| { type: 'set-tab-activity'; tabId: string; activity?: TabActivity }
|
|
324
|
+
| { type: 'set-tab-status'; tabId: string; status: TabStatus; exitCode?: number }
|
|
325
|
+
| { type: 'set-tab-error'; tabId: string; message: string }
|
|
326
|
+
|
|
327
|
+
export type LayoutAction =
|
|
328
|
+
| {
|
|
329
|
+
type: 'split-pane'
|
|
330
|
+
direction: SplitDirection
|
|
331
|
+
newTab: TabSession
|
|
332
|
+
}
|
|
333
|
+
| { type: 'close-pane'; tabId: string }
|
|
334
|
+
| {
|
|
335
|
+
type: 'focus-pane-direction'
|
|
336
|
+
direction: 'left' | 'right' | 'up' | 'down'
|
|
337
|
+
}
|
|
338
|
+
| {
|
|
339
|
+
type: 'resize-pane'
|
|
340
|
+
tabId: string
|
|
341
|
+
delta: number
|
|
342
|
+
axis?: SplitDirection
|
|
343
|
+
}
|
|
344
|
+
| {
|
|
345
|
+
type: 'set-split-ratio'
|
|
346
|
+
tabId: string
|
|
347
|
+
ratio: number
|
|
348
|
+
axis?: SplitDirection
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
export type UIAction =
|
|
352
|
+
| { type: 'toggle-sidebar' }
|
|
353
|
+
| { type: 'resize-sidebar'; delta: number }
|
|
354
|
+
| { type: 'set-focus-mode'; focusMode: FocusMode }
|
|
355
|
+
| { type: 'set-terminal-size'; cols: number; rows: number }
|
|
356
|
+
| { type: 'toggle-git-panel' }
|
|
357
|
+
| { type: 'resize-git-panel'; delta: number }
|
|
358
|
+
| { type: 'set-pending-chords'; chords: string[] | null }
|
|
359
|
+
|
|
360
|
+
export interface GitRefreshPayload {
|
|
361
|
+
branch: string | null
|
|
362
|
+
ahead: number
|
|
363
|
+
behind: number
|
|
364
|
+
files: GitFileEntry[]
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
export type GitPanelAction =
|
|
368
|
+
| { type: 'git-refresh-success'; payload: GitRefreshPayload }
|
|
369
|
+
| { type: 'git-refresh-error'; kind: GitPanelError }
|
|
370
|
+
| { type: 'git-panel-reset' }
|
|
371
|
+
|
|
372
|
+
export type DataAction =
|
|
373
|
+
| { type: 'set-snippets'; snippets: SnippetRecord[] }
|
|
374
|
+
| { type: 'delete-snippet'; snippetId: string }
|
|
375
|
+
|
|
376
|
+
export type AppAction =
|
|
377
|
+
| ModalAction
|
|
378
|
+
| SessionAction
|
|
379
|
+
| TabAction
|
|
380
|
+
| LayoutAction
|
|
381
|
+
| UIAction
|
|
382
|
+
| DataAction
|
|
383
|
+
| GitPanelAction
|
|
384
|
+
|
|
385
|
+
// ─── Side effects ─────────────────────────────────────────────────────────────
|
|
386
|
+
|
|
387
|
+
export type SideEffect =
|
|
388
|
+
| { type: 'quit'; state: AppState }
|
|
389
|
+
| { type: 'launch-selected-assistant' }
|
|
390
|
+
| { type: 'confirm-selected-session' }
|
|
391
|
+
| { type: 'delete-selected-session' }
|
|
392
|
+
| { type: 'open-rename-selected-session' }
|
|
393
|
+
| { type: 'create-session'; name: string; projectPath?: string }
|
|
394
|
+
| { type: 'close-tab'; tabId: string }
|
|
395
|
+
| { type: 'restart-tab'; tab: TabSession }
|
|
396
|
+
| { type: 'paste-selected-snippet' }
|
|
397
|
+
| { type: 'paste-snippet-to-group' }
|
|
398
|
+
| { type: 'edit-selected-snippet' }
|
|
399
|
+
| { type: 'delete-selected-snippet' }
|
|
400
|
+
| { type: 'save-snippet-editor' }
|
|
401
|
+
| { type: 'save-custom-command' }
|
|
402
|
+
| { type: 'apply-theme'; action: 'open' }
|
|
403
|
+
| { type: 'apply-theme'; action: 'restore' }
|
|
404
|
+
| { type: 'apply-theme'; action: 'confirm' }
|
|
405
|
+
| { type: 'apply-theme'; action: 'preview'; delta: 1 | -1 }
|
|
406
|
+
| { type: 'rename-session'; sessionId: string; name: string }
|
|
407
|
+
| { type: 'split-pane'; direction: SplitDirection }
|
|
408
|
+
| { type: 'confirm-split' }
|
|
409
|
+
|
|
410
|
+
// ─── Key input / KeyResult / ModeContext ──────────────────────────────────────
|
|
411
|
+
|
|
412
|
+
/** Structural shape for a parsed key event. Matches @opentui/core's KeyEvent. */
|
|
413
|
+
export interface KeyInput {
|
|
414
|
+
name: string
|
|
415
|
+
ctrl: boolean
|
|
416
|
+
meta: boolean
|
|
417
|
+
shift: boolean
|
|
418
|
+
sequence: string
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
export interface KeyResult {
|
|
422
|
+
actions: AppAction[]
|
|
423
|
+
effects: SideEffect[]
|
|
424
|
+
transition?: ModeId
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
export interface ModeContext {
|
|
428
|
+
readonly state: AppState
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// ─── Themes ───────────────────────────────────────────────────────────────────
|
|
432
|
+
|
|
433
|
+
export interface ThemeColors {
|
|
434
|
+
background: string
|
|
435
|
+
panel: string
|
|
436
|
+
panelMuted: string
|
|
437
|
+
panelHighlight: string
|
|
438
|
+
overlay: string
|
|
439
|
+
border: string
|
|
440
|
+
borderActive: string
|
|
441
|
+
text: string
|
|
442
|
+
textMuted: string
|
|
443
|
+
accent: string
|
|
444
|
+
accentAlt: string
|
|
445
|
+
warning: string
|
|
446
|
+
danger: string
|
|
447
|
+
success: string
|
|
448
|
+
dim: string
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
export type ThemeId =
|
|
452
|
+
| 'aimux'
|
|
453
|
+
| 'dracula'
|
|
454
|
+
| 'dracula-at-night'
|
|
455
|
+
| 'everforest'
|
|
456
|
+
| 'tokyo-night'
|
|
457
|
+
| 'gruvbox-dark'
|
|
458
|
+
| 'catppuccin-mocha'
|
|
459
|
+
| 'nord'
|
|
460
|
+
| 'solarized-dark'
|
|
461
|
+
| 'one-dark'
|
|
462
|
+
| 'kanagawa'
|
|
463
|
+
|
|
464
|
+
export interface ThemeDefinition {
|
|
465
|
+
base?: ThemeId
|
|
466
|
+
colors: ThemeColors
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// ─── Backend config (stub) ────────────────────────────────────────────────────
|
|
470
|
+
|
|
471
|
+
export interface BackendConfig {
|
|
472
|
+
command: string
|
|
473
|
+
args?: string[]
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// ─── Sidebar config (stub) ────────────────────────────────────────────────────
|
|
477
|
+
|
|
478
|
+
export interface SidebarConfig {
|
|
479
|
+
widgets?: string[]
|
|
480
|
+
width?: number
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// ─── Hooks config (stub) ──────────────────────────────────────────────────────
|
|
484
|
+
|
|
485
|
+
export interface HooksConfig {
|
|
486
|
+
onSessionCreate?: (session: { name: string; projectPath?: string }) => void | Promise<void>
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// ─── Snippet config (stub) ────────────────────────────────────────────────────
|
|
490
|
+
|
|
491
|
+
export interface SnippetDef {
|
|
492
|
+
name: string
|
|
493
|
+
trigger?: string
|
|
494
|
+
text: string
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// ─── Action value types ───────────────────────────────────────────────────────
|
|
498
|
+
|
|
499
|
+
export type ActionFn = (ctx: ModeContext) => KeyResult | null
|
|
500
|
+
export type Action = KeyResult | ActionFn
|
|
501
|
+
|
|
502
|
+
// ─── Keymap builder API types ─────────────────────────────────────────────────
|
|
503
|
+
|
|
504
|
+
export interface GroupBuilderApi {
|
|
505
|
+
map(keys: string, action: Action): GroupBuilderApi
|
|
506
|
+
group(
|
|
507
|
+
prefix: string,
|
|
508
|
+
name: string,
|
|
509
|
+
configure: (g: GroupBuilderApi) => GroupBuilderApi
|
|
510
|
+
): GroupBuilderApi
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
export interface ModeBindingBuilderApi {
|
|
514
|
+
map(keys: string, action: Action): ModeBindingBuilderApi
|
|
515
|
+
unmap(keys: string): ModeBindingBuilderApi
|
|
516
|
+
group(
|
|
517
|
+
prefix: string,
|
|
518
|
+
name: string,
|
|
519
|
+
configure: (g: GroupBuilderApi) => GroupBuilderApi
|
|
520
|
+
): ModeBindingBuilderApi
|
|
521
|
+
passthrough(): ModeBindingBuilderApi
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
export interface KeymapBuilderApi {
|
|
525
|
+
leader(key: string): KeymapBuilderApi
|
|
526
|
+
timeout(ms: number): KeymapBuilderApi
|
|
527
|
+
mode(id: ModeId, configure: (m: ModeBindingBuilderApi) => ModeBindingBuilderApi): KeymapBuilderApi
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// ─── Top-level user config ────────────────────────────────────────────────────
|
|
531
|
+
|
|
532
|
+
export interface AimuxUserConfig {
|
|
533
|
+
theme?: ThemeId | ThemeDefinition
|
|
534
|
+
keymaps?: (k: KeymapBuilderApi) => KeymapBuilderApi
|
|
535
|
+
backends?: Record<string, BackendConfig>
|
|
536
|
+
sidebar?: SidebarConfig
|
|
537
|
+
hooks?: HooksConfig
|
|
538
|
+
snippets?: SnippetDef[]
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// ─── Resolved config (internal) ───────────────────────────────────────────────
|
|
542
|
+
|
|
543
|
+
export interface BindingDef {
|
|
544
|
+
keys: string
|
|
545
|
+
result: Action
|
|
546
|
+
group?: string
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
export interface ModeKeymapDef {
|
|
550
|
+
bindings: BindingDef[]
|
|
551
|
+
removals: string[]
|
|
552
|
+
isPassthrough: boolean
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
export interface ResolvedKeymapConfig {
|
|
556
|
+
leader: string
|
|
557
|
+
timeout: number
|
|
558
|
+
modes: Map<ModeId, ModeKeymapDef>
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
export interface ResolvedConfig {
|
|
562
|
+
theme: ThemeId | ThemeDefinition | undefined
|
|
563
|
+
keymaps: ResolvedKeymapConfig
|
|
564
|
+
backends: Record<string, BackendConfig>
|
|
565
|
+
sidebar: SidebarConfig
|
|
566
|
+
hooks: HooksConfig
|
|
567
|
+
snippets: SnippetDef[]
|
|
568
|
+
}
|