pinokiod 3.18.6 → 3.19.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.
@@ -50,8 +50,17 @@ class Api {
50
50
  p3 = this.kernel.path("api", name, "pinokio.json")
51
51
  }
52
52
  let pinokio = (await this.kernel.loader.load(p1)).resolved
53
+ if (pinokio && pinokio.menu && !(Array.isArray(pinokio.menu) || typeof pinokio.menu === "function")) {
54
+ delete pinokio.menu
55
+ }
53
56
  let pinokio2 = (await this.kernel.loader.load(p2)).resolved
57
+ if (pinokio2 && pinokio2.menu && !(Array.isArray(pinokio2.menu) || typeof pinokio2.menu === "function")) {
58
+ delete pinokio2.menu
59
+ }
54
60
  let pinokio3 = (await this.kernel.loader.load(p3)).resolved
61
+ if (pinokio3 && pinokio3.menu && !(Array.isArray(pinokio3.menu) || typeof pinokio3.menu === "function")) {
62
+ delete pinokio3.menu
63
+ }
55
64
  let meta = Object.assign({}, pinokio, pinokio2, pinokio3)
56
65
 
57
66
  // create pinokio.json if it doesn't exist
@@ -929,9 +938,9 @@ class Api {
929
938
  // write to current app folder's ENVIRONMENT
930
939
  let api_path = Util.api_path(request.path, this.kernel)
931
940
  let env_path = path.resolve(api_path, "ENVIRONMENT")
932
- await Util.update_env(env_path, {
933
- PINOKIO_SCRIPT_DEFAULT: "false"
934
- })
941
+ // await Util.update_env(env_path, {
942
+ // PINOKIO_SCRIPT_DEFAULT: "false"
943
+ // })
935
944
  return
936
945
  }
937
946
 
@@ -4,6 +4,7 @@ const _ = require('lodash')
4
4
  const path = require('path')
5
5
  const { rimraf } = require('rimraf')
6
6
  const { DownloaderHelper } = require('node-downloader-helper');
7
+ const { spawn } = require('child_process')
7
8
  const { ProxyAgent } = require('proxy-agent');
8
9
 
9
10
  //const Cmake = require("./cmake")
@@ -77,7 +78,6 @@ class Bin {
77
78
  "User-Agent": userAgent
78
79
  }
79
80
  }
80
- console.log("Download", opts)
81
81
  if (process.env.HTTP_PROXY && process.env.HTTP_PROXY.length > 0) {
82
82
  opts.httpRequestOptions = { agent }
83
83
  opts.httpsRequestOptions = { agent }
@@ -628,6 +628,63 @@ class Bin {
628
628
  return res
629
629
  }
630
630
  }
631
+ async init_launcher(req, ondata) {
632
+ console.log("init_launcher", req)
633
+ try {
634
+ let projectType = req.params.projectType
635
+ let startType = req.params.cliType || req.params.startType
636
+ console.log({ projectType, startType })
637
+
638
+ let cwd = req.cwd
639
+ let name = req.name
640
+ let payload = {}
641
+ payload.cwd = path.resolve(cwd, name)
642
+ payload.input = req.params
643
+
644
+ let mod_path = path.resolve(__dirname, "../proto", projectType, startType)
645
+ let mod = await this.kernel.require(mod_path)
646
+
647
+ await mod(payload, ondata, this.kernel)
648
+
649
+ // copy readme
650
+ let readme_path = path.resolve(__dirname, "../proto/PINOKIO.md")
651
+ console.log("copy to", readme_path, path.resolve(cwd, name, "PINOKIO.md"))
652
+ await fs.promises.cp(readme_path, path.resolve(cwd, name, "PINOKIO.md"))
653
+
654
+ return { success: "/p/" + name }
655
+ } catch (e) {
656
+ console.log("ERROR", e)
657
+ return { error: e.stack }
658
+ }
659
+ }
660
+ async filepicker(req, ondata) {
661
+ /*
662
+ req.params := {
663
+ cwd: cwd
664
+ }
665
+ */
666
+ let response = await new Promise((resolve, reject) => {
667
+ let picker_path = this.kernel.path("bin/py/picker.py")
668
+ const proc = spawn("python", [picker_path])
669
+
670
+ let output = "";
671
+ proc.stdout.on("data", (chunk) => output += chunk);
672
+ proc.stderr.on("data", (err) => console.error("Python error:", err.toString()));
673
+ proc.on("close", () => {
674
+ try {
675
+ const result = JSON.parse(output);
676
+ if (result.error) return reject(result.error);
677
+ resolve(result.paths); // Always an array
678
+ } catch (e) {
679
+ reject("Failed to parse Python output: " + output);
680
+ }
681
+ });
682
+
683
+ proc.stdin.write(JSON.stringify(req.params));
684
+ proc.stdin.end();
685
+ });
686
+ return { paths: response }
687
+ }
631
688
  async install(req, ondata) {
632
689
  /*
633
690
  req.params := {
@@ -12,3 +12,5 @@
12
12
  [user]
13
13
  name = pinokio
14
14
  email = pinokio
15
+ [init]
16
+ defaultBranch = main
package/kernel/peer.js CHANGED
@@ -9,14 +9,12 @@ class PeerDiscovery {
9
9
  this.interval = interval;
10
10
  this.peers = new Set();
11
11
  this.host = this._getLocalIPAddress()
12
- console.log("THIS>HOST", this.host)
13
12
  this.default_port = 42000
14
13
  this.peers.add(this.host)
15
14
  // this.start();
16
15
  }
17
16
  stop() {
18
17
  if (this.socket) {
19
- console.log("peer stop")
20
18
  clearInterval(this.interval_handle)
21
19
  this.socket.close()
22
20
  }
@@ -60,7 +58,6 @@ class PeerDiscovery {
60
58
  // if PINOKIO_NETWORK_SHARE is 0 or false, turn it off
61
59
  // if (env && env.PINOKIO_NETWORK_ACTIVE && (env.PINOKIO_NETWORK_ACTIVE==="0" || env.PINOKIO_NETWORK_ACTIVE.toLowerCase()==="false")) {
62
60
  await this.check(kernel)
63
- console.log({ active: this.active, name: this.name })
64
61
  // if (env && env.PINOKIO_NETWORK_ACTIVE && (env.PINOKIO_NETWORK_ACTIVE==="1" || env.PINOKIO_NETWORK_ACTIVE.toLowerCase()==="true")) {
65
62
  //// this.active = false
66
63
  // this.active = true
@@ -18,52 +18,51 @@ class Proto {
18
18
  await fs.promises.mkdir(this.kernel.path("prototype"), { recursive: true }).catch((e) => { })
19
19
  await this.kernel.exec({
20
20
  //message: "git clone https://github.com/peanutcocktail/prototype system",
21
- message: "git clone https://github.com/pinokiocomputer/prototype system",
21
+ //message: "git clone https://github.com/pinokiocomputer/prototype system",
22
+ message: "git clone https://github.com/pinokiocomputer/proto system",
22
23
  path: this.kernel.path("prototype")
23
24
  }, (e) => {
24
25
  process.stdout.write(e.raw)
25
26
  })
26
- }
27
-
28
- let pinokiojs_path = this.kernel.path("prototype/system/pinokio.js")
29
- let config = await this.kernel.require(pinokiojs_path)
30
- this.config = config
31
-
32
- if (this.config && this.config.menu) {
33
- this.config.menu.push({
34
- icon: "fa-solid fa-rotate",
35
- text: "Update",
36
- shell: {
37
- message: "git pull",
38
- path: this.kernel.path("prototype/system")
39
- }
27
+ await this.kernel.download({
28
+ uri: "https://raw.githubusercontent.com/pinokiocomputer/home/refs/heads/main/docs/README.md",
29
+ path: this.kernel.path("prototype"),
30
+ filename: "PINOKIO.md"
31
+ }, (e) => {
32
+ process.stdout.write(e.raw)
40
33
  })
41
34
  }
35
+ }
36
+ }
37
+ async reset() {
38
+ await fs.promises.rm(this.kernel.path("prototype"), { recursive: true })
39
+ }
40
+ async create(req, ondata) {
41
+ console.log("proto.create", req)
42
+ try {
43
+ let projectType = req.params.projectType
44
+ let startType = req.params.cliType || req.params.startType
45
+ console.log({ projectType, startType })
42
46
 
47
+ let cwd = req.cwd
48
+ let name = req.name
49
+ let payload = {}
50
+ payload.cwd = path.resolve(cwd, name)
51
+ payload.input = req.params
43
52
 
53
+ let mod_path = this.kernel.path("prototype/system", projectType, startType)
54
+ let mod = await this.kernel.require(mod_path)
44
55
 
56
+ await mod(payload, ondata, this.kernel)
45
57
 
58
+ // copy readme
59
+ let readme_path = this.kernel.path("prototype/PINOKIO.md")
60
+ await fs.promises.cp(readme_path, path.resolve(cwd, name, "PINOKIO.md"))
46
61
 
47
- //// let prototype_paths = (await glob('**/pinokio.js', { cwd }))
48
- // let prototype_dir = path.resolve(this.kernel.homedir, "prototype")
49
- // for(let prototype_path of prototype_paths) {
50
- // let proto = path.dirname(prototype_path)
51
- // let pinokiojs = path.resolve(prototype_dir, prototype_path)
52
- // let config = await this.kernel.require(pinokiojs)
53
- // if (config && config.run) {
54
- // if (config.icon) {
55
- // config.icon = "/prototype/" + proto + "/" + config.icon
56
- // } else {
57
- // config.icon === "/pinokio-black.png"
58
- // }
59
- // let c = {
60
- // id: proto,
61
- // ...config
62
- // }
63
- // this.items.push(c)
64
- // this.kv[proto] = c
65
- // }
66
- // }
62
+ return { success: "/p/" + name }
63
+ } catch (e) {
64
+ console.log("ERROR", e)
65
+ return { error: e.stack }
67
66
  }
68
67
  }
69
68
  async readme(proto) {
package/kernel/shell.js CHANGED
@@ -546,9 +546,37 @@ class Shell {
546
546
  //let delimiter = " && "
547
547
  let delimiter
548
548
  if (this.platform === "win32") {
549
- delimiter = " && "; // must use &&. & doesn't necessariliy wait until the curruent command finishes
549
+ if (params.chain) {
550
+ if (params.chain === "&") {
551
+ delimiter = " && "; // stop if one command in the chain fails
552
+ } else if (params.chain === "|") {
553
+ delimiter = " || "; // only run the rest of the chain if a command fails
554
+ } else if (params.chain === "*") {
555
+ delimiter = " & "; // always run all commands regardless of whether a command fails
556
+ } else {
557
+ // exception => use the safe option (stop when command fails)
558
+ delimiter = " && "; // must use &&. & doesn't necessariliy wait until the curruent command finishes
559
+ }
560
+ } else {
561
+ // default
562
+ delimiter = " && "; // must use &&. & doesn't necessariliy wait until the curruent command finishes
563
+ }
550
564
  } else {
551
- delimiter = " ; ";
565
+ if (params.chain) {
566
+ if (params.chain === "&") {
567
+ delimiter = " && "; // stop if one command in the chain fails
568
+ } else if (params.chain === "|") {
569
+ delimiter = " || "; // only run the rest of the chain if a command fails
570
+ } else if (params.chain === "*") {
571
+ delimiter = " ; "; // always run all commands regardless of whether a command fails
572
+ } else {
573
+ // exception => use the safe option (stop when command fails)
574
+ delimiter = " && "; // must use &&. & doesn't necessariliy wait until the curruent command finishes
575
+ }
576
+ } else {
577
+ // default
578
+ delimiter = " && "; // must use &&. & doesn't necessariliy wait until the curruent command finishes
579
+ }
552
580
  }
553
581
  return params.message.filter((m) => {
554
582
  return m && !/^\s+$/.test(m)
package/kernel/shells.js CHANGED
@@ -52,20 +52,29 @@ class Shells {
52
52
  async launch(params, options, ondata) {
53
53
  // if array, duplicate the action
54
54
  if (Array.isArray(params.message)) {
55
- let res
56
- for(let i=0; i<params.message.length; i++) {
57
- let message = params.message[i]
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
55
+ if (params.chain) {
56
+ // if "chain" attribute exists,
57
+ // run commands in the same session
58
+ let res = await this._launch(params, options, ondata)
59
+ return res
60
+ } else {
61
+ // if "chain" attribute Does not exist (Default),
62
+ // launch separate shells
63
+ let res
64
+ for(let i=0; i<params.message.length; i++) {
65
+ let message = params.message[i]
66
+ if (message) {
67
+ let params_dup = Object.assign({}, params)
68
+ params_dup.message = message
69
+ res = await this._launch(params_dup, options, ondata)
70
+ // if there's an error, immediately return with the error
71
+ if (res.error) {
72
+ return res
73
+ }
65
74
  }
66
75
  }
76
+ return res
67
77
  }
68
- return res
69
78
  } else {
70
79
  let res = await this._launch(params, options, ondata)
71
80
  return res
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "3.18.6",
3
+ "version": "3.19.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
+ "download_readme": "wget -O kernel/proto/PINOKIO.md https://raw.githubusercontent.com/pinokiocomputer/home/refs/heads/main/docs/README.md",
7
8
  "start": "node script/index"
8
9
  },
9
10
  "author": "",
package/server/index.js CHANGED
@@ -172,7 +172,6 @@ class Server {
172
172
  //if (this.kernel.api.running[filepath]) {
173
173
  if (this.kernel.api.running[id]) {
174
174
  obj.display = "indent"
175
- console.log("OBJ", obj)
176
175
  running_dynamic.push(obj)
177
176
  }
178
177
  }
@@ -409,28 +408,31 @@ class Server {
409
408
 
410
409
 
411
410
  if (config.init_required) {
412
- // none of the pinokio.js, pinokio.json, pinokio_meta.json exists => need to initialize
413
- // if there is no menu, display all files
414
- let p = this.kernel.path("api", name)
415
- let files = await fs.promises.readdir(p, { withFileTypes: true })
416
- files = files.filter((file) => {
417
- return file.name.endsWith(".json") || file.name.endsWith(".js")
418
- }).filter((file) => {
419
- return file.name !== "pinokio.js" && file.name !== "pinokio.json" && file.name !== "pinokio_meta.json"
420
- })
421
- config = {
422
- init_required: true,
423
- icon: config.icon,
424
- title: name,
425
- menu: files.map((file) => {
426
- return {
427
- text: file.name,
428
- href: file.name
429
- }
430
- })
431
- }
432
- let uri = this.kernel.path("api")
433
- await this.renderMenu(uri, name, config, [])
411
+ res.redirect("/init/" + name)
412
+ return
413
+
414
+ // // none of the pinokio.js, pinokio.json, pinokio_meta.json exists => need to initialize
415
+ // // if there is no menu, display all files
416
+ // let p = this.kernel.path("api", name)
417
+ // let files = await fs.promises.readdir(p, { withFileTypes: true })
418
+ // files = files.filter((file) => {
419
+ // return file.name.endsWith(".json") || file.name.endsWith(".js")
420
+ // }).filter((file) => {
421
+ // return file.name !== "pinokio.js" && file.name !== "pinokio.json" && file.name !== "pinokio_meta.json"
422
+ // })
423
+ // config = {
424
+ // init_required: true,
425
+ // icon: config.icon,
426
+ // title: name,
427
+ // menu: files.map((file) => {
428
+ // return {
429
+ // text: file.name,
430
+ // href: file.name
431
+ // }
432
+ // })
433
+ // }
434
+ // let uri = this.kernel.path("api")
435
+ // await this.renderMenu(uri, name, config, [])
434
436
  } else {
435
437
  let menu = config.menu || []
436
438
  if (typeof config.menu === "function") {
@@ -560,9 +562,6 @@ class Server {
560
562
  if (!this.kernel.proto.config) {
561
563
  await this.kernel.proto.init()
562
564
  }
563
- // if (!this.kernel.plugin.config) {
564
- // await this.kernel.plugin.init()
565
- // }
566
565
  res.render("app", result)
567
566
  }
568
567
  getVariationUrls(req) {
@@ -2579,6 +2578,13 @@ class Server {
2579
2578
 
2580
2579
  let gitconfig = path.resolve(home, "gitconfig")
2581
2580
  await fse.remove(gitconfig)
2581
+ await fs.promises.copyFile(
2582
+ path.resolve(__dirname, "..", "kernel", "gitconfig_template"),
2583
+ gitconfig
2584
+ )
2585
+
2586
+ let prototype_path = path.resolve(home, "prototype")
2587
+ await fse.remove(prototype_path)
2582
2588
 
2583
2589
 
2584
2590
  console.log("[TRY] Updating to the new version")
@@ -2731,9 +2737,9 @@ class Server {
2731
2737
  // return
2732
2738
  // }
2733
2739
 
2734
- if (!this.kernel.proto.config) {
2735
- await this.kernel.proto.init()
2736
- }
2740
+ // if (!this.kernel.proto.config) {
2741
+ // await this.kernel.proto.init()
2742
+ // }
2737
2743
  if (!this.kernel.plugin.config) {
2738
2744
  await this.kernel.plugin.init()
2739
2745
  }
@@ -2906,6 +2912,57 @@ class Server {
2906
2912
  // }
2907
2913
  }))
2908
2914
 
2915
+ this.app.get("/init/:name", ex(async (req, res) => {
2916
+ /*
2917
+ option 1: new vs. clone
2918
+ - new|clone
2919
+
2920
+ option 2: type
2921
+ - empty
2922
+ - cli app
2923
+ - documentation
2924
+ - nodejs project
2925
+ - python project
2926
+ - gradio + torch
2927
+
2928
+ option 3: ai vs. empty
2929
+ - prompt
2930
+
2931
+ */
2932
+ res.render("prototype/init", {
2933
+ cwd: this.kernel.path("api"),
2934
+ name: req.params.name,
2935
+ portal: this.portal,
2936
+ // items,
2937
+ logo: this.logo,
2938
+ platform: this.kernel.platform,
2939
+ theme: this.theme,
2940
+ agent: this.agent,
2941
+ kernel: this.kernel,
2942
+ })
2943
+ /*
2944
+ let config = structuredClone(this.kernel.proto.config)
2945
+ console.log(config)
2946
+ config = this.renderMenu2(config, {
2947
+ cwd: req.query.path,
2948
+ href: "/prototype/show",
2949
+ path: this.kernel.path("prototype/system"),
2950
+ web_path: "/asset/prototype/system"
2951
+ })
2952
+ res.render("prototype/index", {
2953
+ config,
2954
+ path: req.query.path,
2955
+ portal: this.portal,
2956
+ // items,
2957
+ logo: this.logo,
2958
+ platform: this.kernel.platform,
2959
+ theme: this.theme,
2960
+ agent: this.agent,
2961
+ kernel: this.kernel,
2962
+ })
2963
+ */
2964
+ }))
2965
+
2909
2966
  this.app.get("/check_router_up", ex(async (req, res) => {
2910
2967
  let response = await this.check_router_up()
2911
2968
  res.json(response)
@@ -3656,7 +3713,8 @@ class Server {
3656
3713
 
3657
3714
  res.json({
3658
3715
  //success: "/pinokio/browser/"+folder
3659
- success: "/p/"+folder
3716
+ //success: "/p/"+folder
3717
+ success: "/init/"+folder
3660
3718
  })
3661
3719
  } catch (e) {
3662
3720
  res.json({
@@ -147,8 +147,7 @@ body.dark .dynamic.selected {
147
147
 
148
148
  .url-bar {
149
149
  font-family: verdana;
150
- font-size: 13px;
151
- line-height: 15px;
150
+ font-size: 12px;
152
151
  padding: 0 10px;
153
152
  font-weight: normal;
154
153
  flex-grow: 1;
@@ -304,7 +304,10 @@ body.dark .open-menu, body.dark .browse {
304
304
  <% if (ishome) { %>
305
305
  <form class='search'>
306
306
  <div class='app-btns'>
307
- <a class='btn create-new' id='create-new-folder'><i class="fa-solid fa-folder-plus"></i> Create</a>
307
+ <a class='btn create-new' id='create-new-folder'><i class="fa-solid fa-plus"></i> New</a>
308
+ <!--
309
+ <a class='btn create-new' href="/create"><i class="fa-solid fa-folder-plus"></i> Create</a>
310
+ -->
308
311
  <a class='btn' id='explore' href="/?mode=explore"><i class="fa-solid fa-magnifying-glass"></i> Discover</a>
309
312
  </div>
310
313
  <% if (display.includes("form")) { %>