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.
Files changed (119) hide show
  1. package/:w +1247 -0
  2. package/kernel/api/filepicker/index.js +59 -0
  3. package/kernel/api/fs/index.js +6 -4
  4. package/kernel/api/index.js +123 -37
  5. package/kernel/api/input/index.js +2 -0
  6. package/kernel/api/web/index.js +6 -0
  7. package/kernel/bin/caddy.js +127 -0
  8. package/kernel/bin/cloudflared.js +1 -0
  9. package/kernel/bin/conda.js +10 -2
  10. package/kernel/bin/cuda.js +0 -16
  11. package/kernel/bin/ffmpeg.js +4 -6
  12. package/kernel/bin/git.js +55 -29
  13. package/kernel/bin/gxx.js +8 -6
  14. package/kernel/bin/huggingface.js +4 -5
  15. package/kernel/bin/index.js +347 -88
  16. package/kernel/bin/node.js +13 -6
  17. package/kernel/bin/py.js +1 -1
  18. package/kernel/bin/setup.js +146 -0
  19. package/kernel/bin/uv.js +4 -5
  20. package/kernel/bin/zip.js +7 -8
  21. package/kernel/connect/index.js +25 -0
  22. package/kernel/connect/providers/github/README.md +11 -0
  23. package/kernel/connect/providers/x/README.md +96 -0
  24. package/kernel/connect/providers/x/index.js +152 -0
  25. package/kernel/environment.js +50 -1
  26. package/kernel/index.js +152 -32
  27. package/kernel/info.js +4 -2
  28. package/kernel/kv.js +38 -0
  29. package/kernel/loader.js +13 -3
  30. package/kernel/peer.js +161 -0
  31. package/kernel/procs.js +116 -0
  32. package/kernel/prototype.js +62 -0
  33. package/kernel/router/common.js +42 -0
  34. package/kernel/router/connector.js +81 -0
  35. package/kernel/router/index.js +235 -0
  36. package/kernel/router/localhost_home_router.js +84 -0
  37. package/kernel/router/localhost_port_router.js +15 -0
  38. package/kernel/router/localhost_variable_router.js +37 -0
  39. package/kernel/router/peer_home_router.js +15 -0
  40. package/kernel/router/peer_peer_router.js +26 -0
  41. package/kernel/router/peer_port_router.js +45 -0
  42. package/kernel/router/peer_variable_router.js +46 -0
  43. package/kernel/router/processor.js +31 -0
  44. package/kernel/shell.js +141 -60
  45. package/kernel/shells.js +32 -17
  46. package/kernel/store.js +58 -0
  47. package/kernel/sysinfo.js +0 -1
  48. package/kernel/util.js +143 -36
  49. package/package.json +4 -1
  50. package/pipe/index.js +0 -2
  51. package/script/index.js +12 -0
  52. package/server/index.js +1473 -553
  53. package/server/public/Socket.js +5 -1
  54. package/server/public/SourceCodePro-Regular.ttf +0 -0
  55. package/server/public/SpaceMono-Bold.ttf +0 -0
  56. package/server/public/SpaceMono-BoldItalic.ttf +0 -0
  57. package/server/public/SpaceMono-Italic.ttf +0 -0
  58. package/server/public/SpaceMono-Regular.ttf +0 -0
  59. package/server/public/commander.js +40 -0
  60. package/server/public/common.js +60 -0
  61. package/server/public/dropzone-min.js +2 -0
  62. package/server/public/dropzone.css +1 -0
  63. package/server/public/filepond-plugin-file-validate-type.min.js +9 -0
  64. package/server/public/filepond-plugin-image-crop.min.js +9 -0
  65. package/server/public/filepond-plugin-image-edit.min.css +8 -0
  66. package/server/public/filepond-plugin-image-edit.min.js +9 -0
  67. package/server/public/filepond-plugin-image-exif-orientation.min.js +9 -0
  68. package/server/public/filepond-plugin-image-preview.min.css +8 -0
  69. package/server/public/filepond-plugin-image-preview.min.js +9 -0
  70. package/server/public/filepond-plugin-image-resize.min.js +9 -0
  71. package/server/public/filepond-plugin-image-transform.min.js +9 -0
  72. package/server/public/filepond.min.css +8 -0
  73. package/server/public/filepond.min.js +9 -0
  74. package/server/public/fscreator.js +174 -0
  75. package/server/public/fseditor.js +212 -0
  76. package/server/public/github.png +0 -0
  77. package/server/public/highlight-js.js +81 -0
  78. package/server/public/highlight.css +9 -0
  79. package/server/public/highlight.js +1244 -0
  80. package/server/public/install.js +17 -20
  81. package/server/public/modalinput.js +105 -9
  82. package/server/public/opener.js +3 -1
  83. package/server/public/pinokio-black.png +0 -0
  84. package/server/public/pinokio-black2.png +0 -0
  85. package/server/public/redoc.standalone.js +1832 -0
  86. package/server/public/style.css +215 -17
  87. package/server/public/swagger-ui-bundle.js +2 -0
  88. package/server/public/swagger-ui.css +3 -0
  89. package/server/public/x.js +63 -0
  90. package/server/socket.js +136 -39
  91. package/server/views/404.ejs +0 -1
  92. package/server/views/app.ejs +368 -98
  93. package/server/views/bootstrap.ejs +22 -19
  94. package/server/views/connect/x.ejs +324 -0
  95. package/server/views/connect.ejs +197 -0
  96. package/server/views/download.ejs +7 -1
  97. package/server/views/editor.ejs +68 -9
  98. package/server/views/explore.ejs +13 -10
  99. package/server/views/file_explorer.ejs +10 -37
  100. package/server/views/github.ejs +218 -0
  101. package/server/views/help.ejs +4 -3
  102. package/server/views/index.ejs +275 -121
  103. package/server/views/install.ejs +56 -29
  104. package/server/views/keys.ejs +276 -0
  105. package/server/views/network.ejs +889 -0
  106. package/server/views/partials/dynamic.ejs +9 -0
  107. package/server/views/partials/menu.ejs +7 -1
  108. package/server/views/prototype/index.ejs +311 -0
  109. package/server/views/prototype/show.ejs +383 -0
  110. package/server/views/redoc.ejs +18 -0
  111. package/server/views/required_env_editor.ejs +11 -2
  112. package/server/views/settings.ejs +38 -10
  113. package/server/views/setup.ejs +254 -0
  114. package/server/views/setup_home.ejs +192 -0
  115. package/server/views/shell.ejs +781 -0
  116. package/server/views/swaggerui.ejs +19 -0
  117. package/server/views/terminal.ejs +174 -42
  118. package/LICENSE +0 -7
  119. 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 start(params, ondata) {
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]= shellPath.sync() || [
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.prompt) {
279
- this.resolve()
280
- } else {
281
- if (ondata) ondata(stream)
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 (this.ptyProcess) {
291
- this.ptyProcess.write(message)
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
- this.ptyProcess.kill()
928
- this.ptyProcess = undefined
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
- let response = await sh.start({
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
- let params_dup = Object.assign({}, params)
65
- params_dup.message = message
66
- res = await this._launch(params_dup, options, ondata)
67
- // if there's an error, immediately return with the error
68
- if (res.error) {
69
- return res
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
- shell.kill("", true)
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) {
@@ -0,0 +1,58 @@
1
+ const os = require('os')
2
+ const path = require('path')
3
+ const fs = require('fs')
4
+ class Store {
5
+ constructor() {
6
+ this.root = path.resolve(os.homedir(), ".pinokio")
7
+ if (!fs.existsSync(path.resolve(this.root))) {
8
+ fs.mkdirSync(path.resolve(this.root))
9
+ }
10
+ }
11
+ exists() {
12
+ let p = path.resolve(this.root, "config.json")
13
+ return fs.existsSync(p)
14
+ }
15
+ clone(old) {
16
+ console.log("clone", old)
17
+ let p = path.resolve(this.root, "config.json")
18
+ fs.writeFileSync(p, JSON.stringify(old, null, 2))
19
+ }
20
+ set(key, val) {
21
+ let o
22
+ try {
23
+ let str = fs.readFileSync(path.resolve(this.root, "config.json"), "utf8")
24
+ o = JSON.parse(str)
25
+ } catch(e) {
26
+ o = {}
27
+ }
28
+ o[key] = val
29
+ fs.writeFileSync(path.resolve(this.root, "config.json"), JSON.stringify(o, null, 2))
30
+ }
31
+ get(key) {
32
+ try {
33
+ let str = fs.readFileSync(path.resolve(this.root, "config.json"), "utf8")
34
+ let o = JSON.parse(str)
35
+ return o[key]
36
+ } catch (e) {
37
+ return null
38
+ }
39
+ }
40
+ delete(key) {
41
+ try {
42
+ let str = fs.readFileSync(path.resolve(this.root, "config.json"), "utf8")
43
+ let o = JSON.parse(str)
44
+ delete o[key]
45
+ fs.writeFileSync(path.resolve(this.root, "config.json"), JSON.stringify(o, null, 2))
46
+ } catch (e) {
47
+ }
48
+ }
49
+ store() {
50
+ try {
51
+ let str = fs.readFileSync(path.resolve(this.root, "config.json"), "utf8")
52
+ let o = JSON.parse(str)
53
+ return o
54
+ } catch (e) {
55
+ }
56
+ }
57
+ }
58
+ module.exports = Store
package/kernel/sysinfo.js CHANGED
@@ -75,7 +75,6 @@ class Sysinfo {
75
75
  this.info.gpus = gpus
76
76
  this.info.gpu = gpu
77
77
  this.info.gpu_model = gpu_model
78
- console.log("> this.info", this.info)
79
78
 
80
79
  }
81
80
  // async time() {