pinokiod 3.6.29 → 3.6.30
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/api/index.js +97 -26
- package/kernel/bin/index.js +127 -4
- package/kernel/bin/node.js +5 -0
- package/kernel/index.js +39 -1
- package/kernel/shell.js +34 -16
- package/kernel/shells.js +1 -0
- package/kernel/store.js +58 -0
- package/kernel/sysinfo.js +22 -12
- package/kernel/util.js +28 -7
- package/package.json +1 -1
- package/script/index.js +12 -0
- package/server/index.js +270 -187
- package/server/public/pinokio-black.png +0 -0
- package/server/public/pinokio-black2.png +0 -0
- package/server/public/style.css +5 -0
- package/server/socket.js +87 -34
- package/server/views/app.ejs +14 -2
- package/server/views/editor.ejs +12 -2
- package/server/views/index.ejs +27 -36
- package/server/views/terminal.ejs +56 -12
package/kernel/api/index.js
CHANGED
|
@@ -121,8 +121,10 @@ class Api {
|
|
|
121
121
|
async stop(req, ondata) {
|
|
122
122
|
// 1. set the "stop" flag for the uri, so the next execution in the queue for the uri will NOT queue another task
|
|
123
123
|
// 2. stream a message closing the socket
|
|
124
|
+
console.log("> stop", req)
|
|
124
125
|
|
|
125
126
|
let requestPath = this.filePath(req.params.uri)
|
|
127
|
+
console.log({ requestPath })
|
|
126
128
|
|
|
127
129
|
|
|
128
130
|
|
|
@@ -352,13 +354,20 @@ class Api {
|
|
|
352
354
|
let modpath
|
|
353
355
|
if (matched_repo.length > 0) {
|
|
354
356
|
let repo_uri = matched_repo[0]
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
.slice(1) // remove the leading '/' for relative path
|
|
357
|
+
if (!repo_uri.endsWith(".git")) {
|
|
358
|
+
repo_uri = repo_uri + ".git"
|
|
359
|
+
}
|
|
359
360
|
|
|
360
361
|
let repopath = this.gitPath[repo_uri]
|
|
361
|
-
|
|
362
|
+
if (uri === repo_uri) {
|
|
363
|
+
modpath = path.resolve(repopath)
|
|
364
|
+
} else {
|
|
365
|
+
let relative_path = uri
|
|
366
|
+
.replace(repo_uri, "") // remove the git repo uri
|
|
367
|
+
.slice(1) // remove the leading '/' for relative path
|
|
368
|
+
modpath = path.resolve(repopath, relative_path)
|
|
369
|
+
}
|
|
370
|
+
|
|
362
371
|
} else {
|
|
363
372
|
//console.log("no matching gitpath")
|
|
364
373
|
}
|
|
@@ -568,9 +577,13 @@ class Api {
|
|
|
568
577
|
}
|
|
569
578
|
async step (request, rawrpc, input, i, total, args) {
|
|
570
579
|
|
|
571
|
-
await this.init
|
|
580
|
+
await Promise.all([this.init, this.kernel.update_sysinfo])
|
|
572
581
|
|
|
573
|
-
await this.
|
|
582
|
+
// await this.init()
|
|
583
|
+
//
|
|
584
|
+
// console.time("api.update_sysinfo")
|
|
585
|
+
// await this.kernel.update_sysinfo()
|
|
586
|
+
// console.timeEnd("api.update_sysinfo")
|
|
574
587
|
|
|
575
588
|
// clear global regular expression object RegExp.lastMatch (memory leak prevention)
|
|
576
589
|
let r = /\s*/g.exec("");
|
|
@@ -818,6 +831,7 @@ class Api {
|
|
|
818
831
|
// }
|
|
819
832
|
this.ondata(m)
|
|
820
833
|
})
|
|
834
|
+
console.log("EXEC RESULT", { result })
|
|
821
835
|
}
|
|
822
836
|
|
|
823
837
|
|
|
@@ -1122,6 +1136,35 @@ class Api {
|
|
|
1122
1136
|
this.process(request, resolve)
|
|
1123
1137
|
})
|
|
1124
1138
|
}
|
|
1139
|
+
async get_default(repo_path) {
|
|
1140
|
+
let p = path.resolve(repo_path, "pinokio.js")
|
|
1141
|
+
// call 'process' based on the current status
|
|
1142
|
+
let config = (await this.loader.load(p)).resolved
|
|
1143
|
+
if (config && config.menu) {
|
|
1144
|
+
if (typeof config.menu === "function") {
|
|
1145
|
+
if (config.menu.constructor.name === "AsyncFunction") {
|
|
1146
|
+
config.menu = await config.menu(this.kernel, this.kernel.info)
|
|
1147
|
+
} else {
|
|
1148
|
+
config.menu = config.menu(this.kernel, this.kernel.info)
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
// find the default item in the menu
|
|
1152
|
+
let running = config.menu.filter((item) => {
|
|
1153
|
+
return item.default
|
|
1154
|
+
})
|
|
1155
|
+
if (running.length > 0) {
|
|
1156
|
+
let r = running[0]
|
|
1157
|
+
if (r.href) {
|
|
1158
|
+
if (r.href.startsWith("http")) {
|
|
1159
|
+
return r.href
|
|
1160
|
+
} else {
|
|
1161
|
+
let href = path.resolve(repo_path, r.href)
|
|
1162
|
+
return href
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1125
1168
|
async process(request, done) {
|
|
1126
1169
|
/**************************************************************
|
|
1127
1170
|
*
|
|
@@ -1163,41 +1206,69 @@ class Api {
|
|
|
1163
1206
|
// this.kernel.keys = (await this.loader.load(keypath)).resolved
|
|
1164
1207
|
|
|
1165
1208
|
// init shell before running just to make sure the environment variables are fresh
|
|
1209
|
+
console.time("shell.init")
|
|
1166
1210
|
await this.kernel.shell.init()
|
|
1211
|
+
console.timeEnd("shell.init")
|
|
1167
1212
|
|
|
1168
1213
|
if (request.uri){
|
|
1214
|
+
|
|
1169
1215
|
this.counter++;
|
|
1170
1216
|
// API Call
|
|
1171
1217
|
|
|
1172
1218
|
request.path = this.resolvePath(this.userdir, request.uri)
|
|
1173
|
-
let { cwd, script } = await this.resolveScript(request.path)
|
|
1174
|
-
request.cwd = cwd
|
|
1175
1219
|
|
|
1176
|
-
if (!script) {
|
|
1177
|
-
this.ondata({
|
|
1178
|
-
id: request.path,
|
|
1179
|
-
type: "error",
|
|
1180
|
-
data: "the endpoint does not exist: " + request.uri,
|
|
1181
|
-
})
|
|
1182
|
-
} else {
|
|
1183
|
-
// 3. Check if the resolved endpoint has the "run" attribute and it's an array
|
|
1184
|
-
//if (script.run && Array.isArray(script.run)) {
|
|
1185
|
-
if (script.run) {
|
|
1186
|
-
|
|
1187
|
-
this.running[request.path] = true
|
|
1188
|
-
|
|
1189
|
-
this.done[request.path] = done
|
|
1190
|
-
|
|
1191
|
-
this.queue(request, script.run[0], request.input, 0, script.run.length, cwd, request.input)
|
|
1192
1220
|
|
|
1221
|
+
// if the path is
|
|
1222
|
+
let relative = path.relative(this.kernel.homedir, request.path)
|
|
1223
|
+
let chunks = relative.split(path.sep)
|
|
1224
|
+
console.log({ chunks })
|
|
1225
|
+
if (chunks.length == 2) {
|
|
1226
|
+
// the script is requesting a uri of the git repo
|
|
1227
|
+
// look for pinokio.js
|
|
1228
|
+
let p = path.resolve(request.path, "pinokio.js")
|
|
1229
|
+
let exists = await this.exists(p)
|
|
1230
|
+
console.log({ p, exists })
|
|
1231
|
+
if (exists) {
|
|
1232
|
+
await this.launch(request, p)
|
|
1193
1233
|
} else {
|
|
1194
1234
|
this.ondata({
|
|
1195
1235
|
id: request.path,
|
|
1196
1236
|
type: "error",
|
|
1197
|
-
data: "
|
|
1237
|
+
data: "uri doesn't exist \r\n" + JSON.stringify(request, null, 2)
|
|
1198
1238
|
})
|
|
1199
1239
|
}
|
|
1240
|
+
} else {
|
|
1241
|
+
console.log({ request })
|
|
1242
|
+
let { cwd, script } = await this.resolveScript(request.path)
|
|
1243
|
+
request.cwd = cwd
|
|
1244
|
+
|
|
1245
|
+
if (!script) {
|
|
1246
|
+
this.ondata({
|
|
1247
|
+
id: request.path,
|
|
1248
|
+
type: "error",
|
|
1249
|
+
data: "the endpoint does not exist: " + request.uri,
|
|
1250
|
+
})
|
|
1251
|
+
} else {
|
|
1252
|
+
// 3. Check if the resolved endpoint has the "run" attribute and it's an array
|
|
1253
|
+
//if (script.run && Array.isArray(script.run)) {
|
|
1254
|
+
if (script.run) {
|
|
1255
|
+
|
|
1256
|
+
this.running[request.path] = true
|
|
1257
|
+
|
|
1258
|
+
this.done[request.path] = done
|
|
1259
|
+
|
|
1260
|
+
this.queue(request, script.run[0], request.input, 0, script.run.length, cwd, request.input)
|
|
1261
|
+
|
|
1262
|
+
} else {
|
|
1263
|
+
this.ondata({
|
|
1264
|
+
id: request.path,
|
|
1265
|
+
type: "error",
|
|
1266
|
+
data: "missing attribute: run"
|
|
1267
|
+
})
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1200
1270
|
}
|
|
1271
|
+
|
|
1201
1272
|
} else if (request.method) {
|
|
1202
1273
|
let pass = 0;
|
|
1203
1274
|
while(true) {
|
package/kernel/bin/index.js
CHANGED
|
@@ -588,6 +588,24 @@ class Bin {
|
|
|
588
588
|
}
|
|
589
589
|
// }
|
|
590
590
|
}
|
|
591
|
+
async path_exists(req, ondata) {
|
|
592
|
+
let abspath = this.kernel.api.resolvePath(this.kernel.api.userdir, req.params.uri)
|
|
593
|
+
if (abspath) {
|
|
594
|
+
console.log({ abspath })
|
|
595
|
+
let exists = await new Promise(r=>fs.access(abspath, fs.constants.F_OK, e => r(!e)))
|
|
596
|
+
return exists
|
|
597
|
+
} else {
|
|
598
|
+
return false
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
async install2(req, ondata) {
|
|
602
|
+
let { requirements, install_required, requirements_pending, error } = await this.check_bin()
|
|
603
|
+
req.params = JSON.stringify(requirements)
|
|
604
|
+
if (this.install_required) {
|
|
605
|
+
let res = await this.install(req, ondata)
|
|
606
|
+
return res
|
|
607
|
+
}
|
|
608
|
+
}
|
|
591
609
|
async install(req, ondata) {
|
|
592
610
|
/*
|
|
593
611
|
req.params := {
|
|
@@ -607,6 +625,8 @@ class Bin {
|
|
|
607
625
|
this.client = null
|
|
608
626
|
}
|
|
609
627
|
|
|
628
|
+
console.log("install", req)
|
|
629
|
+
|
|
610
630
|
let requirements = JSON.parse(req.params)
|
|
611
631
|
|
|
612
632
|
for(let x=0; x<10; x++) {
|
|
@@ -680,17 +700,29 @@ class Bin {
|
|
|
680
700
|
//}
|
|
681
701
|
await this.init()
|
|
682
702
|
}
|
|
703
|
+
async installed(r) {
|
|
704
|
+
if (Array.isArray(r.name)) {
|
|
705
|
+
for(let name of r.name) {
|
|
706
|
+
let installed = await this._installed(name, r.type)
|
|
707
|
+
if (!installed) return false
|
|
708
|
+
}
|
|
709
|
+
return true
|
|
710
|
+
} else {
|
|
711
|
+
let installed = await this._installed(r.name, r.type)
|
|
712
|
+
return installed
|
|
713
|
+
}
|
|
714
|
+
}
|
|
683
715
|
async _installed(name, type) {
|
|
684
716
|
if (type === "conda") {
|
|
685
|
-
return this.
|
|
717
|
+
return this.installed.conda.has(name)
|
|
686
718
|
} else if (type === "pip") {
|
|
687
|
-
return this.
|
|
719
|
+
return this.installed.pip && this.installed.pip.has(name)
|
|
688
720
|
} else if (type === "brew") {
|
|
689
|
-
return this.
|
|
721
|
+
return this.installed.brew.has(name)
|
|
690
722
|
} else {
|
|
691
723
|
// check kernel/bin/<module>.installed()
|
|
692
724
|
let filepath = path.resolve(__dirname, "..", "kernel", "bin", name + ".js")
|
|
693
|
-
let mod = this.
|
|
725
|
+
let mod = this.mod[name]
|
|
694
726
|
let installed = false
|
|
695
727
|
if (mod.installed) {
|
|
696
728
|
installed = await mod.installed()
|
|
@@ -698,6 +730,97 @@ class Bin {
|
|
|
698
730
|
return installed
|
|
699
731
|
}
|
|
700
732
|
}
|
|
733
|
+
async check_bin() {
|
|
734
|
+
let requirements = [
|
|
735
|
+
{ name: "conda", },
|
|
736
|
+
{ name: "git", },
|
|
737
|
+
{ name: "zip", },
|
|
738
|
+
{ name: "node", },
|
|
739
|
+
{ name: "ffmpeg", }
|
|
740
|
+
]
|
|
741
|
+
let platform = os.platform()
|
|
742
|
+
if (platform === "win32") {
|
|
743
|
+
requirements.push({ name: "registry" })
|
|
744
|
+
requirements.push({ name: "vs" })
|
|
745
|
+
}
|
|
746
|
+
if (platform === "darwin") {
|
|
747
|
+
requirements.push({ name: "brew" })
|
|
748
|
+
}
|
|
749
|
+
if (platform === "linux") {
|
|
750
|
+
requirements.push({ name: "gxx" })
|
|
751
|
+
}
|
|
752
|
+
if (this.kernel.gpu === "nvidia") {
|
|
753
|
+
requirements.push({ name: "cuda", })
|
|
754
|
+
}
|
|
755
|
+
requirements = requirements.concat([
|
|
756
|
+
{ name: "py" },
|
|
757
|
+
{ name: "cloudflared" },
|
|
758
|
+
{ name: "playwright" },
|
|
759
|
+
{ name: "huggingface" },
|
|
760
|
+
{ name: "uv" }
|
|
761
|
+
])
|
|
762
|
+
|
|
763
|
+
let requirements_pending = !this.installed_initialized
|
|
764
|
+
let install_required = true
|
|
765
|
+
if (!requirements_pending) {
|
|
766
|
+
install_required = false
|
|
767
|
+
for(let i=0; i<requirements.length; i++) {
|
|
768
|
+
let r = requirements[i]
|
|
769
|
+
console.time(r.name)
|
|
770
|
+
let installed = await this.installed(r)
|
|
771
|
+
console.log({ r, installed })
|
|
772
|
+
console.timeEnd(r.name)
|
|
773
|
+
requirements[i].installed = installed
|
|
774
|
+
if (!installed) {
|
|
775
|
+
install_required = true
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
let error = null
|
|
781
|
+
try {
|
|
782
|
+
this.compatible()
|
|
783
|
+
} catch (e) {
|
|
784
|
+
error = e.message
|
|
785
|
+
install_required = true
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
this.install_required = install_required
|
|
789
|
+
this.requirements_pending = requirements_pending
|
|
790
|
+
|
|
791
|
+
console.log("check_bin finished 2")
|
|
792
|
+
return {
|
|
793
|
+
error,
|
|
794
|
+
requirements,
|
|
795
|
+
install_required,
|
|
796
|
+
requirements_pending
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
}
|
|
800
|
+
winBuildNumber() {
|
|
801
|
+
let osVersion = (/(\d+)\.(\d+)\.(\d+)/g).exec(os.release());
|
|
802
|
+
let buildNumber = 0;
|
|
803
|
+
if (osVersion && osVersion.length === 4) {
|
|
804
|
+
buildNumber = parseInt(osVersion[3]);
|
|
805
|
+
}
|
|
806
|
+
return buildNumber;
|
|
807
|
+
}
|
|
808
|
+
compatible() {
|
|
809
|
+
if (this.kernel.platform === "win32") {
|
|
810
|
+
let buildNumber = this.winBuildNumber()
|
|
811
|
+
if (buildNumber < 18309) {
|
|
812
|
+
// must use conpty for node-pty, and conpty is only supported in win>=18309
|
|
813
|
+
console.log("Windows buildNumber", buildNumber)
|
|
814
|
+
throw new Error(`Pinokio supports Windows release 18309 and up (current system: ${buildNumber}`)
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
// if (buildNumber > 25000) {
|
|
818
|
+
// console.log("Windows buildNumber", buildNumber)
|
|
819
|
+
// throw new Error(`Pinokio does not currently support Windows Canary (versions 25000 and up). The current system is ${buildNumber}`)
|
|
820
|
+
//
|
|
821
|
+
// }
|
|
822
|
+
}
|
|
823
|
+
}
|
|
701
824
|
async sh(params, ondata) {
|
|
702
825
|
let response = await this.kernel.shell.run(params, null, ondata)
|
|
703
826
|
return response
|
package/kernel/bin/node.js
CHANGED
|
@@ -19,6 +19,11 @@ class Node {
|
|
|
19
19
|
async installed() {
|
|
20
20
|
return this.kernel.bin.installed.conda.has("nodejs") && this.kernel.bin.installed.conda.has("pnpm")
|
|
21
21
|
}
|
|
22
|
+
env() {
|
|
23
|
+
return {
|
|
24
|
+
PATH: [this.kernel.path("bin/npm/bin")]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
22
27
|
async uninstall(req, ondata) {
|
|
23
28
|
await this.kernel.bin.exec({
|
|
24
29
|
message: "conda remove nodejs pnpm",
|
package/kernel/index.js
CHANGED
|
@@ -26,6 +26,7 @@ const Config = require("./pinokio.json")
|
|
|
26
26
|
const Info = require('./info')
|
|
27
27
|
const Pipe = require("../pipe")
|
|
28
28
|
const Cloudflare = require('./api/cloudflare')
|
|
29
|
+
const Store = require('./store')
|
|
29
30
|
const VARS = {
|
|
30
31
|
pip: {
|
|
31
32
|
install: {
|
|
@@ -42,7 +43,29 @@ class Kernel {
|
|
|
42
43
|
schema = "<=3.7.0"
|
|
43
44
|
constructor(store) {
|
|
44
45
|
this.fetch = fetch
|
|
45
|
-
|
|
46
|
+
|
|
47
|
+
// STORE
|
|
48
|
+
// Previously custom STORE could be passed in. This was to support both electron and server based initialization
|
|
49
|
+
// But this creates complexity because the store location is not fixed
|
|
50
|
+
// Migrating it to ~/.pinokio/config.json
|
|
51
|
+
//
|
|
52
|
+
// 1. does ~/.pinokio exist?
|
|
53
|
+
// - load from that file
|
|
54
|
+
// 2. does ~/.pinokio NOT exist?
|
|
55
|
+
// - save the passed in options to the `~/.pinokio`
|
|
56
|
+
// - load the config
|
|
57
|
+
|
|
58
|
+
this.store = new Store()
|
|
59
|
+
let exists = this.store.exists()
|
|
60
|
+
console.log("Store exists?", exists)
|
|
61
|
+
if (!exists) {
|
|
62
|
+
console.log("doesn't exist")
|
|
63
|
+
// clone the store to the new store
|
|
64
|
+
this.store.clone(store.store)
|
|
65
|
+
// load from the store (this will be the last time this is used, since the next time it loads, it will load from the new store)
|
|
66
|
+
}
|
|
67
|
+
console.log("this.store", this.store.store())
|
|
68
|
+
|
|
46
69
|
this.arch = os.arch()
|
|
47
70
|
this.os = os
|
|
48
71
|
this.platform = os.platform()
|
|
@@ -386,6 +409,7 @@ class Kernel {
|
|
|
386
409
|
}
|
|
387
410
|
}
|
|
388
411
|
async init(options) {
|
|
412
|
+
console.time(">>>>>>>>>>>>>> A")
|
|
389
413
|
let home = this.store.get("home")
|
|
390
414
|
|
|
391
415
|
// reset shells if they exist
|
|
@@ -452,7 +476,9 @@ class Kernel {
|
|
|
452
476
|
}
|
|
453
477
|
this.procs = {}
|
|
454
478
|
this.template = new Template()
|
|
479
|
+
console.timeEnd(">>>>>>>>>>>>>> A")
|
|
455
480
|
try {
|
|
481
|
+
console.time(">>>>>>>>>>>>>> B")
|
|
456
482
|
if (this.homedir) {
|
|
457
483
|
|
|
458
484
|
// 0. create homedir
|
|
@@ -490,14 +516,17 @@ class Kernel {
|
|
|
490
516
|
|
|
491
517
|
|
|
492
518
|
}
|
|
519
|
+
console.timeEnd(">>>>>>>>>>>>>> B")
|
|
493
520
|
|
|
494
521
|
// let contents = await fs.promises.readdir(this.homedir)
|
|
495
522
|
//await this.bin.init()
|
|
496
523
|
let ts = Date.now()
|
|
524
|
+
console.time(">>>>>>>>>>>>>> C bin.init")
|
|
497
525
|
this.bin.init().then(() => {
|
|
498
526
|
console.log("bin init finished")
|
|
499
527
|
if (this.homedir) {
|
|
500
528
|
this.shell.init().then(async () => {
|
|
529
|
+
this.bin.check_bin()
|
|
501
530
|
if (this.envs) {
|
|
502
531
|
this.template.update({
|
|
503
532
|
env: this.envs,
|
|
@@ -564,12 +593,16 @@ class Kernel {
|
|
|
564
593
|
})
|
|
565
594
|
}
|
|
566
595
|
})
|
|
596
|
+
console.timeEnd(">>>>>>>>>>>>>> C bin.init")
|
|
567
597
|
let ts2 = Date.now()
|
|
598
|
+
console.time(">>>>>>>>>>>>>> D api.init")
|
|
568
599
|
await this.api.init()
|
|
600
|
+
console.timeEnd(">>>>>>>>>>>>>> D api.init")
|
|
569
601
|
|
|
570
602
|
//await this.shell.init()
|
|
571
603
|
|
|
572
604
|
if (this.homedir) {
|
|
605
|
+
console.time(">>>>>>>>>>>>>> E template.init")
|
|
573
606
|
await this.template.init({
|
|
574
607
|
kernel: this,
|
|
575
608
|
system,
|
|
@@ -579,13 +612,18 @@ class Kernel {
|
|
|
579
612
|
return this.api.get_proxy_url("/proxy", port)
|
|
580
613
|
},
|
|
581
614
|
})
|
|
615
|
+
console.timeEnd(">>>>>>>>>>>>>> E template.init")
|
|
616
|
+
console.time(">>>>>>>>>>>>>> F sys.init")
|
|
582
617
|
this.sys = new Sysinfo()
|
|
583
618
|
await this.sys.init(this)
|
|
619
|
+
console.timeEnd(">>>>>>>>>>>>>> F sys.init")
|
|
584
620
|
let info = this.sys.info
|
|
585
621
|
|
|
586
622
|
this.sysinfo = info
|
|
587
623
|
|
|
624
|
+
console.time(">>>>>>>>>>>>>> G getInfo")
|
|
588
625
|
await this.getInfo()
|
|
626
|
+
console.timeEnd(">>>>>>>>>>>>>> G getInfo")
|
|
589
627
|
|
|
590
628
|
await fs.promises.mkdir(this.path("logs"), { recursive: true }).catch((e) => { })
|
|
591
629
|
await fs.promises.writeFile(this.path("logs/system.json"), JSON.stringify(this.i, null, 2))
|
package/kernel/shell.js
CHANGED
|
@@ -103,6 +103,9 @@ class Shell {
|
|
|
103
103
|
if (this.env.CMAKE_GENERATOR) {
|
|
104
104
|
delete this.env.CMAKE_GENERATOR
|
|
105
105
|
}
|
|
106
|
+
|
|
107
|
+
this.env.NPM_CONFIG_PREFIX = this.kernel.path("bin/npm")
|
|
108
|
+
this.env.npm_config_prefix = this.kernel.path("bin/npm")
|
|
106
109
|
|
|
107
110
|
// if (this.env.CUDA_HOME) {
|
|
108
111
|
// delete this.env.CUDA_HOME
|
|
@@ -274,11 +277,12 @@ class Shell {
|
|
|
274
277
|
return response
|
|
275
278
|
} else {
|
|
276
279
|
let response = await this.request(params, async (stream) => {
|
|
277
|
-
if (stream
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
280
|
+
if (ondata) ondata(stream)
|
|
281
|
+
// if (stream.prompt) {
|
|
282
|
+
// this.resolve()
|
|
283
|
+
// } else {
|
|
284
|
+
// if (ondata) ondata(stream)
|
|
285
|
+
// }
|
|
282
286
|
})
|
|
283
287
|
return response
|
|
284
288
|
}
|
|
@@ -287,7 +291,10 @@ class Shell {
|
|
|
287
291
|
}
|
|
288
292
|
emit(message) {
|
|
289
293
|
if (this.ptyProcess) {
|
|
290
|
-
|
|
294
|
+
// console.log("write", { message, input: this.input })
|
|
295
|
+
if (this.input) {
|
|
296
|
+
this.ptyProcess.write(message)
|
|
297
|
+
}
|
|
291
298
|
}
|
|
292
299
|
}
|
|
293
300
|
send(message, newline, cb) {
|
|
@@ -369,6 +376,9 @@ class Shell {
|
|
|
369
376
|
|
|
370
377
|
// not connected => make a new connection => which means get a new prompt
|
|
371
378
|
// if already connected => no need for a new prompt
|
|
379
|
+
if (params.input) {
|
|
380
|
+
this.input = params.input
|
|
381
|
+
}
|
|
372
382
|
if (params.persistent) {
|
|
373
383
|
this.persistent = params.persistent
|
|
374
384
|
}
|
|
@@ -900,6 +910,7 @@ class Shell {
|
|
|
900
910
|
}
|
|
901
911
|
}
|
|
902
912
|
kill(message, force) {
|
|
913
|
+
console.log("KILL")
|
|
903
914
|
|
|
904
915
|
this.done = true
|
|
905
916
|
this.ready = false
|
|
@@ -1007,6 +1018,11 @@ ${cleaned}
|
|
|
1007
1018
|
|
|
1008
1019
|
}
|
|
1009
1020
|
stream(msg, callback) {
|
|
1021
|
+
if (msg === "\u0007") {
|
|
1022
|
+
// Ignore bell sound escape character because it slows down everything and makes redundant sound
|
|
1023
|
+
callback()
|
|
1024
|
+
return
|
|
1025
|
+
}
|
|
1010
1026
|
this.vt.write(msg, () => {
|
|
1011
1027
|
let buf = this.vts.serialize()
|
|
1012
1028
|
let cleaned = this.stripAnsi(buf)
|
|
@@ -1014,8 +1030,10 @@ ${cleaned}
|
|
|
1014
1030
|
id: this.id,
|
|
1015
1031
|
raw: msg,
|
|
1016
1032
|
cleaned,
|
|
1017
|
-
state: cleaned
|
|
1033
|
+
state: cleaned,
|
|
1034
|
+
shell_id: this.id
|
|
1018
1035
|
}
|
|
1036
|
+
this.state = cleaned
|
|
1019
1037
|
if (this.cb) this.cb(response)
|
|
1020
1038
|
|
|
1021
1039
|
// Decide whether to kill or continue
|
|
@@ -1030,15 +1048,15 @@ ${cleaned}
|
|
|
1030
1048
|
// todo: may need to handle cases when the command returns immediately with no output (example: 'which brew' returns immediately with no text if brew doesn't exist)
|
|
1031
1049
|
setTimeout(() => {
|
|
1032
1050
|
if (cache === cleaned) {
|
|
1033
|
-
if (this.persistent) {
|
|
1034
|
-
if (this.cb) this.cb({
|
|
1035
|
-
//raw: cached_msg,
|
|
1036
|
-
//raw: msg,
|
|
1037
|
-
//raw: "",
|
|
1038
|
-
cleaned,
|
|
1039
|
-
state: cleaned,
|
|
1040
|
-
prompt: true
|
|
1041
|
-
})
|
|
1051
|
+
if (this.input || this.persistent) {
|
|
1052
|
+
// if (this.cb) this.cb({
|
|
1053
|
+
// //raw: cached_msg,
|
|
1054
|
+
// //raw: msg,
|
|
1055
|
+
// //raw: "",
|
|
1056
|
+
// cleaned,
|
|
1057
|
+
// state: cleaned,
|
|
1058
|
+
// prompt: true
|
|
1059
|
+
// })
|
|
1042
1060
|
callback()
|
|
1043
1061
|
} else {
|
|
1044
1062
|
callback()
|
package/kernel/shells.js
CHANGED
package/kernel/store.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const os = require('os')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const fs = require('fs')
|
|
4
|
+
class Store {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.root = path.resolve(os.homedir(), ".pinokio")
|
|
7
|
+
if (!fs.existsSync(path.resolve(this.root))) {
|
|
8
|
+
fs.mkdirSync(path.resolve(this.root))
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
exists() {
|
|
12
|
+
let p = path.resolve(this.root, "config.json")
|
|
13
|
+
return fs.existsSync(p)
|
|
14
|
+
}
|
|
15
|
+
clone(old) {
|
|
16
|
+
console.log("clone", old)
|
|
17
|
+
let p = path.resolve(this.root, "config.json")
|
|
18
|
+
fs.writeFileSync(p, JSON.stringify(old, null, 2))
|
|
19
|
+
}
|
|
20
|
+
set(key, val) {
|
|
21
|
+
let o
|
|
22
|
+
try {
|
|
23
|
+
let str = fs.readFileSync(path.resolve(this.root, "config.json"), "utf8")
|
|
24
|
+
o = JSON.parse(str)
|
|
25
|
+
} catch(e) {
|
|
26
|
+
o = {}
|
|
27
|
+
}
|
|
28
|
+
o[key] = val
|
|
29
|
+
fs.writeFileSync(path.resolve(this.root, "config.json"), JSON.stringify(o, null, 2))
|
|
30
|
+
}
|
|
31
|
+
get(key) {
|
|
32
|
+
try {
|
|
33
|
+
let str = fs.readFileSync(path.resolve(this.root, "config.json"), "utf8")
|
|
34
|
+
let o = JSON.parse(str)
|
|
35
|
+
return o[key]
|
|
36
|
+
} catch (e) {
|
|
37
|
+
return null
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
delete(key) {
|
|
41
|
+
try {
|
|
42
|
+
let str = fs.readFileSync(path.resolve(this.root, "config.json"), "utf8")
|
|
43
|
+
let o = JSON.parse(str)
|
|
44
|
+
delete o[key]
|
|
45
|
+
fs.writeFileSync(path.resolve(this.root, "config.json"), JSON.stringify(o, null, 2))
|
|
46
|
+
} catch (e) {
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
store() {
|
|
50
|
+
try {
|
|
51
|
+
let str = fs.readFileSync(path.resolve(this.root, "config.json"), "utf8")
|
|
52
|
+
let o = JSON.parse(str)
|
|
53
|
+
return o
|
|
54
|
+
} catch (e) {
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
module.exports = Store
|
package/kernel/sysinfo.js
CHANGED
|
@@ -5,24 +5,34 @@ class Sysinfo {
|
|
|
5
5
|
async init(kernel) {
|
|
6
6
|
this.kernel = kernel
|
|
7
7
|
this.info = {}
|
|
8
|
-
await this.static
|
|
9
|
-
await this.
|
|
8
|
+
await Promise.all([this.static, this.refresh])
|
|
9
|
+
// await this.static()
|
|
10
|
+
// await this.refresh()
|
|
10
11
|
}
|
|
11
12
|
async static() {
|
|
12
|
-
await this.gpus
|
|
13
|
-
await this.
|
|
14
|
-
await this.
|
|
15
|
-
await this.
|
|
16
|
-
await this.
|
|
17
|
-
await this.
|
|
13
|
+
await Promise.all([this.gpus, this.system, this.cpu, this.os, this.audio, this.env])
|
|
14
|
+
// await this.gpus()
|
|
15
|
+
// await this.system()
|
|
16
|
+
// await this.cpu()
|
|
17
|
+
// await this.os()
|
|
18
|
+
// await this.audio()
|
|
19
|
+
// await this.env()
|
|
20
|
+
|
|
21
|
+
|
|
18
22
|
// await this.disk()
|
|
19
23
|
}
|
|
20
24
|
async refresh() {
|
|
21
25
|
// await this.time()
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
await this.proc
|
|
25
|
-
await this.
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
await Promise.all([this.memory, this.battery, this.proc, this.bluetooth])
|
|
29
|
+
// await this.memory()
|
|
30
|
+
// await this.battery()
|
|
31
|
+
// await this.proc()
|
|
32
|
+
// await this.bluetooth()
|
|
33
|
+
//
|
|
34
|
+
|
|
35
|
+
|
|
26
36
|
// await this.net()
|
|
27
37
|
}
|
|
28
38
|
async gpus() {
|