@brimveyn/aimux 1.13.2 → 1.14.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.
@@ -1,3 +1,5 @@
1
+ import type { AppAction, AppState, TabSession } from '../types'
2
+
1
3
  import {
2
4
  allLeafIds,
3
5
  createGroupId,
@@ -15,13 +17,6 @@ import {
15
17
  import { normalizeGroupedTabOrder } from '../session-persistence'
16
18
  import { orderTabsByWorktree, withActiveWorktree } from '../session-worktrees'
17
19
  import { createDefaultTerminalModes } from '../terminal-modes'
18
- import {
19
- type AppAction,
20
- type AppState,
21
- DEFAULT_SCROLL_INTENT,
22
- deriveScrollIntent,
23
- type TabSession,
24
- } from '../types'
25
20
 
26
21
  const MAX_BUFFER_LENGTH = 50_000
27
22
 
@@ -448,7 +443,6 @@ export function reduceTabState(state: AppState, action: AppAction): AppState | n
448
443
  buffer: '',
449
444
  errorMessage: undefined,
450
445
  exitCode: undefined,
451
- scrollIntent: DEFAULT_SCROLL_INTENT,
452
446
  status: 'starting',
453
447
  terminalModes: createDefaultTerminalModes(),
454
448
  viewport: undefined,
@@ -470,23 +464,11 @@ export function reduceTabState(state: AppState, action: AppAction): AppState | n
470
464
  ...state,
471
465
  tabs: updateTab(state.tabs, action.tabId, (tab) => ({
472
466
  ...tab,
473
- scrollIntent:
474
- action.source === 'resize' || action.source === 'switch'
475
- ? (tab.scrollIntent ?? DEFAULT_SCROLL_INTENT)
476
- : deriveScrollIntent(action.viewport),
477
467
  status: tab.status === 'starting' ? 'running' : tab.status,
478
468
  terminalModes: action.terminalModes,
479
469
  viewport: action.viewport,
480
470
  })),
481
471
  }
482
- case 'set-scroll-intent':
483
- return {
484
- ...state,
485
- tabs: updateTab(state.tabs, action.tabId, (tab) => ({
486
- ...tab,
487
- scrollIntent: action.intent,
488
- })),
489
- }
490
472
  case 'set-tab-activity':
491
473
  return {
492
474
  ...state,
@@ -1,12 +1,6 @@
1
+ import type { AppState, TabSession, TabStatus, WorkspaceSnapshotV1 } from './types'
2
+
1
3
  import { allLeafIds, createGroupId, type LayoutNode, pruneLayoutTree } from './layout-tree'
2
- import {
3
- type AppState,
4
- DEFAULT_SCROLL_INTENT,
5
- type ScrollIntent,
6
- type TabSession,
7
- type TabStatus,
8
- type WorkspaceSnapshotV1,
9
- } from './types'
10
4
 
11
5
  export function createEmptyWorkspaceSnapshot(): WorkspaceSnapshotV1 {
12
6
  return {
@@ -47,7 +41,6 @@ export function serializeWorkspace(state: AppState): WorkspaceSnapshotV1 {
47
41
  errorMessage: tab.errorMessage,
48
42
  exitCode: tab.exitCode,
49
43
  id: tab.id,
50
- scrollIntent: tab.scrollIntent,
51
44
  status: tab.status === 'disconnected' ? 'running' : tab.status,
52
45
  terminalModes: tab.terminalModes,
53
46
  title: tab.title,
@@ -76,7 +69,6 @@ export function restoreTabsFromWorkspace(snapshot: WorkspaceSnapshotV1 | undefin
76
69
  errorMessage: tab.errorMessage,
77
70
  exitCode: tab.exitCode,
78
71
  id: tab.id,
79
- scrollIntent: tab.scrollIntent ?? DEFAULT_SCROLL_INTENT,
80
72
  status: getDisconnectedStatus(tab.status),
81
73
  terminalModes: tab.terminalModes,
82
74
  title: tab.title,
@@ -85,18 +77,6 @@ export function restoreTabsFromWorkspace(snapshot: WorkspaceSnapshotV1 | undefin
85
77
  }))
86
78
  }
87
79
 
88
- export function getSnapshotScrollIntents(
89
- snapshot: WorkspaceSnapshotV1 | undefined
90
- ): Map<string, ScrollIntent> {
91
- if (!snapshot || snapshot.version !== 1) {
92
- return new Map()
93
- }
94
-
95
- return new Map(
96
- snapshot.tabs.map((tab) => [tab.id, tab.scrollIntent ?? DEFAULT_SCROLL_INTENT] as const)
97
- )
98
- }
99
-
100
80
  export function restoreLayoutTrees(
101
81
  snapshot: WorkspaceSnapshotV1 | undefined,
102
82
  tabs: TabSession[]
@@ -70,16 +70,11 @@ export interface TerminalSnapshot {
70
70
  cursorVisible: boolean
71
71
  }
72
72
 
73
+ // The scroll position is owned end-to-end by the backend emulator; this type
74
+ // only describes the re-anchor target the backend computes for itself across a
75
+ // reflow. The frontend no longer derives, stores, or sends a scroll intent.
73
76
  export type ScrollIntent = { kind: 'bottom' } | { absoluteLine: number; kind: 'anchor' }
74
77
 
75
- export const DEFAULT_SCROLL_INTENT: ScrollIntent = { kind: 'bottom' }
76
-
77
- export function deriveScrollIntent(viewport: TerminalSnapshot): ScrollIntent {
78
- return viewport.viewportY >= viewport.baseY
79
- ? { kind: 'bottom' }
80
- : { absoluteLine: viewport.viewportY, kind: 'anchor' }
81
- }
82
-
83
78
  export interface TerminalModeState {
84
79
  mouseTrackingMode: 'none' | 'x10' | 'vt200' | 'drag' | 'any'
85
80
  sendFocusMode: boolean
@@ -97,7 +92,6 @@ export interface PersistedTabSnapshot {
97
92
  buffer: string
98
93
  viewport?: TerminalSnapshot
99
94
  terminalModes: TerminalModeState
100
- scrollIntent?: ScrollIntent
101
95
  errorMessage?: string
102
96
  exitCode?: number
103
97
  worktreeId?: string
@@ -163,7 +157,6 @@ export interface TabSession {
163
157
  buffer: string
164
158
  viewport?: TerminalSnapshot
165
159
  terminalModes: TerminalModeState
166
- scrollIntent?: ScrollIntent
167
160
  command: string
168
161
  errorMessage?: string
169
162
  exitCode?: number
@@ -583,7 +576,6 @@ export type TabAction =
583
576
  terminalModes: TerminalModeState
584
577
  source?: 'resize' | 'scroll' | 'data' | 'switch'
585
578
  }
586
- | { type: 'set-scroll-intent'; tabId: string; intent: ScrollIntent }
587
579
  | { type: 'set-tab-activity'; tabId: string; activity?: TabActivity }
588
580
  | { type: 'set-tab-error'; tabId: string; message: string }
589
581
 
@@ -56,13 +56,6 @@ function isTerminalSnapshot(value: unknown): value is TerminalSnapshot {
56
56
  )
57
57
  }
58
58
 
59
- function isScrollIntent(value: unknown): boolean {
60
- if (!isObjectRecord(value)) return false
61
- if (value.kind === 'bottom') return true
62
- if (value.kind === 'anchor') return isFiniteNumber(value.absoluteLine)
63
- return false
64
- }
65
-
66
59
  function isTerminalModeState(value: unknown): value is TerminalModeState {
67
60
  return (
68
61
  isObjectRecord(value) &&
@@ -149,7 +142,6 @@ export function isWorkspaceSnapshotV1(value: unknown): value is WorkspaceSnapsho
149
142
  isString(tab.buffer) &&
150
143
  isTerminalModeState(tab.terminalModes) &&
151
144
  (tab.viewport === undefined || isTerminalSnapshot(tab.viewport)) &&
152
- (tab.scrollIntent === undefined || isScrollIntent(tab.scrollIntent)) &&
153
145
  (tab.errorMessage === undefined || isString(tab.errorMessage)) &&
154
146
  (tab.exitCode === undefined || isFiniteNumber(tab.exitCode)) &&
155
147
  (tab.worktreeId === undefined || isString(tab.worktreeId))
@@ -1,12 +1,7 @@
1
1
  import { EventEmitter } from 'node:events'
2
2
  import { connect, type Socket } from 'node:net'
3
3
 
4
- import type {
5
- ScrollIntent,
6
- TerminalModeState,
7
- TerminalSnapshot,
8
- WorkspaceSnapshotV1,
9
- } from '../state/types'
4
+ import type { TerminalModeState, TerminalSnapshot, WorkspaceSnapshotV1 } from '../state/types'
10
5
 
11
6
  import { getTerminalManagerSocketPath } from '../daemon/runtime-paths'
12
7
  import { logDebug } from '../debug/input-log'
@@ -306,29 +301,18 @@ export class TerminalManagerClient extends EventEmitter<ManagerClientEvents> {
306
301
  })
307
302
  }
308
303
 
309
- async resize(
310
- sessionId: string,
311
- cols: number,
312
- rows: number,
313
- intents?: Record<string, ScrollIntent>
314
- ): Promise<void> {
304
+ async resize(sessionId: string, cols: number, rows: number): Promise<void> {
315
305
  return this.sendExpectOk({
316
306
  id: crypto.randomUUID(),
317
- payload: { cols, intents, rows, sessionId },
307
+ payload: { cols, rows, sessionId },
318
308
  type: 'resizeClient',
319
309
  })
320
310
  }
321
311
 
322
- async resizeTab(
323
- sessionId: string,
324
- tabId: string,
325
- cols: number,
326
- rows: number,
327
- intent?: ScrollIntent
328
- ): Promise<void> {
312
+ async resizeTab(sessionId: string, tabId: string, cols: number, rows: number): Promise<void> {
329
313
  return this.sendExpectOk({
330
314
  id: crypto.randomUUID(),
331
- payload: { cols, intent, rows, sessionId, tabId },
315
+ payload: { cols, rows, sessionId, tabId },
332
316
  type: 'resizeTab',
333
317
  })
334
318
  }
@@ -349,14 +333,6 @@ export class TerminalManagerClient extends EventEmitter<ManagerClientEvents> {
349
333
  })
350
334
  }
351
335
 
352
- async reapplyScrollIntent(sessionId: string, tabId: string, intent: ScrollIntent): Promise<void> {
353
- return this.sendExpectOk({
354
- id: crypto.randomUUID(),
355
- payload: { intent, sessionId, tabId },
356
- type: 'reapplyScrollIntent',
357
- })
358
- }
359
-
360
336
  async setActiveTab(sessionId: string, tabId: string | null): Promise<void> {
361
337
  return this.sendExpectOk({
362
338
  id: crypto.randomUUID(),
@@ -211,15 +211,10 @@ export async function runTerminalManager(): Promise<void> {
211
211
  break
212
212
  case 'resizeClient': {
213
213
  requireNegotiatedVersion(socket, negotiatedVersions)
214
- const intentsRecord = message.payload.intents
215
- const intentsMap = intentsRecord
216
- ? new Map(Object.entries(intentsRecord))
217
- : undefined
218
214
  sessionManager.resize(
219
215
  message.payload.sessionId,
220
216
  message.payload.cols,
221
- message.payload.rows,
222
- intentsMap
217
+ message.payload.rows
223
218
  )
224
219
  sendOk(socket, message.id)
225
220
  break
@@ -230,8 +225,7 @@ export async function runTerminalManager(): Promise<void> {
230
225
  message.payload.sessionId,
231
226
  message.payload.tabId,
232
227
  message.payload.cols,
233
- message.payload.rows,
234
- message.payload.intent
228
+ message.payload.rows
235
229
  )
236
230
  sendOk(socket, message.id)
237
231
  break
@@ -249,15 +243,6 @@ export async function runTerminalManager(): Promise<void> {
249
243
  sessionManager.scrollToBottom(message.payload.sessionId, message.payload.tabId)
250
244
  sendOk(socket, message.id)
251
245
  break
252
- case 'reapplyScrollIntent':
253
- requireNegotiatedVersion(socket, negotiatedVersions)
254
- sessionManager.reapplyScrollIntent(
255
- message.payload.sessionId,
256
- message.payload.tabId,
257
- message.payload.intent
258
- )
259
- sendOk(socket, message.id)
260
- break
261
246
  case 'setActiveTab':
262
247
  requireNegotiatedVersion(socket, negotiatedVersions)
263
248
  sessionManager.setActiveTab(message.payload.sessionId, message.payload.tabId)