zerogterm 0.4.0-alpha.1 → 0.6.0-alpha.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.
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Stephen Phillips
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Stephen Phillips
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,153 +1,193 @@
1
- # ZeroG Terminal
2
-
3
- ZeroG Terminal is an Electron workspace manager for persistent terminal and SSH sessions on Linux and Windows, with smart features to help keep you productive. It is designed with AI tooling in mind: leave Codex, Claude Code, or other terminal-based agents running in persistent sessions, then return to them without repeating setup and resume commands.
4
-
5
- ZeroG Terminal is an alpha project, but it is already useful as a multi-session terminal and SSH workspace. It uses `screen` where available for resumable sessions and falls back to a direct shell PTY when `screen` is not installed.
6
-
7
- ## Features
8
-
9
- - Multi-pane workspaces with stack, vertical split, horizontal split, and four-pane grid layouts.
10
- - Maximize a focused pane and cycle between sessions without losing the other panes.
11
- - Local sessions powered by Bash, PowerShell, WSL, and other supported shell backends; persistent sessions use `screen` where available, with a process-only fallback when it is unavailable.
12
- - SSH sessions for hosts, `user@host`, and `user@host:port` targets.
13
- - SSH configuration discovery from known connections, including remote `screen` session discovery.
14
- - Reconnect to existing local or remote `screen` sessions from the Screens view.
15
- - Remote screen attachment that waits for SSH readiness before sending commands, including host and port-aware matching.
16
- - Session history for reconnecting to sessions after a relaunch, with bounded structured history and no stored secrets.
17
- - Workspaces for grouping sessions and quickly switching between projects or tasks.
18
- - Session overview, collapsible sidebar, keyboard shortcuts, and light/dark themes.
19
- - xterm.js terminal rendering with scrollback preservation while changing layouts.
20
- - Local voice input, either with Whisper ONNX inside the app through Transformers.js or through a transcription server on this machine; transcribed text is typed into the selected terminal without automatic execution.
21
- - A settings panel for appearance, terminal behaviour, session defaults, and speech recognition, including a built-in recognition test.
22
- - AI command suggestion and approval UI, keeping command execution explicit.
23
- - Sandboxed Electron renderer, context isolation, disabled Node integration, and a narrow typed preload API.
24
- - Safe argument-array handling and validation around SSH and `screen` session operations.
25
-
26
- The project is particularly useful for terminal-based AI development workflows: start an agent in a persistent session, disconnect or suffer an interrupted connection, and reconnect later to see what it has done and continue working.
27
-
28
- See the project walkthrough on [YouTube](https://youtu.be/4aJZCxLHD14).
29
-
30
- ## Release status
31
-
32
- ZeroG Terminal is currently a public alpha. The current release is `0.3.0-alpha.1`; the version history is tracked in [versions.txt](versions.txt).
33
-
34
- The npm package contains the built Electron application and project documentation. It is intended for early adopters and testing rather than production use.
35
-
36
- ## Terminal shortcuts
37
-
38
- - `Ctrl+Shift+C` — copy selected terminal text
39
- - `Ctrl+Shift+V` — paste into the active terminal
40
- - `Ctrl+C` remains the interrupt signal (not copy)
41
- - `Ctrl+Shift+N` — new workspace
42
- - `Ctrl+Shift+T` new local terminal in the current workspace
43
- - `Ctrl+Shift+O` — session overview
44
- - `Ctrl+Shift+B` — toggle sessions sidebar
45
- - `Ctrl+Shift+,`settings
46
- - `Esc` — close overview / dialogs, cancel voice recording
47
-
48
- Selecting text with the mouse also copies it, and programs running inside a
49
- terminal can copy to the system clipboard themselves through the OSC 52 escape
50
- sequence this is how TUI tools such as CLI coding agents, tmux and Neovim put
51
- text on the clipboard, including over SSH. Reading the clipboard through OSC 52
52
- is refused, so a program on a remote host cannot see what you last copied.
53
-
54
- ## Settings
55
-
56
- Settings open from the gear at the bottom of the left rail, the avatar in the
57
- title bar, or `Ctrl+Shift+,`. Changes apply immediately and are remembered
58
- between launches; each page can be reset on its own.
59
-
60
- - **Appearance** theme, terminal font, size, line height and letter spacing,
61
- with a live preview. Panes restyle in place and keep their scrollback.
62
- - **Terminal** scrollback lines, cursor style and blink, and copy-on-select.
63
- - **Sessions** default shell and WSL distribution for new terminals, the
64
- layout to start in, and whether the sidebar starts collapsed.
65
- - **AI & voice** whether AI suggestions need approval before running, and
66
- whether a transcript is typed straight into the pane or shown for review
67
- first. Neither option presses Enter for you.
68
- - **Speech recognition** — engine, model and tuning, described below.
69
-
70
- ### Speech recognition
71
-
72
- Two engines are available.
73
-
74
- **Built-in** runs Whisper as ONNX inside the app through Transformers.js, with
75
- nothing else to install. Choose the model (tiny, base or small; English-only or
76
- multilingual), the weight precision, and whether to compute on CPU (WASM) or
77
- GPU (WebGPU) WebGPU falls back to WASM when it is unavailable. The panel shows
78
- the download for the chosen combination, from about 41 MB for tiny at q8 to
79
- about 968 MB for small at full precision; models are cached after first use.
80
- Multilingual models add language and transcribe/translate options, which
81
- English-only checkpoints reject and so do not show.
82
-
83
- **Local server** posts the recorded audio as a WAV file to a transcription
84
- server on this machine, using the OpenAI `/v1/audio/transcriptions` shape that
85
- whisper.cpp's server, LM Studio, faster-whisper-server and similar tools speak.
86
- This is the way to use a model the built-in engine cannot load — a GGUF build
87
- such as `unslothai/Qwen3-ASR-0.6B-GGUF` needs a llama.cpp-family runtime, so
88
- something else has to host it. The URL must be on this machine; a non-loopback
89
- address is refused rather than sent.
90
-
91
- Both engines share the maximum utterance length and the silence threshold, and
92
- the **Try it** button on that page records a phrase and shows the transcript,
93
- the recording level and how long transcription took, without typing into a
94
- terminal. It transcribes even below the silence threshold and says so, which is
95
- how the threshold gets tuned for a particular microphone.
96
-
97
- ## Installation and usage
98
-
99
- The simplest way to try the published package is through `npx`:
100
-
101
- ```bash
102
- npx zerogterm
103
- ```
104
-
105
- The package downloads the application and launches it. To use the launcher repeatedly without downloading on each invocation, install it globally:
106
-
107
- ```bash
108
- npm install --global zerogterm
109
- zerogterm
110
- ```
111
-
112
- ## Development
113
-
114
- ```bash
115
- npm install
116
- npm run typecheck
117
- npm test
118
- npm run build
119
- npm start
120
- ```
121
-
122
- Runtime prerequisites on the host include Node.js and the native build tools required by `node-pty`. Install `screen` as well for persistent, discoverable sessions.
123
-
124
- On Fedora/RHEL-like Linux systems:
125
-
126
- ```bash
127
- sudo dnf install screen make gcc-c++ python3
128
- ```
129
-
130
- On Windows, use a supported Node.js installation and choose PowerShell or WSL when creating a local session. WSL distributions can be selected from the local-session dialog. Remote SSH sessions work independently of the local shell backend.
131
-
132
- `node-pty` is required for terminal I/O. When `screen` is installed, local sessions are persistent and discoverable after relaunch. Without `screen`, ZeroG falls back to a direct shell PTY and labels the session as process-only; that shell is lost when the application exits. Install `screen` for full persistence:
133
-
134
- ```bash
135
- sudo dnf install screen
136
- ```
137
-
138
- ## Verification
139
-
140
- The current main branch has the following local verification coverage:
141
-
142
- - `npm run typecheck`: passes.
143
- - `npm test`: passes (28 tests covering remote-screen parsing and prompt readiness, session history, SSH inventory and argument validation, session service behavior, and voice input helpers).
144
- - `npm run build`: passes and writes `dist/main` plus `dist/renderer`.
145
- - `npm audit --omit=dev`: production dependency auditing is part of the project quality checks.
146
-
147
- ## License
148
-
149
- ZeroG Terminal is released under the MIT License. See [LICENSE](LICENSE).
150
-
151
- ## Contributing and security
152
-
153
- See [CONTRIBUTING.md](CONTRIBUTING.md) for development, testing, and pull-request guidance. Please report security vulnerabilities privately through GitHub; see [SECURITY.md](SECURITY.md).
1
+ # ZeroG Terminal
2
+
3
+ ZeroG Terminal is an Electron workspace manager for persistent terminal and SSH sessions on Linux and Windows, with smart features to help keep you productive. It is designed with AI tooling in mind: leave Codex, Claude Code, or other terminal-based agents running in persistent sessions, then return to them without repeating setup and resume commands.
4
+
5
+ ZeroG Terminal is an alpha project, but it is already useful as a multi-session terminal and SSH workspace. It uses `screen` where available for resumable sessions and falls back to a direct shell PTY when `screen` is not installed.
6
+
7
+ ## Features
8
+
9
+ - Multi-pane workspaces with stack, vertical split, horizontal split, and four-pane grid layouts.
10
+ - Draggable dividers between panes and beside the sidebar, so a split does not have to be an even one. Sizes are remembered between launches.
11
+ - Maximize a focused pane and cycle between sessions without losing the other panes.
12
+ - Local sessions powered by Bash, PowerShell, WSL, and other supported shell backends; persistent sessions use `screen` where available, with a process-only fallback when it is unavailable.
13
+ - SSH sessions for hosts, `user@host`, and `user@host:port` targets.
14
+ - SSH configuration discovery from known connections, including remote `screen` session discovery.
15
+ - Reconnect to existing local or remote `screen` sessions from the Screens view.
16
+ - Remote screen attachment that waits for SSH readiness before sending commands, including host and port-aware matching.
17
+ - Session history for reconnecting to sessions after a relaunch, with bounded structured history and no stored secrets.
18
+ - Workspaces for grouping sessions and quickly switching between projects or tasks.
19
+ - Session overview, collapsible sidebar, keyboard shortcuts, and light/dark themes.
20
+ - xterm.js terminal rendering with scrollback preservation while changing layouts.
21
+ - Local voice input, either with Whisper ONNX inside the app through Transformers.js or through a transcription server on this machine; transcribed text is typed into the selected terminal without automatic execution.
22
+ - A per-pane proceed button that sends a configurable phrase — `OK, proceed` by default — for waving an agent on without typing the same reply again.
23
+ - A settings panel for appearance, terminal behaviour, session defaults, and speech recognition, including a built-in recognition test.
24
+ - AI command suggestion and approval UI, keeping command execution explicit.
25
+ - Sandboxed Electron renderer, context isolation, disabled Node integration, and a narrow typed preload API.
26
+ - Safe argument-array handling and validation around SSH and `screen` session operations.
27
+
28
+ The project is particularly useful for terminal-based AI development workflows: start an agent in a persistent session, disconnect or suffer an interrupted connection, and reconnect later to see what it has done and continue working.
29
+
30
+ See the project walkthrough on [YouTube](https://youtu.be/4aJZCxLHD14).
31
+
32
+ ## Release status
33
+
34
+ ZeroG Terminal is currently a public alpha. The current release is `0.5.0-alpha.1`; the version history is tracked in [versions.txt](versions.txt).
35
+
36
+ The npm package contains the built Electron application and project documentation. It is intended for early adopters and testing rather than production use.
37
+
38
+ ## Terminal shortcuts
39
+
40
+ - `Ctrl+Shift+C` copy selected terminal text
41
+ - `Ctrl+Shift+V` — paste into the active terminal
42
+ - `Ctrl+C` remains the interrupt signal (not copy)
43
+ - `Ctrl+Shift+N` — new workspace
44
+ - `Ctrl+Shift+T` — new local terminal in the current workspace
45
+ - `Ctrl+Shift+O`session overview
46
+ - `Ctrl+Shift+B` — toggle sessions sidebar
47
+ - `Ctrl+Shift+,` — settings
48
+ - `Esc` close overview / dialogs, cancel voice recording
49
+
50
+ Selecting text with the mouse also copies it, and programs running inside a
51
+ terminal can copy to the system clipboard themselves through the OSC 52 escape
52
+ sequence this is how TUI tools such as CLI coding agents, tmux and Neovim put
53
+ text on the clipboard, including over SSH. Reading the clipboard through OSC 52
54
+ is refused, so a program on a remote host cannot see what you last copied.
55
+
56
+ ## Resizing panes and the sidebar
57
+
58
+ Drag the line between two panes, or the sidebar's right edge, to change how the
59
+ space is shared. Sizes are remembered between launches and clamped so that no
60
+ pane can be dragged down to nothing.
61
+
62
+ The dividers take keyboard focus as well: the arrow keys nudge one two percent at
63
+ a time, and Enter or a double-click puts it back in the middle. One divider
64
+ position is shared by every layout, so a split you set up in the vertical split
65
+ is the same split you get in the four-pane grid.
66
+
67
+ ## Settings
68
+
69
+ Settings open from the gear at the bottom of the left rail, the avatar in the
70
+ title bar, or `Ctrl+Shift+,`. Changes apply immediately and are remembered
71
+ between launches; each page can be reset on its own.
72
+
73
+ - **Appearance** — theme, terminal font, size, line height and letter spacing,
74
+ with a live preview. Panes restyle in place and keep their scrollback.
75
+ - **Terminal** scrollback lines, cursor style and blink, and copy-on-select.
76
+ - **Sessions** default shell and WSL distribution for new terminals, the
77
+ layout to start in, and whether the sidebar starts collapsed.
78
+ - **AI & voice** whether AI suggestions need approval before running, and
79
+ whether a transcript is typed straight into the pane or shown for review
80
+ first. Neither option presses Enter for you. Also the phrase the pane's
81
+ proceed button sends, described below.
82
+ - **Speech recognition** — engine, model and tuning, described below.
83
+
84
+ ### Proceed button
85
+
86
+ Each pane's title bar carries a tick beside the microphone. Clicking it sends
87
+ `OK, proceed` and presses Enter for the common case of an AI coding agent
88
+ pausing to ask whether it should carry on. The phrase is editable under
89
+ **Settings AI & voice**, so an agent that responds better to different wording
90
+ can have it.
91
+
92
+ This is the one control that presses Enter for you; voice transcripts and AI
93
+ suggestions deliberately do not. It sends to the pane it belongs to, so a pane
94
+ sitting at a shell prompt rather than in an agent will simply try to run the
95
+ phrase as a command.
96
+
97
+ ### Speech recognition
98
+
99
+ Two engines are available.
100
+
101
+ **Built-in** runs Whisper as ONNX inside the app through Transformers.js, with
102
+ nothing else to install. Choose the model (tiny, base or small; English-only or
103
+ multilingual), the weight precision, and whether to compute on CPU (WASM) or
104
+ GPU (WebGPU) — WebGPU falls back to WASM when it is unavailable. The panel shows
105
+ the download for the chosen combination, from about 41 MB for tiny at q8 to
106
+ about 968 MB for small at full precision; models are cached after first use.
107
+ Multilingual models add language and transcribe/translate options, which
108
+ English-only checkpoints reject and so do not show.
109
+
110
+ **Local server** posts the recorded audio as a WAV file to a transcription
111
+ server on this machine, using the OpenAI `/v1/audio/transcriptions` shape that
112
+ whisper.cpp's server, LM Studio, faster-whisper-server and similar tools speak.
113
+ This is the way to use a model the built-in engine cannot load — a GGUF build
114
+ such as `unslothai/Qwen3-ASR-0.6B-GGUF` needs a llama.cpp-family runtime, so
115
+ something else has to host it. The URL must be on this machine; a non-loopback
116
+ address is refused rather than sent.
117
+
118
+ Both engines share the maximum utterance length and the silence threshold, and
119
+ the **Try it** button on that page records a phrase and shows the transcript,
120
+ the recording level and how long transcription took, without typing into a
121
+ terminal. It transcribes even below the silence threshold and says so, which is
122
+ how the threshold gets tuned for a particular microphone.
123
+
124
+ ## Installation and usage
125
+
126
+ The simplest way to try the published package is through `npx`:
127
+
128
+ ```bash
129
+ npx zerogterm
130
+ ```
131
+
132
+ The package downloads the application and launches it. To use the launcher repeatedly without downloading on each invocation, install it globally:
133
+
134
+ ```bash
135
+ npm install --global zerogterm
136
+ zerogterm
137
+ ```
138
+
139
+ ## Development
140
+
141
+ ```bash
142
+ npm install
143
+ npm run typecheck
144
+ npm test
145
+ npm run build
146
+ npm start
147
+ ```
148
+
149
+ Node.js is the only prerequisite every host needs. The scripts above run on Linux
150
+ and Windows; npm runs them through `cmd.exe` on Windows, so no POSIX shell is
151
+ required whichever shell you start them from.
152
+
153
+ `node-pty` provides terminal I/O on every platform. It ships prebuilt binaries
154
+ for Windows and macOS, so a C/C++ toolchain is a Linux requirement rather than a
155
+ general one — there, `npm install` compiles it.
156
+
157
+ ### Linux
158
+
159
+ ```bash
160
+ sudo dnf install screen make gcc-c++ python3
161
+ ```
162
+
163
+ `make`, `gcc-c++` and `python3` build `node-pty`. `screen` is optional but worth
164
+ having: with it, local sessions are persistent and rediscovered after relaunch.
165
+ Without it, ZeroG falls back to a direct PTY on the chosen shell and labels the
166
+ session process-only; that shell is lost when the application exits.
167
+
168
+ ### Windows
169
+
170
+ No tooling beyond Node.js. The new-terminal dialog offers the shells it finds on
171
+ PATH — Windows PowerShell, PowerShell 7, Command Prompt, WSL (with a distribution
172
+ picker), and Git Bash where Git for Windows is installed.
173
+
174
+ `screen` does not exist on Windows, so local sessions are always process-only and
175
+ do not survive app exit. Remote SSH sessions are unaffected by the local shell
176
+ backend, and a remote host with `screen` still gives persistent sessions there.
177
+
178
+ ## Verification
179
+
180
+ The current main branch has the following local verification coverage:
181
+
182
+ - `npm run typecheck`: passes.
183
+ - `npm test`: passes (167 tests covering session service behaviour and PTY sizing, shell discovery, SSH inventory and argument validation, remote-screen parsing and prompt readiness, session history, the session dialog, settings, terminal clipboard and OSC 52 handling, dialog dismissal, and the speech and voice helpers; one further test needs a real `screen` and is opt-in through `ZEROG_LIVE_SCREEN=1`).
184
+ - `npm run build`: passes and writes `dist/main` plus `dist/renderer`.
185
+ - `npm audit --omit=dev`: production dependency auditing is part of the project quality checks.
186
+
187
+ ## License
188
+
189
+ ZeroG Terminal is released under the MIT License. See [LICENSE](LICENSE).
190
+
191
+ ## Contributing and security
192
+
193
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development, testing, and pull-request guidance. Please report security vulnerabilities privately through GitHub; see [SECURITY.md](SECURITY.md).
package/bin/zerogterm.cjs CHANGED
@@ -1,23 +1,23 @@
1
- #!/usr/bin/env node
2
-
3
- const { spawn } = require('node:child_process');
4
- const path = require('node:path');
5
- const electron = require('electron');
6
-
7
- const packageRoot = path.resolve(__dirname, '..');
8
- const child = spawn(electron, [packageRoot, ...process.argv.slice(2)], {
9
- stdio: 'inherit'
10
- });
11
-
12
- child.on('error', (error) => {
13
- console.error(`Failed to start ZeroG Terminal: ${error.message}`);
14
- process.exitCode = 1;
15
- });
16
-
17
- child.on('close', (code, signal) => {
18
- if (signal) {
19
- process.kill(process.pid, signal);
20
- return;
21
- }
22
- process.exitCode = code ?? 1;
23
- });
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require('node:child_process');
4
+ const path = require('node:path');
5
+ const electron = require('electron');
6
+
7
+ const packageRoot = path.resolve(__dirname, '..');
8
+ const child = spawn(electron, [packageRoot, ...process.argv.slice(2)], {
9
+ stdio: 'inherit'
10
+ });
11
+
12
+ child.on('error', (error) => {
13
+ console.error(`Failed to start ZeroG Terminal: ${error.message}`);
14
+ process.exitCode = 1;
15
+ });
16
+
17
+ child.on('close', (code, signal) => {
18
+ if (signal) {
19
+ process.kill(process.pid, signal);
20
+ return;
21
+ }
22
+ process.exitCode = code ?? 1;
23
+ });
@@ -10,6 +10,15 @@ const __dirname = fileURLToPath(new URL('.', import.meta.url));
10
10
  const history = new SessionHistoryStore({ filePath: defaultHistoryPath(app.getPath('userData')) });
11
11
  const service = new ScreenService({ onEvent: (event, session, available) => { void history.record(event, session, available); } });
12
12
  let win;
13
+ /** A pane's measured size, as it arrives from the renderer. */
14
+ function parsePtySize(value) {
15
+ if (!value || typeof value !== 'object')
16
+ return undefined;
17
+ const { cols, rows } = value;
18
+ if (!Number.isInteger(cols) || !Number.isInteger(rows))
19
+ return undefined;
20
+ return { cols: cols, rows: rows };
21
+ }
13
22
  // GPU is unstable under Toolbox/Wayland on this host; allow override.
14
23
  if (process.env.ZEROG_ENABLE_GPU !== '1') {
15
24
  app.disableHardwareAcceleration();
@@ -108,10 +117,10 @@ ipcMain.handle('screens:attachRemote', (_event, input, screenName) => {
108
117
  throw new Error('screenName is required');
109
118
  return buildRemoteScreenAttachArgs(connection, screenName);
110
119
  });
111
- ipcMain.handle('sessions:attach', (_event, id) => {
120
+ ipcMain.handle('sessions:attach', (_event, id, size) => {
112
121
  if (typeof id !== 'string' || !id)
113
122
  throw new Error('attachSession requires a session id');
114
- return service.attach(id, (data) => win?.webContents.send('terminal:data', id, data), (message) => win?.webContents.send('terminal:status', id, message));
123
+ return service.attach(id, (data) => win?.webContents.send('terminal:data', id, data), (message) => win?.webContents.send('terminal:status', id, message), parsePtySize(size));
115
124
  });
116
125
  ipcMain.handle('sessions:close', (_event, id) => {
117
126
  if (typeof id !== 'string' || !id)
@@ -1,33 +1,33 @@
1
- const { contextBridge, ipcRenderer } = require('electron');
2
-
3
- const api = {
4
- listSessions: () => ipcRenderer.invoke('sessions:list'),
5
- listHistory: () => ipcRenderer.invoke('sessions:history'),
6
- removeHistory: (entryId) => ipcRenderer.invoke('sessions:historyRemove', entryId),
7
- listBackends: () => ipcRenderer.invoke('sessions:backends'),
8
- listWslDistributions: () => ipcRenderer.invoke('sessions:wslDistributions'),
9
- createLocalSession: (request) => ipcRenderer.invoke('sessions:createLocal', request),
10
- createSshSession: (request) => ipcRenderer.invoke('sessions:createSsh', request),
11
- listKnownConnections: () => ipcRenderer.invoke('connections:listKnown'),
12
- discoverRemoteScreens: (connection) => ipcRenderer.invoke('screens:discoverRemote', connection),
13
- buildRemoteScreenAttach: (connection, screenName) => ipcRenderer.invoke('screens:attachRemote', connection, screenName),
14
- attachSession: (id) => ipcRenderer.invoke('sessions:attach', id),
15
- closeSession: (id) => ipcRenderer.invoke('sessions:close', id),
16
- write: (sessionId, data) => ipcRenderer.send('terminal:write', sessionId, data),
17
- resize: (sessionId, cols, rows) => ipcRenderer.send('terminal:resize', sessionId, cols, rows),
18
- copyText: (text) => ipcRenderer.invoke('clipboard:writeText', text),
19
- readText: () => ipcRenderer.invoke('clipboard:readText'),
20
- onData: (callback) => {
21
- const listener = (_event, sessionId, data) => callback(sessionId, data);
22
- ipcRenderer.on('terminal:data', listener);
23
- return () => ipcRenderer.removeListener('terminal:data', listener);
24
- },
25
- onStatus: (callback) => {
26
- const listener = (_event, sessionId, message) => callback(sessionId, message);
27
- ipcRenderer.on('terminal:status', listener);
28
- return () => ipcRenderer.removeListener('terminal:status', listener);
29
- },
30
- requestAiCommand: () => ipcRenderer.invoke('ai:suggest')
31
- };
32
-
33
- contextBridge.exposeInMainWorld('zerog', api);
1
+ const { contextBridge, ipcRenderer } = require('electron');
2
+
3
+ const api = {
4
+ listSessions: () => ipcRenderer.invoke('sessions:list'),
5
+ listHistory: () => ipcRenderer.invoke('sessions:history'),
6
+ removeHistory: (entryId) => ipcRenderer.invoke('sessions:historyRemove', entryId),
7
+ listBackends: () => ipcRenderer.invoke('sessions:backends'),
8
+ listWslDistributions: () => ipcRenderer.invoke('sessions:wslDistributions'),
9
+ createLocalSession: (request) => ipcRenderer.invoke('sessions:createLocal', request),
10
+ createSshSession: (request) => ipcRenderer.invoke('sessions:createSsh', request),
11
+ listKnownConnections: () => ipcRenderer.invoke('connections:listKnown'),
12
+ discoverRemoteScreens: (connection) => ipcRenderer.invoke('screens:discoverRemote', connection),
13
+ buildRemoteScreenAttach: (connection, screenName) => ipcRenderer.invoke('screens:attachRemote', connection, screenName),
14
+ attachSession: (id, size) => ipcRenderer.invoke('sessions:attach', id, size),
15
+ closeSession: (id) => ipcRenderer.invoke('sessions:close', id),
16
+ write: (sessionId, data) => ipcRenderer.send('terminal:write', sessionId, data),
17
+ resize: (sessionId, cols, rows) => ipcRenderer.send('terminal:resize', sessionId, cols, rows),
18
+ copyText: (text) => ipcRenderer.invoke('clipboard:writeText', text),
19
+ readText: () => ipcRenderer.invoke('clipboard:readText'),
20
+ onData: (callback) => {
21
+ const listener = (_event, sessionId, data) => callback(sessionId, data);
22
+ ipcRenderer.on('terminal:data', listener);
23
+ return () => ipcRenderer.removeListener('terminal:data', listener);
24
+ },
25
+ onStatus: (callback) => {
26
+ const listener = (_event, sessionId, message) => callback(sessionId, message);
27
+ ipcRenderer.on('terminal:status', listener);
28
+ return () => ipcRenderer.removeListener('terminal:status', listener);
29
+ },
30
+ requestAiCommand: () => ipcRenderer.invoke('ai:suggest')
31
+ };
32
+
33
+ contextBridge.exposeInMainWorld('zerog', api);