@wong2kim/wmux 1.0.0 → 1.0.1

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 (110) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +209 -157
  3. package/dist/cli/cli/client.js +1 -1
  4. package/dist/cli/cli/commands/browser.js +19 -19
  5. package/dist/cli/cli/index.js +58 -58
  6. package/dist/cli/shared/constants.js +17 -4
  7. package/dist/mcp/shared/constants.js +17 -4
  8. package/package.json +96 -84
  9. package/assets/icon.ico +0 -0
  10. package/assets/icon.svg +0 -6
  11. package/forge.config.ts +0 -61
  12. package/index.html +0 -12
  13. package/postcss.config.js +0 -6
  14. package/src/cli/client.ts +0 -76
  15. package/src/cli/commands/browser.ts +0 -128
  16. package/src/cli/commands/input.ts +0 -72
  17. package/src/cli/commands/notify.ts +0 -29
  18. package/src/cli/commands/pane.ts +0 -90
  19. package/src/cli/commands/surface.ts +0 -102
  20. package/src/cli/commands/system.ts +0 -95
  21. package/src/cli/commands/workspace.ts +0 -116
  22. package/src/cli/index.ts +0 -145
  23. package/src/cli/utils.ts +0 -44
  24. package/src/main/index.ts +0 -86
  25. package/src/main/ipc/handlers/clipboard.handler.ts +0 -20
  26. package/src/main/ipc/handlers/metadata.handler.ts +0 -56
  27. package/src/main/ipc/handlers/pty.handler.ts +0 -69
  28. package/src/main/ipc/handlers/session.handler.ts +0 -17
  29. package/src/main/ipc/handlers/shell.handler.ts +0 -11
  30. package/src/main/ipc/registerHandlers.ts +0 -31
  31. package/src/main/mcp/McpRegistrar.ts +0 -156
  32. package/src/main/metadata/MetadataCollector.ts +0 -58
  33. package/src/main/notification/ToastManager.ts +0 -32
  34. package/src/main/pipe/PipeServer.ts +0 -190
  35. package/src/main/pipe/RpcRouter.ts +0 -46
  36. package/src/main/pipe/handlers/_bridge.ts +0 -40
  37. package/src/main/pipe/handlers/browser.rpc.ts +0 -132
  38. package/src/main/pipe/handlers/input.rpc.ts +0 -120
  39. package/src/main/pipe/handlers/meta.rpc.ts +0 -59
  40. package/src/main/pipe/handlers/notify.rpc.ts +0 -53
  41. package/src/main/pipe/handlers/pane.rpc.ts +0 -39
  42. package/src/main/pipe/handlers/surface.rpc.ts +0 -43
  43. package/src/main/pipe/handlers/system.rpc.ts +0 -36
  44. package/src/main/pipe/handlers/workspace.rpc.ts +0 -52
  45. package/src/main/pty/AgentDetector.ts +0 -247
  46. package/src/main/pty/OscParser.ts +0 -81
  47. package/src/main/pty/PTYBridge.ts +0 -88
  48. package/src/main/pty/PTYManager.ts +0 -104
  49. package/src/main/pty/ShellDetector.ts +0 -63
  50. package/src/main/session/SessionManager.ts +0 -53
  51. package/src/main/updater/AutoUpdater.ts +0 -132
  52. package/src/main/window/createWindow.ts +0 -71
  53. package/src/mcp/README.md +0 -56
  54. package/src/mcp/index.ts +0 -153
  55. package/src/mcp/wmux-client.ts +0 -127
  56. package/src/preload/index.ts +0 -111
  57. package/src/preload/preload.ts +0 -108
  58. package/src/renderer/App.tsx +0 -5
  59. package/src/renderer/components/Browser/BrowserPanel.tsx +0 -219
  60. package/src/renderer/components/Browser/BrowserToolbar.tsx +0 -253
  61. package/src/renderer/components/Company/ApprovalDialog.tsx +0 -3
  62. package/src/renderer/components/Company/CompanyView.tsx +0 -7
  63. package/src/renderer/components/Company/MessageFeedPanel.tsx +0 -3
  64. package/src/renderer/components/Layout/AppLayout.tsx +0 -234
  65. package/src/renderer/components/Notification/NotificationPanel.tsx +0 -129
  66. package/src/renderer/components/Palette/CommandPalette.tsx +0 -409
  67. package/src/renderer/components/Palette/PaletteItem.tsx +0 -55
  68. package/src/renderer/components/Pane/Pane.tsx +0 -122
  69. package/src/renderer/components/Pane/PaneContainer.tsx +0 -41
  70. package/src/renderer/components/Pane/SurfaceTabs.tsx +0 -46
  71. package/src/renderer/components/Settings/SettingsPanel.tsx +0 -886
  72. package/src/renderer/components/Sidebar/MiniSidebar.tsx +0 -67
  73. package/src/renderer/components/Sidebar/Sidebar.tsx +0 -84
  74. package/src/renderer/components/Sidebar/WorkspaceItem.tsx +0 -241
  75. package/src/renderer/components/StatusBar/StatusBar.tsx +0 -93
  76. package/src/renderer/components/Terminal/SearchBar.tsx +0 -126
  77. package/src/renderer/components/Terminal/Terminal.tsx +0 -102
  78. package/src/renderer/components/Terminal/ViCopyMode.tsx +0 -104
  79. package/src/renderer/hooks/useKeyboard.ts +0 -310
  80. package/src/renderer/hooks/useNotificationListener.ts +0 -80
  81. package/src/renderer/hooks/useNotificationSound.ts +0 -75
  82. package/src/renderer/hooks/useRpcBridge.ts +0 -451
  83. package/src/renderer/hooks/useT.ts +0 -11
  84. package/src/renderer/hooks/useTerminal.ts +0 -349
  85. package/src/renderer/hooks/useViCopyMode.ts +0 -320
  86. package/src/renderer/i18n/index.ts +0 -69
  87. package/src/renderer/i18n/locales/en.ts +0 -157
  88. package/src/renderer/i18n/locales/ja.ts +0 -155
  89. package/src/renderer/i18n/locales/ko.ts +0 -155
  90. package/src/renderer/i18n/locales/zh.ts +0 -155
  91. package/src/renderer/index.tsx +0 -6
  92. package/src/renderer/stores/index.ts +0 -19
  93. package/src/renderer/stores/slices/notificationSlice.ts +0 -56
  94. package/src/renderer/stores/slices/paneSlice.ts +0 -141
  95. package/src/renderer/stores/slices/surfaceSlice.ts +0 -122
  96. package/src/renderer/stores/slices/uiSlice.ts +0 -247
  97. package/src/renderer/stores/slices/workspaceSlice.ts +0 -120
  98. package/src/renderer/styles/globals.css +0 -150
  99. package/src/renderer/themes.ts +0 -99
  100. package/src/shared/constants.ts +0 -53
  101. package/src/shared/electron.d.ts +0 -11
  102. package/src/shared/rpc.ts +0 -71
  103. package/src/shared/types.ts +0 -176
  104. package/tailwind.config.js +0 -11
  105. package/tsconfig.cli.json +0 -24
  106. package/tsconfig.json +0 -21
  107. package/tsconfig.mcp.json +0 -25
  108. package/vite.main.config.ts +0 -14
  109. package/vite.preload.config.ts +0 -9
  110. package/vite.renderer.config.ts +0 -6
@@ -1,247 +0,0 @@
1
- import type { StateCreator } from 'zustand';
2
- import type { StoreState } from '../index';
3
- import { setLocale as i18nSetLocale, type Locale } from '../../i18n';
4
- import { generateId, type CustomKeybinding } from '../../../shared/types';
5
-
6
- export interface UISlice {
7
- sidebarVisible: boolean;
8
- toggleSidebar: () => void;
9
- setSidebarVisible: (visible: boolean) => void;
10
-
11
- notificationPanelVisible: boolean;
12
- toggleNotificationPanel: () => void;
13
- setNotificationPanelVisible: (visible: boolean) => void;
14
-
15
- commandPaletteVisible: boolean;
16
- toggleCommandPalette: () => void;
17
- setCommandPaletteVisible: (visible: boolean) => void;
18
-
19
- settingsPanelVisible: boolean;
20
- toggleSettingsPanel: () => void;
21
- setSettingsPanelVisible: (visible: boolean) => void;
22
-
23
- notificationSoundEnabled: boolean;
24
- toggleNotificationSound: () => void;
25
- setNotificationSoundEnabled: (enabled: boolean) => void;
26
-
27
- locale: Locale;
28
- setLocale: (locale: Locale) => void;
29
-
30
- viCopyModeActive: boolean;
31
- setViCopyModeActive: (active: boolean) => void;
32
-
33
- searchBarVisible: boolean;
34
- toggleSearchBar: () => void;
35
- setSearchBarVisible: (visible: boolean) => void;
36
-
37
- // ─── Terminal settings ───────────────────────────────────────────────────
38
- terminalFontSize: number;
39
- setTerminalFontSize: (size: number) => void;
40
-
41
- terminalFontFamily: string;
42
- setTerminalFontFamily: (family: string) => void;
43
-
44
- defaultShell: string;
45
- setDefaultShell: (shell: string) => void;
46
-
47
- scrollbackLines: number;
48
- setScrollbackLines: (lines: number) => void;
49
-
50
- // ─── Theme ──────────────────────────────────────────────────────────────
51
- theme: string;
52
- setTheme: (theme: string) => void;
53
-
54
- // ─── Layout ────────────────────────────────────────────────────────────
55
- sidebarPosition: 'left' | 'right';
56
- setSidebarPosition: (position: 'left' | 'right') => void;
57
-
58
- // ─── Toast / ring notification UI ────────────────────────────────────────
59
- toastEnabled: boolean;
60
- setToastEnabled: (enabled: boolean) => void;
61
-
62
- notificationRingEnabled: boolean;
63
- setNotificationRingEnabled: (enabled: boolean) => void;
64
-
65
- // ─── Custom keybindings ──────────────────────────────────────────────
66
- customKeybindings: CustomKeybinding[];
67
- addKeybinding: (kb: Omit<CustomKeybinding, 'id'>) => void;
68
- updateKeybinding: (id: string, kb: Partial<Omit<CustomKeybinding, 'id'>>) => void;
69
- removeKeybinding: (id: string) => void;
70
-
71
- }
72
-
73
- export const createUISlice: StateCreator<StoreState, [['zustand/immer', never]], [], UISlice> = (set) => ({
74
- // ─── Sidebar ─────────────────────────────────────────────────────────────
75
- sidebarVisible: true,
76
-
77
- toggleSidebar: () => set((state) => {
78
- state.sidebarVisible = !state.sidebarVisible;
79
- }),
80
-
81
- setSidebarVisible: (visible) => set((state) => {
82
- state.sidebarVisible = visible;
83
- }),
84
-
85
- // ─── Notification panel ──────────────────────────────────────────────────
86
- notificationPanelVisible: false,
87
-
88
- toggleNotificationPanel: () => set((state) => {
89
- state.notificationPanelVisible = !state.notificationPanelVisible;
90
- if (state.notificationPanelVisible) {
91
- state.commandPaletteVisible = false;
92
- state.settingsPanelVisible = false;
93
- }
94
- }),
95
-
96
- setNotificationPanelVisible: (visible) => set((state) => {
97
- state.notificationPanelVisible = visible;
98
- }),
99
-
100
- // ─── Command palette ─────────────────────────────────────────────────────
101
- commandPaletteVisible: false,
102
-
103
- toggleCommandPalette: () => set((state) => {
104
- state.commandPaletteVisible = !state.commandPaletteVisible;
105
- if (state.commandPaletteVisible) {
106
- state.notificationPanelVisible = false;
107
- state.settingsPanelVisible = false;
108
- }
109
- }),
110
-
111
- setCommandPaletteVisible: (visible) => set((state) => {
112
- state.commandPaletteVisible = visible;
113
- }),
114
-
115
- // ─── Settings panel ──────────────────────────────────────────────────────
116
- settingsPanelVisible: false,
117
-
118
- toggleSettingsPanel: () => set((state) => {
119
- state.settingsPanelVisible = !state.settingsPanelVisible;
120
- if (state.settingsPanelVisible) {
121
- state.commandPaletteVisible = false;
122
- state.notificationPanelVisible = false;
123
- }
124
- }),
125
-
126
- setSettingsPanelVisible: (visible) => set((state) => {
127
- state.settingsPanelVisible = visible;
128
- }),
129
-
130
- // ─── Notification sound ──────────────────────────────────────────────────
131
- notificationSoundEnabled: true,
132
-
133
- toggleNotificationSound: () => set((state) => {
134
- state.notificationSoundEnabled = !state.notificationSoundEnabled;
135
- }),
136
-
137
- setNotificationSoundEnabled: (enabled) => set((state) => {
138
- state.notificationSoundEnabled = enabled;
139
- }),
140
-
141
- // ─── Locale / i18n ───────────────────────────────────────────────────────
142
- locale: 'en',
143
-
144
- setLocale: (locale) => {
145
- // Sync i18n module state immediately (outside immer — pure function call)
146
- i18nSetLocale(locale);
147
- set((state) => {
148
- state.locale = locale;
149
- });
150
- },
151
-
152
- // ─── VI copy mode ─────────────────────────────────────────────────────────
153
- viCopyModeActive: false,
154
-
155
- setViCopyModeActive: (active) => set((state) => {
156
- state.viCopyModeActive = active;
157
- }),
158
-
159
- // ─── Search bar ───────────────────────────────────────────────────────────
160
- searchBarVisible: false,
161
-
162
- toggleSearchBar: () => set((state) => {
163
- state.searchBarVisible = !state.searchBarVisible;
164
- }),
165
-
166
- setSearchBarVisible: (visible) => set((state) => {
167
- state.searchBarVisible = visible;
168
- }),
169
-
170
- // ─── Terminal settings ───────────────────────────────────────────────────
171
- terminalFontSize: 14,
172
-
173
- setTerminalFontSize: (size) => set((state) => {
174
- state.terminalFontSize = size;
175
- }),
176
-
177
- terminalFontFamily: 'Cascadia Code',
178
-
179
- setTerminalFontFamily: (family) => set((state) => {
180
- state.terminalFontFamily = family;
181
- }),
182
-
183
- defaultShell: 'powershell',
184
-
185
- setDefaultShell: (shell) => set((state) => {
186
- state.defaultShell = shell;
187
- }),
188
-
189
- scrollbackLines: 10000,
190
-
191
- setScrollbackLines: (lines) => set((state) => {
192
- state.scrollbackLines = lines;
193
- }),
194
-
195
- // ─── Theme ──────────────────────────────────────────────────────────────
196
- theme: 'catppuccin',
197
-
198
- setTheme: (theme) => {
199
- document.documentElement.setAttribute('data-theme', theme);
200
- set((state) => {
201
- state.theme = theme;
202
- });
203
- },
204
-
205
- // ─── Layout ────────────────────────────────────────────────────────────
206
- sidebarPosition: 'left',
207
-
208
- setSidebarPosition: (position) => set((state) => {
209
- state.sidebarPosition = position;
210
- }),
211
-
212
- // ─── Toast / ring notification UI ────────────────────────────────────────
213
- toastEnabled: true,
214
-
215
- setToastEnabled: (enabled) => {
216
- window.electronAPI.settings.setToastEnabled(enabled);
217
- set((state) => {
218
- state.toastEnabled = enabled;
219
- });
220
- },
221
-
222
- notificationRingEnabled: true,
223
-
224
- setNotificationRingEnabled: (enabled) => set((state) => {
225
- state.notificationRingEnabled = enabled;
226
- }),
227
-
228
- // ─── Custom keybindings ──────────────────────────────────────────────
229
- customKeybindings: [],
230
-
231
- addKeybinding: (kb) => set((state) => {
232
- state.customKeybindings.push({
233
- id: generateId('kb'),
234
- ...kb,
235
- });
236
- }),
237
-
238
- updateKeybinding: (id, updates) => set((state) => {
239
- const idx = state.customKeybindings.findIndex((k) => k.id === id);
240
- if (idx !== -1) Object.assign(state.customKeybindings[idx], updates);
241
- }),
242
-
243
- removeKeybinding: (id) => set((state) => {
244
- state.customKeybindings = state.customKeybindings.filter((k) => k.id !== id);
245
- }),
246
-
247
- });
@@ -1,120 +0,0 @@
1
- import type { StateCreator } from 'zustand';
2
- import type { StoreState } from '../index';
3
- import { createWorkspace, type Pane, type SessionData, type Workspace, type WorkspaceMetadata } from '../../../shared/types';
4
- import { setLocale as i18nSetLocale, type Locale } from '../../i18n';
5
-
6
- export interface WorkspaceSlice {
7
- workspaces: Workspace[];
8
- activeWorkspaceId: string;
9
- addWorkspace: (name?: string) => void;
10
- removeWorkspace: (id: string) => void;
11
- setActiveWorkspace: (id: string) => void;
12
- renameWorkspace: (id: string, name: string) => void;
13
- updateWorkspaceMetadata: (id: string, metadata: Partial<WorkspaceMetadata>) => void;
14
- reorderWorkspace: (fromIndex: number, toIndex: number) => void;
15
- loadSession: (data: SessionData) => void;
16
- }
17
-
18
- export const createWorkspaceSlice: StateCreator<StoreState, [['zustand/immer', never]], [], WorkspaceSlice> = (set) => {
19
- const initial = createWorkspace('Workspace 1');
20
- return {
21
- workspaces: [initial],
22
- activeWorkspaceId: initial.id,
23
-
24
- addWorkspace: (name) => set((state: StoreState) => {
25
- const ws = createWorkspace(name || `Workspace ${state.workspaces.length + 1}`);
26
- state.workspaces.push(ws);
27
- state.activeWorkspaceId = ws.id;
28
- }),
29
-
30
- // NOTE: PTY cleanup is the caller's responsibility (see Sidebar.handleClose, useKeyboard Ctrl+Shift+W)
31
- removeWorkspace: (id) => set((state: StoreState) => {
32
- if (state.workspaces.length <= 1) return;
33
- const idx = state.workspaces.findIndex((w: Workspace) => w.id === id);
34
- if (idx === -1) return;
35
- state.workspaces.splice(idx, 1);
36
- if (state.activeWorkspaceId === id) {
37
- state.activeWorkspaceId = state.workspaces[Math.min(idx, state.workspaces.length - 1)].id;
38
- }
39
- }),
40
-
41
- setActiveWorkspace: (id) => set((state: StoreState) => {
42
- if (state.workspaces.some((w: Workspace) => w.id === id)) {
43
- state.activeWorkspaceId = id;
44
- }
45
- }),
46
-
47
- renameWorkspace: (id, name) => set((state: StoreState) => {
48
- const ws = state.workspaces.find((w: Workspace) => w.id === id);
49
- if (ws) ws.name = name;
50
- }),
51
-
52
- updateWorkspaceMetadata: (id, metadata) => set((state: StoreState) => {
53
- const ws = state.workspaces.find((w: Workspace) => w.id === id);
54
- if (ws) {
55
- if (!ws.metadata) ws.metadata = {};
56
- Object.assign(ws.metadata, metadata);
57
- }
58
- }),
59
-
60
- reorderWorkspace: (fromIndex, toIndex) => set((state: StoreState) => {
61
- if (fromIndex === toIndex) return;
62
- if (fromIndex < 0 || fromIndex >= state.workspaces.length) return;
63
- if (toIndex < 0 || toIndex >= state.workspaces.length) return;
64
- const [removed] = state.workspaces.splice(fromIndex, 1);
65
- state.workspaces.splice(toIndex, 0, removed);
66
- }),
67
-
68
- loadSession: (data: SessionData) => set((state: StoreState) => {
69
- if (!data.workspaces || data.workspaces.length === 0) return;
70
-
71
- // Security: sanitize surfaces — clear ptyIds and block dangerous URLs
72
- const BLOCKED_URL_SCHEMES = ['javascript:', 'data:', 'vbscript:', 'file:'];
73
- const sanitizePanes = (pane: Pane) => {
74
- if (pane.type === 'leaf') {
75
- for (const s of pane.surfaces) {
76
- if (s.surfaceType !== 'browser') {
77
- s.ptyId = '';
78
- }
79
- // Strip dangerous browserUrl schemes that could execute code on load
80
- if (s.browserUrl) {
81
- const normalized = s.browserUrl.trim().toLowerCase();
82
- if (BLOCKED_URL_SCHEMES.some((scheme) => normalized.startsWith(scheme))) {
83
- s.browserUrl = 'about:blank';
84
- }
85
- }
86
- }
87
- } else {
88
- for (const child of pane.children) sanitizePanes(child);
89
- }
90
- };
91
- for (const ws of data.workspaces) sanitizePanes(ws.rootPane);
92
-
93
- state.workspaces = data.workspaces;
94
- state.activeWorkspaceId = data.activeWorkspaceId;
95
- state.sidebarVisible = data.sidebarVisible;
96
-
97
- // Restore user preferences
98
- if (data.theme) {
99
- state.theme = data.theme;
100
- document.documentElement.setAttribute('data-theme', data.theme);
101
- }
102
- if (data.locale) {
103
- state.locale = data.locale as Locale;
104
- i18nSetLocale(data.locale as Locale);
105
- }
106
- if (data.terminalFontSize != null) state.terminalFontSize = data.terminalFontSize;
107
- if (data.terminalFontFamily) state.terminalFontFamily = data.terminalFontFamily;
108
- if (data.defaultShell) state.defaultShell = data.defaultShell;
109
- if (data.scrollbackLines != null) state.scrollbackLines = data.scrollbackLines;
110
- if (data.sidebarPosition) state.sidebarPosition = data.sidebarPosition;
111
- if (data.notificationSoundEnabled != null) state.notificationSoundEnabled = data.notificationSoundEnabled;
112
- if (data.toastEnabled != null) {
113
- state.toastEnabled = data.toastEnabled;
114
- window.electronAPI.settings.setToastEnabled(data.toastEnabled);
115
- }
116
- if (data.notificationRingEnabled != null) state.notificationRingEnabled = data.notificationRingEnabled;
117
- if (data.customKeybindings) state.customKeybindings = data.customKeybindings;
118
- }),
119
- };
120
- };
@@ -1,150 +0,0 @@
1
- @tailwind base;
2
- @tailwind components;
3
- @tailwind utilities;
4
-
5
- /* ─── Theme CSS Variables ────────────────────────────────────────────────── */
6
-
7
- :root, [data-theme="catppuccin"] {
8
- --bg-base: #1e1e2e;
9
- --bg-mantle: #181825;
10
- --bg-surface: #313244;
11
- --bg-overlay: #45475a;
12
- --text-muted: #585b70;
13
- --text-subtle: #6c7086;
14
- --text-sub: #bac2de;
15
- --text-sub2: #a6adc8;
16
- --text-main: #cdd6f4;
17
- --accent-cursor: #f5e0dc;
18
- --accent-blue: #89b4fa;
19
- --accent-green: #a6e3a1;
20
- --accent-red: #f38ba8;
21
- --accent-yellow: #f9e2af;
22
- --accent-pink: #f5c2e7;
23
- --accent-teal: #94e2d5;
24
- --accent-purple: #cba6f7;
25
- /* RGB variants for opacity usage */
26
- --accent-blue-rgb: 137, 180, 250;
27
- --bg-surface-rgb: 49, 52, 68;
28
- --bg-base-rgb: 30, 30, 46;
29
- }
30
-
31
- [data-theme="monochrome"] {
32
- --bg-base: #080808;
33
- --bg-mantle: #050505;
34
- --bg-surface: #1c1c1c;
35
- --bg-overlay: #2e2e2e;
36
- --text-muted: #555555;
37
- --text-subtle: #777777;
38
- --text-sub: #aaaaaa;
39
- --text-sub2: #999999;
40
- --text-main: #e0e0e0;
41
- --accent-cursor: #ffffff;
42
- --accent-blue: #b0b0b0;
43
- --accent-green: #d0d0d0;
44
- --accent-red: #ff5555;
45
- --accent-yellow: #cccccc;
46
- --accent-pink: #c0c0c0;
47
- --accent-teal: #b8b8b8;
48
- --accent-purple: #b8b8b8;
49
- --accent-blue-rgb: 176, 176, 176;
50
- --bg-surface-rgb: 28, 28, 28;
51
- --bg-base-rgb: 8, 8, 8;
52
- }
53
-
54
- [data-theme="claude"] {
55
- --bg-base: #F5F0E8;
56
- --bg-mantle: #EDE6D9;
57
- --bg-surface: #E0D8CA;
58
- --bg-overlay: #D5CCBC;
59
- --text-muted: #B8A898;
60
- --text-subtle: #9A8C7C;
61
- --text-sub: #6B5D4F;
62
- --text-sub2: #7A6E60;
63
- --text-main: #3D3429;
64
- --accent-cursor: #3D3429;
65
- --accent-blue: #DA7756;
66
- --accent-green: #5A8A4C;
67
- --accent-red: #C4533A;
68
- --accent-yellow: #B8912D;
69
- --accent-pink: #B5647A;
70
- --accent-teal: #4A9588;
71
- --accent-purple: #7A6AAF;
72
- --accent-blue-rgb: 218, 119, 86;
73
- --bg-surface-rgb: 224, 216, 202;
74
- --bg-base-rgb: 245, 240, 232;
75
- }
76
-
77
- /* ─── Base ────────────────────────────────────────────────────────────────── */
78
-
79
- * {
80
- margin: 0;
81
- padding: 0;
82
- box-sizing: border-box;
83
- }
84
-
85
- html, body, #root {
86
- height: 100%;
87
- width: 100%;
88
- overflow: hidden;
89
- background-color: var(--bg-base);
90
- color: var(--text-main);
91
- font-family: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
92
- }
93
-
94
- /* Custom scrollbar */
95
- ::-webkit-scrollbar {
96
- width: 6px;
97
- height: 6px;
98
- }
99
- ::-webkit-scrollbar-track {
100
- background: transparent;
101
- }
102
- ::-webkit-scrollbar-thumb {
103
- background: var(--bg-surface);
104
- border-radius: 3px;
105
- }
106
- ::-webkit-scrollbar-thumb:hover {
107
- background: var(--bg-overlay);
108
- }
109
- ::-webkit-scrollbar-corner {
110
- background: transparent;
111
- }
112
-
113
- /* Notification ring pulse on inactive panes with unread notifications */
114
- @keyframes notification-ring-pulse {
115
- 0%, 100% { box-shadow: 0 0 0 0 rgba(var(--accent-blue-rgb), 0.4); }
116
- 50% { box-shadow: 0 0 0 3px rgba(var(--accent-blue-rgb), 0.2); }
117
- }
118
-
119
- .notification-ring {
120
- animation: notification-ring-pulse 2s ease-in-out infinite;
121
- }
122
-
123
- /* Notification panel slide-in */
124
- @keyframes notification-slide-in {
125
- from { transform: translateX(100%); }
126
- to { transform: translateX(0); }
127
- }
128
-
129
- .notification-panel-enter {
130
- animation: notification-slide-in 0.2s ease-out;
131
- }
132
-
133
- /* Pane flash highlight — Ctrl+Shift+H */
134
- @keyframes pane-flash {
135
- 0% { opacity: 0; }
136
- 15% { opacity: 0.35; }
137
- 70% { opacity: 0.25; }
138
- 100% { opacity: 0; }
139
- }
140
-
141
- .pane-flash::after {
142
- content: '';
143
- position: absolute;
144
- inset: 0;
145
- border-radius: 2px;
146
- background: var(--accent-blue);
147
- pointer-events: none;
148
- animation: pane-flash 0.5s ease-out forwards;
149
- z-index: 100;
150
- }
@@ -1,99 +0,0 @@
1
- export type ThemeId = 'catppuccin' | 'monochrome' | 'claude';
2
-
3
- export interface XtermThemeColors {
4
- background: string;
5
- foreground: string;
6
- cursor: string;
7
- selectionBackground: string;
8
- black: string;
9
- red: string;
10
- green: string;
11
- yellow: string;
12
- blue: string;
13
- magenta: string;
14
- cyan: string;
15
- white: string;
16
- brightBlack: string;
17
- brightRed: string;
18
- brightGreen: string;
19
- brightYellow: string;
20
- brightBlue: string;
21
- brightMagenta: string;
22
- brightCyan: string;
23
- brightWhite: string;
24
- }
25
-
26
- export const XTERM_THEMES: Record<ThemeId, XtermThemeColors> = {
27
- catppuccin: {
28
- background: '#1e1e2e',
29
- foreground: '#cdd6f4',
30
- cursor: '#f5e0dc',
31
- selectionBackground: '#585b70',
32
- black: '#45475a',
33
- red: '#f38ba8',
34
- green: '#a6e3a1',
35
- yellow: '#f9e2af',
36
- blue: '#89b4fa',
37
- magenta: '#f5c2e7',
38
- cyan: '#94e2d5',
39
- white: '#bac2de',
40
- brightBlack: '#585b70',
41
- brightRed: '#f38ba8',
42
- brightGreen: '#a6e3a1',
43
- brightYellow: '#f9e2af',
44
- brightBlue: '#89b4fa',
45
- brightMagenta: '#f5c2e7',
46
- brightCyan: '#94e2d5',
47
- brightWhite: '#a6adc8',
48
- },
49
- monochrome: {
50
- background: '#080808',
51
- foreground: '#e0e0e0',
52
- cursor: '#ffffff',
53
- selectionBackground: '#333333',
54
- black: '#2e2e2e',
55
- red: '#ff5555',
56
- green: '#d0d0d0',
57
- yellow: '#cccccc',
58
- blue: '#b0b0b0',
59
- magenta: '#c0c0c0',
60
- cyan: '#b8b8b8',
61
- white: '#aaaaaa',
62
- brightBlack: '#555555',
63
- brightRed: '#ff5555',
64
- brightGreen: '#e0e0e0',
65
- brightYellow: '#dddddd',
66
- brightBlue: '#c0c0c0',
67
- brightMagenta: '#d0d0d0',
68
- brightCyan: '#c8c8c8',
69
- brightWhite: '#999999',
70
- },
71
- claude: {
72
- background: '#F5F0E8',
73
- foreground: '#3D3429',
74
- cursor: '#3D3429',
75
- selectionBackground: '#D5CCBC',
76
- black: '#3D3429',
77
- red: '#C4533A',
78
- green: '#5A8A4C',
79
- yellow: '#B8912D',
80
- blue: '#DA7756',
81
- magenta: '#B5647A',
82
- cyan: '#4A9588',
83
- white: '#EDE6D9',
84
- brightBlack: '#9A8C7C',
85
- brightRed: '#CF6659',
86
- brightGreen: '#7DAA6E',
87
- brightYellow: '#D4A84B',
88
- brightBlue: '#E08A6A',
89
- brightMagenta: '#C97A8D',
90
- brightCyan: '#6AAB9E',
91
- brightWhite: '#F5F0E8',
92
- },
93
- };
94
-
95
- export const THEME_OPTIONS: Array<{ value: ThemeId; label: string }> = [
96
- { value: 'catppuccin', label: 'Catppuccin Mocha' },
97
- { value: 'monochrome', label: 'Monochrome' },
98
- { value: 'claude', label: 'Claude' },
99
- ];
@@ -1,53 +0,0 @@
1
- // IPC Channel names
2
- export const IPC = {
3
- PTY_CREATE: 'pty:create',
4
- PTY_WRITE: 'pty:write',
5
- PTY_RESIZE: 'pty:resize',
6
- PTY_DISPOSE: 'pty:dispose',
7
- PTY_DATA: 'pty:data',
8
- PTY_EXIT: 'pty:exit',
9
- SHELL_LIST: 'shell:list',
10
- SESSION_SAVE: 'session:save',
11
- SESSION_LOAD: 'session:load',
12
- NOTIFICATION: 'notification:new',
13
- CWD_CHANGED: 'notification:cwd-changed',
14
- METADATA_UPDATE: 'metadata:update',
15
- METADATA_REQUEST: 'metadata:request',
16
- // Phase 3: RPC bridge (Main ↔ Renderer)
17
- RPC_COMMAND: 'rpc:command',
18
- RPC_RESPONSE: 'rpc:response',
19
- // Clipboard (main process bridge)
20
- CLIPBOARD_WRITE: 'clipboard:write',
21
- CLIPBOARD_READ: 'clipboard:read',
22
- // Phase 4: Auto updater
23
- UPDATE_CHECK: 'update:check',
24
- UPDATE_AVAILABLE: 'update:available',
25
- UPDATE_NOT_AVAILABLE: 'update:not-available',
26
- UPDATE_ERROR: 'update:error',
27
- UPDATE_DOWNLOAD: 'update:download',
28
- UPDATE_INSTALL: 'update:install',
29
- // Settings sync (renderer → main)
30
- TOAST_ENABLED: 'settings:toast-enabled',
31
- } as const;
32
-
33
- // Named Pipe path for wmux API
34
- // Fixed name so MCP clients (e.g. Claude Code) can reconnect across wmux restarts
35
- export const PIPE_NAME = '\\\\.\\pipe\\wmux';
36
-
37
- export function getPipeName(): string {
38
- return PIPE_NAME;
39
- }
40
-
41
- // Environment variable names injected into PTY sessions
42
- export const ENV_KEYS = {
43
- WORKSPACE_ID: 'WMUX_WORKSPACE_ID',
44
- SURFACE_ID: 'WMUX_SURFACE_ID',
45
- SOCKET_PATH: 'WMUX_SOCKET_PATH',
46
- AUTH_TOKEN: 'WMUX_AUTH_TOKEN',
47
- } as const;
48
-
49
- // Auth token file path — written by wmux main process, read by MCP server
50
- export function getAuthTokenPath(): string {
51
- const home = process.env.USERPROFILE || process.env.HOME || '';
52
- return `${home}/.wmux-auth-token`;
53
- }
@@ -1,11 +0,0 @@
1
- import type { ElectronAPI } from '../preload/index';
2
-
3
- declare global {
4
- interface Window {
5
- electronAPI: ElectronAPI;
6
- clipboardAPI: {
7
- writeText: (text: string) => Promise<void>;
8
- readText: () => Promise<string>;
9
- };
10
- }
11
- }