pinokiod 1.3.61 → 1.3.63

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.
@@ -12,6 +12,7 @@ class C {
12
12
 
13
13
  => cloudflared tunnel --url http://localhost:8080
14
14
  */
15
+ console.log("TUNNEL", req)
15
16
  const message = `cloudflared tunnel --url ${req.params.uri}`
16
17
  let params = {
17
18
  id: message,
@@ -25,6 +26,7 @@ class C {
25
26
  if (req.cwd) options.cwd = req.cwd
26
27
  if (req.parent && req.parent.path) options.group = req.parent.path
27
28
  let pattern = /(https:.+?trycloudflare\.com)/
29
+ console.log("params", params)
28
30
  let cloudflare_url = await new Promise((resolve, reject) => {
29
31
  kernel.shell.start(params, options, (e) => {
30
32
  ondata(e)
@@ -66,6 +66,11 @@ const ENVS = [{
66
66
  val: (home) => {
67
67
  return path.resolve(home, "drive")
68
68
  }
69
+ }, {
70
+ key: "PINOKIO_SCRIPT_DEFAULT",
71
+ val: (home) => {
72
+ return "true"
73
+ }
69
74
  }];
70
75
  const folders = ENVS.filter((env) => {
71
76
  return env.type === "cache_folder" || env.type === "folder"
@@ -141,6 +146,15 @@ const APP_ENV = () => {
141
146
  "#",
142
147
  "##########################################################################",
143
148
  "PINOKIO_SHARE_CLOUDFLARE=false",
149
+ "",
150
+ "##########################################################################",
151
+ "#",
152
+ "# PINOKIO_SCRIPT_DEFAULT",
153
+ "# If this variable is false, 'default': true menu items in pinokio.js",
154
+ "# will NOT automatically run",
155
+ "#",
156
+ "##########################################################################",
157
+ "PINOKIO_SCRIPT_DEFAULT=true",
144
158
  ]
145
159
  return items.join("\n")
146
160
  }
package/kernel/index.js CHANGED
@@ -43,6 +43,24 @@ class Kernel {
43
43
  this.exposed = {}
44
44
  this.envs = {}
45
45
  }
46
+ /*
47
+ kernel.env() => return the system environment
48
+ kernel.env("api/stablediffusion") => returns the full environment object
49
+ */
50
+ async env(...args) {
51
+ let folderpath
52
+ if (args) {
53
+ folderpath = path.resolve(this.homedir, ...args)
54
+ } else {
55
+ folderpath = this.homedir
56
+ }
57
+ console.log({ args , folderpath,homedir: this.homedir })
58
+ let api_path = await Util.api_path(folderpath, this)
59
+ let current_env = await Environment.get(api_path)
60
+ let default_env = await Environment.get(this.homedir)
61
+ console.log({ api_path, current_env, default_env })
62
+ return Object.assign(process.env, default_env, current_env)
63
+ }
46
64
  resumeprocess(uri) {
47
65
  let proc = this.procs[uri]
48
66
  if (proc && proc.resolve) {
package/kernel/shell.js CHANGED
@@ -71,6 +71,8 @@ class Shell {
71
71
  this.cols = params.cols ? params.cols : 100;
72
72
  this.rows = params.rows ? params.rows : 30;
73
73
 
74
+ console.log({ cols: this.cols, rows: this.rows })
75
+
74
76
  this.vt = new Terminal({
75
77
  allowProposedApi: true,
76
78
  cols: this.cols,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "1.3.61",
3
+ "version": "1.3.63",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/server/index.js CHANGED
@@ -234,8 +234,10 @@ class Server {
234
234
  let current = this.kernel.path("api", name, "ENVIRONMENT")
235
235
  // if environment.json doesn't exist,
236
236
  let exists = await this.exists(current)
237
+ console.log("exists", exists)
237
238
  if (!exists) {
238
239
  let content = await Environment.APP_ENV()
240
+ console.log("write", content)
239
241
  await fs.promises.writeFile(current, content)
240
242
  }
241
243
 
@@ -245,8 +247,12 @@ class Server {
245
247
  mode = req.query.mode
246
248
  }
247
249
 
250
+ const env = await this.kernel.env("api/" + name)
251
+ console.log("env", env)
252
+
248
253
  //res.render("browser", {
249
254
  res.render("browser-experimental", {
255
+ env,
250
256
  mode,
251
257
  port: this.port,
252
258
  mem,
@@ -2152,8 +2158,10 @@ class Server {
2152
2158
  this.app.get("/env/*", async (req, res) => {
2153
2159
  let pathComponents = req.params[0].split("/")
2154
2160
  let filepath = path.resolve(this.kernel.homedir, req.params[0])
2161
+ let editorpath = "/edit/" + req.params[0]
2155
2162
  const items = await Util.parse_env_detail(filepath)
2156
2163
  res.render("env_editor", {
2164
+ editorpath,
2157
2165
  items,
2158
2166
  theme: this.theme,
2159
2167
  filepath,
package/server/socket.js CHANGED
@@ -106,9 +106,17 @@ class Socket {
106
106
  //const subscribers = this.subscriptions.get(e.id) || new Set();
107
107
  subscribers.forEach((subscriber) => {
108
108
  if (subscriber.readyState === WebSocket.OPEN) {
109
- delete e.rpc
110
- delete e.rawrpc
111
- subscriber.send(JSON.stringify(e))
109
+ let res = Object.assign({}, e)
110
+ delete res.rpc
111
+ delete res.rawrpc
112
+ if (res.data && res.data.id && res.data.raw) {
113
+ res.data = {
114
+ id: res.data.id,
115
+ raw: res.data.raw
116
+ }
117
+ }
118
+ console.log("*** res1", res)
119
+ subscriber.send(JSON.stringify(res))
112
120
  }
113
121
  });
114
122
  }
@@ -126,9 +134,19 @@ class Socket {
126
134
  if (subscribers.size > 0) {
127
135
  subscribers.forEach((subscriber) => {
128
136
  if (subscriber.readyState === WebSocket.OPEN) {
129
- delete e.rpc
130
- delete e.rawrpc
131
- subscriber.send(JSON.stringify(e))
137
+
138
+ let res = Object.assign({}, e)
139
+ delete res.rpc
140
+ delete res.rawrpc
141
+ if (res.data && res.data.id && res.data.raw) {
142
+ res.data = {
143
+ id: res.data.id,
144
+ raw: res.data.raw
145
+ }
146
+ }
147
+ console.log("*** res2", res)
148
+ subscriber.send(JSON.stringify(res))
149
+
132
150
  }
133
151
  });
134
152
  }
@@ -265,9 +265,11 @@ body.dark .frame-link.selected {
265
265
  }
266
266
  .loader .btn:hover {
267
267
  color: royalblue;
268
+ border-color: royalblue;
268
269
  }
269
270
  .loader .btn {
270
271
  padding: 4px 8px;
272
+ border: 1px solid rgba(255,255,255,0.3);
271
273
  }
272
274
  .frame-link .tab {
273
275
  flex-grow: 1;
@@ -348,9 +350,16 @@ body.dark nav {
348
350
  }
349
351
  .container:hover nav {
350
352
  display: block;
353
+ max-height: 200px;
351
354
  }
352
355
  nav {
356
+ overflow: hidden;
357
+ max-height: 0;
358
+ transition: max-height 0.4s ease-out;
359
+
360
+ /*
353
361
  display: none;
362
+ */
354
363
  background: white;
355
364
  /*
356
365
  position: absolute;
@@ -610,7 +619,7 @@ body.dark .loader-container {
610
619
  <button class='btn2' id='clone-tab'><i class='fa-regular fa-copy'></i> Clone</button>
611
620
  <a class='btn2' id='open-browser' target="_blank" href="" features="browser"><i class="fa-solid fa-square-arrow-up-right"></i> Popout</a>
612
621
  <button class='btn2' id='reload'><i class="fa-solid fa-rotate-right"></i> Refresh</button>
613
- <div id='new-tab' class='btn2'><i class="fa-solid fa-plus"></i> New</div>
622
+ <div id='new-tab' class='btn2'><i class="fa-solid fa-plus"></i> Tab</div>
614
623
  <!--
615
624
  <button class='btn2 logo' id='reload'><i class="fa-solid fa-rotate-right"></i></button>
616
625
  -->
@@ -723,7 +732,7 @@ const renderSelection = (e, force) => {
723
732
  console.log("# 1")
724
733
  // if the menu has a default item, or if the url specifies a selection
725
734
  let selection = null;
726
- <% if (type === "run") { %>
735
+ <% if (type === "run" && env.PINOKIO_SCRIPT_DEFAULT && env.PINOKIO_SCRIPT_DEFAULT.toString().toLowerCase() === "true") { %>
727
736
  selection = document.querySelector("[data-default]")
728
737
  <% } %>
729
738
  if (selection || location.hash && location.hash.length > 0) {
@@ -935,6 +944,9 @@ const renderSelection = (e, force) => {
935
944
  targetFrame.src = target.href
936
945
  }
937
946
  }
947
+ targetFrame.contentWindow.postMessage({
948
+ action: "foreground"
949
+ }, "*")
938
950
  }
939
951
  } else {
940
952
  console.log("# 12")
@@ -162,6 +162,7 @@ document.addEventListener("DOMContentLoaded", async () => {
162
162
  <div id='save' class='btn'>
163
163
  <span class='save'><i class="fa-solid fa-check"></i> Save</span>
164
164
  </div>
165
+ <a class='btn' href="<%=editorpath%>"><i class="fa-solid fa-pen-to-square"></i> Edit file</a>
165
166
  <button class='btn' id='open-fs' data-filepath="<%=filepath%>"><i class="fa-solid fa-eye"></i> Open in File Explorer</button>
166
167
  </div>
167
168
  </header>
@@ -139,6 +139,10 @@ document.addEventListener("DOMContentLoaded", async () => {
139
139
  constructor() {
140
140
  this.socket = new Socket()
141
141
  }
142
+ write(text) {
143
+ this.term.write(text)
144
+ this.dirty = true
145
+ }
142
146
  finished() {
143
147
  /*
144
148
  n.Noty({
@@ -201,7 +205,11 @@ document.addEventListener("DOMContentLoaded", async () => {
201
205
  rows: this.term.rows,
202
206
  }
203
207
  }, async (packet) => {
204
- // console.log("packet", packet)
208
+
209
+ console.log("packet", packet.type, packet)
210
+ if (packet.data) {
211
+ console.log("packet.data.raw", packet.data.raw)
212
+ }
205
213
  if (packet.type === 'start') {
206
214
  refreshParent(packet)
207
215
  reloadMemory()
@@ -233,14 +241,15 @@ document.addEventListener("DOMContentLoaded", async () => {
233
241
  // </div>`
234
242
  }
235
243
  } else if (packet.type === "stream") {
244
+ console.log({ cols: this.term.cols, rows: this.term.rows })
236
245
  if (packet.data.raw) {
237
- this.term.write(packet.data.raw)
246
+ this.write(packet.data.raw)
238
247
  } else if (packet.data.json) {
239
- this.term.write(JSON.stringify(packet.data.json).replace(/\n/g, "\r\n"))
240
- this.term.write("\r\n")
248
+ this.write(JSON.stringify(packet.data.json).replace(/\n/g, "\r\n"))
249
+ this.write("\r\n")
241
250
  } else if (packet.data.json2) {
242
- this.term.write(JSON.stringify(packet.data.json2, null, 2).replace(/\n/g, "\r\n"))
243
- this.term.write("\r\n")
251
+ this.write(JSON.stringify(packet.data.json2, null, 2).replace(/\n/g, "\r\n"))
252
+ this.write("\r\n")
244
253
  }
245
254
  document.querySelector(".run .play").classList.add("hidden")
246
255
  document.querySelector(".run .starting").classList.add("hidden")
@@ -248,14 +257,14 @@ document.addEventListener("DOMContentLoaded", async () => {
248
257
  } else if (packet.type === 'disconnect') {
249
258
  refreshParent(packet)
250
259
  reloadMemory()
251
- this.term.write("\r\nDisconnected...\r\n")
260
+ //this.term.write("\r\nDisconnected...\r\n")
252
261
  document.querySelector("footer").innerHTML = "<b>Ready</b>"
253
262
  this.socket.close()
254
263
  document.querySelector(".run .play").classList.remove("hidden")
255
264
  document.querySelector(".run .stop").classList.add("hidden")
256
265
  } else if (packet.type === 'connect') {
257
266
  const message = "..........Connected!\r\n"
258
- this.term.write(message)
267
+ this.write(message)
259
268
  /*
260
269
  for(let i=0; i<message.length; i++) {
261
270
  await new Promise((r, reject) => {
@@ -527,6 +536,7 @@ document.addEventListener("DOMContentLoaded", async () => {
527
536
  createTerm () {
528
537
  if (!this.term) {
529
538
  const term = new Terminal({
539
+ scrollback: 9999999,
530
540
  //theme: xtermTheme.Piatto_Light,
531
541
  //theme: xtermTheme.Spring,
532
542
 
@@ -597,6 +607,41 @@ document.addEventListener("DOMContentLoaded", async () => {
597
607
  <% if (mod && runnable) { %>
598
608
  window.addEventListener('message', function(event) {
599
609
  console.log("Message received from the parent: ", event.data); // Message received from parent
610
+ // "foreground" message adds a newline to the terminal
611
+ // Needed to fix the issue where the terminal won't write anything when in background
612
+ // so when coming back from background, need to refresh by just adding a newline.
613
+ if (event.data && event.data.action === "foreground") {
614
+
615
+
616
+ // if dirty, update
617
+ // if not dirty, don't update
618
+ const delimiter = "\r\n"
619
+ if (rpc.dirty) {
620
+ rpc.term.write(delimiter)
621
+ rpc.dirty = false
622
+ } else {
623
+ }
624
+
625
+ //console.log("buffer", rpc.term.buffer)
626
+ //if (rpc.term.buffer) {
627
+ // const lastRow = rpc.term.buffer.active.baseY;
628
+ // const lastLine = rpc.term.buffer.active.getLine(lastRow);
629
+ // const lastLine2 = rpc.term.buffer.active.getLine(lastRow-1);
630
+ // const cell = lastLine.getCell().getChars()
631
+ // const cell2 = lastLine.getCell().getChars()
632
+ // console.log({ lastLine, lastLine2, cell, cell2 })
633
+ // const lastStr = cell[cell.length - 3];
634
+ // console.log({ lastRow, lastLine, lastStr })
635
+
636
+ // const delimiter = "\r\n█"
637
+ // if (lastStr === delimiter) {
638
+ // console.log("don't update")
639
+ // } else {
640
+ // console.log("update")
641
+ // rpc.term.write(delimiter)
642
+ // }
643
+ //}
644
+ }
600
645
  });
601
646
 
602
647
  document.querySelector(".stop").addEventListener("click", async (e) => {
@@ -283,9 +283,6 @@ body.dark .browser-options-row {
283
283
  <div class='title'><%=item.name%></div>
284
284
  <div class='description'><%=item.description%></div>
285
285
  <div>
286
- <button class='btn browse' data-src="<%=item.browser_url%>/browse">
287
- <i class="fa-regular fa-folder-open"></i>
288
- </button>
289
286
  <% if (item.running_scripts) { %>
290
287
  <% item.running_scripts.forEach((s) => { %>
291
288
  <button class='btn shutdown' data-src="<%=s.path%>">
@@ -333,9 +330,6 @@ body.dark .browser-options-row {
333
330
  <div class='uri'><i class="fa-regular fa-folder"></i><%=item.url%></div>
334
331
  <div class='title'><%=item.name%></div>
335
332
  <div class='description'><%=item.description%></div>
336
- <button class='btn browse' data-src="<%=item.browser_url%>/browse">
337
- <i class="fa-regular fa-folder-open"></i>
338
- </button>
339
333
  <% if (item.shortcuts && item.shortcuts.length > 0) { %>
340
334
  <div class='btns'>
341
335
  <% item.shortcuts.forEach((btn) => { %>
@@ -758,7 +752,6 @@ document.addEventListener("click", (e) => {
758
752
  }
759
753
 
760
754
 
761
- debugger
762
755
  if (e.target.classList.contains("browse")) {
763
756
  target = e.target
764
757
  } else {
@@ -783,7 +776,6 @@ document.addEventListener("click", (e) => {
783
776
  }
784
777
 
785
778
  console.log("EL", el)
786
- debugger
787
779
 
788
780
  if (el) {
789
781
  e.preventDefault()
@@ -302,7 +302,7 @@ hr {
302
302
  <br>
303
303
  <div>Edit the system ENVIRONMENT file to customize pinokio system wide settings, such as where files are stored, terminal behavior, etc.</div>
304
304
  <br>
305
- <a class='btn' href="/env/ENVIRONMENT">Edit ENVIRONMENT</a>
305
+ <a class='btn' href="/env/ENVIRONMENT"><i class="fa-regular fa-pen-to-square"></i> Edit ENVIRONMENT</a>
306
306
  </div>
307
307
  <hr/>
308
308
  <div class='troubleshoot'>
@@ -109,6 +109,11 @@ body.dark .env-item label {
109
109
  display: inline-block;
110
110
  margin-bottom: 5px;
111
111
  font-weight: bold;
112
+ font-size: 20px;
113
+ letter-spacing: -1px;
114
+ }
115
+ .env-item ul {
116
+ margin: 5px 0;
112
117
  }
113
118
  .env-item {
114
119
  padding-top: 10px;
@@ -173,8 +178,14 @@ document.addEventListener("DOMContentLoaded", async () => {
173
178
  <% } else { %>
174
179
  <input type="checkbox" id="PINOKIO_SHARE_CLOUDFLARE" name="cloudflare" />
175
180
  <% } %>
176
- <label for="cloudflare">Share Publicly</label>
177
- <div>This will set the PINOKIO_SHARE_CLOUDFLARE environment variable to true, and share your local app to the public internet, powered by <a href="https://www.cloudflare.com/products/tunnel/" target="_blank" features="browser">Cloudflare Tunnel</a></div>
181
+ <label for="cloudflare"><i class="fa-brands fa-cloudflare"></i> Start a Public Node</label>
182
+ <ul>
183
+ <li>This will turn this local app into a public node.</li>
184
+ <li>Anyone with a URL can access a public node.</li>
185
+ <li>Users can't access Pinokio itself, only can access each app's UI.</li>
186
+ <li>Powered by <a href="https://www.cloudflare.com/products/tunnel/" target="_blank" features="browser">Cloudflare Tunnel</a></li>
187
+ <li>You can manually configure this in through the Configure menu (set PINOKIO_SHARE_CLOUDFLARE to true)</li>
188
+ </ul>
178
189
  </div>
179
190
  <div class='env-item'>
180
191
  <% if (config.PINOKIO_SHARE_LOCAL.toString() === "true") { %>
@@ -182,8 +193,12 @@ document.addEventListener("DOMContentLoaded", async () => {
182
193
  <% } else { %>
183
194
  <input type="checkbox" id="PINOKIO_SHARE_LOCAL" name="local" />
184
195
  <% } %>
185
- <label for="local">Share with Local Network Devices</label>
186
- <div>This will set the PINOKIO_SHARE_LOCAL environment variable to true, and share your local app to any device on the same local network</div>
196
+ <label for="local"><i class="fa-solid fa-network-wired"></i> Share with Local Network</label>
197
+ <ul>
198
+ <li>This will allow any device on the same local network to access the app.</li>
199
+ <li>A new IP will be provided when local sharing is on, which can be used to access from any device on the same network.</li>
200
+ <li>You can manually configure this through the Configure menu (set PINOKIO_SHARE_LOCAL to true)</li>
201
+ </ul>
187
202
  </div>
188
203
  <div class='runner'>
189
204
  <div id='save' class='btn'>