pinokiod 3.271.0 → 3.273.0

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/kernel/ansi_stream_tracker.js +115 -0
  2. package/kernel/api/app/index.js +422 -0
  3. package/kernel/api/htmlmodal/index.js +94 -0
  4. package/kernel/app_launcher/index.js +115 -0
  5. package/kernel/app_launcher/platform/base.js +276 -0
  6. package/kernel/app_launcher/platform/linux.js +229 -0
  7. package/kernel/app_launcher/platform/macos.js +163 -0
  8. package/kernel/app_launcher/platform/unsupported.js +34 -0
  9. package/kernel/app_launcher/platform/windows.js +247 -0
  10. package/kernel/bin/conda-meta.js +93 -0
  11. package/kernel/bin/conda.js +2 -4
  12. package/kernel/bin/index.js +2 -4
  13. package/kernel/index.js +7 -0
  14. package/kernel/shell.js +212 -1
  15. package/package.json +1 -1
  16. package/server/index.js +491 -6
  17. package/server/public/common.js +224 -741
  18. package/server/public/create-launcher.js +754 -0
  19. package/server/public/htmlmodal.js +292 -0
  20. package/server/public/logs.js +715 -0
  21. package/server/public/resizeSync.js +117 -0
  22. package/server/public/style.css +653 -8
  23. package/server/public/tab-idle-notifier.js +34 -59
  24. package/server/public/tab-link-popover.js +7 -10
  25. package/server/public/terminal-settings.js +723 -9
  26. package/server/public/terminal_input_utils.js +72 -0
  27. package/server/public/terminal_key_caption.js +187 -0
  28. package/server/public/urldropdown.css +120 -3
  29. package/server/public/xterm-inline-bridge.js +116 -0
  30. package/server/socket.js +29 -0
  31. package/server/views/agents.ejs +1 -2
  32. package/server/views/app.ejs +55 -28
  33. package/server/views/bookmarklet.ejs +1 -1
  34. package/server/views/bootstrap.ejs +1 -0
  35. package/server/views/connect.ejs +1 -2
  36. package/server/views/create.ejs +63 -0
  37. package/server/views/editor.ejs +36 -4
  38. package/server/views/index.ejs +1 -2
  39. package/server/views/index2.ejs +1 -2
  40. package/server/views/init/index.ejs +36 -28
  41. package/server/views/install.ejs +20 -22
  42. package/server/views/layout.ejs +2 -8
  43. package/server/views/logs.ejs +155 -0
  44. package/server/views/mini.ejs +0 -18
  45. package/server/views/net.ejs +2 -2
  46. package/server/views/network.ejs +1 -2
  47. package/server/views/network2.ejs +1 -2
  48. package/server/views/old_network.ejs +1 -2
  49. package/server/views/pro.ejs +26 -23
  50. package/server/views/prototype/index.ejs +30 -34
  51. package/server/views/screenshots.ejs +1 -2
  52. package/server/views/settings.ejs +1 -20
  53. package/server/views/shell.ejs +59 -66
  54. package/server/views/terminal.ejs +118 -73
  55. package/server/views/tools.ejs +1 -2
package/kernel/shell.js CHANGED
@@ -17,6 +17,7 @@ const unparse = require('yargs-unparser-custom-flag');
17
17
  const Util = require('./util')
18
18
  const Environment = require('./environment')
19
19
  const ShellParser = require('./shell_parser')
20
+ const AnsiStreamTracker = require('./ansi_stream_tracker')
20
21
  const home = os.homedir()
21
22
 
22
23
  // xterm.js currently ignores DECSYNCTERM (CSI ? 2026 h/l) and renders it as text on Windows.
@@ -48,6 +49,19 @@ class Shell {
48
49
  }
49
50
  }
50
51
  this.decsyncBuffer = ''
52
+ this.nudgeRestoreTimer = null
53
+ this.nudging = false
54
+ this.nudgeReleaseTimer = null
55
+ this.lastInputAt = 0
56
+ this.canNudge = true
57
+ this.awaitingIdleNudge = false
58
+ this.idleNudgeTimer = null
59
+ this.idleNudgeDelay = 100
60
+ this.ignoreNudgeOutput = false
61
+ this.userActive = false
62
+ this.userActiveTimer = null
63
+ this.userActiveTimeout = 1000
64
+ this.ansiTracker = new AnsiStreamTracker()
51
65
 
52
66
  // Windows: /D => ignore AutoRun Registry Key
53
67
  // Others: --noprofile => ignore .bash_profile, --norc => ignore .bashrc
@@ -229,6 +243,25 @@ class Shell {
229
243
  }
230
244
  async start(params, ondata) {
231
245
  this.ondata = ondata
246
+ if (this.nudgeRestoreTimer) {
247
+ clearTimeout(this.nudgeRestoreTimer)
248
+ this.nudgeRestoreTimer = null
249
+ }
250
+ if (this.nudgeReleaseTimer) {
251
+ clearTimeout(this.nudgeReleaseTimer)
252
+ this.nudgeReleaseTimer = null
253
+ }
254
+ this.cancelIdleNudge()
255
+ this.nudging = false
256
+ this.lastInputAt = 0
257
+ this.canNudge = true
258
+ this.ignoreNudgeOutput = false
259
+ if (this.userActiveTimer) {
260
+ clearTimeout(this.userActiveTimer)
261
+ this.userActiveTimer = null
262
+ }
263
+ this.userActive = false
264
+ this.decsyncBuffer = ''
232
265
 
233
266
  /*
234
267
  params := {
@@ -383,6 +416,9 @@ class Shell {
383
416
  // return this.id
384
417
  }
385
418
  resize({ cols, rows }) {
419
+ // console.log("RESIZE", { cols, rows })
420
+ this.cols = cols
421
+ this.rows = rows
386
422
  this.ptyProcess.resize(cols, rows)
387
423
  this.vt.resize(cols, rows)
388
424
  }
@@ -400,6 +436,8 @@ class Shell {
400
436
  chunk_size = 1024
401
437
  }
402
438
  // console.log({ interactive: this.params.interactive, chunk_size })
439
+ this.canNudge = true
440
+ this.cancelIdleNudge()
403
441
  for(let i=0; i<message.length; i+=chunk_size) {
404
442
  let chunk = message.slice(i, i+chunk_size)
405
443
  // console.log("write chunk", { i, chunk })
@@ -417,9 +455,15 @@ class Shell {
417
455
  if (this.input) {
418
456
  if (this.ptyProcess) {
419
457
  if (message.length > 1024) {
458
+ this.lastInputAt = Date.now()
459
+ this.canNudge = true
460
+ this.cancelIdleNudge()
420
461
  this.emit2(message)
421
462
  } else {
422
463
  this.ptyProcess.write(message)
464
+ this.lastInputAt = Date.now()
465
+ this.canNudge = true
466
+ this.cancelIdleNudge()
423
467
  }
424
468
  }
425
469
  }
@@ -433,15 +477,27 @@ class Shell {
433
477
  for(let m of message) {
434
478
  this.cmd = this.build({ message: m })
435
479
  this.ptyProcess.write(this.cmd)
480
+ this.lastInputAt = Date.now()
481
+ this.canNudge = true
482
+ this.cancelIdleNudge()
436
483
  if (newline) {
437
484
  this.ptyProcess.write(this.EOL)
485
+ this.lastInputAt = Date.now()
486
+ this.canNudge = true
487
+ this.cancelIdleNudge()
438
488
  }
439
489
  }
440
490
  } else {
441
491
  this.cmd = this.build({ message })
442
492
  this.ptyProcess.write(this.cmd)
493
+ this.lastInputAt = Date.now()
494
+ this.canNudge = true
495
+ this.cancelIdleNudge()
443
496
  if (newline) {
444
497
  this.ptyProcess.write(this.EOL)
498
+ this.lastInputAt = Date.now()
499
+ this.canNudge = true
500
+ this.cancelIdleNudge()
445
501
  }
446
502
  }
447
503
  })
@@ -457,11 +513,17 @@ class Shell {
457
513
  this.cmd = this.build({ message: m })
458
514
  this.ptyProcess.write(this.cmd)
459
515
  this.ptyProcess.write(this.EOL)
516
+ this.lastInputAt = Date.now()
517
+ this.canNudge = true
518
+ this.cancelIdleNudge()
460
519
  }
461
520
  } else {
462
521
  this.cmd = this.build({ message })
463
522
  this.ptyProcess.write(this.cmd)
464
523
  this.ptyProcess.write(this.EOL)
524
+ this.lastInputAt = Date.now()
525
+ this.canNudge = true
526
+ this.cancelIdleNudge()
465
527
  }
466
528
  })
467
529
  }
@@ -473,6 +535,9 @@ class Shell {
473
535
  this.resolve = resolve
474
536
  this.cmd = this.build({ message })
475
537
  this.ptyProcess.write(this.cmd)
538
+ this.lastInputAt = Date.now()
539
+ this.canNudge = true
540
+ this.cancelIdleNudge()
476
541
  })
477
542
  }
478
543
  }
@@ -1113,7 +1178,12 @@ class Shell {
1113
1178
  data = data.replace(/\x1b\[6n/g, ''); // remove the code
1114
1179
  }
1115
1180
 
1116
- this.queue.push(this.filterDecsync(data))
1181
+ const filtered = this.filterDecsync(data)
1182
+ if (this.awaitingIdleNudge) {
1183
+ this.scheduleIdleNudge()
1184
+ }
1185
+ this.maybeNudgeForSequences(filtered)
1186
+ this.queue.push(filtered)
1117
1187
  }
1118
1188
  });
1119
1189
  }
@@ -1143,6 +1213,24 @@ class Shell {
1143
1213
 
1144
1214
  this.done = true
1145
1215
  this.ready = false
1216
+ if (this.nudgeRestoreTimer) {
1217
+ clearTimeout(this.nudgeRestoreTimer)
1218
+ this.nudgeRestoreTimer = null
1219
+ }
1220
+ if (this.nudgeReleaseTimer) {
1221
+ clearTimeout(this.nudgeReleaseTimer)
1222
+ this.nudgeReleaseTimer = null
1223
+ }
1224
+ this.cancelIdleNudge()
1225
+ this.nudging = false
1226
+ this.lastInputAt = 0
1227
+ this.canNudge = true
1228
+ this.ignoreNudgeOutput = false
1229
+ if (this.userActiveTimer) {
1230
+ clearTimeout(this.userActiveTimer)
1231
+ this.userActiveTimer = null
1232
+ }
1233
+ this.userActive = false
1146
1234
 
1147
1235
  let buf = this.vts.serialize()
1148
1236
  let cleaned = this.stripAnsi(buf)
@@ -1260,6 +1348,129 @@ class Shell {
1260
1348
 
1261
1349
  return result
1262
1350
  }
1351
+ setUserActive(active, ttl) {
1352
+ const clearTimer = () => {
1353
+ if (this.userActiveTimer) {
1354
+ clearTimeout(this.userActiveTimer)
1355
+ this.userActiveTimer = null
1356
+ }
1357
+ }
1358
+ if (active) {
1359
+ this.userActive = true
1360
+ this.lastInputAt = Date.now()
1361
+ const parsedTtl = Number(ttl)
1362
+ const timeout = Number.isFinite(parsedTtl) ? parsedTtl : this.userActiveTimeout
1363
+ clearTimer()
1364
+ if (timeout > 0) {
1365
+ this.userActiveTimer = setTimeout(() => {
1366
+ this.userActive = false
1367
+ this.userActiveTimer = null
1368
+ }, timeout)
1369
+ }
1370
+ this.cancelIdleNudge()
1371
+ } else {
1372
+ clearTimer()
1373
+ this.userActive = false
1374
+ }
1375
+ }
1376
+ maybeNudgeForSequences(chunk = '') {
1377
+ if (!chunk || typeof chunk !== 'string') {
1378
+ return
1379
+ }
1380
+ const detection = this.ansiTracker.push(chunk)
1381
+ if (!detection) {
1382
+ return
1383
+ }
1384
+ if (this.ignoreNudgeOutput || this.userActive) {
1385
+ return
1386
+ }
1387
+ if (this.nudging || !this.canNudge) {
1388
+ // console.log('[nudge] guard: nudging/canNudge', { nudging: this.nudging, canNudge: this.canNudge, reason: detection.reason })
1389
+ return
1390
+ }
1391
+ const sinceInput = Date.now() - this.lastInputAt
1392
+ if (sinceInput < 200) {
1393
+ // console.log('[nudge] guard: recent input', { sinceInput, reason: detection.reason })
1394
+ return
1395
+ }
1396
+ // console.log('[nudge] scheduling idle nudge', {
1397
+ // reason: detection.reason,
1398
+ // sinceInput,
1399
+ // preview: chunk.slice(0, 160)
1400
+ // })
1401
+ this.requestIdleNudge()
1402
+ }
1403
+ cancelIdleNudge() {
1404
+ if (this.idleNudgeTimer) {
1405
+ clearTimeout(this.idleNudgeTimer)
1406
+ this.idleNudgeTimer = null
1407
+ }
1408
+ this.awaitingIdleNudge = false
1409
+ }
1410
+ requestIdleNudge() {
1411
+ if (this.awaitingIdleNudge || this.nudging || !this.canNudge) {
1412
+ return
1413
+ }
1414
+ this.awaitingIdleNudge = true
1415
+ this.scheduleIdleNudge()
1416
+ }
1417
+ scheduleIdleNudge() {
1418
+ if (!this.awaitingIdleNudge) {
1419
+ return
1420
+ }
1421
+ const delay = this.idleNudgeDelay || 500
1422
+ if (this.idleNudgeTimer) {
1423
+ clearTimeout(this.idleNudgeTimer)
1424
+ }
1425
+ this.idleNudgeTimer = setTimeout(() => {
1426
+ if (this.nudging || !this.canNudge) {
1427
+ this.cancelIdleNudge()
1428
+ return
1429
+ }
1430
+ this.idleNudgeTimer = null
1431
+ this.awaitingIdleNudge = false
1432
+ this.canNudge = false
1433
+ // console.log('[nudge] idle window elapsed')
1434
+ this.forceTerminalNudge()
1435
+ }, delay)
1436
+ }
1437
+ forceTerminalNudge() {
1438
+ if (!this.ptyProcess || this.nudging) {
1439
+ // console.log('[nudge] force skipped', { hasPty: !!this.ptyProcess, nudging: this.nudging })
1440
+ return
1441
+ }
1442
+ this.cancelIdleNudge()
1443
+ const baseCols = Number.isFinite(this.cols) ? this.cols : (this.vt && Number.isFinite(this.vt.cols) ? this.vt.cols : 80)
1444
+ const baseRows = Number.isFinite(this.rows) ? this.rows : (this.vt && Number.isFinite(this.vt.rows) ? this.vt.rows : 24)
1445
+ const cols = Math.max(2, Math.floor(baseCols))
1446
+ const rows = Math.max(2, Math.floor(baseRows))
1447
+ if (cols <= 2) {
1448
+ return
1449
+ }
1450
+ this.ignoreNudgeOutput = true
1451
+ this.nudging = true
1452
+ // console.log('[nudge] shrink start', { cols: cols - 1, rows })
1453
+ this.resize({ cols: cols - 1, rows })
1454
+ if (this.nudgeRestoreTimer) {
1455
+ clearTimeout(this.nudgeRestoreTimer)
1456
+ }
1457
+ this.nudgeRestoreTimer = setTimeout(() => {
1458
+ // console.log('[nudge] restore', { cols, rows })
1459
+ // console.log('[nudge] restore start', { cols, rows })
1460
+ this.resize({ cols, rows })
1461
+ if (this.nudgeReleaseTimer) {
1462
+ clearTimeout(this.nudgeReleaseTimer)
1463
+ }
1464
+ this.nudgeReleaseTimer = setTimeout(() => {
1465
+ this.nudging = false
1466
+ this.canNudge = true
1467
+ this.ignoreNudgeOutput = false
1468
+ // console.log('[nudge] complete')
1469
+ this.nudgeReleaseTimer = null
1470
+ }, 100)
1471
+ this.nudgeRestoreTimer = null
1472
+ }, 100)
1473
+ }
1263
1474
  _log(buf, cleaned) {
1264
1475
 
1265
1476
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "3.271.0",
3
+ "version": "3.273.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {