pinokiod 3.9.0 → 3.9.3
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/:w +1247 -0
- package/kernel/api/filepicker/index.js +59 -0
- package/kernel/api/fs/index.js +6 -4
- package/kernel/api/index.js +123 -37
- package/kernel/api/input/index.js +2 -0
- package/kernel/api/web/index.js +6 -0
- package/kernel/bin/caddy.js +127 -0
- package/kernel/bin/cloudflared.js +1 -0
- package/kernel/bin/conda.js +10 -2
- package/kernel/bin/cuda.js +0 -16
- package/kernel/bin/ffmpeg.js +4 -6
- package/kernel/bin/git.js +55 -29
- package/kernel/bin/gxx.js +8 -6
- package/kernel/bin/huggingface.js +4 -5
- package/kernel/bin/index.js +347 -88
- package/kernel/bin/node.js +13 -6
- package/kernel/bin/py.js +1 -1
- package/kernel/bin/setup.js +146 -0
- package/kernel/bin/uv.js +4 -5
- package/kernel/bin/zip.js +7 -8
- package/kernel/connect/index.js +25 -0
- package/kernel/connect/providers/github/README.md +11 -0
- package/kernel/connect/providers/x/README.md +96 -0
- package/kernel/connect/providers/x/index.js +152 -0
- package/kernel/environment.js +50 -1
- package/kernel/index.js +152 -32
- package/kernel/info.js +4 -2
- package/kernel/kv.js +38 -0
- package/kernel/loader.js +13 -3
- package/kernel/peer.js +161 -0
- package/kernel/procs.js +116 -0
- package/kernel/prototype.js +62 -0
- package/kernel/router/common.js +42 -0
- package/kernel/router/connector.js +81 -0
- package/kernel/router/index.js +235 -0
- package/kernel/router/localhost_home_router.js +84 -0
- package/kernel/router/localhost_port_router.js +15 -0
- package/kernel/router/localhost_variable_router.js +37 -0
- package/kernel/router/peer_home_router.js +15 -0
- package/kernel/router/peer_peer_router.js +26 -0
- package/kernel/router/peer_port_router.js +45 -0
- package/kernel/router/peer_variable_router.js +46 -0
- package/kernel/router/processor.js +31 -0
- package/kernel/shell.js +141 -60
- package/kernel/shells.js +32 -17
- package/kernel/store.js +58 -0
- package/kernel/sysinfo.js +0 -1
- package/kernel/util.js +143 -36
- package/package.json +4 -1
- package/pipe/index.js +0 -2
- package/script/index.js +12 -0
- package/server/index.js +1473 -553
- package/server/public/Socket.js +5 -1
- package/server/public/SourceCodePro-Regular.ttf +0 -0
- package/server/public/SpaceMono-Bold.ttf +0 -0
- package/server/public/SpaceMono-BoldItalic.ttf +0 -0
- package/server/public/SpaceMono-Italic.ttf +0 -0
- package/server/public/SpaceMono-Regular.ttf +0 -0
- package/server/public/commander.js +40 -0
- package/server/public/common.js +60 -0
- package/server/public/dropzone-min.js +2 -0
- package/server/public/dropzone.css +1 -0
- package/server/public/filepond-plugin-file-validate-type.min.js +9 -0
- package/server/public/filepond-plugin-image-crop.min.js +9 -0
- package/server/public/filepond-plugin-image-edit.min.css +8 -0
- package/server/public/filepond-plugin-image-edit.min.js +9 -0
- package/server/public/filepond-plugin-image-exif-orientation.min.js +9 -0
- package/server/public/filepond-plugin-image-preview.min.css +8 -0
- package/server/public/filepond-plugin-image-preview.min.js +9 -0
- package/server/public/filepond-plugin-image-resize.min.js +9 -0
- package/server/public/filepond-plugin-image-transform.min.js +9 -0
- package/server/public/filepond.min.css +8 -0
- package/server/public/filepond.min.js +9 -0
- package/server/public/fscreator.js +174 -0
- package/server/public/fseditor.js +212 -0
- package/server/public/github.png +0 -0
- package/server/public/highlight-js.js +81 -0
- package/server/public/highlight.css +9 -0
- package/server/public/highlight.js +1244 -0
- package/server/public/install.js +17 -20
- package/server/public/modalinput.js +105 -9
- package/server/public/opener.js +3 -1
- package/server/public/pinokio-black.png +0 -0
- package/server/public/pinokio-black2.png +0 -0
- package/server/public/redoc.standalone.js +1832 -0
- package/server/public/style.css +215 -17
- package/server/public/swagger-ui-bundle.js +2 -0
- package/server/public/swagger-ui.css +3 -0
- package/server/public/x.js +63 -0
- package/server/socket.js +136 -39
- package/server/views/404.ejs +0 -1
- package/server/views/app.ejs +368 -98
- package/server/views/bootstrap.ejs +22 -19
- package/server/views/connect/x.ejs +324 -0
- package/server/views/connect.ejs +197 -0
- package/server/views/download.ejs +7 -1
- package/server/views/editor.ejs +68 -9
- package/server/views/explore.ejs +13 -10
- package/server/views/file_explorer.ejs +10 -37
- package/server/views/github.ejs +218 -0
- package/server/views/help.ejs +4 -3
- package/server/views/index.ejs +275 -121
- package/server/views/install.ejs +56 -29
- package/server/views/keys.ejs +276 -0
- package/server/views/network.ejs +889 -0
- package/server/views/partials/dynamic.ejs +9 -0
- package/server/views/partials/menu.ejs +7 -1
- package/server/views/prototype/index.ejs +311 -0
- package/server/views/prototype/show.ejs +383 -0
- package/server/views/redoc.ejs +18 -0
- package/server/views/required_env_editor.ejs +11 -2
- package/server/views/settings.ejs +38 -10
- package/server/views/setup.ejs +254 -0
- package/server/views/setup_home.ejs +192 -0
- package/server/views/shell.ejs +781 -0
- package/server/views/swaggerui.ejs +19 -0
- package/server/views/terminal.ejs +174 -42
- package/LICENSE +0 -7
- package/server/views/proxy.ejs +0 -405
package/kernel/bin/index.js
CHANGED
|
@@ -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")
|
|
@@ -37,6 +38,18 @@ class Bin {
|
|
|
37
38
|
this.arch = os.arch()
|
|
38
39
|
this.platform = os.platform()
|
|
39
40
|
}
|
|
41
|
+
async shell_kill(params, ondata) {
|
|
42
|
+
this.kernel.shell.kill(params.params)
|
|
43
|
+
}
|
|
44
|
+
async shell_start(params, ondata) {
|
|
45
|
+
params.path = params.path || this.path()
|
|
46
|
+
if (this.client) {
|
|
47
|
+
params.cols = this.client.cols
|
|
48
|
+
params.rows = this.client.rows
|
|
49
|
+
}
|
|
50
|
+
let response = await this.kernel.shell.start(params, null, ondata)
|
|
51
|
+
return response
|
|
52
|
+
}
|
|
40
53
|
async exec(params, ondata) {
|
|
41
54
|
params.path = params.path || this.path()
|
|
42
55
|
if (this.client) {
|
|
@@ -55,10 +68,8 @@ class Bin {
|
|
|
55
68
|
// })
|
|
56
69
|
// }
|
|
57
70
|
async download(url, dest, ondata) {
|
|
58
|
-
console.log("DOWNLOAD process.env", process.env)
|
|
59
71
|
const agent = new ProxyAgent();
|
|
60
72
|
const userAgent = fakeUa()
|
|
61
|
-
console.log("download userAgent", userAgent)
|
|
62
73
|
const opts = {
|
|
63
74
|
fileName: dest,
|
|
64
75
|
override: true,
|
|
@@ -74,7 +85,6 @@ class Bin {
|
|
|
74
85
|
opts.httpRequestOptions = { agent }
|
|
75
86
|
opts.httpsRequestOptions = { agent }
|
|
76
87
|
}
|
|
77
|
-
console.log("opts", opts)
|
|
78
88
|
const dl = new DownloaderHelper(url, this.path(), opts)
|
|
79
89
|
ondata({ raw: `\r\nDownloading ${url} to ${this.path()}...\r\n` })
|
|
80
90
|
let res = await new Promise((resolve, reject) => {
|
|
@@ -187,7 +197,6 @@ class Bin {
|
|
|
187
197
|
return e
|
|
188
198
|
}
|
|
189
199
|
async init() {
|
|
190
|
-
console.log("kernel.bin.init", this.kernel.homedir)
|
|
191
200
|
if (this.kernel.homedir) {
|
|
192
201
|
const bin_folder = this.path()
|
|
193
202
|
await fs.promises.mkdir(bin_folder, { recursive: true }).catch((e) => { })
|
|
@@ -197,7 +206,6 @@ class Bin {
|
|
|
197
206
|
}
|
|
198
207
|
// await fs.promises.mkdir(playwright_folder, { recursive: true }).catch((e) => { })
|
|
199
208
|
let system_env = await Environment.get(this.kernel.homedir)
|
|
200
|
-
console.log("***********", { system_env })
|
|
201
209
|
|
|
202
210
|
if (system_env.HTTP_PROXY) {
|
|
203
211
|
process.env.HTTP_PROXY = system_env.HTTP_PROXY
|
|
@@ -266,6 +274,8 @@ class Bin {
|
|
|
266
274
|
} catch (e) {
|
|
267
275
|
console.log("RefreshInstalled Error", e)
|
|
268
276
|
}
|
|
277
|
+
|
|
278
|
+
// initialize pipconfig
|
|
269
279
|
let pipconfig_path = path.resolve(this.kernel.homedir, "pipconfig")
|
|
270
280
|
let pipconfig_exists = await this.kernel.api.exists(pipconfig_path)
|
|
271
281
|
// if not, create one
|
|
@@ -273,10 +283,6 @@ class Bin {
|
|
|
273
283
|
const pipconfigStr = `[global]
|
|
274
284
|
timeout = 1000`
|
|
275
285
|
await fs.promises.writeFile(pipconfig_path, pipconfigStr)
|
|
276
|
-
// await fs.promises.copyFile(
|
|
277
|
-
// path.resolve(__dirname, "..", "pipconfig_template"),
|
|
278
|
-
// pipconfig_path
|
|
279
|
-
// )
|
|
280
286
|
}
|
|
281
287
|
|
|
282
288
|
// add gitconfig => support git lfs, long path, etc.
|
|
@@ -286,6 +292,13 @@ class Bin {
|
|
|
286
292
|
path.resolve(__dirname, "..", "gitconfig_template"),
|
|
287
293
|
gitconfig_path
|
|
288
294
|
)
|
|
295
|
+
|
|
296
|
+
for(let mod of this.mods) {
|
|
297
|
+
if (mod.mod.start) {
|
|
298
|
+
await mod.mod.start()
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
289
302
|
}
|
|
290
303
|
|
|
291
304
|
|
|
@@ -311,25 +324,27 @@ class Bin {
|
|
|
311
324
|
} else {
|
|
312
325
|
site_packages_path = path.resolve(this.kernel.homedir, "bin/miniconda/lib/python3.10/site-packages")
|
|
313
326
|
}
|
|
314
|
-
// check if any of 'uvicorn', 'importlib_metadata', 'fastapi' exists
|
|
315
|
-
let module_paths = ["fastapi", "uvicorn", "importlib_metadata"].map((name) => {
|
|
316
|
-
return path.resolve(site_packages_path, name)
|
|
317
|
-
})
|
|
327
|
+
// // check if any of 'uvicorn', 'importlib_metadata', 'fastapi' exists
|
|
328
|
+
// let module_paths = ["fastapi", "uvicorn", "importlib_metadata"].map((name) => {
|
|
329
|
+
// return path.resolve(site_packages_path, name)
|
|
330
|
+
// })
|
|
331
|
+
// let to_reset_exists = false
|
|
332
|
+
// for(let module_path of module_paths) {
|
|
333
|
+
// let e = await this.kernel.exists(module_path)
|
|
334
|
+
// console.log("checking kernel exists", { module_path, e })
|
|
335
|
+
// if (e) {
|
|
336
|
+
// to_reset_exists = true
|
|
337
|
+
// break;
|
|
338
|
+
// }
|
|
339
|
+
// }
|
|
340
|
+
// console.log("> to_reset_exists", to_reset_exists)
|
|
341
|
+
|
|
318
342
|
let to_reset_exists = false
|
|
319
|
-
|
|
320
|
-
let e = await this.kernel.exists(module_path)
|
|
321
|
-
console.log({ e, module_path })
|
|
322
|
-
if (e) {
|
|
323
|
-
to_reset_exists = true
|
|
324
|
-
break;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
console.log({ to_reset_exists })
|
|
343
|
+
|
|
328
344
|
if (to_reset_exists) {
|
|
329
345
|
this.correct_conda = false
|
|
330
346
|
} else {
|
|
331
347
|
res = await this.exec({ message: `conda list` }, (stream) => {
|
|
332
|
-
// process.stdout.write(stream.raw)
|
|
333
348
|
// console.log("conda list check", { stream })
|
|
334
349
|
})
|
|
335
350
|
|
|
@@ -344,17 +359,12 @@ class Bin {
|
|
|
344
359
|
conda_versions[name] = version
|
|
345
360
|
if (name === "conda") {
|
|
346
361
|
conda_check.conda = true
|
|
347
|
-
// //if (String(version) === "24.11.1") {
|
|
348
|
-
// if (String(version) === "24.11.3") {
|
|
349
|
-
// conda_check.conda = true
|
|
350
|
-
// }
|
|
351
362
|
}
|
|
352
363
|
if (name === "conda-libmamba-solver") {
|
|
353
364
|
//if (String(version) === "24.7.0") {
|
|
354
365
|
let channel = chunks[3]
|
|
355
366
|
let coerced = semver.coerce(version)
|
|
356
367
|
let mamba_requirement = ">=24.11.1"
|
|
357
|
-
console.log({ name, channel, version })
|
|
358
368
|
//if (semver.satisfies(coerced, mamba_requirement) && channel === "conda-forge") {
|
|
359
369
|
if (semver.satisfies(coerced, mamba_requirement)) {
|
|
360
370
|
conda_check.mamba = true
|
|
@@ -366,16 +376,6 @@ class Bin {
|
|
|
366
376
|
if (String(version) === "3.47.2") {
|
|
367
377
|
conda_check.sqlite = true
|
|
368
378
|
}
|
|
369
|
-
// let coerced = semver.coerce(version)
|
|
370
|
-
// let sqlite_requirement = ">=3.47.2"
|
|
371
|
-
// // console.log({ coerced, version, sqlite_requirement })
|
|
372
|
-
// if (semver.satisfies(coerced, sqlite_requirement)) {
|
|
373
|
-
// console.log("semver satisfied")
|
|
374
|
-
//
|
|
375
|
-
// conda_check.sqlite = true
|
|
376
|
-
// } else {
|
|
377
|
-
// console.log("semver NOT satisfied")
|
|
378
|
-
// }
|
|
379
379
|
}
|
|
380
380
|
}
|
|
381
381
|
} else {
|
|
@@ -385,7 +385,6 @@ class Bin {
|
|
|
385
385
|
}
|
|
386
386
|
}
|
|
387
387
|
|
|
388
|
-
console.log({ conda_check })
|
|
389
388
|
if (conda_check.conda && conda_check.mamba && conda_check.sqlite) {
|
|
390
389
|
//if (conda_check.conda && conda_check.mamba) {
|
|
391
390
|
this.correct_conda = true
|
|
@@ -396,23 +395,17 @@ class Bin {
|
|
|
396
395
|
}
|
|
397
396
|
async refreshInstalled() {
|
|
398
397
|
|
|
399
|
-
console.log("refreshInstalled start")
|
|
400
|
-
|
|
401
|
-
|
|
402
398
|
/// A. installed packages detection
|
|
403
399
|
|
|
404
400
|
this.installed_initialized = false
|
|
405
401
|
|
|
406
402
|
//this.installed = {}
|
|
407
403
|
|
|
408
|
-
console.log("## check conda")
|
|
409
|
-
|
|
410
404
|
// 1. conda
|
|
411
405
|
|
|
412
406
|
// check conda location and see if it exists. only run if it exists
|
|
413
407
|
let conda_path = path.resolve(this.kernel.homedir, "bin", "miniconda")
|
|
414
408
|
let conda_exists = await this.exists(conda_path)
|
|
415
|
-
console.log({ conda_path, conda_exists })
|
|
416
409
|
|
|
417
410
|
let start
|
|
418
411
|
let res
|
|
@@ -429,48 +422,17 @@ class Bin {
|
|
|
429
422
|
}
|
|
430
423
|
}
|
|
431
424
|
|
|
432
|
-
// // 2. pip
|
|
433
|
-
// let pip = new Set()
|
|
434
|
-
// if (conda_exists) {
|
|
435
|
-
// // conda comes with pip
|
|
436
|
-
// console.log("## check pip")
|
|
437
|
-
// start = false
|
|
438
|
-
// res = await this.exec({ message: `pip list` }, (stream) => {
|
|
439
|
-
//// console.log("pip list check", { stream })
|
|
440
|
-
// })
|
|
441
|
-
// console.log("PIP", res.response)
|
|
442
|
-
// lines = res.response.split(/[\r\n]+/)
|
|
443
|
-
// for(let line of lines) {
|
|
444
|
-
// if (start) {
|
|
445
|
-
// let chunks = line.split(/\s+/).filter(x => x)
|
|
446
|
-
// if (chunks.length > 1) {
|
|
447
|
-
// pip.add(chunks[0])
|
|
448
|
-
// }
|
|
449
|
-
// } else {
|
|
450
|
-
// if (/-------.*/i.test(line)) {
|
|
451
|
-
// start = true
|
|
452
|
-
// }
|
|
453
|
-
// }
|
|
454
|
-
// }
|
|
455
|
-
// }
|
|
456
|
-
// this.installed.pip = pip
|
|
457
|
-
|
|
458
|
-
|
|
459
425
|
if (this.platform === "darwin") {
|
|
460
426
|
// 3. brew
|
|
461
|
-
console.log("## check brew")
|
|
462
427
|
|
|
463
428
|
let brew_path = path.resolve(this.kernel.homedir, "bin", "homebrew")
|
|
464
429
|
let brew_exists = await this.exists(brew_path)
|
|
465
|
-
console.log({ brew_path, brew_exists })
|
|
466
430
|
|
|
467
431
|
let brew = []
|
|
468
432
|
if (brew_exists) {
|
|
469
433
|
start = false
|
|
470
434
|
res = await this.exec({ message: `brew list -1`, conda: { skip: true } }, (stream) => {
|
|
471
|
-
// console.log("brew list check", { stream })
|
|
472
435
|
})
|
|
473
|
-
console.log("BREW", res.response)
|
|
474
436
|
lines = res.response.split(/[\r\n]+/).slice(0, -1) // ignore last line since it's the prompt
|
|
475
437
|
let end = false
|
|
476
438
|
for(let line of lines) {
|
|
@@ -494,7 +456,6 @@ class Bin {
|
|
|
494
456
|
|
|
495
457
|
|
|
496
458
|
// check brew_installed
|
|
497
|
-
console.log("checking brew installed")
|
|
498
459
|
let e = await this.kernel.bin.exists("homebrew")
|
|
499
460
|
let { stdout }= await this.exec({ message: "xcode-select -p", conda: { skip: true } }, (stream) => { })
|
|
500
461
|
let e2 = /(.*Library.*Developer.*CommandLineTools.*|.*Xcode.*Developer.*)/gi.test(stdout)
|
|
@@ -512,7 +473,7 @@ class Bin {
|
|
|
512
473
|
e4 = /xcode-select version ([0-9]+)/gi.exec(result.stdout)
|
|
513
474
|
if (e4 && e4.length > 1) {
|
|
514
475
|
let version = Number(e4[1])
|
|
515
|
-
console.log("xcode-select version", version)
|
|
476
|
+
// console.log("xcode-select version", version)
|
|
516
477
|
if (version >= 2349) {
|
|
517
478
|
e4 = true
|
|
518
479
|
} else {
|
|
@@ -569,7 +530,7 @@ class Bin {
|
|
|
569
530
|
// await this.mod(name).rm({}, ondata)
|
|
570
531
|
// await this.mod(name).install(options, ondata)
|
|
571
532
|
//}
|
|
572
|
-
async tryInstall(requirement, x, i, total, ondata) {
|
|
533
|
+
async tryInstall(id, requirement, x, i, total, ondata) {
|
|
573
534
|
let current_platform = os.platform()
|
|
574
535
|
let current_arch = os.arch()
|
|
575
536
|
let current_gpu = this.kernel.gpu
|
|
@@ -629,7 +590,7 @@ class Bin {
|
|
|
629
590
|
ondata({ html: `<b><i class="fas fa-circle-notch fa-spin"></i> ${progress} Installing ${name}</b>${message}` }, "notify2")
|
|
630
591
|
console.log("## Before m.mod.install", requirement)
|
|
631
592
|
requirement._attempt = x
|
|
632
|
-
await m.mod.install(requirement, ondata, this.kernel)
|
|
593
|
+
await m.mod.install(requirement, ondata, this.kernel, id)
|
|
633
594
|
|
|
634
595
|
// // 2 second delay to fix conda issue
|
|
635
596
|
// await new Promise((resolve, reject) => {
|
|
@@ -646,6 +607,26 @@ class Bin {
|
|
|
646
607
|
}
|
|
647
608
|
// }
|
|
648
609
|
}
|
|
610
|
+
async path_exists(req, ondata) {
|
|
611
|
+
let abspath = this.kernel.api.resolvePath(this.kernel.api.userdir, req.params.uri)
|
|
612
|
+
if (abspath) {
|
|
613
|
+
console.log({ abspath })
|
|
614
|
+
let exists = await new Promise(r=>fs.access(abspath, fs.constants.F_OK, e => r(!e)))
|
|
615
|
+
return exists
|
|
616
|
+
} else {
|
|
617
|
+
return false
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
async install2(req, ondata) {
|
|
621
|
+
let { requirements, install_required, requirements_pending, error } = await this.check({
|
|
622
|
+
bin: this.preset("ai")
|
|
623
|
+
})
|
|
624
|
+
req.params = JSON.stringify(requirements)
|
|
625
|
+
if (this.install_required) {
|
|
626
|
+
let res = await this.install(req, ondata)
|
|
627
|
+
return res
|
|
628
|
+
}
|
|
629
|
+
}
|
|
649
630
|
async install(req, ondata) {
|
|
650
631
|
/*
|
|
651
632
|
req.params := {
|
|
@@ -664,9 +645,7 @@ class Bin {
|
|
|
664
645
|
} else {
|
|
665
646
|
this.client = null
|
|
666
647
|
}
|
|
667
|
-
|
|
668
648
|
let requirements = JSON.parse(req.params)
|
|
669
|
-
|
|
670
649
|
for(let x=0; x<10; x++) {
|
|
671
650
|
console.log(`## Install Attempt ${x}`)
|
|
672
651
|
let i = 0;
|
|
@@ -680,7 +659,7 @@ class Bin {
|
|
|
680
659
|
console.log("already installed. skip.")
|
|
681
660
|
} else {
|
|
682
661
|
console.log("not installed. install.")
|
|
683
|
-
await this.tryInstall(requirement, x, i, requirements.length, ondata)
|
|
662
|
+
await this.tryInstall(req.id, requirement, x, i, requirements.length, ondata)
|
|
684
663
|
}
|
|
685
664
|
}
|
|
686
665
|
|
|
@@ -736,19 +715,45 @@ class Bin {
|
|
|
736
715
|
// }
|
|
737
716
|
// }
|
|
738
717
|
//}
|
|
718
|
+
if (this.kernel.shell) {
|
|
719
|
+
this.kernel.shell.reset()
|
|
720
|
+
}
|
|
739
721
|
await this.init()
|
|
740
722
|
}
|
|
741
|
-
async
|
|
723
|
+
async check_installed(r, dependencies) {
|
|
724
|
+
if (Array.isArray(r.name)) {
|
|
725
|
+
for(let name of r.name) {
|
|
726
|
+
let installed = await this._installed(name, r.type, dependencies)
|
|
727
|
+
if (!installed) return false
|
|
728
|
+
}
|
|
729
|
+
return true
|
|
730
|
+
} else {
|
|
731
|
+
let installed = await this._installed(r.name, r.type, dependencies)
|
|
732
|
+
return installed
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
async _installed(name, type, dependencies) {
|
|
742
736
|
if (type === "conda") {
|
|
743
|
-
|
|
737
|
+
let conda_installed = this.installed.conda.has(name)
|
|
738
|
+
console.log({ dependencies })
|
|
739
|
+
let dependencies_installed = true
|
|
740
|
+
for(let d of dependencies) {
|
|
741
|
+
console.log("checking dependency", d)
|
|
742
|
+
if(!this.installed.conda.has(d)) {
|
|
743
|
+
dependencies_installed = false
|
|
744
|
+
console.log("not installed", d)
|
|
745
|
+
break
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
return conda_installed && dependencies_installed
|
|
744
749
|
} else if (type === "pip") {
|
|
745
|
-
return this.
|
|
750
|
+
return this.installed.pip && this.installed.pip.has(name)
|
|
746
751
|
} else if (type === "brew") {
|
|
747
|
-
return this.
|
|
752
|
+
return this.installed.brew.has(name)
|
|
748
753
|
} else {
|
|
749
754
|
// check kernel/bin/<module>.installed()
|
|
750
755
|
let filepath = path.resolve(__dirname, "..", "kernel", "bin", name + ".js")
|
|
751
|
-
let mod = this.
|
|
756
|
+
let mod = this.mod[name]
|
|
752
757
|
let installed = false
|
|
753
758
|
if (mod.installed) {
|
|
754
759
|
installed = await mod.installed()
|
|
@@ -756,6 +761,260 @@ class Bin {
|
|
|
756
761
|
return installed
|
|
757
762
|
}
|
|
758
763
|
}
|
|
764
|
+
preset(mode) {
|
|
765
|
+
return Setup[mode](this.kernel)
|
|
766
|
+
}
|
|
767
|
+
requirements(config) {
|
|
768
|
+
let requirements = config.bin.requirements
|
|
769
|
+
if (config.script && config.script.requires && config.script.requires.length > 0) {
|
|
770
|
+
/*********************************************************************
|
|
771
|
+
|
|
772
|
+
{
|
|
773
|
+
requires: [{
|
|
774
|
+
platform,
|
|
775
|
+
type,
|
|
776
|
+
name,
|
|
777
|
+
args
|
|
778
|
+
}, {
|
|
779
|
+
platform,
|
|
780
|
+
type,
|
|
781
|
+
name,
|
|
782
|
+
args
|
|
783
|
+
}],
|
|
784
|
+
run: [{
|
|
785
|
+
...
|
|
786
|
+
}]
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
syntax :=
|
|
790
|
+
|
|
791
|
+
{
|
|
792
|
+
platform: <win32|darwin|linux>,
|
|
793
|
+
type: <conda|pip|brew|none>,
|
|
794
|
+
name: <package name>, (example: "ffmpeg", "git")
|
|
795
|
+
args: <install command flags> (example: "-c conda-forge")
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
|
|
799
|
+
1. pinokio native install: no need for specifying platforms since they are included
|
|
800
|
+
|
|
801
|
+
{
|
|
802
|
+
name: "conda"
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
|
|
806
|
+
2. non native install (conda, pip, brew)
|
|
807
|
+
|
|
808
|
+
2.1. Same on all platforms
|
|
809
|
+
|
|
810
|
+
[{
|
|
811
|
+
type: "conda",
|
|
812
|
+
name: "ffmpeg",
|
|
813
|
+
args: "-c conda-forge"
|
|
814
|
+
}]
|
|
815
|
+
|
|
816
|
+
2.2. Specify per platform
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
[
|
|
820
|
+
{ name: "conda" },
|
|
821
|
+
{ platform: "darwin", type: "brew", name: "llvm" },
|
|
822
|
+
{ platform: "linux", tyoe: "conda", name: "llvm", args: "-c conda-forge llvm" },
|
|
823
|
+
{ platform: "win32", tyoe: "conda", name: "llvm", args: "-c conda-forge llvm" }
|
|
824
|
+
]
|
|
825
|
+
|
|
826
|
+
[
|
|
827
|
+
{ name: "conda" },
|
|
828
|
+
{ platform: ["darwin", "linux"], type: "brew", name: "llvm" },
|
|
829
|
+
{ platform: "win32", tyoe: "conda", name: "llvm", args: "-c conda-forge llvm" }
|
|
830
|
+
]
|
|
831
|
+
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
*********************************************************************/
|
|
835
|
+
let type_name_set = new Set()
|
|
836
|
+
for(let r of config.script.requires) {
|
|
837
|
+
// if no platform specified, or if the specified platform matches the current platform
|
|
838
|
+
if (!r.platform || platform === r.platform || Array.isArray(r.platform) && r.platform.includes(platform) ) {
|
|
839
|
+
if (Array.isArray(r.name)) {
|
|
840
|
+
// if array, just add it
|
|
841
|
+
requirements.push(r)
|
|
842
|
+
} else {
|
|
843
|
+
let type_name = `${r.type ? r.type : ''}/${r.name}`
|
|
844
|
+
if (!type_name_set.has(type_name)) {
|
|
845
|
+
type_name_set.add(type_name)
|
|
846
|
+
requirements.push(r)
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
}
|
|
853
|
+
return requirements
|
|
854
|
+
}
|
|
855
|
+
relevant(r) {
|
|
856
|
+
/*
|
|
857
|
+
single platform
|
|
858
|
+
[
|
|
859
|
+
{ name: "conda" },
|
|
860
|
+
{ platform: "darwin", type: "brew", name: "llvm" },
|
|
861
|
+
{ platform: "linux", tyoe: "conda", name: "llvm", args: "-c conda-forge llvm" },
|
|
862
|
+
{ platform: "win32", tyoe: "conda", name: "llvm", args: "-c conda-forge llvm" }
|
|
863
|
+
]
|
|
864
|
+
|
|
865
|
+
multiple platforms
|
|
866
|
+
[
|
|
867
|
+
{ name: "conda" },
|
|
868
|
+
{ platform: ["darwin", "linux"], type: "brew", name: "llvm" },
|
|
869
|
+
{ platform: "win32", tyoe: "conda", name: "llvm", args: "-c conda-forge llvm" }
|
|
870
|
+
]
|
|
871
|
+
|
|
872
|
+
|
|
873
|
+
platform & arch
|
|
874
|
+
[
|
|
875
|
+
{ name: "conda" },
|
|
876
|
+
{ platform: "darwin", arch: ["arm64", "x64"], type: "brew", name: "llvm" },
|
|
877
|
+
]
|
|
878
|
+
*/
|
|
879
|
+
|
|
880
|
+
let platform = os.platform()
|
|
881
|
+
let arch = os.arch()
|
|
882
|
+
let gpu = this.kernel.gpu
|
|
883
|
+
let relevant = {
|
|
884
|
+
platform: false,
|
|
885
|
+
arch: false,
|
|
886
|
+
gpu: false,
|
|
887
|
+
}
|
|
888
|
+
if (r.platform) {
|
|
889
|
+
if (Array.isArray(r.platform)) {
|
|
890
|
+
// multiple items
|
|
891
|
+
if (r.platform.includes(platform)) {
|
|
892
|
+
relevant.platform = true
|
|
893
|
+
}
|
|
894
|
+
} else {
|
|
895
|
+
// one item
|
|
896
|
+
if (r.platform === platform) {
|
|
897
|
+
relevant.platform = true
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
} else {
|
|
901
|
+
// all platforms
|
|
902
|
+
relevant.platform = true
|
|
903
|
+
}
|
|
904
|
+
if (r.arch) {
|
|
905
|
+
if (Array.isArray(r.arch)) {
|
|
906
|
+
// multiple items
|
|
907
|
+
if (r.arch.includes(arch)) {
|
|
908
|
+
relevant.arch = true
|
|
909
|
+
}
|
|
910
|
+
} else {
|
|
911
|
+
// one item
|
|
912
|
+
if (r.arch === arch) {
|
|
913
|
+
relevant.arch = true
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
} else {
|
|
917
|
+
// all platforms
|
|
918
|
+
relevant.arch = true
|
|
919
|
+
}
|
|
920
|
+
if (r.gpu) {
|
|
921
|
+
if (Array.isArray(r.gpu)) {
|
|
922
|
+
// multiple items
|
|
923
|
+
if (r.gpu.includes(gpu)) {
|
|
924
|
+
relevant.gpu = true
|
|
925
|
+
}
|
|
926
|
+
} else {
|
|
927
|
+
// one item
|
|
928
|
+
if (r.gpu === gpu) {
|
|
929
|
+
relevant.gpu = true
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
} else {
|
|
933
|
+
// all platforms
|
|
934
|
+
relevant.gpu = true
|
|
935
|
+
}
|
|
936
|
+
return relevant.platform && relevant.arch && relevant.gpu
|
|
937
|
+
}
|
|
938
|
+
async check(config) {
|
|
939
|
+
let requirements = this.requirements(config)
|
|
940
|
+
let requirements_pending = !this.installed_initialized
|
|
941
|
+
let install_required = true
|
|
942
|
+
if (!requirements_pending) {
|
|
943
|
+
install_required = false
|
|
944
|
+
for(let i=0; i<requirements.length; i++) {
|
|
945
|
+
let r = requirements[i]
|
|
946
|
+
//let installed = await this.installed(r)
|
|
947
|
+
//requirements[i].installed = installed
|
|
948
|
+
//if (!installed) {
|
|
949
|
+
// install_required = true
|
|
950
|
+
//}
|
|
951
|
+
let relevant = this.relevant(r)
|
|
952
|
+
requirements[i].relevant = relevant
|
|
953
|
+
if (relevant) {
|
|
954
|
+
let dependencies
|
|
955
|
+
if (r.name === "conda") {
|
|
956
|
+
dependencies = config.bin.conda_requirements
|
|
957
|
+
console.log("check dependencies", dependencies)
|
|
958
|
+
requirements[i].dependencies = dependencies
|
|
959
|
+
}
|
|
960
|
+
let installed = await this.check_installed(r, dependencies)
|
|
961
|
+
requirements[i].installed = installed
|
|
962
|
+
if (!installed) {
|
|
963
|
+
install_required = true
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
let error = null
|
|
970
|
+
try {
|
|
971
|
+
this.compatible()
|
|
972
|
+
} catch (e) {
|
|
973
|
+
error = e.message
|
|
974
|
+
install_required = true
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
this.install_required = install_required
|
|
978
|
+
this.requirements_pending = requirements_pending
|
|
979
|
+
|
|
980
|
+
console.log("check_bin finished 2")
|
|
981
|
+
|
|
982
|
+
requirements = requirements.filter((r) => {
|
|
983
|
+
return r.relevant
|
|
984
|
+
})
|
|
985
|
+
|
|
986
|
+
return {
|
|
987
|
+
error,
|
|
988
|
+
requirements,
|
|
989
|
+
install_required,
|
|
990
|
+
requirements_pending
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
}
|
|
994
|
+
winBuildNumber() {
|
|
995
|
+
let osVersion = (/(\d+)\.(\d+)\.(\d+)/g).exec(os.release());
|
|
996
|
+
let buildNumber = 0;
|
|
997
|
+
if (osVersion && osVersion.length === 4) {
|
|
998
|
+
buildNumber = parseInt(osVersion[3]);
|
|
999
|
+
}
|
|
1000
|
+
return buildNumber;
|
|
1001
|
+
}
|
|
1002
|
+
compatible() {
|
|
1003
|
+
if (this.kernel.platform === "win32") {
|
|
1004
|
+
let buildNumber = this.winBuildNumber()
|
|
1005
|
+
if (buildNumber < 18309) {
|
|
1006
|
+
// must use conpty for node-pty, and conpty is only supported in win>=18309
|
|
1007
|
+
console.log("Windows buildNumber", buildNumber)
|
|
1008
|
+
throw new Error(`Pinokio supports Windows release 18309 and up (current system: ${buildNumber}`)
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
// if (buildNumber > 25000) {
|
|
1012
|
+
// console.log("Windows buildNumber", buildNumber)
|
|
1013
|
+
// throw new Error(`Pinokio does not currently support Windows Canary (versions 25000 and up). The current system is ${buildNumber}`)
|
|
1014
|
+
//
|
|
1015
|
+
// }
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
759
1018
|
async sh(params, ondata) {
|
|
760
1019
|
let response = await this.kernel.shell.run(params, null, ondata)
|
|
761
1020
|
return response
|
package/kernel/bin/node.js
CHANGED
|
@@ -3,23 +3,30 @@ const fetch = require('cross-fetch')
|
|
|
3
3
|
const { rimraf } = require('rimraf')
|
|
4
4
|
const decompress = require('decompress');
|
|
5
5
|
class Node {
|
|
6
|
+
cmd() {
|
|
7
|
+
return "nodejs pnpm"
|
|
8
|
+
}
|
|
6
9
|
async install(req, ondata) {
|
|
7
10
|
await this.kernel.bin.exec({
|
|
8
|
-
//message: "conda install -y nodejs=22.12.0 -c conda-forge"
|
|
9
11
|
message: [
|
|
10
12
|
"conda clean -y --all",
|
|
11
13
|
//"conda install -y nodejs=20.17.0 pnpm -c conda-forge"
|
|
12
|
-
|
|
14
|
+
`conda install -y -c conda-forge ${this.cmd()}`
|
|
13
15
|
]
|
|
14
|
-
// conda: {
|
|
15
|
-
// name: "base",
|
|
16
|
-
// activate: "minimal"
|
|
17
|
-
// }
|
|
18
16
|
}, ondata)
|
|
19
17
|
}
|
|
20
18
|
async installed() {
|
|
21
19
|
return this.kernel.bin.installed.conda.has("nodejs") && this.kernel.bin.installed.conda.has("pnpm")
|
|
22
20
|
}
|
|
21
|
+
env() {
|
|
22
|
+
return {
|
|
23
|
+
PATH: [this.kernel.path("bin/npm"), this.kernel.path("bin/npm/bin")],
|
|
24
|
+
NPM_CONFIG_PREFIX: this.kernel.path("bin/npm"),
|
|
25
|
+
npm_config_prefix: this.kernel.path("bin/npm"),
|
|
26
|
+
PNPM_HOME: this.kernel.path("bin/npm"),
|
|
27
|
+
pnpm_home: this.kernel.path("bin/npm"),
|
|
28
|
+
}
|
|
29
|
+
}
|
|
23
30
|
async uninstall(req, ondata) {
|
|
24
31
|
await this.kernel.bin.exec({
|
|
25
32
|
message: "conda remove nodejs pnpm",
|
package/kernel/bin/py.js
CHANGED