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
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const Common = require('./common')
|
|
2
|
+
class PeerPeerRouter {
|
|
3
|
+
constructor(router) {
|
|
4
|
+
this.router = router
|
|
5
|
+
this.common = new Common(router)
|
|
6
|
+
}
|
|
7
|
+
handle(peer) {
|
|
8
|
+
for(let dial in peer.router) {
|
|
9
|
+
let matches = peer.router[dial]
|
|
10
|
+
let exposed_matches = matches.filter((m) => {
|
|
11
|
+
return m.endsWith(`${peer.name}.localhost`)
|
|
12
|
+
})
|
|
13
|
+
let chunks = dial.split(":")
|
|
14
|
+
let port = chunks[chunks.length-1]
|
|
15
|
+
let exposed_dial = `${peer.host}:${port}` // exposed_dial :- 192.168...
|
|
16
|
+
for(let match of exposed_matches) {
|
|
17
|
+
this.common.handle({
|
|
18
|
+
match,
|
|
19
|
+
dial: exposed_dial,
|
|
20
|
+
host: peer.host
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
module.exports = PeerPeerRouter
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const path = require('path')
|
|
2
|
+
const Processor = require('./processor')
|
|
3
|
+
const Connector = require('./connector')
|
|
4
|
+
class PeerPortRouter extends Processor {
|
|
5
|
+
constructor(router) {
|
|
6
|
+
super()
|
|
7
|
+
this.router = router
|
|
8
|
+
this.connector = new Connector(router)
|
|
9
|
+
}
|
|
10
|
+
handle(peer) {
|
|
11
|
+
let https_domains_mapping = this.router.info[peer.host]
|
|
12
|
+
for(let dial in https_domains_mapping) {
|
|
13
|
+
let parsed_dial = this.parse_ip(dial)
|
|
14
|
+
if (parsed_dial.host !== peer.host) {
|
|
15
|
+
// ONLY connect for 127.0.0.1 or localhost
|
|
16
|
+
// DO NOT connect if it's the actual host => because it will keep creating proxies forever recursively. only need to create proxies for localhost
|
|
17
|
+
let https_domains = https_domains_mapping[dial]
|
|
18
|
+
|
|
19
|
+
// 1. if https_domains is made up of one item <port>.localhost,
|
|
20
|
+
// add <port>.<account>.localhost
|
|
21
|
+
// 2. if https_domains is made up of two items <port>.localhost and <port>.<account>.localhost, don't do anything
|
|
22
|
+
for(let https_domain of https_domains) {
|
|
23
|
+
// insert the $account value right before the last part (1234.localhost => 1234.x.localhost)
|
|
24
|
+
let match
|
|
25
|
+
if (https_domain.endsWith(`${peer.name}.localhost`)) {
|
|
26
|
+
match = https_domain
|
|
27
|
+
} else {
|
|
28
|
+
let chunks = https_domain.split(".")
|
|
29
|
+
chunks.splice(chunks.length - 1, 0, peer.name)
|
|
30
|
+
match = chunks.join(".")
|
|
31
|
+
}
|
|
32
|
+
this.connector.handle({
|
|
33
|
+
match,
|
|
34
|
+
connector: {
|
|
35
|
+
host: peer.host,
|
|
36
|
+
port: parsed_dial.port
|
|
37
|
+
},
|
|
38
|
+
dial,
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
module.exports = PeerPortRouter
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const path = require('path')
|
|
2
|
+
const Connector = require('./connector')
|
|
3
|
+
const Processor = require('./processor')
|
|
4
|
+
class PeerVariableRouter extends Processor {
|
|
5
|
+
constructor(router) {
|
|
6
|
+
super()
|
|
7
|
+
this.router = router
|
|
8
|
+
this.connector = new Connector(router)
|
|
9
|
+
}
|
|
10
|
+
handle(peer) {
|
|
11
|
+
for(let script_path in peer.memory.local) {
|
|
12
|
+
let local_variables = peer.memory.local[script_path]
|
|
13
|
+
for(let key in local_variables) {
|
|
14
|
+
let val = local_variables[key]
|
|
15
|
+
if (val.startsWith("http")) {
|
|
16
|
+
let dial = val.replace(/https?:\/\//, '')
|
|
17
|
+
let name = this.api_name(peer.platform, peer.home, script_path)
|
|
18
|
+
if (this.has_port(dial)) {
|
|
19
|
+
let parsed_dial = this.parse_ip(dial)
|
|
20
|
+
if (key === "url") {
|
|
21
|
+
this.connector.handle({
|
|
22
|
+
match: `${name}.${peer.name}.localhost`.toLowerCase(),
|
|
23
|
+
connector: {
|
|
24
|
+
host: peer.host,
|
|
25
|
+
port: parsed_dial.port
|
|
26
|
+
},
|
|
27
|
+
dial,
|
|
28
|
+
host: peer.host,
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
this.connector.handle({
|
|
32
|
+
match:`${key}.${name}.${peer.name}.localhost`.toLowerCase(),
|
|
33
|
+
connector: {
|
|
34
|
+
host: peer.host,
|
|
35
|
+
port: parsed_dial.port
|
|
36
|
+
},
|
|
37
|
+
dial,
|
|
38
|
+
host: peer.host,
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
module.exports = PeerVariableRouter
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const path = require('path')
|
|
2
|
+
class Processor {
|
|
3
|
+
has_port(str) {
|
|
4
|
+
let chunks = str.split(":")
|
|
5
|
+
return chunks.length === 2
|
|
6
|
+
}
|
|
7
|
+
api_name(platform, home, str) {
|
|
8
|
+
let api_path
|
|
9
|
+
let rel_path
|
|
10
|
+
let name
|
|
11
|
+
let _path
|
|
12
|
+
if (platform === 'win32') {
|
|
13
|
+
_path = path.win32
|
|
14
|
+
api_path = _path.resolve(home, "api")
|
|
15
|
+
rel_path = _path.relative(api_path, str)
|
|
16
|
+
} else {
|
|
17
|
+
_path = path.posix
|
|
18
|
+
api_path = _path.resolve(home, "api")
|
|
19
|
+
rel_path = _path.relative(api_path, str)
|
|
20
|
+
}
|
|
21
|
+
name = rel_path.split(_path.sep)[0]
|
|
22
|
+
return name
|
|
23
|
+
}
|
|
24
|
+
parse_ip(str) {
|
|
25
|
+
let chunks = str.split(":")
|
|
26
|
+
let port = chunks[chunks.length-1]
|
|
27
|
+
let host = chunks.slice(0, chunks.length-1).join(":")
|
|
28
|
+
return { host, port }
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
module.exports = Processor
|
package/kernel/shell.js
CHANGED
|
@@ -2,7 +2,7 @@ const { Terminal } = require('xterm-headless');
|
|
|
2
2
|
const { SerializeAddon } = require("xterm-addon-serialize");
|
|
3
3
|
const sanitize = require("sanitize-filename");
|
|
4
4
|
const YAML = require('yaml')
|
|
5
|
-
|
|
5
|
+
const kill = require('kill-sync')
|
|
6
6
|
const fastq = require('fastq')
|
|
7
7
|
const { v4: uuidv4 } = require('uuid');
|
|
8
8
|
const os = require('os');
|
|
@@ -13,7 +13,6 @@ const pty = require('@homebridge/node-pty-prebuilt-multiarch')
|
|
|
13
13
|
const path = require("path")
|
|
14
14
|
const sudo = require("sudo-prompt-programfiles-x86");
|
|
15
15
|
const unparse = require('yargs-unparser-custom-flag');
|
|
16
|
-
const shellPath = require('shell-path');
|
|
17
16
|
const Util = require('./util')
|
|
18
17
|
const Environment = require('./environment')
|
|
19
18
|
const home = os.homedir()
|
|
@@ -60,36 +59,7 @@ class Shell {
|
|
|
60
59
|
}, 1)
|
|
61
60
|
|
|
62
61
|
}
|
|
63
|
-
async
|
|
64
|
-
|
|
65
|
-
/*
|
|
66
|
-
params := {
|
|
67
|
-
group: <group id>,
|
|
68
|
-
id: <shell id>,
|
|
69
|
-
path: <shell cwd (always absolute path)>,
|
|
70
|
-
env: <environment value key pairs>
|
|
71
|
-
}
|
|
72
|
-
*/
|
|
73
|
-
this.cols = params.cols ? params.cols : 100;
|
|
74
|
-
this.rows = params.rows ? params.rows : 30;
|
|
75
|
-
|
|
76
|
-
this.vt = new Terminal({
|
|
77
|
-
allowProposedApi: true,
|
|
78
|
-
cols: this.cols,
|
|
79
|
-
rows: this.rows,
|
|
80
|
-
})
|
|
81
|
-
this.vts = new SerializeAddon()
|
|
82
|
-
this.vt.loadAddon(this.vts)
|
|
83
|
-
|
|
84
|
-
// 1. id
|
|
85
|
-
this.id = (params.id ? params.id : uuidv4())
|
|
86
|
-
|
|
87
|
-
// 2. group id
|
|
88
|
-
this.group = params.group
|
|
89
|
-
|
|
90
|
-
// 2. env
|
|
91
|
-
// default env
|
|
92
|
-
|
|
62
|
+
async init_env(params) {
|
|
93
63
|
this.env = Object.assign({}, process.env)
|
|
94
64
|
// If the user has set PYTHONPATH, unset it.
|
|
95
65
|
if (this.env.PYTHONPATH) {
|
|
@@ -103,21 +73,29 @@ class Shell {
|
|
|
103
73
|
if (this.env.CMAKE_GENERATOR) {
|
|
104
74
|
delete this.env.CMAKE_GENERATOR
|
|
105
75
|
}
|
|
76
|
+
|
|
77
|
+
//this.env.PNPM_CONFIG_PREFIX = this.kernel.path("bin/npm")
|
|
78
|
+
//this.env.pnpm_config_prefix = this.kernel.path("bin/npm")
|
|
79
|
+
// this.env.PNPM_HOME = this.kernel.path("bin/npm")
|
|
80
|
+
// this.env.pnpm_home = this.kernel.path("bin/npm")
|
|
81
|
+
|
|
82
|
+
// this.env.NPM_CONFIG_PREFIX = this.kernel.path("bin/npm")
|
|
83
|
+
// this.env.npm_config_prefix = this.kernel.path("bin/npm")
|
|
84
|
+
|
|
106
85
|
|
|
107
86
|
// if (this.env.CUDA_HOME) {
|
|
108
87
|
// delete this.env.CUDA_HOME
|
|
109
88
|
// }
|
|
110
89
|
for(let key in this.env) {
|
|
111
90
|
if (key.startsWith("CUDA")) {
|
|
112
|
-
console.log("Unset env key: " + key)
|
|
113
91
|
delete this.env[key]
|
|
114
92
|
}
|
|
115
93
|
if (/.*(SSH|SSL).*/.test(key)) {
|
|
116
|
-
console.log("Unset env key: " + key)
|
|
117
94
|
delete this.env[key]
|
|
118
95
|
}
|
|
119
96
|
}
|
|
120
97
|
|
|
98
|
+
// this.env.TCELL_MINIMIZE=1
|
|
121
99
|
this.env.CMAKE_OBJECT_PATH_MAX = 1024
|
|
122
100
|
this.env.PYTORCH_ENABLE_MPS_FALLBACK = 1
|
|
123
101
|
this.env.TORCH_FORCE_NO_WEIGHTS_ONLY_LOAD = 1
|
|
@@ -152,7 +130,7 @@ class Shell {
|
|
|
152
130
|
if (this.platform === 'win32') {
|
|
153
131
|
// ignore
|
|
154
132
|
} else {
|
|
155
|
-
this.env[PATH_KEY]=
|
|
133
|
+
this.env[PATH_KEY]= this.kernel.shellpath || [
|
|
156
134
|
'./node_modules/.bin',
|
|
157
135
|
'/.nodebrew/current/bin',
|
|
158
136
|
'/usr/local/bin',
|
|
@@ -162,7 +140,6 @@ class Shell {
|
|
|
162
140
|
|
|
163
141
|
if (this.platform === "linux") {
|
|
164
142
|
let gxx = this.kernel.which('g++')
|
|
165
|
-
console.log({ gxx })
|
|
166
143
|
if (gxx) {
|
|
167
144
|
this.env.NVCC_PREPEND_FLAGS = `-ccbin ${gxx}`
|
|
168
145
|
}
|
|
@@ -204,8 +181,6 @@ class Shell {
|
|
|
204
181
|
}
|
|
205
182
|
}
|
|
206
183
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
184
|
for(let key in this.env) {
|
|
210
185
|
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key) && key !== "ProgramFiles(x86)") {
|
|
211
186
|
delete this.env[key]
|
|
@@ -224,12 +199,68 @@ class Shell {
|
|
|
224
199
|
delete this.env[key]
|
|
225
200
|
}
|
|
226
201
|
}
|
|
202
|
+
}
|
|
203
|
+
async start(params, ondata) {
|
|
204
|
+
this.ondata = ondata
|
|
205
|
+
|
|
206
|
+
/*
|
|
207
|
+
params := {
|
|
208
|
+
group: <group id>,
|
|
209
|
+
id: <shell id>,
|
|
210
|
+
path: <shell cwd (always absolute path)>,
|
|
211
|
+
env: <environment value key pairs>
|
|
212
|
+
}
|
|
213
|
+
*/
|
|
214
|
+
|
|
215
|
+
this.kill_messages = params.kill
|
|
216
|
+
|
|
217
|
+
this.cols = 100
|
|
218
|
+
this.rows = 30
|
|
219
|
+
|
|
220
|
+
if (params.cols) {
|
|
221
|
+
this.cols = params.cols
|
|
222
|
+
}
|
|
223
|
+
if (params.rows) {
|
|
224
|
+
this.rows = params.rows
|
|
225
|
+
}
|
|
226
|
+
if (params.client && params.client.cols) {
|
|
227
|
+
this.cols = params.client.cols
|
|
228
|
+
}
|
|
229
|
+
if (params.client && params.client.rows) {
|
|
230
|
+
this.rows = params.client.rows
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
this.vt = new Terminal({
|
|
234
|
+
allowProposedApi: true,
|
|
235
|
+
cols: this.cols,
|
|
236
|
+
rows: this.rows,
|
|
237
|
+
})
|
|
238
|
+
this.vts = new SerializeAddon()
|
|
239
|
+
this.vt.loadAddon(this.vts)
|
|
240
|
+
|
|
241
|
+
// 1. id
|
|
242
|
+
this.id = (params.id ? params.id : uuidv4())
|
|
243
|
+
|
|
244
|
+
// 2. group id
|
|
245
|
+
this.group = params.group
|
|
246
|
+
|
|
247
|
+
// 2. env
|
|
248
|
+
// default env
|
|
249
|
+
await this.init_env(params)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
this.ondata({ raw: `\r\n████\r\n██ Starting Shell ${this.id}\r\n` })
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
this.params = params
|
|
256
|
+
|
|
227
257
|
// 3. path => path can be http, relative, absolute
|
|
228
258
|
this.path = params.path
|
|
229
259
|
|
|
230
260
|
// automatically add self to the shells registry
|
|
231
261
|
this.kernel.shell.add(this)
|
|
232
262
|
|
|
263
|
+
|
|
233
264
|
if (params.sudo) {
|
|
234
265
|
let options = {
|
|
235
266
|
name: "Pinokio",
|
|
@@ -275,20 +306,39 @@ class Shell {
|
|
|
275
306
|
return response
|
|
276
307
|
} else {
|
|
277
308
|
let response = await this.request(params, async (stream) => {
|
|
278
|
-
if (stream
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
309
|
+
if (ondata) ondata(stream)
|
|
310
|
+
// if (stream.prompt) {
|
|
311
|
+
// this.resolve()
|
|
312
|
+
// } else {
|
|
313
|
+
// if (ondata) ondata(stream)
|
|
314
|
+
// }
|
|
283
315
|
})
|
|
284
316
|
return response
|
|
285
317
|
}
|
|
286
318
|
|
|
287
319
|
// return this.id
|
|
288
320
|
}
|
|
321
|
+
emit2(message) {
|
|
322
|
+
let i = 0;
|
|
323
|
+
const interval = setInterval(() => {
|
|
324
|
+
if (i >= message.length) {
|
|
325
|
+
clearInterval(interval);
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
let chunk = message.slice(i, i+1024)
|
|
329
|
+
this.ptyProcess.write(chunk)
|
|
330
|
+
i += 1024;
|
|
331
|
+
}, 10);
|
|
332
|
+
}
|
|
289
333
|
emit(message) {
|
|
290
|
-
if (
|
|
291
|
-
this.
|
|
334
|
+
if (message.length > 1024) {
|
|
335
|
+
this.emit2(message)
|
|
336
|
+
} else {
|
|
337
|
+
if (this.ptyProcess) {
|
|
338
|
+
if (this.input) {
|
|
339
|
+
this.ptyProcess.write(message)
|
|
340
|
+
}
|
|
341
|
+
}
|
|
292
342
|
}
|
|
293
343
|
}
|
|
294
344
|
send(message, newline, cb) {
|
|
@@ -370,6 +420,9 @@ class Shell {
|
|
|
370
420
|
|
|
371
421
|
// not connected => make a new connection => which means get a new prompt
|
|
372
422
|
// if already connected => no need for a new prompt
|
|
423
|
+
if (params.input) {
|
|
424
|
+
this.input = params.input
|
|
425
|
+
}
|
|
373
426
|
if (params.persistent) {
|
|
374
427
|
this.persistent = params.persistent
|
|
375
428
|
}
|
|
@@ -898,9 +951,11 @@ class Shell {
|
|
|
898
951
|
this.resolve(buf)
|
|
899
952
|
}
|
|
900
953
|
this.resolve = undefined
|
|
954
|
+
this.ondata({ raw: `\r\n\r\n██ Detached from Shell ${this.id}\r\n\r\n` })
|
|
901
955
|
}
|
|
902
956
|
}
|
|
903
|
-
kill(message, force) {
|
|
957
|
+
kill(message, force, cb) {
|
|
958
|
+
console.log("KILL")
|
|
904
959
|
|
|
905
960
|
this.done = true
|
|
906
961
|
this.ready = false
|
|
@@ -924,12 +979,31 @@ class Shell {
|
|
|
924
979
|
this.vt.dispose()
|
|
925
980
|
this.queue.killAndDrain()
|
|
926
981
|
if (this.ptyProcess) {
|
|
927
|
-
|
|
928
|
-
|
|
982
|
+
if (cb) {
|
|
983
|
+
kill(this.ptyProcess.pid, "SIGKILL", true)
|
|
984
|
+
this.ptyProcess.kill()
|
|
985
|
+
this.ptyProcess = undefined
|
|
986
|
+
// automatically remove the shell from this.kernel.shells
|
|
987
|
+
this.kernel.shell.rm(this.id)
|
|
988
|
+
this.ondata({ raw: `\r\n\r\n██ Terminated Shell ${this.id}\r\n████\r\n` })
|
|
989
|
+
this.ondata({ raw: "", type: "shell.kill" })
|
|
990
|
+
console.log("before cb 1")
|
|
991
|
+
cb()
|
|
992
|
+
} else {
|
|
993
|
+
kill(this.ptyProcess.pid, "SIGKILL", true)
|
|
994
|
+
this.ptyProcess.kill()
|
|
995
|
+
this.ptyProcess = undefined
|
|
996
|
+
// automatically remove the shell from this.kernel.shells
|
|
997
|
+
this.kernel.shell.rm(this.id)
|
|
998
|
+
this.ondata({ raw: `\r\n\r\n██ Terminated Shell ${this.id}\r\n████\r\n` })
|
|
999
|
+
this.ondata({ raw: "", type: "shell.kill" })
|
|
1000
|
+
}
|
|
1001
|
+
} else {
|
|
1002
|
+
this.kernel.shell.rm(this.id)
|
|
1003
|
+
this.ondata({ raw: `\r\n\r\n██ Terminated Shell ${this.id}\r\n████\r\n` })
|
|
1004
|
+
this.ondata({ raw: "", type: "shell.kill" })
|
|
929
1005
|
}
|
|
930
1006
|
|
|
931
|
-
// automatically remove the shell from this.kernel.shells
|
|
932
|
-
this.kernel.shell.rm(this.id)
|
|
933
1007
|
|
|
934
1008
|
}
|
|
935
1009
|
log() {
|
|
@@ -1008,6 +1082,11 @@ ${cleaned}
|
|
|
1008
1082
|
|
|
1009
1083
|
}
|
|
1010
1084
|
stream(msg, callback) {
|
|
1085
|
+
if (msg === "\u0007") {
|
|
1086
|
+
// Ignore bell sound escape character because it slows down everything and makes redundant sound
|
|
1087
|
+
callback()
|
|
1088
|
+
return
|
|
1089
|
+
}
|
|
1011
1090
|
this.vt.write(msg, () => {
|
|
1012
1091
|
let buf = this.vts.serialize()
|
|
1013
1092
|
let cleaned = this.stripAnsi(buf)
|
|
@@ -1015,8 +1094,10 @@ ${cleaned}
|
|
|
1015
1094
|
id: this.id,
|
|
1016
1095
|
raw: msg,
|
|
1017
1096
|
cleaned,
|
|
1018
|
-
state: cleaned
|
|
1097
|
+
state: cleaned,
|
|
1098
|
+
shell_id: this.id
|
|
1019
1099
|
}
|
|
1100
|
+
this.state = cleaned
|
|
1020
1101
|
if (this.cb) this.cb(response)
|
|
1021
1102
|
|
|
1022
1103
|
// Decide whether to kill or continue
|
|
@@ -1031,15 +1112,15 @@ ${cleaned}
|
|
|
1031
1112
|
// 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)
|
|
1032
1113
|
setTimeout(() => {
|
|
1033
1114
|
if (cache === cleaned) {
|
|
1034
|
-
if (this.persistent) {
|
|
1035
|
-
if (this.cb) this.cb({
|
|
1036
|
-
//raw: cached_msg,
|
|
1037
|
-
//raw: msg,
|
|
1038
|
-
//raw: "",
|
|
1039
|
-
cleaned,
|
|
1040
|
-
state: cleaned,
|
|
1041
|
-
prompt: true
|
|
1042
|
-
})
|
|
1115
|
+
if (this.input || this.persistent) {
|
|
1116
|
+
// if (this.cb) this.cb({
|
|
1117
|
+
// //raw: cached_msg,
|
|
1118
|
+
// //raw: msg,
|
|
1119
|
+
// //raw: "",
|
|
1120
|
+
// cleaned,
|
|
1121
|
+
// state: cleaned,
|
|
1122
|
+
// prompt: true
|
|
1123
|
+
// })
|
|
1043
1124
|
callback()
|
|
1044
1125
|
} else {
|
|
1045
1126
|
callback()
|
package/kernel/shells.js
CHANGED
|
@@ -35,14 +35,8 @@ class Shells {
|
|
|
35
35
|
} else {
|
|
36
36
|
m = "ls"
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
message: m,
|
|
38
|
+
await sh.init_env({
|
|
40
39
|
env: this.kernel.bin.envs({}),
|
|
41
|
-
conda: {
|
|
42
|
-
skip: true
|
|
43
|
-
}
|
|
44
|
-
}, async (stream) => {
|
|
45
|
-
process.stdout.write(stream.raw)
|
|
46
40
|
})
|
|
47
41
|
|
|
48
42
|
this.kernel.envs = sh.env
|
|
@@ -61,12 +55,14 @@ class Shells {
|
|
|
61
55
|
let res
|
|
62
56
|
for(let i=0; i<params.message.length; i++) {
|
|
63
57
|
let message = params.message[i]
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
58
|
+
if (message) {
|
|
59
|
+
let params_dup = Object.assign({}, params)
|
|
60
|
+
params_dup.message = message
|
|
61
|
+
res = await this._launch(params_dup, options, ondata)
|
|
62
|
+
// if there's an error, immediately return with the error
|
|
63
|
+
if (res.error) {
|
|
64
|
+
return res
|
|
65
|
+
}
|
|
70
66
|
}
|
|
71
67
|
}
|
|
72
68
|
return res
|
|
@@ -103,6 +99,7 @@ class Shells {
|
|
|
103
99
|
break: false
|
|
104
100
|
}]
|
|
105
101
|
params.on = params.on.concat(defaultHandlers)
|
|
102
|
+
|
|
106
103
|
let response = await sh.start(params, async (stream) => {
|
|
107
104
|
/*
|
|
108
105
|
{
|
|
@@ -150,7 +147,6 @@ class Shells {
|
|
|
150
147
|
}
|
|
151
148
|
ondata(stream)
|
|
152
149
|
})
|
|
153
|
-
|
|
154
150
|
/*
|
|
155
151
|
{
|
|
156
152
|
method: "shell.run",
|
|
@@ -350,18 +346,33 @@ class Shells {
|
|
|
350
346
|
stop (request, message) {
|
|
351
347
|
return this.kill(request, message)
|
|
352
348
|
}
|
|
353
|
-
reset() {
|
|
349
|
+
reset(cb) {
|
|
354
350
|
let info = this.shells.map((s) => {
|
|
355
351
|
return { id: s.id, group: s.group, cmd: s.cmd }
|
|
356
352
|
})
|
|
357
|
-
if (this.shells) {
|
|
353
|
+
if (this.shells && this.shells.length > 0) {
|
|
358
354
|
let shells = []
|
|
359
355
|
for(let i=0; i<this.shells.length; i++) {
|
|
360
356
|
shells.push(this.shells[i])
|
|
361
357
|
}
|
|
358
|
+
let count = 0
|
|
362
359
|
for(let shell of shells) {
|
|
363
360
|
console.log("[Kill Shell]", { id: shell.id, group: shell.group, cmd: shell.cmd })
|
|
364
|
-
|
|
361
|
+
if (cb) {
|
|
362
|
+
shell.kill("", true, () => {
|
|
363
|
+
count++
|
|
364
|
+
if (count >= shells.length) {
|
|
365
|
+
cb()
|
|
366
|
+
}
|
|
367
|
+
})
|
|
368
|
+
} else {
|
|
369
|
+
shell.kill("", true)
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
} else {
|
|
373
|
+
console.log("no shells running")
|
|
374
|
+
if (cb) {
|
|
375
|
+
cb()
|
|
365
376
|
}
|
|
366
377
|
}
|
|
367
378
|
}
|
|
@@ -373,6 +384,7 @@ class Shells {
|
|
|
373
384
|
* - Kill by group ID
|
|
374
385
|
* request = { group }
|
|
375
386
|
*/
|
|
387
|
+
|
|
376
388
|
if (request.id) {
|
|
377
389
|
|
|
378
390
|
let shells = []
|
|
@@ -451,6 +463,9 @@ class Shells {
|
|
|
451
463
|
return shell.group === group
|
|
452
464
|
})
|
|
453
465
|
return found
|
|
466
|
+
} else if (request.filter) {
|
|
467
|
+
let found = this.shells.filter(request.filter)
|
|
468
|
+
return found
|
|
454
469
|
}
|
|
455
470
|
}
|
|
456
471
|
get(id) {
|
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
|