zerogterm 0.1.0-alpha.2 → 0.2.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/README.md CHANGED
@@ -9,6 +9,7 @@ ZeroG Terminal is a Linux-first Electron workspace for persistent `screen` sessi
9
9
  - Persistent dark/light theme with an accessible sun/moon toggle.
10
10
  - Safe session-name validation and argument-array `screen` invocation.
11
11
  - AI command approval surface; suggestions are visible and require explicit approval before being sent to the terminal.
12
+ - Voice input per pane: click the microphone, speak, and the utterance is transcribed locally with Whisper-tiny (via Transformers.js; the model is downloaded once on first use) and typed into the pane's prompt without auto-execution.
12
13
 
13
14
  ## Release status
14
15
 
@@ -25,7 +26,7 @@ The npm package contains the built Electron application and project documentatio
25
26
  - `Ctrl+Shift+T` — new local terminal in the current workspace
26
27
  - `Ctrl+Shift+O` — session overview
27
28
  - `Ctrl+Shift+B` — toggle sessions sidebar
28
- - `Esc` — close overview / dialogs
29
+ - `Esc` — close overview / dialogs, cancel voice recording
29
30
 
30
31
  ## Development
31
32
 
@@ -59,7 +60,7 @@ sudo dnf install screen
59
60
  ## Current verification
60
61
 
61
62
  - `npm run typecheck`: passes.
62
- - `npm test`: passes (3 tests covering name validation, `screen -ls` parsing, and SSH argument validation).
63
+ - `npm test`: passes (9 tests covering name validation, `screen -ls` parsing, SSH argument validation, session close semantics, and voice silence detection).
63
64
  - `npm run build`: passes and writes `dist/main` plus `dist/renderer`.
64
65
  - Electron is configured to disable hardware acceleration by default for the Fedora Toolbox/Wayland runtime; set `ZEROG_ENABLE_GPU=1` only when GPU launch is stable on the host.
65
66
  - `npm audit --omit=dev`: reports no known production vulnerabilities.
package/bin/zerogterm.cjs CHANGED
File without changes
@@ -1,4 +1,4 @@
1
- import { app, BrowserWindow, clipboard, ipcMain, Menu } from 'electron';
1
+ import { app, BrowserWindow, clipboard, ipcMain, Menu, session } from 'electron';
2
2
  import { join } from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
4
  import { ScreenService } from './session-service.js';
@@ -72,6 +72,11 @@ ipcMain.handle('sessions:attach', (_event, id) => {
72
72
  throw new Error('attachSession requires a session id');
73
73
  return service.attach(id, (data) => win?.webContents.send('terminal:data', id, data), (message) => win?.webContents.send('terminal:status', id, message));
74
74
  });
75
+ ipcMain.handle('sessions:close', (_event, id) => {
76
+ if (typeof id !== 'string' || !id)
77
+ throw new Error('closeSession requires a session id');
78
+ service.close(id);
79
+ });
75
80
  ipcMain.on('terminal:write', (_event, sessionId, data) => {
76
81
  if (typeof sessionId === 'string' && typeof data === 'string')
77
82
  service.write(sessionId, data);
@@ -92,6 +97,11 @@ ipcMain.handle('ai:suggest', () => ({
92
97
  explanation: 'Read-only preview of changed files in the active workspace.'
93
98
  }));
94
99
  app.whenReady().then(() => {
100
+ // Voice input captures the local microphone only. Electron denies all
101
+ // permission requests unless a handler answers, so grant media explicitly.
102
+ session.defaultSession.setPermissionRequestHandler((_webContents, permission, callback) => {
103
+ callback(permission === 'media');
104
+ });
95
105
  // Keep the normal window chrome, but let the ZeroG UI occupy the full
96
106
  // client area instead of showing Electron's default File/Edit/etc. menu.
97
107
  Menu.setApplicationMenu(null);
@@ -5,6 +5,7 @@ const api = {
5
5
  createLocalSession: (request) => ipcRenderer.invoke('sessions:createLocal', request),
6
6
  createSshSession: (request) => ipcRenderer.invoke('sessions:createSsh', request),
7
7
  attachSession: (id) => ipcRenderer.invoke('sessions:attach', id),
8
+ closeSession: (id) => ipcRenderer.invoke('sessions:close', id),
8
9
  write: (sessionId, data) => ipcRenderer.send('terminal:write', sessionId, data),
9
10
  resize: (sessionId, cols, rows) => ipcRenderer.send('terminal:resize', sessionId, cols, rows),
10
11
  copyText: (text) => ipcRenderer.invoke('clipboard:writeText', text),
@@ -253,4 +253,14 @@ export class ScreenService {
253
253
  for (const sessionId of this.ptys.keys())
254
254
  this.detach(sessionId);
255
255
  }
256
+ /**
257
+ * Close a pane's session: detach its PTY and drop transient bookkeeping.
258
+ * Screen-backed sessions are deliberately left running so they remain
259
+ * discoverable via `screen -ls`; SSH and process-only sessions end.
260
+ */
261
+ close(sessionId) {
262
+ this.detach(sessionId);
263
+ this.sshSessions.delete(sessionId);
264
+ this.fallbackLocalSessions.delete(sessionId);
265
+ }
256
266
  }