pinokiod 3.20.3 → 3.20.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.
@@ -730,6 +730,7 @@ class Api {
730
730
  uri: request.uri,
731
731
  path: request.path,
732
732
  git: this.parentGitURI(request.path),
733
+ cwd,
733
734
  origin: request.origin,
734
735
  body: script
735
736
  }
@@ -435,7 +435,7 @@ const get_raw = async (homedir) => {
435
435
  return current_env
436
436
  }
437
437
 
438
- const requirements = async (script, filepath, kernel) => {
438
+ const requirements = async (script, cwd, kernel) => {
439
439
  let pre_items = []
440
440
  let requires_instantiation = false
441
441
  if (script) {
@@ -446,7 +446,7 @@ const requirements = async (script, filepath, kernel) => {
446
446
  pre = script.env
447
447
  }
448
448
  if (pre) {
449
- let env = await get2(filepath, kernel)
449
+ let env = await get2(cwd, kernel)
450
450
  for(let item of pre) {
451
451
  let env_key
452
452
  if (item.env) {
@@ -59,14 +59,25 @@ class Proto {
59
59
  console.log({ projectType, startType })
60
60
 
61
61
  let cwd = req.cwd
62
- let name = req.name
62
+ let name = req.params.name
63
+ // let name = req.name
63
64
  let payload = {}
64
65
  payload.cwd = path.resolve(cwd, name)
65
66
  payload.input = req.params
66
67
 
68
+
69
+ await fs.promises.mkdir(payload.cwd)
70
+
71
+ let default_icon_path = path.resolve(__dirname, "../server/public/pinokio-black.png")
72
+ let icon_path = path.resolve(payload.cwd, "icon.png")
73
+ await fs.promises.cp(default_icon_path, icon_path)
74
+
67
75
  let mod_path = this.kernel.path("prototype/system", projectType, startType)
68
76
  let mod = await this.kernel.require(mod_path)
69
77
 
78
+ console.log({ mod_path, projectType, startType })
79
+ console.log("payload", payload)
80
+
70
81
  await mod(payload, ondata, this.kernel)
71
82
 
72
83
  // copy readme
package/kernel/shell.js CHANGED
@@ -114,7 +114,12 @@ class Shell {
114
114
  // if the shell is running from a script file, the params.$parent will include the path to the parent script
115
115
  // this means we need to apply app environment as well
116
116
  if (params.$parent) {
117
- let api_path = Util.api_path(params.$parent.path, this.kernel)
117
+ let api_path
118
+ if (params.$parent.cwd) {
119
+ api_path = Util.api_path(params.$parent.cwd, this.kernel)
120
+ } else {
121
+ api_path = Util.api_path(params.$parent.path, this.kernel)
122
+ }
118
123
 
119
124
  // initialize folders
120
125
  await Environment.init_folders(api_path)
@@ -352,7 +357,6 @@ class Shell {
352
357
  // return this.id
353
358
  }
354
359
  resize({ cols, rows }) {
355
- console.log("RESIZE", { cols, rows })
356
360
  this.ptyProcess.resize(cols, rows)
357
361
  this.vt.resize(cols, rows)
358
362
  }
@@ -384,7 +388,6 @@ class Shell {
384
388
  }
385
389
  }
386
390
  emit(message) {
387
- //console.log("emit", { message, input: this.input, pty: this.ptyProcess })
388
391
  if (this.input) {
389
392
  if (this.ptyProcess) {
390
393
  if (message.length > 1024) {
@@ -1017,7 +1020,6 @@ class Shell {
1017
1020
  async exec(params) {
1018
1021
  params = await this.activate(params)
1019
1022
  this.cmd = this.build(params)
1020
- console.log("build", this.cmd)
1021
1023
  let res = await new Promise((resolve, reject) => {
1022
1024
  this.resolve = resolve
1023
1025
  this.reject = reject
@@ -1104,7 +1106,7 @@ class Shell {
1104
1106
  }
1105
1107
  this.vt.dispose()
1106
1108
  this.queue.killAndDrain()
1107
- console.log("KILL PTY", this.id)
1109
+ // console.log("KILL PTY", this.id)
1108
1110
  if (this.ptyProcess) {
1109
1111
  if (cb) {
1110
1112
  kill(this.ptyProcess.pid, "SIGKILL", true)
package/kernel/shells.js CHANGED
@@ -85,6 +85,13 @@ class Shells {
85
85
  // iterate through all the envs
86
86
  params.env = this.kernel.bin.envs(params.env)
87
87
 
88
+ // set $parent for scripts stored globally but run locally (git, prototype, plugin, etc)
89
+ if (params.path && !params.$parent) {
90
+ params.$parent = {
91
+ path: params.path
92
+ }
93
+ }
94
+
88
95
  let exec_path = (params.path ? params.path : ".") // use the current path if not specified
89
96
  let cwd = (options && options.cwd ? options.cwd : this.kernel.homedir) // if cwd exists, use it. Otherwise the cwd is pinokio home folder (~/pinokio)
90
97
  params.path = this.kernel.api.resolvePath(cwd, exec_path)
@@ -339,7 +346,6 @@ class Shells {
339
346
  }
340
347
  */
341
348
  let session = this.get(params.id)
342
- console.log({ session })
343
349
  if (session) {
344
350
  session.resize(params.resize)
345
351
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "3.20.3",
3
+ "version": "3.20.5",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/server/index.js CHANGED
@@ -60,6 +60,8 @@ function normalize(str) {
60
60
 
61
61
  class Server {
62
62
  constructor(config) {
63
+ this.menu_hidden = {}
64
+ this.selected = {}
63
65
  this.tabs = {}
64
66
  this.agent = config.agent
65
67
  this.port = DEFAULT_PORT
@@ -579,7 +581,14 @@ class Server {
579
581
  this.running_dynamic(name, plugin.menu)
580
582
  plugin_menu = plugin.menu
581
583
  }
584
+
585
+
586
+ let menu_hidden = false
587
+ if (this.menu_hidden[name] && this.menu_hidden[name][type]) {
588
+ menu_hidden = true
589
+ }
582
590
  const result = {
591
+ minimized: menu_hidden,
583
592
  // repos,
584
593
  current_urls,
585
594
  path: this.kernel.path("api", name),
@@ -651,7 +660,6 @@ class Server {
651
660
  return shell_id
652
661
  }
653
662
  async render(req, res, pathComponents, meta) {
654
- console.log("######## RENDER", { pathComponents })
655
663
  let base_path = req.base || this.kernel.path("api")
656
664
  let full_filepath = path.resolve(base_path, ...pathComponents)
657
665
 
@@ -1049,13 +1057,17 @@ class Server {
1049
1057
  let { editorUrl, prevUrl } = this.getVariationUrls(req)
1050
1058
 
1051
1059
 
1052
- let env_requirements = await Environment.requirements(resolved, filepath, this.kernel)
1060
+ //let cwd = req.query.cwd ? req.query.cwd : path.dirname(filepath)
1061
+ let cwd = req.query.cwd ? req.query.cwd : filepath
1062
+ let env_requirements = await Environment.requirements(resolved, cwd, this.kernel)
1053
1063
  if (env_requirements.requires_instantiation) {
1054
- let p = Util.api_path(filepath, this.kernel)
1064
+ //let p = Util.api_path(filepath, this.kernel)
1065
+ let p = Util.api_path(cwd, this.kernel)
1055
1066
  let platform = os.platform()
1056
1067
  if (platform === "win32") {
1057
1068
  p = p.replace(/\\/g, '\\\\')
1058
1069
  }
1070
+ console.log({ p, cwd })
1059
1071
  res.render("required_env_editor", {
1060
1072
  portal: this.portal,
1061
1073
  agent: this.agent,
@@ -3029,8 +3041,9 @@ class Server {
3029
3041
  // }
3030
3042
  }))
3031
3043
 
3032
- this.app.get("/init/:name", ex(async (req, res) => {
3033
- console.log("Rnder init", req.params.name)
3044
+ // this.app.get("/init/:name", ex(async (req, res) => {
3045
+ // console.log("Rnder init", req.params.name)
3046
+ this.app.get("/init", ex(async (req, res) => {
3034
3047
  /*
3035
3048
  option 1: new vs. clone
3036
3049
  - new|clone
@@ -3060,7 +3073,8 @@ class Server {
3060
3073
  // await this.kernel.proto.init()
3061
3074
  res.render("init/index", {
3062
3075
  cwd: this.kernel.path("api"),
3063
- name: req.params.name,
3076
+ name: null,
3077
+ // name: req.params.name,
3064
3078
  portal: this.portal,
3065
3079
  // items,
3066
3080
  logo: this.logo,
@@ -3829,6 +3843,48 @@ class Server {
3829
3843
  let str = await fs.promises.readFile(req.query.logpath, "utf8")
3830
3844
  res.send(str)
3831
3845
  }))
3846
+ this.app.get("/state/:type/:name", ex(async (req,res) => {
3847
+ let selected = null
3848
+ try {
3849
+ selected = this.selected[req.params.name][req.params.type]
3850
+ } catch (e) {
3851
+ }
3852
+ res.json({
3853
+ selected,
3854
+ })
3855
+ }))
3856
+ this.app.post("/state", ex(async (req, res) => {
3857
+ console.log("POST /state", req.body)
3858
+ /*
3859
+ req.body := {
3860
+ name: <name>,
3861
+ type: "browse"|"run",
3862
+ method: "toggleMenu"|"select",
3863
+ params: {
3864
+ <url>,
3865
+ }
3866
+ }
3867
+ */
3868
+ if (req.body.method === "select") {
3869
+ if (!this.selected[req.body.name]) {
3870
+ this.selected[req.body.name] = {}
3871
+ }
3872
+ this.selected[req.body.name][req.body.type] = req.body.params.url
3873
+ } else if (req.body.method === "toggleMenu") {
3874
+ if (!this.menu_hidden[req.body.name]) {
3875
+ this.menu_hidden[req.body.name] = {}
3876
+ }
3877
+ if (this.menu_hidden[req.body.name][req.body.type]) {
3878
+ this.menu_hidden[req.body.name][req.body.type] = false
3879
+ } else {
3880
+ this.menu_hidden[req.body.name][req.body.type] = true
3881
+ }
3882
+ }
3883
+ console.log("select", req.body)
3884
+ res.json({
3885
+ success: true
3886
+ })
3887
+ }))
3832
3888
  this.app.post("/mkdir", ex(async (req, res) => {
3833
3889
  let folder = req.body.folder
3834
3890
  let folder_path = path.resolve(this.kernel.api.userdir, req.body.folder)
@@ -4194,6 +4250,7 @@ class Server {
4194
4250
  let fullpath = path.resolve(this.kernel.homedir, req.body.filepath, "ENVIRONMENT")
4195
4251
  let updated = req.body.vals
4196
4252
  let hosts = req.body.hosts
4253
+ console.log("Util.update_env", { fullpath, filepath: req.body.filepath, updated })
4197
4254
  await Util.update_env(fullpath, updated)
4198
4255
  // for all environment variables that have hosts, save the key as well
4199
4256
  // hosts := { env_key: host }
@@ -637,19 +637,22 @@ form.search > * {
637
637
  margin: 10px;
638
638
  */
639
639
  }
640
+ /*
640
641
  body.dark form.search {
641
642
  border-left: 10px solid rgba(255,255,255,0.1);
642
643
  }
644
+ */
643
645
  form.search {
646
+ /*
644
647
  border-left: 10px solid rgba(0,0,0,0.04);
645
- padding: 0px;
648
+ */
646
649
  /*
647
650
  background: #F5F4FA;
648
651
  */
649
652
  margin: 0;
650
653
  display: flex;
651
654
  flex-grow: 1;
652
- padding: 10px;
655
+ padding: 0 10px 20px;
653
656
  }
654
657
  .input-form {
655
658
  padding: 10px;
@@ -996,7 +999,7 @@ header {
996
999
  padding: 10px;
997
1000
  top: 0;
998
1001
  box-sizing: border-box;
999
- z-index: 100000;
1002
+ z-index: 1000;
1000
1003
  }
1001
1004
  #reinstall {
1002
1005
  padding: 10px 20px;
package/server/socket.js CHANGED
@@ -158,7 +158,6 @@ class Socket {
158
158
  paste: req.paste
159
159
  })
160
160
  } else if (req.resize && req.id) {
161
- console.log("RESIZE", req)
162
161
  this.parent.kernel.shell.resize({
163
162
  id: req.id,
164
163
  resize: req.resize
@@ -178,7 +178,7 @@ body.dark .header-item.btn {
178
178
  color: var(--dark-color);
179
179
  }
180
180
  .header-item.btn {
181
- padding: 6px 8px;
181
+ padding: 5px 8px;
182
182
  background: none !important;
183
183
  color: var(--light-color);
184
184
  }
@@ -210,7 +210,7 @@ body.dark #new-window {
210
210
  }
211
211
  */
212
212
  .app-info-card img {
213
- padding: 10px;
213
+ margin-right: 10px;
214
214
  }
215
215
  .app-info {
216
216
 
@@ -219,7 +219,6 @@ body.dark #new-window {
219
219
  */
220
220
  box-sizing: border-box;
221
221
  text-align: center;;
222
- font-weight: bold;
223
222
  align-items: center;
224
223
  /*
225
224
  background: rgba(0,0,0,0.04);
@@ -316,8 +315,32 @@ body.dark .app-info .mode-section .btn {
316
315
  body.dark .app-info-card > * {
317
316
  color: var(--dark-color);
318
317
  }
318
+ .app-info-container {
319
+ padding: 10px 0;
320
+ min-width: 0;
321
+ text-overflow: ellipsis;
322
+ }
319
323
  .app-info-title {
324
+ width: 100%;
325
+ font-weight: bold;
326
+ /*
320
327
  padding: 15px 0;
328
+ */
329
+ }
330
+ .app-info-description.collapsed {
331
+ display: -webkit-box;
332
+ -webkit-line-clamp: 3;
333
+ -webkit-box-orient: vertical;
334
+
335
+ display: box; /* For the future */
336
+ line-clamp: 3; /* For future spec */
337
+ box-orient: vertical;
338
+
339
+ overflow: hidden;
340
+ }
341
+ .app-info-description {
342
+ word-wrap: break-word;
343
+ width: 100%;
321
344
  }
322
345
  .footer {
323
346
  /*
@@ -457,15 +480,18 @@ body.dark .grid-btns .btn2 {
457
480
  margin-right: 10px;
458
481
  }
459
482
  .tab i {
460
- margin-right: 10px;
483
+ margin-right: 6px;
461
484
  font-size: 14px;
462
- width: 14px;
485
+ padding: 2px;
486
+ border-radius: 4px;
463
487
  }
464
488
  .menu-item-image {
465
- width: 16px !important;
466
- height: 16px !important;
467
- margin-right: 10px;
489
+ width: 18px !important;
490
+ height: 18px !important;
491
+ margin-right: 6px;
468
492
  background: white;
493
+ padding: 2px;
494
+ border-radius: 20px;
469
495
  }
470
496
  .temp-menu {
471
497
  /*
@@ -733,6 +759,28 @@ body.dark .top-menu .btn2.selected {
733
759
  background: black;
734
760
  color: white;
735
761
  }
762
+ body.minimized #collapse {
763
+ background: none;
764
+ }
765
+ body.dark #collapse {
766
+ background: rgba(255,255,255,0.07);
767
+ }
768
+ #collapse {
769
+ background: rgba(0,0,0,0.04);
770
+ }
771
+ body.dark .mode-selector .btn2.selected {
772
+ background: rgba(255,255,255,0.07);
773
+ }
774
+ .mode-selector .btn2.selected {
775
+ background: rgba(0,0,0,0.04);
776
+ }
777
+ .mode-selector {
778
+ display: flex;
779
+ }
780
+ .mode-selector .btn2 {
781
+ padding: 10px 0;
782
+ min-width: 40px;
783
+ }
736
784
 
737
785
  @media only screen and (max-width: 1000px) {
738
786
  .url-bar {
@@ -815,12 +863,13 @@ body.dark .top-menu .btn2.selected {
815
863
  <script src="/popper.min.js"></script>
816
864
  <script src="/tippy-bundle.umd.min.js"></script>
817
865
  </head>
818
- <body class='<%=theme%>' data-platform="<%=platform%>" data-agent="<%=agent%>">
866
+ <body class='<%=theme%> <%=minimized ? "minimized" : ""%>' data-platform="<%=platform%>" data-agent="<%=agent%>">
819
867
  <header class='navheader grabbable'>
820
868
  <h1>
821
869
  <a class='home' href="/">
822
870
  <img class='icon' src="/pinokio-black.png">
823
871
  </a>
872
+ <!--
824
873
  <div class='app-icon'>
825
874
  <% if (config.icon) { %>
826
875
  <img src="<%=config.icon%>"/>
@@ -828,9 +877,20 @@ body.dark .top-menu .btn2.selected {
828
877
  <i class="fa-regular fa-circle-dot"></i>
829
878
  <% } %>
830
879
  </div>
880
+ -->
831
881
  <button class='btn2' id='back'><div><i class="fa-solid fa-chevron-left"></i></div><div>Prev</div></button>
832
882
  <button class='btn2' id='forward'><div><i class="fa-solid fa-chevron-right"></i></div><div>Next</div></button>
833
883
  <button class='btn2' id='refresh-page'><div><i class="fa-solid fa-rotate-right"></i></div><div>Refresh</div></button>
884
+ <div class='mode-selector'>
885
+ <button id='collapse' class='btn2'><div><i class="fa-solid fa-bars"></i></div><div id='collapse-text'>menu</div></button>
886
+ <% if (type === "run") { %>
887
+ <a id='switch-dev' class='btn2' href="<%=home.endsWith("/") ? home : home + "/" %>dev"><div><i class="fa-solid fa-code"></i></div><div>dev</div></a>
888
+ <a class='btn2 selected'><div><i class="fa-solid fa-circle-play"></i></div><div>run</div></a>
889
+ <% } else { %>
890
+ <a id='switch-dev' class='btn2 selected'><div><i class="fa-solid fa-code"></i></div><div>dev</div></a>
891
+ <a class='btn2' href="."><div><i class="fa-solid fa-circle-play"></i></div><div>run</div></a>
892
+ <% } %>
893
+ </div>
834
894
  <div class='flexible filler'></div>
835
895
  <div class='url-bar'>
836
896
  <% if (current_urls.https) { %>
@@ -857,18 +917,6 @@ body.dark .top-menu .btn2.selected {
857
917
  </header>
858
918
  <div class='appcanvas'>
859
919
  <aside class='active'>
860
- <div class='header-top header-item header-menu'>
861
- <div class='top-menu'>
862
- <button id='collapse' class='btn2'><i class="fa-solid fa-chevron-up"></i> hide</button>
863
- <% if (type === "run") { %>
864
- <a id='switch-dev' class='btn2' href="<%=home.endsWith("/") ? home : home + "/" %>dev"><i class="fa-solid fa-code"></i> dev</a>
865
- <a class='btn2 selected'><i class="fa-solid fa-circle-play"></i> run</a>
866
- <% } else { %>
867
- <a id='switch-dev' class='btn2 selected'><i class="fa-solid fa-code"></i> dev</a>
868
- <a class='btn2' href="."><i class="fa-solid fa-circle-play"></i> run</a>
869
- <% } %>
870
- </div>
871
- </div>
872
920
  <div class='header-top header-item'>
873
921
  <div class='app-info'>
874
922
  <div class='app-info-card'>
@@ -877,7 +925,10 @@ body.dark .top-menu .btn2.selected {
877
925
  <% } else { %>
878
926
  <i class="fa-regular fa-circle-dot"></i>
879
927
  <% } %>
880
- <div class='app-info-title'><%=config.title%></div>
928
+ <div class='app-info-container'>
929
+ <div class='app-info-title'><%=config.title%></div>
930
+ <div class='app-info-description collapsed'><%=config.description%></div>
931
+ </div>
881
932
  </div>
882
933
  <div class='header-btns <%=type === 'run' ? 'hidden' : ''%>'>
883
934
  <div class='btn header-item frame-link revealer' id='edit-toggle' data-group='.edit-group'>
@@ -1066,11 +1117,20 @@ body.dark .top-menu .btn2.selected {
1066
1117
  let loaded = {}
1067
1118
  let cursorIndex = 0;
1068
1119
  let interacted = false
1069
- document.querySelector(".app-icon").addEventListener("click", (e) => {
1070
- document.body.classList.toggle("minimized")
1071
- })
1072
1120
  document.querySelector("#collapse").addEventListener("click", (e) => {
1073
1121
  document.body.classList.toggle("minimized")
1122
+ fetch("/state", {
1123
+ method: "POST",
1124
+ headers: {
1125
+ "Content-Type": "application/json"
1126
+ },
1127
+ body: JSON.stringify({
1128
+ name: "<%=name%>",
1129
+ type: "<%=type%>",
1130
+ method: "toggleMenu"
1131
+ })
1132
+ }).then((res) => {
1133
+ })
1074
1134
  })
1075
1135
  document.addEventListener("click", (e) => {
1076
1136
  interacted = true
@@ -1085,13 +1145,15 @@ body.dark .top-menu .btn2.selected {
1085
1145
  });
1086
1146
  <% } %>
1087
1147
  <% if (type === "run" && config.meta_required) { %>
1088
- tippy('#switch-dev', {
1089
- arrow: true,
1090
- showOnCreate: true,
1091
- theme: "pointer",
1092
- placement: "bottom-end",
1093
- content: "Switch to dev mode to make changes to the app"
1094
- });
1148
+ setTimeout(() => {
1149
+ tippy('#switch-dev', {
1150
+ arrow: true,
1151
+ showOnCreate: true,
1152
+ theme: "pointer",
1153
+ placement: "bottom-end",
1154
+ content: "Switch to dev mode to make changes to the app"
1155
+ });
1156
+ }, 500)
1095
1157
  <% } %>
1096
1158
  const n = new N()
1097
1159
  const getTarget = (href) => {
@@ -1177,7 +1239,7 @@ body.dark .top-menu .btn2.selected {
1177
1239
  // */
1178
1240
  // }
1179
1241
  }
1180
- const renderSelection = (e, force) => {
1242
+ const renderSelection = async (e, force) => {
1181
1243
  let selection = null
1182
1244
  <% if (type === "run" && env.PINOKIO_SCRIPT_DEFAULT && env.PINOKIO_SCRIPT_DEFAULT.toString().toLowerCase() === "true") { %>
1183
1245
  selection = document.querySelector("[data-default]")
@@ -1277,6 +1339,26 @@ body.dark .top-menu .btn2.selected {
1277
1339
  })
1278
1340
  target.classList.add("selected")
1279
1341
 
1342
+ // save target.href
1343
+ <% if (type !== "run") { %>
1344
+ let _url = new URL(target.href)
1345
+ fetch("/state", {
1346
+ method: "POST",
1347
+ headers: {
1348
+ "Content-Type": "application/json"
1349
+ },
1350
+ body: JSON.stringify({
1351
+ name: "<%=name%>",
1352
+ type: "<%=type%>",
1353
+ method: "select",
1354
+ params: {
1355
+ url: _url.pathname + _url.search + _url.hash,
1356
+ }
1357
+ })
1358
+ }).then((res) => {
1359
+ })
1360
+ <% } %>
1361
+
1280
1362
  // hide all frames
1281
1363
  document.querySelectorAll("iframe").forEach((el) => {
1282
1364
  el.classList.add("hidden")
@@ -1681,6 +1763,11 @@ body.dark .top-menu .btn2.selected {
1681
1763
  }
1682
1764
  */
1683
1765
  })
1766
+ document.querySelector(".app-info-description").addEventListener("click", (e) => {
1767
+ e.preventDefault()
1768
+ e.stopPropagation()
1769
+ e.target.classList.toggle("collapsed")
1770
+ })
1684
1771
  document.querySelector("#delete").addEventListener("click", async (e) => {
1685
1772
  e.preventDefault()
1686
1773
  e.stopPropagation()
@@ -1953,14 +2040,7 @@ body.dark .top-menu .btn2.selected {
1953
2040
  <% } %>
1954
2041
  return
1955
2042
  } else {
1956
- //location.hash = target.target
1957
-
1958
2043
 
1959
- // let id = getTarget(target.getAttribute("href"))
1960
- // console.log("ID", id, target.href)
1961
- // location.hash = id
1962
-
1963
- //location.hash = target.getAttribute("href")
1964
2044
 
1965
2045
  if (target.closest(".h")) {
1966
2046
  if (target.target) {
@@ -2097,7 +2177,9 @@ body.dark .top-menu .btn2.selected {
2097
2177
  // render the selected frame only if not silent
2098
2178
  if (silent) {
2099
2179
  } else {
2180
+ <% if (type === 'run') { %>
2100
2181
  renderSelection()
2182
+ <% } %>
2101
2183
  }
2102
2184
  }
2103
2185
  if (document.querySelector("#genlog")) {
@@ -2204,6 +2286,14 @@ body.dark .top-menu .btn2.selected {
2204
2286
  });
2205
2287
  refresh_du()
2206
2288
  refresh_du("logs")
2289
+ fetch("/state/<%=type%>/<%=name%>").then((res) => {
2290
+ return res.json()
2291
+ }).then((res) => {
2292
+ if (res.selected) {
2293
+ let selection = document.querySelector(`[href='${res.selected}']`)
2294
+ selection.click()
2295
+ }
2296
+ })
2207
2297
  <% if (type !== 'run') { %>
2208
2298
  fetch("<%=repos%>").then((res) => {
2209
2299
  return res.text()
@@ -660,8 +660,11 @@ document.querySelector(".changes").addEventListener("click", (e) => {
660
660
  }
661
661
  }
662
662
  if (href) {
663
- document.querySelector("#term").classList.remove("hidden")
664
- window.open(href, "terminal")
663
+ let c = confirm("are you sure? this will reset the file to the previous version.")
664
+ if (c) {
665
+ document.querySelector("#term").classList.remove("hidden")
666
+ window.open(href, "terminal")
667
+ }
665
668
  }
666
669
  })
667
670
  document.querySelector("aside").addEventListener("click", (e) => {
@@ -689,7 +692,6 @@ document.querySelector("aside").addEventListener("click", (e) => {
689
692
  let href = target.getAttribute("data-href")
690
693
 
691
694
  let ref = document.querySelector("aside").getAttribute("data-ref")
692
- debugger
693
695
 
694
696
  fetch(href).then((res) => {
695
697
  return res.json()
@@ -730,8 +732,6 @@ document.querySelector("aside").addEventListener("click", (e) => {
730
732
  }
731
733
  })
732
734
  window.addEventListener('message', (event) => {
733
- console.log(">> EVENT", event)
734
- debugger
735
735
  if (event.data) {
736
736
  if (event.data.callback) {
737
737
  if (event.data.callback.startsWith("$")) {
@@ -155,6 +155,11 @@ body.dark .context-menu-wrapper {
155
155
  text-align: left;
156
156
  color: black;
157
157
  }
158
+ .app-btns .btn {
159
+ border-radius: 20px;
160
+ width: 70px;
161
+ text-align: center;
162
+ }
158
163
  body.dark .context-menu .btn {
159
164
  color: white;
160
165
  }
@@ -304,14 +309,20 @@ body.dark .open-menu, body.dark .browse {
304
309
  <% if (ishome) { %>
305
310
  <form class='search'>
306
311
  <div class='app-btns'>
307
- <a class='btn create-new' id='create-new-folder'><i class="fa-solid fa-plus"></i> New</a>
312
+ <a class='btn create-new' href="/init"><i class="fa-solid fa-plus"></i> Build</a>
313
+ <!--
314
+ <a class='btn create-new' id='create-new-folder'><i class="fa-solid fa-plus"></i> Create</a>
315
+ -->
316
+
317
+
318
+
308
319
  <!--
309
320
  <a class='btn create-new' href="/create"><i class="fa-solid fa-folder-plus"></i> Create</a>
310
321
  -->
311
322
  <a class='btn' id='explore' href="/?mode=explore"><i class="fa-solid fa-magnifying-glass"></i> Discover</a>
312
323
  </div>
313
324
  <% if (display.includes("form")) { %>
314
- <input type='search' class="flexible" placeholder='Filter downloaded apps'>
325
+ <input type='search' class="flexible" placeholder='Filter apps'>
315
326
  <% } else { %>
316
327
  <% } %>
317
328
  </form>