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.
@@ -20,9 +20,11 @@ class Caddy {
20
20
  }
21
21
  }
22
22
  async start() {
23
+ // console.log(">> proc", this.kernel.processes.caddy_pid, this.kernel.processes.info)
23
24
  // let running = await this.running()
24
25
  // console.log("Running", running)
25
26
  // if (running) {
27
+ // // kill first
26
28
  // return
27
29
  // }
28
30
  let installed = await this.installed()
@@ -105,12 +107,7 @@ class Caddy {
105
107
  console.log("FINISHED")
106
108
  }
107
109
  async installed() {
108
- // let e = true
109
110
  let e = await this.kernel.exists(this.kernel.path("cache/XDG_DATA_HOME/caddy/pki/authorities/local/root.crt"))
110
- // let exists = await this.kernel.exists(this.kernel.path("cache/XDG_DATA_HOME/caddy/certificates/local/pinokio.localhost/pinokio.localhost.crt"))
111
- // let exists2 = await this.kernel.exists(this.kernel.path("cache/XDG_DATA_HOME/caddy/certificates/local/pinokio.localhost/pinokio.localhost.key"))
112
- // if (exists && exists2) {
113
- console.log("checking installed", e)
114
111
  if (e) {
115
112
  if (this.kernel.platform === "win32") {
116
113
  return this.kernel.bin.installed.conda.has("caddy")
@@ -122,9 +119,13 @@ class Caddy {
122
119
  }
123
120
  }
124
121
  async uninstall(req, ondata) {
122
+ ondata({ raw: "cleaning up\r\n" })
125
123
  await this.kernel.bin.exec({
126
124
  message: `conda remove ${this.cmd()}`,
127
125
  }, ondata)
126
+ const folder = this.kernel.path("cache/XDG_DATA_HOME/caddy")
127
+ await rimraf(folder)
128
+ ondata({ raw: "finished cleaning up\r\n" })
128
129
  }
129
130
  }
130
131
  module.exports = Caddy
@@ -253,8 +253,12 @@ report_errors: false`)
253
253
  // 2. The pinned file says conda-libmamba-solver=24.11.1
254
254
  // 3. so after conda update --all, it should be conda-libmamba-solver=24.11.1
255
255
 
256
+ console.log({ req })
257
+
258
+
256
259
  let mods = this.kernel.bin.mods.filter((m) => {
257
- return ["zip", "uv", "node", "huggingface", "gxx", "git", "ffmpeg", "caddy"].includes(m.name)
260
+ return req.dependencies.includes(m.name)
261
+ // return ["zip", "uv", "node", "huggingface", "gxx", "git", "ffmpeg", "caddy"].includes(m.name)
258
262
  }).map((m) => {
259
263
  return m.mod.cmd()
260
264
  }).join(" ")
@@ -28,6 +28,7 @@ const semver = require('semver')
28
28
  const Environment = require('../environment')
29
29
  //const imageToAscii = require("image-to-ascii");
30
30
 
31
+ const Setup = require('./setup')
31
32
 
32
33
 
33
34
  //const Puppet = require("./puppeteer")
@@ -440,33 +441,6 @@ class Bin {
440
441
  }
441
442
  }
442
443
 
443
- // // 2. pip
444
- // let pip = new Set()
445
- // if (conda_exists) {
446
- // // conda comes with pip
447
- // console.log("## check pip")
448
- // start = false
449
- // res = await this.exec({ message: `pip list` }, (stream) => {
450
- //// console.log("pip list check", { stream })
451
- // })
452
- // console.log("PIP", res.response)
453
- // lines = res.response.split(/[\r\n]+/)
454
- // for(let line of lines) {
455
- // if (start) {
456
- // let chunks = line.split(/\s+/).filter(x => x)
457
- // if (chunks.length > 1) {
458
- // pip.add(chunks[0])
459
- // }
460
- // } else {
461
- // if (/-------.*/i.test(line)) {
462
- // start = true
463
- // }
464
- // }
465
- // }
466
- // }
467
- // this.installed.pip = pip
468
-
469
-
470
444
  if (this.platform === "darwin") {
471
445
  // 3. brew
472
446
  console.log("## check brew")
@@ -668,7 +642,9 @@ class Bin {
668
642
  }
669
643
  }
670
644
  async install2(req, ondata) {
671
- let { requirements, install_required, requirements_pending, error } = await this.check_bin()
645
+ let { requirements, install_required, requirements_pending, error } = await this.check({
646
+ bin: this.preset("ai")
647
+ })
672
648
  req.params = JSON.stringify(requirements)
673
649
  console.log(">>>>> 1")
674
650
  if (this.install_required) {
@@ -678,6 +654,7 @@ class Bin {
678
654
  }
679
655
  }
680
656
  async install(req, ondata) {
657
+ console.time("kernel.bin.install")
681
658
  /*
682
659
  req.params := {
683
660
  client: {
@@ -778,23 +755,35 @@ class Bin {
778
755
  console.log(">>> shell reset")
779
756
  this.kernel.shell.reset()
780
757
  }
758
+ console.timeEnd("kernel.bin.install")
781
759
  await this.init()
782
760
  }
783
- async installed(r) {
761
+ async check_installed(r, dependencies) {
784
762
  if (Array.isArray(r.name)) {
785
763
  for(let name of r.name) {
786
- let installed = await this._installed(name, r.type)
764
+ let installed = await this._installed(name, r.type, dependencies)
787
765
  if (!installed) return false
788
766
  }
789
767
  return true
790
768
  } else {
791
- let installed = await this._installed(r.name, r.type)
769
+ let installed = await this._installed(r.name, r.type, dependencies)
792
770
  return installed
793
771
  }
794
772
  }
795
- async _installed(name, type) {
773
+ async _installed(name, type, dependencies) {
796
774
  if (type === "conda") {
797
- return this.installed.conda.has(name)
775
+ let conda_installed = this.installed.conda.has(name)
776
+ console.log({ dependencies })
777
+ let dependencies_installed = true
778
+ for(let d of dependencies) {
779
+ console.log("checking dependency", d)
780
+ if(!this.installed.conda.has(d)) {
781
+ dependencies_installed = false
782
+ console.log("not installed", d)
783
+ break
784
+ }
785
+ }
786
+ return conda_installed && dependencies_installed
798
787
  } else if (type === "pip") {
799
788
  return this.installed.pip && this.installed.pip.has(name)
800
789
  } else if (type === "brew") {
@@ -810,50 +799,234 @@ class Bin {
810
799
  return installed
811
800
  }
812
801
  }
813
- async check_bin() {
814
- let requirements = [
815
- { name: "conda", },
816
- { name: "git", },
817
- { name: "zip", },
818
- { name: "node", },
819
- { name: "ffmpeg", },
820
- { name: "caddy", }
821
- ]
802
+ preset(mode) {
803
+ return Setup[mode](this.kernel)
804
+ }
805
+ requirements(config) {
806
+ let requirements = config.bin.requirements
807
+ // let requirements = [
808
+ // { name: "conda", },
809
+ // { name: "git", },
810
+ //// { name: "zip", },
811
+ // { name: "node", },
812
+ // { name: "ffmpeg", },
813
+ // { name: "caddy", }
814
+ // ]
815
+ // let platform = os.platform()
816
+ // if (platform === "win32") {
817
+ // requirements.push({ name: "registry" })
818
+ // requirements.push({ name: "vs" })
819
+ // }
820
+ // if (platform === "darwin") {
821
+ // requirements.push({ name: "brew" })
822
+ // }
823
+ // if (platform === "linux") {
824
+ // requirements.push({ name: "gxx" })
825
+ // }
826
+ // if (this.kernel.gpu === "nvidia") {
827
+ // requirements.push({ name: "cuda", })
828
+ // }
829
+ // requirements = requirements.concat([
830
+ // { name: "cloudflared" },
831
+ //// { name: "playwright" },
832
+ // { name: "huggingface" },
833
+ // { name: "uv" },
834
+ // { name: "py" },
835
+ // ])
836
+ if (config.script && config.script.requires && config.script.requires.length > 0) {
837
+ /*********************************************************************
838
+
839
+ {
840
+ requires: [{
841
+ platform,
842
+ type,
843
+ name,
844
+ args
845
+ }, {
846
+ platform,
847
+ type,
848
+ name,
849
+ args
850
+ }],
851
+ run: [{
852
+ ...
853
+ }]
854
+ }
855
+
856
+ syntax :=
857
+
858
+ {
859
+ platform: <win32|darwin|linux>,
860
+ type: <conda|pip|brew|none>,
861
+ name: <package name>, (example: "ffmpeg", "git")
862
+ args: <install command flags> (example: "-c conda-forge")
863
+ }
864
+
865
+
866
+ 1. pinokio native install: no need for specifying platforms since they are included
867
+
868
+ {
869
+ name: "conda"
870
+ }
871
+
872
+
873
+ 2. non native install (conda, pip, brew)
874
+
875
+ 2.1. Same on all platforms
876
+
877
+ [{
878
+ type: "conda",
879
+ name: "ffmpeg",
880
+ args: "-c conda-forge"
881
+ }]
882
+
883
+ 2.2. Specify per platform
884
+
885
+
886
+ [
887
+ { name: "conda" },
888
+ { platform: "darwin", type: "brew", name: "llvm" },
889
+ { platform: "linux", tyoe: "conda", name: "llvm", args: "-c conda-forge llvm" },
890
+ { platform: "win32", tyoe: "conda", name: "llvm", args: "-c conda-forge llvm" }
891
+ ]
892
+
893
+ [
894
+ { name: "conda" },
895
+ { platform: ["darwin", "linux"], type: "brew", name: "llvm" },
896
+ { platform: "win32", tyoe: "conda", name: "llvm", args: "-c conda-forge llvm" }
897
+ ]
898
+
899
+
900
+
901
+ *********************************************************************/
902
+ let type_name_set = new Set()
903
+ for(let r of config.script.requires) {
904
+ // if no platform specified, or if the specified platform matches the current platform
905
+ if (!r.platform || platform === r.platform || Array.isArray(r.platform) && r.platform.includes(platform) ) {
906
+ if (Array.isArray(r.name)) {
907
+ // if array, just add it
908
+ requirements.push(r)
909
+ } else {
910
+ let type_name = `${r.type ? r.type : ''}/${r.name}`
911
+ if (!type_name_set.has(type_name)) {
912
+ type_name_set.add(type_name)
913
+ requirements.push(r)
914
+ }
915
+ }
916
+ }
917
+ }
918
+
919
+ }
920
+ return requirements
921
+ }
922
+ relevant(r) {
923
+ /*
924
+ single platform
925
+ [
926
+ { name: "conda" },
927
+ { platform: "darwin", type: "brew", name: "llvm" },
928
+ { platform: "linux", tyoe: "conda", name: "llvm", args: "-c conda-forge llvm" },
929
+ { platform: "win32", tyoe: "conda", name: "llvm", args: "-c conda-forge llvm" }
930
+ ]
931
+
932
+ multiple platforms
933
+ [
934
+ { name: "conda" },
935
+ { platform: ["darwin", "linux"], type: "brew", name: "llvm" },
936
+ { platform: "win32", tyoe: "conda", name: "llvm", args: "-c conda-forge llvm" }
937
+ ]
938
+
939
+
940
+ platform & arch
941
+ [
942
+ { name: "conda" },
943
+ { platform: "darwin", arch: ["arm64", "x64"], type: "brew", name: "llvm" },
944
+ ]
945
+ */
946
+
822
947
  let platform = os.platform()
823
- if (platform === "win32") {
824
- requirements.push({ name: "registry" })
825
- requirements.push({ name: "vs" })
948
+ let arch = os.arch()
949
+ let gpu = this.kernel.gpu
950
+ let relevant = {
951
+ platform: false,
952
+ arch: false,
953
+ gpu: false,
826
954
  }
827
- if (platform === "darwin") {
828
- requirements.push({ name: "brew" })
955
+ if (r.platform) {
956
+ if (Array.isArray(r.platform)) {
957
+ // multiple items
958
+ if (r.platform.includes(platform)) {
959
+ relevant.platform = true
960
+ }
961
+ } else {
962
+ // one item
963
+ if (r.platform === platform) {
964
+ relevant.platform = true
965
+ }
966
+ }
967
+ } else {
968
+ // all platforms
969
+ relevant.platform = true
829
970
  }
830
- if (platform === "linux") {
831
- requirements.push({ name: "gxx" })
971
+ if (r.arch) {
972
+ if (Array.isArray(r.arch)) {
973
+ // multiple items
974
+ if (r.arch.includes(arch)) {
975
+ relevant.arch = true
976
+ }
977
+ } else {
978
+ // one item
979
+ if (r.arch === arch) {
980
+ relevant.arch = true
981
+ }
982
+ }
983
+ } else {
984
+ // all platforms
985
+ relevant.arch = true
832
986
  }
833
- if (this.kernel.gpu === "nvidia") {
834
- requirements.push({ name: "cuda", })
987
+ if (r.gpu) {
988
+ if (Array.isArray(r.gpu)) {
989
+ // multiple items
990
+ if (r.gpu.includes(gpu)) {
991
+ relevant.gpu = true
992
+ }
993
+ } else {
994
+ // one item
995
+ if (r.gpu === gpu) {
996
+ relevant.gpu = true
997
+ }
998
+ }
999
+ } else {
1000
+ // all platforms
1001
+ relevant.gpu = true
835
1002
  }
836
- requirements = requirements.concat([
837
- { name: "cloudflared" },
838
- // { name: "playwright" },
839
- { name: "huggingface" },
840
- { name: "uv" },
841
- { name: "py" },
842
- ])
843
-
1003
+ return relevant.platform && relevant.arch && relevant.gpu
1004
+ }
1005
+ async check(config) {
1006
+ let requirements = this.requirements(config)
844
1007
  let requirements_pending = !this.installed_initialized
845
1008
  let install_required = true
846
1009
  if (!requirements_pending) {
847
1010
  install_required = false
848
1011
  for(let i=0; i<requirements.length; i++) {
849
1012
  let r = requirements[i]
850
- console.time(r.name)
851
- let installed = await this.installed(r)
852
- console.log({ r, installed })
853
- console.timeEnd(r.name)
854
- requirements[i].installed = installed
855
- if (!installed) {
856
- install_required = true
1013
+ //let installed = await this.installed(r)
1014
+ //requirements[i].installed = installed
1015
+ //if (!installed) {
1016
+ // install_required = true
1017
+ //}
1018
+ let relevant = this.relevant(r)
1019
+ requirements[i].relevant = relevant
1020
+ if (relevant) {
1021
+ let dependencies
1022
+ if (r.name === "conda") {
1023
+ dependencies = config.bin.conda_requirements
1024
+ }
1025
+ let installed = await this.check_installed(r, dependencies)
1026
+ requirements[i].installed = installed
1027
+ if (!installed) {
1028
+ install_required = true
1029
+ }
857
1030
  }
858
1031
  }
859
1032
  }
@@ -870,6 +1043,11 @@ class Bin {
870
1043
  this.requirements_pending = requirements_pending
871
1044
 
872
1045
  console.log("check_bin finished 2")
1046
+
1047
+ requirements = requirements.filter((r) => {
1048
+ return r.relevant
1049
+ })
1050
+
873
1051
  return {
874
1052
  error,
875
1053
  requirements,
@@ -0,0 +1,130 @@
1
+ const os = require('os')
2
+ let platform = os.platform()
3
+ module.exports = {
4
+ ai: (kernel) => {
5
+ let conda_requirements = [
6
+ "uv",
7
+ "node",
8
+ "huggingface",
9
+ "git",
10
+ "ffmpeg",
11
+ // "caddy"
12
+ ]
13
+ let requirements = [
14
+ { name: "conda", },
15
+ { name: "git", },
16
+ // { name: "zip", },
17
+ { name: "node", },
18
+ { name: "ffmpeg", },
19
+ // { name: "caddy", }
20
+ ]
21
+ if (platform === "win32") {
22
+ requirements.push({ name: "registry" })
23
+ requirements.push({ name: "vs" })
24
+ }
25
+ if (platform === "darwin") {
26
+ requirements.push({ name: "brew" })
27
+ }
28
+ if (platform === "linux") {
29
+ requirements.push({ name: "gxx" })
30
+ conda_requirements.push("gxx")
31
+ }
32
+ if (kernel.gpu === "nvidia") {
33
+ requirements.push({ name: "cuda", })
34
+ conda_requirements.push("cuda")
35
+ }
36
+ requirements = requirements.concat([
37
+ { name: "cloudflared" },
38
+ // { name: "playwright" },
39
+ { name: "huggingface" },
40
+ { name: "uv" },
41
+ { name: "py" },
42
+ ])
43
+ return {
44
+ icon: "fa-solid fa-brain",
45
+ title: "AI",
46
+ description: "Install common modules required for running AI locally",
47
+ requirements,
48
+ conda_requirements
49
+ }
50
+ },
51
+ javascript: (kernel) => {
52
+ return {
53
+ icon: "fa-brands fa-js",
54
+ title: "Node.js",
55
+ description: "Set up self-contained node.js development environment",
56
+ requirements: [
57
+ { name: "conda", },
58
+ { name: "git", },
59
+ { name: "node", },
60
+ ],
61
+ conda_requirements: [
62
+ "node",
63
+ "git",
64
+ ]
65
+ }
66
+ },
67
+ python: (kernel) => {
68
+ return {
69
+ icon: "fa-brands fa-python",
70
+ title: "Python",
71
+ description: "Set up self-contained python development environment",
72
+ requirements: [
73
+ { name: "conda", },
74
+ { name: "git", },
75
+ { name: "uv", },
76
+ ],
77
+ conda_requirements: [
78
+ "uv",
79
+ "git",
80
+ ]
81
+ }
82
+ },
83
+ dev: (kernel) => {
84
+ let requirements = [
85
+ { name: "conda", },
86
+ { name: "git", },
87
+ { name: "node", },
88
+ { name: "uv", },
89
+ ]
90
+ let conda_requirements = [
91
+ "uv",
92
+ "node",
93
+ "git",
94
+ ]
95
+ if (platform === "win32") {
96
+ requirements.push({ name: "registry" })
97
+ requirements.push({ name: "vs" })
98
+ }
99
+ if (platform === "darwin") {
100
+ requirements.push({ name: "brew" })
101
+ }
102
+ if (platform === "linux") {
103
+ requirements.push({ name: "gxx" })
104
+ conda_requirements.push("gxx")
105
+ }
106
+ return {
107
+ icon: "fa-solid fa-laptop-code",
108
+ title: "Coding",
109
+ description: "Install common modules required for development (Node.js, python, Visual Studio Developer Tools (Windows), Xcode build tools (Mac)",
110
+ requirements,
111
+ conda_requirements,
112
+ }
113
+ },
114
+ network: (kernel) => {
115
+ return {
116
+ icon: "fa-solid fa-wifi",
117
+ title: "Network",
118
+ description: "Automatic HTTPS and local network sharing for ALL local apps",
119
+ requirements: [
120
+ { name: "conda", },
121
+ { name: "git", },
122
+ { name: "caddy", },
123
+ ],
124
+ conda_requirements: [
125
+ "git",
126
+ "caddy"
127
+ ]
128
+ }
129
+ }
130
+ }
@@ -439,4 +439,39 @@ const get_raw = async (homedir) => {
439
439
  }
440
440
  return current_env
441
441
  }
442
- module.exports = { ENV, get, get2, init_folders }
442
+
443
+ const requirements = async (script, filepath, kernel) => {
444
+ let pre_items = []
445
+ let requires_instantiation = false
446
+ if (script && script.pre) {
447
+ let env = await get2(filepath, kernel)
448
+ for(let item of script.pre) {
449
+ if (item.env) {
450
+
451
+ if (!item.index) {
452
+ item.index = 0
453
+ }
454
+ if (item.key) {
455
+ const hasProtocol = /^[a-zA-Z][a-zA-Z\d+\-.]*:\/\//.test(item.key);
456
+ const url = new URL(hasProtocol ? item.key : `https://${item.key}`);
457
+ item.host = url.host
458
+ item.val = await kernel.kv.get(item.host, item.index)
459
+ } else {
460
+ item.host = ""
461
+ }
462
+
463
+ if (env[item.env]) {
464
+ item.val = env[item.env]
465
+ } else {
466
+ if (item.default) {
467
+ item.val = item.default
468
+ }
469
+ requires_instantiation = true
470
+ }
471
+ pre_items.push(item)
472
+ }
473
+ }
474
+ }
475
+ return { items: pre_items, requires_instantiation }
476
+ }
477
+ module.exports = { ENV, get, get2, init_folders, requirements }
package/kernel/index.js CHANGED
@@ -271,31 +271,45 @@ class Kernel {
271
271
 
272
272
  // 1. get the process list
273
273
  // console.log("Step 1: Get process list")
274
+ console.log("> 1")
274
275
  await this.processes.refresh()
275
276
  // console.log("Process info", this.processes.info)
276
277
 
278
+ console.log("> 2")
279
+
277
280
  // 2. refresh peer info to reflect the proc info
278
281
  await this.peer.refresh()
279
282
 
283
+
284
+ console.log("> 3")
285
+ // 3. load custom routers from ~/pinokio/network
286
+ await this.router.init()
287
+
288
+ console.log("> 4")
280
289
  // 3. set current local host router info
281
290
  // console.log("Step 3: Set current local host router")
282
291
  await this.router.local()
283
292
  // console.log("router mapping after step 3", this.router.info)
284
293
 
294
+ console.log("> 5")
285
295
  // 4. refresh peer info to reflect the updated router info
286
296
  await this.peer.refresh()
287
297
 
298
+ console.log("> 6")
288
299
  // 4. tell peers to refresh
289
300
  if (notify_peers) {
290
301
  // console.log("Step 4: notify peers to refresh")
302
+ console.log("> 7")
291
303
  await this.peer.notify_peers()
292
304
  }
293
305
 
306
+ console.log("> 8")
294
307
  // 4. update remote router
295
308
  // console.log("Step 5: Set remote routers")
296
309
  await this.router.remote()
297
310
  // console.log("router mapping after step 5", this.router.info)
298
311
 
312
+ console.log("> 9")
299
313
  await this.router.update()
300
314
 
301
315
 
@@ -668,10 +682,8 @@ class Kernel {
668
682
  this.bin.init().then(() => {
669
683
  if (this.homedir) {
670
684
  this.shell.init().then(async () => {
671
- this.bin.check_bin()
672
- console.log(">>>> 1")
685
+ // this.bin.check()
673
686
  if (this.envs) {
674
- console.log(">>>> 2")
675
687
  this.template.update({
676
688
  env: this.envs,
677
689
  envs: this.envs,
@@ -720,7 +732,6 @@ class Kernel {
720
732
  }
721
733
  }
722
734
  }
723
- console.log(">>>>>> d")
724
735
  clearInterval(interval)
725
736
  setTimeout(() => {
726
737
  this.launch_complete = true