pinokiod 3.19.79 → 3.19.80

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/bin/cli.js CHANGED
@@ -9,36 +9,31 @@ class CLI {
9
9
  }, ondata)
10
10
  }
11
11
  async installed(req, ondata) {
12
- console.log("Check CLI installed")
13
-
14
12
  let exists
15
- console.log("platform", this.kernel.platform)
16
13
  if (this.kernel.platform === "win32") {
17
14
  exists = await Util.exists(this.kernel.path("bin/npm/pterm"))
18
- console.log("Exists", exists)
19
15
  } else {
20
16
  exists = await Util.exists(this.kernel.path("bin/npm/bin/pterm"))
21
- console.log("Exists", exists)
22
17
  }
23
-
24
18
  if (exists) {
25
19
  let p = this.kernel.which("pterm")
26
20
  if (p) {
27
21
  let res = await this.kernel.exec({
28
22
  message: "pterm version terminal"
29
23
  }, ondata)
30
- let v = res.stdout.replace("pterm@", "")
31
- let coerced = semver.coerce(v)
32
- console.log({ v, coerced })
33
- if (semver.satisfies(coerced, this.version)) {
34
- console.log("Installed")
35
- return true
24
+ let e = /pterm@([0-9.]+)/.exec(res.stdout)
25
+ if (e && e.length > 0) {
26
+ let v = e[1]
27
+ let coerced = semver.coerce(v)
28
+ if (semver.satisfies(coerced, this.version)) {
29
+ return true
30
+ } else {
31
+ return false
32
+ }
36
33
  } else {
37
- console.log("Not Installed")
38
34
  return false
39
35
  }
40
36
  } else {
41
- console.log("FALSE")
42
37
  return false
43
38
  }
44
39
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "3.19.79",
3
+ "version": "3.19.80",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/server/index.js CHANGED
@@ -367,7 +367,7 @@ class Server {
367
367
 
368
368
  async chrome(req, res, type) {
369
369
  let d = Date.now()
370
- console.time("1 chrome " + d)
370
+ // console.time("1 chrome " + d)
371
371
  let { requirements, install_required, requirements_pending, error } = await this.kernel.bin.check({
372
372
  bin: this.kernel.bin.preset("dev"),
373
373
  })
@@ -375,7 +375,7 @@ class Server {
375
375
  res.redirect(`/setup/dev?callback=${req.originalUrl}`)
376
376
  return
377
377
  }
378
- console.timeEnd("1 chrome " + d)
378
+ // console.timeEnd("1 chrome " + d)
379
379
 
380
380
  let name = req.params.name
381
381
  let config = await this.kernel.api.meta(name)
@@ -490,22 +490,22 @@ class Server {
490
490
  // }
491
491
  // }
492
492
 
493
- console.time("2 chrome " + d)
493
+ // console.time("2 chrome " + d)
494
494
  await this.init_env("api/" + name)
495
- console.timeEnd("2 chrome " + d)
495
+ // console.timeEnd("2 chrome " + d)
496
496
 
497
- console.time("3 chrome " + d)
497
+ // console.time("3 chrome " + d)
498
498
  let mode = "run"
499
499
  if (req.query && req.query.mode) {
500
500
  mode = req.query.mode
501
501
  }
502
502
  const env = await this.kernel.env("api/" + name)
503
- console.timeEnd("3 chrome " + d)
503
+ // console.timeEnd("3 chrome " + d)
504
504
 
505
505
  // profile + feed
506
506
  const repositoryPath = path.resolve(this.kernel.api.userdir, name)
507
507
 
508
- console.time("4 chrome " + d)
508
+ // console.time("4 chrome " + d)
509
509
  try {
510
510
  await git.resolveRef({ fs, dir: repositoryPath, ref: 'HEAD' });
511
511
  } catch (err) {
@@ -514,9 +514,9 @@ class Server {
514
514
  await git.init({ fs, dir: repositoryPath });
515
515
  }
516
516
 
517
- console.timeEnd("4 chrome " + d)
517
+ // console.timeEnd("4 chrome " + d)
518
518
 
519
- console.time("5 chrome " + d)
519
+ // console.time("5 chrome " + d)
520
520
  let gitRemote = await git.getConfig({ fs, http, dir: repositoryPath, path: 'remote.origin.url' })
521
521
  let profile
522
522
  let feed
@@ -530,20 +530,24 @@ class Server {
530
530
  profile = this.profile(gitRemote)
531
531
  feed = this.newsfeed(gitRemote)
532
532
  }
533
- console.timeEnd("5 chrome " + d)
533
+ // console.timeEnd("5 chrome " + d)
534
534
 
535
535
  // git
536
536
 
537
537
  let c = this.kernel.path("api", name)
538
538
 
539
- console.time("6 chrome " + d)
539
+ // console.time("6 chrome " + d)
540
540
  await this.kernel.plugin.init()
541
- let plugin = await this.getPlugin(name)
542
- let plugin_menu = null
543
- if (plugin && plugin.menu && Array.isArray(plugin.menu)) {
544
- let running_dynamic = this.running_dynamic(name, plugin.menu)
545
- plugin_menu = plugin.menu.concat(running_dynamic)
546
- }
541
+ // console.timeEnd("6 chrome " + d)
542
+ // console.time("7 chrome " + d)
543
+ // let plugin = await this.getPlugin(name)
544
+ // console.timeEnd("7 chrome " + d)
545
+ // console.time("8 chrome " + d)
546
+ // let plugin_menu = null
547
+ // if (plugin && plugin.menu && Array.isArray(plugin.menu)) {
548
+ // let running_dynamic = this.running_dynamic(name, plugin.menu)
549
+ // plugin_menu = plugin.menu.concat(running_dynamic)
550
+ // }
547
551
 
548
552
 
549
553
  let current_urls = await this.current_urls(req.originalUrl.slice(1))
@@ -553,7 +557,7 @@ class Server {
553
557
  current_urls,
554
558
  path: this.kernel.path("api", name),
555
559
  log_path: this.kernel.path("api", name, "logs"),
556
- plugin_menu,
560
+ plugin_menu: null,
557
561
  portal: this.portal,
558
562
  install: this.install,
559
563
  error: err,
@@ -567,6 +571,7 @@ class Server {
567
571
  memory: this.kernel.memory,
568
572
  sidebar: "/pinokio/sidebar/" + name,
569
573
  repos: "/pinokio/repos/" + name,
574
+ ai: "/pinokio/ai/" + name,
570
575
  dynamic: "/pinokio/dynamic/" + name,
571
576
  // dynamic: "/pinokio/dynamic/" + name,
572
577
  dynamic_content: null,
@@ -585,12 +590,12 @@ class Server {
585
590
  execUrl: "/api/" + name,
586
591
  // rawpath,
587
592
  }
588
- console.timeEnd("6 chrome " + d)
589
- console.time("7 chrome " + d)
590
- if (!this.kernel.proto.config) {
591
- await this.kernel.proto.init()
592
- }
593
- console.timeEnd("7 chrome " + d)
593
+ // console.timeEnd("8 chrome " + d)
594
+ // console.time("9 chrome " + d)
595
+ // if (!this.kernel.proto.config) {
596
+ // await this.kernel.proto.init()
597
+ // }
598
+ // console.timeEnd("9 chrome " + d)
594
599
  res.render("app", result)
595
600
  }
596
601
  getVariationUrls(req) {
@@ -2443,6 +2448,9 @@ class Server {
2443
2448
  }
2444
2449
  }
2445
2450
  async getPluginGlobal(filepath) {
2451
+ if (!this.kernel.plugin.config) {
2452
+ await this.kernel.plugin.init()
2453
+ }
2446
2454
  if (this.kernel.plugin.config) {
2447
2455
  try {
2448
2456
  let info = new Info(this.kernel)
@@ -2468,17 +2476,16 @@ class Server {
2468
2476
  return plugin
2469
2477
  } catch (e) {
2470
2478
  console.log("getPlugin ERROR", e)
2471
- return {
2472
- menu: []
2473
- }
2479
+ return null
2474
2480
  }
2475
2481
  } else {
2476
- return {
2477
- menu: []
2478
- }
2482
+ return null
2479
2483
  }
2480
2484
  }
2481
2485
  async getPlugin(name) {
2486
+ if (!this.kernel.plugin.config) {
2487
+ await this.kernel.plugin.init()
2488
+ }
2482
2489
  if (this.kernel.plugin.config) {
2483
2490
  try {
2484
2491
  let info = new Info(this.kernel)
@@ -2492,15 +2499,10 @@ class Server {
2492
2499
  return plugin
2493
2500
  } catch (e) {
2494
2501
  console.log("getPlugin ERROR", e)
2495
- return {
2496
- menu: []
2497
- }
2502
+ return null
2498
2503
  }
2499
2504
  } else {
2500
- return {
2501
- menu: []
2502
- }
2503
-
2505
+ return null
2504
2506
  }
2505
2507
  }
2506
2508
  async check_router_up() {
@@ -4499,6 +4501,7 @@ class Server {
4499
4501
  })
4500
4502
  }))
4501
4503
  this.app.get("/dev/*", ex(async (req, res) => {
4504
+ console.log("GET /dev/*", req.params)
4502
4505
  let { requirements, install_required, requirements_pending, error } = await this.kernel.bin.check({
4503
4506
  bin: this.kernel.bin.preset("dev"),
4504
4507
  })
@@ -4507,19 +4510,19 @@ class Server {
4507
4510
  return
4508
4511
  }
4509
4512
  let platform = os.platform()
4510
- await this.kernel.plugin.init()
4513
+ // await this.kernel.plugin.init()
4511
4514
  let filepath = Util.u2p(req.params[0])
4512
- let plugin = await this.getPluginGlobal(filepath)
4515
+ // let plugin = await this.getPluginGlobal(filepath)
4513
4516
  let current_urls = await this.current_urls(req.originalUrl.slice(1))
4514
- let plugin_menu
4515
- try {
4516
- plugin_menu = plugin.menu[0].menu
4517
- } catch (e) {
4518
- plugin_menu = []
4519
- }
4517
+ // let plugin_menu
4518
+ // try {
4519
+ // plugin_menu = plugin.menu[0].menu
4520
+ // } catch (e) {
4521
+ // plugin_menu = []
4522
+ // }
4520
4523
  const result = {
4521
4524
  current_urls,
4522
- plugin_menu,
4525
+ plugin_menu: null,
4523
4526
  portal: this.portal,
4524
4527
  install: this.install,
4525
4528
  port: this.port,
@@ -4616,35 +4619,83 @@ class Server {
4616
4619
  }))
4617
4620
  this.app.get("/pinokio/dynamic_global/*", ex(async (req, res) => {
4618
4621
  let plugin = await this.getPluginGlobal("/" + req.params[0])
4619
- let html = ""
4620
- if (plugin && plugin.menu) {
4621
- let plugin_menu
4622
- try {
4623
- plugin_menu = plugin.menu[0].menu
4624
- } catch (e) {
4625
- plugin_menu = []
4626
- }
4627
- html = await new Promise((resolve, reject) => {
4628
- ejs.renderFile(path.resolve(__dirname, "views/partials/dynamic.ejs"), { dynamic: plugin_menu }, (err, html) => {
4629
- resolve(html)
4622
+ if (plugin) {
4623
+ let html = ""
4624
+ if (plugin && plugin.menu) {
4625
+ let plugin_menu
4626
+ try {
4627
+ plugin_menu = plugin.menu[0].menu
4628
+ } catch (e) {
4629
+ plugin_menu = []
4630
+ }
4631
+ html = await new Promise((resolve, reject) => {
4632
+ ejs.renderFile(path.resolve(__dirname, "views/partials/dynamic.ejs"), { dynamic: plugin_menu }, (err, html) => {
4633
+ resolve(html)
4634
+ })
4630
4635
  })
4631
- })
4636
+ }
4637
+ res.send(html)
4638
+ } else {
4639
+ res.send("")
4632
4640
  }
4633
- res.send(html)
4634
4641
  }))
4635
4642
  this.app.get("/pinokio/dynamic/:name", ex(async (req, res) => {
4636
4643
  // await this.kernel.plugin.init()
4637
4644
  let plugin = await this.getPlugin(req.params.name)
4638
- let html = ""
4639
- if (plugin && plugin.menu && Array.isArray(plugin.menu)) {
4640
- let running_dynamic = this.running_dynamic(req.params.name, plugin.menu)
4641
- plugin.menu = plugin.menu.concat(running_dynamic)
4642
- html = await new Promise((resolve, reject) => {
4643
- ejs.renderFile(path.resolve(__dirname, "views/partials/dynamic.ejs"), { dynamic: plugin.menu }, (err, html) => {
4644
- resolve(html)
4645
+ if (plugin) {
4646
+ let html = ""
4647
+ if (plugin && plugin.menu && Array.isArray(plugin.menu)) {
4648
+ let running_dynamic = this.running_dynamic(req.params.name, plugin.menu)
4649
+ plugin.menu = plugin.menu.concat(running_dynamic)
4650
+ html = await new Promise((resolve, reject) => {
4651
+ ejs.renderFile(path.resolve(__dirname, "views/partials/dynamic.ejs"), { dynamic: plugin.menu }, (err, html) => {
4652
+ resolve(html)
4653
+ })
4645
4654
  })
4646
- })
4655
+ }
4656
+ res.send(html)
4657
+ } else {
4658
+ res.send("")
4647
4659
  }
4660
+ }))
4661
+ this.app.get("/pinokio/ai/:name", ex(async (req, res) => {
4662
+ /*
4663
+ link to
4664
+ README.md
4665
+ AGENTS.md
4666
+ CLAUDE.md
4667
+ GEMINI.md
4668
+ */
4669
+ let c = this.kernel.path("api", req.params.name, "README.md")
4670
+ let readme_exists = await this.exists(c)
4671
+ let files
4672
+ if (readme_exists) {
4673
+ files = [
4674
+ "README.md",
4675
+ "AGENTS.md",
4676
+ "CLAUDE.md",
4677
+ "GEMINI.md"
4678
+ ]
4679
+ } else {
4680
+ files = [
4681
+ "AGENTS.md",
4682
+ "CLAUDE.md",
4683
+ "GEMINI.md"
4684
+ ]
4685
+ }
4686
+
4687
+
4688
+ let items = files.map((item) => {
4689
+ return {
4690
+ text: item,
4691
+ href: `/_api/${req.params.name}/${item}`
4692
+ }
4693
+ })
4694
+ let html = await new Promise((resolve, reject) => {
4695
+ ejs.renderFile(path.resolve(__dirname, "views/partials/ai.ejs"), { items }, (err, html) => {
4696
+ resolve(html)
4697
+ })
4698
+ })
4648
4699
  res.send(html)
4649
4700
  }))
4650
4701
  this.app.get("/pinokio/repos/:name", ex(async (req, res) => {
@@ -121,7 +121,7 @@ body.dark *::-webkit-scrollbar-thumb {
121
121
  .drawer.vertical-collapsed {
122
122
  max-height: 0;
123
123
  }
124
- .git.selected {
124
+ .blue.selected {
125
125
  border-left: 10px solid royalblue;
126
126
  }
127
127
  body.dark .dynamic.selected {
@@ -840,12 +840,6 @@ body.dark .appcanvas {
840
840
  </div>
841
841
  <div class='disk-usage' data-path="/"></div>
842
842
  </a>
843
- <a target="<%=logs%>" href="<%=logs%>" class='btn header-item frame-link' data-index="1" data-mode="refresh">
844
- <div class='tab'>
845
- <i class="fa-solid fa-clock-rotate-left"></i> Logs
846
- </div>
847
- <div class='disk-usage' data-path="/logs"></div>
848
- </a>
849
843
  <% if (profile || feed) { %>
850
844
  <div class='btn header-item frame-link revealer' data-group='.info-group'>
851
845
  <div class='tab'>
@@ -866,13 +860,18 @@ body.dark .appcanvas {
866
860
  <% } %>
867
861
  </div>
868
862
  <% } %>
869
- <div class='dynamic'>
870
- <% if (plugin_menu) { %>
871
- <%- include('./partials/dynamic', { dynamic: plugin_menu, }) %>
863
+ <div class="dynamic <%=type==='run' ? '' : 'selected'%>">
864
+ <% if (type !== "run") { %>
865
+ <div class="nested-menu">
866
+ <div class="btn header-item frame-link selected">
867
+ <div class="tab"><i class="fa-solid fa-code"></i> Dev</div>
868
+ <div class="loader"><i class="fa-solid fa-circle-notch fa-spin"></i></div>
869
+ </div>
870
+ </div>
872
871
  <% } %>
873
872
  </div>
874
873
  <% if (type === "browse") { %>
875
- <div class='nested-menu selected git'>
874
+ <div class='nested-menu selected git blue'>
876
875
  <div class='btn header-item frame-link reveal'>
877
876
  <div class='tab'><i class="fa-solid fa-cloud"></i> Git</div>
878
877
  <div class='loader'><i class="fa-solid fa-angle-down"></i><i class="fa-solid fa-angle-up hidden"></i></div>
@@ -880,6 +879,22 @@ body.dark .appcanvas {
880
879
  <div class='submenu' id='git-repos'>
881
880
  </div>
882
881
  </div>
882
+ <div class='nested-menu selected blue'>
883
+ <a target="<%=logs%>" href="<%=logs%>" class='btn header-item frame-link' data-index="1" data-mode="refresh">
884
+ <div class='tab'>
885
+ <i class="fa-solid fa-clock-rotate-left"></i> Logs
886
+ </div>
887
+ <div class='disk-usage' data-path="/logs"></div>
888
+ </a>
889
+ </div>
890
+ <div class='nested-menu selected blue'>
891
+ <div class='btn header-item frame-link reveal'>
892
+ <div class='tab'><i class="fa-solid fa-robot"></i> AI Recipes</div>
893
+ <div class='loader'><i class="fa-solid fa-angle-down"></i><i class="fa-solid fa-angle-up hidden"></i></div>
894
+ </div>
895
+ <div class='submenu hidden' id='ai-prompts'>
896
+ </div>
897
+ </div>
883
898
  <% } %>
884
899
  <div class='btn header-item frame-link revealer' data-group='.config-group'>
885
900
  <div class='tab'>
@@ -915,7 +930,9 @@ body.dark .appcanvas {
915
930
  <div class='app-info'>
916
931
  <% if (type === 'run') { %>
917
932
  <div class='mode-section'>
933
+ <!--
918
934
  <h3><i class='fa-solid fa-circle-play'></i> Run mode</h3>
935
+ -->
919
936
  <div class='desc'>Switch to dev mode to make changes to the app.</div>
920
937
  <a class='btn' href="<%=home.endsWith("/") ? home : home + "/" %>dev"><i class="fa-solid fa-code"></i> Switch to Dev mode</a>
921
938
  </div>
@@ -1491,7 +1508,6 @@ body.dark .appcanvas {
1491
1508
  edit: true,
1492
1509
  redirect: (new_path) => {
1493
1510
  let u = location.href.replace(/(\/pinokio\/browser\/)[^\/]+(?=\/|$)/, `$1${new_path}`)
1494
- debugger
1495
1511
  return u
1496
1512
  }
1497
1513
  })
@@ -1510,7 +1526,6 @@ body.dark .appcanvas {
1510
1526
  edit: true,
1511
1527
  redirect: (new_path) => {
1512
1528
  let u = location.href.replace(/(\/pinokio\/browser\/)[^\/]+(?=\/|$)/, `$1${new_path}`)
1513
- debugger
1514
1529
  return u
1515
1530
  }
1516
1531
  })
@@ -1530,7 +1545,6 @@ body.dark .appcanvas {
1530
1545
  edit: true,
1531
1546
  redirect: (new_path) => {
1532
1547
  let u = location.href.replace(/(\/pinokio\/browser\/)[^\/]+(?=\/|$)/, `$1${new_path}`)
1533
- debugger
1534
1548
  return u
1535
1549
  }
1536
1550
  })
@@ -1671,7 +1685,6 @@ body.dark .appcanvas {
1671
1685
  e.stopPropagation()
1672
1686
  let shell = target.closest("[data-shell]")
1673
1687
  if (shell) {
1674
- debugger
1675
1688
  let shell_id = shell.getAttribute("data-shell")
1676
1689
  n.Noty({
1677
1690
  text: `stopping shell`,
@@ -1728,7 +1741,6 @@ body.dark .appcanvas {
1728
1741
  })
1729
1742
  } else {
1730
1743
  let link = target.closest("[href]")
1731
- debugger
1732
1744
  if (link) {
1733
1745
  let src = new URL(link.href).pathname
1734
1746
  target.querySelector("i.fa-square").className = "fa-solid fa-check"
@@ -1835,7 +1847,7 @@ body.dark .appcanvas {
1835
1847
  <% } else { %>
1836
1848
  // dev mode => already dev. reveal the hidden menu
1837
1849
  if (target.closest(".dynamic")) {
1838
- target.closest(".dynamic").classList.toggle("selected")
1850
+ target.closest(".dynamic").classList.add("selected")
1839
1851
  target.closest(".nested-menu").querySelector(".submenu").classList.toggle("hidden")
1840
1852
  target.querySelector(".loader .fa-angle-down").classList.toggle("hidden")
1841
1853
  target.querySelector(".loader .fa-angle-up").classList.toggle("hidden")
@@ -1910,8 +1922,45 @@ body.dark .appcanvas {
1910
1922
  }
1911
1923
  })
1912
1924
  }
1913
- const refresh = async (silent, options) => {
1914
1925
 
1926
+ let dynamic_loaded = false
1927
+
1928
+ const try_dynamic = async () => {
1929
+ console.log("Try_dynamic")
1930
+ let rendered
1931
+ const dynamic = await fetch("<%=dynamic%>").then((res) => {
1932
+ return res.text()
1933
+ })
1934
+ if (dynamic && dynamic.length > 0) {
1935
+ console.log({ dynamic })
1936
+ if (document.querySelector(".dynamic")) {
1937
+ document.querySelector(".dynamic").innerHTML = dynamic
1938
+ }
1939
+ rendered = true
1940
+ } else {
1941
+ rendered = false
1942
+ }
1943
+ console.log({ rendered, dynamic_loaded })
1944
+ if (rendered) {
1945
+ if (dynamic_loaded) {
1946
+ // already loaded, don't touch the UI
1947
+ } else {
1948
+ // first time being loaded
1949
+ dynamic_loaded = true
1950
+ if (document.querySelector(".dynamic .reveal")) {
1951
+ console.log("click")
1952
+
1953
+ document.querySelector(".dynamic .reveal").click()
1954
+ }
1955
+ }
1956
+ } else {
1957
+ console.log("Not yet rendered. Try again")
1958
+ setTimeout(() => {
1959
+ try_dynamic()
1960
+ }, 1000)
1961
+ }
1962
+ }
1963
+ const refresh = async (silent, options) => {
1915
1964
 
1916
1965
  if (options && options.nodelay) {
1917
1966
  } else {
@@ -1926,14 +1975,9 @@ body.dark .appcanvas {
1926
1975
  })
1927
1976
  document.querySelector(".menu").innerHTML = html
1928
1977
 
1929
- const dynamic = await fetch("<%=dynamic%>").then((res) => {
1930
- return res.text()
1931
- })
1932
- console.log({ dynamic })
1933
- if (document.querySelector(".dynamic")) {
1934
- document.querySelector(".dynamic").innerHTML = dynamic
1935
- }
1936
-
1978
+ <% if (type !== 'run') { %>
1979
+ try_dynamic()
1980
+ <% } %>
1937
1981
 
1938
1982
  const repos = await fetch("<%=repos%>").then((res) => {
1939
1983
  return res.text()
@@ -1942,6 +1986,14 @@ body.dark .appcanvas {
1942
1986
  document.querySelector("#git-repos").innerHTML = repos
1943
1987
  }
1944
1988
 
1989
+ const ai = await fetch("<%=ai%>").then((res) => {
1990
+ return res.text()
1991
+ })
1992
+ console.log({ ai })
1993
+ if (document.querySelector("#ai-prompts")) {
1994
+ document.querySelector("#ai-prompts").innerHTML = ai
1995
+ }
1996
+
1945
1997
  location.hash = ""
1946
1998
 
1947
1999
  // render the selected frame only if not silent
@@ -2053,7 +2105,6 @@ body.dark .appcanvas {
2053
2105
  refresh_du()
2054
2106
  refresh_du("logs")
2055
2107
  <% if (type !== 'run') { %>
2056
- debugger
2057
2108
  fetch("<%=repos%>").then((res) => {
2058
2109
  return res.text()
2059
2110
  }).then((repos) => {
@@ -2061,9 +2112,7 @@ body.dark .appcanvas {
2061
2112
  document.querySelector("#git-repos").innerHTML = repos
2062
2113
  }
2063
2114
  })
2064
- if (document.querySelector(".dynamic .reveal")) {
2065
- document.querySelector(".dynamic .reveal").click()
2066
- }
2115
+ refresh()
2067
2116
  <% } %>
2068
2117
  /*
2069
2118
  document.addEventListener("keydown", (e) => {
@@ -228,10 +228,12 @@ document.addEventListener("DOMContentLoaded", async () => {
228
228
  document.querySelector(".run .starting").classList.add("hidden")
229
229
  }
230
230
  stop() {
231
+ let cwd = "<%-JSON.stringify(execUrl).slice(1, -1)%>"
231
232
  this.socket.run({
232
233
  method: "kernel.api.stop",
233
234
  params: {
234
- uri: "<%=execUrl%>",
235
+ //uri: "<%=execUrl%>",
236
+ uri: cwd,
235
237
  //uri: "~" + location.pathname
236
238
  }
237
239
  }, (stream) => {
@@ -239,7 +241,8 @@ document.addEventListener("DOMContentLoaded", async () => {
239
241
  }
240
242
  save() {
241
243
  return new Promise((resolve, reject) => {
242
- let cwd = "<%=execUrl%>"
244
+ let cwd = "<%-JSON.stringify(execUrl).slice(1, -1)%>"
245
+ //let cwd = "<%=execUrl%>"
243
246
  //let cwd = "~" + location.pathname
244
247
  this.socket.close()
245
248
  this.socket.run({
@@ -269,7 +272,8 @@ document.addEventListener("DOMContentLoaded", async () => {
269
272
  this.socket.run({
270
273
  //uri: location.pathname.slice(1).replace("api/", ""),
271
274
  //uri: "~" + location.pathname,
272
- uri: "<%=execUrl%>",
275
+ uri: "<%-JSON.stringify(execUrl).slice(1, -1)%>",
276
+ //uri: "<%=execUrl%>",
273
277
  //uri: "~" + location.pathname,
274
278
  mode,
275
279
  input: query,
@@ -1454,6 +1454,7 @@ body.dark .appcanvas {
1454
1454
 
1455
1455
  })
1456
1456
  const refresh = async (silent, options) => {
1457
+ debugger
1457
1458
  console.log("REFRESH")
1458
1459
  const dynamic = await fetch("<%=dynamic%>").then((res) => {
1459
1460
  return res.text()
@@ -1537,6 +1538,7 @@ body.dark .appcanvas {
1537
1538
  if (document.querySelector(".dynamic .reveal")) {
1538
1539
  document.querySelector(".dynamic .reveal").click()
1539
1540
  }
1541
+ refresh()
1540
1542
  </script>
1541
1543
  </body>
1542
1544
  </html>
@@ -0,0 +1,5 @@
1
+ <% items.forEach((item, index) => { %>
2
+ <a target="<%=item.href%>" href="<%=item.href%>" class='btn header-item frame-link' data-index="<%=index%>" data-mode="refresh">
3
+ <div class='tab'><i class="fa-regular fa-folder-open"></i> <%=item.text%></div>
4
+ </a>
5
+ <% }) %>
@@ -25,7 +25,7 @@
25
25
  img.appicon {
26
26
  width: 40px;
27
27
  height: 40px;
28
- margin-right: 10px;
28
+ margin-right: 5px;
29
29
  padding: 5px;
30
30
  border-radius: 4px;
31
31
  background: white;
@@ -53,7 +53,7 @@ h4 {
53
53
  }
54
54
 
55
55
  h2 {
56
- font-size: 25px;
56
+ font-size: 30px;
57
57
  }
58
58
  h1 {
59
59
  letter-spacing: 0px;
@@ -145,6 +145,11 @@ body.dark .radio-group label {
145
145
  }
146
146
 
147
147
  .radio-group label span {
148
+ font-size: 16px;
149
+ /*
150
+ font-weight: lighter;
151
+ */
152
+ margin-left: 5px;
148
153
  font-weight: bold;
149
154
  flex: 1;
150
155
  }
@@ -152,6 +157,10 @@ body.dark .radio-group label {
152
157
  .radio-group label .description {
153
158
  opacity: 0.7;
154
159
  margin-left: 0.5rem;
160
+ /*
161
+ width: 350px;
162
+ text-align: right;
163
+ */
155
164
  }
156
165
 
157
166
  .checkbox-group {
@@ -184,6 +193,35 @@ body.dark .conditional-options {
184
193
  */
185
194
  display: none;
186
195
  }
196
+ #step-1 .radio-group {
197
+ display: flex;
198
+ }
199
+ #step-1 .radio-group label:hover {
200
+ color: royalblue;
201
+ }
202
+ #step-1 .radio-group label .description {
203
+ margin: 0;
204
+ }
205
+ #step-1 .radio-group label .col {
206
+ flex-grow: 1;
207
+ }
208
+ #step-1 .radio-group label {
209
+ display: flex;
210
+ padding: 30px;
211
+ text-align: left;
212
+ }
213
+ #step-1 .radio-group label i {
214
+ padding-right: 15px;
215
+ display: block;
216
+ font-size: 40px;
217
+ }
218
+ #step-1 .radio-group input[type=radio] {
219
+ display: none;
220
+ }
221
+ #step-1 .radio-group label span {
222
+ margin: 0;
223
+ font-size: 20px;
224
+ }
187
225
 
188
226
  /*
189
227
  .conditional-options .radio-group label, .conditional-options .checkbox-group label {
@@ -1051,24 +1089,30 @@ body.dark .command-fields {
1051
1089
  <form id="bootstrap-form">
1052
1090
  <!-- Step 1: New vs Clone -->
1053
1091
  <div class="step-content active" id="step-1">
1054
- <h2>Step 1: Choose Your Starting Point</h2>
1092
+ <h2>What do you want to build?</h2>
1055
1093
  <div class="radio-group">
1056
1094
  <label>
1057
- <input type="radio" name="startType" value="new" required>
1058
- <span>New Project</span>
1059
- <p class="description">Start with a fresh project</p>
1095
+ <input type="radio" name="startType" value="clone" required>
1096
+ <i class="fa-solid fa-rocket"></i>
1097
+ <div class='col'>
1098
+ <span>1-Click Launcher</span>
1099
+ <p class="description">Build a 1-click launcher for an existing app (from git)</p>
1100
+ </div>
1060
1101
  </label>
1061
1102
  <label>
1062
- <input type="radio" name="startType" value="clone" required>
1063
- <span>Clone Repository</span>
1064
- <p class="description">Clone an existing git repository</p>
1103
+ <input type="radio" name="startType" value="new" required>
1104
+ <i class="fa-solid fa-code"></i>
1105
+ <div class='col'>
1106
+ <span> New Project</span>
1107
+ <p class="description">Build a new app with a built-in 1-click launcher</p>
1108
+ </div>
1065
1109
  </label>
1066
1110
  </div>
1067
1111
  </div>
1068
1112
 
1069
1113
  <!-- Step 2: Project Type -->
1070
1114
  <div class="step-content" id="step-2">
1071
- <h2>Step 2: Select Project Type</h2>
1115
+ <h2>Select Project Type</h2>
1072
1116
 
1073
1117
  <!-- Clone Project Options -->
1074
1118
  <div id="clone-options" class="project-options">
@@ -1077,19 +1121,19 @@ body.dark .command-fields {
1077
1121
  <input type="radio" name="projectType" value="nodejs">
1078
1122
  <img class='appicon' src="/asset/prototype/system/nodejs/icon.png"/>
1079
1123
  <span>Node.js</span>
1080
- <p class="description">A launcher for a typical node.js project</p>
1124
+ <p class="description">Build a 1-click launcher for a node.js project.</p>
1081
1125
  </label>
1082
1126
  <label>
1083
1127
  <input type="radio" name="projectType" value="python">
1084
1128
  <img class='appicon' src="/asset/prototype/system/python/icon.png"/>
1085
1129
  <span>Python</span>
1086
- <p class='description'>A launcher for a typical python project)</p>
1130
+ <p class='description'>Build a 1-click launcher for a python project.</p>
1087
1131
  </label>
1088
1132
  <label>
1089
1133
  <input type="radio" name="projectType" value="empty">
1090
1134
  <img class='appicon' src="/asset/prototype/system/empty/icon.png"/>
1091
1135
  <span>Any</span>
1092
- <p class='description'>A minimal launcher you can customize on your own</p>
1136
+ <p class='description'>Build a 1-click launcher for anything else or to customize on your own.</p>
1093
1137
  </label>
1094
1138
  </div>
1095
1139