pinokiod 2.15.19 → 2.15.20

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.
@@ -67,7 +67,6 @@ class FS {
67
67
  }
68
68
 
69
69
  async link(req, ondata, kernel) {
70
- console.log("FS.link", req)
71
70
  let response = await this.share(req, ondata, kernel)
72
71
  return response
73
72
  }
@@ -277,7 +276,7 @@ class FS {
277
276
  }
278
277
 
279
278
 
280
-
279
+ // fs.link should overwrite by default.
281
280
  if (req.params.options) {
282
281
  d.options = req.params.options
283
282
  } else {
@@ -311,7 +310,6 @@ class FS {
311
310
  ondata({
312
311
  raw: "\r\nLINKING DRIVES:\r\n" + JSON.stringify(d, null, 2).replace(/\n/g, "\r\n")
313
312
  })
314
- console.log("CREATE", JSON.stringify(d, null, 2))
315
313
  await drive.create(d)
316
314
  ondata({
317
315
  raw: "Done.\r\n"
@@ -56,14 +56,12 @@ class Api {
56
56
  this.checkProxy({ uri, name })
57
57
  // if the name exists, throw error
58
58
  // if the uri exists, throw error
59
- console.log("lproxy start", uri, options)
60
59
  let proxy_uri = await this.lproxy.start(uri, options)
61
60
  if (this.proxies[scriptPath]) {
62
61
  this.proxies[scriptPath].push({ target: uri, proxy: proxy_uri, name})
63
62
  } else {
64
63
  this.proxies[scriptPath] = [{ target: uri, proxy: proxy_uri, name }]
65
64
  }
66
- console.log("this.proxies", JSON.stringify(this.proxies, null, 2))
67
65
  return {
68
66
  target: uri,
69
67
  proxy: proxy_uri
@@ -92,7 +90,6 @@ class Api {
92
90
  })
93
91
  }
94
92
  }
95
- console.log("this.proxies", JSON.stringify(this.proxies, null, 2))
96
93
  }
97
94
  async init() {
98
95
  if (this.kernel.homedir) {
@@ -519,11 +516,11 @@ class Api {
519
516
  mods.push(r)
520
517
  }
521
518
  let mod = _.zipObjectDeep(paths, mods)
522
- console.log("MOD", mod)
523
519
  return mod
524
520
 
525
521
  }
526
522
  async step (request, rawrpc, input, i, total, args) {
523
+ console.log("STEP")
527
524
 
528
525
  await this.init()
529
526
 
@@ -534,6 +531,8 @@ class Api {
534
531
 
535
532
  let { cwd, script } = await this.resolveScript(request.path)
536
533
 
534
+ console.log("RESOLVED SCRIPT", script)
535
+
537
536
  let memory = {
538
537
  script: this.kernel.script,
539
538
  input,
@@ -565,10 +564,19 @@ class Api {
565
564
  // 1. render once
566
565
  let rpc = rawrpc
567
566
  let pass = 0;
567
+ console.log("PARSE START")
568
568
  while(true) {
569
+ console.log("rpc", rpc)
570
+ console.log("memory", memory)
569
571
  rpc = this.kernel.template.render(rpc, memory)
572
+ console.log("parsed rpc", rpc)
573
+ console.log(this.kernel.template.istemplate.toString())
574
+ console.log("isteamplate = ", this.kernel.template.istemplate(rpc))
575
+ let test = this.kernel.template.istemplate(rpc)
576
+ console.log({ test })
570
577
  if (this.kernel.template.istemplate(rpc)) {
571
578
  pass++;
579
+ console.log("PASS", pass)
572
580
  if (pass >= 4) {
573
581
  // only try 4 times
574
582
  break;
@@ -579,10 +587,13 @@ class Api {
579
587
  break;
580
588
  }
581
589
  }
590
+ console.log("rpc before", { rpc })
582
591
 
583
592
  // replace {{{ }}} with {{ }}
584
593
  rpc = this.kernel.template.flatten(rpc)
585
594
 
595
+ console.log("rpc after", { rpc })
596
+
586
597
  // 6. rpc must have method names
587
598
  if (rpc.method) {
588
599
 
@@ -0,0 +1,112 @@
1
+ const path = require('path')
2
+ const set = require("../set")
3
+ const rm = require("../rm")
4
+ class J {
5
+ async get(req, ondata, kernel) {
6
+ /*
7
+ // set local variables from json
8
+ req := {
9
+ "method": "json.get",
10
+ "params": {
11
+ "<key1>": <filepath1>,
12
+ "<key1>": <filepath2>
13
+ }
14
+ }
15
+ */
16
+ let params = {}
17
+ for(let key in req.params) {
18
+ let filepath = path.resolve(req.cwd, req.params[key])
19
+ if (filepath.endsWith(".json")) {
20
+ let j = (await kernel.loader.load(filepath)).resolved
21
+ params[key] = j
22
+ }
23
+ }
24
+ let converted = Object.assign({}, req, {
25
+ params: {
26
+ local: params
27
+ }
28
+ })
29
+ await set(converted, ondata, kernel)
30
+ }
31
+ async set(req, ondata, kernel) {
32
+ /*
33
+ req := {
34
+ "method": "json.set",
35
+ "params": {
36
+ "index.json": {
37
+ <key>: <val>,
38
+ <key>: <val>,
39
+ },
40
+ "data/models.json": {
41
+ <key>: <val>,
42
+ <key>: <val>,
43
+ }
44
+ }
45
+ }
46
+
47
+ equivalent to:
48
+
49
+ req := {
50
+ "method": "set",
51
+ "params": {
52
+ "json": {
53
+ "index.json": {
54
+ <key>: <val>,
55
+ <key>: <val>,
56
+ },
57
+ "data/models.json": {
58
+ <key>: <val>,
59
+ <key>: <val>,
60
+ }
61
+ }
62
+ }
63
+ }
64
+ */
65
+ let converted = Object.assign({}, req, {
66
+ params: {
67
+ json: req.params
68
+ }
69
+ })
70
+ let res = await set(converted, ondata, kernel)
71
+ return res
72
+ }
73
+ async rm(req, ondata, kernel) {
74
+ /*
75
+ req := {
76
+ "method": "json.rm",
77
+ "params": {
78
+ "index.json": {
79
+ "abc": "def"
80
+ },
81
+ "data/models.json": {
82
+ [ "attr", "a.b.c" ]
83
+ }
84
+ }
85
+ }
86
+
87
+ equivalent to:
88
+
89
+ req := {
90
+ "method": "rm",
91
+ "params": {
92
+ "json": {
93
+ "index.json": {
94
+ "abc": "def"
95
+ },
96
+ "data/models.json": {
97
+ [ "attr", "a.b.c" ]
98
+ }
99
+ }
100
+ }
101
+ }
102
+ */
103
+ let converted = Object.assign({}, req, {
104
+ params: {
105
+ json: req.params
106
+ }
107
+ })
108
+ let res = await rm(converted, ondata, kernel)
109
+ return res
110
+ }
111
+ }
112
+ module.exports = J
@@ -25,7 +25,6 @@ class Local {
25
25
  return res
26
26
  }
27
27
  async set(req, ondata, kernel) {
28
- console.log("SET", req)
29
28
  /*
30
29
  req := {
31
30
  "method": "local.set",
@@ -96,7 +95,6 @@ class Local {
96
95
  }
97
96
  }
98
97
  const p = new Proxy()
99
- console.log("> proxy", req)
100
98
  await p.start(req, ondata, kernel)
101
99
  }
102
100
  }
@@ -52,8 +52,12 @@ module.exports = async (req, ondata, kernel) => {
52
52
  }
53
53
  */
54
54
 
55
- if (req.params.self) {
56
- for(let relative_filepath in req.params.self) {
55
+ let self = req.params.self
56
+ if (!self) {
57
+ self = req.params.json
58
+ }
59
+ if (self) {
60
+ for(let relative_filepath in self) {
57
61
  let filepath = path.resolve(req.cwd, relative_filepath)
58
62
  // ensure that the filepath is .json
59
63
  if (filepath.endsWith(".json")) {
@@ -66,7 +70,7 @@ module.exports = async (req, ondata, kernel) => {
66
70
  let folder = path.dirname(filepath)
67
71
  await fs.promises.mkdir(folder, { recursive: true }).catch((e) => { })
68
72
  }
69
- let kv = req.params.self[relative_filepath]
73
+ let kv = self[relative_filepath]
70
74
 
71
75
 
72
76
  old = rm(old, kv)
@@ -1,6 +1,7 @@
1
1
  const path = require('path')
2
2
  const fs = require('fs')
3
3
  const set = async (old, kv, kernel, req, ondata) => {
4
+ console.log("SET", { old, kv })
4
5
  for (let key in kv) {
5
6
  try {
6
7
  if (key.startsWith('[')) {
@@ -13,14 +14,33 @@ const set = async (old, kv, kernel, req, ondata) => {
13
14
  );
14
15
  old = fun(old, key, kv[key]);
15
16
  } else {
16
- let fun = new Function(
17
- 'old',
18
- 'key',
19
- 'val',
20
- //`old.${key} = val; return old;`
21
- `old["${key}"] = val; return old;`
22
- );
23
- old = fun(old, key, kv[key]);
17
+
18
+ let keypath = key.split(".")
19
+ // multiple keys. check if that path exists.
20
+ // if not, create the path
21
+ let next = old
22
+ for(let i=0; i<keypath.length; i++) {
23
+ console.log("turn", { i, path: keypath[i], next })
24
+ if (i === keypath.length-1) {
25
+ // last
26
+ next[keypath[i]] = kv[key]
27
+ } else {
28
+ const key = keypath[i];
29
+ if (!(key in next)) {
30
+ next[key] = {}
31
+ }
32
+ next = next[key];
33
+ }
34
+ }
35
+
36
+ // let fun = new Function(
37
+ // 'old',
38
+ // 'key',
39
+ // 'val',
40
+ // //`old.${key} = val; return old;`
41
+ // `old["${key}"] = val; return old;`
42
+ // );
43
+ // old = fun(old, key, kv[key]);
24
44
  }
25
45
 
26
46
 
@@ -89,6 +109,7 @@ module.exports = async (req, ondata, kernel) => {
89
109
  // }
90
110
  }
91
111
  }
112
+ console.log("kernel.memory", kernel.memory)
92
113
 
93
114
  // set self => save to the file
94
115
 
@@ -110,8 +131,12 @@ module.exports = async (req, ondata, kernel) => {
110
131
  }
111
132
  */
112
133
 
113
- if (req.params.self) {
114
- for(let relative_filepath in req.params.self) {
134
+ let self = req.params.self
135
+ if (!self) {
136
+ self = req.params.json
137
+ }
138
+ if (self) {
139
+ for(let relative_filepath in self) {
115
140
  let filepath = path.resolve(req.cwd, relative_filepath)
116
141
  // ensure that the filepath is .json
117
142
  if (filepath.endsWith(".json")) {
@@ -124,7 +149,7 @@ module.exports = async (req, ondata, kernel) => {
124
149
  let folder = path.dirname(filepath)
125
150
  await fs.promises.mkdir(folder, { recursive: true }).catch((e) => { })
126
151
  }
127
- let kv = req.params.self[relative_filepath]
152
+ let kv = self[relative_filepath]
128
153
 
129
154
  old = await set(old, kv, kernel, req, ondata)
130
155
 
@@ -207,7 +207,6 @@ class Bin {
207
207
  })
208
208
  let pipconfig_path = path.resolve(this.kernel.homedir, "pipconfig")
209
209
  let pipconfig_exists = await this.kernel.api.exists(pipconfig_path)
210
- console.log("pipconfig exists?", { pipconfig_path, pipconfig_exists })
211
210
  // if not, create one
212
211
  if (!pipconfig_exists) {
213
212
  const pipconfigStr = `[global]
@@ -371,9 +370,6 @@ class Bin {
371
370
  // console.log("metaFiles", metaFiles)
372
371
  // console.log("paths", paths)
373
372
 
374
- console.log("this.installed", this.installed)
375
-
376
-
377
373
 
378
374
  this.installed_initialized = true
379
375
 
@@ -0,0 +1,20 @@
1
+ const fs = require('fs')
2
+ const fetch = require('cross-fetch')
3
+ const { rimraf } = require('rimraf')
4
+ const decompress = require('decompress');
5
+ class UV {
6
+ async install(req, ondata) {
7
+ await this.kernel.bin.exec({
8
+ message: "conda install -y -c conda-forge uv",
9
+ }, ondata)
10
+ }
11
+ async installed() {
12
+ return this.kernel.bin.installed.conda.has("uv")
13
+ }
14
+ async uninstall(req, ondata) {
15
+ await this.kernel.bin.exec({
16
+ message: "conda remove uv",
17
+ }, ondata)
18
+ }
19
+ }
20
+ module.exports = UV
package/kernel/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  const fs = require('fs')
2
- //const {JSONPath} = require('jsonpath-plus');
3
2
  const os = require("os")
4
3
  const jsdom = require("jsdom");
5
4
  const path = require('path')
@@ -359,6 +358,7 @@ class Kernel {
359
358
  system,
360
359
  platform: this.platform,
361
360
  arch: this.arch,
361
+ env: this.envs,
362
362
  proxy: (port) => {
363
363
  return this.api.get_proxy_url("/proxy", port)
364
364
  },
package/kernel/shell.js CHANGED
@@ -403,9 +403,9 @@ class Shell {
403
403
  })
404
404
  cb()
405
405
  }, 1)
406
- term.onExit((result) => {
407
- console.log("onExit", { result })
408
- })
406
+ // term.onExit((result) => {
407
+ // console.log("onExit", { result })
408
+ // })
409
409
  term.onData((data) => {
410
410
  if (ready) {
411
411
  queue.push(data)
@@ -670,9 +670,9 @@ class Shell {
670
670
  this.queue.push(data)
671
671
  }
672
672
  });
673
- this.ptyProcess.onExit((result) => {
674
- console.log("onExit", result)
675
- })
673
+ // this.ptyProcess.onExit((result) => {
674
+ // console.log("onExit", result)
675
+ // })
676
676
  }
677
677
  } catch (e) {
678
678
  console.log("** Error", e)
package/kernel/shells.js CHANGED
@@ -41,8 +41,16 @@ class Shells {
41
41
  }, async (stream) => {
42
42
  process.stdout.write(stream.raw)
43
43
  })
44
- console.log(">>> sh.env =", sh.env)
44
+
45
45
  this.kernel.envs = sh.env
46
+ // also set the uppercase variables if they're not set
47
+ for(let key in sh.env) {
48
+ let up = key.toUpperCase()
49
+ if (!this.kernel.envs[up]) {
50
+ this.kernel.envs[up] = sh.env[key]
51
+ }
52
+ }
53
+
46
54
  }
47
55
  async launch(params, options, ondata) {
48
56
  // iterate through all the envs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "2.15.19",
3
+ "version": "2.15.20",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -35,7 +35,7 @@
35
35
  "http-proxy-middleware": "^3.0.0",
36
36
  "http-terminator": "^3.2.0",
37
37
  "isomorphic-git": "^1.23.0",
38
- "jimini": "^0.0.6",
38
+ "jimini": "^0.0.7",
39
39
  "jsdom": "^24.0.0",
40
40
  "key-store": "^1.2.0",
41
41
  "kleur": "^4.1.5",
package/server/index.js CHANGED
@@ -158,8 +158,15 @@ class Server {
158
158
  name = x.name
159
159
  description = ""
160
160
  }
161
+ let browser_url
162
+ if (x.run) {
163
+ browser_url = "/env/api/" + x.name
164
+ } else {
165
+ browser_url = "/pinokio/browser/" + x.name
166
+ }
161
167
  return {
162
168
  icon,
169
+ run: x.run,
163
170
  menu: x.menu,
164
171
  shortcuts: x.shortcuts,
165
172
  index: x.index,
@@ -170,11 +177,11 @@ class Server {
170
177
  //description: x.path,
171
178
  description,
172
179
  url: p + "/" + x.name,
173
- browser_url: "/pinokio/browser/" + x.name
180
+ browser_url,
174
181
  }
175
182
  })
176
183
  }
177
- async init_env(env_dir_path) {
184
+ async init_env(env_dir_path, options) {
178
185
  let current = this.kernel.path(env_dir_path, "ENVIRONMENT")
179
186
  // if environment.json doesn't exist,
180
187
  let exists = await this.exists(current)
@@ -187,12 +194,19 @@ class Server {
187
194
  // if _ENVIRONMENT exists,
188
195
  let _environment = this.kernel.path(env_dir_path, "_ENVIRONMENT")
189
196
  let _exists = await this.exists(_environment)
190
- let content = await Environment.ENV("app", this.kernel.homedir)
191
- if (_exists) {
192
- let _environmentStr = await fs.promises.readFile(_environment, "utf8")
193
- await fs.promises.writeFile(current, _environmentStr + "\n\n\n" + content)
197
+ if (options && options.no_inherit) {
198
+ if (_exists) {
199
+ let _environmentStr = await fs.promises.readFile(_environment, "utf8")
200
+ await fs.promises.writeFile(current, _environmentStr)
201
+ }
194
202
  } else {
195
- await fs.promises.writeFile(current, content)
203
+ let content = await Environment.ENV("app", this.kernel.homedir)
204
+ if (_exists) {
205
+ let _environmentStr = await fs.promises.readFile(_environment, "utf8")
206
+ await fs.promises.writeFile(current, _environmentStr + "\n\n\n" + content)
207
+ } else {
208
+ await fs.promises.writeFile(current, content)
209
+ }
196
210
  }
197
211
  }
198
212
  }
@@ -453,6 +467,8 @@ class Server {
453
467
  name: "playwright"
454
468
  }, {
455
469
  name: "huggingface"
470
+ }, {
471
+ name: "uv"
456
472
  }])
457
473
 
458
474
  let requirements_pending = !this.kernel.bin.installed_initialized
@@ -691,6 +707,7 @@ class Server {
691
707
  // template = "editor"
692
708
  // }
693
709
  // }
710
+
694
711
 
695
712
  let requirements = [{
696
713
  name: "conda",
@@ -730,6 +747,8 @@ class Server {
730
747
  name: "playwright"
731
748
  }, {
732
749
  name: "huggingface"
750
+ }, {
751
+ name: "uv"
733
752
  }])
734
753
  // if (platform === "linux") {
735
754
  // requirements.push({
@@ -845,7 +864,16 @@ class Server {
845
864
  edu.searchParams.set("mode", "source")
846
865
  let editorUrl = edu.pathname + edu.search
847
866
 
867
+ let referer = req.get("Referer")
868
+ console.log({ referer })
869
+
870
+ let prev = null
871
+ if (/\/env\/api\/.+/.test(new URL(referer).pathname)) {
872
+ prev = referer
873
+ }
874
+
848
875
  const result = {
876
+ prev,
849
877
  error,
850
878
  memory: mem,
851
879
  // memory: mem,
@@ -880,6 +908,8 @@ class Server {
880
908
  proxies: this.kernel.api.proxies[filepath],
881
909
  }
882
910
 
911
+ console.log({ result })
912
+
883
913
  res.render(template, result)
884
914
  } else {
885
915
  res.render("frame", {
@@ -1055,19 +1085,22 @@ class Server {
1055
1085
  error = `Please update Pinokio to the latest version (current script version: ${config.version}, supported: ${this.kernel.schema}`
1056
1086
  }
1057
1087
  }
1058
- if (config.menu) {
1059
- if (typeof config.menu === "function") {
1060
- if (config.menu.constructor.name === "AsyncFunction") {
1061
- config.menu = await config.menu(this.kernel, this.kernel.info)
1062
- } else {
1063
- config.menu = config.menu(this.kernel, this.kernel.info)
1064
- }
1065
- }
1066
-
1067
- await this.renderMenu(uri, item.name, config, pathComponents)
1068
-
1069
- items[i].menu = config.menu
1070
- }
1088
+ // if (config.run) {
1089
+ // items[i].run = config.run
1090
+ // }
1091
+ // if (config.menu) {
1092
+ // if (typeof config.menu === "function") {
1093
+ // if (config.menu.constructor.name === "AsyncFunction") {
1094
+ // config.menu = await config.menu(this.kernel, this.kernel.info)
1095
+ // } else {
1096
+ // config.menu = config.menu(this.kernel, this.kernel.info)
1097
+ // }
1098
+ // }
1099
+ //
1100
+ // await this.renderMenu(uri, item.name, config, pathComponents)
1101
+ //
1102
+ // items[i].menu = config.menu
1103
+ // }
1071
1104
 
1072
1105
  if (config.shortcuts) {
1073
1106
  if (typeof config.shortcuts === "function") {
@@ -1087,6 +1120,11 @@ class Server {
1087
1120
  continue
1088
1121
  }
1089
1122
 
1123
+ // // if there's a run clause, do not display on the home page
1124
+ // if (config && config.run && Array.isArray(config.run)) {
1125
+ // continue
1126
+ // }
1127
+
1090
1128
 
1091
1129
  // check if there is a running process with this folder name
1092
1130
  let runningApps = new Set()
@@ -1123,10 +1161,63 @@ class Server {
1123
1161
 
1124
1162
  // check running for each
1125
1163
  // running_items
1164
+ items = items.map((x) => {
1165
+ //let name = (x.name.startsWith("0x") ? Buffer.from(x.name.slice(2), "hex").toString() : x.name)
1166
+ let name
1167
+ let description
1168
+ let icon
1169
+ let uri
1170
+ if (meta) {
1171
+ let m = meta[x.name]
1172
+ name = (m && m.title ? m.title : x.name)
1173
+ description = (m && m.description ? m.description : "")
1174
+ if (m && m.icon) {
1175
+ icon = m.icon
1176
+ } else {
1177
+ icon = null
1178
+ }
1179
+ uri = x.name
1180
+ } else {
1181
+ if (x.isDirectory()) {
1182
+ icon = "fa-solid fa-folder"
1183
+ } else {
1184
+ icon = "fa-regular fa-file"
1185
+ }
1186
+ name = x.name
1187
+ description = ""
1188
+ }
1189
+ return {
1190
+ icon,
1191
+ menu: x.menu,
1192
+ run: x.run,
1193
+ shortcuts: x.shortcuts,
1194
+ //icon: (x.isDirectory() ? "fa-solid fa-folder" : "fa-regular fa-file"),
1195
+ name,
1196
+ uri,
1197
+ //description: x.path,
1198
+ description,
1199
+ //url: p + "/" + x.name,
1200
+ url: _p + "/" + x.name,
1201
+ // url: `${U}/${x.name}`,
1202
+ browser_url: "/pinokio/browser/" + x.name
1203
+ }
1204
+ })
1126
1205
 
1127
- // items
1128
-
1129
-
1206
+ // if (req.query && req.query.mode === "task") {
1207
+ // running = running.filter((x) => {
1208
+ // return x.run && Array.isArray(x.run)
1209
+ // })
1210
+ // notRunning = notRunning.filter((x) => {
1211
+ // return x.run && Array.isArray(x.run)
1212
+ // })
1213
+ // } else {
1214
+ // running = running.filter((x) => {
1215
+ // return !(x.run && Array.isArray(x.run))
1216
+ // })
1217
+ // notRunning = notRunning.filter((x) => {
1218
+ // return !(x.run && Array.isArray(x.run))
1219
+ // })
1220
+ // }
1130
1221
 
1131
1222
 
1132
1223
  // let U = `${_p}/${pathComponents.join("/")}`
@@ -1146,7 +1237,6 @@ class Server {
1146
1237
  if (this.cloudflare_pub) {
1147
1238
  qr_cloudflare = await QRCode.toDataURL(this.cloudflare_pub)
1148
1239
  }
1149
- console.log("****************", { items })
1150
1240
 
1151
1241
  res.render("index", {
1152
1242
  home_url: `http://localhost:${this.port}`,
@@ -1172,50 +1262,9 @@ class Server {
1172
1262
  notRunning,
1173
1263
  readme,
1174
1264
  filepath,
1175
- items: items
1176
- // .filter((x) => {
1177
- // return x.type !== "lib"
1178
- // })
1179
- .map((x) => {
1180
- //let name = (x.name.startsWith("0x") ? Buffer.from(x.name.slice(2), "hex").toString() : x.name)
1181
- let name
1182
- let description
1183
- let icon
1184
- let uri
1185
- if (meta) {
1186
- let m = meta[x.name]
1187
- name = (m && m.title ? m.title : x.name)
1188
- description = (m && m.description ? m.description : "")
1189
- if (m && m.icon) {
1190
- icon = m.icon
1191
- } else {
1192
- icon = null
1193
- }
1194
- uri = x.name
1195
- } else {
1196
- if (x.isDirectory()) {
1197
- icon = "fa-solid fa-folder"
1198
- } else {
1199
- icon = "fa-regular fa-file"
1200
- }
1201
- name = x.name
1202
- description = ""
1203
- }
1204
- return {
1205
- icon,
1206
- menu: x.menu,
1207
- shortcuts: x.shortcuts,
1208
- //icon: (x.isDirectory() ? "fa-solid fa-folder" : "fa-regular fa-file"),
1209
- name,
1210
- uri,
1211
- //description: x.path,
1212
- description,
1213
- //url: p + "/" + x.name,
1214
- url: _p + "/" + x.name,
1215
- // url: `${U}/${x.name}`,
1216
- browser_url: "/pinokio/browser/" + x.name
1217
- }
1218
- }),
1265
+ mode: null,
1266
+ //mode: (req.query && req.query.mode ? req.query.mode : null),
1267
+ items
1219
1268
  })
1220
1269
  }
1221
1270
  }
@@ -2120,17 +2169,18 @@ class Server {
2120
2169
  this.app.get("/proxy", ex(async (req, res) => {
2121
2170
  let live_proxies = this.kernel.api.proxies["/proxy"]
2122
2171
  if (!live_proxies) live_proxies = []
2123
- let proxies = [{
2124
- icon: "ollama.webp",
2125
- name: "Ollama",
2126
- target: 'http://127.0.0.1:11434',
2127
- port: 44002
2128
- }, {
2129
- icon: "lmstudio.jpg",
2130
- name: "LMStudio",
2131
- target: 'http://127.0.0.1:1234',
2132
- port: 44003
2133
- }]
2172
+ let proxies = []
2173
+ // let proxies = [{
2174
+ // icon: "ollama.webp",
2175
+ // name: "Ollama",
2176
+ // target: 'http://127.0.0.1:11434',
2177
+ // port: 44002
2178
+ // }, {
2179
+ // icon: "lmstudio.jpg",
2180
+ // name: "LMStudio",
2181
+ // target: 'http://127.0.0.1:1234',
2182
+ // port: 44003
2183
+ // }]
2134
2184
  for(let i=0; i<proxies.length; i++) {
2135
2185
  proxies[i].running = false
2136
2186
  for(let live_proxy of live_proxies) {
@@ -2182,8 +2232,6 @@ class Server {
2182
2232
  })
2183
2233
  }
2184
2234
  }
2185
- console.log({ apps })
2186
-
2187
2235
  res.render("proxy", {
2188
2236
  agent: this.agent,
2189
2237
  theme: this.theme,
@@ -2313,17 +2361,22 @@ class Server {
2313
2361
  this.app.get("/env/*", ex(async (req, res) => {
2314
2362
 
2315
2363
  let env_path = req.params[0]
2316
- await this.init_env(env_path)
2317
-
2318
- let pathComponents = req.params[0].split("/")
2319
- let filepath = path.resolve(this.kernel.homedir, req.params[0], "ENVIRONMENT")
2320
- let editorpath = "/edit/" + req.params[0] + "/ENVIRONMENT"
2321
- const items = await Util.parse_env_detail(filepath)
2322
2364
  let p = path.resolve(this.kernel.homedir, env_path, "pinokio.js")
2323
2365
  let config = (await this.kernel.loader.load(p)).resolved
2366
+ if (config.run) {
2367
+ await this.init_env(env_path, { no_inherit: true })
2368
+ } else {
2369
+ await this.init_env(env_path)
2370
+ }
2324
2371
 
2372
+ let pathComponents = req.params[0].split("/")
2373
+ let filepath = path.resolve(this.kernel.homedir, req.params[0], "ENVIRONMENT")
2325
2374
 
2326
- console.log(">>>>>>>>>>>>>>>>>", { config })
2375
+ let items = []
2376
+ let e = await this.exists(filepath)
2377
+ if (e) {
2378
+ items = await Util.parse_env_detail(filepath)
2379
+ }
2327
2380
  if (config.icon) {
2328
2381
  config.icon = `/${env_path}/${config.icon}?raw=true`
2329
2382
  }
@@ -2332,48 +2385,49 @@ class Server {
2332
2385
  if (env_path.startsWith("api")) {
2333
2386
  name = env_path.split("/")[1]
2334
2387
  }
2388
+ let editorpath = "/edit/" + req.params[0] + "/ENVIRONMENT"
2335
2389
 
2336
- //if (config.run) {
2337
- // let configStr = await fs.promises.readFile(p, "utf8")
2338
- // res.render("disposable", {
2339
- // home: null,
2340
- // config,
2341
- // name,
2342
- // init: req.query ? req.query.init : null,
2343
- // editorpath,
2344
- // items,
2345
- // theme: this.theme,
2346
- // filepath,
2347
- // agent: this.agent,
2348
- // path: "/api/" + name + "/pinokio.js",
2349
- // _path: "/_api/" + name,
2350
- // str: configStr
2351
- // })
2352
- //} else {
2353
- // res.render("env_editor", {
2354
- // home: null,
2355
- // config,
2356
- // name,
2357
- // init: req.query ? req.query.init : null,
2358
- // editorpath,
2359
- // items,
2360
- // theme: this.theme,
2361
- // filepath,
2362
- // agent: this.agent,
2363
- // })
2364
- //}
2365
- res.render("env_editor", {
2366
- home: null,
2367
- config,
2368
- name,
2369
- init: req.query ? req.query.init : null,
2370
- editorpath,
2371
- items,
2372
- theme: this.theme,
2373
- filepath,
2374
- agent: this.agent,
2375
- })
2376
-
2390
+ if (config.run) {
2391
+ let configStr = await fs.promises.readFile(p, "utf8")
2392
+ res.render("task", {
2393
+ home: null,
2394
+ config,
2395
+ name,
2396
+ init: true,
2397
+ // init: req.query ? req.query.init : null,
2398
+ editorpath,
2399
+ items,
2400
+ theme: this.theme,
2401
+ filepath,
2402
+ agent: this.agent,
2403
+ path: "/api/" + name + "/pinokio.js",
2404
+ _path: "/_api/" + name,
2405
+ str: configStr
2406
+ })
2407
+ } else {
2408
+ res.render("env_editor", {
2409
+ home: null,
2410
+ config,
2411
+ name,
2412
+ init: req.query ? req.query.init : null,
2413
+ editorpath,
2414
+ items,
2415
+ theme: this.theme,
2416
+ filepath,
2417
+ agent: this.agent,
2418
+ })
2419
+ }
2420
+ //res.render("env_editor", {
2421
+ // home: null,
2422
+ // config,
2423
+ // name,
2424
+ // init: req.query ? req.query.init : null,
2425
+ // editorpath,
2426
+ // items,
2427
+ // theme: this.theme,
2428
+ // filepath,
2429
+ // agent: this.agent,
2430
+ //})
2377
2431
  }))
2378
2432
  this.app.get("/pre/api/:name", ex(async (req, res) => {
2379
2433
  let p = path.resolve(this.kernel.homedir, "api", req.params.name, "pinokio.js")
@@ -53,6 +53,40 @@
53
53
  */
54
54
  --dark-btn-color: whitesmoke;
55
55
  }
56
+ .type-tabs {
57
+ display: flex;
58
+ padding: 20px 20px 0;
59
+ /*
60
+ background: rgba(0,0,0,0.05);
61
+ */
62
+ }
63
+ .type-tab {
64
+ display: flex;
65
+ align-items: center;
66
+ padding: 10px 20px;
67
+ text-decoration: none;
68
+ color: black;
69
+ margin-right: 10px;
70
+ }
71
+ .type-tab.selected {
72
+ background: rgba(0,0,100,0.04);
73
+ }
74
+ body.dark .type-tab {
75
+ background: none;
76
+ color: white;
77
+ }
78
+ body.dark .type-tab.selected {
79
+ background: rgba(255,255,255,0.03);
80
+ }
81
+ body.dark .type-tabs {
82
+ /*
83
+ background: rgba(255,255,255,0.05);
84
+ */
85
+ }
86
+ .type-tab img {
87
+ height: 20px;
88
+ margin-right: 5px;
89
+ }
56
90
  .navheader {
57
91
  padding: 15px 10px;
58
92
  }
@@ -1468,8 +1502,16 @@ body.dark .btn2 {
1468
1502
  body.dark .btn2:hover {
1469
1503
  background: rgba(255,255,255,0.06);
1470
1504
  }
1505
+ /*
1506
+ body.dark .browser-options {
1507
+ background: rgba(255,255,255,0.05);
1508
+ }
1509
+ */
1471
1510
  .browser-options {
1472
1511
  padding: 10px;
1512
+ /*
1513
+ background: rgba(0,0,0,0.05);
1514
+ */
1473
1515
  }
1474
1516
  .btn2 {
1475
1517
  background: none;
@@ -1530,7 +1572,7 @@ body.dark .header-label {
1530
1572
  font-weight: bold;
1531
1573
  text-transform: uppercase;
1532
1574
  top: 0;
1533
- padding: 10px;
1575
+ padding: 25px 15px 15px;
1534
1576
  /*
1535
1577
  border-top: 2px solid rgba(0,0,0,0.04);
1536
1578
  */
@@ -1542,7 +1584,11 @@ nav.error-message {
1542
1584
  color: rgba(0,0,0,0.7);
1543
1585
  font-weight: bold;
1544
1586
  }
1545
- .not-running-apps {
1587
+ .not-running-apps, .running-apps {
1588
+ background: rgba(0,0,100,0.04);
1589
+ }
1590
+ body.dark .not-running-apps, body.dark .running-apps {
1591
+ background: rgba(255,255,255,0.03);
1546
1592
  }
1547
1593
  .running-apps .line img {
1548
1594
  border: 4px solid #8fd400;
Binary file
Binary file
Binary file
@@ -178,8 +178,6 @@ body {
178
178
  }
179
179
  h1 {
180
180
  font-size: 50px;
181
- font-family: georgia;
182
- font-style: italic;
183
181
  padding-bottom: 20px;
184
182
  }
185
183
  footer {
@@ -495,6 +495,12 @@ document.addEventListener("DOMContentLoaded", async () => {
495
495
  }
496
496
  })
497
497
  }
498
+ <% if (locals.prev) { %>
499
+ n.Noty({
500
+ text: '[Notice] finished',
501
+ type: 'success'
502
+ })
503
+ <% } %>
498
504
  /*
499
505
  n.Noty({
500
506
  text: '[Notice] finished',
@@ -740,6 +746,9 @@ const reloadMemory = async () => {
740
746
  <header class='navheader'>
741
747
  <% if (!install_required) { %>
742
748
  <div class='runner'>
749
+ <% if (locals.prev) { %>
750
+ <a class='btn' href="<%=prev%>"><i class="fa-solid fa-arrow-left"></i> Back</a>
751
+ <% } %>
743
752
  <div class='btn run <%= mod && runnable ? "" : "hidden" %>'>
744
753
  <span class='play'><i class="fa-solid fa-play"></i> Start</span>
745
754
  <span class='starting hidden'><i class="fa-solid fa-circle-notch fa-spin"></i> Starting...</span>
@@ -70,10 +70,12 @@ header .runner {
70
70
  padding-top: 5px;
71
71
  }
72
72
  .browser-options-row {
73
+ /*
73
74
  border-top: 1px solid rgba(0,0,0,0.1);
74
75
  border-bottom: 1px solid rgba(0,0,0,0.1);
76
+ */
75
77
  display: flex;
76
- padding: 20px 0;
78
+ padding: 10px;
77
79
  align-items: flex-start;
78
80
  }
79
81
  .browser-options-row h3 {
@@ -117,10 +119,12 @@ body.dark .btn {
117
119
  body.dark .badge {
118
120
  background: rgba(255,255,255,0.1);
119
121
  }
122
+ /*
120
123
  body.dark .browser-options-row {
121
124
  border-top: 1px solid rgba(255,255,255,0.05);
122
125
  border-bottom: 1px solid rgba(255,255,255,0.05);
123
126
  }
127
+ */
124
128
  @media only screen and (max-width: 480px) {
125
129
  .btn2 {
126
130
  padding: 5px;
@@ -288,6 +292,17 @@ body.dark .browser-options-row {
288
292
  </div>
289
293
  </div>
290
294
  <% } %>
295
+ <!--
296
+ <div class='type-tabs'>
297
+ <% if (mode === "task") { %>
298
+ <a class='type-tab' href="/"><img src='/pinokio-<%=theme=='dark' ? 'white' : 'black'%>.png'> Apps</a>
299
+ <a class='type-tab selected' href="/?mode=task"> <img src='/<%=theme=='dark' ? 'term-dark.png' : 'term-white.png'%>'> Tasks</a>
300
+ <% } else { %>
301
+ <a class='type-tab selected' href="/"><img src='/pinokio-<%=theme=='dark' ? 'white' : 'black'%>.png'> Apps</a>
302
+ <a class='type-tab' href="/?mode=task"> <img src='/<%=theme=='dark' ? 'term-dark.png' : 'term-white.png'%>'> Tasks</a>
303
+ <% } %>
304
+ </div>
305
+ -->
291
306
  <% if (running.length > 0) { %>
292
307
  <div class='running-apps'>
293
308
  <div class='header-label'>Running</div>
@@ -143,8 +143,6 @@ body.dark .browser-options-row {
143
143
  margin-top: 10px;
144
144
  }
145
145
  .header-label {
146
- font-family: Georgia;
147
- font-style: italic;
148
146
  font-size: 50px;
149
147
  letter-spacing: -1px;
150
148
  padding: 50px;
@@ -255,7 +253,15 @@ body.dark .browser-options-row {
255
253
  <% apps.forEach((item) => { %>
256
254
  <a class='line align-top' href="<%=item.link%>">
257
255
  <h3>
258
- <img class='icon' src="<%=item.icon%>">
256
+ <% if (item.icon) { %>
257
+ <img class='icon' src="<%=item.icon%>">
258
+ <% } else { %>
259
+ <% if (theme === 'dark') { %>
260
+ <img class='icon' src="/pinokio-white.png">
261
+ <% } else { %>
262
+ <img class='icon' src="/pinokio-black.png">
263
+ <% } %>
264
+ <% } %>
259
265
  <div class='col'>
260
266
  <div class='title'><%=item.name%></div>
261
267
  <div class='description'><%=item.description%></div>
@@ -66,10 +66,8 @@
66
66
  padding: 20px 0;
67
67
  }
68
68
  .titleview h1 {
69
- font-style: italic;
70
69
  word-break: break-word;
71
70
  font-size: 50px;
72
- font-family: Georgia;
73
71
  letter-spacing: -1px;
74
72
  }
75
73
  .item > .d {
@@ -206,8 +206,6 @@ body.dark .cloudflare-running {
206
206
  }
207
207
  h1 {
208
208
  font-size: 50px;
209
- font-family: georgia;
210
- font-style: italic;
211
209
  padding-bottom: 10px;
212
210
  }
213
211
 
@@ -178,8 +178,6 @@ body {
178
178
  }
179
179
  h1 {
180
180
  font-size: 50px;
181
- font-family: georgia;
182
- font-style: italic;
183
181
  padding-bottom: 20px;
184
182
  }
185
183
  footer {
@@ -234,20 +232,14 @@ document.addEventListener("DOMContentLoaded", async () => {
234
232
  return res.json()
235
233
  })
236
234
  console.log("res" ,res)
237
- <% if (init && name) { %>
238
- location.href = "/pinokio/browser/<%=name%>"
239
- <% } else { %>
240
- n.Noty({
241
- text: `Updated!`
242
- })
243
- <% } %>
235
+ location.href = "<%=path%>"
244
236
  })
245
237
  <% if (init) { %>
246
- /*
247
238
  document.querySelector("#customize").addEventListener("click", (e) => {
248
239
  e.preventDefault()
249
240
  e.stopPropagation()
250
241
  document.querySelector("#editor").classList.toggle("hidden")
242
+ document.querySelector("body").classList.toggle("center")
251
243
  })
252
244
  let editor = ace.edit("editor");
253
245
  editor.setTheme("ace/theme/nord_dark");
@@ -257,7 +249,6 @@ document.addEventListener("DOMContentLoaded", async () => {
257
249
  });
258
250
  editor.session.setMode("ace/mode/javascript");
259
251
  editor.clearSelection()
260
- */
261
252
  <% } %>
262
253
  })
263
254
  </script>
@@ -266,25 +257,38 @@ document.addEventListener("DOMContentLoaded", async () => {
266
257
  <main>
267
258
  <% if (init) { %>
268
259
  <div>
269
- <h1>Run</h1>
270
260
  <% if (config) { %>
271
261
  <div class='card'>
272
262
  <% if (config.icon) { %>
273
263
  <img src="<%=config.icon%>">
264
+ <% } else { %>
265
+ <img src="/term.png">
274
266
  <% } %>
275
267
  <div class='col'>
276
268
  <div class='title'><%=config.title%></div>
277
269
  <div class='description'><%=config.description%></div>
278
270
  </div>
279
271
  </div>
272
+ <div class='env-form'>
273
+ <% items.forEach((item) => { %>
274
+ <% if (item.type === "comment") { %>
275
+ <div class='comment'><%=item.val.replaceAll(/^[ #]+/g, "")%></div>
276
+ <% } else { %>
277
+ <div class='env-item'>
278
+ <label for="<%=item.key%>"><%=item.key%></label>
279
+ <input id="<%=item.key%>" type="text" value="<%=item.val%>">
280
+ </div>
281
+ <% } %>
282
+ <% }) %>
283
+ </div>
280
284
  <% } %>
281
285
  <footer>
282
286
  <a href="/" class='btn go-home'><i class='fa-solid fa-home'></i> home</a>
283
287
  <div class='flexible'></div>
284
- <a id='customize' class='btn' target="_blank" href='<%=_path%>'><i class='fa-solid fa-code'></i> View Script</a>
285
288
  <!--
286
- <button id='customize' class='btn'><i class="fa-solid fa-code"></i> View Script</button>
289
+ <a id='customize' class='btn' target="_blank" href='<%=_path%>'><i class='fa-solid fa-code'></i> View Script</a>
287
290
  -->
291
+ <button id='customize' class='btn'><i class="fa-solid fa-code"></i> View Script</button>
288
292
  <a id='save' href="<%=path%>" class='btn'>
289
293
  <span class='save'><i class="fa-solid fa-check"></i> Run</span>
290
294
  </a>
@@ -307,7 +311,7 @@ document.addEventListener("DOMContentLoaded", async () => {
307
311
  </h1>
308
312
  </header>
309
313
  <% } %>
310
- <div id='editor' class='<%=init ? "hidden" : ''%>'><%=str%></div>
311
314
  </main>
315
+ <div id='editor' class='<%=init ? "hidden" : ''%>'><%=str%></div>
312
316
  </body>
313
317
  </html>