pinokiod 7.3.0 → 7.3.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 (125) hide show
  1. package/kernel/api/github/index.js +444 -0
  2. package/kernel/api/index.js +199 -11
  3. package/kernel/api/process/index.js +124 -44
  4. package/kernel/api/shell_run_template.js +273 -0
  5. package/kernel/api/uri/index.js +51 -0
  6. package/kernel/bin/{conda-python.js → conda-pins.js} +23 -0
  7. package/kernel/bin/conda.js +15 -5
  8. package/kernel/bin/git.js +9 -10
  9. package/kernel/bin/huggingface.js +1 -1
  10. package/kernel/bin/index.js +5 -2
  11. package/kernel/bin/zip.js +9 -1
  12. package/kernel/connect/providers/github/README.md +5 -4
  13. package/kernel/environment.js +195 -92
  14. package/kernel/git.js +98 -19
  15. package/kernel/gitconfig_template +7 -0
  16. package/kernel/gpu/amd.js +72 -0
  17. package/kernel/gpu/apple.js +8 -0
  18. package/kernel/gpu/common.js +12 -0
  19. package/kernel/gpu/intel.js +47 -0
  20. package/kernel/gpu/nvidia.js +8 -0
  21. package/kernel/index.js +11 -1
  22. package/kernel/managed_skills.js +871 -0
  23. package/kernel/plugin.js +6 -58
  24. package/kernel/plugin_sources.js +316 -0
  25. package/kernel/resource_usage/gpu.js +349 -0
  26. package/kernel/resource_usage/index.js +322 -0
  27. package/kernel/resource_usage/macos_footprint.js +197 -0
  28. package/kernel/resource_usage/preferences.js +92 -0
  29. package/kernel/resource_usage/process_tree.js +303 -0
  30. package/kernel/scripts/git/create +4 -4
  31. package/kernel/scripts/git/fork +7 -8
  32. package/kernel/shell.js +23 -2
  33. package/kernel/shells.js +41 -0
  34. package/kernel/sysinfo.js +62 -9
  35. package/kernel/util.js +60 -0
  36. package/package.json +1 -1
  37. package/server/index.js +984 -156
  38. package/server/lib/app_log_report.js +543 -0
  39. package/server/lib/content_validation.js +55 -33
  40. package/server/lib/launcher_instruction_bootstrap.js +4 -96
  41. package/server/lib/terminal_session_helpers.js +0 -3
  42. package/server/public/common.js +77 -31
  43. package/server/public/create-launcher.js +4 -32
  44. package/server/public/logs.js +1428 -0
  45. package/server/public/nav.js +7 -0
  46. package/server/public/plugin-detail.js +93 -10
  47. package/server/public/privacy_filter_worker.js +391 -0
  48. package/server/public/style.css +1104 -154
  49. package/server/public/task-launcher.js +8 -29
  50. package/server/public/universal-launcher.css +8 -6
  51. package/server/public/universal-launcher.js +3 -27
  52. package/server/routes/apps.js +195 -1
  53. package/server/views/app.ejs +3041 -717
  54. package/server/views/autolaunch.ejs +917 -0
  55. package/server/views/bootstrap.ejs +7 -1
  56. package/server/views/d.ejs +408 -65
  57. package/server/views/editor.ejs +85 -19
  58. package/server/views/index.ejs +661 -111
  59. package/server/views/init/index.ejs +1 -1
  60. package/server/views/install.ejs +1 -1
  61. package/server/views/logs.ejs +164 -86
  62. package/server/views/net.ejs +7 -1
  63. package/server/views/partials/d_terminal_column.ejs +2 -2
  64. package/server/views/partials/d_terminal_options.ejs +0 -8
  65. package/server/views/partials/fs_status.ejs +47 -0
  66. package/server/views/partials/home_action_modal.ejs +86 -0
  67. package/server/views/partials/home_run_menu.ejs +87 -0
  68. package/server/views/partials/main_sidebar.ejs +2 -0
  69. package/server/views/partials/menu.ejs +1 -1
  70. package/server/views/plugin_detail.ejs +19 -4
  71. package/server/views/plugins.ejs +201 -3
  72. package/server/views/pre.ejs +1 -1
  73. package/server/views/pro.ejs +1 -1
  74. package/server/views/shell.ejs +40 -18
  75. package/server/views/skills.ejs +506 -0
  76. package/server/views/terminal.ejs +45 -19
  77. package/spec/INSTRUCTION_SYNC.md +20 -10
  78. package/system/plugin/antigravity-cli/antigravity.png +0 -0
  79. package/system/plugin/antigravity-cli/common.js +155 -0
  80. package/system/plugin/antigravity-cli/install.js +272 -0
  81. package/system/plugin/antigravity-cli/pinokio.js +13 -0
  82. package/system/plugin/antigravity-cli-auto/antigravity.png +0 -0
  83. package/system/plugin/antigravity-cli-auto/pinokio.js +13 -0
  84. package/system/plugin/claude/claude.png +0 -0
  85. package/system/plugin/claude/pinokio.js +47 -0
  86. package/system/plugin/claude-auto/claude.png +0 -0
  87. package/system/plugin/claude-auto/pinokio.js +58 -0
  88. package/system/plugin/claude-desktop/icon.jpeg +0 -0
  89. package/system/plugin/claude-desktop/pinokio.js +23 -0
  90. package/system/plugin/codex/openai.webp +0 -0
  91. package/system/plugin/codex/pinokio.js +42 -0
  92. package/system/plugin/codex-auto/openai.webp +0 -0
  93. package/system/plugin/codex-auto/pinokio.js +49 -0
  94. package/system/plugin/codex-desktop/icon.png +0 -0
  95. package/system/plugin/codex-desktop/pinokio.js +23 -0
  96. package/system/plugin/crush/crush.png +0 -0
  97. package/system/plugin/crush/pinokio.js +15 -0
  98. package/system/plugin/cursor/cursor.jpeg +0 -0
  99. package/system/plugin/cursor/pinokio.js +23 -0
  100. package/system/plugin/qwen/pinokio.js +34 -0
  101. package/system/plugin/qwen/qwen.png +0 -0
  102. package/system/plugin/vscode/pinokio.js +20 -0
  103. package/system/plugin/vscode/vscode.png +0 -0
  104. package/system/plugin/windsurf/pinokio.js +23 -0
  105. package/system/plugin/windsurf/windsurf.png +0 -0
  106. package/test/antigravity-cli-plugin.test.js +185 -0
  107. package/test/app-api.test.js +239 -0
  108. package/test/app-log-report.test.js +67 -0
  109. package/test/environment-cache-preflight.test.js +98 -0
  110. package/test/git-bin.test.js +59 -0
  111. package/test/git-defaults.test.js +97 -0
  112. package/test/github-api.test.js +158 -0
  113. package/test/github-connection.test.js +117 -0
  114. package/test/huggingface-bin.test.js +25 -0
  115. package/test/managed-skills.test.js +351 -0
  116. package/test/plugin-action-functions.test.js +337 -0
  117. package/test/plugin-dev-iframe.test.js +17 -0
  118. package/test/plugin-sources.test.js +203 -0
  119. package/test/privacy-filter-worker-heuristics.test.js +69 -0
  120. package/test/process-wait.test.js +169 -0
  121. package/test/script-api.test.js +97 -0
  122. package/test/shell-api.test.js +134 -0
  123. package/test/shell-run-template.test.js +209 -0
  124. package/test/storage-api.test.js +137 -0
  125. package/test/uri-api.test.js +100 -0
@@ -11,6 +11,15 @@ const fastq = require('fastq')
11
11
  const Loader = require("../loader")
12
12
  const Environment = require("../environment")
13
13
  const Util = require('../util')
14
+ const ShellRunTemplate = require('./shell_run_template')
15
+ const PluginSources = require('../plugin_sources')
16
+
17
+ const escapeHtml = (value) => String(value || "")
18
+ .replace(/&/g, "&")
19
+ .replace(/</g, "&lt;")
20
+ .replace(/>/g, "&gt;")
21
+ .replace(/"/g, "&quot;")
22
+ .replace(/'/g, "&#39;")
14
23
 
15
24
  class Api {
16
25
  constructor(kernel) {
@@ -26,6 +35,7 @@ class Api {
26
35
  this.proxies = {}
27
36
  this.mods = {}
28
37
  this.child_procs = {}
38
+ this.resolved_actions = {}
29
39
  this.lproxy = new Lproxy()
30
40
  }
31
41
  async launcher_path(name) {
@@ -398,6 +408,152 @@ class Api {
398
408
  let result = await endpoint(rpc, ondata, this.kernel)
399
409
  return result
400
410
  }
411
+ requestId(request) {
412
+ return request ? (request.id || request.path) : null
413
+ }
414
+ clearResolvedAction(requestOrId) {
415
+ const id = typeof requestOrId === "string" ? requestOrId : this.requestId(requestOrId)
416
+ if (id) {
417
+ delete this.resolved_actions[id]
418
+ }
419
+ }
420
+ setRunning(request, done) {
421
+ const id = this.requestId(request)
422
+ if (!id) {
423
+ return
424
+ }
425
+ this.running[id] = true
426
+ this.done[id] = done
427
+ }
428
+ isActionCandidate(action) {
429
+ return (Array.isArray(action) && action.length > 0) || typeof action === "function"
430
+ }
431
+ isPathInsideRoot(candidatePath, rootPath) {
432
+ if (!candidatePath || !rootPath) {
433
+ return false
434
+ }
435
+ const relative = path.relative(path.resolve(rootPath), path.resolve(candidatePath))
436
+ return relative === "" || (!!relative && !relative.startsWith("..") && !path.isAbsolute(relative))
437
+ }
438
+ toPosixPath(value) {
439
+ return String(value || "").split(path.sep).join("/")
440
+ }
441
+ pluginPathFromFilePath(filePath) {
442
+ if (!filePath) {
443
+ return ""
444
+ }
445
+ const candidatePath = path.resolve(filePath)
446
+ const systemPluginRoot = PluginSources.systemPluginRoot(this.kernel)
447
+ if (this.isPathInsideRoot(candidatePath, systemPluginRoot)) {
448
+ const relativePath = this.toPosixPath(path.relative(systemPluginRoot, candidatePath))
449
+ return PluginSources.normalizePluginPath(`${PluginSources.SYSTEM_PLUGIN_RUN_PREFIX}/${relativePath}`)
450
+ }
451
+ const localPluginRoot = this.kernel && typeof this.kernel.path === "function"
452
+ ? this.kernel.path("plugin")
453
+ : ""
454
+ if (this.isPathInsideRoot(candidatePath, localPluginRoot)) {
455
+ const relativePath = this.toPosixPath(path.relative(localPluginRoot, candidatePath))
456
+ return PluginSources.normalizePluginPath(`/plugin/${relativePath}`)
457
+ }
458
+ return ""
459
+ }
460
+ pluginInstallDetailHref(request) {
461
+ const uri = request && typeof request.uri === "string" ? request.uri : ""
462
+ let pluginPath = ""
463
+ if (uri && (PluginSources.isRunPath(uri) || uri.startsWith("/plugin/") || uri.startsWith("plugin/"))) {
464
+ pluginPath = PluginSources.normalizePluginPath(uri)
465
+ }
466
+ if (!pluginPath) {
467
+ pluginPath = this.pluginPathFromFilePath(request && request.path)
468
+ }
469
+ return pluginPath
470
+ ? `/plugin?path=${encodeURIComponent(pluginPath)}&next=install`
471
+ : "/plugins"
472
+ }
473
+ pluginInstallNoticeStep(request, script) {
474
+ const title = escapeHtml(script && script.title ? script.title : "This plugin")
475
+ return {
476
+ method: "notify",
477
+ params: {
478
+ html: `${title} is not installed. Open the plugin page and click Install.`,
479
+ href: this.pluginInstallDetailHref(request),
480
+ target: "_parent",
481
+ type: "warning",
482
+ }
483
+ }
484
+ }
485
+ async actionContext({ request, script, scriptDir, actionKey, input, args }) {
486
+ const cwd = request.cwd || scriptDir
487
+ const id = this.requestId(request)
488
+ const env = await Environment.get2(request.path, this.kernel)
489
+ this.kernel.template.update({ envs: env, env })
490
+ const port = await this.kernel.port()
491
+ const name = path.relative(this.kernel.path("api"), scriptDir)
492
+ return {
493
+ kernel: this.kernel,
494
+ info: this.kernel.info,
495
+ script: this.kernel.script,
496
+ action: actionKey,
497
+ input,
498
+ args,
499
+ global: (this.kernel.memory.global[id] || {}),
500
+ local: (this.kernel.memory.local[id] || {}),
501
+ key: this.kernel.memory.key,
502
+ uri: request.uri,
503
+ cwd,
504
+ dirname: scriptDir,
505
+ exists: (...args) => {
506
+ return fs.existsSync(path.resolve(cwd, ...args))
507
+ },
508
+ running: (...args) => {
509
+ let fullpath = path.resolve(cwd, ...args)
510
+ return this.running[fullpath]
511
+ },
512
+ name,
513
+ self: script,
514
+ port,
515
+ env,
516
+ envs: env,
517
+ ...this.kernel.vars,
518
+ }
519
+ }
520
+ async resolveActionSteps({ request, script, scriptDir, actionKey, input, args }) {
521
+ const id = this.requestId(request)
522
+
523
+ if (actionKey === "run" && script && typeof script.installed === "function" && this.isActionCandidate(script.install)) {
524
+ let installed = null
525
+ try {
526
+ const context = await this.actionContext({ request, script, scriptDir, actionKey: "installed", input, args })
527
+ installed = await script.installed.call(script, this.kernel, this.kernel.info, context)
528
+ } catch (error) {
529
+ console.warn("Plugin installed check failed", request && request.path, error)
530
+ }
531
+ if (installed === false) {
532
+ return [this.pluginInstallNoticeStep(request, script)]
533
+ }
534
+ }
535
+
536
+ const cached = id ? this.resolved_actions[id] : null
537
+ if (cached && cached.actionKey === actionKey && Array.isArray(cached.steps)) {
538
+ return cached.steps
539
+ }
540
+
541
+ const action = script ? script[actionKey] : null
542
+ let steps
543
+ if (Array.isArray(action)) {
544
+ steps = action
545
+ } else if (typeof action === "function") {
546
+ const context = await this.actionContext({ request, script, scriptDir, actionKey, input, args })
547
+ steps = await action.call(script, this.kernel, this.kernel.info, context)
548
+ } else {
549
+ steps = null
550
+ }
551
+
552
+ if (id && Array.isArray(steps)) {
553
+ this.resolved_actions[id] = { actionKey, steps }
554
+ }
555
+ return steps
556
+ }
401
557
  async stop(req, ondata) {
402
558
  // 1. set the "stop" flag for the uri, so the next execution in the queue for the uri will NOT queue another task
403
559
  // 2. stream a message closing the socket
@@ -406,10 +562,12 @@ class Api {
406
562
  // /Users/x/pinokio/prototype/system/aicode/template/claude.json?cwd=/Users/x/pinokio/api/MMAudio.git
407
563
  // take the first part only since the rest is the cwd
408
564
  req.params.uri = req.params.id.split("?")[0]
565
+ this.clearResolvedAction(req.params.id)
409
566
  }
410
567
 
411
568
  // 1. if the scropt has 'on.stop', run it when stopping
412
569
  let requestPath = this.filePath(req.params.uri)
570
+ this.clearResolvedAction(requestPath)
413
571
  let { cwd, script } = await this.resolveScript(requestPath)
414
572
  if (script.on) {
415
573
  if (script.on.stop) {
@@ -890,7 +1048,7 @@ class Api {
890
1048
 
891
1049
  let { cwd: scriptDir, script } = await this.resolveScript(request.path)
892
1050
  const actionKey = request.action || 'run'
893
- const steps = (script && Array.isArray(script[actionKey])) ? script[actionKey] : []
1051
+ const steps = await this.resolveActionSteps({ request, script, scriptDir, actionKey, input, args }) || []
894
1052
  const totalSteps = steps.length
895
1053
 
896
1054
  let name = path.relative(this.kernel.path("api"), scriptDir)
@@ -1010,6 +1168,7 @@ class Api {
1010
1168
  }
1011
1169
  // replace {{{ }}} with {{ }}
1012
1170
  rpc = this.kernel.template.flatten(rpc)
1171
+ rpc = ShellRunTemplate.renderEnvArgs(this.kernel, rpc, memory)
1013
1172
 
1014
1173
  // 6. rpc must have method names
1015
1174
  if (rpc.method) {
@@ -1222,6 +1381,7 @@ class Api {
1222
1381
 
1223
1382
 
1224
1383
  if (result && result.error) {
1384
+ this.clearResolvedAction(request)
1225
1385
  this.ondata({
1226
1386
  id: request.id || request.path,
1227
1387
  type: "error",
@@ -1403,6 +1563,7 @@ class Api {
1403
1563
 
1404
1564
  } catch (e) {
1405
1565
  console.log("<>ERROR", e)
1566
+ this.clearResolvedAction(request)
1406
1567
  this.ondata({
1407
1568
  id: request.id || request.path,
1408
1569
  type: "error",
@@ -1492,6 +1653,7 @@ class Api {
1492
1653
  // console.log("kernel.refresh after step")
1493
1654
  // this.kernel.refresh(true)
1494
1655
  } catch (e) {
1656
+ this.clearResolvedAction(request)
1495
1657
  ondata({ raw: e.toString() })
1496
1658
  }
1497
1659
  }, concurrency)
@@ -1671,18 +1833,12 @@ class Api {
1671
1833
  } else {
1672
1834
  const actionKey = request.action || 'run'
1673
1835
  request.action = actionKey
1674
- const steps = script ? script[actionKey] : null
1836
+ const action = script ? script[actionKey] : null
1675
1837
 
1676
- // 3. Check if the resolved endpoint has the requested action attribute and it's an array
1677
- if (Array.isArray(steps) && steps.length > 0) {
1838
+ // 3. Check if the resolved endpoint has the requested action attribute and resolve it to steps.
1839
+ if (this.isActionCandidate(action)) {
1678
1840
 
1679
- if (request.id) {
1680
- this.running[request.id] = true
1681
- this.done[request.id] = done
1682
- } else if (request.path) {
1683
- this.running[request.path] = true
1684
- this.done[request.path] = done
1685
- }
1841
+ this.setRunning(request, done)
1686
1842
 
1687
1843
  // set DNS
1688
1844
 
@@ -1695,6 +1851,38 @@ class Api {
1695
1851
  }
1696
1852
 
1697
1853
  const initialPayload = typeof request.input === "undefined" ? {} : request.input
1854
+ let steps
1855
+ try {
1856
+ steps = await this.resolveActionSteps({
1857
+ request,
1858
+ script,
1859
+ scriptDir: cwd,
1860
+ actionKey,
1861
+ input: initialPayload,
1862
+ args: initialPayload
1863
+ })
1864
+ } catch (e) {
1865
+ this.clearResolvedAction(request)
1866
+ delete this.running[this.requestId(request)]
1867
+ this.ondata({
1868
+ id: request.id || request.path,
1869
+ type: "error",
1870
+ data: e.stack,
1871
+ })
1872
+ return
1873
+ }
1874
+
1875
+ if (!Array.isArray(steps) || steps.length === 0) {
1876
+ this.clearResolvedAction(request)
1877
+ delete this.running[this.requestId(request)]
1878
+ this.ondata({
1879
+ id: request.id || request.path,
1880
+ type: "error",
1881
+ data: `missing or invalid attribute: ${actionKey}`
1882
+ })
1883
+ return
1884
+ }
1885
+
1698
1886
  this.queue(request, steps[0], initialPayload, 0, steps.length, cwd, initialPayload)
1699
1887
 
1700
1888
  } else {
@@ -34,6 +34,37 @@ class Process {
34
34
  constructor() {
35
35
  this.appApi = new AppAPI()
36
36
  }
37
+ isIndefiniteWait(params) {
38
+ return !params || !(
39
+ params.app ||
40
+ params.id ||
41
+ params.name ||
42
+ params.sec ||
43
+ params.min ||
44
+ params.uri ||
45
+ params.url ||
46
+ params.on
47
+ )
48
+ }
49
+ normalizeIndefiniteWaitParams(req) {
50
+ if (!req.params) {
51
+ req.params = {}
52
+ }
53
+ if (!req.params.title && !req.params.description && !req.params.message) {
54
+ req.params.title = "Waiting"
55
+ req.params.description = "Click Stop when done."
56
+ }
57
+ }
58
+ async waitIndefinitely(req, kernel) {
59
+ await new Promise((resolve, reject) => {
60
+ this.resolve = resolve
61
+
62
+ // register the process with the root uri so it can be manually resolved (with this.resolve()) later
63
+ if (kernel && kernel.procs && req && req.parent && req.parent.path) {
64
+ kernel.procs[req.parent.path] = this
65
+ }
66
+ })
67
+ }
37
68
  // async start(req, ondata, kernel) {
38
69
  // /*
39
70
  // req := {
@@ -159,6 +190,8 @@ class Process {
159
190
  /*
160
191
  params := {
161
192
  sec: <SECONDS>,
193
+ title: (optional) Title to display in the footer while waiting,
194
+ description: (optional) Description to display in the footer while waiting,
162
195
  message: (optional) Description to display while waiting,
163
196
  menu: (optional) menu to display in the modal while waiting,
164
197
  // ok: (optional) <ok button text> (if not specified, no ok button),
@@ -169,6 +202,8 @@ class Process {
169
202
 
170
203
  params := {
171
204
  min: <MINUTES>,
205
+ title: (optional) Title to display in the footer while waiting,
206
+ description: (optional) Description to display in the footer while waiting,
172
207
  message: (optional) Description to display while waiting,
173
208
  menu: (optional) menu to display in the modal while waiting,
174
209
  // ok: (optional) <ok button text> (if not specified, no ok button),
@@ -180,6 +215,8 @@ class Process {
180
215
  params := {
181
216
  url: <URL>,
182
217
  interval: (optional) how often to retry checking (in seconds)
218
+ title: (optional) Title to display in the footer while waiting,
219
+ description: (optional) Description to display in the footer while waiting,
183
220
  message: (optional) the message to display while retrying (default: no message)
184
221
  }
185
222
 
@@ -198,9 +235,21 @@ class Process {
198
235
 
199
236
  or
200
237
 
238
+ params := {
239
+ title: (optional) Title to display in the footer while waiting,
240
+ description: (optional) Description to display in the footer while waiting,
241
+ }
242
+
243
+ This waits indefinitely until the script is stopped or the wait is manually
244
+ resolved.
245
+
246
+ or
247
+
201
248
 
202
249
  params := {
203
250
  on: <wait-on condition https://github.com/jeffbski/wait-on>,
251
+ title: (optional) Title to display in the footer while waiting,
252
+ description: (optional) Description to display in the footer while waiting,
204
253
  message: (optional) Description to display while waiting,
205
254
  menu: (optional) menu to display in the modal while waiting,
206
255
  // ok: (optional) <ok button text> (if not specified, no ok button),
@@ -212,57 +261,88 @@ class Process {
212
261
  if 'cancel' is pressed before the condition is met, stops the script
213
262
 
214
263
  */
215
- let ms
216
- if (req.params) {
217
- if (req.params.app || req.params.id || req.params.name) {
218
- await this.appApi.waitForAppPresence(req, ondata, kernel)
219
- return
264
+ let ms
265
+ const waitPath = req && req.parent && req.parent.path
266
+ const indefiniteWait = this.isIndefiniteWait(req && req.params)
267
+ if (indefiniteWait && req) {
268
+ this.normalizeIndefiniteWaitParams(req)
269
+ }
270
+ if (waitPath && kernel) {
271
+ if (!kernel.activeProcessWaits) {
272
+ kernel.activeProcessWaits = {}
273
+ }
274
+ kernel.activeProcessWaits[waitPath] = {
275
+ path: waitPath,
276
+ params: req.params || {},
277
+ title: req.params && req.params.title,
278
+ description: req.params && req.params.description,
279
+ message: req.params && req.params.message,
280
+ started: Date.now()
220
281
  }
221
- // Display modal
222
- if (req.params.sec || req.params.min) {
223
- // Wait
224
- if (req.params.sec) {
225
- ms = req.params.sec * 1000
226
- } else if (req.params.min) {
227
- ms = req.params.min * 60 * 1000
282
+ }
283
+ const showFooter = req.params && (req.params.title || req.params.description || req.params.message)
284
+ if (showFooter && typeof ondata === "function") {
285
+ ondata(req.params, "process.wait.start")
286
+ }
287
+ try {
288
+ if (req.params) {
289
+ if (req.params.app || req.params.id || req.params.name) {
290
+ await this.appApi.waitForAppPresence(req, ondata, kernel)
291
+ return
228
292
  }
229
- await new Promise((resolve, reject) => {
230
- this.resolve = resolve
293
+ // Display modal
294
+ if (req.params.sec || req.params.min) {
295
+ // Wait
296
+ if (req.params.sec) {
297
+ ms = req.params.sec * 1000
298
+ } else if (req.params.min) {
299
+ ms = req.params.min * 60 * 1000
300
+ }
301
+ await new Promise((resolve, reject) => {
302
+ this.resolve = resolve
231
303
 
232
- // register the process with the root uri so it can be manually resolved (with this.resolve()) later
233
- kernel.procs[req.parent.path] = this
304
+ // register the process with the root uri so it can be manually resolved (with this.resolve()) later
305
+ kernel.procs[req.parent.path] = this
234
306
 
235
- setTimeout(() => {
236
- this.resolve()
237
- }, ms)
238
- })
239
- } else if (req.params.uri) {
240
- let interval = req.params.interval ? req.params.interval * 1000 : 1000
241
- ondata(req.params, "loading.start")
242
- await waitForUrl(req.params.uri, req.params.message, interval, ondata)
243
- ondata(req.params, "loading.end")
244
- } else if (req.params.url) {
245
- let interval = req.params.interval ? req.params.interval * 1000 : 1000
246
- ondata(req.params, "loading.start")
247
- await waitForUrl(req.params.url, req.params.message, interval, ondata)
248
- ondata(req.params, "loading.end")
249
- } else if (req.params.on) {
250
- // Wait
251
- if (req.params.message) {
252
- ondata({
253
- raw: `\r\nWaiting: ${JSON.stringify(req.params.on)}\r\n`
307
+ setTimeout(() => {
308
+ this.resolve()
309
+ }, ms)
254
310
  })
255
- ondata(req.params, "wait")
311
+ } else if (req.params.uri) {
312
+ let interval = req.params.interval ? req.params.interval * 1000 : 1000
313
+ ondata(req.params, "loading.start")
314
+ await waitForUrl(req.params.uri, req.params.message, interval, ondata)
315
+ ondata(req.params, "loading.end")
316
+ } else if (req.params.url) {
317
+ let interval = req.params.interval ? req.params.interval * 1000 : 1000
318
+ ondata(req.params, "loading.start")
319
+ await waitForUrl(req.params.url, req.params.message, interval, ondata)
320
+ ondata(req.params, "loading.end")
321
+ } else if (req.params.on) {
322
+ // Wait
323
+ if (req.params.message) {
324
+ ondata({
325
+ raw: `\r\nWaiting: ${JSON.stringify(req.params.on)}\r\n`
326
+ })
327
+ ondata(req.params, "wait")
328
+ }
329
+ console.log("Wait", req.params.on)
330
+ await waitOn(req.params.on)
331
+ console.log("Wait finished")
332
+ ondata(req.params, "wait.end")
333
+ } else {
334
+ await this.waitIndefinitely(req, kernel)
256
335
  }
257
- console.log("Wait", req.params.on)
258
- await waitOn(req.params.on)
259
- console.log("Wait finished")
260
- ondata(req.params, "wait.end")
336
+ } else {
337
+ await this.waitIndefinitely(req, kernel)
338
+ }
339
+ } finally {
340
+ if (waitPath && kernel && kernel.activeProcessWaits) {
341
+ delete kernel.activeProcessWaits[waitPath]
342
+ }
343
+ if (showFooter && typeof ondata === "function") {
344
+ ondata(req.params, "process.wait.end")
261
345
  }
262
- } else {
263
- await new Promise((resolve, reject) => {
264
- this.resolve = resolve
265
- })
266
346
  }
267
347
  }
268
348
  }