pinokiod 3.8.148 → 3.8.149

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/server/index.js CHANGED
@@ -47,6 +47,8 @@ const Environment = require("../kernel/environment")
47
47
  const Cloudflare = require("../kernel/api/cloudflare")
48
48
  const Util = require("../kernel/util")
49
49
 
50
+ const Setup = require("../kernel/bin/setup")
51
+
50
52
  class Server {
51
53
  constructor(config) {
52
54
  this.tabs = {}
@@ -428,6 +430,21 @@ class Server {
428
430
  rawpath,
429
431
  })
430
432
  }
433
+ getVariationUrls(req) {
434
+ let edu = new URL("http://localhost" + req.originalUrl)
435
+ edu.searchParams.set("mode", "source")
436
+ let editorUrl = edu.pathname + edu.search
437
+
438
+ let referer = req.get("Referer")
439
+ let prevUrl = null
440
+ try {
441
+ if (/\/env\/api\/.+/.test(new URL(referer).pathname)) {
442
+ prevUrl = referer
443
+ }
444
+ } catch (e) {
445
+ }
446
+ return { editorUrl, prevUrl }
447
+ }
431
448
  async render(req, res, pathComponents, meta) {
432
449
 
433
450
 
@@ -556,8 +573,9 @@ class Server {
556
573
  display: ["form"]
557
574
  })
558
575
  } else if (pathComponents.length === 0 && req.query.mode === "download") {
559
- let { requirements, install_required, requirements_pending, error } = await this.kernel.bin.check_bin()
560
-
576
+ let { requirements, install_required, requirements_pending, error } = await this.kernel.bin.check({
577
+ bin: this.kernel.bin.preset("ai"),
578
+ })
561
579
  res.render("download", {
562
580
  error,
563
581
  current: req.originalUrl,
@@ -762,240 +780,57 @@ class Server {
762
780
  resolved = runner
763
781
  }
764
782
 
765
- let template
766
- template = "terminal"
767
-
783
+ let template = "terminal"
768
784
  if (req.query && req.query.mode === "source") {
769
785
  template = "editor"
770
786
  }
771
787
 
772
-
773
- // Deprecate source view and form view => Everything is full screen by default
774
- // if (req.query && req.query.mode === "source") {
775
- // if (req.query && req.query.fullscreen) {
776
- // template = "fullscreen_editor"
777
- // } else {
778
- // template = "editor"
779
- // }
780
- // } else if (schemaPath && schemaPath.length > 0) {
781
- // template = "form"
782
- // } else {
783
- // if (req.query && req.query.fullscreen) {
784
- // template = "fullscreen_editor"
785
- // } else {
786
- // template = "editor"
787
- // }
788
- // }
789
-
790
-
791
- let requirements = [{
792
- name: "conda",
793
- }, {
794
- name: "git",
795
- }, {
796
- name: "zip",
797
- }, {
798
- name: "node",
799
- }, {
800
- name: "ffmpeg",
801
- }, {
802
- name: "caddy",
803
- // type: "conda",
804
- // name: "ffmpeg",
805
- // args: "-c conda-forge"
806
- }]
807
- let platform = os.platform()
808
- if (platform === "win32") {
809
- requirements.push({
810
- name: "registry"
811
- })
812
- requirements.push({
813
- name: "vs"
814
- })
815
- }
816
- if (platform === "darwin") {
817
- requirements.push({
818
- name: "brew"
819
- })
820
- }
821
- if (platform === "linux") {
822
- requirements.push({
823
- name: "gxx"
824
- })
825
- }
826
- if (this.kernel.gpu === "nvidia") {
827
- requirements.push({
828
- name: "cuda"
829
- })
830
- }
831
- requirements = requirements.concat([{
832
- name: "cloudflared"
833
- // }, {
834
- // name: "playwright"
835
- }, {
836
- name: "huggingface"
837
- }, {
838
- name: "uv"
839
- }, {
840
- name: "py"
841
- }])
842
- // if (platform === "linux") {
843
- // requirements.push({
844
- // name: "brew"
845
- // })
846
- // }
847
-
848
- if (resolved && resolved.requires && resolved.requires.length > 0) {
849
- /*********************************************************************
850
-
851
- syntax :=
852
-
853
- {
854
- platform: <win32|darwin|linux>,
855
- type: <conda|pip|brew|none>,
856
- name: <package name>, (example: "ffmpeg", "git")
857
- args: <install command flags> (example: "-c conda-forge")
858
- }
859
-
860
-
861
- 1. pinokio native install: no need for specifying platforms since they are included
862
-
863
- {
864
- name: "conda"
865
- }
866
-
867
-
868
- 2. non native install (conda, pip, brew)
869
-
870
- 2.1. Same on all platforms
871
-
872
- [{
873
- type: "conda",
874
- name: "ffmpeg",
875
- args: "-c conda-forge"
876
- }]
877
-
878
- 2.2. Specify per platform
879
-
880
-
881
- [
882
- { name: "conda" },
883
- { platform: "darwin", type: "brew", name: "llvm" },
884
- { platform: "linux", tyoe: "conda", name: "llvm", args: "-c conda-forge llvm" },
885
- { platform: "win32", tyoe: "conda", name: "llvm", args: "-c conda-forge llvm" }
886
- ]
887
-
888
- [
889
- { name: "conda" },
890
- { platform: ["darwin", "linux"], type: "brew", name: "llvm" },
891
- { platform: "win32", tyoe: "conda", name: "llvm", args: "-c conda-forge llvm" }
892
- ]
893
-
894
-
895
-
896
- *********************************************************************/
897
-
898
-
899
- let platform = os.platform()
900
- let type_name_set = new Set()
901
- for(let r of resolved.requires) {
902
- // if no platform specified, or if the specified platform matches the current platform
903
- if (!r.platform || platform === r.platform || Array.isArray(r.platform) && r.platform.includes(platform) ) {
904
- if (Array.isArray(r.name)) {
905
- // if array, just add it
906
- requirements.push(r)
907
- } else {
908
- let type_name = `${r.type ? r.type : ''}/${r.name}`
909
- if (!type_name_set.has(type_name)) {
910
- type_name_set.add(type_name)
911
- requirements.push(r)
912
- }
913
- }
914
- }
915
- }
916
-
917
- }
918
- let requirements_pending = !this.kernel.bin.installed_initialized
919
-
920
- let install_required = true
921
- if (!requirements_pending) {
922
- install_required = false
923
- for(let i=0; i<requirements.length; i++) {
924
- let r = requirements[i]
925
-
926
- let relevant = this.relevant(r)
927
- requirements[i].relevant = relevant
928
- if (relevant) {
929
- let installed = await this.installed(r)
930
- requirements[i].installed = installed
931
- if (!installed) {
932
- install_required = true
933
- }
934
- }
935
- }
936
- }
937
-
938
- let error = null
939
- try {
940
- this.kernel.bin.compatible()
941
- } catch (e) {
942
- error = e.message
943
- install_required = true
944
- }
945
-
946
- requirements = requirements.filter((r) => {
947
- return r.relevant
788
+ let { requirements, install_required, requirements_pending, error } = await this.kernel.bin.check({
789
+ bin: this.kernel.bin.preset("ai"),
790
+ script: resolved
948
791
  })
949
792
 
793
+ //let requirements = this.kernel.bin.requirements(resolved)
794
+ //let requirements_pending = !this.kernel.bin.installed_initialized
795
+ //let install_required = true
796
+ //if (!requirements_pending) {
797
+ // install_required = false
798
+ // for(let i=0; i<requirements.length; i++) {
799
+ // let r = requirements[i]
800
+
801
+ // let relevant = this.relevant(r)
802
+ // requirements[i].relevant = relevant
803
+ // if (relevant) {
804
+ // let installed = await this.installed(r)
805
+ // requirements[i].installed = installed
806
+ // if (!installed) {
807
+ // install_required = true
808
+ // }
809
+ // }
810
+ // }
811
+ //}
950
812
 
951
- let mem = this.getMemory(filepath)
952
- let edu = new URL("http://localhost" + req.originalUrl)
953
- edu.searchParams.set("mode", "source")
954
- let editorUrl = edu.pathname + edu.search
813
+ //let error = null
814
+ //try {
815
+ // this.kernel.bin.compatible()
816
+ //} catch (e) {
817
+ // error = e.message
818
+ // install_required = true
819
+ //}
955
820
 
956
- let referer = req.get("Referer")
821
+ //requirements = requirements.filter((r) => {
822
+ // return r.relevant
823
+ //})
957
824
 
958
- let prev = null
959
- try {
960
- if (/\/env\/api\/.+/.test(new URL(referer).pathname)) {
961
- prev = referer
962
- }
963
- } catch (e) {
964
- }
965
825
 
826
+ let mem = this.getMemory(filepath)
966
827
 
967
- let requires_instantiation = false
968
- let pre_items = []
969
- if (resolved && resolved.pre) {
970
- let env = await Environment.get2(filepath, this.kernel)
971
- for(let item of resolved.pre) {
972
- if (item.env) {
828
+ let { editorUrl, prevUrl } = this.getVariationUrls(req)
973
829
 
974
- if (!item.index) {
975
- item.index = 0
976
- }
977
- if (item.key) {
978
- const hasProtocol = /^[a-zA-Z][a-zA-Z\d+\-.]*:\/\//.test(item.key);
979
- const url = new URL(hasProtocol ? item.key : `https://${item.key}`);
980
- item.host = url.host
981
- item.val = await this.kernel.kv.get(item.host, item.index)
982
- } else {
983
- item.host = ""
984
- }
985
830
 
986
- if (env[item.env]) {
987
- item.val = env[item.env]
988
- } else {
989
- if (item.default) {
990
- item.val = item.default
991
- }
992
- requires_instantiation = true
993
- }
994
- pre_items.push(item)
995
- }
996
- }
997
- }
998
- if (requires_instantiation) {
831
+ let env_requirements = await Environment.requirements(resolved, filepath, this.kernel)
832
+ console.log({ env_requirements })
833
+ if (env_requirements.requires_instantiation) {
999
834
  let p = Util.api_path(filepath, this.kernel)
1000
835
  let platform = os.platform()
1001
836
  if (platform === "win32") {
@@ -1006,12 +841,12 @@ class Server {
1006
841
  theme: this.theme,
1007
842
  filename,
1008
843
  filepath: p,
1009
- items: pre_items
844
+ items: env_requirements.items
1010
845
  })
1011
846
  } else {
1012
847
  let logpath = encodeURIComponent(Util.log_path(filepath, this.kernel))
1013
848
  const result = {
1014
- prev,
849
+ prev: prevUrl,
1015
850
  error,
1016
851
  memory: mem,
1017
852
  // memory: mem,
@@ -1762,89 +1597,6 @@ class Server {
1762
1597
  return config
1763
1598
  }
1764
1599
  }
1765
- relevant(r) {
1766
- /*
1767
- single platform
1768
- [
1769
- { name: "conda" },
1770
- { platform: "darwin", type: "brew", name: "llvm" },
1771
- { platform: "linux", tyoe: "conda", name: "llvm", args: "-c conda-forge llvm" },
1772
- { platform: "win32", tyoe: "conda", name: "llvm", args: "-c conda-forge llvm" }
1773
- ]
1774
-
1775
- multiple platforms
1776
- [
1777
- { name: "conda" },
1778
- { platform: ["darwin", "linux"], type: "brew", name: "llvm" },
1779
- { platform: "win32", tyoe: "conda", name: "llvm", args: "-c conda-forge llvm" }
1780
- ]
1781
-
1782
-
1783
- platform & arch
1784
- [
1785
- { name: "conda" },
1786
- { platform: "darwin", arch: ["arm64", "x64"], type: "brew", name: "llvm" },
1787
- ]
1788
- */
1789
-
1790
- let platform = os.platform()
1791
- let arch = os.arch()
1792
- let gpu = this.kernel.gpu
1793
- let relevant = {
1794
- platform: false,
1795
- arch: false,
1796
- gpu: false,
1797
- }
1798
- if (r.platform) {
1799
- if (Array.isArray(r.platform)) {
1800
- // multiple items
1801
- if (r.platform.includes(platform)) {
1802
- relevant.platform = true
1803
- }
1804
- } else {
1805
- // one item
1806
- if (r.platform === platform) {
1807
- relevant.platform = true
1808
- }
1809
- }
1810
- } else {
1811
- // all platforms
1812
- relevant.platform = true
1813
- }
1814
- if (r.arch) {
1815
- if (Array.isArray(r.arch)) {
1816
- // multiple items
1817
- if (r.arch.includes(arch)) {
1818
- relevant.arch = true
1819
- }
1820
- } else {
1821
- // one item
1822
- if (r.arch === arch) {
1823
- relevant.arch = true
1824
- }
1825
- }
1826
- } else {
1827
- // all platforms
1828
- relevant.arch = true
1829
- }
1830
- if (r.gpu) {
1831
- if (Array.isArray(r.gpu)) {
1832
- // multiple items
1833
- if (r.gpu.includes(gpu)) {
1834
- relevant.gpu = true
1835
- }
1836
- } else {
1837
- // one item
1838
- if (r.gpu === gpu) {
1839
- relevant.gpu = true
1840
- }
1841
- }
1842
- } else {
1843
- // all platforms
1844
- relevant.gpu = true
1845
- }
1846
- return relevant.platform && relevant.arch && relevant.gpu
1847
- }
1848
1600
  async _installed(name, type) {
1849
1601
  if (type === "conda") {
1850
1602
  return this.kernel.bin.installed.conda.has(name)
@@ -2470,6 +2222,15 @@ class Server {
2470
2222
  //let home = this.kernel.homedir
2471
2223
  //let home = this.kernel.store.get("home")
2472
2224
  this.app.get("/", ex(async (req, res) => {
2225
+ // check bin folder
2226
+ let bin_path = this.kernel.path("bin/miniconda")
2227
+ let bin_exists = await this.exists(bin_path)
2228
+ if (!bin_exists) {
2229
+ res.redirect("/setup")
2230
+ return
2231
+ }
2232
+
2233
+
2473
2234
  if (req.query.mode !== "settings" && !home) {
2474
2235
  res.redirect("/?mode=settings")
2475
2236
  return
@@ -2717,7 +2478,66 @@ class Server {
2717
2478
  }
2718
2479
  }
2719
2480
  }))
2481
+ this.app.get("/setup", ex(async (req, res) => {
2482
+ let items = []
2483
+ for(let id in Setup) {
2484
+ let item = Setup[id](this.kernel)
2485
+ items.push({
2486
+ id,
2487
+ ...item
2488
+ })
2489
+ }
2490
+ res.render("setup_home", {
2491
+ items,
2492
+ logo: this.logo,
2493
+ theme: this.theme,
2494
+ agent: this.agent,
2495
+ })
2496
+ }))
2497
+ this.app.get("/setup/:mode", ex(async (req, res) => {
2498
+ /*
2499
+ 1. mode:ai => all
2500
+ 2. mode:coding => conda, nodejs, git
2501
+ 3. mode:network => conda, git, caddy
2502
+ 4. mode:
2503
+ */
2504
+
2505
+ let bin = this.kernel.bin.preset(req.params.mode)
2506
+
2507
+ let { requirements, install_required, requirements_pending, error } = await this.kernel.bin.check({
2508
+ bin
2509
+ })
2510
+ // set dependencies for conda
2511
+ for(let i=0; i<requirements.length; i++) {
2512
+ let r = requirements[i]
2513
+ if (r.name === "conda") {
2514
+ requirements[i].dependencies = bin.conda_requirements
2515
+ }
2516
+ }
2517
+ console.log("RE", JSON.stringify(requirements, null, 2))
2518
+ let current = req.query.callback || req.originalUrl
2519
+ res.render("setup", {
2520
+ error,
2521
+ current,
2522
+ install_required,
2523
+ requirements,
2524
+ requirements_pending,
2525
+ logo: this.logo,
2526
+ theme: this.theme,
2527
+ agent: this.agent,
2528
+ })
2529
+ }))
2720
2530
  this.app.get("/network", ex(async (req, res) => {
2531
+ let { requirements, install_required, requirements_pending, error } = await this.kernel.bin.check({
2532
+ bin: this.kernel.bin.preset("network"),
2533
+ })
2534
+ console.log({ requirements, install_required, requirements_pending })
2535
+
2536
+ if (install_required) {
2537
+ res.redirect("/setup/network?callback=/network")
2538
+ return
2539
+ }
2540
+
2721
2541
  let list = this.getPeerInfo()
2722
2542
 
2723
2543
 
@@ -3603,11 +3423,11 @@ class Server {
3603
3423
  }
3604
3424
  res.redirect(webpath)
3605
3425
  }))
3606
- this.app.get("/pinokio/folder/:id", ex(async (req, res) => {
3607
- let folder = this.kernel.proto.kv[req.params.id]
3608
- res.json(folder)
3426
+ this.app.get("/pinokio/prototype/*", ex(async (req, res) => {
3427
+ let id = req.params[0]
3428
+ res.json(this.kernel.proto.kv[id])
3609
3429
  }))
3610
- this.app.post("/pinokio/create_folder", this.upload.any(), ex(async (req, res) => {
3430
+ this.app.post("/pinokio/prototype", this.upload.any(), ex(async (req, res) => {
3611
3431
  try {
3612
3432
  /*
3613
3433
  {
@@ -3625,7 +3445,7 @@ class Server {
3625
3445
  console.log({ formData })
3626
3446
  // 1. instantiate based on id
3627
3447
  let script = this.kernel.proto.kv[formData.id]
3628
- await script.run(this.kernel, formData)
3448
+ await script.create(this.kernel, formData)
3629
3449
  // 2. create pinokio_meta.json
3630
3450
  await this.createMeta(formData)
3631
3451
  res.json({ success: true })
@@ -3908,7 +3728,6 @@ class Server {
3908
3728
 
3909
3729
  }))
3910
3730
  this.app.get("/pinokio/requirements_ready", ex((req, res) => {
3911
-
3912
3731
  let requirements_pending = !this.kernel.bin.installed_initialized
3913
3732
  console.log({ requirements_pending })
3914
3733
  res.json({ requirements_pending })
@@ -3983,7 +3802,6 @@ class Server {
3983
3802
  })
3984
3803
  });
3985
3804
  process.on('SIGINT', () => {
3986
- console.log("[SigInt event] Kill", process.pid)
3987
3805
  //if (this.kernel && this.kernel.shell) {
3988
3806
  // console.log("shell reset")
3989
3807
  // this.kernel.shell.reset(() => {
@@ -3992,7 +3810,12 @@ class Server {
3992
3810
  //} else {
3993
3811
  // process.exit()
3994
3812
  //}
3995
- let map = this.kernel.processes.map || {}
3813
+ console.log("[SigInt event] Kill", process.pid)
3814
+ if (this.kernel.processes.caddy_pid) {
3815
+ console.log("kill caddy", this.kernel.processes.caddy_pid)
3816
+ kill(this.kernel.processes.caddy_pid, "SIGKILL", true)
3817
+ }
3818
+ console.log("kill self")
3996
3819
  kill(process.pid, 'SIGKILL', true)
3997
3820
  //kill(process.pid, map, 'SIGKILL', () => {
3998
3821
  // console.log("child procs killed for", process.pid)
@@ -4001,7 +3824,6 @@ class Server {
4001
3824
  })
4002
3825
 
4003
3826
  process.on('SIGTERM', () => {
4004
- console.log("[Sigterm event] Kill", process.pid)
4005
3827
  // if (this.kernel && this.kernel.shell) {
4006
3828
  // console.log("shell reset")
4007
3829
  // this.kernel.shell.reset(() => {
@@ -4010,6 +3832,12 @@ class Server {
4010
3832
  // } else {
4011
3833
  // process.exit()
4012
3834
  // }
3835
+ console.log("[Sigterm event] Kill", process.pid)
3836
+ if (this.kernel.processes.caddy_pid) {
3837
+ console.log("kill caddy", this.kernel.processes.caddy_pid)
3838
+ kill(this.kernel.processes.caddy_pid, "SIGKILL", true)
3839
+ }
3840
+ console.log("kill self")
4013
3841
  kill(process.pid, 'SIGKILL', true)
4014
3842
  //let map = this.kernel.processes.map || {}
4015
3843
  //kill(process.pid, map, 'SIGKILL', () => {
@@ -99,7 +99,7 @@ const FSCreator = async (config) => {
99
99
  instantUpload: false,
100
100
  server: {
101
101
  process: {
102
- url: '/pinokio/create_folder', // optional if same as above
102
+ url: '/pinokio/prototype', // optional if same as above
103
103
  ondata: (formData) => {
104
104
  // set custom input fields
105
105
  if (config.input) {
@@ -201,9 +201,11 @@ a.ln:hover {
201
201
  }
202
202
  .container-row.current {
203
203
  }
204
+ /*
204
205
  .container-row.current .header-label-sub {
205
206
  color: royalblue;
206
207
  }
208
+ */
207
209
  .desc {
208
210
  /*
209
211
  text-align:center;
@@ -428,7 +430,7 @@ input:checked + .slider:before {
428
430
  <tr>
429
431
  <th><h2>Server</h2><div>Running apps</div></th>
430
432
  <th><h2>Shared</h2><div>Use on any machine on the network</div></th>
431
- <th><h2>Local</h2><div>Use on this machine</div></th>
433
+ <th><h2>Local</h2><div>Use on <%=current_host%></div></th>
432
434
  </tr>
433
435
  <% processes.forEach((item) => { %>
434
436
  <tr>
@@ -415,7 +415,7 @@ document.querySelector(".folder-templates").addEventListener("click", async (e)
415
415
  target = e.target.closest(".folder")
416
416
  }
417
417
  let id = target.getAttribute("data-id")
418
- let res = await fetch("/pinokio/folder/" + id).then((res) => {
418
+ let res = await fetch("/pinokio/prototype/" + id).then((res) => {
419
419
  return res.json()
420
420
  })
421
421
  console.log(res)