claude-remote-cli 1.9.2 → 1.9.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-remote-cli",
3
- "version": "1.9.2",
3
+ "version": "1.9.4",
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
@@ -1108,8 +1108,8 @@
1108
1108
  var text = btn.dataset.text;
1109
1109
  var key = btn.dataset.key;
1110
1110
 
1111
- // Flush composed text before sending Enter so pending input isn't lost
1112
- if (key === '\r' && mobileInput.flushComposedText) {
1111
+ // Flush composed text before sending Enter/newline so pending input isn't lost
1112
+ if ((key === '\r' || key === '\x1b[13;2u') && mobileInput.flushComposedText) {
1113
1113
  mobileInput.flushComposedText();
1114
1114
  }
1115
1115
 
@@ -1119,8 +1119,8 @@
1119
1119
  ws.send(key);
1120
1120
  }
1121
1121
 
1122
- // Clear input after Enter to reset state
1123
- if (key === '\r' && mobileInput.clearInput) {
1122
+ // Clear input after Enter/newline to reset state
1123
+ if ((key === '\r' || key === '\x1b[13;2u') && mobileInput.clearInput) {
1124
1124
  mobileInput.clearInput();
1125
1125
  }
1126
1126
 
@@ -1286,6 +1286,20 @@
1286
1286
  (function () {
1287
1287
  if (!isMobileDevice) return;
1288
1288
 
1289
+ // ── Debug Panel (temporary) ──
1290
+ var debugPanel = document.createElement('div');
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;';
1293
+ document.body.appendChild(debugPanel);
1294
+ var debugLines = [];
1295
+ function dbg(msg) {
1296
+ var t = performance.now().toFixed(1);
1297
+ debugLines.push('[' + t + '] ' + msg);
1298
+ if (debugLines.length > 60) debugLines.shift();
1299
+ debugPanel.innerHTML = debugLines.join('<br>');
1300
+ debugPanel.scrollTop = debugPanel.scrollHeight;
1301
+ }
1302
+
1289
1303
  var lastInputValue = '';
1290
1304
  var isComposing = false;
1291
1305
 
@@ -1332,13 +1346,18 @@
1332
1346
  // Send the diff between lastInputValue and currentValue to the terminal.
1333
1347
  // Handles autocorrect expansions, deletions, and same-length replacements.
1334
1348
  function sendInputDiff(currentValue) {
1335
- if (currentValue === lastInputValue) return;
1349
+ if (currentValue === lastInputValue) {
1350
+ dbg(' sendInputDiff: NO-OP (same)');
1351
+ return;
1352
+ }
1336
1353
 
1337
1354
  var commonLen = commonPrefixLength(lastInputValue, currentValue);
1338
1355
  var deletedSlice = lastInputValue.slice(commonLen);
1339
1356
  var charsToDelete = codepointCount(deletedSlice);
1340
1357
  var newChars = currentValue.slice(commonLen);
1341
1358
 
1359
+ dbg(' sendInputDiff: del=' + charsToDelete + ' "' + deletedSlice + '" add="' + newChars + '"');
1360
+
1342
1361
  for (var i = 0; i < charsToDelete; i++) {
1343
1362
  ws.send('\x7f'); // backspace
1344
1363
  }
@@ -1347,11 +1366,17 @@
1347
1366
  }
1348
1367
  }
1349
1368
 
1350
- mobileInput.addEventListener('compositionstart', function () {
1369
+ mobileInput.addEventListener('compositionstart', function (e) {
1370
+ dbg('COMP_START data="' + e.data + '" val="' + mobileInput.value + '" last="' + lastInputValue + '"');
1351
1371
  isComposing = true;
1352
1372
  });
1353
1373
 
1354
- mobileInput.addEventListener('compositionend', function () {
1374
+ mobileInput.addEventListener('compositionupdate', function (e) {
1375
+ dbg('COMP_UPDATE data="' + e.data + '" val="' + mobileInput.value + '"');
1376
+ });
1377
+
1378
+ mobileInput.addEventListener('compositionend', function (e) {
1379
+ dbg('COMP_END data="' + e.data + '" val="' + mobileInput.value + '" last="' + lastInputValue + '"');
1355
1380
  isComposing = false;
1356
1381
  if (ws && ws.readyState === WebSocket.OPEN) {
1357
1382
  var currentValue = mobileInput.value;
@@ -1393,25 +1418,36 @@
1393
1418
 
1394
1419
  // Handle text input with autocorrect
1395
1420
  var clearTimer = null;
1396
- mobileInput.addEventListener('input', function () {
1421
+ mobileInput.addEventListener('input', function (e) {
1422
+ dbg('INPUT type="' + e.inputType + '" composing=' + isComposing + ' val="' + mobileInput.value + '" last="' + lastInputValue + '"');
1423
+
1397
1424
  // Reset the auto-clear timer to prevent unbounded growth
1398
1425
  if (clearTimer) clearTimeout(clearTimer);
1399
1426
  clearTimer = setTimeout(function () {
1427
+ dbg('TIMER_CLEAR val="' + mobileInput.value + '"');
1400
1428
  mobileInput.value = '';
1401
1429
  lastInputValue = '';
1402
1430
  }, 5000);
1403
1431
 
1404
1432
  if (!ws || ws.readyState !== WebSocket.OPEN) return;
1405
1433
 
1406
- if (isComposing) return;
1434
+ if (isComposing) {
1435
+ dbg(' INPUT: skipped (composing)');
1436
+ return;
1437
+ }
1407
1438
 
1408
1439
  var currentValue = mobileInput.value;
1409
1440
  sendInputDiff(currentValue);
1410
1441
  lastInputValue = currentValue;
1411
1442
  });
1412
1443
 
1444
+ mobileInput.addEventListener('beforeinput', function (e) {
1445
+ dbg('BEFORE_INPUT type="' + e.inputType + '" data="' + (e.data || '') + '" composing=' + isComposing);
1446
+ });
1447
+
1413
1448
  // Handle special keys (Enter, Backspace, Escape, arrows, Tab)
1414
1449
  mobileInput.addEventListener('keydown', function (e) {
1450
+ dbg('KEYDOWN key="' + e.key + '" shift=' + e.shiftKey + ' composing=' + isComposing + ' val="' + mobileInput.value + '"');
1415
1451
  if (!ws || ws.readyState !== WebSocket.OPEN) return;
1416
1452
 
1417
1453
  var handled = true;
@@ -1419,7 +1455,11 @@
1419
1455
  switch (e.key) {
1420
1456
  case 'Enter':
1421
1457
  flushComposedText();
1422
- ws.send('\r');
1458
+ if (e.shiftKey) {
1459
+ ws.send('\x1b[13;2u'); // kitty protocol: Shift+Enter (newline)
1460
+ } else {
1461
+ ws.send('\r');
1462
+ }
1423
1463
  mobileInput.value = '';
1424
1464
  lastInputValue = '';
1425
1465
  break;
package/public/index.html CHANGED
@@ -79,10 +79,12 @@
79
79
  <button class="tb-btn tb-arrow" data-key="&#x1b;[A" aria-label="Up arrow">&#8593;</button>
80
80
  <button class="tb-btn" data-key="&#x1b;" aria-label="Escape">Esc</button>
81
81
  <button class="tb-btn" id="upload-image-btn" aria-label="Upload image">&#128247;</button>
82
+ <button class="tb-btn" data-key="&#x04;" aria-label="Ctrl+D">^D</button>
82
83
  <button class="tb-btn" data-key="&#x03;" aria-label="Ctrl+C">^C</button>
83
84
  <button class="tb-btn tb-arrow" data-key="&#x1b;[D" aria-label="Left arrow">&#8592;</button>
84
85
  <button class="tb-btn tb-arrow" data-key="&#x1b;[B" aria-label="Down arrow">&#8595;</button>
85
86
  <button class="tb-btn tb-arrow" data-key="&#x1b;[C" aria-label="Right arrow">&#8594;</button>
87
+ <button class="tb-btn tb-newline" data-key="&#x1b;[13;2u" aria-label="Shift+Enter (newline)">&#8679;&#9166;</button>
86
88
  <button class="tb-btn tb-enter" data-key="&#x0d;" aria-label="Enter">&#9166;</button>
87
89
  </div>
88
90
  </div>
package/public/style.css CHANGED
@@ -521,7 +521,7 @@ html, body {
521
521
 
522
522
  .toolbar-grid {
523
523
  display: grid;
524
- grid-template-columns: repeat(5, 1fr);
524
+ grid-template-columns: repeat(6, 1fr);
525
525
  grid-template-rows: auto auto;
526
526
  gap: 4px;
527
527
  max-width: 500px;