pinokiod 3.8.0 → 3.8.5

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 (51) hide show
  1. package/kernel/api/fs/index.js +6 -4
  2. package/kernel/api/index.js +102 -31
  3. package/kernel/bin/cuda.js +7 -0
  4. package/kernel/bin/index.js +143 -4
  5. package/kernel/bin/node.js +9 -0
  6. package/kernel/index.js +32 -1
  7. package/kernel/info.js +1 -0
  8. package/kernel/prototype.js +47 -0
  9. package/kernel/shell.js +110 -54
  10. package/kernel/shells.js +16 -7
  11. package/kernel/store.js +58 -0
  12. package/kernel/util.js +106 -35
  13. package/package.json +1 -1
  14. package/script/index.js +12 -0
  15. package/server/index.js +466 -250
  16. package/server/public/SpaceMono-Bold.ttf +0 -0
  17. package/server/public/SpaceMono-BoldItalic.ttf +0 -0
  18. package/server/public/SpaceMono-Italic.ttf +0 -0
  19. package/server/public/SpaceMono-Regular.ttf +0 -0
  20. package/server/public/filepond-plugin-file-validate-type.min.js +9 -0
  21. package/server/public/filepond-plugin-image-crop.min.js +9 -0
  22. package/server/public/filepond-plugin-image-edit.min.css +8 -0
  23. package/server/public/filepond-plugin-image-edit.min.js +9 -0
  24. package/server/public/filepond-plugin-image-exif-orientation.min.js +9 -0
  25. package/server/public/filepond-plugin-image-preview.min.css +8 -0
  26. package/server/public/filepond-plugin-image-preview.min.js +9 -0
  27. package/server/public/filepond-plugin-image-resize.min.js +9 -0
  28. package/server/public/filepond-plugin-image-transform.min.js +9 -0
  29. package/server/public/filepond.min.css +8 -0
  30. package/server/public/filepond.min.js +9 -0
  31. package/server/public/fscreator.js +160 -0
  32. package/server/public/fseditor.js +189 -0
  33. package/server/public/github.png +0 -0
  34. package/server/public/opener.js +3 -1
  35. package/server/public/pinokio-black.png +0 -0
  36. package/server/public/pinokio-black2.png +0 -0
  37. package/server/public/style.css +131 -9
  38. package/server/socket.js +123 -37
  39. package/server/views/app.ejs +184 -11
  40. package/server/views/editor.ejs +12 -2
  41. package/server/views/explore.ejs +4 -3
  42. package/server/views/help.ejs +4 -2
  43. package/server/views/index.ejs +218 -80
  44. package/server/views/install.ejs +1 -1
  45. package/server/views/local_editor.ejs +282 -0
  46. package/server/views/minterm.ejs +687 -0
  47. package/server/views/partials/menu.ejs +7 -1
  48. package/server/views/prototypes.ejs +463 -0
  49. package/server/views/proxy.ejs +10 -4
  50. package/server/views/settings.ejs +4 -3
  51. package/server/views/terminal.ejs +99 -15
@@ -10,6 +10,9 @@
10
10
  <link href="/css/brands.min.css" rel="stylesheet">
11
11
  <link href="/markdown.css" rel="stylesheet"/>
12
12
  <link href="/noty.css" rel="stylesheet"/>
13
+ <link href="/filepond.min.css" rel="stylesheet" />
14
+ <link href="/filepond-plugin-image-preview.min.css" rel="stylesheet" />
15
+ <link href="/filepond-plugin-image-edit.min.css" rel="stylesheet" />
13
16
  <link href="/style.css" rel="stylesheet"/>
14
17
  <% if (agent === "electron") { %>
15
18
  <link href="/electron.css" rel="stylesheet"/>
@@ -125,6 +128,27 @@ body.dark .browser-options-row {
125
128
  border-bottom: 1px solid rgba(255,255,255,0.05);
126
129
  }
127
130
  */
131
+ .context-menu {
132
+ /*
133
+ max-height: 10000px;
134
+ overflow: hidden;
135
+ transition: max-height 1s ease-in-out;
136
+ */
137
+ padding: 10px 0;
138
+ }
139
+ .context-menu.collapsed {
140
+ /*
141
+ max-height: 0;
142
+ */
143
+ display: none;
144
+ }
145
+ .open-menu.selected {
146
+ border: none !important;
147
+ /*
148
+ background: none !important;
149
+ */
150
+ opacity: 0.5;
151
+ }
128
152
  @media only screen and (max-width: 480px) {
129
153
  .btn2 {
130
154
  padding: 5px;
@@ -152,6 +176,16 @@ body.dark .browser-options-row {
152
176
  <script src="/nav.js"></script>
153
177
  <script src="/fuse.js"></script>
154
178
  <script src="/report.js"></script>
179
+ <script src="/filepond-plugin-file-validate-type.min.js"></script>
180
+ <script src="/filepond-plugin-image-exif-orientation.min.js"></script>
181
+ <script src="/filepond-plugin-image-preview.min.js"></script>
182
+ <script src="/filepond-plugin-image-edit.min.js"></script>
183
+ <script src="/filepond-plugin-image-crop.min.js"></script>
184
+ <script src="/filepond-plugin-image-resize.min.js"></script>
185
+ <script src="/filepond-plugin-image-transform.min.js"></script>
186
+ <script src="/filepond.min.js"></script>
187
+ <script src="/fscreator.js"></script>
188
+ <script src="/fseditor.js"></script>
155
189
  </head>
156
190
  <body class='<%=theme%>'>
157
191
  <% if (error) { %>
@@ -168,8 +202,13 @@ body.dark .browser-options-row {
168
202
  <h1>
169
203
  <% if (ishome) { %>
170
204
  <a class='home' href="/"><i class="fa-solid fa-house"></i></a>
171
- <button class='btn2' id='back'><i class="fa-solid fa-chevron-left"></i></button>
172
- <button class='btn2' id='forward'><i class="fa-solid fa-chevron-right"></i></button>
205
+ <button class='btn2' id='back'><div><i class="fa-solid fa-chevron-left"></i></div><div>Prev</div></button>
206
+ <button class='btn2' id='forward'><div><i class="fa-solid fa-chevron-right"></i></div><div>Next</div></button>
207
+ <a href="/new" class='btn2'><div><i class='fa-solid fa-folder-plus'></i></div><div>Create</div></a>
208
+ <a class='btn2' id='explore'><div><i class="fa-solid fa-globe"></i></div><div>Discover</div></a>
209
+ <!--
210
+ <button id='newfolder' class='btn2'><div><i class="fa-solid fa-folder-plus"></i></div><div>New Folder</div></button>
211
+ -->
173
212
  <% } %>
174
213
  <% paths.forEach((path) => { %>
175
214
  <% if (path.action) { %>
@@ -186,7 +225,10 @@ body.dark .browser-options-row {
186
225
  </form>
187
226
  <% if (ishome) { %>
188
227
  <div class='nav-btns'>
228
+ <!--
189
229
  <a class='btn2' id='explore'><div><i class="fa-solid fa-globe"></i></div><div>Discover</div></a>
230
+ -->
231
+ <a href="/proxy" class='btn2'><div><i class="fa-solid fa-wifi"></i></div><div>Wifi Sharing</div></a>
190
232
  <a class='btn2' href="https://portal.pinokio.computer/" target="_blank"><div><i class="fa-solid fa-question"></i></div><div>Help</div></a>
191
233
  <% if (agent === "electron") { %>
192
234
  <a class='btn2' data-filepath="<%=filepath%>"><div><i class="fa-regular fa-folder-open"></i></div><div>Files</div></a>
@@ -194,6 +236,11 @@ body.dark .browser-options-row {
194
236
  <button class='btn2' id='genlog'><div><i class="fa-solid fa-laptop-code"></i></div><div>Debug</div></button>
195
237
  <a id='downloadlogs' download class='hidden btn2' href="/pinokio/logs.zip"><div><i class="fa-solid fa-download"></i></div><div>Download logs</div></a>
196
238
  <a class='btn2' href="/?mode=settings"><div><i class="fa-solid fa-gear"></i></div><div>Settings</div></a>
239
+ <% if (agent === "electron") { %>
240
+ <a href="/" target="_blank" class='btn2' features="browser"><div><i class="fa-solid fa-square-up-right"></i></div><div>Open</div></a>
241
+ <% } else { %>
242
+ <a href="/" target="_blank" class='btn2'><div><i class="fa-solid fa-square-up-right"></i></div><div>Open</div></a>
243
+ <% } %>
197
244
  <button id='new-window' title='open a new window' class='btn2'><div><i class="fa-solid fa-plus"></i></div><div>Window</div></button>
198
245
  </div>
199
246
  <% } %>
@@ -203,7 +250,7 @@ body.dark .browser-options-row {
203
250
  <button class='btn' id='open-fs' data-filepath="<%=filepath%>"><i class="fa-solid fa-eye"></i> View Folder</button>
204
251
  </div>
205
252
  <% } %>
206
- <% if (display.includes("dependencies")) { %>
253
+ <% if (display.includes("dependencies") && config) { %>
207
254
  <div class='dependencies'>
208
255
  <h2>Prerequisites</h2>
209
256
  <div class='item'>Download and install the following dependencies first</div>
@@ -225,6 +272,7 @@ body.dark .browser-options-row {
225
272
  <% if (ishome) { %>
226
273
  <% if (running.length === 0 && notRunning.length === 0) { %>
227
274
  <% } else { %>
275
+ <% if (false) { %>
228
276
  <div class='browser-options'>
229
277
  <% if (agent === "electron") { %>
230
278
  <div class='browser-options-row'>
@@ -246,32 +294,6 @@ body.dark .browser-options-row {
246
294
  <div>Serve Pinokio, installed apps, and even external apps (example: Ollama) to any device on the same network.</div>
247
295
  </div>
248
296
  </div>
249
- <!--
250
- <div class='browser-options-row'>
251
- <a href="/proxy" class='flexible'>
252
- <h3><i class="fa-solid fa-wifi"></i> Local Share</h3>
253
- <div>Access Pinokio, Ollama, and other 3rd party apps from any device on the same network. By default it's off.</div>
254
- </a>
255
- <% if (false) { %>
256
- <% if (proxy) { %>
257
- <a id='wifi-stop' data-proxy="<%=proxy.proxy%>" class='btn'><div><i class="fa-solid fa-stop"></i> Stop</div></a>
258
- <div class='flexible'>
259
- <h3><i class="fa-solid fa-wifi"></i> Local Share</h3>
260
- <div>Access Pinokio from any device on the same network. By default it's off.</div>
261
- <span class='badge'><i class="fa-solid fa-circle-notch fa-spin"></i> Running at <a href="<%=proxy.proxy%>" target="_blank" features="browser"><%=proxy.proxy%></a></span>
262
- <a id='wifi-qr' class='badge'><i class="fa-solid fa-qrcode"></i> Scan QR Code</a>
263
- </div>
264
- <% } else { %>
265
- <a id='wifi' class='btn'><div><i class="fa-solid fa-play"></i> Start</div></a>
266
- <a id='wifi-starting' class='btn disabled hidden'><div><i class="fa-solid fa-circle-notch fa-spin"></i> Starting</div></a>
267
- <div class='flexible'>
268
- <h3><i class="fa-solid fa-wifi"></i> Local Share</h3>
269
- <div>Access Pinokio from any device on the same network. By default it's off.</div>
270
- </div>
271
- <% } %>
272
- <% } %>
273
- </div>
274
- -->
275
297
  <div class='browser-options-row hidden'>
276
298
  <% if (cloudflare_pub) { %>
277
299
  <a id='cloudflare-stop' class='btn'><div><i class="fa-solid fa-stop"></i> Stop</div></a>
@@ -291,49 +313,43 @@ body.dark .browser-options-row {
291
313
  <% } %>
292
314
  </div>
293
315
  </div>
294
- <% } %>
295
- <!--
296
- <div class='type-tabs'>
297
- <% if (mode === "task") { %>
298
- <a class='type-tab' href="/"><img src='/pinokio-<%=theme=='dark' ? 'white' : 'black'%>.png'> Apps</a>
299
- <a class='type-tab selected' href="/?mode=task"> <img src='/<%=theme=='dark' ? 'term-dark.png' : 'term-white.png'%>'> Tasks</a>
300
- <% } else { %>
301
- <a class='type-tab selected' href="/"><img src='/pinokio-<%=theme=='dark' ? 'white' : 'black'%>.png'> Apps</a>
302
- <a class='type-tab' href="/?mode=task"> <img src='/<%=theme=='dark' ? 'term-dark.png' : 'term-white.png'%>'> Tasks</a>
303
316
  <% } %>
304
- </div>
305
- -->
317
+ <% } %>
306
318
  <% if (running.length > 0) { %>
307
319
  <div class='running-apps'>
320
+ <!--
308
321
  <div class='header-label'>Running</div>
322
+ -->
309
323
  <% running.forEach((item) => { %>
310
- <a href="<%=item.browser_url%>" data-description="<%=item.description%>" data-index="<%=item.index%>" data-name="<%=item.name%>" data-uri="<%=item.uri%>" class='line align-top'>
324
+ <a href="<%=item.browser_url%>" data-description="<%=item.description%>" data-index="<%=item.index%>" data-name="<%=item.name%>" data-title="<%=item.name%>" data-uri="<%=item.uri%>" data-icon="<%=item.icon%>" data-path="<%=item.path%>" data-iconpath="<%=item.iconpath ? item.iconpath : ''%>" class='line align-top'>
311
325
  <h3>
312
- <% if (item.icon) { %>
313
- <img src="<%=item.icon%>">
314
- <% } else { %>
315
- <% if (theme === 'dark') { %>
316
- <img src="/pinokio-white.png">
326
+ <div class='item-icon'>
327
+ <% if (item.icon) { %>
328
+ <img src="<%=item.icon%>">
317
329
  <% } else { %>
318
- <img src="/pinokio-black.png">
330
+ <% if (theme === 'dark') { %>
331
+ <img src="/pinokio-white.png">
332
+ <% } else { %>
333
+ <img src="/pinokio-black.png">
334
+ <% } %>
319
335
  <% } %>
320
- <!--
321
- <div class='avatar'>
322
- <i class="fa-regular fa-circle-dot"></i>
323
- </div>
324
- -->
325
- <% } %>
336
+ </div>
326
337
  <div class='col'>
327
338
  <div class='uri'><i class="fa-regular fa-folder"></i><%=item.url%></div>
328
339
  <div class='title'><%=item.name%></div>
329
340
  <div class='description'><%=item.description%></div>
330
341
  <div>
331
- <button class='btn browse' data-src="<%=item.browser_url%>/browse">
332
- <i class='fa-regular fa-folder-open'></i>
333
- </button>
334
- <button class='btn del' data-src="<%=item.url%>">
335
- <i class="fa-solid fa-trash-can"></i>
342
+ <button class='btn open-menu'>
343
+ <i class="fa-solid fa-bars"></i> Menu
336
344
  </button>
345
+ <div class='context-menu collapsed'>
346
+ <button class='btn browse' data-src="<%=item.browser_url%>/browse">
347
+ <i class='fa-regular fa-folder-open'></i> View
348
+ </button>
349
+ <button class='btn copy-menu' data-src="<%=item.browser_url%>/browse">
350
+ <i class='fa-solid fa-copy'></i> Copy
351
+ </button>
352
+ </div>
337
353
  <% if (item.running_scripts) { %>
338
354
  <% item.running_scripts.forEach((s) => { %>
339
355
  <button class='btn shutdown' data-src="<%=s.path%>">
@@ -366,34 +382,47 @@ body.dark .browser-options-row {
366
382
  <% } %>
367
383
  <% if (notRunning.length > 0) { %>
368
384
  <div class='not-running-apps'>
385
+ <!--
369
386
  <div class='header-label'>Not Running</div>
387
+ -->
370
388
  <% notRunning.forEach((item) => { %>
371
- <a href="<%=item.browser_url%>" data-description="<%=item.description%>" data-index="<%=item.index%>" data-name="<%=item.name%>" data-uri="<%=item.uri%>" class='line align-top'>
389
+ <a href="<%=item.browser_url%>" data-description="<%=item.description%>" data-index="<%=item.index%>" data-name="<%=item.name%>" data-title="<%=item.name%>" data-uri="<%=item.uri%>" data-icon="<%=item.icon%>" data-path="<%=item.path%>" data-iconpath="<%=item.iconpath ? item.iconpath : ''%>" class='line align-top'>
372
390
  <h3>
373
- <% if (item.icon) { %>
374
- <img src="<%=item.icon%>">
375
- <% } else { %>
376
- <!--
377
- <div class='avatar'>
378
- <i class="fa-regular fa-circle-dot"></i>
379
- </div>
380
- -->
381
- <% if (theme === 'dark') { %>
382
- <img src="/pinokio-white.png">
391
+ <div class='item-icon'>
392
+ <% if (item.icon) { %>
393
+ <img src="<%=item.icon%>">
383
394
  <% } else { %>
384
- <img src="/pinokio-black.png">
395
+ <% if (theme === 'dark') { %>
396
+ <img src="/pinokio-white.png">
397
+ <% } else { %>
398
+ <img src="/pinokio-black.png">
399
+ <% } %>
385
400
  <% } %>
386
- <% } %>
401
+ </div>
387
402
  <div class='col'>
388
403
  <div class='uri'><i class="fa-regular fa-folder"></i><%=item.url%></div>
389
404
  <div class='title'><%=item.name%></div>
390
405
  <div class='description'><%=item.description%></div>
391
- <button class='btn browse' data-src="<%=item.browser_url%>/browse">
392
- <i class='fa-regular fa-folder-open'></i>
393
- </button>
394
- <button class='btn del' data-src="<%=item.url%>">
395
- <i class="fa-solid fa-trash-can"></i>
406
+ <button class='btn open-menu'>
407
+ <i class="fa-solid fa-bars"></i> Menu
396
408
  </button>
409
+ <div class='context-menu collapsed'>
410
+ <button class='btn browse' data-src="<%=item.browser_url%>/browse">
411
+ <i class='fa-regular fa-folder-open'></i> View
412
+ </button>
413
+ <button class='btn copy-menu' data-src="<%=item.browser_url%>/browse">
414
+ <i class='fa-solid fa-copy'></i> Copy
415
+ </button>
416
+ <button class='btn move-menu' data-src="<%=item.browser_url%>/browse">
417
+ <i class="fa-solid fa-pencil"></i> Move
418
+ </button>
419
+ <button class='btn edit-menu' data-src="<%=item.browser_url%>/browse">
420
+ <i class='fa-solid fa-pen-to-square'></i> Edit
421
+ </button>
422
+ <button class='btn del' data-src="<%=item.url%>">
423
+ <i class="fa-solid fa-trash-can"></i> Delete
424
+ </button>
425
+ </div>
397
426
  <% if (item.shortcuts && item.shortcuts.length > 0) { %>
398
427
  <div class='btns'>
399
428
  <% item.shortcuts.forEach((btn) => { %>
@@ -825,14 +854,114 @@ document.addEventListener("click", async (e) => {
825
854
  })
826
855
  setTimeout(() => {
827
856
  location.href = location.href
828
- }, 1000)
857
+ }, 500)
858
+ }
859
+ })
860
+
861
+ return
862
+ }
863
+ if (e.target.classList.contains("open-menu")) {
864
+ target = e.target
865
+ } else {
866
+ target = e.target.closest(".open-menu")
867
+ }
868
+ if (target) {
869
+ e.preventDefault()
870
+ e.stopPropagation()
871
+ let contextMenu = target.closest(".col").querySelector(".context-menu").classList.toggle("collapsed")
872
+ target.classList.toggle("selected")
873
+ return
874
+ }
875
+
876
+ if (e.target.classList.contains("move-menu")) {
877
+ target = e.target
878
+ } else {
879
+ target = e.target.closest(".move-menu")
880
+ }
881
+ if (target) {
882
+ e.preventDefault()
883
+ e.stopPropagation()
884
+ let line = target.closest(".line")
885
+ let title = line.getAttribute("data-title")
886
+ let icon = line.getAttribute("data-icon")
887
+ let iconpath = line.getAttribute("data-iconpath")
888
+ let path = line.getAttribute("data-path")
889
+ let description = line.getAttribute("data-description")
890
+ await FSEditor({
891
+ title,
892
+ description,
893
+ old_path: path,
894
+ icon,
895
+ iconpath,
896
+ move: true,
897
+ edit: true,
898
+ redirect: (new_path) => {
899
+ return location.href
900
+ }
901
+ })
902
+ return
903
+ }
904
+
905
+ if (e.target.classList.contains("copy-menu")) {
906
+ target = e.target
907
+ } else {
908
+ target = e.target.closest(".copy-menu")
909
+ }
910
+ if (target) {
911
+ e.preventDefault()
912
+ e.stopPropagation()
913
+ let line = target.closest(".line")
914
+ let title = line.getAttribute("data-title")
915
+ let icon = line.getAttribute("data-icon")
916
+ let iconpath = line.getAttribute("data-iconpath")
917
+ let path = line.getAttribute("data-path")
918
+ let description = line.getAttribute("data-description")
919
+ await FSEditor({
920
+ title,
921
+ description,
922
+ old_path: path,
923
+ icon,
924
+ iconpath,
925
+ copy: true,
926
+ edit: true,
927
+ redirect: (new_path) => {
928
+ return location.href
829
929
  }
830
930
  })
931
+ return
932
+ }
831
933
 
934
+ if (e.target.classList.contains("edit-menu")) {
935
+ target = e.target
936
+ } else {
937
+ target = e.target.closest(".edit-menu")
938
+ }
939
+ if (target) {
940
+ e.preventDefault()
941
+ e.stopPropagation()
942
+ let line = target.closest(".line")
943
+ let title = line.getAttribute("data-title")
944
+ let icon = line.getAttribute("data-icon")
945
+ let iconpath = line.getAttribute("data-iconpath")
946
+ let path = line.getAttribute("data-path")
947
+ let description = line.getAttribute("data-description")
948
+ await FSEditor({
949
+ title,
950
+ description,
951
+ old_path: path,
952
+ icon,
953
+ iconpath,
954
+ edit: true,
955
+ redirect: (new_path) => {
956
+ return location.href
957
+ }
958
+ })
832
959
  return
833
960
  }
834
961
 
835
962
 
963
+
964
+
836
965
  if (e.target.classList.contains("browse")) {
837
966
  target = e.target
838
967
  } else {
@@ -898,9 +1027,18 @@ document.addEventListener("click", async (e) => {
898
1027
 
899
1028
  if (document.querySelector(".container")) {
900
1029
  document.querySelector(".container").addEventListener("click", async (e) => {
901
- let el = e.target.closest(".menu-btn")
902
- if (!el) {
903
- if (el.classList.contains("menu-btn")) {
1030
+ //let el = e.target.closest(".menu-btn")
1031
+ //if (!el) {
1032
+ // if (el.classList.contains("menu-btn")) {
1033
+ // el = e.target
1034
+ // }
1035
+ //}
1036
+
1037
+ let el
1038
+ if (e.target.classList.contains("menu-btn")) {
1039
+ el = e.target
1040
+ } else {
1041
+ if (e.target.closest(".menu-btn")) {
904
1042
  el = e.target
905
1043
  }
906
1044
  }
@@ -128,7 +128,7 @@ body {
128
128
  </head>
129
129
  <body class='<%=theme%>'>
130
130
  <header class='grabbable'></header>
131
- <div id='status-screen'></div>
131
+ <div id='status-screen'><b><i class="fas fa-circle-notch fa-spin"></i></div>
132
132
  <div class='terminal-container'>
133
133
  <div id='terminal'></div>
134
134
  </div>