pinokiod 3.86.0 → 3.87.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 (67) hide show
  1. package/Dockerfile +61 -0
  2. package/docker-entrypoint.sh +75 -0
  3. package/kernel/api/hf/index.js +1 -1
  4. package/kernel/api/index.js +1 -1
  5. package/kernel/api/shell/index.js +6 -0
  6. package/kernel/api/terminal/index.js +166 -0
  7. package/kernel/bin/conda.js +3 -2
  8. package/kernel/bin/index.js +53 -2
  9. package/kernel/bin/setup.js +32 -0
  10. package/kernel/bin/vs.js +11 -2
  11. package/kernel/index.js +42 -2
  12. package/kernel/info.js +36 -0
  13. package/kernel/peer.js +42 -15
  14. package/kernel/router/index.js +23 -15
  15. package/kernel/router/localhost_static_router.js +0 -3
  16. package/kernel/router/pinokio_domain_router.js +333 -0
  17. package/kernel/shells.js +21 -1
  18. package/kernel/util.js +2 -2
  19. package/package.json +2 -1
  20. package/script/install-mode.js +33 -0
  21. package/script/pinokio.json +7 -0
  22. package/server/index.js +513 -173
  23. package/server/public/Socket.js +48 -0
  24. package/server/public/common.js +1441 -276
  25. package/server/public/fseditor.js +71 -12
  26. package/server/public/install.js +1 -1
  27. package/server/public/layout.js +740 -0
  28. package/server/public/modalinput.js +0 -1
  29. package/server/public/style.css +97 -105
  30. package/server/public/tab-idle-notifier.js +629 -0
  31. package/server/public/terminal_input_tracker.js +63 -0
  32. package/server/public/urldropdown.css +319 -53
  33. package/server/public/urldropdown.js +615 -159
  34. package/server/public/window_storage.js +97 -28
  35. package/server/socket.js +40 -9
  36. package/server/views/500.ejs +2 -2
  37. package/server/views/app.ejs +3136 -1367
  38. package/server/views/bookmarklet.ejs +1 -1
  39. package/server/views/bootstrap.ejs +1 -1
  40. package/server/views/columns.ejs +2 -13
  41. package/server/views/connect.ejs +3 -4
  42. package/server/views/container.ejs +1 -2
  43. package/server/views/d.ejs +223 -53
  44. package/server/views/editor.ejs +1 -1
  45. package/server/views/file_explorer.ejs +1 -1
  46. package/server/views/index.ejs +12 -11
  47. package/server/views/index2.ejs +4 -4
  48. package/server/views/init/index.ejs +4 -5
  49. package/server/views/install.ejs +1 -1
  50. package/server/views/layout.ejs +105 -0
  51. package/server/views/net.ejs +39 -7
  52. package/server/views/network.ejs +20 -6
  53. package/server/views/network2.ejs +1 -1
  54. package/server/views/old_network.ejs +2 -2
  55. package/server/views/partials/dynamic.ejs +3 -5
  56. package/server/views/partials/menu.ejs +3 -5
  57. package/server/views/partials/running.ejs +1 -1
  58. package/server/views/pro.ejs +1 -1
  59. package/server/views/prototype/index.ejs +1 -1
  60. package/server/views/review.ejs +11 -23
  61. package/server/views/rows.ejs +2 -13
  62. package/server/views/screenshots.ejs +293 -138
  63. package/server/views/settings.ejs +3 -4
  64. package/server/views/setup.ejs +1 -2
  65. package/server/views/shell.ejs +277 -26
  66. package/server/views/terminal.ejs +322 -49
  67. package/server/views/tools.ejs +448 -4
@@ -141,7 +141,7 @@
141
141
  <ol class="steps">
142
142
  <li>Make sure your bookmarks bar is visible (View → Toolbars → Bookmarks Toolbar, or press <kbd>Ctrl</kbd>/<kbd>Cmd</kbd> + <kbd>Shift</kbd> + <kbd>B</kbd>).</li>
143
143
  <li>Drag the “Pinokio Create” button above to the bar.</li>
144
- <li>When you are on a page you want to automate, click the bookmark. Pinokio will open at <code><%= baseUrl %>/?create=1</code> with the current page URL in the prompt field.</li>
144
+ <li>When you are on a page you want to automate, click the bookmark. Pinokio will open at <code><%= baseUrl %>/home?create=1</code> with the current page URL in the prompt field.</li>
145
145
  </ol>
146
146
  </section>
147
147
 
@@ -136,7 +136,7 @@ document.addEventListener("DOMContentLoaded", () => {
136
136
  })
137
137
  let config = {
138
138
  scrollback: 9999999,
139
- fontSize: 14,
139
+ fontSize: 12,
140
140
  theme,
141
141
  }
142
142
  let res = await fetch("/xterm_config").then((res) => {
@@ -82,9 +82,9 @@ body[data-agent='electron'] {
82
82
  </head>
83
83
  <body class='<%=theme%>' data-agent="<%=agent%>">
84
84
  <div id='dragger'></div>
85
- <iframe id='col0' data-src="<%=src%>"></iframe>
85
+ <iframe id='col0' data-src="<%= originSrc || '/' %>"></iframe>
86
86
  <div id="gutter" class="gutter" tabindex="0" role="separator" aria-orientation="vertical" aria-label="Resize panels" aria-valuemin="120" aria-valuemax="0" aria-valuenow="0"></div>
87
- <iframe id='col1' data-src="<%=src%>"></iframe>
87
+ <iframe id='col1' data-src="<%= targetSrc || originSrc || '/' %>"></iframe>
88
88
 
89
89
  <script>
90
90
  if (window !== window.top) {
@@ -366,17 +366,6 @@ body[data-agent='electron'] {
366
366
  }
367
367
  })
368
368
  })();
369
- if (document.querySelector("#collapse") && window.windowStorage) {
370
- document.querySelector("#collapse").addEventListener("click", (e) => {
371
- document.body.classList.toggle("minimized")
372
- let frame_key = window.frameElement?.name || "";
373
- if (document.body.classList.contains("minimized")) {
374
- windowStorage.setItem(frame_key + ":window_mode", "minimized")
375
- } else {
376
- windowStorage.setItem(frame_key + ":window_mode", "full")
377
- }
378
- })
379
- }
380
369
  </script>
381
370
  </body>
382
371
  </html>
@@ -814,7 +814,6 @@ document.addEventListener('DOMContentLoaded', function() {
814
814
  <header class='navheader grabbable'>
815
815
  <h1>
816
816
  <a class='home' href="/"><img class='icon' src="/pinokio-black.png"></a>
817
- <button id='collapse' class='btn2' data-tippy-content="toggle fullscreen view"><i class="fa-solid fa-bars"></i></button>
818
817
  <button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
819
818
  <button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
820
819
  <button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
@@ -822,7 +821,7 @@ document.addEventListener('DOMContentLoaded', function() {
822
821
  <button class='btn2 mobile-link-button' id='mobile-link-button' data-tippy-content="enter url"><i class="fa-solid fa-link"></i></button>
823
822
  <form class='urlbar'>
824
823
  <div class='url-input-container'>
825
- <input type='url' placeholder='enter a local url'>
824
+ <input type='url' placeholder='enter any local url to open in pinokio'>
826
825
  <div class='url-dropdown' id='url-dropdown'></div>
827
826
  </div>
828
827
  </form>
@@ -936,7 +935,7 @@ document.addEventListener('DOMContentLoaded', function() {
936
935
  <aside>
937
936
  <div class='btn-tab'>
938
937
  <button type='button' class='btn' id='create-launcher-button'><i class="fa-solid fa-plus"></i><div class='caption'>Create</div></button>
939
- <a class='btn' id='explore' href="/?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Discover</div></a>
938
+ <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Discover</div></a>
940
939
  </div>
941
940
  <a href="/" class='tab'><i class='fas fa-laptop-code'></i><div class='caption'>This machine</div></a>
942
941
  <a href="/network" class='tab'><i class="fa-solid fa-wifi"></i><div class='caption'>Local network</div></a>
@@ -952,7 +951,7 @@ document.addEventListener('DOMContentLoaded', function() {
952
951
  <a id='downloadlogs' download class='hidden btn2' href="/pinokio/logs.zip"><i class="fa-solid fa-download"></i><div class='caption'>Download logs</div></a>
953
952
  <a class='tab' href="/screenshots"><i class="fa-solid fa-camera"></i><div class='caption'>Screenshots</div></a>
954
953
  <a class='tab' href="/tools"><i class="fa-solid fa-toolbox"></i><div class='caption'>Installed Tools</div></a>
955
- <a class='tab' href="/?mode=settings"><i class="fa-solid fa-gear"></i><div class='caption'>Settings</div></a>
954
+ <a class='tab' href="/home?mode=settings"><i class="fa-solid fa-gear"></i><div class='caption'>Settings</div></a>
956
955
  </aside>
957
956
  </main>
958
957
  </body>
@@ -328,7 +328,6 @@ iframe {
328
328
  <header class='navheader grabbable'>
329
329
  <h1>
330
330
  <a class='home' href="/"><img class='icon' src="/pinokio-black.png"></a>
331
- <button id='collapse' class='btn2' data-tippy-content="toggle fullscreen view"><i class="fa-solid fa-bars"></i></button>
332
331
  <button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
333
332
  <button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
334
333
  <button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
@@ -336,7 +335,7 @@ iframe {
336
335
  <button class='btn2 mobile-link-button' id='mobile-link-button' data-tippy-content="enter url"><i class="fa-solid fa-link"></i></button>
337
336
  <form class='urlbar'>
338
337
  <div class='url-input-container'>
339
- <input type='url' placeholder='enter a local url' value="<%=src%>">
338
+ <input type='url' placeholder='enter any local url to open in pinokio' value="<%=src%>">
340
339
  <div class='url-dropdown' id='url-dropdown'></div>
341
340
  </div>
342
341
  </form>
@@ -17,11 +17,14 @@
17
17
  <style>
18
18
  main {
19
19
  box-sizing: border-box;
20
+ padding: 0;
20
21
  /*
21
22
  flex-wrap: wrap;
22
23
  */
24
+ /*
23
25
  max-width: 800px;
24
26
  padding: 30px 45px;
27
+ */
25
28
  /*
26
29
  justify-content: center;
27
30
  */
@@ -29,72 +32,102 @@ main {
29
32
  .tab-content {
30
33
  display: flex;
31
34
  flex-wrap: wrap;
32
- gap: 5px;
33
35
  flex-grow: 1;
34
36
  width: 100%;
35
37
  }
36
38
  .submenu.tab {
37
39
  margin: 10px 0;
38
40
  }
39
- .tab:hover {
40
- color: rgba(127, 91, 243, 0.9);
41
- }
42
41
  .tab {
43
- /*
44
- min-width: 250px;
45
- */
46
42
  width: 100%;
47
43
  text-decoration: none;
48
44
  display: flex;
49
- /*
50
- flex-direction: column;
51
- */
52
45
  font-size: 14px;
53
46
  font-weight: bold;
54
47
  color: black;
55
48
  overflow: hidden;
56
49
  box-sizing: border-box;
57
- border-radius: 4px;
58
50
  align-items: center;
59
51
  gap: 10px;
60
- /*
61
- width: 120px;
62
- */
52
+ padding: 5px;
53
+ cursor: pointer;
54
+ transition: background 0.2s ease;
63
55
 
64
56
  /*
65
57
  margin-bottom: 10px;
66
58
  */
67
59
  background: rgba(0,0,0,0.05);
68
60
  }
61
+ .tab:hover,
62
+ .tab:focus-visible {
63
+ background: rgba(0, 0, 0, 0.1);
64
+ }
65
+ .tab:focus-visible {
66
+ outline: 2px solid rgba(127, 91, 243, 0.6);
67
+ outline-offset: 2px;
68
+ }
69
69
  body.dark .tab {
70
70
  color: white;
71
71
  background: rgba(255,255,255,0.03);
72
72
  }
73
+ body.dark .tab:hover,
74
+ body.dark .tab:focus-visible {
75
+ background: rgba(255, 255, 255, 0.08);
76
+ }
73
77
  .tab h2 {
74
78
  margin: 0;
75
- font-size: 18px;
79
+ font-weight: normal;
80
+ font-size: 14px;
76
81
  }
77
82
  .tab .col {
78
83
  flex-grow: 1;
79
84
  margin-left: 10px;
80
85
  }
81
86
  .tab i.img {
82
- height: 50px;
83
- width: 50px;
87
+ height: 30px;
88
+ width: 30px;
84
89
  background: white;
85
90
  color: black;
86
91
  display: flex;
87
92
  justify-content: center;
88
93
  font-size: 20px;
89
94
  align-items: center;
90
- border-radius: 3px;
91
95
  }
92
96
  .tab img {
93
- height: 50px;
94
- width: 50px;
95
- border-radius: 3px;
97
+ height: 30px;
98
+ width: 30px;
96
99
  background: white;
97
100
  }
101
+ .tab .disclosure-indicator {
102
+ display: inline-flex;
103
+ align-items: center;
104
+ justify-content: center;
105
+ width: 20px;
106
+ height: 20px;
107
+ color: rgba(0, 0, 0, 0.4);
108
+ flex-shrink: 0;
109
+ pointer-events: none;
110
+ transition: transform 0.2s ease, color 0.2s ease;
111
+ }
112
+ .tab:hover .disclosure-indicator,
113
+ .tab:focus-visible .disclosure-indicator {
114
+ color: rgba(0, 0, 0, 0.7);
115
+ transform: translateX(2px);
116
+ }
117
+ .tab.is-starting {
118
+ cursor: wait;
119
+ opacity: 0.7;
120
+ }
121
+ .tab.is-starting .disclosure-indicator {
122
+ opacity: 0.85;
123
+ }
124
+ body.dark .tab .disclosure-indicator {
125
+ color: rgba(255, 255, 255, 0.4);
126
+ }
127
+ body.dark .tab:hover .disclosure-indicator,
128
+ body.dark .tab:focus-visible .disclosure-indicator {
129
+ color: rgba(255, 255, 255, 0.9);
130
+ }
98
131
  /*
99
132
  body.dark .tab i {
100
133
  background: rgba(0,0,0,0.1);
@@ -114,12 +147,6 @@ body.dark .tab i {
114
147
  }
115
148
  */
116
149
  .menu-container {
117
- /*
118
- border: 15px solid rgba(0,0,0,0.04);
119
- background: white;
120
- border-radius: 20px;
121
- */
122
- margin-bottom: 30px;
123
150
  align-items: flex-start;
124
151
  }
125
152
  /*
@@ -132,9 +159,15 @@ body.dark .menu-container {
132
159
  flex-direction: column;
133
160
  box-sizing: border-box;
134
161
  }
162
+ body.dark .tab-header {
163
+ background: rgba(255,255,255,0.04);
164
+ }
135
165
  .tab-header {
136
- margin-bottom: 10px;
137
166
  font-weight: bold;
167
+ width: 100%;
168
+ box-sizing: border-box;
169
+ padding: 10px;
170
+ background: rgba(0,0,0,0.04);
138
171
  }
139
172
  .container {
140
173
  margin: 0;
@@ -233,8 +266,9 @@ body.dark .btn.run-btn {
233
266
  }
234
267
  .tab-header h3 {
235
268
  margin: 0;
236
- font-size: 16px;
237
- text-transform: capitalize;
269
+ font-size: 14px;
270
+ text-transform: uppercase;
271
+ opacity: 0.6;
238
272
  }
239
273
  .tab-header h3 i {
240
274
  }
@@ -268,6 +302,9 @@ header h1 {
268
302
  h4 {
269
303
  margin: 0 0 5px;
270
304
  }
305
+ form.search {
306
+ padding: 10px;
307
+ }
271
308
  body.dark .btn.file-open {
272
309
  background: rgba(255,255,255,0.1) !important;
273
310
  }
@@ -298,6 +335,7 @@ body.dark #update-spec {
298
335
  <form class='search'>
299
336
  <input type='search' class="flexible" placeholder='Filter tools'>
300
337
  </form>
338
+ <!--
301
339
  <header>
302
340
  <h1>Build</h1>
303
341
  <div class='flexible'></div>
@@ -309,20 +347,14 @@ body.dark #update-spec {
309
347
  </div>
310
348
  </div>
311
349
  </header>
350
+ -->
312
351
  <div class='spec'>
313
352
  <div class='explain'>
314
353
  <h3><i class="fa-regular fa-circle-check"></i> TODO</h3>
315
354
  <ol>
316
355
  <li><strong>Build manually:</strong> Open the project files and start building. <a class='btn file-open' data-filepath="<%=filepath%>"><i class="fa-solid fa-folder-open"></i> open project folder</a></li>
317
356
  <li><strong>Build with AI:</strong> Click any of the below AI tools to instantly start building with AI.</li>
318
- <!--
319
- <li><strong>Build with AI:</strong> Click any of the AI tools below to start building with AI. The AI will automatically build based on the spec:</li>
320
- -->
321
357
  </ol>
322
- <!--
323
- <textarea><%=spec%></textarea>
324
- <button id='update-spec'>Update</button>
325
- -->
326
358
  </div>
327
359
  </div>
328
360
 
@@ -332,13 +364,10 @@ body.dark #update-spec {
332
364
  <div class='menu-container'>
333
365
  <div class='tab-header'>
334
366
  <h3><i class='<%=item.icon%>'></i> <%=item.title%></h3>
335
- <% if (item.subtitle) { %>
336
- <div class='subtitle'><%=item.subtitle%></div>
337
- <% } %>
338
367
  </div>
339
368
  <div class='tab-content'>
340
369
  <% item.menu.forEach((i) => { %>
341
- <a href="<%=i.href%>" class='tab' data-index="<%=index++%>" data-target="@<%=i.href.split("?")[0].replace("/run", "")%>">
370
+ <div class='tab' role="button" tabindex="0" data-index="<%=index++%>" data-target="@<%=i.href%>" data-href="<%=i.href%>">
342
371
  <% if (i.image) { %>
343
372
  <img src="<%=i.image%>">
344
373
  <% } else if (i.icon) { %>
@@ -348,14 +377,14 @@ body.dark #update-spec {
348
377
  <% if (i.subtitle) { %>
349
378
  <div class='subtitle'><%=i.subtitle%></div>
350
379
  <% } %>
380
+ <div class='flexible'></div>
351
381
  <% if (i.link) { %>
352
382
  <div target="_blank" data-href="<%=i.link%>"><i class="fa-solid fa-circle-info"></i></div>
353
383
  <% } %>
354
- <div class='flexible'></div>
355
- <div class='btn'>
356
- <i class="fa-solid fa-angle-right"></i>
384
+ <div class='disclosure-indicator' aria-hidden="true">
385
+ <i class="fa-solid fa-chevron-right"></i>
357
386
  </div>
358
- </a>
387
+ </div>
359
388
  <% }) %>
360
389
  </div>
361
390
  </div>
@@ -397,6 +426,7 @@ setTimeout(() => {
397
426
  location.href = location.href
398
427
  }, 2000)
399
428
  <% } %>
429
+ /*
400
430
  document.querySelector("#git-pull").addEventListener("click", (e) => {
401
431
  e.preventDefault()
402
432
  e.stopPropagation()
@@ -415,6 +445,7 @@ document.querySelector("#git-pull").addEventListener("click", (e) => {
415
445
  }
416
446
  })
417
447
  })
448
+ */
418
449
  /*
419
450
  const resize = (textarea) => {
420
451
  textarea.style.height = "";
@@ -501,6 +532,74 @@ const renderSearch = () => {
501
532
  }
502
533
  }
503
534
  renderSearch()
535
+ const generateSession = () => {
536
+ if (typeof crypto !== 'undefined' && crypto.randomUUID) {
537
+ return crypto.randomUUID()
538
+ }
539
+ return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`
540
+ }
541
+ const appendSessionParam = (value, session) => {
542
+ if (!value) return value
543
+ if (value.includes('session=')) {
544
+ return value
545
+ }
546
+ const delimiter = value.includes('?') ? '&' : '?'
547
+ return `${value}${delimiter}session=${session}`
548
+ }
549
+ const START_ICON_HTML = '<i class="fa-solid fa-chevron-right"></i>'
550
+ const STARTING_ICON_HTML = '<i class="fa-solid fa-circle-notch fa-spin"></i>'
551
+ const setTabLaunchState = (tab, state) => {
552
+ if (!tab) return
553
+ const indicator = tab.querySelector('.disclosure-indicator')
554
+ if (indicator) {
555
+ indicator.innerHTML = state === 'starting' ? STARTING_ICON_HTML : START_ICON_HTML
556
+ }
557
+ if (state === 'starting') {
558
+ tab.classList.add('is-starting')
559
+ } else {
560
+ tab.classList.remove('is-starting')
561
+ }
562
+ }
563
+ const pendingLaunchTabs = new Map()
564
+ const launchTab = (tab) => {
565
+ if (!tab) {
566
+ return false
567
+ }
568
+
569
+ if (tab.classList.contains('is-starting')) {
570
+ return false
571
+ }
572
+
573
+ const baseHref = tab.dataset.href
574
+ const baseTarget = tab.dataset.target
575
+
576
+ if (!baseHref || !baseTarget) {
577
+ return false
578
+ }
579
+
580
+ const session = generateSession()
581
+ pendingLaunchTabs.set(session, tab)
582
+ setTabLaunchState(tab, 'starting')
583
+
584
+ const href = appendSessionParam(baseHref, session)
585
+ const target = appendSessionParam(baseTarget, session)
586
+
587
+ window.parent.postMessage({
588
+ launch: {
589
+ name: target,
590
+ href
591
+ }
592
+ }, "*")
593
+
594
+ return true
595
+ }
596
+ const extractSession = (value) => {
597
+ if (!value || typeof value !== 'string') {
598
+ return null
599
+ }
600
+ const match = value.match(/session=([^&]+)/)
601
+ return match ? match[1] : null
602
+ }
504
603
  document.querySelector("form input[type=search]").addEventListener("input", (e) => {
505
604
  selectedIndex = 0
506
605
  selectedBtnIndex = 0
@@ -508,16 +607,87 @@ document.querySelector("form input[type=search]").addEventListener("input", (e)
508
607
  })
509
608
  document.querySelector("form input[type=search]").focus()
510
609
  document.addEventListener("click", (e) => {
511
- if (e.target.classList.contains("tab")) {
610
+ const infoTarget = e.target.closest('[data-href][target="_blank"]')
611
+ if (infoTarget) {
612
+ e.preventDefault()
613
+ e.stopPropagation()
614
+ window.open(infoTarget.getAttribute('data-href'), '_blank')
615
+ return
616
+ }
617
+
618
+ const tab = e.target.closest('.tab[data-href]')
619
+ if (!tab) {
620
+ return
621
+ }
622
+
623
+ if (launchTab(tab)) {
624
+ e.preventDefault()
625
+ e.stopPropagation()
626
+ }
627
+ })
628
+
629
+ document.addEventListener('keydown', (e) => {
630
+ if (!['Enter', ' ', 'Spacebar'].includes(e.key)) {
631
+ return
632
+ }
633
+
634
+ const target = e.target
635
+ if (!(target instanceof HTMLElement)) {
636
+ return
637
+ }
638
+
639
+ const tab = target.closest('.tab[data-href]')
640
+ if (!tab || tab !== target) {
641
+ return
642
+ }
643
+
644
+ const launched = launchTab(tab)
645
+ if (launched) {
512
646
  e.preventDefault()
513
647
  e.stopPropagation()
514
- let href = e.target.href
515
- window.parent.postMessage({
516
- launch: {
517
- name: e.target.getAttribute("data-target"),
518
- href
519
- }
520
- }, "*")
648
+ }
649
+ })
650
+
651
+ window.addEventListener('message', (event) => {
652
+ const data = event.data
653
+ if (!data || typeof data !== 'object') {
654
+ return
655
+ }
656
+
657
+ let session = null
658
+
659
+ if (typeof data.session === 'string') {
660
+ session = data.session
661
+ }
662
+
663
+ if (!session && typeof data.id === 'string') {
664
+ session = extractSession(data.id)
665
+ }
666
+
667
+ if (!session && data.data && typeof data.data.id === 'string') {
668
+ session = extractSession(data.data.id)
669
+ }
670
+
671
+ if (!session && data.launch && typeof data.launch.href === 'string') {
672
+ session = extractSession(data.launch.href)
673
+ }
674
+
675
+ if (!session && typeof data.href === 'string') {
676
+ session = extractSession(data.href)
677
+ }
678
+
679
+ if (session && pendingLaunchTabs.has(session)) {
680
+ const tab = pendingLaunchTabs.get(session)
681
+ pendingLaunchTabs.delete(session)
682
+ setTabLaunchState(tab, 'idle')
683
+ return
684
+ }
685
+
686
+ if (data.type === 'start' || data.type === 'result' || data.type === 'error' || data.type === 'disconnect') {
687
+ pendingLaunchTabs.forEach((tab) => {
688
+ setTabLaunchState(tab, 'idle')
689
+ })
690
+ pendingLaunchTabs.clear()
521
691
  }
522
692
  })
523
693
  </script>
@@ -671,7 +671,7 @@ document.addEventListener("DOMContentLoaded", async () => {
671
671
  })
672
672
  let config = {
673
673
  scrollback: 9999999,
674
- fontSize: 14,
674
+ fontSize: 12,
675
675
  theme,
676
676
  }
677
677
  let res = await fetch("/xterm_config").then((res) => {
@@ -196,7 +196,7 @@ body.dark .browser-options-row {
196
196
  <% if (dep.downloaded) { %>
197
197
  <div class='item'><i class="fa-solid fa-check"></i> <a class='downloaded' href="<%=dep.downloaded%>" target="_blank"><%=dep.uri%></a><div class='flexible'></div></div>
198
198
  <% } else { %>
199
- <div class='item'><a class='btn' href="/?mode=download&uri=<%=dep.uri%>" target="_blank"><i class="fa-solid fa-download"></i> Download</a> <%=dep.uri%><div class='flexible'></div></div>
199
+ <div class='item'><a class='btn' href="/home?mode=download&uri=<%=dep.uri%>" target="_blank"><i class="fa-solid fa-download"></i> Download</a> <%=dep.uri%><div class='flexible'></div></div>
200
200
  <% } %>
201
201
  <% }) %>
202
202
  </div>
@@ -419,7 +419,6 @@ body.dark aside .current.selected {
419
419
  <h1>
420
420
  <% if (ishome) { %>
421
421
  <a class='home' href="/"><img class='icon' src="/pinokio-black.png"></a>
422
- <button id='collapse' class='btn2' data-tippy-content="toggle fullscreen view"><i class="fa-solid fa-bars"></i></button>
423
422
  <button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
424
423
  <button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
425
424
  <button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
@@ -427,7 +426,7 @@ body.dark aside .current.selected {
427
426
  <button class='btn2 mobile-link-button' id='mobile-link-button' data-tippy-content="enter url"><i class="fa-solid fa-link"></i></button>
428
427
  <form class='urlbar'>
429
428
  <div class='url-input-container'>
430
- <input type='url' placeholder='enter a local url'>
429
+ <input type='url' placeholder='enter any local url to open in pinokio'>
431
430
  <div class='url-dropdown' id='url-dropdown'></div>
432
431
  </div>
433
432
  </form>
@@ -476,7 +475,7 @@ body.dark aside .current.selected {
476
475
  <% if (dep.downloaded) { %>
477
476
  <div class='item'><i class="fa-solid fa-check"></i> <a class='downloaded' href="<%=dep.downloaded%>" target="_blank"><%=dep.uri%></a><div class='flexible'></div></div>
478
477
  <% } else { %>
479
- <div class='item'><a class='btn' href="/?mode=download&uri=<%=dep.uri%>" target="_blank"><i class="fa-solid fa-download"></i> Download</a> <%=dep.uri%><div class='flexible'></div></div>
478
+ <div class='item'><a class='btn' href="/home?mode=download&uri=<%=dep.uri%>" target="_blank"><i class="fa-solid fa-download"></i> Download</a> <%=dep.uri%><div class='flexible'></div></div>
480
479
  <% } %>
481
480
  <% }) %>
482
481
  </div>
@@ -491,10 +490,10 @@ body.dark aside .current.selected {
491
490
  <div class='app-btns'>
492
491
  <!--
493
492
  <a class='btn create-new' href="/init"><i class="fa-solid fa-plus"></i> Build</a>
494
- <a class='btn' id='explore' href="/?mode=explore"><i class="fa-solid fa-globe"></i> Discover</a>
493
+ <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i> Discover</a>
495
494
  -->
496
495
  <!--
497
- <a class='btn' id='explore' href="/?mode=explore"><i class="fa-solid fa-magnifying-glass"></i> Discover</a>
496
+ <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-magnifying-glass"></i> Discover</a>
498
497
  -->
499
498
  </div>
500
499
  <% if (display.includes("form")) { %>
@@ -536,7 +535,7 @@ body.dark aside .current.selected {
536
535
  <div class='description'><%=item.description%></div>
537
536
  <div class='menu-btns'>
538
537
  <button class='btn browse' data-src="<%=item.dev_url%>">
539
- <i class='fa-solid fa-code'></i> Dev
538
+ <i class="fa-solid fa-code"></i> Dev
540
539
  </button>
541
540
  <button class='btn browse' data-src="<%=item.review_url%>">
542
541
  <i class="fa-regular fa-message"></i> Community
@@ -627,7 +626,7 @@ body.dark aside .current.selected {
627
626
  <div class='description'><%=item.description%></div>
628
627
  <div class='menu-btns'>
629
628
  <button class='btn browse' data-src="<%=item.dev_url%>">
630
- <i class='fa-solid fa-code'></i> Dev
629
+ <i class="fa-solid fa-code"></i> Dev
631
630
  </button>
632
631
  <button class='btn browse' data-src="<%=item.review_url%>">
633
632
  <i class="fa-regular fa-message"></i> Community
@@ -680,8 +679,10 @@ body.dark aside .current.selected {
680
679
  <div class='placeholder'>
681
680
  <h1>Welcome.</h1>
682
681
  <br>
683
- <div>Get started by installing some Pinokio scripts.</div>
684
- <a href="/?mode=explore" class='btn'><i class="fa-solid fa-globe"></i> Visit Discover Page</a>
682
+ <div>Get started by installing or creating some pinokio scripts.</div>
683
+ <a href="/home?mode=explore" class='btn'><i class="fa-solid fa-globe"></i> Discover</a>
684
+ <span>&nbsp;or&nbsp;</span>
685
+ <a href="/home?create=1" class='btn'><i class="fa-solid fa-wand-magic-sparkles"></i> Create</a>
685
686
  </div>
686
687
  <% } %>
687
688
  <% } else { %>
@@ -720,7 +721,7 @@ body.dark aside .current.selected {
720
721
  <aside>
721
722
  <div class='btn-tab'>
722
723
  <button type='button' class='btn' id='create-launcher-button'><i class="fa-solid fa-plus"></i><div class='caption'>Create</div></button>
723
- <a class='btn' id='explore' href="/?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Discover</div></a>
724
+ <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Discover</div></a>
724
725
  </div>
725
726
  <a href="/" class='tab selected'><i class='fas fa-laptop-code'></i><div class='caption'>This machine</div></a>
726
727
  <a href="/network" class='tab'><i class="fa-solid fa-wifi"></i><div class='caption'>Local network</div></a>
@@ -736,7 +737,7 @@ body.dark aside .current.selected {
736
737
  <a id='downloadlogs' download class='hidden btn2' href="/pinokio/logs.zip"><i class="fa-solid fa-download"></i><div class='caption'>Download logs</div></a>
737
738
  <a class='tab' href="/screenshots"><i class="fa-solid fa-camera"></i><div class='caption'>Screenshots</div></a>
738
739
  <a class='tab' href="/tools"><i class="fa-solid fa-toolbox"></i><div class='caption'>Installed Tools</div></a>
739
- <a class='tab' href="/?mode=settings"><i class="fa-solid fa-gear"></i><div class='caption'>Settings</div></a>
740
+ <a class='tab' href="/home?mode=settings"><i class="fa-solid fa-gear"></i><div class='caption'>Settings</div></a>
740
741
  </aside>
741
742
  </main>
742
743
  <script>