pinokiod 7.5.9 → 7.5.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/kernel/api/shell/index.js +1 -4
- package/kernel/index.js +1 -1
- package/kernel/shell.js +3 -2
- package/kernel/shell_conda_runtime_guard.js +263 -105
- package/kernel/shells.js +1 -1
- package/package.json +1 -1
- package/server/public/style.css +2 -2
- package/server/views/index.ejs +218 -14
- package/test/shell-api.test.js +7 -6
- package/test/shell-conda-runtime-guard.test.js +477 -77
package/server/views/index.ejs
CHANGED
|
@@ -197,6 +197,15 @@ body.dark .context-menu-wrapper {
|
|
|
197
197
|
text-transform: none;
|
|
198
198
|
transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
|
|
199
199
|
}
|
|
200
|
+
.home-app-line .menu-btns > .open-actions-modal {
|
|
201
|
+
width: 28px;
|
|
202
|
+
min-width: 28px;
|
|
203
|
+
padding: 0 !important;
|
|
204
|
+
}
|
|
205
|
+
.home-app-line .menu-btns > .open-actions-modal i {
|
|
206
|
+
width: 14px;
|
|
207
|
+
font-size: 13px;
|
|
208
|
+
}
|
|
200
209
|
body.dark .home-app-line .menu-btns > .btn {
|
|
201
210
|
border-color: rgba(255, 255, 255, 0.075) !important;
|
|
202
211
|
background: rgba(255, 255, 255, 0.045) !important;
|
|
@@ -749,6 +758,8 @@ body.dark .home-search-form .home-apps-sort .ts-dropdown [data-selectable].optio
|
|
|
749
758
|
gap: 8px;
|
|
750
759
|
}
|
|
751
760
|
body.is-home {
|
|
761
|
+
--home-actions-drawer-width: min(420px, calc(100vw - 240px));
|
|
762
|
+
--home-actions-drawer-top: 0px;
|
|
752
763
|
--home-page-nav-bg: #ffffff;
|
|
753
764
|
--home-page-nav-border: rgba(15, 23, 42, 0.12);
|
|
754
765
|
--home-page-accent: #6b7280;
|
|
@@ -1164,6 +1175,69 @@ body.dark .home-actions-empty {
|
|
|
1164
1175
|
border-color: rgba(255, 255, 255, 0.12);
|
|
1165
1176
|
color: rgba(226, 232, 240, 0.58);
|
|
1166
1177
|
}
|
|
1178
|
+
@media only screen and (min-width: 961px) {
|
|
1179
|
+
body.is-home.home-actions-drawer-open main > .container {
|
|
1180
|
+
padding-right: calc(var(--home-actions-drawer-width) + 16px);
|
|
1181
|
+
}
|
|
1182
|
+
@keyframes homeActionsDrawerIn {
|
|
1183
|
+
from {
|
|
1184
|
+
opacity: 0.72;
|
|
1185
|
+
transform: translateX(18px);
|
|
1186
|
+
}
|
|
1187
|
+
to {
|
|
1188
|
+
opacity: 1;
|
|
1189
|
+
transform: translateX(0);
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
@keyframes homeActionsDrawerOut {
|
|
1193
|
+
from {
|
|
1194
|
+
opacity: 1;
|
|
1195
|
+
transform: translateX(0);
|
|
1196
|
+
}
|
|
1197
|
+
to {
|
|
1198
|
+
opacity: 0.72;
|
|
1199
|
+
transform: translateX(18px);
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
.home-actions-dialog.is-docked[open] {
|
|
1203
|
+
top: var(--home-actions-drawer-top);
|
|
1204
|
+
right: 0;
|
|
1205
|
+
bottom: 0;
|
|
1206
|
+
left: auto;
|
|
1207
|
+
width: var(--home-actions-drawer-width);
|
|
1208
|
+
max-height: none;
|
|
1209
|
+
height: calc(100vh - var(--home-actions-drawer-top));
|
|
1210
|
+
border-top: none;
|
|
1211
|
+
border-right: none;
|
|
1212
|
+
border-bottom: none;
|
|
1213
|
+
border-radius: 0;
|
|
1214
|
+
box-shadow: none;
|
|
1215
|
+
transform: none;
|
|
1216
|
+
animation: homeActionsDrawerIn 180ms cubic-bezier(0.22, 1, 0.36, 1);
|
|
1217
|
+
will-change: transform, opacity;
|
|
1218
|
+
}
|
|
1219
|
+
body.dark .home-actions-dialog.is-docked[open] {
|
|
1220
|
+
box-shadow: none;
|
|
1221
|
+
}
|
|
1222
|
+
.home-actions-dialog.is-docked.is-closing[open] {
|
|
1223
|
+
pointer-events: none;
|
|
1224
|
+
animation: homeActionsDrawerOut 130ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
|
|
1225
|
+
}
|
|
1226
|
+
.home-actions-dialog.is-docked::backdrop {
|
|
1227
|
+
background: transparent;
|
|
1228
|
+
}
|
|
1229
|
+
.home-actions-dialog.is-docked .home-actions-shell {
|
|
1230
|
+
height: 100%;
|
|
1231
|
+
min-height: 0;
|
|
1232
|
+
}
|
|
1233
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1234
|
+
.home-actions-dialog.is-docked[open],
|
|
1235
|
+
.home-actions-dialog.is-docked.is-closing[open] {
|
|
1236
|
+
animation: none;
|
|
1237
|
+
will-change: auto;
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1167
1241
|
#suggestion {
|
|
1168
1242
|
padding: 20px;
|
|
1169
1243
|
display: flex;
|
|
@@ -1452,8 +1526,8 @@ body.dark aside .current.selected {
|
|
|
1452
1526
|
>
|
|
1453
1527
|
<i class="fa-<%=item.starred ? "solid" : "regular"%> fa-star" aria-hidden="true"></i>
|
|
1454
1528
|
</button>
|
|
1455
|
-
<button class='btn open-menu open-actions-modal' type='button' data-dialog-id="home-actions-running-<%=index%>" aria-haspopup="dialog" title="
|
|
1456
|
-
<i class="fa-solid fa-
|
|
1529
|
+
<button class='btn open-menu open-actions-modal' type='button' data-dialog-id="home-actions-running-<%=index%>" aria-haspopup="dialog" aria-expanded="false" title="Open actions panel" aria-label="Open actions panel">
|
|
1530
|
+
<i class="fa-solid fa-list-ul" aria-hidden="true"></i>
|
|
1457
1531
|
</button>
|
|
1458
1532
|
<% const autolaunchRunningScript = !!(item.autolaunch_starting && item.autolaunch_script && item.running_scripts && item.running_scripts.some((s) => { const scriptName = s && (s.name || s.script_path || s.path || ""); return scriptName === item.autolaunch_script || String(scriptName).endsWith(`/${item.autolaunch_script}`) })) %>
|
|
1459
1533
|
<% if (item.autolaunch_starting && !autolaunchRunningScript) { %>
|
|
@@ -1551,8 +1625,8 @@ body.dark aside .current.selected {
|
|
|
1551
1625
|
>
|
|
1552
1626
|
<i class="fa-<%=item.starred ? "solid" : "regular"%> fa-star" aria-hidden="true"></i>
|
|
1553
1627
|
</button>
|
|
1554
|
-
<button class='btn open-menu open-actions-modal' type='button' data-dialog-id="home-actions-not-running-<%=index%>" aria-haspopup="dialog" title="
|
|
1555
|
-
<i class="fa-solid fa-
|
|
1628
|
+
<button class='btn open-menu open-actions-modal' type='button' data-dialog-id="home-actions-not-running-<%=index%>" aria-haspopup="dialog" aria-expanded="false" title="Open actions panel" aria-label="Open actions panel">
|
|
1629
|
+
<i class="fa-solid fa-list-ul" aria-hidden="true"></i>
|
|
1556
1630
|
</button>
|
|
1557
1631
|
<% if (notRunningTerminalOnlineCount > 0) { %>
|
|
1558
1632
|
<% const notRunningTerminalLabel = notRunningTerminalOnlineCount > 0 ? `${notRunningTerminalOnlineCount} terminal${notRunningTerminalOnlineCount === 1 ? "" : "s"} online` : "Terminals" %>
|
|
@@ -2488,6 +2562,10 @@ const startHomeAutolaunchPolling = () => {
|
|
|
2488
2562
|
startHomeAutolaunchPolling()
|
|
2489
2563
|
document.addEventListener("keydown", (e) => {
|
|
2490
2564
|
e = e || window.event;
|
|
2565
|
+
if (e.key === "Escape" && !hasHomeActionsBlockingOverlay() && closeActiveHomeActionsDrawer()) {
|
|
2566
|
+
e.preventDefault()
|
|
2567
|
+
return
|
|
2568
|
+
}
|
|
2491
2569
|
if (e.key === "ArrowUp") {
|
|
2492
2570
|
console.log("up arrow pressed");
|
|
2493
2571
|
selectedIndex = Math.max(selectedIndex-1, 0)
|
|
@@ -2583,12 +2661,6 @@ const closeContextMenuForNode = (node) => {
|
|
|
2583
2661
|
contextMenu.dataset.open = 'false'
|
|
2584
2662
|
}
|
|
2585
2663
|
}
|
|
2586
|
-
const dialog = node && typeof node.closest === 'function'
|
|
2587
|
-
? node.closest('.home-actions-dialog')
|
|
2588
|
-
: null
|
|
2589
|
-
if (dialog && dialog.open && typeof dialog.close === 'function') {
|
|
2590
|
-
dialog.close()
|
|
2591
|
-
}
|
|
2592
2664
|
}
|
|
2593
2665
|
window.PinokioHomeCloseContextMenu = closeContextMenuForNode
|
|
2594
2666
|
const setHomeActionsTab = (dialog, tabName) => {
|
|
@@ -2606,6 +2678,90 @@ const setHomeActionsTab = (dialog, tabName) => {
|
|
|
2606
2678
|
panel.hidden = !isActive
|
|
2607
2679
|
})
|
|
2608
2680
|
}
|
|
2681
|
+
const homeActionsDrawerMedia = window.matchMedia('(min-width: 961px)')
|
|
2682
|
+
const homeActionsReducedMotionMedia = window.matchMedia('(prefers-reduced-motion: reduce)')
|
|
2683
|
+
const isHomeActionsDrawerViewport = () => homeActionsDrawerMedia.matches
|
|
2684
|
+
const syncHomeActionsDrawerState = () => {
|
|
2685
|
+
const hasDockedDialog = Boolean(document.querySelector('.home-actions-dialog.is-docked[open]'))
|
|
2686
|
+
document.body.classList.toggle('home-actions-drawer-open', hasDockedDialog)
|
|
2687
|
+
}
|
|
2688
|
+
const setHomeActionsDrawerOffset = () => {
|
|
2689
|
+
const header = document.querySelector('body.is-home > header.navheader')
|
|
2690
|
+
const top = header ? Math.max(0, Math.round(header.getBoundingClientRect().bottom)) : 0
|
|
2691
|
+
document.body.style.setProperty('--home-actions-drawer-top', `${top}px`)
|
|
2692
|
+
}
|
|
2693
|
+
const setHomeActionsTriggerExpanded = (dialog, expanded) => {
|
|
2694
|
+
if (!dialog || !dialog.id) {
|
|
2695
|
+
return
|
|
2696
|
+
}
|
|
2697
|
+
document.querySelectorAll('.open-actions-modal').forEach((button) => {
|
|
2698
|
+
if (button.getAttribute('data-dialog-id') === dialog.id) {
|
|
2699
|
+
button.setAttribute('aria-expanded', expanded ? 'true' : 'false')
|
|
2700
|
+
}
|
|
2701
|
+
})
|
|
2702
|
+
}
|
|
2703
|
+
const closeHomeActionsDialog = (dialog) => {
|
|
2704
|
+
if (!dialog || !dialog.open) {
|
|
2705
|
+
return
|
|
2706
|
+
}
|
|
2707
|
+
const shouldAnimate = dialog.classList.contains('is-docked')
|
|
2708
|
+
&& isHomeActionsDrawerViewport()
|
|
2709
|
+
&& !homeActionsReducedMotionMedia.matches
|
|
2710
|
+
if (!shouldAnimate) {
|
|
2711
|
+
if (typeof dialog.close === 'function') {
|
|
2712
|
+
dialog.close()
|
|
2713
|
+
} else {
|
|
2714
|
+
dialog.removeAttribute('open')
|
|
2715
|
+
dialog.classList.remove('is-docked', 'is-closing')
|
|
2716
|
+
setHomeActionsTriggerExpanded(dialog, false)
|
|
2717
|
+
syncHomeActionsDrawerState()
|
|
2718
|
+
}
|
|
2719
|
+
return
|
|
2720
|
+
}
|
|
2721
|
+
if (dialog.classList.contains('is-closing')) {
|
|
2722
|
+
return
|
|
2723
|
+
}
|
|
2724
|
+
dialog.classList.add('is-closing')
|
|
2725
|
+
let finished = false
|
|
2726
|
+
const finishClose = () => {
|
|
2727
|
+
if (finished) {
|
|
2728
|
+
return
|
|
2729
|
+
}
|
|
2730
|
+
finished = true
|
|
2731
|
+
dialog.removeEventListener('animationend', finishClose)
|
|
2732
|
+
if (dialog.open) {
|
|
2733
|
+
dialog.close()
|
|
2734
|
+
}
|
|
2735
|
+
}
|
|
2736
|
+
dialog.addEventListener('animationend', finishClose)
|
|
2737
|
+
window.setTimeout(finishClose, 180)
|
|
2738
|
+
}
|
|
2739
|
+
const closeHomeActionsDialogs = (exceptDialog = null) => {
|
|
2740
|
+
document.querySelectorAll('.home-actions-dialog[open]').forEach((dialog) => {
|
|
2741
|
+
if (dialog === exceptDialog) {
|
|
2742
|
+
return
|
|
2743
|
+
}
|
|
2744
|
+
if (typeof dialog.close === 'function') {
|
|
2745
|
+
dialog.close()
|
|
2746
|
+
} else {
|
|
2747
|
+
dialog.removeAttribute('open')
|
|
2748
|
+
dialog.classList.remove('is-docked', 'is-closing')
|
|
2749
|
+
setHomeActionsTriggerExpanded(dialog, false)
|
|
2750
|
+
}
|
|
2751
|
+
})
|
|
2752
|
+
syncHomeActionsDrawerState()
|
|
2753
|
+
}
|
|
2754
|
+
document.querySelectorAll('.home-actions-dialog').forEach((dialog) => {
|
|
2755
|
+
if (dialog.dataset.homeActionsBound === 'true') {
|
|
2756
|
+
return
|
|
2757
|
+
}
|
|
2758
|
+
dialog.dataset.homeActionsBound = 'true'
|
|
2759
|
+
dialog.addEventListener('close', () => {
|
|
2760
|
+
dialog.classList.remove('is-docked', 'is-closing')
|
|
2761
|
+
setHomeActionsTriggerExpanded(dialog, false)
|
|
2762
|
+
syncHomeActionsDrawerState()
|
|
2763
|
+
})
|
|
2764
|
+
})
|
|
2609
2765
|
const openHomeActionsDialog = (button) => {
|
|
2610
2766
|
if (!button) {
|
|
2611
2767
|
return
|
|
@@ -2615,13 +2771,61 @@ const openHomeActionsDialog = (button) => {
|
|
|
2615
2771
|
if (!dialog) {
|
|
2616
2772
|
return
|
|
2617
2773
|
}
|
|
2774
|
+
if (dialog.open) {
|
|
2775
|
+
closeHomeActionsDialog(dialog)
|
|
2776
|
+
return
|
|
2777
|
+
}
|
|
2778
|
+
closeHomeActionsDialogs(dialog)
|
|
2618
2779
|
setHomeActionsTab(dialog, button.getAttribute('data-default-tab') || 'run')
|
|
2619
|
-
if (
|
|
2780
|
+
if (isHomeActionsDrawerViewport()) {
|
|
2781
|
+
setHomeActionsDrawerOffset()
|
|
2782
|
+
dialog.classList.remove('is-closing')
|
|
2783
|
+
dialog.classList.add('is-docked')
|
|
2784
|
+
if (!dialog.open) {
|
|
2785
|
+
if (typeof dialog.show === 'function') {
|
|
2786
|
+
dialog.show()
|
|
2787
|
+
} else {
|
|
2788
|
+
dialog.setAttribute('open', '')
|
|
2789
|
+
}
|
|
2790
|
+
}
|
|
2791
|
+
button.setAttribute('aria-expanded', 'true')
|
|
2792
|
+
syncHomeActionsDrawerState()
|
|
2793
|
+
} else if (typeof dialog.showModal === 'function') {
|
|
2794
|
+
dialog.classList.remove('is-docked')
|
|
2620
2795
|
dialog.showModal()
|
|
2796
|
+
button.setAttribute('aria-expanded', 'true')
|
|
2621
2797
|
} else {
|
|
2798
|
+
dialog.classList.remove('is-docked')
|
|
2622
2799
|
dialog.setAttribute('open', '')
|
|
2800
|
+
button.setAttribute('aria-expanded', 'true')
|
|
2623
2801
|
}
|
|
2624
2802
|
}
|
|
2803
|
+
const closeActiveHomeActionsDrawer = () => {
|
|
2804
|
+
const dialog = document.querySelector('.home-actions-dialog.is-docked[open]')
|
|
2805
|
+
if (!dialog) {
|
|
2806
|
+
return false
|
|
2807
|
+
}
|
|
2808
|
+
if (typeof dialog.close === 'function') {
|
|
2809
|
+
closeHomeActionsDialog(dialog)
|
|
2810
|
+
} else {
|
|
2811
|
+
dialog.removeAttribute('open')
|
|
2812
|
+
dialog.classList.remove('is-docked', 'is-closing')
|
|
2813
|
+
setHomeActionsTriggerExpanded(dialog, false)
|
|
2814
|
+
syncHomeActionsDrawerState()
|
|
2815
|
+
}
|
|
2816
|
+
return true
|
|
2817
|
+
}
|
|
2818
|
+
const hasHomeActionsBlockingOverlay = () => {
|
|
2819
|
+
return Boolean(document.querySelector('.swal2-container.swal2-shown, .swal2-container.swal2-backdrop-show'))
|
|
2820
|
+
}
|
|
2821
|
+
const handleHomeActionsDrawerMediaChange = () => {
|
|
2822
|
+
closeHomeActionsDialogs()
|
|
2823
|
+
}
|
|
2824
|
+
if (typeof homeActionsDrawerMedia.addEventListener === 'function') {
|
|
2825
|
+
homeActionsDrawerMedia.addEventListener('change', handleHomeActionsDrawerMediaChange)
|
|
2826
|
+
} else if (typeof homeActionsDrawerMedia.addListener === 'function') {
|
|
2827
|
+
homeActionsDrawerMedia.addListener(handleHomeActionsDrawerMediaChange)
|
|
2828
|
+
}
|
|
2625
2829
|
const navigateHomeAppLine = (line) => {
|
|
2626
2830
|
if (!line) {
|
|
2627
2831
|
return
|
|
@@ -2866,13 +3070,13 @@ document.addEventListener("click", async (e) => {
|
|
|
2866
3070
|
e.preventDefault()
|
|
2867
3071
|
e.stopPropagation()
|
|
2868
3072
|
const dialog = target.closest(".home-actions-dialog")
|
|
2869
|
-
if (dialog
|
|
2870
|
-
dialog
|
|
3073
|
+
if (dialog) {
|
|
3074
|
+
closeHomeActionsDialog(dialog)
|
|
2871
3075
|
}
|
|
2872
3076
|
return
|
|
2873
3077
|
}
|
|
2874
3078
|
if (e.target.classList.contains("home-actions-dialog")) {
|
|
2875
|
-
e.target
|
|
3079
|
+
closeHomeActionsDialog(e.target)
|
|
2876
3080
|
return
|
|
2877
3081
|
}
|
|
2878
3082
|
if (e.target.classList.contains("home-actions-tab")) {
|
package/test/shell-api.test.js
CHANGED
|
@@ -13,23 +13,23 @@ function createKernel () {
|
|
|
13
13
|
homedir: '/tmp/pinokio-home',
|
|
14
14
|
shell: {
|
|
15
15
|
start: async (params, options) => {
|
|
16
|
-
calls.push({ method: 'start', guard:
|
|
16
|
+
calls.push({ method: 'start', guard: options && options[CondaRuntimeGuard.SHELL_RUN_GUARD_OPTION] === true, params: structuredClone(params), options: structuredClone(options) })
|
|
17
17
|
return 'shell-id'
|
|
18
18
|
},
|
|
19
19
|
enter: async (params) => {
|
|
20
|
-
calls.push({ method: 'enter', guard:
|
|
20
|
+
calls.push({ method: 'enter', guard: false, params: structuredClone(params) })
|
|
21
21
|
return 'entered'
|
|
22
22
|
},
|
|
23
23
|
write: async (params) => {
|
|
24
|
-
calls.push({ method: 'write', guard:
|
|
24
|
+
calls.push({ method: 'write', guard: false, params: structuredClone(params) })
|
|
25
25
|
return 'written'
|
|
26
26
|
},
|
|
27
27
|
run: async (params, options) => {
|
|
28
|
-
calls.push({ method: 'run', guard:
|
|
28
|
+
calls.push({ method: 'run', guard: options && options[CondaRuntimeGuard.SHELL_RUN_GUARD_OPTION] === true, params: structuredClone(params), options: structuredClone(options) })
|
|
29
29
|
return { stdout: 'ok' }
|
|
30
30
|
},
|
|
31
31
|
kill: async (params) => {
|
|
32
|
-
calls.push({ method: 'kill', guard:
|
|
32
|
+
calls.push({ method: 'kill', guard: false, params: structuredClone(params) })
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -136,7 +136,8 @@ test('shell.run applies deterministic defaults and forwards execution options',
|
|
|
136
136
|
},
|
|
137
137
|
options: {
|
|
138
138
|
cwd,
|
|
139
|
-
group: path.join(cwd, 'script.js')
|
|
139
|
+
group: path.join(cwd, 'script.js'),
|
|
140
|
+
[CondaRuntimeGuard.SHELL_RUN_GUARD_OPTION]: true
|
|
140
141
|
}
|
|
141
142
|
}])
|
|
142
143
|
})
|