pinokiod 7.5.26 → 7.5.28

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 (38) hide show
  1. package/kernel/index.js +2 -5
  2. package/kernel/info.js +20 -0
  3. package/kernel/shell.js +2 -54
  4. package/kernel/sysinfo.js +2 -2
  5. package/package.json +1 -1
  6. package/server/public/common.js +42 -0
  7. package/server/public/style.css +142 -14
  8. package/server/public/task-launcher.css +11 -0
  9. package/server/views/app.ejs +173 -15
  10. package/server/views/app_search_test.ejs +3 -0
  11. package/server/views/connect/x.ejs +3 -0
  12. package/server/views/container.ejs +3 -0
  13. package/server/views/download.ejs +3 -0
  14. package/server/views/explore.ejs +3 -0
  15. package/server/views/form.ejs +3 -0
  16. package/server/views/frame.ejs +3 -0
  17. package/server/views/help.ejs +3 -0
  18. package/server/views/index.ejs +21 -66
  19. package/server/views/index2.ejs +3 -0
  20. package/server/views/init/index.ejs +3 -0
  21. package/server/views/mini.ejs +3 -0
  22. package/server/views/net.ejs +3 -0
  23. package/server/views/network.ejs +3 -0
  24. package/server/views/network2.ejs +3 -0
  25. package/server/views/old_network.ejs +3 -0
  26. package/server/views/partials/app_navheader.ejs +3 -0
  27. package/server/views/partials/home_action_modal.ejs +18 -31
  28. package/server/views/partials/main_sidebar.ejs +101 -4
  29. package/server/views/prototype/index.ejs +3 -0
  30. package/server/views/review.ejs +3 -0
  31. package/server/views/screenshots.ejs +3 -0
  32. package/server/views/settings.ejs +3 -0
  33. package/server/views/setup_home.ejs +3 -0
  34. package/server/views/terminal.ejs +3 -0
  35. package/server/views/terminals.ejs +3 -0
  36. package/test/info-ready.test.js +88 -0
  37. package/test/launch-settings-ui.test.js +3 -0
  38. package/test/shell-cleaned-log.test.js +66 -0
@@ -399,17 +399,6 @@ body.dark #sidebar-toggle[aria-expanded="true"] {
399
399
  box-shadow: 0 3.8px 0 currentColor, 0 7.6px 0 currentColor;
400
400
  transition: opacity 150ms cubic-bezier(0.25, 1, 0.5, 1), transform 150ms cubic-bezier(0.25, 1, 0.5, 1);
401
401
  }
402
- #sidebar-toggle[aria-expanded="false"] .sidebar-toggle-panel {
403
- background: transparent;
404
- outline: 1.5px solid currentColor;
405
- outline-offset: -1px;
406
- opacity: 0.35;
407
- transform: translateX(-1px) scaleX(0.8);
408
- }
409
- #sidebar-toggle[aria-expanded="false"] .sidebar-toggle-content {
410
- opacity: 0.42;
411
- transform: translateX(-2px);
412
- }
413
402
  #devtab {
414
403
  align-items: center;
415
404
  justify-content: center;
@@ -2017,6 +2006,7 @@ body.dark .workspace-mode-link:hover {
2017
2006
  flex-grow: 1;
2018
2007
  min-height: 0;
2019
2008
  overflow: hidden;
2009
+ position: relative;
2020
2010
  /*
2021
2011
  border-top: 1px solid rgba(0,0,0,0.04);
2022
2012
  */
@@ -2036,6 +2026,9 @@ body.dark .appcanvas_filler {
2036
2026
  height: 5px;
2037
2027
  background: #F1F1F1 !important;
2038
2028
  }
2029
+ .app-sidebar-peek-trigger {
2030
+ display: none;
2031
+ }
2039
2032
  .appcanvas-resizer {
2040
2033
  display: none;
2041
2034
  }
@@ -2179,6 +2172,81 @@ body.dark .appcanvas > aside {
2179
2172
  pointer-events: none;
2180
2173
  }
2181
2174
 
2175
+ @media (min-width: 769px) and (hover: hover) and (pointer: fine) {
2176
+ .appcanvas.vertical.sidebar-collapsed > aside {
2177
+ position: absolute;
2178
+ top: 0;
2179
+ bottom: 0;
2180
+ left: 0;
2181
+ z-index: 10000020;
2182
+ display: flex;
2183
+ flex: none;
2184
+ width: var(--appcanvas-sidebar-width);
2185
+ min-width: var(--appcanvas-sidebar-width);
2186
+ max-width: var(--appcanvas-sidebar-width);
2187
+ border-right: 1px solid var(--pinokio-sidebar-separator);
2188
+ opacity: 0;
2189
+ pointer-events: none;
2190
+ overflow: hidden;
2191
+ transform: translateX(-100%);
2192
+ }
2193
+
2194
+ .appcanvas.vertical.sidebar-collapsed > aside .menu-container {
2195
+ width: var(--appcanvas-sidebar-width);
2196
+ }
2197
+
2198
+ .appcanvas.vertical.sidebar-collapsed .app-sidebar-peek-trigger {
2199
+ display: block;
2200
+ position: absolute;
2201
+ top: 0;
2202
+ bottom: 0;
2203
+ left: 0;
2204
+ z-index: 10000021;
2205
+ width: 14px;
2206
+ padding: 0;
2207
+ border: 0;
2208
+ border-radius: 0;
2209
+ background: transparent;
2210
+ cursor: default;
2211
+ }
2212
+
2213
+ .appcanvas.vertical.sidebar-collapsed .app-sidebar-peek-trigger::after {
2214
+ content: "";
2215
+ position: absolute;
2216
+ top: 50%;
2217
+ left: 4px;
2218
+ width: 3px;
2219
+ height: 36px;
2220
+ border-radius: 999px;
2221
+ background: var(--pinokio-sidebar-separator-hover);
2222
+ opacity: 0;
2223
+ transform: translateY(-50%);
2224
+ transition: opacity 140ms cubic-bezier(0.25, 1, 0.5, 1);
2225
+ }
2226
+
2227
+ .appcanvas.vertical.sidebar-collapsed .app-sidebar-peek-trigger:hover::after,
2228
+ .appcanvas.vertical.sidebar-collapsed .app-sidebar-peek-trigger:focus-visible::after,
2229
+ .appcanvas.vertical.sidebar-peeking .app-sidebar-peek-trigger::after {
2230
+ opacity: 1;
2231
+ }
2232
+
2233
+ .appcanvas.vertical.sidebar-peeking .app-sidebar-peek-trigger {
2234
+ z-index: 10000019;
2235
+ }
2236
+
2237
+ .appcanvas.vertical.sidebar-collapsed.sidebar-peeking > aside {
2238
+ box-shadow: 20px 0 42px rgba(15, 23, 42, 0.16);
2239
+ opacity: 1;
2240
+ pointer-events: auto;
2241
+ transform: translateX(0);
2242
+ }
2243
+
2244
+ body.dark .appcanvas.vertical.sidebar-collapsed.sidebar-peeking > aside {
2245
+ box-shadow: 22px 0 46px rgba(0, 0, 0, 0.38);
2246
+ }
2247
+
2248
+ }
2249
+
2182
2250
  @media (prefers-reduced-motion: reduce) {
2183
2251
  #sidebar-toggle,
2184
2252
  .sidebar-toggle-panel,
@@ -4730,8 +4798,8 @@ body.dark .swal2-html-container input[type="text"] {
4730
4798
  }
4731
4799
 
4732
4800
  body.dark .swal2-html-container option {
4733
- background: #2d3748;
4734
- color: white;
4801
+ background: #ffffff;
4802
+ color: #111827;
4735
4803
  }
4736
4804
 
4737
4805
  /* Checkbox styling for dark mode */
@@ -7810,6 +7878,9 @@ body.dark .pinokio-custom-terminal-header {
7810
7878
  </span>
7811
7879
  </span>
7812
7880
  </button>
7881
+ <a class='btn2 pinokio-explore-nav-button' href="/home?mode=explore" data-pinokio-explore-nav="true" data-tippy-content="Explore" title="Explore" aria-label="Explore">
7882
+ <div><i class="fa-solid fa-globe" aria-hidden="true"></i></div>
7883
+ </a>
7813
7884
  <button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
7814
7885
  <button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
7815
7886
  <button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
@@ -7906,6 +7977,7 @@ body.dark .pinokio-custom-terminal-header {
7906
7977
  </header>
7907
7978
  <div class='appcanvas vertical <%=type === "browse" ? "dev-workspace" : ""%>' data-page-error="<%= error ? '1' : '0' %>">
7908
7979
  <% if (type !== 'files') { %>
7980
+ <button type='button' class='app-sidebar-peek-trigger' data-app-sidebar-peek-trigger aria-label='Show app navigation' aria-controls='app-sidebar' aria-expanded='false'></button>
7909
7981
  <aside id='app-sidebar' class='active'>
7910
7982
  <div class='menu-container'>
7911
7983
  <div class='menu-scroller'>
@@ -16084,6 +16156,7 @@ const rerenderMenuSection = (container, html) => {
16084
16156
  const appcanvas = document.querySelector(".appcanvas")
16085
16157
  const aside = document.getElementById("app-sidebar")
16086
16158
  const toggle = document.getElementById("sidebar-toggle")
16159
+ const peekTrigger = document.querySelector("[data-app-sidebar-peek-trigger]")
16087
16160
  if (!appcanvas || !aside || !toggle) {
16088
16161
  if (toggle) {
16089
16162
  toggle.classList.add("hidden")
@@ -16109,10 +16182,49 @@ const rerenderMenuSection = (container, html) => {
16109
16182
  }
16110
16183
  }
16111
16184
 
16185
+ const desktopPeekMq = window.matchMedia("(min-width: 769px) and (hover: hover) and (pointer: fine)")
16186
+ let peekCloseTimer = 0
16187
+
16188
+ const isCollapsed = () => appcanvas.classList.contains("sidebar-collapsed")
16189
+ const isPeeking = () => appcanvas.classList.contains("sidebar-peeking")
16190
+ const syncSidebarVisibility = () => {
16191
+ const peeking = isPeeking()
16192
+ aside.setAttribute("aria-hidden", isCollapsed() && !peeking ? "true" : "false")
16193
+ if (peekTrigger) {
16194
+ peekTrigger.setAttribute("aria-expanded", peeking ? "true" : "false")
16195
+ }
16196
+ }
16197
+ const canPeek = () => desktopPeekMq.matches && isCollapsed() && !document.body.classList.contains("mobile-menu-open")
16198
+ const setPeeking = (peeking) => {
16199
+ const next = !!peeking && canPeek()
16200
+ window.clearTimeout(peekCloseTimer)
16201
+ appcanvas.classList.toggle("sidebar-peeking", next)
16202
+ syncSidebarVisibility()
16203
+ }
16204
+ const shouldKeepPeekOpen = () => {
16205
+ const active = document.activeElement
16206
+ return (
16207
+ (peekTrigger && peekTrigger.matches(":hover")) ||
16208
+ aside.matches(":hover") ||
16209
+ (peekTrigger && active === peekTrigger) ||
16210
+ (active instanceof Node && aside.contains(active))
16211
+ )
16212
+ }
16213
+ const closePeekSoon = () => {
16214
+ window.clearTimeout(peekCloseTimer)
16215
+ peekCloseTimer = window.setTimeout(() => {
16216
+ if (shouldKeepPeekOpen()) return
16217
+ setPeeking(false)
16218
+ }, 120)
16219
+ }
16220
+
16112
16221
  const setCollapsed = (collapsed, options = {}) => {
16113
16222
  const next = !!collapsed
16223
+ if (!next) {
16224
+ appcanvas.classList.remove("sidebar-peeking")
16225
+ }
16114
16226
  appcanvas.classList.toggle("sidebar-collapsed", next)
16115
- aside.setAttribute("aria-hidden", next ? "true" : "false")
16227
+ syncSidebarVisibility()
16116
16228
  updateToggle(next)
16117
16229
  if (options.persist !== false) {
16118
16230
  try {
@@ -16138,9 +16250,55 @@ const rerenderMenuSection = (container, html) => {
16138
16250
  setCollapsed(!appcanvas.classList.contains("sidebar-collapsed"))
16139
16251
  })
16140
16252
 
16253
+ if (peekTrigger) {
16254
+ peekTrigger.addEventListener("pointerenter", () => setPeeking(true))
16255
+ peekTrigger.addEventListener("focus", () => setPeeking(true))
16256
+ peekTrigger.addEventListener("click", () => setPeeking(true))
16257
+ peekTrigger.addEventListener("pointerleave", closePeekSoon)
16258
+ peekTrigger.addEventListener("blur", closePeekSoon)
16259
+ aside.addEventListener("pointerenter", () => {
16260
+ if (isPeeking()) {
16261
+ window.clearTimeout(peekCloseTimer)
16262
+ }
16263
+ })
16264
+ aside.addEventListener("focusin", () => {
16265
+ if (isPeeking()) {
16266
+ window.clearTimeout(peekCloseTimer)
16267
+ }
16268
+ })
16269
+ aside.addEventListener("pointerleave", closePeekSoon)
16270
+ aside.addEventListener("focusout", closePeekSoon)
16271
+ document.addEventListener("pointerdown", (event) => {
16272
+ if (!isPeeking()) return
16273
+ const target = event.target
16274
+ if (target instanceof Node && (aside.contains(target) || peekTrigger.contains(target))) return
16275
+ setPeeking(false)
16276
+ })
16277
+ document.addEventListener("keydown", (event) => {
16278
+ if (event.key === "Escape" && isPeeking()) {
16279
+ setPeeking(false)
16280
+ if (typeof peekTrigger.focus === "function") {
16281
+ peekTrigger.focus()
16282
+ }
16283
+ }
16284
+ })
16285
+ const handlePeekMediaChange = () => {
16286
+ if (!desktopPeekMq.matches) {
16287
+ setPeeking(false)
16288
+ }
16289
+ }
16290
+ if (typeof desktopPeekMq.addEventListener === "function") {
16291
+ desktopPeekMq.addEventListener("change", handlePeekMediaChange)
16292
+ } else if (typeof desktopPeekMq.addListener === "function") {
16293
+ desktopPeekMq.addListener(handlePeekMediaChange)
16294
+ }
16295
+ }
16296
+
16141
16297
  window.PinokioSidebar = {
16142
16298
  setCollapsed,
16143
- isCollapsed: () => appcanvas.classList.contains("sidebar-collapsed")
16299
+ setPeeking,
16300
+ isCollapsed,
16301
+ isPeeking
16144
16302
  }
16145
16303
  })()
16146
16304
  </script>
@@ -111,6 +111,9 @@ document.addEventListener('DOMContentLoaded', function() {
111
111
  <button class="btn2" id="minimize-header" data-tippy-content="fullscreen" title="fullscreen">
112
112
  <div><i class="fa-solid fa-expand"></i></div>
113
113
  </button>
114
+ <a class='btn2 pinokio-explore-nav-button' href="/home?mode=explore" data-pinokio-explore-nav="true" data-tippy-content="Explore" title="Explore" aria-label="Explore">
115
+ <div><i class="fa-solid fa-globe" aria-hidden="true"></i></div>
116
+ </a>
114
117
  <button class="btn2" id="back" data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
115
118
  <button class="btn2" id="forward" data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
116
119
  <button class="btn2" id="refresh-page" data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
@@ -197,6 +197,9 @@ pre {
197
197
  <button class='btn2' id='minimize-header' data-tippy-content="fullscreen" title='fullscreen'>
198
198
  <div><i class="fa-solid fa-expand"></i></div>
199
199
  </button>
200
+ <a class='btn2 pinokio-explore-nav-button' href="/home?mode=explore" data-pinokio-explore-nav="true" data-tippy-content="Explore" title="Explore" aria-label="Explore">
201
+ <div><i class="fa-solid fa-globe" aria-hidden="true"></i></div>
202
+ </a>
200
203
  <button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
201
204
  <button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
202
205
  <button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
@@ -332,6 +332,9 @@ iframe {
332
332
  <button class='btn2' id='minimize-header' data-tippy-content="fullscreen" title='fullscreen'>
333
333
  <div><i class="fa-solid fa-expand"></i></div>
334
334
  </button>
335
+ <a class='btn2 pinokio-explore-nav-button' href="/home?mode=explore" data-pinokio-explore-nav="true" data-tippy-content="Explore" title="Explore" aria-label="Explore">
336
+ <div><i class="fa-solid fa-globe" aria-hidden="true"></i></div>
337
+ </a>
335
338
  <button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
336
339
  <button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
337
340
  <button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
@@ -125,6 +125,9 @@ body.frozen {
125
125
  <button class='btn2' id='minimize-header' data-tippy-content="fullscreen" title='fullscreen'>
126
126
  <div><i class="fa-solid fa-expand"></i></div>
127
127
  </button>
128
+ <a class='btn2 pinokio-explore-nav-button' href="/home?mode=explore" data-pinokio-explore-nav="true" data-tippy-content="Explore" title="Explore" aria-label="Explore">
129
+ <div><i class="fa-solid fa-globe" aria-hidden="true"></i></div>
130
+ </a>
128
131
  <button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
129
132
  <button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
130
133
  <button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
@@ -150,6 +150,9 @@ body.dark .explore-url {
150
150
  <button class='btn2' id='minimize-header' data-tippy-content="fullscreen" title='fullscreen'>
151
151
  <div><i class="fa-solid fa-expand"></i></div>
152
152
  </button>
153
+ <a class='btn2 pinokio-explore-nav-button' href="/home?mode=explore" data-pinokio-explore-nav="true" data-tippy-content="Explore" title="Explore" aria-label="Explore">
154
+ <div><i class="fa-solid fa-globe" aria-hidden="true"></i></div>
155
+ </a>
153
156
  <button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
154
157
  <button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
155
158
  <button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
@@ -162,6 +162,9 @@ document.addEventListener("DOMContentLoaded", async () => {
162
162
  <button class='btn2' id='minimize-header' data-tippy-content="fullscreen" title='fullscreen'>
163
163
  <div><i class="fa-solid fa-expand"></i></div>
164
164
  </button>
165
+ <a class='btn2 pinokio-explore-nav-button' href="/home?mode=explore" data-pinokio-explore-nav="true" data-tippy-content="Explore" title="Explore" aria-label="Explore">
166
+ <div><i class="fa-solid fa-globe" aria-hidden="true"></i></div>
167
+ </a>
165
168
  <button class='btn2' id='screenshot' data-tippy-content="screen capture"><i class="fa-solid fa-camera"></i></button>
166
169
  <button class='btn2' id='inspector' data-tippy-content="X-ray mode"><i class="fa-solid fa-eye"></i></button>
167
170
  <div class='flexible'></div>
@@ -92,6 +92,9 @@ main iframe {
92
92
  <button class='btn2' id='minimize-header' data-tippy-content="fullscreen" title='fullscreen'>
93
93
  <div><i class="fa-solid fa-expand"></i></div>
94
94
  </button>
95
+ <a class='btn2 pinokio-explore-nav-button' href="/home?mode=explore" data-pinokio-explore-nav="true" data-tippy-content="Explore" title="Explore" aria-label="Explore">
96
+ <div><i class="fa-solid fa-globe" aria-hidden="true"></i></div>
97
+ </a>
95
98
  <button class='btn2' id='screenshot' data-tippy-content="screen capture"><i class="fa-solid fa-camera"></i></button>
96
99
  <button class='btn2' id='inspector' data-tippy-content="X-ray mode"><i class="fa-solid fa-eye"></i></button>
97
100
  <div class='flexible'></div>
@@ -259,6 +259,9 @@ body.dark .item .tile .badge {
259
259
  <button class='btn2' id='minimize-header' data-tippy-content="fullscreen" title='fullscreen'>
260
260
  <div><i class="fa-solid fa-expand"></i></div>
261
261
  </button>
262
+ <a class='btn2 pinokio-explore-nav-button' href="/home?mode=explore" data-pinokio-explore-nav="true" data-tippy-content="Explore" title="Explore" aria-label="Explore">
263
+ <div><i class="fa-solid fa-globe" aria-hidden="true"></i></div>
264
+ </a>
262
265
  <button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
263
266
  <button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
264
267
  <button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
@@ -1005,51 +1005,29 @@ body.dark .home-actions-close:hover,
1005
1005
  body.dark .home-actions-close:focus-visible {
1006
1006
  background: rgba(255, 255, 255, 0.08);
1007
1007
  }
1008
- .home-actions-tabs {
1009
- display: flex;
1010
- gap: 6px;
1011
- padding: 10px 18px 0;
1012
- border-bottom: 1px solid rgba(15, 23, 42, 0.09);
1013
- }
1014
- body.dark .home-actions-tabs {
1015
- border-bottom-color: rgba(255, 255, 255, 0.08);
1016
- }
1017
- .home-actions-tab {
1018
- display: inline-flex;
1019
- align-items: center;
1020
- gap: 7px;
1021
- height: 34px;
1022
- padding: 0 12px;
1023
- border: 1px solid transparent;
1024
- border-bottom: none;
1025
- border-radius: 6px 6px 0 0;
1026
- background: transparent;
1027
- color: rgba(15, 23, 42, 0.68);
1028
- font-size: 12px;
1029
- font-weight: 700;
1030
- cursor: pointer;
1031
- }
1032
- .home-actions-tab.is-active {
1033
- border-color: rgba(15, 23, 42, 0.11);
1034
- background: rgba(248, 250, 252, 0.9);
1035
- color: rgba(15, 23, 42, 0.94);
1036
- }
1037
- body.dark .home-actions-tab {
1038
- color: rgba(226, 232, 240, 0.68);
1039
- }
1040
- body.dark .home-actions-tab.is-active {
1041
- border-color: rgba(255, 255, 255, 0.1);
1042
- background: rgba(255, 255, 255, 0.055);
1043
- color: rgba(248, 250, 252, 0.94);
1044
- }
1045
1008
  .home-actions-body {
1046
1009
  min-height: 0;
1047
1010
  flex: 1 1 auto;
1048
1011
  overflow: auto;
1049
1012
  padding: 14px 18px 18px;
1050
1013
  }
1051
- .home-actions-panel[hidden] {
1052
- display: none;
1014
+ .home-actions-section + .home-actions-section {
1015
+ margin-top: 16px;
1016
+ padding-top: 16px;
1017
+ border-top: 1px solid rgba(15, 23, 42, 0.09);
1018
+ }
1019
+ body.dark .home-actions-section + .home-actions-section {
1020
+ border-top-color: rgba(255, 255, 255, 0.08);
1021
+ }
1022
+ .home-actions-section-title {
1023
+ margin: 0 0 8px;
1024
+ color: rgba(15, 23, 42, 0.58);
1025
+ font-size: 11px;
1026
+ font-weight: 800;
1027
+ line-height: 1.2;
1028
+ }
1029
+ body.dark .home-actions-section-title {
1030
+ color: rgba(226, 232, 240, 0.56);
1053
1031
  }
1054
1032
  .home-run-menu-list,
1055
1033
  .home-actions-command-list,
@@ -1165,6 +1143,7 @@ body.dark .home-run-stop {
1165
1143
  color: rgba(252, 165, 165, 0.86);
1166
1144
  }
1167
1145
  .home-mode-command.is-danger {
1146
+ margin-top: 6px;
1168
1147
  color: rgba(185, 28, 28, 0.86);
1169
1148
  }
1170
1149
  body.dark .home-mode-command.is-danger {
@@ -1421,6 +1400,9 @@ body.dark aside .current.selected {
1421
1400
  <button class='btn2' id='minimize-header' data-tippy-content="fullscreen" title='fullscreen'>
1422
1401
  <div><i class="fa-solid fa-expand"></i></div>
1423
1402
  </button>
1403
+ <a class='btn2 pinokio-explore-nav-button' href="/home?mode=explore" data-pinokio-explore-nav="true" data-tippy-content="Explore" title="Explore" aria-label="Explore">
1404
+ <div><i class="fa-solid fa-globe" aria-hidden="true"></i></div>
1405
+ </a>
1424
1406
  <button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
1425
1407
  <button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
1426
1408
  <button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
@@ -2678,21 +2660,6 @@ const closeContextMenuForNode = (node) => {
2678
2660
  }
2679
2661
  }
2680
2662
  window.PinokioHomeCloseContextMenu = closeContextMenuForNode
2681
- const setHomeActionsTab = (dialog, tabName) => {
2682
- if (!dialog || !tabName) {
2683
- return
2684
- }
2685
- dialog.querySelectorAll('.home-actions-tab[data-tab]').forEach((tab) => {
2686
- const isActive = tab.getAttribute('data-tab') === tabName
2687
- tab.classList.toggle('is-active', isActive)
2688
- tab.setAttribute('aria-selected', isActive ? 'true' : 'false')
2689
- })
2690
- dialog.querySelectorAll('.home-actions-panel').forEach((panel) => {
2691
- const isActive = panel.getAttribute('data-panel') === tabName
2692
- panel.classList.toggle('is-active', isActive)
2693
- panel.hidden = !isActive
2694
- })
2695
- }
2696
2663
  const homeActionsDrawerMedia = window.matchMedia('(min-width: 961px)')
2697
2664
  const homeActionsReducedMotionMedia = window.matchMedia('(prefers-reduced-motion: reduce)')
2698
2665
  const isHomeActionsDrawerViewport = () => homeActionsDrawerMedia.matches
@@ -2791,7 +2758,6 @@ const openHomeActionsDialog = (button) => {
2791
2758
  return
2792
2759
  }
2793
2760
  closeHomeActionsDialogs(dialog)
2794
- setHomeActionsTab(dialog, button.getAttribute('data-default-tab') || 'run')
2795
2761
  if (isHomeActionsDrawerViewport()) {
2796
2762
  setHomeActionsDrawerOffset()
2797
2763
  dialog.classList.remove('is-closing')
@@ -3094,17 +3060,6 @@ document.addEventListener("click", async (e) => {
3094
3060
  closeHomeActionsDialog(e.target)
3095
3061
  return
3096
3062
  }
3097
- if (e.target.classList.contains("home-actions-tab")) {
3098
- target = e.target
3099
- } else {
3100
- target = e.target.closest(".home-actions-tab")
3101
- }
3102
- if (target && target.hasAttribute("data-tab")) {
3103
- e.preventDefault()
3104
- e.stopPropagation()
3105
- setHomeActionsTab(target.closest(".home-actions-dialog"), target.getAttribute("data-tab"))
3106
- return
3107
- }
3108
3063
  if (e.target.classList.contains("home-run-stop")) {
3109
3064
  target = e.target
3110
3065
  } else {
@@ -272,6 +272,9 @@ body.dark .open-menu, body.dark .browse {
272
272
  <button class='btn2' id='minimize-header' data-tippy-content="fullscreen" title='fullscreen'>
273
273
  <div><i class="fa-solid fa-expand"></i></div>
274
274
  </button>
275
+ <a class='btn2 pinokio-explore-nav-button' href="/home?mode=explore" data-pinokio-explore-nav="true" data-tippy-content="Explore" title="Explore" aria-label="Explore">
276
+ <div><i class="fa-solid fa-globe" aria-hidden="true"></i></div>
277
+ </a>
275
278
  <div class='nav-btns'>
276
279
  <a class='btn2' href="<%=portal%>" target="_blank"><div><i class="fa-solid fa-question"></i></div><div>Help</div></a>
277
280
  <a class='btn2' id='genlog' href="/logs"><div><i class="fa-solid fa-laptop-code"></i></div><div>Logs</div></a>
@@ -1528,6 +1528,9 @@ body.dark .ace-editor {
1528
1528
  <button class='btn2' id='minimize-header' data-tippy-content="fullscreen" title='fullscreen'>
1529
1529
  <div><i class="fa-solid fa-expand"></i></div>
1530
1530
  </button>
1531
+ <a class='btn2 pinokio-explore-nav-button' href="/home?mode=explore" data-pinokio-explore-nav="true" data-tippy-content="Explore" title="Explore" aria-label="Explore">
1532
+ <div><i class="fa-solid fa-globe" aria-hidden="true"></i></div>
1533
+ </a>
1531
1534
  <button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
1532
1535
  <button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
1533
1536
  <button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
@@ -761,6 +761,9 @@ body.dark .appcanvas {
761
761
  <button class='btn2' id='minimize-header' data-tippy-content="fullscreen" title='fullscreen'>
762
762
  <div><i class="fa-solid fa-expand"></i></div>
763
763
  </button>
764
+ <a class='btn2 pinokio-explore-nav-button' href="/home?mode=explore" data-pinokio-explore-nav="true" data-tippy-content="Explore" title="Explore" aria-label="Explore">
765
+ <div><i class="fa-solid fa-globe" aria-hidden="true"></i></div>
766
+ </a>
764
767
  <button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
765
768
  <button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
766
769
  <button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
@@ -1294,6 +1294,9 @@ document.addEventListener('DOMContentLoaded', function() {
1294
1294
  <button class='btn2' id='minimize-header' data-tippy-content="fullscreen" title='fullscreen'>
1295
1295
  <div><i class="fa-solid fa-expand"></i></div>
1296
1296
  </button>
1297
+ <a class='btn2 pinokio-explore-nav-button' href="/home?mode=explore" data-pinokio-explore-nav="true" data-tippy-content="Explore" title="Explore" aria-label="Explore">
1298
+ <div><i class="fa-solid fa-globe" aria-hidden="true"></i></div>
1299
+ </a>
1297
1300
  <button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
1298
1301
  <button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
1299
1302
  <button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
@@ -1369,6 +1369,9 @@ document.addEventListener('DOMContentLoaded', function() {
1369
1369
  <button class='btn2' id='minimize-header' data-tippy-content="fullscreen" title='fullscreen'>
1370
1370
  <div><i class="fa-solid fa-expand"></i></div>
1371
1371
  </button>
1372
+ <a class='btn2 pinokio-explore-nav-button' href="/home?mode=explore" data-pinokio-explore-nav="true" data-tippy-content="Explore" title="Explore" aria-label="Explore">
1373
+ <div><i class="fa-solid fa-globe" aria-hidden="true"></i></div>
1374
+ </a>
1372
1375
  <button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
1373
1376
  <button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
1374
1377
  <button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
@@ -422,6 +422,9 @@ table h3 {
422
422
  <button class='btn2' id='minimize-header' data-tippy-content="fullscreen" title='fullscreen'>
423
423
  <div><i class="fa-solid fa-expand"></i></div>
424
424
  </button>
425
+ <a class='btn2 pinokio-explore-nav-button' href="/home?mode=explore" data-pinokio-explore-nav="true" data-tippy-content="Explore" title="Explore" aria-label="Explore">
426
+ <div><i class="fa-solid fa-globe" aria-hidden="true"></i></div>
427
+ </a>
425
428
  <button class='btn2' id='back'><div><i class="fa-solid fa-chevron-left"></i></div></button>
426
429
  <button class='btn2' id='forward'><div><i class="fa-solid fa-chevron-right"></i></div></button>
427
430
  <button class='btn2' id='refresh-page'><div><i class="fa-solid fa-rotate-right"></i></div></button>
@@ -405,6 +405,9 @@ input:checked + .slider:before {
405
405
  <button class='btn2' id='minimize-header' data-tippy-content="fullscreen" title='fullscreen'>
406
406
  <div><i class="fa-solid fa-expand"></i></div>
407
407
  </button>
408
+ <a class='btn2 pinokio-explore-nav-button' href="/home?mode=explore" data-pinokio-explore-nav="true" data-tippy-content="Explore" title="Explore" aria-label="Explore">
409
+ <div><i class="fa-solid fa-globe" aria-hidden="true"></i></div>
410
+ </a>
408
411
  <button class='btn2' id='back'><div><i class="fa-solid fa-chevron-left"></i></div></button>
409
412
  <button class='btn2' id='forward'><div><i class="fa-solid fa-chevron-right"></i></div></button>
410
413
  <button class='btn2' id='refresh-page'><div><i class="fa-solid fa-rotate-right"></i></div></button>
@@ -4,6 +4,9 @@
4
4
  <button class='btn2' id='minimize-header' data-tippy-content="fullscreen" title='fullscreen'>
5
5
  <div><i class="fa-solid fa-expand"></i></div>
6
6
  </button>
7
+ <a class='btn2 pinokio-explore-nav-button' href="/home?mode=explore" data-pinokio-explore-nav="true" data-tippy-content="Explore" title="Explore" aria-label="Explore">
8
+ <div><i class="fa-solid fa-globe" aria-hidden="true"></i></div>
9
+ </a>
7
10
  <button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
8
11
  <button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
9
12
  <button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
@@ -25,42 +25,29 @@
25
25
  </button>
26
26
  </div>
27
27
 
28
- <div class='home-actions-tabs' aria-label='App action modes'>
29
- <button type='button' class='home-actions-tab is-active' role='tab' aria-selected='true' data-tab='run' aria-controls='<%= id %>-run'>
30
- <i class='fa-solid fa-play' aria-hidden='true'></i>
31
- <span>Run</span>
32
- </button>
33
- <button type='button' class='home-actions-tab home-browse' data-src='<%= item.dev_url %>' title='Open dev mode' aria-label='Open dev mode'>
34
- <i class='fa-solid fa-code' aria-hidden='true'></i>
35
- <span>Dev</span>
36
- <% if (item.terminal_online_count > 0) { %>
37
- <span class='home-actions-count'><%= item.terminal_online_count %> online</span>
38
- <% } %>
39
- </button>
40
- <button type='button' class='home-actions-tab' role='tab' aria-selected='false' data-tab='files' aria-controls='<%= id %>-files'>
41
- <i class='fa-solid fa-file-lines' aria-hidden='true'></i>
42
- <span>Files</span>
43
- </button>
44
- </div>
45
-
46
28
  <div class='home-actions-body'>
47
- <section id='<%= id %>-run' class='home-actions-panel is-active' role='tabpanel' data-panel='run'>
48
- <div class='home-run-menu-list'>
29
+ <% if (item.menu && item.menu.length > 0) { %>
30
+ <section class='home-actions-section' aria-labelledby='<%= id %>-run-title'>
31
+ <div class='home-actions-section-title' id='<%= id %>-run-title'>Run</div>
32
+ <div class='home-run-menu-list'>
33
+ <%- include('./home_run_menu', { menu: item.menu, app: item }) %>
34
+ </div>
35
+ </section>
36
+ <% } %>
37
+
38
+ <section class='home-actions-section' aria-labelledby='<%= id %>-app-title'>
39
+ <div class='home-actions-section-title' id='<%= id %>-app-title'>App</div>
40
+ <div class='home-actions-command-list'>
49
41
  <button type='button' class='home-mode-command home-browse' data-src='<%= item.view_url %>'>
50
42
  <i class='fa-regular fa-eye' aria-hidden='true'></i>
51
43
  <span>Open without launching</span>
52
44
  </button>
53
- <% if (item.menu && item.menu.length > 0) { %>
54
- <%- include('./home_run_menu', { menu: item.menu, app: item }) %>
55
- <% } %>
56
- </div>
57
- </section>
58
-
59
- <section id='<%= id %>-files' class='home-actions-panel' role='tabpanel' data-panel='files' hidden>
60
- <div class='home-actions-command-list'>
61
- <button type='button' class='home-mode-command home-browse' data-src='<%= item.files_url %>'>
62
- <i class='fa-solid fa-file-lines' aria-hidden='true'></i>
63
- <span>Open files mode</span>
45
+ <button type='button' class='home-mode-command home-browse' data-src='<%= item.dev_url %>'>
46
+ <i class='fa-solid fa-code' aria-hidden='true'></i>
47
+ <span>Open dev mode</span>
48
+ <% if (item.terminal_online_count > 0) { %>
49
+ <span class='home-actions-count'><%= item.terminal_online_count %> online</span>
50
+ <% } %>
64
51
  </button>
65
52
  <button type='button' class='home-mode-command' data-filepath='<%= item.filepath %>'>
66
53
  <i class='fa-solid fa-folder-open' aria-hidden='true'></i>