pinokiod 3.85.0 → 3.86.0

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 (55) hide show
  1. package/kernel/api/index.js +7 -0
  2. package/kernel/bin/caddy.js +10 -4
  3. package/kernel/peer.js +0 -3
  4. package/kernel/prototype.js +1 -0
  5. package/kernel/shell.js +43 -2
  6. package/kernel/util.js +2 -0
  7. package/package.json +1 -1
  8. package/pipe/views/login.ejs +1 -1
  9. package/server/index.js +133 -83
  10. package/server/public/common.js +534 -0
  11. package/server/public/opener.js +12 -11
  12. package/server/public/serve/style.css +1 -1
  13. package/server/public/style.css +25 -24
  14. package/server/public/urldropdown.css +473 -4
  15. package/server/public/urldropdown.js +202 -8
  16. package/server/views/404.ejs +1 -1
  17. package/server/views/500.ejs +1 -1
  18. package/server/views/app.ejs +29 -33
  19. package/server/views/bookmarklet.ejs +197 -0
  20. package/server/views/connect/x.ejs +4 -4
  21. package/server/views/connect.ejs +10 -10
  22. package/server/views/container.ejs +2 -2
  23. package/server/views/d.ejs +3 -3
  24. package/server/views/download.ejs +1 -1
  25. package/server/views/editor.ejs +1 -1
  26. package/server/views/env_editor.ejs +3 -3
  27. package/server/views/explore.ejs +2 -2
  28. package/server/views/file_explorer.ejs +2 -2
  29. package/server/views/git.ejs +7 -7
  30. package/server/views/github.ejs +3 -3
  31. package/server/views/help.ejs +2 -2
  32. package/server/views/index.ejs +5 -5
  33. package/server/views/index2.ejs +3 -3
  34. package/server/views/init/index.ejs +11 -74
  35. package/server/views/install.ejs +3 -3
  36. package/server/views/keys.ejs +2 -2
  37. package/server/views/mini.ejs +2 -2
  38. package/server/views/net.ejs +6 -6
  39. package/server/views/network.ejs +21 -21
  40. package/server/views/network2.ejs +10 -10
  41. package/server/views/old_network.ejs +8 -8
  42. package/server/views/pro.ejs +369 -0
  43. package/server/views/prototype/index.ejs +2 -2
  44. package/server/views/required_env_editor.ejs +2 -2
  45. package/server/views/review.ejs +6 -6
  46. package/server/views/screenshots.ejs +5 -4
  47. package/server/views/settings.ejs +3 -3
  48. package/server/views/setup.ejs +2 -2
  49. package/server/views/setup_home.ejs +2 -2
  50. package/server/views/share_editor.ejs +4 -4
  51. package/server/views/shell.ejs +3 -3
  52. package/server/views/start.ejs +2 -2
  53. package/server/views/task.ejs +2 -2
  54. package/server/views/terminal.ejs +5 -4
  55. package/server/views/tools.ejs +13 -13
@@ -802,6 +802,13 @@ class Api {
802
802
  current: i,
803
803
  uri: request.uri,
804
804
  cwd,
805
+ exists: (...args) => {
806
+ return fs.existsSync(path.resolve(cwd, ...args))
807
+ },
808
+ running: (...args) => {
809
+ let fullpath = path.resolve(cwd, ...args)
810
+ return this.running[fullpath]
811
+ },
805
812
  name,
806
813
  self: script,
807
814
  port,
@@ -32,10 +32,16 @@ class Caddy {
32
32
  await new Promise((resolve, reject) => {
33
33
  let interval = setInterval(() => {
34
34
  if (this.kernel.processes.caddy_pid) {
35
- console.log("kill caddy", this.kernel.processes.caddy_pid)
36
- kill(this.kernel.processes.caddy_pid, "SIGKILL", true)
37
- console.log("killed existing caddy")
38
- resolve()
35
+ try {
36
+ console.log("kill caddy", this.kernel.processes.caddy_pid)
37
+ kill(this.kernel.processes.caddy_pid, "SIGKILL", true)
38
+ console.log("killed existing caddy")
39
+ clearInterval(interval)
40
+ resolve()
41
+ } catch (error) {
42
+ clearInterval(interval)
43
+ reject(error)
44
+ }
39
45
  } else {
40
46
  console.log("try killing existing caddy again in 1 sec")
41
47
  }
package/kernel/peer.js CHANGED
@@ -23,14 +23,11 @@ class PeerDiscovery {
23
23
  }
24
24
  }
25
25
  async check_peers () {
26
- console.log(">>>>>>>>>>>> check peers")
27
26
  let peer_array = Array.from(this.peers)
28
27
  for(let host of peer_array) {
29
28
  if (this.host !== host) {
30
29
  let result = await this._refresh(host)
31
- console.log("check peers", { host, result })
32
30
  if (!result) {
33
- console.log("delete host", host)
34
31
  this.peers.delete(host)
35
32
  delete this.info[host]
36
33
  }
@@ -75,6 +75,7 @@ class Proto {
75
75
  await fs.promises.rm(this.kernel.path("prototype"), { recursive: true })
76
76
  }
77
77
  async create(req, ondata) {
78
+ console.log("CREATE", req)
78
79
  try {
79
80
  if (req.client) {
80
81
  this.kernel.client = req.client
package/kernel/shell.js CHANGED
@@ -18,6 +18,9 @@ const Util = require('./util')
18
18
  const Environment = require('./environment')
19
19
  const ShellParser = require('./shell_parser')
20
20
  const home = os.homedir()
21
+
22
+ // xterm.js currently ignores DECSYNCTERM (CSI ? 2026 h/l) and renders it as text on Windows.
23
+ // filterDecsync() removes these sequences so they do not pollute the terminal output.
21
24
  class Shell {
22
25
  /*
23
26
  params
@@ -37,6 +40,7 @@ class Shell {
37
40
  this.platform = os.platform()
38
41
  this.logs = {}
39
42
  this.shell = this.platform === 'win32' ? 'cmd.exe' : 'bash';
43
+ this.decsyncBuffer = ''
40
44
 
41
45
  // Windows: /D => ignore AutoRun Registry Key
42
46
  // Others: --noprofile => ignore .bash_profile, --norc => ignore .bashrc
@@ -551,7 +555,7 @@ class Shell {
551
555
  term.onData((data) => {
552
556
  if (!this.prompt_done) {
553
557
  if (this.prompt_ready) {
554
- queue.push(data)
558
+ queue.push(this.filterDecsync(data))
555
559
  } else {
556
560
  setTimeout(() => {
557
561
  if (!this.prompt_ready) {
@@ -1080,7 +1084,7 @@ class Shell {
1080
1084
  data = data.replace(/\x1b\[6n/g, ''); // remove the code
1081
1085
  }
1082
1086
 
1083
- this.queue.push(data)
1087
+ this.queue.push(this.filterDecsync(data))
1084
1088
  }
1085
1089
  });
1086
1090
  }
@@ -1182,6 +1186,43 @@ class Shell {
1182
1186
  let cleaned = this.stripAnsi(buf)
1183
1187
  this._log(buf, cleaned)
1184
1188
  }
1189
+ filterDecsync(data) {
1190
+ if (!data) return data
1191
+
1192
+ const prefix = '\u001b[?2026'
1193
+ let chunk = this.decsyncBuffer ? this.decsyncBuffer + data : data
1194
+ if (chunk.includes('\u2190')) {
1195
+ chunk = chunk.replace(/\u2190/g, '\u001b')
1196
+ }
1197
+ this.decsyncBuffer = ''
1198
+
1199
+ let result = ''
1200
+ let i = 0
1201
+ while (i < chunk.length) {
1202
+ if (chunk.charCodeAt(i) === 0x1b) { // ESC
1203
+ const remaining = chunk.slice(i)
1204
+ if (remaining.startsWith('\u001b[?2026h') || remaining.startsWith('\u001b[?2026l')) {
1205
+ i += 8
1206
+ continue
1207
+ }
1208
+
1209
+ // Check if the remaining characters form a partial prefix of DECSYNCTERM
1210
+ let matched = 0
1211
+ const len = Math.min(prefix.length, remaining.length)
1212
+ while (matched < len && remaining[matched] === prefix[matched]) {
1213
+ matched++
1214
+ }
1215
+ if (matched === remaining.length && matched < prefix.length + 1) {
1216
+ this.decsyncBuffer = remaining
1217
+ return result
1218
+ }
1219
+ }
1220
+ result += chunk[i]
1221
+ i++
1222
+ }
1223
+
1224
+ return result
1225
+ }
1185
1226
  _log(buf, cleaned) {
1186
1227
 
1187
1228
 
package/kernel/util.js CHANGED
@@ -146,6 +146,8 @@ let file_type = async (cwd, file) => {
146
146
  link: true
147
147
  }
148
148
  }
149
+ } else {
150
+ return { }
149
151
  }
150
152
  }
151
153
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "3.85.0",
3
+ "version": "3.86.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -41,7 +41,7 @@ main input {
41
41
  }
42
42
  main button {
43
43
  color: white;
44
- background: royalblue;
44
+ background: rgba(127, 91, 243, 0.9);
45
45
  padding: 10px;
46
46
  box-sizing: border-box;
47
47
  border: none;
package/server/index.js CHANGED
@@ -108,10 +108,53 @@ class Server {
108
108
  stop() {
109
109
  this.server.close()
110
110
  }
111
+ killProcessTree(pid, label) {
112
+ const numericPid = typeof pid === 'string' ? parseInt(pid, 10) : pid
113
+ if (!Number.isInteger(numericPid) || numericPid <= 0) {
114
+ return
115
+ }
116
+ if (label) {
117
+ console.log(label, numericPid)
118
+ }
119
+ try {
120
+ kill(numericPid, 'SIGKILL', true)
121
+ } catch (error) {
122
+ if (error && error.code === 'ESRCH') {
123
+ return
124
+ }
125
+ console.error(`Failed to kill pid ${numericPid}`, error)
126
+ }
127
+ }
128
+ killTrackedProcesses() {
129
+ if (this.kernel && this.kernel.processes && this.kernel.processes.map) {
130
+ for (const [pid, name] of Object.entries(this.kernel.processes.map)) {
131
+ if (parseInt(pid, 10) === process.pid) {
132
+ continue
133
+ }
134
+ this.killProcessTree(pid, `kill child ${name}`)
135
+ }
136
+ }
137
+ }
138
+ shutdown(signalLabel) {
139
+ const label = signalLabel || 'Shutdown'
140
+ console.log(`[${label} event] Kill`, process.pid)
141
+ if (this.kernel && this.kernel.shell) {
142
+ try {
143
+ this.kernel.shell.reset()
144
+ } catch (error) {
145
+ console.error('Failed to reset shells', error)
146
+ }
147
+ }
148
+ this.killTrackedProcesses()
149
+ if (this.kernel && this.kernel.processes && this.kernel.processes.caddy_pid) {
150
+ this.killProcessTree(this.kernel.processes.caddy_pid, 'kill caddy')
151
+ }
152
+ this.killProcessTree(process.pid, 'kill self')
153
+ }
111
154
  exists (s) {
112
155
  return new Promise(r=>fs.access(s, fs.constants.F_OK, e => r(!e)))
113
156
  }
114
- running_dynamic (name, menu) {
157
+ running_dynamic (name, menu, selected_query) {
115
158
  let cwd = this.kernel.path("api", name)
116
159
  let running_dynamic = []
117
160
  const traverse = (obj, indexPath) => {
@@ -136,9 +179,17 @@ class Server {
136
179
 
137
180
  let id = `${filepath}?cwd=${cwd}`
138
181
  //if (this.kernel.api.running[filepath]) {
139
- if (this.kernel.api.running[id]) {
182
+ if (this.kernel.api.running[id] || selected_query.plugin === obj.src) {
140
183
  obj.running = true
141
184
  obj.display = "indent"
185
+ if (selected_query.plugin === obj.src) {
186
+ obj.default = true
187
+ for(let key in selected_query) {
188
+ if (key !== "plugin") {
189
+ obj.href = obj.href + "&" + key + "=" + encodeURIComponent(selected_query[key])
190
+ }
191
+ }
192
+ }
142
193
  running_dynamic.push(obj)
143
194
  }
144
195
  } else if (href.startsWith("/run")) {
@@ -148,9 +199,18 @@ class Server {
148
199
  let id = `${filepath}?cwd=${cwd}`
149
200
  obj.script_id = id
150
201
  //if (this.kernel.api.running[filepath]) {
151
- if (this.kernel.api.running[id]) {
202
+ if (this.kernel.api.running[id] || selected_query.plugin === obj.src) {
152
203
  obj.running = true
153
204
  obj.display = "indent"
205
+ if (selected_query.plugin === obj.src) {
206
+ console.log("selected_query", selected_query)
207
+ obj.default = true
208
+ for(let key in selected_query) {
209
+ if (key !== "plugin") {
210
+ obj.href = obj.href + "&" + key + "=" + encodeURIComponent(selected_query[key])
211
+ }
212
+ }
213
+ }
154
214
  running_dynamic.push(obj)
155
215
  }
156
216
  }
@@ -158,9 +218,19 @@ class Server {
158
218
  let unix_path = Util.p2u(this.kernel.path("api", name))
159
219
  let shell_id = this.get_shell_id(unix_path, indexPath, obj[key])
160
220
  let decoded_shell_id = decodeURIComponent(shell_id)
161
- if (this.kernel.api.running["shell/" + decoded_shell_id]) {
221
+ let id = "shell/" + decoded_shell_id
222
+ if (this.kernel.api.running[id] || selected_query.plugin === id) {
162
223
  obj.running = true
163
224
  obj.display = "indent"
225
+ if (selected_query.plugin === id) {
226
+ obj.default = true
227
+ console.log("selected_query", selected_query)
228
+ for(let key in selected_query) {
229
+ if (key !== "plugin") {
230
+ obj.href = obj.href + "&" + key + "=" + encodeURIComponent(selected_query[key])
231
+ }
232
+ }
233
+ }
164
234
  running_dynamic.push(obj)
165
235
  }
166
236
  }
@@ -292,20 +362,20 @@ class Server {
292
362
  }
293
363
  }
294
364
  } else {
295
- cfg = await this.renderIndex(name)
365
+ cfg = await this.renderIndex(name, cfg)
296
366
  }
297
367
  } else {
298
- cfg = await this.renderIndex(name)
368
+ cfg = await this.renderIndex(name, cfg)
299
369
  }
300
370
  return cfg
301
371
  }
302
- async renderIndex(name) {
372
+ async renderIndex(name, cfg) {
303
373
  let p = this.kernel.path("api", name)
304
374
  let html_path = path.resolve(p, "index.html")
305
375
  let html_exists = await this.kernel.exists(html_path)
306
376
  console.log({ html_path, html_exists })
307
377
  if (html_exists) {
308
- return {
378
+ return Object.assign({
309
379
  title: name,
310
380
  menu: [{
311
381
  default: true,
@@ -313,9 +383,9 @@ class Server {
313
383
  text: "index.html",
314
384
  href: "index.html?raw=true",
315
385
  }]
316
- }
386
+ }, cfg)
317
387
  } else {
318
- return {
388
+ return Object.assign({
319
389
  title: name,
320
390
  menu: [{
321
391
  default: true,
@@ -323,7 +393,7 @@ class Server {
323
393
  text: "Project Files",
324
394
  href: `/files/api/${name}`,
325
395
  }]
326
- }
396
+ }, cfg)
327
397
  }
328
398
  }
329
399
  async getGit(ref, filepath) {
@@ -520,9 +590,7 @@ class Server {
520
590
  err = e.stack
521
591
  }
522
592
 
523
- console.log("renderMenu before", config)
524
593
  await this.renderMenu(req, uri, name, config, [])
525
- console.log("renderMenu after", config)
526
594
 
527
595
  let platform = os.platform()
528
596
 
@@ -602,7 +670,11 @@ class Server {
602
670
  let plugin = await this.getPlugin(req, plugin_config, name)
603
671
  if (plugin && plugin.menu && Array.isArray(plugin.menu)) {
604
672
  plugin = structuredClone(plugin)
605
- plugin_menu = this.running_dynamic(name, plugin.menu)
673
+ let default_plugin_query
674
+ if (req.query) {
675
+ default_plugin_query = req.query
676
+ }
677
+ plugin_menu = this.running_dynamic(name, plugin.menu, default_plugin_query)
606
678
  }
607
679
 
608
680
  let posix_path = Util.p2u(this.kernel.path("api", name))
@@ -617,6 +689,18 @@ class Server {
617
689
  let dev_tab = "/p/" + name + "/dev"
618
690
  let review_tab = "/p/" + name + "/review"
619
691
 
692
+ let dynamic_url = "/pinokio/dynamic/" + name;
693
+ if (Object.values(req.query).length > 0) {
694
+ let index = 0
695
+ for(let key in req.query) {
696
+ if (index === 0) {
697
+ dynamic_url = dynamic_url + `?${key}=${encodeURIComponent(req.query[key])}`
698
+ } else {
699
+ dynamic_url = dynamic_url + `&${key}=${encodeURIComponent(req.query[key])}`
700
+ }
701
+ index++;
702
+ }
703
+ }
620
704
 
621
705
  const result = {
622
706
  dev_link,
@@ -639,7 +723,7 @@ class Server {
639
723
  sidebar: "/pinokio/sidebar/" + name,
640
724
  repos: "/pinokio/repos/" + name,
641
725
  ai: "/pinokio/ai/" + name,
642
- dynamic: "/pinokio/dynamic/" + name,
726
+ dynamic: dynamic_url,
643
727
  // dynamic: "/pinokio/dynamic/" + name,
644
728
  dynamic_content: null,
645
729
  name,
@@ -1019,7 +1103,6 @@ class Server {
1019
1103
  template = "editor"
1020
1104
  }
1021
1105
 
1022
- console.log("check requirements")
1023
1106
  let { requirements, install_required, requirements_pending, error } = await this.kernel.bin.check({
1024
1107
  //bin: this.kernel.bin.preset("ai"),
1025
1108
  bin: this.kernel.bin.preset("dev"),
@@ -1076,7 +1159,6 @@ class Server {
1076
1159
  if (platform === "win32") {
1077
1160
  root_path = root_path.replace(/\\/g, '\\\\')
1078
1161
  }
1079
- console.log({ cwd, api_path, root, root_path })
1080
1162
  res.render("required_env_editor", {
1081
1163
  portal: this.portal,
1082
1164
  agent: req.agent,
@@ -1613,7 +1695,6 @@ class Server {
1613
1695
  items
1614
1696
  })
1615
1697
  } else {
1616
- console.log("RENDER FILE EXPLORER")
1617
1698
  res.render("file_explorer", {
1618
1699
  docs: this.docs,
1619
1700
  portal: this.portal,
@@ -2033,7 +2114,6 @@ class Server {
2033
2114
  if (menuitem.image.startsWith("/")) {
2034
2115
  imagePath = menuitem.image
2035
2116
  } else {
2036
- console.log({ launcher_root, name, image: menuitem.image })
2037
2117
  if (launcher_root) {
2038
2118
  imagePath = `/api/${name}/${launcher_root}/${menuitem.image}?raw=true`
2039
2119
  } else {
@@ -3075,7 +3155,6 @@ class Server {
3075
3155
  ...result
3076
3156
  })
3077
3157
  }
3078
- console.log(JSON.stringify(bundles, null, 2))
3079
3158
  res.render("tools", {
3080
3159
  current_host: this.kernel.peer.host,
3081
3160
  pending,
@@ -3125,6 +3204,23 @@ class Server {
3125
3204
  })
3126
3205
  }))
3127
3206
 
3207
+ this.app.get("/bookmarklet", ex(async (req, res) => {
3208
+ const protocol = (req.$source && req.$source.protocol) || req.protocol || 'http';
3209
+ const host = req.get('host') || `localhost:${this.port}`;
3210
+ const baseUrl = `${protocol}://${host}`;
3211
+ const targetBase = `${baseUrl}/?create=1&prompt=`;
3212
+ const safeTargetBase = targetBase.replace(/'/g, "\\'");
3213
+ const bookmarkletHref = `javascript:(()=>{window.open('${safeTargetBase}'+encodeURIComponent(window.location.href),'_blank');})();`;
3214
+
3215
+ res.render("bookmarklet", {
3216
+ theme: this.theme,
3217
+ agent: req.agent,
3218
+ baseUrl,
3219
+ targetBase,
3220
+ bookmarkletHref
3221
+ });
3222
+ }))
3223
+
3128
3224
  //let home = this.kernel.homedir
3129
3225
  //let home = this.kernel.store.get("home")
3130
3226
  this.app.get("/launch", ex(async (req, res) => {
@@ -3145,7 +3241,6 @@ class Server {
3145
3241
  autolaunch = true
3146
3242
  }
3147
3243
  let chunks = host.split(".")
3148
- console.log("GET /launch", { url, host, chunks })
3149
3244
  if (chunks[chunks.length-1] === "localhost") {
3150
3245
  // if <...>.<kernel.peer.name>.localhost
3151
3246
  let nameChunks
@@ -3172,7 +3267,6 @@ class Server {
3172
3267
  for(let folder of folders) {
3173
3268
  let pattern1 = `${folder}.${this.kernel.peer.name}.localhost`
3174
3269
  let pattern2 = `${folder}.localhost`
3175
- console.log("checking", { pattern1, pattern2, chunks: chunks.join(".") })
3176
3270
  if (pattern1 === chunks.join(".")) {
3177
3271
  matched = true
3178
3272
  nameChunks = chunks.slice(0, -2)
@@ -3193,20 +3287,16 @@ class Server {
3193
3287
  // look for any matching peer names
3194
3288
  // if exists, redirect to that host
3195
3289
  for(let name of peer_names) {
3196
- console.log({ host, name })
3197
3290
  if (host.endsWith(`.${name}.localhost`)) {
3198
- console.log("matched. redirecting")
3199
3291
  res.redirect(`https://pinokio.${name}.localhost/launch?url=${url}`)
3200
3292
  return
3201
3293
  }
3202
3294
  }
3203
3295
  }
3204
3296
  } else {
3205
- console.log("> 3")
3206
3297
  nameChunks = chunks
3207
3298
  }
3208
3299
  let name = nameChunks.join(".")
3209
- console.log({ nameChunks, chunks, name })
3210
3300
  let api_path = this.kernel.path("api", name)
3211
3301
  let exists = await this.exists(api_path)
3212
3302
  if (exists) {
@@ -3556,7 +3646,6 @@ class Server {
3556
3646
  } catch (e) {
3557
3647
  console.log(e)
3558
3648
  }
3559
- console.log({ https_running })
3560
3649
  if (!https_running) {
3561
3650
  // res.json({ error: "pinokio.host not yet available" })
3562
3651
  res.redirect("/setup/connect?callback=/connect/" + req.params.provider)
@@ -3574,7 +3663,6 @@ class Server {
3574
3663
  break
3575
3664
  }
3576
3665
  }
3577
- console.log({ router_running })
3578
3666
  if (!router_running) {
3579
3667
  // res.json({ error: "pinokio.localhost not yet available" })
3580
3668
  res.redirect("/setup/connect?callback=/connect/" + req.params.provider)
@@ -3677,7 +3765,6 @@ class Server {
3677
3765
  res.json({ success: true })
3678
3766
  }))
3679
3767
  this.app.post("/go", ex(async (req, res) => {
3680
- console.log("GO", req.body)
3681
3768
  Util.openURL(req.body.url)
3682
3769
  res.json({ success: true })
3683
3770
  }))
@@ -3691,7 +3778,6 @@ class Server {
3691
3778
  // relpath : ...
3692
3779
  let relpath = req.body.asset_path.split("/").filter((x) => { return x }).slice(1).join("/")
3693
3780
  let filepath = this.kernel.path(relpath)
3694
- console.log({ filepath, relpath })
3695
3781
  Util.openfs(filepath, req.body, this.kernel)
3696
3782
  } else if (req.body.path) {
3697
3783
  Util.openfs(req.body.path, req.body, this.kernel)
@@ -3701,7 +3787,6 @@ class Server {
3701
3787
  this.app.post("/keys", ex(async (req, res) => {
3702
3788
  let p = this.kernel.path("key.json")
3703
3789
  let keys = (await this.kernel.loader.load(p)).resolved
3704
- console.log("update", req.body)
3705
3790
  for(let host in req.body) {
3706
3791
  let updated = req.body[host]
3707
3792
  for(let indexStr in updated) {
@@ -3806,8 +3891,6 @@ class Server {
3806
3891
 
3807
3892
  let hosts = await this.get_github_hosts()
3808
3893
 
3809
- console.log("hosts", hosts)
3810
-
3811
3894
  let items
3812
3895
  if (hosts.length > 0) {
3813
3896
  // logged in => display logout
@@ -4018,6 +4101,16 @@ class Server {
4018
4101
  running: (shell ? true : false)
4019
4102
  })
4020
4103
  }))
4104
+ this.app.get("/pro", ex(async (req, res) => {
4105
+ let target = req.query.target ? req.query.target : null
4106
+ let cwd = this.kernel.path("api")
4107
+ res.render("pro", {
4108
+ target,
4109
+ cwd,
4110
+ theme: this.theme,
4111
+ agent: req.agent,
4112
+ })
4113
+ }))
4021
4114
  // this.app.get("/terminal/:api/:id", ex(async (req, res) => {
4022
4115
  // res.render("shell", {
4023
4116
  // theme: this.theme,
@@ -4089,7 +4182,6 @@ class Server {
4089
4182
  if (cr.has("caddy")) {
4090
4183
  wait = "caddy"
4091
4184
  }
4092
- console.log({ wait, cr })
4093
4185
 
4094
4186
  let current = req.query.callback || req.originalUrl
4095
4187
 
@@ -4245,9 +4337,7 @@ class Server {
4245
4337
 
4246
4338
  // let list = this.getPeerInfo()
4247
4339
  // console.log("peeerInfo", JSON.stringify(list, null, 2))
4248
- console.time("check peers")
4249
4340
  await this.kernel.peer.check_peers()
4250
- console.timeEnd("check peers")
4251
4341
 
4252
4342
 
4253
4343
  let peers = []
@@ -4828,7 +4918,6 @@ class Server {
4828
4918
  //const repositoryPath = this.kernel.path(pathComponents[0], pathComponents[1])
4829
4919
  //const repositoryPath = this.kernel.path(pathComponents[0])
4830
4920
  const repositoryPath = path.resolve(this.kernel.api.userdir, api_path)
4831
- console.log({ repositoryPath })
4832
4921
  gitRemote = await git.getConfig({
4833
4922
  fs,
4834
4923
  http,
@@ -4974,7 +5063,6 @@ class Server {
4974
5063
  if (config) {
4975
5064
  if (config.xterm) {
4976
5065
  this.xterm = config.xterm
4977
- console.log("this.xterm", this.xterm)
4978
5066
  }
4979
5067
  }
4980
5068
  }
@@ -5309,7 +5397,6 @@ class Server {
5309
5397
  })
5310
5398
  }))
5311
5399
  this.app.get("/dev/*", ex(async (req, res) => {
5312
- console.log("GET /dev/*", req.params)
5313
5400
  let { requirements, install_required, requirements_pending, error } = await this.kernel.bin.check({
5314
5401
  bin: this.kernel.bin.preset("dev"),
5315
5402
  })
@@ -5444,7 +5531,11 @@ class Server {
5444
5531
  if (plugin) {
5445
5532
  if (plugin && plugin.menu && Array.isArray(plugin.menu)) {
5446
5533
  plugin = structuredClone(plugin)
5447
- plugin_menu = this.running_dynamic(req.params.name, plugin.menu)
5534
+ let default_plugin_query
5535
+ if (req.query) {
5536
+ default_plugin_query = req.query
5537
+ }
5538
+ plugin_menu = this.running_dynamic(req.params.name, plugin.menu, default_plugin_query)
5448
5539
  html = await new Promise((resolve, reject) => {
5449
5540
  ejs.renderFile(path.resolve(__dirname, "views/partials/dynamic.ejs"), { dynamic: plugin_menu }, (err, html) => {
5450
5541
  resolve(html)
@@ -5752,7 +5843,6 @@ class Server {
5752
5843
  let gitRemote = null
5753
5844
  try {
5754
5845
  const repositoryPath = path.resolve(this.kernel.api.userdir, req.params.name)
5755
- console.log({ repositoryPath })
5756
5846
  gitRemote = await git.getConfig({
5757
5847
  fs,
5758
5848
  http,
@@ -5905,7 +5995,6 @@ class Server {
5905
5995
  res.redirect("/pinokio/install")
5906
5996
  }))
5907
5997
  this.app.get("/pinokio/install", ex((req, res) => {
5908
- console.log("render /pinokio/install")
5909
5998
  let requirements = req.session.requirements
5910
5999
  let callback = req.session.callback
5911
6000
  req.session.requirements = null
@@ -6087,7 +6176,6 @@ class Server {
6087
6176
  await fs.promises.mkdir(this.kernel.path("screenshots"), { recursive: true }).catch((e) => { })
6088
6177
  for(let key in req.files) {
6089
6178
  let file = req.files[key]
6090
- console.log({ file, key })
6091
6179
  let ts = String(Date.now()) + ".png"
6092
6180
  await fs.promises.writeFile(this.kernel.path("screenshots", ts), file.buffer)
6093
6181
  }
@@ -6278,7 +6366,6 @@ class Server {
6278
6366
  }
6279
6367
  } else {
6280
6368
  // if network is not active, return success immediately (just checking if the server is up)
6281
- console.log("this.kernel.router.published()")
6282
6369
  res.json({ success: true })
6283
6370
  }
6284
6371
  }))
@@ -6340,48 +6427,11 @@ class Server {
6340
6427
  })
6341
6428
  });
6342
6429
  process.on('SIGINT', () => {
6343
- //if (this.kernel && this.kernel.shell) {
6344
- // console.log("shell reset")
6345
- // this.kernel.shell.reset(() => {
6346
- // process.exit()
6347
- // })
6348
- //} else {
6349
- // process.exit()
6350
- //}
6351
- console.log("[SigInt event] Kill", process.pid)
6352
- if (this.kernel.processes.caddy_pid) {
6353
- console.log("kill caddy", this.kernel.processes.caddy_pid)
6354
- kill(this.kernel.processes.caddy_pid, "SIGKILL", true)
6355
- }
6356
- console.log("kill self")
6357
- kill(process.pid, 'SIGKILL', true)
6358
- //kill(process.pid, map, 'SIGKILL', () => {
6359
- // console.log("child procs killed for", process.pid)
6360
- // process.exit()
6361
- //});
6430
+ this.shutdown('SigInt')
6362
6431
  })
6363
6432
 
6364
6433
  process.on('SIGTERM', () => {
6365
- // if (this.kernel && this.kernel.shell) {
6366
- // console.log("shell reset")
6367
- // this.kernel.shell.reset(() => {
6368
- // process.exit()
6369
- // })
6370
- // } else {
6371
- // process.exit()
6372
- // }
6373
- console.log("[Sigterm event] Kill", process.pid)
6374
- if (this.kernel.processes.caddy_pid) {
6375
- console.log("kill caddy", this.kernel.processes.caddy_pid)
6376
- kill(this.kernel.processes.caddy_pid, "SIGKILL", true)
6377
- }
6378
- console.log("kill self")
6379
- kill(process.pid, 'SIGKILL', true)
6380
- //let map = this.kernel.processes.map || {}
6381
- //kill(process.pid, map, 'SIGKILL', () => {
6382
- // console.log("child procs killed for", process.pid)
6383
- // process.exit()
6384
- //});
6434
+ this.shutdown('SigTerm')
6385
6435
  })
6386
6436
  // process.on('exit', () => {
6387
6437
  // console.log("[Exit event]")