pinokiod 3.19.2 → 3.19.5

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.
@@ -1,5 +1,3 @@
1
- const path = require('path')
2
- const { spawn } = require("child_process");
3
1
  /*
4
2
  {
5
3
  method: "filepicker.open",
@@ -7,6 +5,7 @@ const { spawn } = require("child_process");
7
5
  title, := <dialog title>
8
6
  type, := folder | file (default)
9
7
  path, := <cwd to open from>
8
+ filetype, := <file types to accept> can be an array or string (example: `image/*.png,*.jpg` or `["image/*.png", "docs/*.pdf"]`)
10
9
  filetypes, := <file types to accept> (example: [["Images", "*.png *.jpg *.jpeg"]] )
11
10
  multiple, := True | False (allow multiple)
12
11
  save, := True | False ('save as' dialog, which lets the user select a file name)
@@ -26,6 +25,8 @@ returns: {
26
25
  }
27
26
 
28
27
  */
28
+ const path = require('path')
29
+ const Util = require("../../util")
29
30
  class Filepicker {
30
31
  async open(req, ondata, kernel) {
31
32
  if (req.params.cwd) {
@@ -35,27 +36,10 @@ class Filepicker {
35
36
  } else {
36
37
  req.params.cwd = req.cwd
37
38
  }
38
- let response = await new Promise((resolve, reject) => {
39
- let picker_path = kernel.path("bin/py/picker.py")
40
- const proc = spawn("python", [picker_path])
41
39
 
42
- let output = "";
43
- proc.stdout.on("data", (chunk) => output += chunk);
44
- proc.stderr.on("data", (err) => console.error("Python error:", err.toString()));
45
- proc.on("close", () => {
46
- try {
47
- const result = JSON.parse(output);
48
- if (result.error) return reject(result.error);
49
- resolve(result.paths); // Always an array
50
- } catch (e) {
51
- reject("Failed to parse Python output: " + output);
52
- }
53
- });
40
+ let res = await Util.filepicker(req, ondata, kernel)
41
+ return res
54
42
 
55
- proc.stdin.write(JSON.stringify(req.params));
56
- proc.stdin.end();
57
- });
58
- return { paths: response }
59
43
  }
60
44
  }
61
45
  module.exports = Filepicker
@@ -1321,7 +1321,6 @@ class Api {
1321
1321
  // look for pinokio.js
1322
1322
  let p = path.resolve(request.path, "pinokio.js")
1323
1323
  let exists = await this.exists(p)
1324
- console.log({ p, exists })
1325
1324
  if (exists) {
1326
1325
  await this.launch(request, p)
1327
1326
  } else {
@@ -1332,7 +1331,6 @@ class Api {
1332
1331
  })
1333
1332
  }
1334
1333
  } else {
1335
- console.log({ request })
1336
1334
  let { cwd, script } = await this.resolveScript(request.path)
1337
1335
 
1338
1336
  if (!script) {
@@ -0,0 +1,21 @@
1
+ /*
2
+ {
3
+ method: "push",
4
+ params: {
5
+ title: <string>,
6
+ subtitle: <string>,
7
+ message: <string>,
8
+ image: <image path>,
9
+ sound: true|false,
10
+ }
11
+ }
12
+ (*/
13
+ const util = require('../../util')
14
+ const path = require('path');
15
+ module.exports = async (req, ondata, kernel) => {
16
+ let params = req.params
17
+ if (params.image) {
18
+ params.image = path.resolve(req.cwd, params.image)
19
+ }
20
+ util.push(params)
21
+ }
@@ -0,0 +1,31 @@
1
+ const path = require('path')
2
+ class CLI {
3
+ async install(req, ondata) {
4
+ await this.kernel.exec({
5
+ message: "npm install -g pterm@latest --force",
6
+ }, ondata)
7
+ }
8
+ async installed(req, ondata) {
9
+ console.log("Check installed")
10
+ if (this.kernel.which('pinokio')) {
11
+ let res = await this.kernel.exec({
12
+ message: "pinokio version"
13
+ }, ondata)
14
+ if (/.*v0\.0\.5.*/.test(res.stdout)) {
15
+ console.log("Installed")
16
+ return true
17
+ } else {
18
+ console.log("Not Installed")
19
+ return false
20
+ }
21
+ } else {
22
+ return false
23
+ }
24
+ }
25
+ async uninstall(req, ondata) {
26
+ await this.kernel.exec({
27
+ message: "npm uninstall -g pterm",
28
+ }, ondata)
29
+ }
30
+ }
31
+ module.exports = CLI
package/kernel/bin/git.js CHANGED
@@ -45,6 +45,25 @@ class Git {
45
45
  gitconfig_path
46
46
  )
47
47
  }
48
+
49
+ await fs.promises.mkdir(this.kernel.path("scripts/git"), { recursive: true }).catch((e) => { })
50
+ let gitpush_path = path.resolve(this.kernel.homedir, "scripts/git/push.json")
51
+ await fs.promises.copyFile(
52
+ path.resolve(__dirname, "..", "scripts/git/push"),
53
+ gitpush_path
54
+ )
55
+
56
+ let gitcreate_path = path.resolve(this.kernel.homedir, "scripts/git/create.json")
57
+ await fs.promises.copyFile(
58
+ path.resolve(__dirname, "..", "scripts/git/create"),
59
+ gitcreate_path
60
+ )
61
+
62
+ let gitcommit_path = path.resolve(this.kernel.homedir, "scripts/git/commit.json")
63
+ await fs.promises.copyFile(
64
+ path.resolve(__dirname, "..", "scripts/git/commit"),
65
+ gitcommit_path
66
+ )
48
67
  }
49
68
  async installed() {
50
69
  let gitconfig_path = path.resolve(this.kernel.homedir, "gitconfig")
@@ -52,6 +71,21 @@ class Git {
52
71
  if (!exists) {
53
72
  return false;
54
73
  }
74
+ let gitpush_path = path.resolve(this.kernel.homedir, "scripts/git/push.json")
75
+ let exists2 = await this.kernel.api.exists(gitpush_path)
76
+ if (!exists2) {
77
+ return false;
78
+ }
79
+ let gitcreate_path = path.resolve(this.kernel.homedir, "scripts/git/create.json")
80
+ let exists3 = await this.kernel.api.exists(gitcreate_path)
81
+ if (!exists3) {
82
+ return false;
83
+ }
84
+ let gitcommit_path = path.resolve(this.kernel.homedir, "scripts/git/commit.json")
85
+ let exists4 = await this.kernel.api.exists(gitcommit_path)
86
+ if (!exists4) {
87
+ return false;
88
+ }
55
89
 
56
90
  if (this.kernel.platform === "darwin") {
57
91
  let gh_config_exists = await this.kernel.exists("config/gh")
@@ -4,13 +4,13 @@ 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')
8
7
  const { ProxyAgent } = require('proxy-agent');
9
8
 
10
9
  //const Cmake = require("./cmake")
11
10
  const Python = require('./python')
12
11
  const Git = require('./git')
13
12
  const Node = require('./node')
13
+ const CLI = require('./cli')
14
14
  const Brew = require("./brew")
15
15
  const Conda = require("./conda")
16
16
  const Win = require("./win")
@@ -27,6 +27,7 @@ const fse = require('fs-extra')
27
27
  const semver = require('semver')
28
28
  //const { bootstrap } = require('global-agent')
29
29
  const Environment = require('../environment')
30
+ const Util = require("../util")
30
31
  //const imageToAscii = require("image-to-ascii");
31
32
 
32
33
  const Setup = require('./setup')
@@ -198,6 +199,7 @@ class Bin {
198
199
  return e
199
200
  }
200
201
  async init() {
202
+ this.requirements_cache = {}
201
203
  this.mods = []
202
204
  if (this.kernel.homedir) {
203
205
  const bin_folder = this.path()
@@ -628,62 +630,41 @@ class Bin {
628
630
  return res
629
631
  }
630
632
  }
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
- }
633
+ // async init_launcher(req, ondata) {
634
+ // console.log("init_launcher", req)
635
+ // try {
636
+ // let projectType = req.params.projectType
637
+ // let startType = req.params.cliType || req.params.startType
638
+ // console.log({ projectType, startType })
639
+ //
640
+ // let cwd = req.cwd
641
+ // let name = req.name
642
+ // let payload = {}
643
+ // payload.cwd = path.resolve(cwd, name)
644
+ // payload.input = req.params
645
+ //
646
+ // let mod_path = path.resolve(__dirname, "../proto", projectType, startType)
647
+ // let mod = await this.kernel.require(mod_path)
648
+ //
649
+ // await mod(payload, ondata, this.kernel)
650
+ //
651
+ // // copy readme
652
+ // let readme_path = path.resolve(__dirname, "../proto/PINOKIO.md")
653
+ // console.log("copy to", readme_path, path.resolve(cwd, name, "PINOKIO.md"))
654
+ // await fs.promises.cp(readme_path, path.resolve(cwd, name, "PINOKIO.md"))
655
+ //
656
+ // // copy CLI.md
657
+ // let cli_readme_path =
658
+ //
659
+ // return { success: "/p/" + name }
660
+ // } catch (e) {
661
+ // console.log("ERROR", e)
662
+ // return { error: e.stack }
663
+ // }
664
+ // }
660
665
  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 }
666
+ let res = await Util.filepicker(req, ondata, this.kernel)
667
+ return res
687
668
  }
688
669
  async install(req, ondata) {
689
670
  /*
@@ -703,6 +684,7 @@ class Bin {
703
684
  } else {
704
685
  this.client = null
705
686
  }
687
+ console.log("Client", this.client)
706
688
  let requirements = JSON.parse(req.params)
707
689
  for(let x=0; x<10; x++) {
708
690
  console.log(`## Install Attempt ${x}`)
@@ -782,6 +764,7 @@ class Bin {
782
764
  async check_installed(r, dependencies) {
783
765
  if (Array.isArray(r.name)) {
784
766
  for(let name of r.name) {
767
+ let d = Date.now()
785
768
  let installed = await this._installed(name, r.type, dependencies)
786
769
  if (!installed) return false
787
770
  }
@@ -794,13 +777,10 @@ class Bin {
794
777
  async _installed(name, type, dependencies) {
795
778
  if (type === "conda") {
796
779
  let conda_installed = this.installed.conda.has(name)
797
- console.log({ dependencies })
798
780
  let dependencies_installed = true
799
781
  for(let d of dependencies) {
800
- console.log("checking dependency", d)
801
782
  if(!this.installed.conda.has(d)) {
802
783
  dependencies_installed = false
803
- console.log("not installed", d)
804
784
  break
805
785
  }
806
786
  }
@@ -814,10 +794,20 @@ class Bin {
814
794
  let filepath = path.resolve(__dirname, "..", "kernel", "bin", name + ".js")
815
795
  let mod = this.mod[name]
816
796
  let installed = false
817
- if (mod.installed) {
818
- installed = await mod.installed()
797
+ if (!this.cached_mod_installed) {
798
+ this.cached_mod_installed = {}
799
+ }
800
+ if (this.cached_mod_installed[name] === true) {
801
+ return true
802
+ } else {
803
+ if (mod.installed) {
804
+ installed = await mod.installed()
805
+ if (installed) {
806
+ this.cached_mod_installed[name] = true
807
+ }
808
+ }
809
+ return installed
819
810
  }
820
- return installed
821
811
  }
822
812
  }
823
813
  preset(mode) {
@@ -1002,25 +992,36 @@ class Bin {
1002
992
  install_required = false
1003
993
  for(let i=0; i<requirements.length; i++) {
1004
994
  let r = requirements[i]
1005
- //let installed = await this.installed(r)
1006
- //requirements[i].installed = installed
1007
- //if (!installed) {
1008
- // install_required = true
1009
- //}
1010
- let relevant = this.relevant(r)
1011
- requirements[i].relevant = relevant
1012
- if (relevant) {
1013
- let dependencies
1014
- if (r.name === "conda") {
1015
- dependencies = config.bin.conda_requirements
1016
- requirements[i].dependencies = dependencies
1017
- }
1018
- let installed = await this.check_installed(r, dependencies)
1019
- requirements[i].installed = installed
1020
- if (!installed) {
1021
- install_required = true
995
+ let fingerprint = JSON.stringify(r)
996
+ let installed
997
+ if (this.requirements_cache[fingerprint]) {
998
+ installed = true
999
+ requirements[i].installed = true
1000
+ } else {
1001
+ //let installed = await this.installed(r)
1002
+ //requirements[i].installed = installed
1003
+ //if (!installed) {
1004
+ // install_required = true
1005
+ //}
1006
+ let relevant = this.relevant(r)
1007
+ requirements[i].relevant = relevant
1008
+ if (relevant) {
1009
+ let dependencies
1010
+ if (r.name === "conda") {
1011
+ dependencies = config.bin.conda_requirements
1012
+ requirements[i].dependencies = dependencies
1013
+ }
1014
+ installed = await this.check_installed(r, dependencies)
1015
+ if (installed) {
1016
+ // cache if true
1017
+ this.requirements_cache[fingerprint] = true
1018
+ }
1019
+ requirements[i].installed = installed
1022
1020
  }
1023
1021
  }
1022
+ if (!installed) {
1023
+ install_required = true
1024
+ }
1024
1025
  }
1025
1026
  }
1026
1027
 
@@ -27,6 +27,7 @@ module.exports = {
27
27
  requirements = requirements.concat([
28
28
  { name: "git", },
29
29
  { name: "node", },
30
+ { name: "cli", },
30
31
  { name: "ffmpeg", },
31
32
  // { name: "caddy", }
32
33
  ])
@@ -68,6 +69,7 @@ module.exports = {
68
69
  requirements = requirements.concat([
69
70
  { name: "git", },
70
71
  { name: "node", },
72
+ { name: "cli", },
71
73
  { name: "py" },
72
74
  ])
73
75
  return {
@@ -118,6 +120,7 @@ module.exports = {
118
120
  requirements = requirements.concat([
119
121
  { name: "git", },
120
122
  { name: "node", },
123
+ { name: "cli", },
121
124
  { name: "uv", },
122
125
  ])
123
126
  let conda_requirements = [
@@ -310,9 +310,6 @@ const ENV = async (type, homedir) => {
310
310
  irrelevant_keys.push(e.key)
311
311
  }
312
312
  }
313
-
314
- console.log({ filtered_envs, irrelevant_keys })
315
-
316
313
  // let filtered_envs = envs.filter((e) => {
317
314
  // return e.type.includes(type)
318
315
  // })
package/kernel/git.js ADDED
@@ -0,0 +1,64 @@
1
+ const git = require('isomorphic-git')
2
+ const fs = require('fs')
3
+ const path = require('path')
4
+ const { glob, sync, hasMagic } = require('glob-gitignore')
5
+ const http = require('isomorphic-git/http/node')
6
+ const ini = require('ini')
7
+ class Git {
8
+ constructor(kernel) {
9
+ this.kernel = kernel
10
+ }
11
+ async repos (root) {
12
+ let _repos = await glob('**/.git/', {
13
+ cwd: root,
14
+ onlyDirectories: true,
15
+ dot: true,
16
+ ignore: ['**/node_modules/**', "**/venv/**"], // optional
17
+ });
18
+
19
+ let repos = []
20
+ for(let r of _repos) {
21
+ const gitPath = path.resolve(root, r)
22
+ const gitRelPath = path.relative(root, gitPath)
23
+ const gitParentPath = path.dirname(gitPath)
24
+ const gitParentRelPath = path.relative(this.kernel.path("api"), gitParentPath)
25
+ let dir = path.dirname(gitPath)
26
+ try {
27
+ let gitRemote = await git.getConfig({
28
+ fs,
29
+ http,
30
+ dir,
31
+ path: 'remote.origin.url'
32
+ })
33
+ repos.push({
34
+ gitPath,
35
+ gitRelPath,
36
+ gitParentPath,
37
+ gitParentRelPath,
38
+ dir,
39
+ url: gitRemote
40
+ })
41
+ } catch (e) {
42
+ repos.push({
43
+ gitPath,
44
+ gitRelPath,
45
+ gitParentPath,
46
+ gitParentRelPath,
47
+ dir,
48
+ })
49
+ }
50
+ }
51
+ return repos
52
+ }
53
+ async config (dir) {
54
+ try {
55
+ const gitConfigPath = path.resolve(dir, ".git/config")
56
+ const content = await fs.promises.readFile(gitConfigPath, 'utf-8');
57
+ const gitconfig = ini.parse(content);
58
+ return gitconfig
59
+ } catch (e) {
60
+ return null
61
+ }
62
+ }
63
+ }
64
+ module.exports = Git
package/kernel/index.js CHANGED
@@ -35,6 +35,7 @@ const Plugin = require('./plugin')
35
35
  const Router = require("./router")
36
36
  const Procs = require('./procs')
37
37
  const Peer = require('./peer')
38
+ const Git = require('./git')
38
39
  const Connect = require('./connect')
39
40
  const { DownloaderHelper } = require('node-downloader-helper');
40
41
  const { ProxyAgent } = require('proxy-agent');
@@ -276,7 +277,8 @@ class Kernel {
276
277
  return installed
277
278
  }
278
279
  async network_running() {
279
- let installed = await this.network_installed()
280
+ let installed = true
281
+ // let installed = await this.network_installed()
280
282
  if (installed) {
281
283
  try {
282
284
  await axios.get(`http://127.0.0.1:2019/config/`, { timeout: 1000 });
@@ -658,6 +660,7 @@ class Kernel {
658
660
  this.kv = new KV(this)
659
661
  this.cloudflare = new Cloudflare()
660
662
  this.peer = new Peer()
663
+ this.git = new Git(this)
661
664
 
662
665
  this.homedir = home
663
666
 
@@ -780,7 +783,9 @@ class Kernel {
780
783
  this.bin.init().then(() => {
781
784
  if (this.homedir) {
782
785
  this.shell.init().then(async () => {
783
- // this.bin.check()
786
+ this.bin.check({
787
+ bin: this.bin.preset("ai"),
788
+ })
784
789
  if (this.envs) {
785
790
  this.template.update({
786
791
  env: this.envs,
@@ -24,6 +24,9 @@ class Proto {
24
24
  }, (e) => {
25
25
  process.stdout.write(e.raw)
26
26
  })
27
+ }
28
+ let exists2 = await this.kernel.exists("prototype/PINOKIO.md")
29
+ if (!exists2) {
27
30
  await this.kernel.download({
28
31
  uri: "https://raw.githubusercontent.com/pinokiocomputer/home/refs/heads/main/docs/README.md",
29
32
  path: this.kernel.path("prototype"),
@@ -32,6 +35,16 @@ class Proto {
32
35
  process.stdout.write(e.raw)
33
36
  })
34
37
  }
38
+ let exists3 = await this.kernel.exists("prototype/CLI.md")
39
+ if (!exists3) {
40
+ await this.kernel.download({
41
+ uri: "https://raw.githubusercontent.com/pinokiocomputer/pterm/refs/heads/main/README.md",
42
+ path: this.kernel.path("prototype"),
43
+ filename: "CLI.md"
44
+ }, (e) => {
45
+ process.stdout.write(e.raw)
46
+ })
47
+ }
35
48
  }
36
49
  }
37
50
  async reset() {
@@ -59,6 +72,11 @@ class Proto {
59
72
  let readme_path = this.kernel.path("prototype/PINOKIO.md")
60
73
  await fs.promises.cp(readme_path, path.resolve(cwd, name, "PINOKIO.md"))
61
74
 
75
+ // copy cli.md
76
+ let cli_readme_path = this.kernel.path("prototype/CLI.md")
77
+ await fs.promises.cp(cli_readme_path, path.resolve(cwd, name, "CLI.md"))
78
+
79
+
62
80
  return { success: "/p/" + name }
63
81
  } catch (e) {
64
82
  console.log("ERROR", e)
@@ -200,19 +200,21 @@ class Router {
200
200
  this._mapping = {}
201
201
  this.localhost_home_router.handle()
202
202
  this.localhost_variable_router.handle(this.kernel.memory.local)
203
- for(let proc of this.kernel.processes.info) {
204
- this.localhost_port_router.handle(proc)
205
- }
206
- if (this.kernel.peer.active) {
207
- for(let host in this.kernel.peer.info) {
208
- let peer = this.kernel.peer.info[host]
209
- if (peer.host === this.kernel.peer.host) {
210
- this.peer_home_router.handle(peer)
211
- this.peer_variable_router.handle(peer)
212
- this.peer_port_router.handle(peer)
203
+ if (this.kernel.processes && this.kernel.processes.info) {
204
+ for(let proc of this.kernel.processes.info) {
205
+ this.localhost_port_router.handle(proc)
206
+ }
207
+ if (this.kernel.peer.active) {
208
+ for(let host in this.kernel.peer.info) {
209
+ let peer = this.kernel.peer.info[host]
210
+ if (peer.host === this.kernel.peer.host) {
211
+ this.peer_home_router.handle(peer)
212
+ this.peer_variable_router.handle(peer)
213
+ this.peer_port_router.handle(peer)
214
+ }
213
215
  }
216
+ await this.fill()
214
217
  }
215
- await this.fill()
216
218
  }
217
219
  this.mapping = this._mapping
218
220
  }
@@ -0,0 +1,21 @@
1
+ {
2
+ "run": [{
3
+ "method": "input",
4
+ "params": {
5
+ "form": [{
6
+ "key": "commit",
7
+ "title": "Commit message"
8
+ }]
9
+ }
10
+ }, {
11
+ "method": "shell.run",
12
+ "params": {
13
+ "chain": true,
14
+ "path": "{{args.cwd}}",
15
+ "message": [
16
+ "git add .",
17
+ "git commit -am {{input.commit}}"
18
+ ]
19
+ }
20
+ }]
21
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "run": [{
3
+ "method": "shell.run",
4
+ "params": {
5
+ "path": "{{args.cwd}}",
6
+ "input": true,
7
+ "message": [
8
+ "gh repo create"
9
+ ]
10
+ }
11
+ }]
12
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "run": [{
3
+ "method": "input",
4
+ "params": {
5
+ "form": [{
6
+ "key": "commit",
7
+ "title": "Commit message"
8
+ }]
9
+ }
10
+ }, {
11
+ "method": "shell.run",
12
+ "params": {
13
+ "chain": true,
14
+ "path": "{{args.cwd}}",
15
+ "message": [
16
+ "git add .",
17
+ "git commit -am {{input.commit}}",
18
+ "git push"
19
+ ]
20
+ }
21
+ }]
22
+ }