pinokiod 1.3.39 → 1.3.41
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/cloudflare/index.js +1 -3
- package/kernel/api/fs/index.js +30 -5
- package/kernel/api/index.js +40 -24
- package/kernel/api/local/index.js +43 -0
- package/kernel/api/proxy/index.js +16 -2
- package/kernel/api/shell/index.js +10 -0
- package/kernel/environment.js +138 -0
- package/kernel/index.js +35 -49
- package/kernel/shell.js +4 -46
- package/kernel/util.js +22 -0
- package/package.json +2 -1
- package/server/index.js +69 -40
- package/server/views/editor.ejs +22 -12
|
@@ -24,7 +24,6 @@ class C {
|
|
|
24
24
|
let options = {}
|
|
25
25
|
if (req.cwd) options.cwd = req.cwd
|
|
26
26
|
if (req.parent && req.parent.path) options.group = req.parent.path
|
|
27
|
-
console.log("shells before", kernel.shell.shells)
|
|
28
27
|
let pattern = /(https:.+?trycloudflare\.com)/
|
|
29
28
|
let cloudflare_url = await new Promise((resolve, reject) => {
|
|
30
29
|
kernel.shell.start(params, options, (e) => {
|
|
@@ -35,9 +34,8 @@ class C {
|
|
|
35
34
|
}
|
|
36
35
|
})
|
|
37
36
|
})
|
|
38
|
-
console.log("cloudflare_url", cloudflare_url)
|
|
39
37
|
|
|
40
|
-
ondata({ raw: yellow("\r\n## Scan the QR code to open in any device\r\n\r\n") })
|
|
38
|
+
ondata({ raw: yellow("\r\n## [CLOUDFLARE SHARING] Scan the QR code to open in any device\r\n\r\n") })
|
|
41
39
|
ondata({ raw: blue(`${cloudflare_url}\r\n\r\n`) })
|
|
42
40
|
|
|
43
41
|
await new Promise((resolve, reject) => {
|
package/kernel/api/fs/index.js
CHANGED
|
@@ -9,7 +9,8 @@ const randomUseragent = require('random-useragent');
|
|
|
9
9
|
const symlinkDir = require('symlink-dir')
|
|
10
10
|
const retry = require('async-retry');
|
|
11
11
|
const { createHash } = require('crypto');
|
|
12
|
-
|
|
12
|
+
const Environment = require("../../environment")
|
|
13
|
+
const Util = require("../../util")
|
|
13
14
|
|
|
14
15
|
const log = (msgs, ondata) => {
|
|
15
16
|
for(let msg of msgs) {
|
|
@@ -127,6 +128,22 @@ class FS {
|
|
|
127
128
|
|
|
128
129
|
ondata({ raw: "\r\ncreating a shared drive:\r\n" + JSON.stringify(req.params, null, 2).replace(/\n/g, "\r\n") })
|
|
129
130
|
|
|
131
|
+
|
|
132
|
+
let api_path = await Util.api_path(req.parent.path, kernel)
|
|
133
|
+
let current_env = await Environment.get(api_path)
|
|
134
|
+
let default_env = await Environment.get(kernel.homedir)
|
|
135
|
+
current_env = Object.assign(process.env, default_env, current_env)
|
|
136
|
+
|
|
137
|
+
let env_drive_path = current_env.PINOKIO_DRIVE
|
|
138
|
+
let drive_home
|
|
139
|
+
if (env_drive_path) {
|
|
140
|
+
let api_path = `${kernel.homedir}${path.sep}api`
|
|
141
|
+
let rel_path = path.relative(api_path, req.parent.path)
|
|
142
|
+
let api_name = rel_path.split(path.sep)[0]
|
|
143
|
+
let current_api_path = `${api_path}${path.sep}${api_name}`
|
|
144
|
+
drive_home = path.resolve(current_api_path, env_drive_path)
|
|
145
|
+
}
|
|
146
|
+
|
|
130
147
|
if (req.params.venv) {
|
|
131
148
|
// pip sharing
|
|
132
149
|
// 1. get all pip items
|
|
@@ -150,7 +167,7 @@ class FS {
|
|
|
150
167
|
// symlink:
|
|
151
168
|
// from => :package_path
|
|
152
169
|
// to => /drives/packages/pip/:package_name/:package_version
|
|
153
|
-
const drivePath = kernel.path("drive")
|
|
170
|
+
const drivePath = drive_home || kernel.path("drive")
|
|
154
171
|
const drive = new Pdrive(drivePath)
|
|
155
172
|
for(let name in res) {
|
|
156
173
|
/*
|
|
@@ -259,10 +276,18 @@ class FS {
|
|
|
259
276
|
}
|
|
260
277
|
|
|
261
278
|
for(let relpath of copy) {
|
|
262
|
-
|
|
279
|
+
if (drive_home) {
|
|
280
|
+
d.copy[relpath] = path.resolve(drive_home, p, relpath)
|
|
281
|
+
} else {
|
|
282
|
+
d.copy[relpath] = kernel.path("drive", p, relpath)
|
|
283
|
+
}
|
|
263
284
|
}
|
|
264
285
|
for(let relpath of move) {
|
|
265
|
-
|
|
286
|
+
if (drive_home) {
|
|
287
|
+
d.move[relpath] = path.resolve(drive_home, p, relpath)
|
|
288
|
+
} else {
|
|
289
|
+
d.move[relpath] = kernel.path("drive", p, relpath)
|
|
290
|
+
}
|
|
266
291
|
}
|
|
267
292
|
ondata({
|
|
268
293
|
raw: "\r\nLINKING DRIVES:\r\n" + JSON.stringify(d, null, 2).replace(/\n/g, "\r\n")
|
|
@@ -279,7 +304,7 @@ class FS {
|
|
|
279
304
|
|
|
280
305
|
}
|
|
281
306
|
} else if (req.params.drive) {
|
|
282
|
-
const drivePath = kernel.path("drive")
|
|
307
|
+
const drivePath = drive_home || kernel.path("drive")
|
|
283
308
|
const drive = new Pdrive(drivePath)
|
|
284
309
|
for(const route in req.params.drive) {
|
|
285
310
|
const link = req.params.drive[route]
|
package/kernel/api/index.js
CHANGED
|
@@ -560,6 +560,7 @@ class Api {
|
|
|
560
560
|
// 6. rpc must have method names
|
|
561
561
|
if (rpc.method) {
|
|
562
562
|
|
|
563
|
+
|
|
563
564
|
// 7. resolve the rpc
|
|
564
565
|
let resolved = await this.resolveMethod(rpc, cwd)
|
|
565
566
|
|
|
@@ -666,31 +667,46 @@ class Api {
|
|
|
666
667
|
data: rpc
|
|
667
668
|
})
|
|
668
669
|
|
|
669
|
-
//
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
670
|
+
// DEPRECATED APIS
|
|
671
|
+
// If deprecated, just ignore and move on
|
|
672
|
+
const deprecated = [
|
|
673
|
+
"proxy.start"
|
|
674
|
+
]
|
|
675
|
+
|
|
676
|
+
|
|
677
|
+
let result
|
|
678
|
+
if (deprecated.includes(rpc.method)) {
|
|
679
|
+
const msg = `DEPRECATED API ${rpc.method}. Ignored`
|
|
680
|
+
console.log(msg)
|
|
681
|
+
} else {
|
|
682
|
+
// 11. actually make the rpc call
|
|
683
|
+
result = await this.run(resolved.method, rpc, (stream, type) => {
|
|
684
|
+
let m = {
|
|
685
|
+
id: request.path,
|
|
686
|
+
caller: request.caller,
|
|
687
|
+
type: (type ? type : "stream"),
|
|
688
|
+
index: i,
|
|
689
|
+
total,
|
|
690
|
+
data: stream,
|
|
691
|
+
rpc,
|
|
692
|
+
rawrpc
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
// if (["input", "modal"].includes(m.type)) {
|
|
696
|
+
// // if a message requires user feedback, do not modify id
|
|
697
|
+
// } else {
|
|
698
|
+
// // if a message does not require user feedback
|
|
699
|
+
// // if the current session has a "caller" (parent process),
|
|
700
|
+
// // set the id to request.caller so the terminal prints the logs
|
|
701
|
+
// if (request.caller) {
|
|
702
|
+
// m.id = request.caller
|
|
703
|
+
// }
|
|
704
|
+
// }
|
|
705
|
+
this.ondata(m)
|
|
706
|
+
})
|
|
707
|
+
}
|
|
708
|
+
|
|
681
709
|
|
|
682
|
-
// if (["input", "modal"].includes(m.type)) {
|
|
683
|
-
// // if a message requires user feedback, do not modify id
|
|
684
|
-
// } else {
|
|
685
|
-
// // if a message does not require user feedback
|
|
686
|
-
// // if the current session has a "caller" (parent process),
|
|
687
|
-
// // set the id to request.caller so the terminal prints the logs
|
|
688
|
-
// if (request.caller) {
|
|
689
|
-
// m.id = request.caller
|
|
690
|
-
// }
|
|
691
|
-
// }
|
|
692
|
-
this.ondata(m)
|
|
693
|
-
})
|
|
694
710
|
|
|
695
711
|
if (result && rpc.returns) {
|
|
696
712
|
// set the scope variable from the return value
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
const set = require("../set")
|
|
2
2
|
const rm = require("../rm")
|
|
3
|
+
const Cloudflare = require("../cloudflare")
|
|
4
|
+
const Proxy = require('../proxy')
|
|
5
|
+
const Environment = require('../../environment')
|
|
6
|
+
const Util = require("../../util")
|
|
3
7
|
class Local {
|
|
4
8
|
async import(req, ondata, kernel) {
|
|
5
9
|
/*
|
|
@@ -48,6 +52,45 @@ class Local {
|
|
|
48
52
|
}
|
|
49
53
|
})
|
|
50
54
|
let res = await set(converted, ondata, kernel)
|
|
55
|
+
|
|
56
|
+
// handle special local variables
|
|
57
|
+
/*
|
|
58
|
+
req :- {
|
|
59
|
+
method: "set",
|
|
60
|
+
params: {
|
|
61
|
+
"url": k
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
let api_path = await Util.api_path(req.parent.path, kernel)
|
|
67
|
+
let current_env = await Environment.get(api_path)
|
|
68
|
+
let default_env = await Environment.get(kernel.homedir)
|
|
69
|
+
current_env = Object.assign(process.env, default_env, current_env)
|
|
70
|
+
|
|
71
|
+
// if the key at current_env.PINOKIO_SHARE_VAR (by default it's 'url') is the variable being set, trigger the share logic
|
|
72
|
+
if (current_env.PINOKIO_SHARE_VAR && current_env.PINOKIO_SHARE_VAR in req.params) {
|
|
73
|
+
// the share logic is triggered ONLY IF the env.PINOKIO_SHARE is non-empty and contains "cloudflare", "local", or "cloudflare,local"
|
|
74
|
+
const KEY = current_env.PINOKIO_SHARE_VAR
|
|
75
|
+
if ("PINOKIO_SHARE_CLOUDFLARE" in current_env) {
|
|
76
|
+
let val = current_env.PINOKIO_SHARE_CLOUDFLARE.trim().toLowerCase()
|
|
77
|
+
if (val === "true" || val === "1") {
|
|
78
|
+
const c = new Cloudflare()
|
|
79
|
+
req.params.uri = req.params[KEY]
|
|
80
|
+
await c.tunnel(req, ondata, kernel)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if ("PINOKIO_SHARE_LOCAL" in current_env) {
|
|
84
|
+
let val = current_env.PINOKIO_SHARE_LOCAL.trim().toLowerCase()
|
|
85
|
+
if (val === "true" || val === "1") {
|
|
86
|
+
const p = new Proxy()
|
|
87
|
+
req.params.name = "Local Sharing",
|
|
88
|
+
req.params.uri = req.params[KEY]
|
|
89
|
+
await p.start(req, ondata, kernel)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
51
94
|
return res
|
|
52
95
|
}
|
|
53
96
|
async rm(req, ondata, kernel) {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const { yellow, green, blue } = require('kleur');
|
|
2
|
+
const QRCode = require('qrcode');
|
|
1
3
|
class P {
|
|
2
4
|
async start (req, ondata, kernel) {
|
|
3
5
|
/*
|
|
@@ -16,14 +18,26 @@ class P {
|
|
|
16
18
|
// if exists, don't do anything
|
|
17
19
|
} catch (e) {
|
|
18
20
|
ondata({
|
|
19
|
-
raw: `\r\n[Start
|
|
21
|
+
raw: `\r\n[Start Local Sharing]\r\n`
|
|
20
22
|
})
|
|
21
23
|
let { name, uri, ...o } = req.params
|
|
22
24
|
console.log("proxy.start", { name, uri, o })
|
|
23
25
|
let response = await kernel.api.startProxy(req.parent.path, req.params.uri, req.params.name, o)
|
|
24
26
|
|
|
27
|
+
ondata({ raw: yellow("\r\n## [LOCAL NETWORK SHARING] Scan the QR code to open in any device\r\n\r\n") })
|
|
25
28
|
ondata({
|
|
26
|
-
raw:
|
|
29
|
+
raw: `${blue(response.proxy)}\r\n\r\n`
|
|
30
|
+
})
|
|
31
|
+
await new Promise((resolve, reject) => {
|
|
32
|
+
QRCode.toString(response.proxy, {
|
|
33
|
+
type: "terminal"
|
|
34
|
+
}, function(err, data) {
|
|
35
|
+
ondata({ raw: green(data.replaceAll("\n", "\r\n")) })
|
|
36
|
+
ondata({ raw: "\r\n" })
|
|
37
|
+
setTimeout(() => {
|
|
38
|
+
resolve()
|
|
39
|
+
}, 2000)
|
|
40
|
+
});
|
|
27
41
|
})
|
|
28
42
|
|
|
29
43
|
return response
|
|
@@ -37,6 +37,10 @@ class Shell {
|
|
|
37
37
|
req.params.cols = req.client.cols
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
if (req.params) {
|
|
41
|
+
req.params.$parent = req.parent
|
|
42
|
+
}
|
|
43
|
+
|
|
40
44
|
// // create a persistent session
|
|
41
45
|
// req.params.persistent = true
|
|
42
46
|
|
|
@@ -85,6 +89,9 @@ class Shell {
|
|
|
85
89
|
if (!req.params.id) {
|
|
86
90
|
req.params.id = req.cwd
|
|
87
91
|
}
|
|
92
|
+
if (req.params) {
|
|
93
|
+
req.params.$parent = req.parent
|
|
94
|
+
}
|
|
88
95
|
|
|
89
96
|
console.log("#### shell.enter", req.params)
|
|
90
97
|
|
|
@@ -111,6 +118,9 @@ class Shell {
|
|
|
111
118
|
}
|
|
112
119
|
}
|
|
113
120
|
*/
|
|
121
|
+
if (req.params) {
|
|
122
|
+
req.params.$parent = req.parent
|
|
123
|
+
}
|
|
114
124
|
let options = {}
|
|
115
125
|
if (req.cwd) options.cwd = req.cwd
|
|
116
126
|
if (req.parent && req.parent.path) options.group = req.parent.path
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
const path = require('path')
|
|
2
|
+
const fs = require('fs')
|
|
3
|
+
const util = require('./util')
|
|
4
|
+
const ENVS = [{
|
|
5
|
+
type: "cache_folder",
|
|
6
|
+
key: "HF_HOME",
|
|
7
|
+
}, {
|
|
8
|
+
type: "cache_folder",
|
|
9
|
+
key: "TORCH_HOME",
|
|
10
|
+
}, {
|
|
11
|
+
type: "cache_folder",
|
|
12
|
+
key: "HOMEBREW_CACHE",
|
|
13
|
+
}, {
|
|
14
|
+
type: "cache_folder",
|
|
15
|
+
key: "XDG_CACHE_HOME",
|
|
16
|
+
}, {
|
|
17
|
+
type: "cache_folder",
|
|
18
|
+
key: "PIP_CACHE_DIR",
|
|
19
|
+
}, {
|
|
20
|
+
type: "cache_folder",
|
|
21
|
+
key: "PIP_TMPDIR",
|
|
22
|
+
}, {
|
|
23
|
+
type: "cache_folder",
|
|
24
|
+
key: "TMPDIR",
|
|
25
|
+
}, {
|
|
26
|
+
type: "cache_folder",
|
|
27
|
+
key: "TEMP",
|
|
28
|
+
}, {
|
|
29
|
+
type: "cache_folder",
|
|
30
|
+
key: "TMP",
|
|
31
|
+
}, {
|
|
32
|
+
type: "cache_folder",
|
|
33
|
+
key: "XDG_DATA_HOME",
|
|
34
|
+
}, {
|
|
35
|
+
type: "cache_folder",
|
|
36
|
+
key: "XDG_CONFIG_HOME",
|
|
37
|
+
}, {
|
|
38
|
+
type: "cache_folder",
|
|
39
|
+
key: "XDG_STATE_HOME",
|
|
40
|
+
}, {
|
|
41
|
+
type: "cache_folder",
|
|
42
|
+
key: "GRADIO_TEMP_DIR",
|
|
43
|
+
}, {
|
|
44
|
+
key: "PIP_CONFIG_FILE",
|
|
45
|
+
val: (home) => {
|
|
46
|
+
return path.resolve(home, "pipconfig")
|
|
47
|
+
}
|
|
48
|
+
}, {
|
|
49
|
+
key: "CONDARC",
|
|
50
|
+
val: (home) => {
|
|
51
|
+
return path.resolve(home, "condarc")
|
|
52
|
+
},
|
|
53
|
+
}, {
|
|
54
|
+
key: "PS1",
|
|
55
|
+
val: (home) => {
|
|
56
|
+
return "<<PINOKIO SHELL>> "
|
|
57
|
+
},
|
|
58
|
+
}, {
|
|
59
|
+
key: "PINOKIO_SHARE_VAR",
|
|
60
|
+
val: (home) => {
|
|
61
|
+
return "url"
|
|
62
|
+
},
|
|
63
|
+
}, {
|
|
64
|
+
type: "folder",
|
|
65
|
+
key: "PINOKIO_DRIVE",
|
|
66
|
+
val: (home) => {
|
|
67
|
+
return path.resolve(home, "drive")
|
|
68
|
+
}
|
|
69
|
+
}];
|
|
70
|
+
const folders = ENVS.filter((env) => {
|
|
71
|
+
return env.type === "cache_folder" || env.type === "folder"
|
|
72
|
+
}).map((e) => {
|
|
73
|
+
return e.key
|
|
74
|
+
})
|
|
75
|
+
const ENV = (homedir) => {
|
|
76
|
+
const lines = ENVS.map((e) => {
|
|
77
|
+
if (e.type) {
|
|
78
|
+
if (e.type === "cache_folder") {
|
|
79
|
+
return `${e.key}=${path.resolve(homedir, "cache", e.key)}`
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
if (e.val) {
|
|
83
|
+
return `${e.key}=${e.val(homedir)}`
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
return lines.join("\n")
|
|
88
|
+
}
|
|
89
|
+
const APP_ENV = () => {
|
|
90
|
+
const items = [
|
|
91
|
+
"####################################################################",
|
|
92
|
+
"# GRADIO_TEMP_DIR",
|
|
93
|
+
"# All files uploaded through gradio goes here.",
|
|
94
|
+
"# Delete or comment this line",
|
|
95
|
+
"GRADIO_TEMP_DIR=cache/GRADIO_TEMP_DIR",
|
|
96
|
+
"",
|
|
97
|
+
"####################################################################",
|
|
98
|
+
"# PINOKIO_SHARE_LOCAL",
|
|
99
|
+
"# Set this variable to true to share the app on the local network.",
|
|
100
|
+
"PINOKIO_SHARE_LOCAL=true",
|
|
101
|
+
"",
|
|
102
|
+
"####################################################################",
|
|
103
|
+
"# PINOKIO_SHARE_CLOUDFLARE",
|
|
104
|
+
"# Set this variable to share the app publicly via cloudflare tunnel.",
|
|
105
|
+
"PINOKIO_SHARE_CLOUDFLARE=false",
|
|
106
|
+
]
|
|
107
|
+
return items.join("\n")
|
|
108
|
+
}
|
|
109
|
+
const init_folders = async (homedir) => {
|
|
110
|
+
// get the environment object from homedir
|
|
111
|
+
const current_env = await get(homedir)
|
|
112
|
+
|
|
113
|
+
// filter out only the folder keys
|
|
114
|
+
|
|
115
|
+
// create folders
|
|
116
|
+
for(let key in current_env) {
|
|
117
|
+
// env key included in folders
|
|
118
|
+
if (folders.includes(key)) {
|
|
119
|
+
// mkdir
|
|
120
|
+
let full_path = path.resolve(homedir, current_env[key])
|
|
121
|
+
await fs.promises.mkdir(full_path, { recursive: true }).catch((e) => {})
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const get = async (homedir) => {
|
|
127
|
+
const env_path = path.resolve(homedir, "ENVIRONMENT")
|
|
128
|
+
const current_env = await util.parse_env(env_path)
|
|
129
|
+
// if the key is a folder/cache_folder type, resolve the path
|
|
130
|
+
for(let key in current_env) {
|
|
131
|
+
if (folders.includes(key)) {
|
|
132
|
+
let full_path = path.resolve(homedir, current_env[key])
|
|
133
|
+
current_env[key] = full_path
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return current_env
|
|
137
|
+
}
|
|
138
|
+
module.exports = { ENV, get, init_folders, APP_ENV }
|
package/kernel/index.js
CHANGED
|
@@ -7,7 +7,6 @@ const fastq = require('fastq')
|
|
|
7
7
|
const fetch = require('cross-fetch');
|
|
8
8
|
const waitOn = require('wait-on');
|
|
9
9
|
const system = require('systeminformation');
|
|
10
|
-
//const hostile = require('hostile');
|
|
11
10
|
const Sysinfo = require('./sysinfo')
|
|
12
11
|
const portfinder = require('portfinder');
|
|
13
12
|
const Loader = require("./loader")
|
|
@@ -19,6 +18,8 @@ const Template = require('jimini')
|
|
|
19
18
|
const Shells = require("./shells")
|
|
20
19
|
const Key = require("./key")
|
|
21
20
|
const Script = require('./script')
|
|
21
|
+
const Environment = require("./environment")
|
|
22
|
+
const Util = require('./util')
|
|
22
23
|
const Config = require("./pinokio.json")
|
|
23
24
|
const VARS = {
|
|
24
25
|
pip: {
|
|
@@ -30,7 +31,7 @@ const VARS = {
|
|
|
30
31
|
//const memwatch = require('@airbnb/node-memwatch');
|
|
31
32
|
class Kernel {
|
|
32
33
|
//schema = ">=1.0.0"
|
|
33
|
-
schema = "<=1.
|
|
34
|
+
schema = "<=1.7.0"
|
|
34
35
|
constructor(store) {
|
|
35
36
|
this.fetch = fetch
|
|
36
37
|
this.store = store
|
|
@@ -40,6 +41,7 @@ class Kernel {
|
|
|
40
41
|
this.key = new Key()
|
|
41
42
|
this.jsdom = jsdom
|
|
42
43
|
this.exposed = {}
|
|
44
|
+
this.envs = {}
|
|
43
45
|
}
|
|
44
46
|
resumeprocess(uri) {
|
|
45
47
|
let proc = this.procs[uri]
|
|
@@ -99,7 +101,6 @@ class Kernel {
|
|
|
99
101
|
return portfinder.getPortPromise()
|
|
100
102
|
}
|
|
101
103
|
path(...args) {
|
|
102
|
-
console.log("ARGS", args)
|
|
103
104
|
return path.resolve(this.homedir, ...args)
|
|
104
105
|
}
|
|
105
106
|
exists(...args) {
|
|
@@ -173,7 +174,8 @@ class Kernel {
|
|
|
173
174
|
await waitOn(options)
|
|
174
175
|
}
|
|
175
176
|
|
|
176
|
-
async init() {
|
|
177
|
+
async init(options) {
|
|
178
|
+
this.port = options.port
|
|
177
179
|
let home = this.store.get("home")
|
|
178
180
|
|
|
179
181
|
// reset shells if they exist
|
|
@@ -237,30 +239,32 @@ class Kernel {
|
|
|
237
239
|
}
|
|
238
240
|
this.procs = {}
|
|
239
241
|
this.template = new Template()
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
242
|
try {
|
|
244
243
|
if (this.homedir) {
|
|
244
|
+
|
|
245
|
+
// 0. create homedir
|
|
245
246
|
await fs.promises.mkdir(this.homedir, { recursive: true }).catch((e) => {})
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
"
|
|
253
|
-
"TMPDIR",
|
|
254
|
-
"TEMP",
|
|
255
|
-
"TMP",
|
|
256
|
-
"XDG_DATA_HOME",
|
|
257
|
-
"XDG_CONFIG_HOME",
|
|
258
|
-
"XDG_STATE_HOME",
|
|
259
|
-
"GRADIO_TEMP_DIR"
|
|
260
|
-
]
|
|
261
|
-
for(let folder of cache_folders) {
|
|
262
|
-
await fs.promises.mkdir(path.resolve(this.homedir, "cache", folder), { recursive: true }).catch((e) => {})
|
|
247
|
+
|
|
248
|
+
// 1. check if ENVIRONMENT exists
|
|
249
|
+
// if it doesn't exist, write to ~/pinokio/ENVIRONMENT
|
|
250
|
+
let e = await this.exists(this.homedir, "ENVIRONMENT")
|
|
251
|
+
if (!e) {
|
|
252
|
+
let str = Environment.ENV(this.homedir)
|
|
253
|
+
await fs.promises.writeFile(path.resolve(this.homedir, "ENVIRONMENT"), str)
|
|
263
254
|
}
|
|
255
|
+
// 2. mkdir all the folders if not already created
|
|
256
|
+
await Environment.init_folders(this.homedir)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
// // 3. check if Caddyfile exists
|
|
260
|
+
// let e2 = await this.exists(this.homedir, "Caddyfile")
|
|
261
|
+
// if (!e2) {
|
|
262
|
+
// let str = `pinokio.local {
|
|
263
|
+
// reverse_proxy localhost:${this.port}
|
|
264
|
+
//}`
|
|
265
|
+
// await fs.promises.writeFile(path.resolve(this.homedir, "Caddyfile"), str)
|
|
266
|
+
// }
|
|
267
|
+
|
|
264
268
|
|
|
265
269
|
}
|
|
266
270
|
|
|
@@ -301,34 +305,16 @@ class Kernel {
|
|
|
301
305
|
// userDataDir: this.bin.path("puppet")
|
|
302
306
|
// });
|
|
303
307
|
|
|
304
|
-
|
|
305
|
-
// set hosts
|
|
306
|
-
//hostile.get(false, async (err, lines) => {
|
|
307
|
-
// if (err) {
|
|
308
|
-
// console.error(err.message)
|
|
309
|
-
// }
|
|
310
|
-
// let hostSet
|
|
311
|
-
// for(let line of lines) {
|
|
312
|
-
// if (line.includes("pinokio.network")) {
|
|
313
|
-
// hostSet = true
|
|
314
|
-
// }
|
|
315
|
-
// }
|
|
316
|
-
// console.log({ hostSet })
|
|
317
|
-
// if (!hostSet) {
|
|
318
|
-
// console.log("setting hosts")
|
|
319
|
-
// await this.exec({
|
|
320
|
-
// sudo: true,
|
|
321
|
-
// message: "npx hostile set 127.0.0.1 pinokio.network"
|
|
322
|
-
// }, (e) => {
|
|
323
|
-
// console.log(e)
|
|
324
|
-
// })
|
|
325
|
-
// console.log("success")
|
|
326
|
-
// }
|
|
327
|
-
//})
|
|
328
|
-
|
|
329
308
|
} catch (e) {
|
|
330
309
|
console.log("### ERROR", e)
|
|
331
310
|
}
|
|
311
|
+
|
|
312
|
+
// await this.exec({
|
|
313
|
+
// message: "caddy run",
|
|
314
|
+
// path: this.homedir
|
|
315
|
+
// }, (e) => {
|
|
316
|
+
// process.stdout.write(e.raw)
|
|
317
|
+
// })
|
|
332
318
|
}
|
|
333
319
|
async update_sysinfo() {
|
|
334
320
|
try {
|
package/kernel/shell.js
CHANGED
|
@@ -12,6 +12,8 @@ const path = require("path")
|
|
|
12
12
|
const sudo = require("sudo-prompt-programfiles-x86");
|
|
13
13
|
const unparse = require('yargs-unparser-custom-flag');
|
|
14
14
|
const shellPath = require('shell-path');
|
|
15
|
+
const util = require('./util')
|
|
16
|
+
const Environment = require('./environment')
|
|
15
17
|
const home = os.homedir()
|
|
16
18
|
class Shell {
|
|
17
19
|
/*
|
|
@@ -111,25 +113,8 @@ class Shell {
|
|
|
111
113
|
this.env.CMAKE_OBJECT_PATH_MAX = 1024
|
|
112
114
|
|
|
113
115
|
// Well Known Cache
|
|
114
|
-
|
|
115
|
-
this.env
|
|
116
|
-
this.env.HOMEBREW_CACHE = path.resolve(this.kernel.homedir, "cache", "TORCH_HOME")
|
|
117
|
-
this.env.XDG_CACHE_HOME = path.resolve(this.kernel.homedir, "cache", "XDG_CACHE_HOME")
|
|
118
|
-
this.env.PIP_CACHE_DIR = path.resolve(this.kernel.homedir, "cache", "PIP_CACHE_DIR")
|
|
119
|
-
this.env.PIP_TMPDIR = path.resolve(this.kernel.homedir, "cache", "PIP_TMPDIR")
|
|
120
|
-
this.env.TMPDIR = path.resolve(this.kernel.homedir, "cache", "TMPDIR")
|
|
121
|
-
this.env.TEMP = path.resolve(this.kernel.homedir, "cache", "TEMP")
|
|
122
|
-
this.env.TMP = path.resolve(this.kernel.homedir, "cache", "TMP")
|
|
123
|
-
this.env.XDG_DATA_HOME = path.resolve(this.kernel.homedir, "cache", "XDG_DATA_HOME")
|
|
124
|
-
this.env.XDG_CONFIG_HOME = path.resolve(this.kernel.homedir, "cache", "XDG_CONFIG_HOME")
|
|
125
|
-
this.env.XDG_STATE_HOME = path.resolve(this.kernel.homedir, "cache", "XDG_STATE_HOME")
|
|
126
|
-
this.env.GRADIO_TEMP_DIR = path.resolve(this.kernel.homedir, "cache", "GRADIO_TEMP_DIR")
|
|
127
|
-
this.env.PIP_CONFIG_FILE = path.resolve(this.kernel.homedir, "pipconfig")
|
|
128
|
-
this.env.CONDARC = path.resolve(this.kernel.homedir, "condarc")
|
|
129
|
-
|
|
130
|
-
this.env.PS1 = "<<PINOKIO SHELL>> "
|
|
131
|
-
// this.env.PROMPT_COMMAND = "export PS1=\"<<PINOKIO SHELL>> \""
|
|
132
|
-
|
|
116
|
+
let home_env = await Environment.get(this.kernel.homedir)
|
|
117
|
+
this.env = Object.assign(this.env, home_env)
|
|
133
118
|
let PATH_KEY;
|
|
134
119
|
if (this.env.Path) {
|
|
135
120
|
PATH_KEY = "Path"
|
|
@@ -149,32 +134,6 @@ class Shell {
|
|
|
149
134
|
|
|
150
135
|
this.env[PATH_KEY] = this.env[PATH_KEY] + path.delimiter + path.resolve(this.kernel.homedir, 'bin')
|
|
151
136
|
|
|
152
|
-
// custom env was passed in
|
|
153
|
-
|
|
154
|
-
// override cache folders if cache is specified
|
|
155
|
-
if (params.cache) {
|
|
156
|
-
// cache data files
|
|
157
|
-
let cache_path = path.resolve(params.path, params.cache)
|
|
158
|
-
let types = [
|
|
159
|
-
"HF_HOME", // huggingface models
|
|
160
|
-
"TORCH_HOME", // torch hub models
|
|
161
|
-
"GRADIO_TEMP_DIR" // gradio data
|
|
162
|
-
// "XDG_CACHE_HOME",
|
|
163
|
-
// "PIP_CACHE_DIR",
|
|
164
|
-
// "TMPDIR",
|
|
165
|
-
// "TEMP",
|
|
166
|
-
// "TMP",
|
|
167
|
-
// "XDG_DATA_HOME",
|
|
168
|
-
// "XDG_CONFIG_HOME",
|
|
169
|
-
// "XDG_STATE_HOME",
|
|
170
|
-
]
|
|
171
|
-
for(let type of types) {
|
|
172
|
-
let p = path.resolve(cache_path, type)
|
|
173
|
-
this.env[type] = p
|
|
174
|
-
await fs.promises.mkdir(p, { recursive: true }).catch((e) => { })
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
137
|
|
|
179
138
|
if (params.env) {
|
|
180
139
|
for(let key in params.env) {
|
|
@@ -226,7 +185,6 @@ class Shell {
|
|
|
226
185
|
delete this.env[key]
|
|
227
186
|
}
|
|
228
187
|
}
|
|
229
|
-
|
|
230
188
|
// 3. path => path can be http, relative, absolute
|
|
231
189
|
this.path = params.path
|
|
232
190
|
|
package/kernel/util.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const dotenv = require('dotenv')
|
|
4
|
+
const parse_env = async (filename) => {
|
|
5
|
+
try {
|
|
6
|
+
const buf = await fs.promises.readFile(filename)
|
|
7
|
+
const config = dotenv.parse(buf) // will return an object
|
|
8
|
+
return config
|
|
9
|
+
} catch (e) {
|
|
10
|
+
return {}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const api_path = async (fullpath, kernel) => {
|
|
14
|
+
let api_path = `${kernel.homedir}${path.sep}api`
|
|
15
|
+
let rel_path = path.relative(api_path, fullpath)
|
|
16
|
+
let api_name = rel_path.split(path.sep)[0]
|
|
17
|
+
let current_api_path = `${api_path}${path.sep}${api_name}`
|
|
18
|
+
return current_api_path
|
|
19
|
+
}
|
|
20
|
+
module.exports = {
|
|
21
|
+
parse_env, api_path
|
|
22
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pinokiod",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.41",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"cross-fetch": "^3.1.5",
|
|
20
20
|
"csv-parse": "^5.3.10",
|
|
21
21
|
"decompress": "^4.2.1",
|
|
22
|
+
"dotenv": "^16.4.5",
|
|
22
23
|
"ejs": "^3.1.9",
|
|
23
24
|
"express": "^4.18.2",
|
|
24
25
|
"express-http-proxy-cp": "^2.0.3",
|
package/server/index.js
CHANGED
|
@@ -34,6 +34,7 @@ const ejs = require('ejs');
|
|
|
34
34
|
const Socket = require('./socket')
|
|
35
35
|
const Kernel = require("../kernel")
|
|
36
36
|
const packagejson = require("../package.json")
|
|
37
|
+
const Environment = require("../kernel/environment")
|
|
37
38
|
class Server {
|
|
38
39
|
constructor(config) {
|
|
39
40
|
this.tabs = {}
|
|
@@ -326,6 +327,14 @@ class Server {
|
|
|
326
327
|
// }
|
|
327
328
|
// }
|
|
328
329
|
|
|
330
|
+
if (path.basename(filepath) === "ENVIRONMENT") {
|
|
331
|
+
// if environment.json doesn't exist,
|
|
332
|
+
let exists = await this.exists(filepath)
|
|
333
|
+
if (!exists) {
|
|
334
|
+
let content = await Environment.APP_ENV()
|
|
335
|
+
await fs.promises.writeFile(filepath, content)
|
|
336
|
+
}
|
|
337
|
+
}
|
|
329
338
|
|
|
330
339
|
let stat = await fs.promises.stat(filepath)
|
|
331
340
|
if (pathComponents.length === 0 && req.query.mode === "explore") {
|
|
@@ -353,12 +362,8 @@ class Server {
|
|
|
353
362
|
name: "zip",
|
|
354
363
|
}, {
|
|
355
364
|
type: "conda",
|
|
356
|
-
name: ["nodejs", "ffmpeg"],
|
|
365
|
+
name: ["nodejs", "ffmpeg", ],
|
|
357
366
|
args: "-c conda-forge"
|
|
358
|
-
}, {
|
|
359
|
-
name: "py"
|
|
360
|
-
}, {
|
|
361
|
-
name: "cloudflared"
|
|
362
367
|
}]
|
|
363
368
|
let platform = os.platform()
|
|
364
369
|
if (platform === "win32") {
|
|
@@ -369,11 +374,22 @@ class Server {
|
|
|
369
374
|
name: "vs"
|
|
370
375
|
})
|
|
371
376
|
}
|
|
377
|
+
if (platform === "darwin") {
|
|
378
|
+
requirements.push({
|
|
379
|
+
name: "brew"
|
|
380
|
+
})
|
|
381
|
+
}
|
|
372
382
|
if (this.kernel.gpu === "nvidia") {
|
|
373
383
|
requirements.push({
|
|
374
384
|
name: "cuda"
|
|
375
385
|
})
|
|
376
386
|
}
|
|
387
|
+
requirements = requirements.concat([{
|
|
388
|
+
name: "py"
|
|
389
|
+
}, {
|
|
390
|
+
name: "cloudflared"
|
|
391
|
+
}])
|
|
392
|
+
|
|
377
393
|
let requirements_pending = !this.kernel.bin.installed_initialized
|
|
378
394
|
|
|
379
395
|
|
|
@@ -390,8 +406,6 @@ class Server {
|
|
|
390
406
|
}
|
|
391
407
|
}
|
|
392
408
|
|
|
393
|
-
console.log({ type: 1, requirements })
|
|
394
|
-
|
|
395
409
|
let error = null
|
|
396
410
|
try {
|
|
397
411
|
this.compatible()
|
|
@@ -451,7 +465,6 @@ class Server {
|
|
|
451
465
|
...folders
|
|
452
466
|
})
|
|
453
467
|
} else if (stat.isFile()) {
|
|
454
|
-
|
|
455
468
|
if (req.query && req.query.raw) {
|
|
456
469
|
try {
|
|
457
470
|
// res.setHeader('Content-Disposition', 'inline');
|
|
@@ -511,7 +524,12 @@ class Server {
|
|
|
511
524
|
|
|
512
525
|
let rawpath = `/raw/${pathComponents.join('/')}` + "?frame=true"
|
|
513
526
|
if (editmode) {
|
|
514
|
-
let content
|
|
527
|
+
let content
|
|
528
|
+
try {
|
|
529
|
+
content = await fs.promises.readFile(filepath, "utf8")
|
|
530
|
+
} catch (e) {
|
|
531
|
+
content = ""
|
|
532
|
+
}
|
|
515
533
|
|
|
516
534
|
/********************************************************************
|
|
517
535
|
*
|
|
@@ -614,18 +632,17 @@ class Server {
|
|
|
614
632
|
name: "zip",
|
|
615
633
|
}, {
|
|
616
634
|
type: "conda",
|
|
617
|
-
name: ["nodejs", "ffmpeg"],
|
|
635
|
+
name: ["nodejs", "ffmpeg", ],
|
|
618
636
|
args: "-c conda-forge"
|
|
619
|
-
}, {
|
|
620
|
-
name: "py"
|
|
621
|
-
}, {
|
|
622
|
-
name: "cloudflared"
|
|
623
637
|
}]
|
|
624
638
|
let platform = os.platform()
|
|
625
639
|
if (platform === "win32") {
|
|
626
640
|
requirements.push({
|
|
627
641
|
name: "registry"
|
|
628
642
|
})
|
|
643
|
+
requirements.push({
|
|
644
|
+
name: "vs"
|
|
645
|
+
})
|
|
629
646
|
}
|
|
630
647
|
if (platform === "darwin") {
|
|
631
648
|
requirements.push({
|
|
@@ -637,6 +654,11 @@ class Server {
|
|
|
637
654
|
name: "cuda"
|
|
638
655
|
})
|
|
639
656
|
}
|
|
657
|
+
requirements = requirements.concat([{
|
|
658
|
+
name: "py"
|
|
659
|
+
}, {
|
|
660
|
+
name: "cloudflared"
|
|
661
|
+
}])
|
|
640
662
|
// if (platform === "linux") {
|
|
641
663
|
// requirements.push({
|
|
642
664
|
// name: "brew"
|
|
@@ -745,8 +767,6 @@ class Server {
|
|
|
745
767
|
return r.relevant
|
|
746
768
|
})
|
|
747
769
|
|
|
748
|
-
console.log({ type: 2, requirements })
|
|
749
|
-
|
|
750
770
|
|
|
751
771
|
let mem = this.getMemory(filepath)
|
|
752
772
|
// let localMem = this.kernel.memory.local[filepath]
|
|
@@ -1203,8 +1223,14 @@ class Server {
|
|
|
1203
1223
|
|
|
1204
1224
|
|
|
1205
1225
|
async renderMenu(uri, name, config, pathComponents) {
|
|
1206
|
-
console.log("config.menu =" ,config.menu)
|
|
1207
1226
|
if (config.menu) {
|
|
1227
|
+
|
|
1228
|
+
config.menu = [{
|
|
1229
|
+
text: "Configure",
|
|
1230
|
+
href: "ENVIRONMENT?mode=source",
|
|
1231
|
+
icon: "fa-solid fa-gear"
|
|
1232
|
+
}].concat(config.menu)
|
|
1233
|
+
|
|
1208
1234
|
for(let i=0; i<config.menu.length; i++) {
|
|
1209
1235
|
let menuitem = config.menu[i]
|
|
1210
1236
|
|
|
@@ -1359,31 +1385,34 @@ class Server {
|
|
|
1359
1385
|
return item.btn
|
|
1360
1386
|
})
|
|
1361
1387
|
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
1388
|
|
|
1365
|
-
// get all proxies that belong to this repository
|
|
1366
|
-
let childProxies = []
|
|
1367
|
-
for(let scriptPath in this.kernel.api.proxies) {
|
|
1368
|
-
let proxies = this.kernel.api.proxies[scriptPath]
|
|
1369
|
-
for(let proxy of proxies) {
|
|
1370
|
-
if (scriptPath.startsWith(this.kernel.path("api", name))) {
|
|
1371
|
-
childProxies.push(proxy)
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
}
|
|
1375
1389
|
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
btn: `<i class="fa-solid fa-wifi"></i> <strong>WiFi</strong> - ${proxy.name}`,
|
|
1380
|
-
target: "_blank",
|
|
1381
|
-
href: proxy.proxy
|
|
1382
|
-
})
|
|
1383
|
-
}
|
|
1384
|
-
config.menu = proxyMenu.concat(config.menu)
|
|
1390
|
+
console.log("MENU", config.menu)
|
|
1391
|
+
|
|
1392
|
+
|
|
1385
1393
|
|
|
1386
|
-
|
|
1394
|
+
// // get all proxies that belong to this repository
|
|
1395
|
+
// let childProxies = []
|
|
1396
|
+
// for(let scriptPath in this.kernel.api.proxies) {
|
|
1397
|
+
// let proxies = this.kernel.api.proxies[scriptPath]
|
|
1398
|
+
// for(let proxy of proxies) {
|
|
1399
|
+
// if (scriptPath.startsWith(this.kernel.path("api", name))) {
|
|
1400
|
+
// childProxies.push(proxy)
|
|
1401
|
+
// }
|
|
1402
|
+
// }
|
|
1403
|
+
// }
|
|
1404
|
+
//
|
|
1405
|
+
// let proxyMenu = []
|
|
1406
|
+
// for(let proxy of childProxies) {
|
|
1407
|
+
// proxyMenu.push({
|
|
1408
|
+
// btn: `<i class="fa-solid fa-wifi"></i> <strong>WiFi</strong> - ${proxy.name}`,
|
|
1409
|
+
// target: "_blank",
|
|
1410
|
+
// href: proxy.proxy
|
|
1411
|
+
// })
|
|
1412
|
+
// }
|
|
1413
|
+
// config.menu = proxyMenu.concat(config.menu)
|
|
1414
|
+
//
|
|
1415
|
+
// console.log("MENU", JSON.stringify(config.menu, null, 2))
|
|
1387
1416
|
|
|
1388
1417
|
|
|
1389
1418
|
return config
|
|
@@ -1787,7 +1816,7 @@ class Server {
|
|
|
1787
1816
|
await this.syncConfig()
|
|
1788
1817
|
|
|
1789
1818
|
// initialize kernel
|
|
1790
|
-
await this.kernel.init()
|
|
1819
|
+
await this.kernel.init({ port: this.port})
|
|
1791
1820
|
|
|
1792
1821
|
// start proxy for Pinokio itself
|
|
1793
1822
|
await this.kernel.api.startProxy("/", `http://127.0.0.1:${this.port}`, "/")
|
package/server/views/editor.ejs
CHANGED
|
@@ -129,6 +129,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
129
129
|
maxLines: Infinity, // set to a large number
|
|
130
130
|
minLines: 1 // set to a small number
|
|
131
131
|
});
|
|
132
|
+
console.log("location.pathname", location.pathname)
|
|
132
133
|
<% if (mod) { %>
|
|
133
134
|
<% if (js) { %>
|
|
134
135
|
editor.session.setMode("ace/mode/javascript");
|
|
@@ -136,6 +137,9 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
136
137
|
editor.session.setMode("ace/mode/json");
|
|
137
138
|
<% } %>
|
|
138
139
|
<% } %>
|
|
140
|
+
if (location.pathname.endsWith("ENVIRONMENT")) {
|
|
141
|
+
editor.session.setMode("ace/mode/python");
|
|
142
|
+
}
|
|
139
143
|
//editor.session.setMode("ace/mode/javascript");
|
|
140
144
|
//editor.setValue(file)
|
|
141
145
|
editor.clearSelection()
|
|
@@ -191,14 +195,17 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
191
195
|
this.socket.run({
|
|
192
196
|
method: "kernel.api.stop",
|
|
193
197
|
params: {
|
|
194
|
-
uri: "<%=execUrl%>",
|
|
198
|
+
//uri: "<%=execUrl%>",
|
|
199
|
+
uri: "~" + location.pathname
|
|
195
200
|
}
|
|
196
201
|
}, (stream) => {
|
|
197
202
|
})
|
|
198
203
|
}
|
|
199
204
|
save() {
|
|
200
205
|
return new Promise((resolve, reject) => {
|
|
201
|
-
let cwd = "<%=execUrl%>"
|
|
206
|
+
//let cwd = "<%=execUrl%>"
|
|
207
|
+
let cwd = "~" + location.pathname
|
|
208
|
+
debugger
|
|
202
209
|
this.socket.close()
|
|
203
210
|
this.socket.run({
|
|
204
211
|
method: "fs.write",
|
|
@@ -226,7 +233,8 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
226
233
|
this.socket.run({
|
|
227
234
|
//uri: location.pathname.slice(1).replace("api/", ""),
|
|
228
235
|
//uri: "~" + location.pathname,
|
|
229
|
-
uri: "<%=execUrl%>",
|
|
236
|
+
//uri: "<%=execUrl%>",
|
|
237
|
+
uri: "~" + location.pathname,
|
|
230
238
|
mode,
|
|
231
239
|
input: query,
|
|
232
240
|
client: {
|
|
@@ -689,15 +697,17 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
689
697
|
// await reloadMemory()
|
|
690
698
|
// }
|
|
691
699
|
// })
|
|
692
|
-
document.querySelector("#lv")
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
m.
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
700
|
+
if (document.querySelector("#lv")) {
|
|
701
|
+
document.querySelector("#lv").addEventListener("click", (e) => {
|
|
702
|
+
let m = e.target.closest(".memory")
|
|
703
|
+
m.classList.toggle("collapsed")
|
|
704
|
+
if (m.classList.contains("collapsed")) {
|
|
705
|
+
m.querySelector("i").className = "fa-solid fa-sort-down"
|
|
706
|
+
} else {
|
|
707
|
+
m.querySelector("i").className = "fa-solid fa-sort-up"
|
|
708
|
+
}
|
|
709
|
+
})
|
|
710
|
+
}
|
|
701
711
|
})
|
|
702
712
|
const reloadMemory = async () => {
|
|
703
713
|
let url = "/pinokio/memory?filepath=" + encodeURI("<%-filepath%>")
|