zerogterm 0.7.0-alpha2 → 0.8.0-alpha

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
@@ -7,24 +7,27 @@ ZeroG Terminal is an alpha project, but it is already useful as a multi-session
7
7
  ## Features
8
8
 
9
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
- - A compact navigation rail for sessions, overview, settings, SSH connections, and opening a new local terminal, while keeping the sessions sidebar collapsible.
12
- - Layout controls that restore a split, even up its pane sizes, and maximize or restore a pane in a predictable sequence.
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
+ - A compact navigation rail for sessions, overview, settings, SSH connections, and opening a new local terminal, while keeping the sessions sidebar collapsible.
12
+ - Layout controls that restore a split, even up its pane sizes, and maximize or restore a pane in a predictable sequence.
13
13
  - Maximize a focused pane and cycle between sessions without losing the other panes.
14
- - 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.
14
+ - 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. A WSL pane starts in the distribution's own home directory rather than the Windows one seen through `/mnt/c`.
15
15
  - SSH sessions for hosts, `user@host`, and `user@host:port` targets.
16
- - SSH configuration discovery from known connections, including remote `screen` session discovery.
16
+ - SSH configuration discovery from known connections, including remote `screen` session discovery. In the sidebar's Connections tab, clicking a saved connection opens the connect dialog with the host filled in, and double-clicking it skips the dialog and opens the host in a new pane.
17
17
  - Reconnect to existing local or remote `screen` sessions from the Screens view.
18
18
  - Remote screen attachment that waits for SSH readiness before sending commands, including host and port-aware matching.
19
+ - Shared ports over SSH, in a Ports view opened from the rail: forward a port on a remote host so it answers on this machine, or a port here so it answers on the remote. Each tunnel is its own SSH connection, so a host needs no terminal open first. Ports bind to loopback unless you widen them, and are remembered between launches.
20
+ - A directory browser inside a pane, opened from the folder button in its title bar: the pane splits, terminal on one side and the directories on the other, with a draggable divider. Double-click a folder to take the shell there. It works on SSH panes and on local ones, WSL included, follows a `cd` you type by hand, and is remembered per pane when you switch workspaces or relaunch.
19
21
  - An SFTP transfer panel, opened from the ⇅ button above the panes: local files on the left, the active SSH session's host on the right, with upload, download, new folder, rename, and delete. It connects to the host that session is already using and opens at the directory its shell is standing in, so a file can go straight to the project being worked on.
20
22
  - Session history for reconnecting to sessions after a relaunch, with bounded structured history and no stored secrets.
21
- - Workspaces for grouping sessions and quickly switching between projects or tasks.
23
+ - A ranked command palette on `Ctrl+Shift+R`, in the spirit of [McFly](https://github.com/cantino/mcfly): commands you have run, ranked by directory, host, recency, frequency, whether they worked, and whether you picked them before. Off by default — it is the one feature that stores what you typed — and it refuses anything that looks like it carries a credential.
24
+ - Workspaces for grouping sessions and quickly switching between projects or tasks. Drag the tabs beside the wordmark to put them in the order you want; `Ctrl+Shift+1` … `9` follow that order, and it is remembered between launches. Right-click a tab to rename it, duplicate it, move it, or close it. Each workspace keeps its own panes, layout, focused terminal, and maximized pane, so switching to one restores the arrangement you left it in. Workspaces survive a relaunch: local `screen` terminals reattach on their own, and SSH panes come back as ghost rows that reconnect when clicked, rather than dialling out to a host on startup.
22
25
  - Session overview, collapsible sidebar, keyboard shortcuts, and light/dark themes.
23
26
  - xterm.js terminal rendering with scrollback preservation while changing layouts.
24
- - 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.
27
+ - Voice input, either with Whisper ONNX inside the app through Transformers.js or through an OpenAI-compatible transcription server you point it at — on this machine, on the LAN, or hosted; transcribed text is typed into the selected terminal without automatic execution.
25
28
  - 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.
26
29
  - A settings panel for appearance, terminal behaviour, session defaults, and speech recognition, including a built-in recognition test.
27
- - AI command suggestion and approval UI, keeping command execution explicit.
30
+ - AI command suggestions from any OpenAI-compatible endpoint — Ollama, LM Studio, llama.cpp, vLLM, OpenRouter, or OpenAI itself — configured with a base URL, a model and an optional key in Settings. Ask what you want, get one command with an explanation, and approve it before it runs.
28
31
  - Sandboxed Electron renderer, context isolation, disabled Node integration, and a narrow typed preload API.
29
32
  - Safe argument-array handling and validation around SSH and `screen` session operations.
30
33
 
@@ -34,9 +37,9 @@ See the project walkthrough on [YouTube](https://youtu.be/4aJZCxLHD14).
34
37
 
35
38
  ## Release status
36
39
 
37
- ZeroG Terminal is currently a public alpha. The current release is `0.7.0-alpha2`; the version history is tracked in [versions.txt](versions.txt).
40
+ ZeroG Terminal is currently a public alpha. The current release is `0.8.0-alpha`; the version history is tracked in [versions.txt](versions.txt). The running version is shown beside the wordmark in the title bar, read from the app itself rather than written into the interface, so it is accurate in a packaged build too.
38
41
 
39
- The npm package contains the built Electron application and project documentation. It is intended for early adopters and testing rather than production use.
42
+ The GitHub Releases page provides a Windows x64 installer and portable executable for each desktop release. These alpha builds are intended for early adopters and testing rather than production use. The npm package remains available for developers who prefer to launch ZeroG from Node.js.
40
43
 
41
44
  ## Terminal shortcuts
42
45
 
@@ -44,12 +47,42 @@ The npm package contains the built Electron application and project documentatio
44
47
  - `Ctrl+Shift+V` — paste into the active terminal
45
48
  - `Ctrl+C` remains the interrupt signal (not copy)
46
49
  - `Ctrl+Shift+N` — new workspace
50
+ - `Ctrl+Shift+1` … `Ctrl+Shift+9` — switch to a workspace by position
47
51
  - `Ctrl+Shift+T` — new local terminal in the current workspace
52
+ - `Ctrl+Shift+R` — ranked command history palette
53
+ - `Ctrl+Shift+A` — ask the AI endpoint for a command
54
+ - `Ctrl+Shift+L` — fold to a single pane, or back to the last split
48
55
  - `Ctrl+Shift+O` — session overview
49
56
  - `Ctrl+Shift+B` — toggle sessions sidebar
50
57
  - `Ctrl+Shift+,` — settings
58
+ - `Ctrl+Shift+/` — the help panel: what is here, and this list
51
59
  - `Esc` — close overview / dialogs, cancel voice recording
52
60
 
61
+ Every one of these can be moved: **Settings → Shortcuts** lists them, and
62
+ pressing a new chord in a row rebinds it. A shortcut needs Ctrl and at least one
63
+ of Shift or Alt, so a shell keeps its own bindings — `Ctrl+C` interrupts,
64
+ `Ctrl+R` is still readline's reverse search, `Ctrl+L` still clears the screen,
65
+ and `Ctrl+A` still reaches `screen` or `tmux`. None of these shortcuts reaches
66
+ the shell in the pane that has focus, which was verified by asking bash to report
67
+ the control characters it receives.
68
+
69
+ Rebinding exists because nothing in the app can outrank the machine it runs on.
70
+ `Ctrl+Shift+T` was reported already taken on Windows 11; Windows itself uses Ctrl
71
+ and Shift together to switch keyboard layout when more than one is installed; and
72
+ some applications — Teams, for one — register chords globally while they are
73
+ running. `Ctrl+Alt` is usually clear, though on some layouts it behaves as AltGr,
74
+ so a chord you would type in a terminal is worth avoiding. `Ctrl+Shift+1` … `9`
75
+ and the clipboard pair cannot be moved.
76
+
77
+ The `?` in the title bar opens the same help panel, which lists the shortcuts as
78
+ they are currently bound rather than as they shipped.
79
+
80
+ The Ports view, the SFTP transfer panel and a pane's directory browser have no
81
+ shortcut of their own; they open from the rail, the ⇅ button above the panes, and
82
+ the folder button in a pane's title bar. `Esc` deliberately does not close the
83
+ directory browser: it is part of the pane rather than an overlay, and `Esc` has
84
+ to keep reaching the shell for `vi` to be usable.
85
+
53
86
  Clicking a link in a pane opens it in your own browser rather than in a window
54
87
  of ZeroG. Hovering one first shows where it actually goes in the status bar,
55
88
  which matters because a terminal hyperlink can be labelled with anything. Only
@@ -63,6 +96,61 @@ sequence — this is how TUI tools such as CLI coding agents, tmux and Neovim pu
63
96
  text on the clipboard, including over SSH. Reading the clipboard through OSC 52
64
97
  is refused, so a program on a remote host cannot see what you last copied.
65
98
 
99
+ ## The command history palette
100
+
101
+ `Ctrl+Shift+R` opens a search over the commands you have actually run, ranked so
102
+ the one you want is usually first: same directory beats same host, recent beats
103
+ frequent, something that worked beats something that failed, and something you
104
+ picked from this palette before beats something you merely ran. Typing matches a
105
+ subsequence, so `gcm` finds `git commit -m`, and the matched characters are
106
+ highlighted so it is clear why a row is there.
107
+
108
+ Enter puts the command on the prompt **without running it**. The command came out
109
+ of a store rather than from your hands a moment ago, so pressing Enter is your
110
+ decision — and it leaves room to change an argument, which is most of why anyone
111
+ reaches for history.
112
+
113
+ `Ctrl+R` is untouched. Your shell keeps its own reverse search; McFly can rebind
114
+ that key because it *is* the shell, and ZeroG taking it would remove
115
+ reverse-search from every pane including remote ones this feature cannot see.
116
+
117
+ ### Turning it on
118
+
119
+ Recording is off until you switch it on in Settings under "AI & voice". It is the
120
+ only part of ZeroG that stores what you typed, so it is opt-in rather than a
121
+ default you have to find and disable.
122
+
123
+ Commands are read from the standard OSC 133 prompt marks a shell emits — the same
124
+ marks VS Code, kitty, WezTerm and Windows Terminal use. If you already have shell
125
+ integration from any of those, or from an oh-my-zsh plugin, ZeroG reads what is
126
+ already there and you need to add nothing. Otherwise Settings offers a snippet
127
+ per shell to paste into your rc file, and the panel says how many of your open
128
+ panes are actually reporting marks, so "did that work" has an answer.
129
+
130
+ A remote host needs the snippet installed on the remote host: the marks come from
131
+ the shell, and over SSH that shell is on the far side. A pane whose shell reports
132
+ no marks records nothing, rather than guessing from the screen and recording
133
+ something wrong.
134
+
135
+ ### What is stored, and what is refused
136
+
137
+ Each entry holds the command, the directory and host it ran in, its exit status,
138
+ when it last ran, how many times, and how often you picked it. It lives in
139
+ `command-history.json` in ZeroG's profile directory, written with owner-only
140
+ permissions. "Forget all remembered commands" empties it and deletes the file.
141
+
142
+ A command that looks like it carries a credential is refused outright rather than
143
+ stored with the value masked — a masked entry still records that you set a
144
+ particular secret in a particular directory at a particular time. Refused shapes
145
+ include assignments to anything named like a token, key, secret or password;
146
+ `--password`, `--token` and `--api-key` flags; credentials inside a URL;
147
+ `Authorization` headers; `curl -u user:pass`; vendor-shaped tokens; and long
148
+ high-entropy words.
149
+
150
+ This is not a complete defence and is not claimed to be. A secret typed as a bare
151
+ argument to an unusual program, or piped in from `echo`, looks like ordinary text.
152
+ See [SECURITY.md](SECURITY.md).
153
+
66
154
  ## Resizing panes and the sidebar
67
155
 
68
156
  Drag the line between two panes, or the sidebar's right edge, to change how the
@@ -74,6 +162,65 @@ a time, and Enter or a double-click puts it back in the middle. One divider
74
162
  position is shared by every layout, so a split you set up in the vertical split
75
163
  is the same split you get in the four-pane grid.
76
164
 
165
+ ## Sharing ports over SSH
166
+
167
+ The Ports button in the rail opens a list of shared ports, grouped by the host
168
+ each one runs through. "Share port" asks for a host and a port, and the port is
169
+ then reachable as though the service were running here.
170
+
171
+ Two directions are available under "More options". The default sends a port on
172
+ the remote to this machine, which is what a remote dev server, database, or
173
+ debugger needs. The other sends a port here to the remote, for a webhook or an
174
+ agent on that host calling back. A row always names the side that listens first,
175
+ so which way a tunnel runs is never left to be inferred.
176
+
177
+ A shared port answers only on the machine that binds it, unless you tick "Share
178
+ on my network" — which re-exports the service to whatever network that machine is
179
+ attached to, and is marked `LAN` on the row so it cannot be forgotten about. A
180
+ port sent to the remote is bound on loopback there by default; widening it also
181
+ needs `GatewayPorts` enabled in that host's `sshd_config`, and the row says so
182
+ when the server refuses.
183
+
184
+ Each tunnel is a separate `ssh` process, which is what makes closing one exact:
185
+ the cross stops that tunnel and nothing else. It also means a host that
186
+ authenticates with a password asks once per tunnel, in the panel, and nothing
187
+ typed there is stored. Hosts using a key or an agent are not asked at all.
188
+
189
+ Shared ports are remembered between launches and come back listed but not
190
+ connected. Clicking one reconnects it — the app never opens a connection to a
191
+ host on its own at startup.
192
+
193
+ ## AI command suggestions
194
+
195
+ Set an endpoint in Settings under "AI & voice": a base URL ending in `/v1`, a
196
+ model, and a key if the endpoint wants one. One field serves every provider,
197
+ because `chat/completions` is the request shape they all implement — a local
198
+ Ollama at `http://127.0.0.1:11434/v1` needs no key at all. "Test connection"
199
+ asks the model for a token and reports what came back, and "Refresh" lists the
200
+ models the endpoint says it has. A key is stored encrypted by the operating
201
+ system, never in the settings file, and is only ever read in the main process:
202
+ it is not held in the window.
203
+
204
+ Suggest asks what you want, then returns a single command with an explanation.
205
+ Only one command, ever — a reply naming several, or answering in prose rather
206
+ than the structure asked for, produces no command to run and says so. The
207
+ command is written to the pane you asked from, not to whichever pane is focused
208
+ when the answer arrives.
209
+
210
+ By default the model is told only your shell, directory and host. Turning on
211
+ "Send recent terminal output" also sends the tail of the focused pane, which is
212
+ what lets a suggestion read the error you are actually looking at — and means
213
+ terminal content goes to whatever endpoint you configured. The panel says which
214
+ of those is happening.
215
+
216
+ While output is being sent, approval cannot be turned off. Terminal output can
217
+ come from a remote host, and a host can print text shaped like an instruction;
218
+ a command chosen downstream of that must be read before it runs. The output is
219
+ sent as clearly delimited data with the delimiter stripped out of it, and the
220
+ answer is only believed if it arrives in the exact structure requested — but
221
+ neither of those is trusted to hold on its own, which is why the approval step
222
+ is not optional in that configuration.
223
+
77
224
  ## Transferring files over SFTP
78
225
 
79
226
  The ⇅ button above the panes opens a two-pane transfer panel: this computer on
@@ -92,12 +239,12 @@ OSC 7 — the sequence a shell emits to report its directory — and otherwise f
92
239
  the path in the prompt; it never types `pwd` into your session to find out. When
93
240
  neither is available the panel opens at the login directory.
94
241
 
95
- Select files with a click, or several with Ctrl-click or Shift-click, then Upload or Download.
242
+ Select files with a click, or several with Ctrl-click or Shift-click, then Upload or Download.
96
243
  Double-click a folder to open it, or type a path into the folder box. New folder,
97
244
  rename, and delete act on one selected item; deleting asks first, and a folder
98
- must be empty, so a single click can never remove a tree. Remote folders can be
99
- downloaded recursively with the system `sftp` client; uploads remain file-only,
100
- so a local folder is never copied accidentally as a different job.
245
+ must be empty, so a single click can never remove a tree. Remote folders can be
246
+ downloaded recursively with the system `sftp` client; uploads remain file-only,
247
+ so a local folder is never copied accidentally as a different job.
101
248
 
102
249
  Filenames containing quotes, backslashes, or the wildcard characters `* ? [ ]`
103
250
  are refused with a message rather than acted on. The `sftp` client re-reads its
@@ -105,6 +252,67 @@ own arguments through a glob pass, and there is no encoding of those characters
105
252
  that is provably correct for every command — being approximately right about
106
253
  which file to delete is not good enough.
107
254
 
255
+ ### Duplicating a workspace
256
+
257
+ Right-clicking a tab offers **Duplicate**, which copies the arrangement rather
258
+ than the sessions: the layout comes across, and each SSH pane comes across as a
259
+ pane waiting to be reconnected, so clicking it opens a *new* session to the same
260
+ host. A local pane is not copied — its shell is a process on this machine, so a
261
+ copy would be a different terminal rather than a duplicate of anything, and the
262
+ status line says how many were left behind rather than letting you notice a pane
263
+ missing.
264
+
265
+ ## Browsing directories inside a pane
266
+
267
+ The folder button in a pane's title bar splits that pane: the terminal on one
268
+ side, the directories where its shell is standing on the other. Drag the divider
269
+ to change the balance, double-click it to centre it, or use the arrow keys when
270
+ it has focus. A pane remembers whether its browser was open and where the divider
271
+ was, per workspace and between launches.
272
+
273
+ Single-click a folder to look inside it without moving the shell.
274
+ **Double-click** it to take the shell there — ZeroG types the `cd` into the pane,
275
+ which is deliberately visible: you asked for it, and seeing the command is how
276
+ you know what happened. The button in the bottom-right corner does the same for
277
+ the directory already on screen, which is how you retry after a `cd` that was
278
+ refused because the pane was busy, or catch the shell up after browsing around.
279
+ `..` is always the first row, except at a root the shell cannot go above.
280
+
281
+ A single click waits a moment before it acts, because it has to find out whether
282
+ it is the first half of a double-click: browsing immediately would replace the
283
+ row under the pointer and the second press would land on a different one.
284
+
285
+ The browser opens on the directory the pane's shell reports, and on the login
286
+ directory before it has reported anything — a pane that has just connected has
287
+ run nothing, so there is nothing to read yet. That login directory comes from the
288
+ connection itself, never from a command typed into your session.
289
+
290
+ Where it lists from depends on the pane. An SSH pane lists over an SFTP
291
+ connection to its host, opening one if there is not already one open — the same
292
+ client, `~/.ssh/config`, agent and `known_hosts` the transfer panel uses, and the
293
+ same connection when both are looking at the same host. If the host asks for a
294
+ password, a key passphrase, or a decision about its host key, the browser says
295
+ so and the transfer panel (⇅) is where you answer: it shows the question with
296
+ the key fingerprint beside it, and ZeroG never answers one on your behalf. The
297
+ login directory that connection reports is also how a `~` in the pane's prompt
298
+ becomes a path. A native local pane lists the filesystem directly. A WSL pane lists the distribution through the `\\wsl.localhost\` share
299
+ Windows serves it on, so what you see is the distribution's own filesystem and
300
+ not the Windows one — and `~` is resolved by asking the distribution once, never
301
+ by typing `pwd` into your pane.
302
+
303
+ Two things it will refuse, with a sentence rather than in silence:
304
+
305
+ - **A pane that is not at a prompt.** A `cd` sent while `vi`, `less`, or an agent
306
+ has the terminal goes to that program instead. Where a shell reports the OSC 133
307
+ prompt marks — the same integration the command history uses — this is known
308
+ exactly; otherwise the shape of the last line is the best available answer.
309
+ - **A directory name it cannot quote for that shell.** A name containing a line
310
+ break, or a double quote in a Command Prompt pane, is not typed at all rather
311
+ than approximated.
312
+
313
+ The browser navigates; it does not move files. The SFTP panel is the surface for
314
+ that.
315
+
108
316
  ## Settings
109
317
 
110
318
  Settings open from the gear at the bottom of the left rail, the avatar in the
@@ -148,13 +356,23 @@ about 968 MB for small at full precision; models are cached after first use.
148
356
  Multilingual models add language and transcribe/translate options, which
149
357
  English-only checkpoints reject and so do not show.
150
358
 
151
- **Local server** posts the recorded audio as a WAV file to a transcription
152
- server on this machine, using the OpenAI `/v1/audio/transcriptions` shape that
153
- whisper.cpp's server, LM Studio, faster-whisper-server and similar tools speak.
154
- This is the way to use a model the built-in engine cannot load — a GGUF build
155
- such as `unslothai/Qwen3-ASR-0.6B-GGUF` needs a llama.cpp-family runtime, so
156
- something else has to host it. The URL must be on this machine; a non-loopback
157
- address is refused rather than sent.
359
+ **Server** posts the recorded audio as a WAV file to a transcription server,
360
+ using the OpenAI `/v1/audio/transcriptions` shape that whisper.cpp's server, LM
361
+ Studio, faster-whisper-server and similar tools speak. This is the way to use a
362
+ model the built-in engine cannot load — a GGUF build such as
363
+ `unslothai/Qwen3-ASR-0.6B-GGUF` needs a llama.cpp-family runtime, so something
364
+ else has to host it. Any `http://` or `https://` address works: loopback, a
365
+ machine on the LAN such as `http://10.0.10.46:8888/v1/audio/transcriptions`, or
366
+ a hosted service. The field says whether the address it holds is on this machine
367
+ or not, because a remote one means recorded speech leaves it.
368
+
369
+ Servers that want authentication take an API key in the same panel, sent as an
370
+ `Authorization: Bearer` header. The key is not kept in the settings file: the
371
+ main process stores it encrypted through the operating system's own secret store
372
+ — DPAPI on Windows, Keychain on macOS, libsecret or kwallet on Linux — and hands
373
+ it to the renderer only for the request being made. On a system with no keyring
374
+ available, saving is refused rather than written in the clear, and the key can be
375
+ held for the session instead. Leave it empty for a local server that wants none.
158
376
 
159
377
  Both engines share the maximum utterance length and the silence threshold, and
160
378
  the **Try it** button on that page records a phrase and shows the transcript,
@@ -195,6 +413,11 @@ required whichever shell you start them from.
195
413
  for Windows and macOS, so a C/C++ toolchain is a Linux requirement rather than a
196
414
  general one — there, `npm install` compiles it.
197
415
 
416
+ ### Windows desktop release
417
+
418
+ Download the latest Windows x64 installer from [GitHub Releases](https://github.com/HappyMonkeyAI/ZeroGTerm/releases). The installer adds ZeroG Terminal to the current user's applications. The portable `.exe` can be run without installation.
419
+
420
+ These binaries are unsigned alpha builds, so Windows SmartScreen may show a warning on first launch. If you downloaded the release from the official repository, choose **More info → Run anyway**. Review the release notes before installing; SSH, WSL, PowerShell, Git Bash, and any remote `screen` sessions are provided by the host system rather than bundled with the app.
198
421
  ### Linux
199
422
 
200
423
  ```bash
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
+ });