claude-remote 0.4.3 → 0.4.4

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 (2) hide show
  1. package/package.json +1 -1
  2. package/server.js +30 -10
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-remote",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
4
4
  "description": "Remote control bridge for Claude Code REPL - drive from phone/WebUI",
5
5
  "main": "server.js",
6
6
  "bin": {
package/server.js CHANGED
@@ -194,9 +194,10 @@ let turnState = {
194
194
  version: 0,
195
195
  updatedAt: Date.now(),
196
196
  };
197
- let ttyInputForwarderAttached = false;
198
- let ttyInputHandler = null;
199
- let ttyResizeHandler = null;
197
+ let ttyInputForwarderAttached = false;
198
+ let ttyInputHandler = null;
199
+ let ttyResizeHandler = null;
200
+ let activeLinuxClipboardProc = null;
200
201
 
201
202
  // --- Permission approval state ---
202
203
  let approvalSeq = 0;
@@ -218,6 +219,18 @@ function formatTtyInputChunk(chunk) {
218
219
  const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
219
220
  return `len=${buf.length} hex=${buf.toString('hex')} base64=${buf.toString('base64')} utf8=${JSON.stringify(buf.toString('utf8'))}`;
220
221
  }
222
+
223
+ function clearActiveLinuxClipboardProc(reason = '') {
224
+ if (!activeLinuxClipboardProc) return;
225
+ const { child, tool } = activeLinuxClipboardProc;
226
+ activeLinuxClipboardProc = null;
227
+ try {
228
+ child.kill('SIGTERM');
229
+ log(`Linux clipboard process terminated (${tool}) reason=${reason || 'cleanup'}`);
230
+ } catch (err) {
231
+ log(`Linux clipboard process terminate error (${tool}): ${err.message}`);
232
+ }
233
+ }
221
234
 
222
235
  function wsLabel(ws) {
223
236
  const clientId = ws && ws._clientInstanceId ? ` client=${ws._clientInstanceId}` : '';
@@ -688,13 +701,15 @@ function startLinuxClipboardImage(tmpFile, mediaType) {
688
701
  const type = String(mediaType || 'image/png').toLowerCase();
689
702
  const tool = assertLinuxClipboardAvailable();
690
703
  const imageBuffer = fs.readFileSync(tmpFile);
704
+ clearActiveLinuxClipboardProc('replace');
691
705
  const args = tool === 'xclip'
692
- ? ['-selection', 'clipboard', '-t', type, '-i', '-loops', '1']
693
- : ['--type', type, '--paste-once'];
706
+ ? ['-selection', 'clipboard', '-t', type, '-i']
707
+ : ['--type', type];
694
708
  const child = spawn(tool, args, {
695
709
  detached: true,
696
710
  stdio: ['pipe', 'ignore', 'pipe'],
697
711
  });
712
+ activeLinuxClipboardProc = { child, tool };
698
713
  let stderr = '';
699
714
  child.on('error', (err) => {
700
715
  log(`Linux clipboard process error (${tool}): ${err.message}`);
@@ -704,6 +719,7 @@ function startLinuxClipboardImage(tmpFile, mediaType) {
704
719
  if (stderr.length > 2000) stderr = stderr.slice(-2000);
705
720
  });
706
721
  child.on('exit', (code, signal) => {
722
+ if (activeLinuxClipboardProc && activeLinuxClipboardProc.child === child) activeLinuxClipboardProc = null;
707
723
  const extra = stderr.trim() ? ` stderr=${JSON.stringify(stderr.trim())}` : '';
708
724
  log(`Linux clipboard process exited (${tool}) code=${code ?? 'null'} signal=${signal ?? 'null'}${extra}`);
709
725
  });
@@ -1736,11 +1752,15 @@ function handlePreparedImageUpload({ tmpFile, mediaType, text, logLabel = '', on
1736
1752
  if (trimmedText) claudeProc.write(trimmedText);
1737
1753
 
1738
1754
  setTimeout(() => {
1739
- if (claudeProc) claudeProc.write('\r');
1740
- log('Sent Enter after image paste' + (trimmedText ? ` + text: "${trimmedText.substring(0, 60)}"` : ''));
1741
-
1742
- setTimeout(() => {
1743
- if (onCleanup) onCleanup();
1755
+ if (claudeProc) claudeProc.write('\r');
1756
+ log('Sent Enter after image paste' + (trimmedText ? ` + text: "${trimmedText.substring(0, 60)}"` : ''));
1757
+
1758
+ if (!isWin && !isMac) {
1759
+ setTimeout(() => clearActiveLinuxClipboardProc('post-paste'), 1000);
1760
+ }
1761
+
1762
+ setTimeout(() => {
1763
+ if (onCleanup) onCleanup();
1744
1764
  else {
1745
1765
  try { fs.unlinkSync(tmpFile); } catch {}
1746
1766
  }