@brimveyn/aimux 1.15.0 → 1.15.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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brimveyn/aimux",
|
|
3
|
-
"version": "1.15.
|
|
3
|
+
"version": "1.15.2",
|
|
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",
|
|
@@ -57,7 +57,9 @@
|
|
|
57
57
|
"format": "oxfmt --write .",
|
|
58
58
|
"format:check": "oxfmt --check .",
|
|
59
59
|
"knip": "knip-bun",
|
|
60
|
-
"bump": "bun run scripts/bump.ts"
|
|
60
|
+
"bump": "bun run scripts/bump.ts",
|
|
61
|
+
"bump:ipc": "bun run scripts/bump-protocol.ts ipc",
|
|
62
|
+
"bump:terminal_manager": "bun run scripts/bump-protocol.ts terminal-manager"
|
|
61
63
|
},
|
|
62
64
|
"dependencies": {
|
|
63
65
|
"@brimveyn/aimux-config": "0.6.11",
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// opentui re-emits 'finishSelection' on re-renders, focus changes, and
|
|
2
|
+
// viewport refreshes. Each of those would call copyToSystemClipboard with the
|
|
3
|
+
// *same* text, blindly clobbering whatever the user just copied in another
|
|
4
|
+
// app. We dedupe by content: aimux never writes the same selection twice in
|
|
5
|
+
// a row to the system clipboard, so an external copy survives any phantom
|
|
6
|
+
// re-emit of the previous in-aimux selection.
|
|
7
|
+
//
|
|
8
|
+
// The dedup state is reset when the renderer reports an empty selection
|
|
9
|
+
// (deselect), so a user who deliberately reselects the same text after
|
|
10
|
+
// clicking elsewhere still gets it copied.
|
|
11
|
+
let lastWrittenText: string | null = null
|
|
12
|
+
|
|
13
|
+
export function shouldWriteSelectionToClipboard(text: string): boolean {
|
|
14
|
+
if (text === lastWrittenText) return false
|
|
15
|
+
lastWrittenText = text
|
|
16
|
+
return true
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function resetSelectionClipboardDedup(): void {
|
|
20
|
+
lastWrittenText = null
|
|
21
|
+
}
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
} from './click-selection-resolver'
|
|
22
22
|
import { recordMultiClickClipboardWrite } from './multi-click-clipboard-guard'
|
|
23
23
|
import { requestRenderUpTree } from './render-invalidation'
|
|
24
|
+
import { shouldWriteSelectionToClipboard } from './selection-clipboard-dedup'
|
|
24
25
|
import {
|
|
25
26
|
type AnchoredRatioDragState,
|
|
26
27
|
type AxisDragState,
|
|
@@ -146,7 +147,9 @@ function applyMultiClickInitialSelection(
|
|
|
146
147
|
finishDragging: false,
|
|
147
148
|
})
|
|
148
149
|
requestRenderUpTree(selection.target)
|
|
149
|
-
|
|
150
|
+
if (shouldWriteSelectionToClipboard(selection.selectedText)) {
|
|
151
|
+
copyToSystemClipboard(selection.selectedText)
|
|
152
|
+
}
|
|
150
153
|
}
|
|
151
154
|
|
|
152
155
|
export function useMouseHandlers({
|
|
@@ -573,7 +576,7 @@ export function useMouseHandlers({
|
|
|
573
576
|
const anchorIdx = drag.anchorAbsRow - startAbs
|
|
574
577
|
const focusIdx = drag.focusAbsRow - startAbs
|
|
575
578
|
const text = extractStreamText(lines, anchorIdx, anchorCol, focusIdx, drag.focusCol)
|
|
576
|
-
if (text.length > 0) {
|
|
579
|
+
if (text.length > 0 && shouldWriteSelectionToClipboard(text)) {
|
|
577
580
|
copyToSystemClipboard(text)
|
|
578
581
|
recordMultiClickClipboardWrite()
|
|
579
582
|
}
|
|
@@ -23,6 +23,10 @@ import {
|
|
|
23
23
|
import { shouldSuppressSelectionCopy } from './multi-click-clipboard-guard'
|
|
24
24
|
import { writeMacroExpansionToTab, writePasteToTab, writeToTab } from './pty-write'
|
|
25
25
|
import { type OtuiSelection, resolveSelectionClipboardText } from './selection-clipboard'
|
|
26
|
+
import {
|
|
27
|
+
resetSelectionClipboardDedup,
|
|
28
|
+
shouldWriteSelectionToClipboard,
|
|
29
|
+
} from './selection-clipboard-dedup'
|
|
26
30
|
import { applyViewportObservation, type ViewportObservation } from './selection-scroll'
|
|
27
31
|
|
|
28
32
|
const BRACKETED_PASTE_ENABLE_SEQUENCE = '\x1b[?2004h'
|
|
@@ -239,7 +243,13 @@ export function useRendererBindings({
|
|
|
239
243
|
textLength: selectedText.length,
|
|
240
244
|
})
|
|
241
245
|
|
|
242
|
-
if (selection.isDragging === true
|
|
246
|
+
if (selection.isDragging === true) {
|
|
247
|
+
return
|
|
248
|
+
}
|
|
249
|
+
if (selectedText.length === 0) {
|
|
250
|
+
// Deselect → forget the last-written text so a deliberate reselection
|
|
251
|
+
// of the same text writes it again.
|
|
252
|
+
resetSelectionClipboardDedup()
|
|
243
253
|
return
|
|
244
254
|
}
|
|
245
255
|
|
|
@@ -254,7 +264,11 @@ export function useRendererBindings({
|
|
|
254
264
|
}
|
|
255
265
|
|
|
256
266
|
renderer.copyToClipboardOSC52(selectedText)
|
|
257
|
-
|
|
267
|
+
if (shouldWriteSelectionToClipboard(selectedText)) {
|
|
268
|
+
copyToSystemClipboard(selectedText)
|
|
269
|
+
} else {
|
|
270
|
+
logInputDebug('app.selection.dedup', { textLength: selectedText.length })
|
|
271
|
+
}
|
|
258
272
|
}
|
|
259
273
|
|
|
260
274
|
renderer.prependInputHandler(handler)
|
|
@@ -32,8 +32,8 @@ import {
|
|
|
32
32
|
// either way (pre-v7 TM → new client never sees the indices; new TM →
|
|
33
33
|
// pre-v7 client ignores them and falls back to the theme default), so Min
|
|
34
34
|
// is raised in lockstep to force matching binaries.
|
|
35
|
-
export const MANAGER_PROTOCOL_MIN_VERSION =
|
|
36
|
-
export const MANAGER_PROTOCOL_VERSION =
|
|
35
|
+
export const MANAGER_PROTOCOL_MIN_VERSION = 8
|
|
36
|
+
export const MANAGER_PROTOCOL_VERSION = 8
|
|
37
37
|
/**
|
|
38
38
|
* Minimum version required to send `setBroadcastEnabled`. Older TMs (v3) will
|
|
39
39
|
* not understand the message; the daemon must check the negotiated version
|
package/src/ipc/protocol.ts
CHANGED
|
@@ -14,8 +14,8 @@ import { isWorkspaceSnapshotV1 } from '../state/validation'
|
|
|
14
14
|
// `reapplyScrollIntent` message — the frontend no longer derives or sends it.
|
|
15
15
|
// (v8 was the unfilled-viewport status-detector change; this is a further
|
|
16
16
|
// breaking wire change, so the version steps again.)
|
|
17
|
-
export const IPC_PROTOCOL_MIN_VERSION =
|
|
18
|
-
export const IPC_PROTOCOL_VERSION =
|
|
17
|
+
export const IPC_PROTOCOL_MIN_VERSION = 10
|
|
18
|
+
export const IPC_PROTOCOL_VERSION = 10
|
|
19
19
|
|
|
20
20
|
export interface ProtocolHelloRequest {
|
|
21
21
|
minVersion: number
|