pinokiod 3.8.1530 → 3.8.1533

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 (43) hide show
  1. package/kernel/api/index.js +27 -7
  2. package/kernel/api/web/index.js +6 -0
  3. package/kernel/bin/git.js +36 -10
  4. package/kernel/bin/index.js +2 -21
  5. package/kernel/bin/setup.js +16 -0
  6. package/kernel/connect/index.js +25 -0
  7. package/kernel/connect/providers/github/README.md +11 -0
  8. package/kernel/connect/providers/x/README.md +96 -0
  9. package/kernel/connect/providers/x/index.js +152 -0
  10. package/kernel/index.js +2 -45
  11. package/kernel/prototype.js +1 -1
  12. package/kernel/router/index.js +10 -0
  13. package/kernel/shell.js +1 -1
  14. package/package.json +3 -1
  15. package/script/index.js +12 -0
  16. package/server/index.js +421 -79
  17. package/server/public/common.js +28 -0
  18. package/server/public/fscreator.js +32 -15
  19. package/server/public/highlight-js.js +81 -0
  20. package/server/public/highlight.css +9 -0
  21. package/server/public/highlight.js +1244 -0
  22. package/server/public/style.css +10 -3
  23. package/server/public/x.js +63 -0
  24. package/server/views/500.ejs +1 -1
  25. package/server/views/app.ejs +73 -8
  26. package/server/views/connect/x.ejs +324 -0
  27. package/server/views/connect.ejs +197 -0
  28. package/server/views/editor.ejs +38 -9
  29. package/server/views/explore.ejs +4 -9
  30. package/server/views/file_explorer.ejs +4 -39
  31. package/server/views/github.ejs +218 -0
  32. package/server/views/help.ejs +1 -7
  33. package/server/views/index.ejs +25 -44
  34. package/server/views/network.ejs +16 -6
  35. package/server/views/partials/dynamic.ejs +6 -0
  36. package/server/views/prototype.ejs +299 -0
  37. package/server/views/settings.ejs +14 -16
  38. package/server/views/setup_home.ejs +3 -2
  39. package/server/views/shell.ejs +1 -1
  40. package/server/views/terminal.ejs +56 -21
  41. package/LICENSE +0 -0
  42. package/server/views/local_editor.ejs +0 -282
  43. package/server/views/prototypes.ejs +0 -482
@@ -28,6 +28,21 @@ class Api {
28
28
  this.child_procs = {}
29
29
  this.lproxy = new Lproxy()
30
30
  }
31
+ async meta(name) {
32
+ let p = this.kernel.path("api", name, "pinokio.js")
33
+ let pinokio = (await this.kernel.loader.load(p)).resolved
34
+ let p2 = this.kernel.path("api", name, "pinokio_meta.json")
35
+ let pinokio2 = (await this.kernel.loader.load(p2)).resolved
36
+ let p3 = this.kernel.path("api", name, "pinokio.json")
37
+ let pinokio3 = (await this.kernel.loader.load(p3)).resolved
38
+ let meta = Object.assign({}, pinokio, pinokio2, pinokio3)
39
+ meta.iconpath = meta.icon ? this.kernel.path("api", name, meta.icon) : null
40
+ meta.icon = meta.icon ? `/api/${name}/${meta.icon}?raw=true` : "/pinokio-black.png"
41
+ meta.path = this.kernel.path("api", name)
42
+ meta.name = meta.title
43
+ meta.link = `/pinokio/browser/${name}/browse#n1`
44
+ return meta
45
+ }
31
46
  get_proxy_url(root, port) {
32
47
  if (this.proxies) {
33
48
  let proxies = this.proxies[root]
@@ -160,7 +175,6 @@ class Api {
160
175
 
161
176
  await this.kernel.stopCloudflare({ path: requestPath })
162
177
 
163
-
164
178
  // if there are any pending waiters, delete them
165
179
 
166
180
  if (this.waiter[requestPath]) {
@@ -431,14 +445,18 @@ class Api {
431
445
  let method
432
446
  let dirname
433
447
  let mod
434
- if (req.uri) {
448
+ if (req.method && typeof req.method === "function") {
449
+ modpath = null
450
+ method = req.method
451
+ dirname = __dirname
452
+ mod = null
453
+ } else if (req.uri) {
435
454
  modpath = this.resolvePath(cwd, req.uri)
436
455
  let m = (await this.loader.load(modpath))
437
456
  const stats = await fs.promises.stat(modpath)
438
457
  if (!this.child_procs[req.parent.path]) {
439
458
  this.child_procs[req.parent.path] = new Set()
440
459
  }
441
- console.log("SCRIPT RESOLVE METHOD", req)
442
460
  if (this.mods[modpath]) {
443
461
  // use the cached module if unchanged
444
462
  if (String(stats.mtime) === String(this.mods[modpath].updated)) {
@@ -572,9 +590,7 @@ class Api {
572
590
 
573
591
  }
574
592
  async step (request, rawrpc, input, i, total, args) {
575
- console.time("STEP INIT")
576
593
  await Promise.all([this.init(), this.kernel.update_sysinfo()])
577
- console.timeEnd("STEP INIT")
578
594
 
579
595
  // clear global regular expression object RegExp.lastMatch (memory leak prevention)
580
596
  let r = /\s*/g.exec("");
@@ -583,6 +599,10 @@ class Api {
583
599
 
584
600
  let { cwd, script } = await this.resolveScript(request.path)
585
601
 
602
+ if (request.cwd) {
603
+ cwd = request.cwd
604
+ }
605
+
586
606
  let memory = {
587
607
  script: this.kernel.script,
588
608
  input,
@@ -635,7 +655,6 @@ class Api {
635
655
  break;
636
656
  }
637
657
  }
638
-
639
658
  // replace {{{ }}} with {{ }}
640
659
  rpc = this.kernel.template.flatten(rpc)
641
660
 
@@ -769,6 +788,7 @@ class Api {
769
788
  uri: request.path
770
789
  }
771
790
  })
791
+ console.log(">>>>>> STOPPED", request)
772
792
  }
773
793
  return { request, input: null, step: rpc.next, total: script.run.length, args }
774
794
  } else {
@@ -987,6 +1007,7 @@ class Api {
987
1007
  uri: request.path
988
1008
  }
989
1009
  })
1010
+ console.log("<<<<<< STOPPED", request)
990
1011
  return { request, input: result, step: rpc.next, total: script.run.length, args }
991
1012
  }
992
1013
 
@@ -1232,7 +1253,6 @@ class Api {
1232
1253
  } else {
1233
1254
  console.log({ request })
1234
1255
  let { cwd, script } = await this.resolveScript(request.path)
1235
- request.cwd = cwd
1236
1256
 
1237
1257
  if (!script) {
1238
1258
  this.ondata({
@@ -21,5 +21,11 @@ class Web {
21
21
  kernel.exposed[app] = req.params.uri
22
22
  console.log("kernel.exposed", kernel.exposed)
23
23
  }
24
+ async open(req, ondata, kernel) {
25
+ ondata(req.params, "browser.open")
26
+ }
27
+ async close(req, ondata, kernel) {
28
+ ondata(req.params, "browser.close")
29
+ }
24
30
  }
25
31
  module.exports = Web
package/kernel/bin/git.js CHANGED
@@ -5,15 +5,26 @@ const { rimraf } = require('rimraf')
5
5
  const path = require("path")
6
6
  class Git {
7
7
  cmd() {
8
- return "git git-lfs gh"
8
+ if (this.kernel.platform === "darwin") {
9
+ return "git git-lfs"
10
+ } else {
11
+ return "git git-lfs gh"
12
+ }
9
13
  }
10
14
  async install(req, ondata) {
11
- await this.kernel.bin.exec({
12
- message: [
13
- "conda clean -y --all",
14
- `conda install -y -c conda-forge ${this.cmd()}`
15
- ]
16
- }, ondata)
15
+ if (this.kernel.platform === "darwin") {
16
+ await this.kernel.bin.exec({
17
+ conda: { skip: true },
18
+ message: "brew install gh",
19
+ }, ondata)
20
+ } else {
21
+ await this.kernel.bin.exec({
22
+ message: [
23
+ "conda clean -y --all",
24
+ `conda install -y -c conda-forge ${this.cmd()}`
25
+ ]
26
+ }, ondata)
27
+ }
17
28
  await fs.promises.mkdir(this.kernel.path("config/gh"), { recursive: true }).catch((e) => { })
18
29
  // if (this.kernel.platform === 'win32') {
19
30
  // let gitconfig_path = path.resolve(this.kernel.homedir, "gitconfig")
@@ -29,11 +40,26 @@ class Git {
29
40
  // }
30
41
  }
31
42
  async installed() {
32
- let gh_config_exists = await this.kernel.exists("config/gh")
33
- return this.kernel.bin.installed.conda && this.kernel.bin.installed.conda.has("git") && this.kernel.bin.installed.conda.has("gh") && gh_config_exists
43
+ if (this.kernel.platform === "darwin") {
44
+ let gh_config_exists = await this.kernel.exists("config/gh")
45
+ console.log("conda installed", this.kernel.bin.installed.conda)
46
+ return this.kernel.bin.installed.conda && this.kernel.bin.installed.conda.has("git") && this.kernel.bin.installed.brew.has("gh") && gh_config_exists
47
+ } else {
48
+ let gh_config_exists = await this.kernel.exists("config/gh")
49
+ console.log("conda installed", this.kernel.bin.installed.conda)
50
+ return this.kernel.bin.installed.conda && this.kernel.bin.installed.conda.has("git") && this.kernel.bin.installed.conda.has("gh") && gh_config_exists
51
+ }
34
52
  }
35
53
  async uninstall(req, ondata) {
36
- await this.kernel.bin.exec({ message: "conda remove git gh" }, ondata)
54
+ if (this.kernel.platform === "darwin") {
55
+ await this.kernel.bin.exec({ message: "conda remove git" }, ondata)
56
+ await this.kernel.bin.exec({
57
+ conda: { skip: true },
58
+ message: "brew uninstall gh",
59
+ })
60
+ } else {
61
+ await this.kernel.bin.exec({ message: "conda remove git gh" }, ondata)
62
+ }
37
63
  }
38
64
  env() {
39
65
  let gitconfig_path = path.resolve(this.kernel.homedir, "gitconfig")
@@ -56,7 +56,6 @@ class Bin {
56
56
  params.cols = this.client.cols
57
57
  params.rows = this.client.rows
58
58
  }
59
- console.log({ params })
60
59
  let response = await this.kernel.shell.run(params, null, ondata)
61
60
  return response
62
61
  }
@@ -360,17 +359,12 @@ class Bin {
360
359
  conda_versions[name] = version
361
360
  if (name === "conda") {
362
361
  conda_check.conda = true
363
- // //if (String(version) === "24.11.1") {
364
- // if (String(version) === "24.11.3") {
365
- // conda_check.conda = true
366
- // }
367
362
  }
368
363
  if (name === "conda-libmamba-solver") {
369
364
  //if (String(version) === "24.7.0") {
370
365
  let channel = chunks[3]
371
366
  let coerced = semver.coerce(version)
372
367
  let mamba_requirement = ">=24.11.1"
373
- // console.log({ name, channel, version })
374
368
  //if (semver.satisfies(coerced, mamba_requirement) && channel === "conda-forge") {
375
369
  if (semver.satisfies(coerced, mamba_requirement)) {
376
370
  conda_check.mamba = true
@@ -382,16 +376,6 @@ class Bin {
382
376
  if (String(version) === "3.47.2") {
383
377
  conda_check.sqlite = true
384
378
  }
385
- // let coerced = semver.coerce(version)
386
- // let sqlite_requirement = ">=3.47.2"
387
- // // console.log({ coerced, version, sqlite_requirement })
388
- // if (semver.satisfies(coerced, sqlite_requirement)) {
389
- // console.log("semver satisfied")
390
- //
391
- // conda_check.sqlite = true
392
- // } else {
393
- // console.log("semver NOT satisfied")
394
- // }
395
379
  }
396
380
  }
397
381
  } else {
@@ -443,15 +427,12 @@ class Bin {
443
427
 
444
428
  let brew_path = path.resolve(this.kernel.homedir, "bin", "homebrew")
445
429
  let brew_exists = await this.exists(brew_path)
446
- // console.log({ brew_path, brew_exists })
447
430
 
448
431
  let brew = []
449
432
  if (brew_exists) {
450
433
  start = false
451
434
  res = await this.exec({ message: `brew list -1`, conda: { skip: true } }, (stream) => {
452
- // console.log("brew list check", { stream })
453
435
  })
454
- // console.log("BREW", res.response)
455
436
  lines = res.response.split(/[\r\n]+/).slice(0, -1) // ignore last line since it's the prompt
456
437
  let end = false
457
438
  for(let line of lines) {
@@ -475,7 +456,6 @@ class Bin {
475
456
 
476
457
 
477
458
  // check brew_installed
478
- // console.log("checking brew installed")
479
459
  let e = await this.kernel.bin.exists("homebrew")
480
460
  let { stdout }= await this.exec({ message: "xcode-select -p", conda: { skip: true } }, (stream) => { })
481
461
  let e2 = /(.*Library.*Developer.*CommandLineTools.*|.*Xcode.*Developer.*)/gi.test(stdout)
@@ -736,7 +716,6 @@ class Bin {
736
716
  // }
737
717
  //}
738
718
  if (this.kernel.shell) {
739
- console.log(">>> shell reset")
740
719
  this.kernel.shell.reset()
741
720
  }
742
721
  await this.init()
@@ -975,6 +954,8 @@ class Bin {
975
954
  let dependencies
976
955
  if (r.name === "conda") {
977
956
  dependencies = config.bin.conda_requirements
957
+ console.log("check dependencies", dependencies)
958
+ requirements[i].dependencies = dependencies
978
959
  }
979
960
  let installed = await this.check_installed(r, dependencies)
980
961
  requirements[i].installed = installed
@@ -126,5 +126,21 @@ module.exports = {
126
126
  "caddy"
127
127
  ]
128
128
  }
129
+ },
130
+ connect: (kernel) => {
131
+ return {
132
+ icon: "fa-solid fa-wifi",
133
+ title: "API Connect",
134
+ description: "Connect with 3rd party APIs",
135
+ requirements: [
136
+ { name: "conda", },
137
+ { name: "git", },
138
+ { name: "caddy", },
139
+ ],
140
+ conda_requirements: [
141
+ "git",
142
+ "caddy"
143
+ ]
144
+ }
129
145
  }
130
146
  }
@@ -0,0 +1,25 @@
1
+ const fetch = require('cross-fetch')
2
+ const X = require('./providers/x')
3
+ class Connect {
4
+ constructor(kernel) {
5
+ this.kernel = kernel
6
+ this.x = new X(kernel)
7
+ }
8
+ async request(provider, method, req) {
9
+ let res = await this[provider].request(method, req)
10
+ return res
11
+ }
12
+ async login(provider, req) {
13
+ let res = await this[provider].login(req)
14
+ return res
15
+ }
16
+ async logout(provider, req) {
17
+ let res = await this[provider].logout(req)
18
+ return res
19
+ }
20
+ async keys(provider) {
21
+ let res = await this[provider].keys()
22
+ return res
23
+ }
24
+ }
25
+ module.exports = Connect
@@ -0,0 +1,11 @@
1
+ ---
2
+
3
+ # Usage
4
+
5
+ When you log into Github here, the login will be used for the git installed within Pinokio.
6
+
7
+ Logging into Github lets you do things like:
8
+
9
+ 1. Cloning from Private Repositories
10
+ 2. Publishing to Github
11
+ 3. Use all `gh` CLI commands in all Pinokio shells ([Learn more](https://cli.github.com/))
@@ -0,0 +1,96 @@
1
+ ---
2
+
3
+ # Usage
4
+
5
+ ## 1. Iniitialize
6
+
7
+ First include the script
8
+
9
+ ```html
10
+ <script src="https://pinokio.localhost/x.js"></script>
11
+ ```
12
+
13
+ Then initialize the X object
14
+
15
+ ```javascript
16
+ const x = new X()
17
+ ```
18
+
19
+ ## 2. Make API Calls
20
+
21
+ Now you can make API calls to X v2 API (Without worrying about authentication). For example:
22
+
23
+ ```javascript
24
+ await x.tweet({ text: text })
25
+ ```
26
+
27
+ The instantiated object `x` is equivalent to the `client.v2` object from [node-twitter-api-v2](https://github.com/PLhery/node-twitter-api-v2)
28
+
29
+ Read the full API documentation here: https://github.com/PLhery/node-twitter-api-v2/blob/master/doc/v2.md
30
+
31
+ ---
32
+
33
+ # Examples
34
+
35
+ ## 1. Minimal Post App
36
+
37
+ The authentication is automatically taken care of. You just need to make a POST request to the `/connect/x/api` endpoint, using ANY x.com API.
38
+
39
+ ```html
40
+ <html>
41
+ <body>
42
+ <form>
43
+ <input type='text' id='post'/>
44
+ <input type='submit'>
45
+ </form>
46
+ <script src="https://pinokio.localhost/x.js"></script>
47
+ <script>
48
+ const x = new X()
49
+ document.querySelector("form").addEventListener('submit', async (e) => {
50
+ e.preventDefault()
51
+ let text = document.querySelector("#post").value
52
+ await x.tweet({ text: text })
53
+ })
54
+ </script>
55
+ </body>
56
+ </html>
57
+ ```
58
+
59
+ ---
60
+
61
+ ## 2. Upload Media App
62
+
63
+ ```html
64
+ <html>
65
+ <body>
66
+ <form>
67
+ <input type='file' id='media' name='media'>
68
+ <input type='submit'>
69
+ </form>
70
+ <script src="https://pinokio.localhost/x.js"></script>
71
+ <script>
72
+ const x = new X()
73
+ document.querySelector("form").addEventListener('submit', async (e) => {
74
+ e.preventDefault()
75
+ // 1. get the uploaded file
76
+ let media = document.querySelector("#media").files[0]
77
+ // 2. determine the media_type ("tweet_gif", "tweet_image", or "tweet_video")
78
+ let type = media.type; // e.g., "image/png", "video/mp4", "image/gif"
79
+ let media_category
80
+ if (type.startsWith("image/")) {
81
+ media_category = (type === "image/gif" ? "tweet_gif" : "tweet_image");
82
+ } else if (type.startsWith("video/")) {
83
+ media_category = "tweet_video"
84
+ }
85
+ // 3. upload media
86
+ let media_id = await x.uploadMedia(media, { media_category })
87
+ // 4. post the uploaded media
88
+ let res = await x.tweet({ media: { media_ids: [media_id] }})
89
+ console.log(res)
90
+ })
91
+ </script>
92
+ </body>
93
+ </html>
94
+ ```
95
+
96
+ ---
@@ -0,0 +1,152 @@
1
+ const fs = require('fs')
2
+ const path = require('path')
3
+ const fetch = require('cross-fetch')
4
+ const FormData = require('form-data');
5
+ const marked = require('marked')
6
+ const { TwitterApi } = require('twitter-api-v2')
7
+ class X {
8
+ id = 'd2FQZ0U4NXpzYnRyS1hZeHBvbUc6MTpjaQ'
9
+ constructor(kernel) {
10
+ this.kernel = kernel
11
+ }
12
+ async readme() {
13
+ let md = await fs.promises.readFile(path.resolve(__dirname, "README.md"), "utf8")
14
+ return marked.parse(md, {
15
+ //baseUrl: req._parsedUrl.pathname.replace(/^\/_api/, "/raw/") + "/"
16
+ //baseUrl: req.originalUrl + "/"
17
+ })
18
+ }
19
+ async persist(auth) {
20
+ this.auth = auth
21
+ this.auth.expires_at = Date.now() + this.auth.expires_in * 1000
22
+ let authPath = this.kernel.path('connect/x.json')
23
+ await fs.promises.mkdir(this.kernel.path("connect"), { recursive: true }).catch((e) => { })
24
+ await fs.promises.writeFile(authPath, JSON.stringify(this.auth, null, 2))
25
+ }
26
+ async destroy() {
27
+ await fs.promises.rm(this.kernel.path("connect/x.json"))
28
+ this.auth = null
29
+ }
30
+ async sync() {
31
+ // check if auth exists
32
+ // if not, throw error
33
+ let authPath = this.kernel.path('connect/x.json')
34
+ this.auth = (await this.kernel.loader.load(authPath)).resolved
35
+ if (!this.auth) {
36
+ throw new Error("not authenticated")
37
+ return
38
+ }
39
+ if (!this.auth.refresh_token) {
40
+ throw new Error("no refresh token")
41
+ return
42
+ }
43
+
44
+ // check if auth has expired
45
+ // if expired, refresh and return
46
+ if (Date.now() < this.auth.expires_at) {
47
+ console.log("authentication valid")
48
+ return
49
+ }
50
+
51
+
52
+ console.log("auth expired. refresh....", JSON.stringify({ auth: this.auth, id: this.id }, null, 2))
53
+ // expired — refresh
54
+ const response = await fetch('https://api.twitter.com/2/oauth2/token', {
55
+ method: 'POST',
56
+ headers: { 'Content-Type': 'application/json' },
57
+ body: JSON.stringify({
58
+ grant_type: 'refresh_token',
59
+ refresh_token: this.auth.refresh_token,
60
+ client_id: this.id
61
+ })
62
+ }).then((res) => {
63
+ return res.json()
64
+ });
65
+ await this.persist(response)
66
+ return this.auth
67
+ }
68
+ async keys() {
69
+ await this.sync()
70
+ return this.auth
71
+ }
72
+ async request(method, req) {
73
+ /*
74
+ method := "uploadMedia"
75
+ params := {
76
+ "value.0", val1,
77
+ "type.0": "String",
78
+ "value.1": val2,
79
+ "type.1": "Blob"
80
+ }
81
+
82
+ uploadMedia(
83
+ val1,
84
+ {
85
+ key2: val2,
86
+ key3: val3
87
+ }
88
+ )
89
+ */
90
+ await this.sync()
91
+ const contentType = req.headers['content-type'];
92
+ let args
93
+ if (contentType.toLowerCase() === "application/json") {
94
+ // don't transform
95
+ args = req.body
96
+ let response = await this.client.v2[method](...args)
97
+ return response
98
+ } else {
99
+ args = []
100
+ let body = Object.assign({}, req.body)
101
+ if (req.files) {
102
+ for (const file of req.files) {
103
+ body[file.fieldname] = file.buffer
104
+ }
105
+ }
106
+ let types = []
107
+ for(let key in body) {
108
+ let chunks = key.split(".")
109
+ let index = parseInt(chunks[1])
110
+ if (chunks[0] === "type") {
111
+ types[index] = body[key]
112
+ }
113
+ }
114
+ for(let key in body) {
115
+ let chunks = key.split(".")
116
+ let index = parseInt(chunks[1])
117
+ if (chunks[0] === "value") {
118
+ let type = types[index]
119
+ if (type === "Object") {
120
+ args[index] = JSON.parse(body[key])
121
+ } else {
122
+ args[index] = body[key]
123
+ }
124
+ }
125
+ }
126
+ console.log({ args, method })
127
+
128
+ this.client = new TwitterApi(this.auth.access_token);
129
+ let response = await this.client.v2[method](...args)
130
+ return response
131
+ }
132
+ }
133
+ async login (req) {
134
+ const authHeader = 'Basic ' + Buffer.from(`${this.id}:`).toString('base64');
135
+ const response = await fetch('https://api.x.com/2/oauth2/token', {
136
+ method: 'POST',
137
+ headers: {
138
+ 'Content-Type': 'application/json',
139
+ // 'Authorization': authHeader
140
+ },
141
+ body: JSON.stringify(req.payload)
142
+ }).then((res) => {
143
+ return res.json()
144
+ });
145
+ await this.persist(response)
146
+ return this.auth
147
+ }
148
+ async logout (req) {
149
+ await this.destroy()
150
+ }
151
+ }
152
+ module.exports = X
package/kernel/index.js CHANGED
@@ -33,6 +33,7 @@ const Proto = require('./prototype')
33
33
  const Router = require("./router")
34
34
  const Procs = require('./procs')
35
35
  const Peer = require('./peer')
36
+ const Connect = require('./connect')
36
37
  //const kill = require('./tree-kill');
37
38
  const kill = require('kill-sync')
38
39
  const VARS = {
@@ -45,10 +46,6 @@ const VARS = {
45
46
 
46
47
  //const memwatch = require('@airbnb/node-memwatch');
47
48
  class Kernel {
48
- //schema = ">=1.0.0"
49
- //schema = "<=2.1.0"
50
- //schema = "<=3.2.0"
51
- //schema = "<=3.7.0"
52
49
  schema = "<=4.0.0"
53
50
  constructor(store) {
54
51
  this.fetch = fetch
@@ -81,13 +78,6 @@ class Kernel {
81
78
  this.jsdom = jsdom
82
79
  this.exposed = {}
83
80
  this.envs = {}
84
- // this.info = new Info(this)
85
- // this.pipe = new Pipe(this)
86
- // this.proto = new Proto(this)
87
- // this.processes = new Procs()
88
- // this.kv = new KV(this)
89
- // this.cloudflare = new Cloudflare()
90
- // this.peer = new Peer()
91
81
  this.shellpath = shellPath.sync()
92
82
 
93
83
 
@@ -292,41 +282,7 @@ class Kernel {
292
282
 
293
283
  // 9. announce self to the peer network
294
284
  this.peer.announce()
295
-
296
285
  }
297
-
298
- //if (https_installed && peer_active) {
299
-
300
- // // 1. get the process list
301
- // await this.processes.refresh()
302
-
303
- // // 2. refresh peer info to reflect the proc info
304
- // await this.peer.refresh()
305
-
306
- // // 3. load custom routers from ~/pinokio/network
307
- // await this.router.init()
308
-
309
- // // 4. set current local host router info
310
- // await this.router.local()
311
-
312
- // // 5. refresh peer info to reflect the updated router info
313
- // await this.peer.refresh()
314
-
315
- // // 6. tell peers to refresh
316
- // if (notify_peers) {
317
- // await this.peer.notify_peers()
318
- // }
319
-
320
- // // 7. update remote router
321
- // await this.router.remote()
322
-
323
- // // 8. update caddy config
324
- // await this.router.update()
325
-
326
- // // 9. announce self to the peer network
327
- // this.peer.announce()
328
-
329
- //}
330
286
  }
331
287
  async clearLog(group) {
332
288
  let relativePath = path.relative(this.homedir, group)
@@ -599,6 +555,7 @@ class Kernel {
599
555
  this.python = new Python(this)
600
556
  this.shell = new Shells(this)
601
557
  this.router = new Router(this)
558
+ this.connect = new Connect(this)
602
559
  this.system = system
603
560
  this.keys = {}
604
561
  this.memory = {
@@ -30,7 +30,7 @@ class Proto {
30
30
  let proto = path.dirname(prototype_path)
31
31
  let pinokiojs = path.resolve(prototype_dir, prototype_path)
32
32
  let config = await this.kernel.require(pinokiojs)
33
- if (config && config.create && typeof config.create === "function") {
33
+ if (config && config.run) {
34
34
  if (config.icon) {
35
35
  config.icon = "/prototype/" + proto + "/" + config.icon
36
36
  } else {
@@ -221,5 +221,15 @@ class Router {
221
221
  }
222
222
  }
223
223
  }
224
+ async check() {
225
+ try {
226
+ let res = await axios.get(`http://localhost:2019/config/`, {
227
+ timeout: 2000
228
+ })
229
+ return res.data
230
+ } catch (e) {
231
+ return null
232
+ }
233
+ }
224
234
  }
225
235
  module.exports = Router