claude-opencode-viewer 2.1.7 → 2.1.9

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 (3) hide show
  1. package/index.html +4 -3
  2. package/package.json +1 -1
  3. package/server.js +40 -13
package/index.html CHANGED
@@ -145,7 +145,7 @@
145
145
  var isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent);
146
146
  var MOBILE_COLS = 60;
147
147
  var fontSize = isMobile ? 11 : 13;
148
- var currentMode = 'claude';
148
+ var currentMode = 'opencode';
149
149
  var isTransitioning = false;
150
150
 
151
151
  var term = new Terminal({
@@ -369,13 +369,11 @@
369
369
  function startTransition() {
370
370
  isTransitioning = true;
371
371
  terminalEl.classList.add('transitioning');
372
- modeIndicator.textContent = '切换中...';
373
372
  }
374
373
 
375
374
  function endTransition(mode) {
376
375
  currentMode = mode;
377
376
  modeSelect.value = mode;
378
- modeIndicator.textContent = mode === 'claude' ? 'Claude' : 'OpenCode';
379
377
  terminalEl.classList.remove('transitioning');
380
378
  isTransitioning = false;
381
379
  }
@@ -390,6 +388,9 @@
390
388
  switchMode(modeSelect.value);
391
389
  });
392
390
 
391
+ // 设置初始选中项
392
+ modeSelect.value = currentMode;
393
+
393
394
  function connect() {
394
395
  var proto = location.protocol === 'https:' ? 'wss:' : 'ws:';
395
396
  ws = new WebSocket(proto + '//' + location.host + '/ws');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-opencode-viewer",
3
- "version": "2.1.7",
3
+ "version": "2.1.9",
4
4
  "description": "A unified terminal viewer for Claude Code and OpenCode with seamless switching",
5
5
  "type": "module",
6
6
  "main": "server.js",
package/server.js CHANGED
@@ -30,6 +30,7 @@ let lastPtyRows = 30;
30
30
  let activeWs = null;
31
31
  const clientSizes = new Map();
32
32
  const mobileClients = new Set();
33
+ let currentMode = 'opencode';
33
34
 
34
35
  function getMobileSize() {
35
36
  for (const mws of mobileClients) {
@@ -133,18 +134,25 @@ async function spawnProcess(mode) {
133
134
  }
134
135
  });
135
136
 
137
+ // 只在初始化时杀死旧进程,switchMode 已经处理了切换时的进程清理
136
138
  if (mode === 'claude') {
137
- if (claudeProcess?.pid) {
138
- try { claudeProcess.kill(); } catch {}
139
+ if (claudeProcess && claudeProcess !== proc && claudeProcess.pid) {
140
+ try {
141
+ console.log(`[spawnProcess] 清理旧 claude 进程 PID: ${claudeProcess.pid}`);
142
+ claudeProcess.kill();
143
+ } catch {}
139
144
  }
140
145
  claudeProcess = proc;
141
146
  } else {
142
- if (opencodeProcess?.pid) {
143
- try { opencodeProcess.kill(); } catch {}
147
+ if (opencodeProcess && opencodeProcess !== proc && opencodeProcess.pid) {
148
+ try {
149
+ console.log(`[spawnProcess] 清理旧 opencode 进程 PID: ${opencodeProcess.pid}`);
150
+ opencodeProcess.kill();
151
+ } catch {}
144
152
  }
145
153
  opencodeProcess = proc;
146
154
  }
147
-
155
+
148
156
  currentProcess = proc;
149
157
  console.log(`[claude-opencode-viewer] ${mode === 'claude' ? 'Claude Code' : 'OpenCode'} 已启动 (PID: ${proc.pid})`);
150
158
  return proc;
@@ -152,24 +160,43 @@ async function spawnProcess(mode) {
152
160
 
153
161
  async function switchMode(newMode) {
154
162
  if (newMode === currentMode) return;
155
-
163
+
164
+ console.log(`[switchMode] 从 ${currentMode} 切换到 ${newMode}`);
165
+
156
166
  // 清空所有历史输出
157
167
  outputBuffer = '';
158
-
168
+
159
169
  // 杀死旧进程
160
170
  if (currentMode === 'claude' && claudeProcess) {
161
- try { claudeProcess.kill(); } catch {}
171
+ try {
172
+ console.log(`[switchMode] 杀死 claude 进程 PID: ${claudeProcess.pid}`);
173
+ claudeProcess.kill();
174
+ } catch (e) {
175
+ console.log('[switchMode] 杀死 claude 进程失败:', e.message);
176
+ }
162
177
  claudeProcess = null;
163
178
  } else if (currentMode === 'opencode' && opencodeProcess) {
164
- try { opencodeProcess.kill(); } catch {}
179
+ try {
180
+ console.log(`[switchMode] 杀死 opencode 进程 PID: ${opencodeProcess.pid}`);
181
+ opencodeProcess.kill();
182
+ } catch (e) {
183
+ console.log('[switchMode] 杀死 opencode 进程失败:', e.message);
184
+ }
165
185
  opencodeProcess = null;
166
186
  }
167
187
  currentProcess = null;
168
-
188
+
189
+ // 等待一小段时间确保进程完全退出
190
+ await new Promise(resolve => setTimeout(resolve, 100));
191
+
169
192
  // 切换到新模式
170
193
  currentMode = newMode;
171
- await spawnProcess(newMode);
172
- console.log(`[CombinedV2] 切换到 ${newMode}`);
194
+ try {
195
+ await spawnProcess(newMode);
196
+ console.log(`[switchMode] 切换到 ${newMode} 成功`);
197
+ } catch (e) {
198
+ console.error('[switchMode] 启动新进程失败:', e.message);
199
+ }
173
200
  }
174
201
 
175
202
  function writeToPty(data) {
@@ -308,5 +335,5 @@ server.listen(PORT, '0.0.0.0', async () => {
308
335
  console.log('='.repeat(50));
309
336
  console.log('\n按 Ctrl+C 停止服务\n');
310
337
 
311
- await spawnProcess('claude');
338
+ await spawnProcess('opencode');
312
339
  });