claude-remote-cli 1.9.4 → 1.9.6

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/public/app.js +54 -15
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-remote-cli",
3
- "version": "1.9.4",
3
+ "version": "1.9.6",
4
4
  "description": "Remote web interface for Claude Code CLI sessions",
5
5
  "type": "module",
6
6
  "main": "dist/server/index.js",
package/public/app.js CHANGED
@@ -1286,16 +1286,32 @@
1286
1286
  (function () {
1287
1287
  if (!isMobileDevice) return;
1288
1288
 
1289
- // ── Debug Panel (temporary) ──
1289
+ // ── Debug Panel (hidden by default, toggle with button) ──
1290
1290
  var debugPanel = document.createElement('div');
1291
1291
  debugPanel.id = 'debug-panel';
1292
- debugPanel.style.cssText = 'position:fixed;top:0;left:0;right:0;height:30vh;overflow-y:auto;background:rgba(0,0,0,0.92);color:#0f0;font:11px/1.4 monospace;padding:6px;z-index:9999;pointer-events:auto;';
1292
+ debugPanel.style.cssText = 'position:fixed;top:0;left:0;right:0;height:30vh;overflow-y:auto;background:rgba(0,0,0,0.92);color:#0f0;font:11px/1.4 monospace;padding:6px 6px 6px 40px;z-index:9999;display:none;';
1293
1293
  document.body.appendChild(debugPanel);
1294
+
1295
+ var debugToggle = document.createElement('button');
1296
+ debugToggle.id = 'debug-toggle';
1297
+ debugToggle.textContent = 'dbg';
1298
+ debugToggle.style.cssText = 'position:fixed;bottom:60px;right:8px;z-index:10000;background:#333;color:#0f0;border:1px solid #0f0;border-radius:6px;font:12px monospace;padding:6px 10px;opacity:0.5;min-width:44px;min-height:44px;';
1299
+ document.body.appendChild(debugToggle);
1300
+
1301
+ var debugVisible = false;
1302
+ debugToggle.addEventListener('click', function (e) {
1303
+ e.preventDefault();
1304
+ e.stopPropagation();
1305
+ debugVisible = !debugVisible;
1306
+ debugPanel.style.display = debugVisible ? 'block' : 'none';
1307
+ debugToggle.style.opacity = debugVisible ? '1' : '0.6';
1308
+ });
1309
+
1294
1310
  var debugLines = [];
1295
1311
  function dbg(msg) {
1296
1312
  var t = performance.now().toFixed(1);
1297
1313
  debugLines.push('[' + t + '] ' + msg);
1298
- if (debugLines.length > 60) debugLines.shift();
1314
+ if (debugLines.length > 200) debugLines.shift();
1299
1315
  debugPanel.innerHTML = debugLines.join('<br>');
1300
1316
  debugPanel.scrollTop = debugPanel.scrollHeight;
1301
1317
  }
@@ -1343,11 +1359,33 @@
1343
1359
  return count;
1344
1360
  }
1345
1361
 
1362
+ // Batched send: accumulates payload across rapid input events (e.g. autocorrect
1363
+ // fires deleteContentBackward + insertText ~2ms apart) and flushes in one
1364
+ // ws.send() so the PTY receives backspaces + replacement text atomically.
1365
+ var sendBuffer = '';
1366
+ var sendTimer = null;
1367
+ var SEND_DELAY = 10; // ms – enough to batch autocorrect pairs, imperceptible for typing
1368
+
1369
+ function scheduleSend(data) {
1370
+ sendBuffer += data;
1371
+ if (sendTimer !== null) clearTimeout(sendTimer);
1372
+ sendTimer = setTimeout(flushSendBuffer, SEND_DELAY);
1373
+ }
1374
+
1375
+ function flushSendBuffer() {
1376
+ sendTimer = null;
1377
+ if (sendBuffer && ws && ws.readyState === WebSocket.OPEN) {
1378
+ dbg('FLUSH: "' + sendBuffer.replace(/\x7f/g, '\u232b') + '" (' + sendBuffer.length + ' bytes)');
1379
+ ws.send(sendBuffer);
1380
+ }
1381
+ sendBuffer = '';
1382
+ }
1383
+
1346
1384
  // Send the diff between lastInputValue and currentValue to the terminal.
1347
1385
  // Handles autocorrect expansions, deletions, and same-length replacements.
1348
1386
  function sendInputDiff(currentValue) {
1349
1387
  if (currentValue === lastInputValue) {
1350
- dbg(' sendInputDiff: NO-OP (same)');
1388
+ dbg('sendInputDiff: NO-OP (same)');
1351
1389
  return;
1352
1390
  }
1353
1391
 
@@ -1356,13 +1394,15 @@
1356
1394
  var charsToDelete = codepointCount(deletedSlice);
1357
1395
  var newChars = currentValue.slice(commonLen);
1358
1396
 
1359
- dbg(' sendInputDiff: del=' + charsToDelete + ' "' + deletedSlice + '" add="' + newChars + '"');
1397
+ dbg('sendInputDiff: del=' + charsToDelete + ' "' + deletedSlice + '" add="' + newChars + '"');
1360
1398
 
1399
+ var payload = '';
1361
1400
  for (var i = 0; i < charsToDelete; i++) {
1362
- ws.send('\x7f'); // backspace
1401
+ payload += '\x7f';
1363
1402
  }
1364
- if (newChars) {
1365
- ws.send(newChars);
1403
+ payload += newChars;
1404
+ if (payload) {
1405
+ scheduleSend(payload);
1366
1406
  }
1367
1407
  }
1368
1408
 
@@ -1397,9 +1437,7 @@
1397
1437
  lastInputValue = '';
1398
1438
  });
1399
1439
 
1400
- // Flush any pending composed text to the terminal.
1401
- // Safe to call even if compositionend already ran: sendInputDiff
1402
- // is a no-op when lastInputValue === mobileInput.value.
1440
+ // Flush any pending composed text and buffered sends to the terminal.
1403
1441
  function flushComposedText() {
1404
1442
  isComposing = false;
1405
1443
  if (ws && ws.readyState === WebSocket.OPEN) {
@@ -1407,6 +1445,7 @@
1407
1445
  sendInputDiff(currentValue);
1408
1446
  lastInputValue = currentValue;
1409
1447
  }
1448
+ flushSendBuffer();
1410
1449
  }
1411
1450
  function clearInput() {
1412
1451
  mobileInput.value = '';
@@ -1418,6 +1457,10 @@
1418
1457
 
1419
1458
  // Handle text input with autocorrect
1420
1459
  var clearTimer = null;
1460
+ mobileInput.addEventListener('beforeinput', function (e) {
1461
+ dbg('BEFORE_INPUT type="' + e.inputType + '" data="' + (e.data || '') + '" composing=' + isComposing);
1462
+ });
1463
+
1421
1464
  mobileInput.addEventListener('input', function (e) {
1422
1465
  dbg('INPUT type="' + e.inputType + '" composing=' + isComposing + ' val="' + mobileInput.value + '" last="' + lastInputValue + '"');
1423
1466
 
@@ -1441,10 +1484,6 @@
1441
1484
  lastInputValue = currentValue;
1442
1485
  });
1443
1486
 
1444
- mobileInput.addEventListener('beforeinput', function (e) {
1445
- dbg('BEFORE_INPUT type="' + e.inputType + '" data="' + (e.data || '') + '" composing=' + isComposing);
1446
- });
1447
-
1448
1487
  // Handle special keys (Enter, Backspace, Escape, arrows, Tab)
1449
1488
  mobileInput.addEventListener('keydown', function (e) {
1450
1489
  dbg('KEYDOWN key="' + e.key + '" shift=' + e.shiftKey + ' composing=' + isComposing + ' val="' + mobileInput.value + '"');