pinokiod 7.3.6 → 7.3.8

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 (37) hide show
  1. package/kernel/api/index.js +3 -2
  2. package/kernel/api/script/index.js +1 -0
  3. package/kernel/resource_usage/gpu.js +1 -1
  4. package/package.json +1 -1
  5. package/server/index.js +11 -2
  6. package/server/public/nav.js +1 -1
  7. package/server/public/style.css +298 -191
  8. package/server/public/task-launcher.css +16 -20
  9. package/server/public/universal-launcher.css +0 -113
  10. package/server/public/universal-launcher.js +1 -1
  11. package/server/views/app.ejs +592 -298
  12. package/server/views/autolaunch.ejs +1 -1
  13. package/server/views/checkpoints.ejs +2 -6
  14. package/server/views/connect.ejs +1 -1
  15. package/server/views/explore.ejs +2 -1
  16. package/server/views/index.ejs +89 -60
  17. package/server/views/install.ejs +1 -0
  18. package/server/views/invalid_content.ejs +1 -1
  19. package/server/views/layout.ejs +8 -2
  20. package/server/views/logs.ejs +5 -27
  21. package/server/views/net.ejs +1 -1
  22. package/server/views/network.ejs +1 -1
  23. package/server/views/partials/fs_status.ejs +0 -8
  24. package/server/views/partials/main_sidebar.ejs +108 -44
  25. package/server/views/plugin_detail.ejs +1 -1
  26. package/server/views/plugins.ejs +1 -28
  27. package/server/views/screenshots.ejs +1 -1
  28. package/server/views/settings.ejs +2 -1
  29. package/server/views/setup.ejs +15 -1
  30. package/server/views/skills.ejs +1 -1
  31. package/server/views/task_builder.ejs +1 -1
  32. package/server/views/task_install.ejs +1 -1
  33. package/server/views/task_launch.ejs +1 -1
  34. package/server/views/task_list.ejs +1 -1
  35. package/server/views/tools.ejs +1 -1
  36. package/test/resource-usage-gpu.test.js +23 -0
  37. package/test/script-api.test.js +90 -0
@@ -472,7 +472,7 @@ body.autolaunch-page .autolaunch-loading i {
472
472
  }
473
473
  </style>
474
474
  </head>
475
- <body class='<%=theme%> task-launcher-page task-page autolaunch-page' data-agent="<%=agent%>">
475
+ <body class='<%=theme%> main-sidebar-page task-launcher-page task-page autolaunch-page' data-agent="<%=agent%>">
476
476
  <%- include('partials/app_navheader', { agent }) %>
477
477
  <main>
478
478
  <div class="task-container">
@@ -1042,12 +1042,8 @@ document.addEventListener("DOMContentLoaded", () => {
1042
1042
  })
1043
1043
  </script>
1044
1044
  </head>
1045
- <body class='<%=theme%> task-launcher-page task-page checkpoints-page' data-agent="<%=agent%>">
1046
- <header class='navheader grabbable'>
1047
- <h1>
1048
- <a class='home' href="/home"><img class='icon' src="/pinokio-black.png"></a>
1049
- </h1>
1050
- </header>
1045
+ <body class='<%=theme%> main-sidebar-page task-launcher-page task-page checkpoints-page' data-agent="<%=agent%>">
1046
+ <%- include('partials/app_navheader', { agent }) %>
1051
1047
  <main>
1052
1048
  <div class='task-container'>
1053
1049
  <section class='task-shell checkpoints-shell'>
@@ -798,7 +798,7 @@ body.dark .profile td {
798
798
  }
799
799
  </style>
800
800
  </head>
801
- <body class='<%=theme%> task-launcher-page task-page connect-page' data-agent="<%=agent%>">
801
+ <body class='<%=theme%> main-sidebar-page task-launcher-page task-page connect-page' data-agent="<%=agent%>">
802
802
  <%- include('partials/app_navheader', { agent }) %>
803
803
  <main>
804
804
  <div class='task-container connect-container'>
@@ -143,7 +143,7 @@ body.dark .explore-url {
143
143
  <script src="/sweetalert2.js"></script>
144
144
  <script src="/nav.js"></script>
145
145
  </head>
146
- <body class='<%=theme%>' data-agent="<%=agent%>">
146
+ <body class='<%=theme%> main-sidebar-page' data-agent="<%=agent%>">
147
147
  <header class='navheader grabbable'>
148
148
  <h1>
149
149
  <a class='home' href="/home"><img class='icon' src="/pinokio-black.png"></a>
@@ -176,6 +176,7 @@ body.dark .explore-url {
176
176
  <% } else { %>
177
177
  <iframe name="<%=schema%>" src="<%=discover_light%>" <%=agent === "electron" ? "no-referrer" : ""%> allow="fullscreen *;" allowfullscreen></iframe>
178
178
  <% } %>
179
+ <%- include('partials/main_sidebar', { selected: 'explore' }) %>
179
180
  </main>
180
181
  <link href="/xterm.min.css" rel="stylesheet" />
181
182
  <link href="/css/fontawesome.min.css" rel="stylesheet">
@@ -173,6 +173,47 @@ body.dark .context-menu-wrapper {
173
173
  }
174
174
  .menu-btns {
175
175
  position: relative;
176
+ display: inline-flex;
177
+ align-items: center;
178
+ flex-wrap: wrap;
179
+ gap: 4px;
180
+ margin-top: 6px;
181
+ }
182
+ .home-app-line .menu-btns > .btn {
183
+ min-height: 22px;
184
+ margin: 0 !important;
185
+ border: 1px solid rgba(15, 23, 42, 0.08) !important;
186
+ border-radius: 6px !important;
187
+ background: rgba(15, 23, 42, 0.035) !important;
188
+ color: rgba(31, 41, 55, 0.74) !important;
189
+ box-sizing: border-box;
190
+ display: inline-flex !important;
191
+ align-items: center;
192
+ justify-content: center;
193
+ gap: 6px;
194
+ font-size: 12px;
195
+ font-weight: 600;
196
+ line-height: 1;
197
+ text-transform: none;
198
+ transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
199
+ }
200
+ body.dark .home-app-line .menu-btns > .btn {
201
+ border-color: rgba(255, 255, 255, 0.075) !important;
202
+ background: rgba(255, 255, 255, 0.045) !important;
203
+ color: rgba(229, 231, 235, 0.72) !important;
204
+ }
205
+ .home-app-line .menu-btns > .btn:hover,
206
+ .home-app-line .menu-btns > .btn:focus-visible {
207
+ border-color: rgba(15, 23, 42, 0.14) !important;
208
+ background: rgba(15, 23, 42, 0.055) !important;
209
+ color: rgba(17, 24, 39, 0.9) !important;
210
+ outline: none;
211
+ }
212
+ body.dark .home-app-line .menu-btns > .btn:hover,
213
+ body.dark .home-app-line .menu-btns > .btn:focus-visible {
214
+ border-color: rgba(255, 255, 255, 0.12) !important;
215
+ background: rgba(255, 255, 255, 0.07) !important;
216
+ color: rgba(248, 250, 252, 0.9) !important;
176
217
  }
177
218
  .context-menu {
178
219
  position: absolute;
@@ -236,23 +277,11 @@ body.dark .context-menu-section-title {
236
277
  body.dark .context-menu-divider {
237
278
  background: rgba(255,255,255,0.08);
238
279
  }
239
- body.dark .open-menu, body.dark .browse {
240
- border: none !important;
241
- /*
242
- background: black !important;
243
- */
244
- color: white !important;
245
- }
246
- .open-menu:hover, .browse:hover, body.dark .open-menu:hover, body.dark .browse:hover {
247
- color: royalblue !important;
248
- }
249
280
  .open-menu, .browse {
250
281
  /*
251
282
  width: 80px;
252
283
  */
253
- border-radius: 0 !important;
254
- background: rgba(0,0,0,0.04) !important;
255
- color: black !important;
284
+ border-radius: 6px !important;
256
285
  /*
257
286
  border: 1px solid rgba(0, 0, 0, 0.3);
258
287
  */
@@ -267,16 +296,16 @@ body.dark .open-menu, body.dark .browse {
267
296
  }
268
297
  .menu-btns .shutdown,
269
298
  .menu-btns .terminals-link.is-online {
270
- border-radius: 0 !important;
271
- background: var(--pinokio-chrome-accent-bg-light) !important;
272
- border-color: var(--pinokio-chrome-accent-bg-light) !important;
273
- color: var(--pinokio-chrome-accent-fg-light) !important;
299
+ padding: 0 7px !important;
300
+ background: rgba(15, 23, 42, 0.05) !important;
301
+ border-color: rgba(15, 23, 42, 0.09) !important;
302
+ color: rgba(31, 41, 55, 0.82) !important;
274
303
  }
275
304
  body.dark .menu-btns .shutdown,
276
305
  body.dark .menu-btns .terminals-link.is-online {
277
- background: var(--pinokio-chrome-accent-bg-dark) !important;
278
- border-color: var(--pinokio-chrome-accent-bg-dark) !important;
279
- color: var(--pinokio-chrome-accent-fg-dark) !important;
306
+ background: rgba(255, 255, 255, 0.055) !important;
307
+ border-color: rgba(255, 255, 255, 0.09) !important;
308
+ color: rgba(229, 231, 235, 0.82) !important;
280
309
  }
281
310
  .menu-btns .shutdown:hover,
282
311
  .menu-btns .shutdown:focus-visible,
@@ -284,9 +313,9 @@ body.dark .menu-btns .terminals-link.is-online {
284
313
  .menu-btns .terminals-link.is-online:hover,
285
314
  .menu-btns .terminals-link.is-online:focus-visible,
286
315
  .menu-btns .terminals-link.is-online:active {
287
- background: var(--pinokio-chrome-accent-bg-light) !important;
288
- border-color: var(--pinokio-chrome-accent-bg-light) !important;
289
- color: var(--pinokio-chrome-accent-fg-light) !important;
316
+ background: rgba(15, 23, 42, 0.075) !important;
317
+ border-color: rgba(15, 23, 42, 0.14) !important;
318
+ color: rgba(17, 24, 39, 0.94) !important;
290
319
  outline: none;
291
320
  }
292
321
  body.dark .menu-btns .shutdown:hover,
@@ -295,14 +324,27 @@ body.dark .menu-btns .shutdown:active,
295
324
  body.dark .menu-btns .terminals-link.is-online:hover,
296
325
  body.dark .menu-btns .terminals-link.is-online:focus-visible,
297
326
  body.dark .menu-btns .terminals-link.is-online:active {
298
- background: var(--pinokio-chrome-accent-bg-dark) !important;
299
- border-color: var(--pinokio-chrome-accent-bg-dark) !important;
300
- color: var(--pinokio-chrome-accent-fg-dark) !important;
327
+ background: rgba(255, 255, 255, 0.08) !important;
328
+ border-color: rgba(255, 255, 255, 0.14) !important;
329
+ color: rgba(248, 250, 252, 0.94) !important;
301
330
  }
302
331
  .menu-btns .shutdown i,
303
332
  .menu-btns .terminals-link.is-online i {
304
333
  color: inherit !important;
305
334
  }
335
+ .menu-btns .shutdown i.fa-stop {
336
+ color: #b45309 !important;
337
+ font-size: 10px;
338
+ }
339
+ body.dark .menu-btns .shutdown i.fa-stop {
340
+ color: #d6a451 !important;
341
+ }
342
+ .menu-btns .terminals-link.is-online i.fa-terminal {
343
+ color: #4b5563 !important;
344
+ }
345
+ body.dark .menu-btns .terminals-link.is-online i.fa-terminal {
346
+ color: #a7adb7 !important;
347
+ }
306
348
  .toggle-star.is-starred i {
307
349
  color: #b8860b;
308
350
  }
@@ -666,26 +708,18 @@ body.dark .home-search-form .home-apps-sort .ts-dropdown [data-selectable].optio
666
708
  gap: 8px;
667
709
  }
668
710
  body.is-home {
669
- --home-page-accent: var(--pinokio-chrome-accent-fg-light);
670
- --home-page-nav-bg: color-mix(in srgb, #f5f6f8 96%, white);
711
+ --home-page-nav-bg: #ffffff;
671
712
  --home-page-nav-border: rgba(15, 23, 42, 0.12);
672
- background:
673
- radial-gradient(circle at top left, color-mix(in srgb, var(--home-page-accent) 10%, transparent), transparent 24rem),
674
- linear-gradient(180deg, #fafbfd 0%, #f3f5f8 100%);
675
- background-attachment: fixed;
676
- background-repeat: no-repeat;
713
+ --home-page-accent: #6b7280;
714
+ background: #ffffff;
677
715
  isolation: isolate;
678
716
  min-height: 100vh;
679
717
  }
680
718
  body.dark.is-home {
681
- --home-page-accent: var(--pinokio-chrome-accent-fg-dark);
682
- --home-page-nav-bg: color-mix(in srgb, #090b10 94%, black);
719
+ --home-page-accent: #9ca3af;
720
+ --home-page-nav-bg: #1b1c1d;
683
721
  --home-page-nav-border: rgba(255, 255, 255, 0.08);
684
- background:
685
- radial-gradient(circle at top left, color-mix(in srgb, var(--home-page-accent) 16%, transparent), transparent 24rem),
686
- linear-gradient(180deg, #0a0c10 0%, #07090d 100%);
687
- background-attachment: fixed;
688
- background-repeat: no-repeat;
722
+ background: #1b1c1d;
689
723
  }
690
724
  body.is-home > header.navheader {
691
725
  background: transparent;
@@ -724,42 +758,37 @@ body.dark .home-app-line {
724
758
  .home-app-line .item-icon {
725
759
  align-self: flex-start;
726
760
  flex: 0 0 auto;
761
+ width: 40px;
762
+ height: 40px;
763
+ }
764
+ .home-app-line .item-icon img {
765
+ width: 40px;
766
+ height: 40px;
767
+ display: block;
768
+ border-radius: 6px;
769
+ object-fit: cover;
727
770
  }
728
771
  .menu-btns .home-icon-btn {
729
- width: 32px;
772
+ width: 28px;
730
773
  height: 22px;
731
- min-width: 32px;
774
+ min-width: 28px;
732
775
  min-height: 22px;
733
776
  display: inline-flex !important;
734
777
  align-items: center;
735
778
  justify-content: center;
736
- padding: 4px 8px !important;
737
- margin: 0 0px 5px 0 !important;
738
- border: none !important;
739
- border-radius: 0 !important;
740
- background: rgba(0,0,0,0.04) !important;
741
- color: rgba(15, 23, 42, 0.68) !important;
779
+ padding: 0 !important;
742
780
  font-size: 13px;
743
781
  line-height: 1;
744
782
  cursor: pointer;
745
- transition: color 0.12s ease;
746
783
  vertical-align: top;
747
784
  box-sizing: border-box;
748
785
  }
749
786
  .menu-btns .home-icon-btn:hover,
750
787
  .menu-btns .home-icon-btn:focus-visible {
751
- background: rgba(0,0,0,0.04) !important;
752
788
  color: var(--home-page-accent) !important;
753
- outline: none;
754
- }
755
- body.dark .menu-btns .home-icon-btn {
756
- border-color: transparent !important;
757
- background: rgba(255,255,255,0.05) !important;
758
- color: rgba(226, 232, 240, 0.72) !important;
759
789
  }
760
790
  body.dark .menu-btns .home-icon-btn:hover,
761
791
  body.dark .menu-btns .home-icon-btn:focus-visible {
762
- background: rgba(255,255,255,0.05) !important;
763
792
  color: var(--home-page-accent) !important;
764
793
  }
765
794
  .menu-btns .home-icon-btn i {
@@ -1149,9 +1178,9 @@ body.dark aside .current.selected {
1149
1178
  font-size: 11px;
1150
1179
  }
1151
1180
  .menu-btns .home-icon-btn {
1152
- width: 32px;
1181
+ width: 28px;
1153
1182
  height: 22px;
1154
- min-width: 32px;
1183
+ min-width: 28px;
1155
1184
  min-height: 22px;
1156
1185
  }
1157
1186
  .nav-btns {
@@ -1191,7 +1220,7 @@ body.dark aside .current.selected {
1191
1220
  <script src="/urldropdown.js"></script>
1192
1221
  <script src="/tom-select.complete.min.js"></script>
1193
1222
  </head>
1194
- <body class='<%= [theme, ishome ? "is-home" : ""].filter(Boolean).join(" ") %>' data-agent="<%=agent%>">
1223
+ <body class='<%= [theme, "main-sidebar-page", ishome ? "is-home" : ""].filter(Boolean).join(" ") %>' data-agent="<%=agent%>">
1195
1224
  <% if (error) { %>
1196
1225
  <nav class='error-message'>
1197
1226
  <div><%=error%></div>
@@ -189,6 +189,7 @@ body.dark {
189
189
  .install-status-grid-anchor {
190
190
  opacity: 0.16;
191
191
  }
192
+ .install-status-grid-anchor,
192
193
  .install-status-grid-tile,
193
194
  .install-status-grid-chaser,
194
195
  .install-status-grid-pixel {
@@ -14,7 +14,7 @@
14
14
  <link href="/electron.css" rel="stylesheet"/>
15
15
  <% } %>
16
16
  </head>
17
- <body class="<%= theme %> task-launcher-page task-page invalid-content-page" data-agent="<%= agent %>">
17
+ <body class="<%= theme %> main-sidebar-page task-launcher-page task-page invalid-content-page" data-agent="<%= agent %>">
18
18
  <%- include('partials/app_navheader', { agent }) %>
19
19
  <main>
20
20
  <div class="task-container">
@@ -10,6 +10,8 @@
10
10
  --layout-background: #ffffff;
11
11
  --layout-gutter-bg: rgba(0, 0, 0, 0.04);
12
12
  --layout-gutter-bg-hover: cornflowerblue;
13
+ --layout-dragger-bg: var(--layout-background);
14
+ --layout-dragger-border: rgba(15, 23, 42, 0.06);
13
15
  --layout-shadow: rgba(0, 0, 0, 0.06);
14
16
  --layout-viewport-height: 100vh;
15
17
  --layout-dragger-height: 0px;
@@ -32,10 +34,13 @@
32
34
  display: none;
33
35
  height: 32px;
34
36
  width: 100%;
35
- background: var(--layout-gutter-bg);
37
+ box-sizing: border-box;
38
+ background: var(--layout-dragger-bg);
39
+ border-bottom: 1px solid var(--layout-dragger-border);
36
40
  }
37
41
  body.dark > #dragger {
38
- background: var(--layout-gutter-bg);
42
+ background: var(--layout-dragger-bg);
43
+ border-bottom-color: var(--layout-dragger-border);
39
44
  }
40
45
 
41
46
  body[data-agent="electron"] {
@@ -49,6 +54,7 @@
49
54
  body.dark {
50
55
  --layout-background: #1b1c1d;
51
56
  --layout-gutter-bg: rgba(255, 255, 255, 0.04);
57
+ --layout-dragger-border: rgba(255, 255, 255, 0.055);
52
58
  /*
53
59
  --layout-background: #101010;
54
60
  --layout-gutter-bg: #101010;
@@ -32,34 +32,9 @@
32
32
  <script src="/nav.js"></script>
33
33
  <script src="/report.js"></script>
34
34
  </head>
35
- <body class='<%=theme%> <%= logsEmbedded ? "logs-embedded" : "" %>' data-agent="<%=agent%>">
35
+ <body class='<%=theme%> <%= logsEmbedded ? "logs-embedded" : "main-sidebar-page" %>' data-agent="<%=agent%>">
36
36
  <% if (!logsEmbedded) { %>
37
- <header class='navheader grabbable'>
38
- <h1>
39
- <a class='home' href="/home"><img class='icon' src="/pinokio-black.png"></a>
40
- <button class='btn2' id='minimize-header' data-tippy-content="fullscreen" title='fullscreen'>
41
- <div><i class="fa-solid fa-expand"></i></div>
42
- </button>
43
- <button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
44
- <button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
45
- <button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
46
- <button class='btn2' id='screenshot' data-tippy-content="screen capture"><i class="fa-solid fa-camera"></i></button>
47
- <button class='btn2' id='inspector' data-tippy-content="X-ray mode"><i class="fa-solid fa-eye"></i></button>
48
- <div class='mobile-flexible'></div>
49
- <a class='btn2' href="/columns" data-tippy-content="split into 2 columns">
50
- <div><i class="fa-solid fa-table-columns"></i></div>
51
- </a>
52
- <a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
53
- <div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
54
- </a>
55
- <button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
56
- <div><i class="fa-solid fa-plus"></i></div>
57
- </button>
58
- <button class='btn2 hidden' id='close-window' data-tippy-content='close this section'>
59
- <div><i class="fa-solid fa-xmark"></i></div>
60
- </button>
61
- </h1>
62
- </header>
37
+ <%- include('partials/app_navheader', { agent }) %>
63
38
  <% } %>
64
39
  <main>
65
40
  <div class='container'>
@@ -224,6 +199,9 @@
224
199
  </section>
225
200
  <% } %>
226
201
  </div>
202
+ <% if (!logsEmbedded) { %>
203
+ <%- include('partials/main_sidebar', { selected: 'logs' }) %>
204
+ <% } %>
227
205
  </main>
228
206
  <script>
229
207
  window.LOGS_PAGE_DATA = <%- JSON.stringify({ rootDisplay: logsRootDisplay || '', downloadUrl: logsDownloadUrl || '/pinokio/logs.zip', workspace: logsWorkspace || '', workspaceTitle: logsTitle || '', reportUrl: logsReportUrl || '', draftUrl: typeof logsDraftUrl !== 'undefined' ? logsDraftUrl : '', registryBase: 'https://pinokio.co', initialView: logsInitialView || 'raw', embedded: !!logsEmbedded }) %>
@@ -1017,7 +1017,7 @@ document.addEventListener('DOMContentLoaded', function() {
1017
1017
  <script src="/fscreator.js"></script>
1018
1018
  <script src="/fseditor.js"></script>
1019
1019
  </head>
1020
- <body class='<%=theme%> task-launcher-page task-page net-page' data-agent="<%=agent%>">
1020
+ <body class='<%=theme%> main-sidebar-page task-launcher-page task-page net-page' data-agent="<%=agent%>">
1021
1021
  <% if (error) { %>
1022
1022
  <nav class='error-message'>
1023
1023
  <div><%=error%></div>
@@ -1344,7 +1344,7 @@ document.addEventListener('DOMContentLoaded', function() {
1344
1344
  });
1345
1345
  </script>
1346
1346
  </head>
1347
- <body class='<%=theme%> task-launcher-page task-page network-page' data-agent="<%=agent%>">
1347
+ <body class='<%=theme%> main-sidebar-page task-launcher-page task-page network-page' data-agent="<%=agent%>">
1348
1348
  <header class='navheader grabbable'>
1349
1349
  <h1>
1350
1350
  <a class='home' href="/home"><img class='icon' src="/pinokio-black.png"></a>
@@ -11,14 +11,6 @@
11
11
  </div>
12
12
  </div>
13
13
  -->
14
- <div class='fs-status-dropdown fs-open-explorer'>
15
- <button class='fs-status-btn' data-filepath="<%=path%>" type='button'>
16
- <span class='fs-status-label'>
17
- <i class="fa-solid fa-folder-open"></i>
18
- <span class='fs-status-title'>Open in File Explorer</span>
19
- </span>
20
- </button>
21
- </div>
22
14
  <div class='fs-status-dropdown git-changes'>
23
15
  <button id='fs-changes-btn' class='fs-status-btn revealer' data-group='#fs-changes-menu' type='button'>
24
16
  <span class='fs-status-label'><i class="fa-solid fa-code-compare"></i> Changes</span>
@@ -2,7 +2,6 @@
2
2
  const sidebarSelected = (typeof selected !== "undefined" && selected) ? String(selected) : "";
3
3
  const sidebarList = (typeof list !== "undefined" && Array.isArray(list)) ? list : [];
4
4
  const sidebarCurrentHost = (typeof current_host !== "undefined" && current_host) ? current_host : "";
5
- const sidebarHelpUrl = (typeof portal !== "undefined" && portal) ? portal : "https://beta.pinokio.co";
6
5
  const sidebarSelectedNetName = (typeof selectedNetName !== "undefined" && selectedNetName) ? String(selectedNetName) : "";
7
6
  const sidebarShowPeerAccess = typeof showPeerAccess === "boolean" ? showPeerAccess : true;
8
7
  const brands = { win32: "windows", darwin: "apple", linux: "Linux" };
@@ -11,64 +10,129 @@
11
10
  <i class="fa-solid fa-bars" aria-hidden="true"></i>
12
11
  </button>
13
12
  <button type="button" class="main-sidebar-mobile-backdrop" data-main-sidebar-backdrop aria-label="Close navigation" hidden></button>
14
- <aside class="main-sidebar">
15
- <div class='btn-tab quick-actions universal-quick-actions'>
16
- <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe quick-action-leading-icon"></i><div class='caption'>Explore</div></a>
17
- <details class="universal-create-menu">
18
- <summary class="btn" aria-label="Create options"><i class="fa-solid fa-plus quick-action-leading-icon"></i><div class='caption'>Create</div><i class="fa-solid fa-chevron-down universal-create-caret" aria-hidden="true"></i></summary>
19
- <div class="universal-create-dropdown">
20
- <button type="button" data-universal-launcher-open="create_app">Create app</button>
21
- <button type="button" data-universal-launcher-open="create_plugin">Create plugin</button>
22
- </div>
23
- </details>
24
- <button type="button" class="btn" data-universal-launcher-open="ask" aria-label="Ask Pinokio">
25
- <span class="quick-action-icon quick-action-leading-icon ask-pinokio-icon" aria-hidden="true"></span>
26
- <div class='caption'>Ask Pinokio</div>
27
- </button>
28
- </div>
29
- <a href="/home" class="tab <%= sidebarSelected === 'home' ? 'selected' : '' %>" data-tippy-content="This machine"><i class='fas fa-laptop-code'></i><div class='caption'>This machine</div></a>
30
- <a href="/network" class="tab <%= sidebarSelected === 'network' ? 'selected' : '' %>" data-tippy-content="Local network"><i class="fa-solid fa-wifi"></i><div class='caption'>Local network</div></a>
31
- <% if (sidebarList.length > 0) { %>
32
- <% sidebarList.forEach(({ host, name, platform }) => { %>
33
- <% const selectedNet = sidebarSelectedNetName && String(name || "") === sidebarSelectedNetName; %>
34
- <a href="/net/<%=name%>" class="submenu tab <%= selectedNet ? 'selected' : '' %>" data-tippy-content="<%=name%> (<%=sidebarCurrentHost === host ? 'this machine' : host%>)"><i class="fa-brands fa-<%=brands[platform]%>"></i><div class='caption'><%=name%> (<%=sidebarCurrentHost === host ? 'this machine' : host%>)</div></a>
35
- <% }) %>
36
- <% } %>
37
- <a href="/connect" class="tab <%= sidebarSelected === 'connect' ? 'selected' : '' %>" data-tippy-content="Login"><i class="fa-solid fa-plug"></i><div class='caption'>Login</div></a>
38
- <a class='tab' href="<%=sidebarHelpUrl%>" target="_blank" data-tippy-content="Help"><i class="fa-solid fa-question"></i><div class='caption'>Help</div></a>
39
- <a class="tab <%= sidebarSelected === 'logs' ? 'selected' : '' %>" id='genlog' href="/logs" data-tippy-content="Logs"><i class="fa-solid fa-laptop-code"></i><div class='caption'>Logs</div></a>
40
- <a class="tab <%= sidebarSelected === 'autolaunch' ? 'selected' : '' %>" href="/autolaunch" data-tippy-content="Autolaunch"><i class="fa-solid fa-power-off"></i><div class='caption'>Autolaunch</div></a>
41
- <a class="tab <%= sidebarSelected === 'checkpoints' ? 'selected' : '' %>" href="/checkpoints" data-tippy-content="Checkpoints"><i class="fa-solid fa-clock-rotate-left"></i><div class='caption'>Checkpoints</div></a>
42
- <a class="tab <%= sidebarSelected === 'screenshots' ? 'selected' : '' %>" href="/screenshots" data-tippy-content="Screenshots"><i class="fa-solid fa-camera"></i><div class='caption'>Screenshots</div></a>
43
- <a class="tab <%= sidebarSelected === 'tools' ? 'selected' : '' %>" href="/tools" data-tippy-content="Installed Tools"><i class="fa-solid fa-toolbox"></i><div class='caption'>Installed Tools</div></a>
44
- <a class="tab <%= sidebarSelected === 'plugins' ? 'selected' : '' %>" href="/plugins" data-tippy-content="Plugins"><i class="fa-solid fa-plug-circle-bolt"></i><div class='caption'>Plugins</div></a>
45
- <a class="tab <%= sidebarSelected === 'tasks' ? 'selected' : '' %>" href="/tasks" data-tippy-content="Tasks"><i class="fa-solid fa-list-check"></i><div class='caption'>Tasks</div></a>
46
- <a class="tab <%= sidebarSelected === 'skills' ? 'selected' : '' %>" href="/skills" data-tippy-content="Skills"><i class="fa-solid fa-wand-magic-sparkles"></i><div class='caption'>Skills</div></a>
47
- <a class="tab <%= sidebarSelected === 'settings' ? 'selected' : '' %>" href="/home?mode=settings" data-tippy-content="Settings"><i class="fa-solid fa-gear"></i><div class='caption'>Settings</div></a>
13
+ <aside class="main-sidebar" id="main-sidebar" aria-label="Primary navigation">
14
+ <nav class="main-sidebar-nav" aria-label="Pinokio navigation">
15
+ <div class='main-sidebar-section main-sidebar-section-actions' aria-label="Actions">
16
+ <a class='tab main-sidebar-action <%= sidebarSelected === 'explore' ? 'selected' : '' %>' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe main-sidebar-action-icon"></i><div class='caption'>Explore</div></a>
17
+ <details class="universal-create-menu">
18
+ <summary class="tab main-sidebar-action" aria-label="Create options"><i class="fa-solid fa-plus main-sidebar-action-icon"></i><div class='caption'>Create</div></summary>
19
+ <div class="universal-create-dropdown">
20
+ <button type="button" data-universal-launcher-open="create_app">Create app</button>
21
+ <button type="button" data-universal-launcher-open="create_plugin">Create plugin</button>
22
+ </div>
23
+ </details>
24
+ <button type="button" class="tab main-sidebar-action" data-universal-launcher-open="ask" aria-label="Ask Pinokio">
25
+ <span class="main-sidebar-action-icon ask-pinokio-icon" aria-hidden="true"></span>
26
+ <div class='caption'>Ask</div>
27
+ </button>
28
+ </div>
29
+
30
+ <div class='main-sidebar-section' aria-label="Computer">
31
+ <div class="main-sidebar-section-title">Computer</div>
32
+ <a href="/home" class="tab <%= sidebarSelected === 'home' ? 'selected' : '' %>" data-tippy-content="This machine"><i class='fas fa-laptop-code'></i><div class='caption'>This machine</div></a>
33
+ <a href="/network" class="tab <%= sidebarSelected === 'network' ? 'selected' : '' %>" data-tippy-content="Local network"><i class="fa-solid fa-wifi"></i><div class='caption'>Local network</div></a>
34
+ <% if (sidebarList.length > 0) { %>
35
+ <% sidebarList.forEach(({ host, name, platform }) => { %>
36
+ <% const selectedNet = sidebarSelectedNetName && String(name || "") === sidebarSelectedNetName; %>
37
+ <a href="/net/<%=name%>" class="submenu tab <%= selectedNet ? 'selected' : '' %>" data-tippy-content="<%=name%> (<%=sidebarCurrentHost === host ? 'this machine' : host%>)"><i class="fa-brands fa-<%=brands[platform]%>"></i><div class='caption'><%=name%> (<%=sidebarCurrentHost === host ? 'this machine' : host%>)</div></a>
38
+ <% }) %>
39
+ <% } %>
40
+ </div>
41
+
42
+ <div class='main-sidebar-section' aria-label="Manage">
43
+ <div class="main-sidebar-section-title">Manage</div>
44
+ <a class="tab <%= sidebarSelected === 'checkpoints' ? 'selected' : '' %>" href="/checkpoints" data-tippy-content="Checkpoints"><i class="fa-solid fa-clock-rotate-left"></i><div class='caption'>Checkpoints</div></a>
45
+ <a class="tab <%= sidebarSelected === 'tools' ? 'selected' : '' %>" href="/tools" data-tippy-content="Installed Tools"><i class="fa-solid fa-toolbox"></i><div class='caption'>Tools</div></a>
46
+ <a class="tab <%= sidebarSelected === 'plugins' ? 'selected' : '' %>" href="/plugins" data-tippy-content="Plugins"><i class="fa-solid fa-plug-circle-bolt"></i><div class='caption'>Plugins</div></a>
47
+ <a class="tab <%= sidebarSelected === 'tasks' ? 'selected' : '' %>" href="/tasks" data-tippy-content="Tasks"><i class="fa-solid fa-list-check"></i><div class='caption'>Tasks</div></a>
48
+ <a class="tab <%= sidebarSelected === 'skills' ? 'selected' : '' %>" href="/skills" data-tippy-content="Skills"><i class="fa-solid fa-wand-magic-sparkles"></i><div class='caption'>Skills</div></a>
49
+ <a class="tab <%= sidebarSelected === 'logs' ? 'selected' : '' %>" id='genlog' href="/logs" data-tippy-content="Logs"><i class="fa-solid fa-laptop-code"></i><div class='caption'>Logs</div></a>
50
+ </div>
51
+
52
+ <div class='main-sidebar-section' aria-label="Configure">
53
+ <div class="main-sidebar-section-title">Configure</div>
54
+ <a class="tab <%= sidebarSelected === 'autolaunch' ? 'selected' : '' %>" href="/autolaunch" data-tippy-content="Autolaunch"><i class="fa-solid fa-power-off"></i><div class='caption'>Autolaunch</div></a>
55
+ <a href="/connect" class="tab <%= sidebarSelected === 'connect' ? 'selected' : '' %>" data-tippy-content="Login"><i class="fa-solid fa-plug"></i><div class='caption'>Login</div></a>
56
+ <a class="tab <%= sidebarSelected === 'settings' ? 'selected' : '' %>" href="/home?mode=settings" data-tippy-content="Settings"><i class="fa-solid fa-gear"></i><div class='caption'>Settings</div></a>
57
+ </div>
58
+ </nav>
59
+
48
60
  <% if (sidebarShowPeerAccess) { %>
49
- <%- include('peer_access_points', {
50
- peer_access_points: (typeof peer_access_points !== "undefined" ? peer_access_points : null),
51
- peer_url: (typeof peer_url !== "undefined" ? peer_url : null),
52
- peer_qr: (typeof peer_qr !== "undefined" ? peer_qr : null),
53
- }) %>
61
+ <div class='main-sidebar-peer'>
62
+ <%- include('peer_access_points', {
63
+ peer_access_points: (typeof peer_access_points !== "undefined" ? peer_access_points : null),
64
+ peer_url: (typeof peer_url !== "undefined" ? peer_url : null),
65
+ peer_qr: (typeof peer_qr !== "undefined" ? peer_qr : null),
66
+ }) %>
67
+ </div>
54
68
  <% } %>
55
69
  </aside>
56
70
  <script>
57
71
  (() => {
72
+ const body = document.body;
73
+
74
+ const headerToggle = document.getElementById("minimize-header");
75
+ const sidebar = document.getElementById("main-sidebar");
76
+ if (body && sidebar && headerToggle && !headerToggle.dataset.mainSidebarHeaderToggle) {
77
+ headerToggle.dataset.mainSidebarHeaderToggle = "true";
78
+ headerToggle.classList.add("sidebar-toggle", "main-sidebar-header-toggle");
79
+ headerToggle.setAttribute("type", "button");
80
+ headerToggle.setAttribute("aria-controls", "main-sidebar");
81
+ headerToggle.innerHTML = `
82
+ <span class="sidebar-toggle-glyph" aria-hidden="true">
83
+ <span class="sidebar-toggle-frame">
84
+ <span class="sidebar-toggle-panel"></span>
85
+ <span class="sidebar-toggle-content"></span>
86
+ </span>
87
+ </span>
88
+ `;
89
+
90
+ const updateToggle = (collapsed) => {
91
+ const expanded = !collapsed;
92
+ const label = expanded ? "Hide sidebar" : "Show sidebar";
93
+ headerToggle.setAttribute("aria-expanded", expanded ? "true" : "false");
94
+ headerToggle.setAttribute("aria-label", label);
95
+ headerToggle.setAttribute("title", label);
96
+ headerToggle.setAttribute("data-tippy-content", label);
97
+ headerToggle.dataset.sidebarState = expanded ? "expanded" : "collapsed";
98
+ if (headerToggle._tippy && typeof headerToggle._tippy.setContent === "function") {
99
+ headerToggle._tippy.setContent(label);
100
+ }
101
+ };
102
+
103
+ const setCollapsed = (collapsed) => {
104
+ const next = !!collapsed;
105
+ body.classList.toggle("main-sidebar-collapsed", next);
106
+ sidebar.setAttribute("aria-hidden", next ? "true" : "false");
107
+ updateToggle(next);
108
+ document.dispatchEvent(new CustomEvent("pinokio:sidebar-state", {
109
+ detail: { collapsed: next, source: "main-sidebar" }
110
+ }));
111
+ };
112
+
113
+ setCollapsed(false);
114
+
115
+ headerToggle.addEventListener("click", (event) => {
116
+ event.preventDefault();
117
+ setCollapsed(!body.classList.contains("main-sidebar-collapsed"));
118
+ });
119
+
120
+ window.PinokioMainSidebar = {
121
+ setCollapsed,
122
+ isCollapsed: () => body.classList.contains("main-sidebar-collapsed")
123
+ };
124
+ }
125
+
58
126
  if (window.__pinokioMainSidebarMobileInit) return;
59
127
  window.__pinokioMainSidebarMobileInit = true;
60
128
 
61
- const body = document.body;
62
129
  const html = document.documentElement;
63
- const sidebar = document.querySelector(".main-sidebar");
64
130
  const toggle = document.querySelector("[data-main-sidebar-toggle]");
65
131
  const backdrop = document.querySelector("[data-main-sidebar-backdrop]");
66
132
  const mobileMq = window.matchMedia("(max-width: 600px)");
67
133
 
68
134
  if (!body || !html || !sidebar || !toggle || !backdrop) return;
69
135
 
70
- body.classList.add("main-sidebar-page");
71
-
72
136
  const sync = () => {
73
137
  const open = body.classList.contains("main-sidebar-mobile-open");
74
138
  toggle.setAttribute("aria-expanded", open ? "true" : "false");