clitrigger 0.2.3 → 0.2.5

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 (55) hide show
  1. package/dist/client/assets/{index-DGrNwWj5.css → index-BTACCEnN.css} +1 -1
  2. package/dist/client/assets/index-CnEvBKLE.js +707 -0
  3. package/dist/client/index.html +2 -2
  4. package/dist/server/db/queries.d.ts +4 -2
  5. package/dist/server/db/queries.d.ts.map +1 -1
  6. package/dist/server/db/queries.js +11 -3
  7. package/dist/server/db/queries.js.map +1 -1
  8. package/dist/server/db/schema.d.ts.map +1 -1
  9. package/dist/server/db/schema.js +10 -0
  10. package/dist/server/db/schema.js.map +1 -1
  11. package/dist/server/index.d.ts.map +1 -1
  12. package/dist/server/index.js +2 -0
  13. package/dist/server/index.js.map +1 -1
  14. package/dist/server/lib/svn.d.ts +22 -0
  15. package/dist/server/lib/svn.d.ts.map +1 -0
  16. package/dist/server/lib/svn.js +60 -0
  17. package/dist/server/lib/svn.js.map +1 -0
  18. package/dist/server/routes/projects.d.ts.map +1 -1
  19. package/dist/server/routes/projects.js +69 -8
  20. package/dist/server/routes/projects.js.map +1 -1
  21. package/dist/server/routes/session-settings.d.ts.map +1 -1
  22. package/dist/server/routes/session-settings.js +21 -0
  23. package/dist/server/routes/session-settings.js.map +1 -1
  24. package/dist/server/routes/svn.d.ts +3 -0
  25. package/dist/server/routes/svn.d.ts.map +1 -0
  26. package/dist/server/routes/svn.js +260 -0
  27. package/dist/server/routes/svn.js.map +1 -0
  28. package/dist/server/services/claude-manager.d.ts.map +1 -1
  29. package/dist/server/services/claude-manager.js +8 -1
  30. package/dist/server/services/claude-manager.js.map +1 -1
  31. package/dist/server/services/cli-status.d.ts.map +1 -1
  32. package/dist/server/services/cli-status.js +55 -17
  33. package/dist/server/services/cli-status.js.map +1 -1
  34. package/dist/server/services/orchestrator.d.ts.map +1 -1
  35. package/dist/server/services/orchestrator.js +3 -0
  36. package/dist/server/services/orchestrator.js.map +1 -1
  37. package/dist/server/services/session-manager.d.ts +14 -0
  38. package/dist/server/services/session-manager.d.ts.map +1 -1
  39. package/dist/server/services/session-manager.js +75 -14
  40. package/dist/server/services/session-manager.js.map +1 -1
  41. package/dist/server/services/svn-manager.d.ts +78 -0
  42. package/dist/server/services/svn-manager.d.ts.map +1 -0
  43. package/dist/server/services/svn-manager.js +260 -0
  44. package/dist/server/services/svn-manager.js.map +1 -0
  45. package/dist/server/services/worktree-manager.d.ts +16 -1
  46. package/dist/server/services/worktree-manager.d.ts.map +1 -1
  47. package/dist/server/services/worktree-manager.js +35 -8
  48. package/dist/server/services/worktree-manager.js.map +1 -1
  49. package/dist/server/websocket/index.d.ts.map +1 -1
  50. package/dist/server/websocket/index.js +11 -4
  51. package/dist/server/websocket/index.js.map +1 -1
  52. package/electron/main.cjs +96 -1
  53. package/electron/preload.cjs +10 -3
  54. package/package.json +2 -1
  55. package/dist/client/assets/index-CgoXRShG.js +0 -696
package/electron/main.cjs CHANGED
@@ -1,4 +1,5 @@
1
- const { app, BrowserWindow, dialog, shell, Menu, nativeTheme } = require('electron');
1
+ const { app, BrowserWindow, dialog, shell, Menu, nativeTheme, ipcMain } = require('electron');
2
+ const { autoUpdater } = require('electron-updater');
2
3
  const path = require('node:path');
3
4
  const fs = require('node:fs');
4
5
  const net = require('node:net');
@@ -7,6 +8,7 @@ const { pathToFileURL } = require('node:url');
7
8
  let mainWindow = null;
8
9
  let serverPort = null;
9
10
  let cleanupStarted = false;
11
+ let updateCheckInFlight = false;
10
12
 
11
13
  const userDataDir = app.getPath('userData');
12
14
  const configFile = path.join(userDataDir, 'config.json');
@@ -139,6 +141,93 @@ function createWindow(port) {
139
141
  }
140
142
 
141
143
  mainWindow.on('closed', () => { mainWindow = null; });
144
+
145
+ // Windows lock-screen / screensaver hands the native HWND keyboard focus
146
+ // off to the lock UI; on resume it doesn't always return to webContents,
147
+ // leaving every input (SessionForm, SessionTerminal) dead until the user
148
+ // minimizes and restores. Re-focus webContents on every window focus event
149
+ // so the OS-level focus is always routed back into the renderer.
150
+ mainWindow.on('focus', () => {
151
+ if (!mainWindow.isDestroyed()) mainWindow.webContents.focus();
152
+ });
153
+ }
154
+
155
+ ipcMain.on('ime:reset', () => {
156
+ if (mainWindow && !mainWindow.isDestroyed()) {
157
+ mainWindow.webContents.focus();
158
+ }
159
+ });
160
+
161
+ function checkForUpdates({ silent } = { silent: true }) {
162
+ if (!app.isPackaged) {
163
+ if (!silent) {
164
+ dialog.showMessageBox(mainWindow, {
165
+ type: 'info',
166
+ message: '개발 모드에서는 업데이트 확인을 사용할 수 없습니다.',
167
+ });
168
+ }
169
+ return;
170
+ }
171
+ if (updateCheckInFlight) return;
172
+ updateCheckInFlight = true;
173
+ autoUpdater
174
+ .checkForUpdates()
175
+ .catch((err) => {
176
+ console.error('[updater] check failed:', (err && err.message) || err);
177
+ if (!silent && mainWindow && !mainWindow.isDestroyed()) {
178
+ dialog.showMessageBox(mainWindow, {
179
+ type: 'error',
180
+ title: '업데이트 확인 실패',
181
+ message: '업데이트를 확인하는 중 오류가 발생했습니다.',
182
+ detail: String((err && err.message) || err),
183
+ });
184
+ }
185
+ })
186
+ .finally(() => {
187
+ updateCheckInFlight = false;
188
+ });
189
+ }
190
+
191
+ function setupAutoUpdater() {
192
+ if (!app.isPackaged) return;
193
+
194
+ autoUpdater.autoDownload = true;
195
+ autoUpdater.autoInstallOnAppQuit = true;
196
+
197
+ autoUpdater.on('error', (err) => {
198
+ console.error('[updater] error:', (err && err.message) || err);
199
+ });
200
+
201
+ autoUpdater.on('update-available', (info) => {
202
+ console.log('[updater] update available:', info && info.version);
203
+ });
204
+
205
+ autoUpdater.on('update-not-available', () => {
206
+ console.log('[updater] up-to-date');
207
+ });
208
+
209
+ autoUpdater.on('download-progress', (p) => {
210
+ console.log(`[updater] downloading ${Math.round(p.percent)}%`);
211
+ });
212
+
213
+ autoUpdater.on('update-downloaded', (info) => {
214
+ if (!mainWindow || mainWindow.isDestroyed()) return;
215
+ dialog
216
+ .showMessageBox(mainWindow, {
217
+ type: 'info',
218
+ buttons: ['지금 재시작', '나중에'],
219
+ defaultId: 0,
220
+ cancelId: 1,
221
+ title: 'CLITrigger 업데이트 준비 완료',
222
+ message: `새 버전 ${info && info.version}이(가) 다운로드되었습니다.`,
223
+ detail: '지금 재시작하면 업데이트가 적용됩니다. 나중에 선택 시 다음 종료 시점에 자동 설치됩니다.',
224
+ })
225
+ .then((result) => {
226
+ if (result.response === 0) autoUpdater.quitAndInstall();
227
+ });
228
+ });
229
+
230
+ setTimeout(() => checkForUpdates({ silent: true }), 5000);
142
231
  }
143
232
 
144
233
  function buildMenu() {
@@ -165,6 +254,11 @@ function buildMenu() {
165
254
  if (serverPort) shell.openExternal(`http://127.0.0.1:${serverPort}`);
166
255
  },
167
256
  },
257
+ { type: 'separator' },
258
+ {
259
+ label: '업데이트 확인',
260
+ click: () => checkForUpdates({ silent: false }),
261
+ },
168
262
  ],
169
263
  },
170
264
  ];
@@ -205,6 +299,7 @@ if (!gotLock) {
205
299
  const { port } = await bootServer();
206
300
  buildMenu();
207
301
  createWindow(port);
302
+ setupAutoUpdater();
208
303
  } catch (err) {
209
304
  dialog.showErrorBox(
210
305
  'CLITrigger failed to start',
@@ -1,3 +1,10 @@
1
- // Intentionally empty: the renderer talks to the local Express server over HTTP/WebSocket.
2
- // Kept as a placeholder so contextIsolation has a preload to attach to, and
3
- // future native bridges (file picker, clipboard, OS auth) have a home.
1
+ const { contextBridge, ipcRenderer } = require('electron');
2
+
3
+ // `imeReset` calls `webContents.focus()` in the main process to recover the
4
+ // native HWND keyboard focus when it gets stuck on xterm's helper textarea
5
+ // after a session has been interacted with — Korean IME on Windows EXE
6
+ // otherwise requires the user to alt-tab away and back to type into the
7
+ // SessionForm inputs.
8
+ contextBridge.exposeInMainWorld('electronAPI', {
9
+ imeReset: () => ipcRenderer.send('ime:reset'),
10
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clitrigger",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "Spawn isolated git worktrees and orchestrate Claude/Gemini/Codex CLI tasks in parallel from a web UI.",
5
5
  "keywords": [
6
6
  "claude",
@@ -75,6 +75,7 @@
75
75
  "cloudflared": "^0.7.1",
76
76
  "cors": "^2.8.5",
77
77
  "dotenv": "^16.4.7",
78
+ "electron-updater": "^6.8.3",
78
79
  "express": "^4.21.2",
79
80
  "express-rate-limit": "^8.3.1",
80
81
  "express-session": "^1.18.1",