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.
- package/kernel/api/cloudflare/index.js +2 -0
- package/kernel/environment.js +14 -0
- package/kernel/index.js +18 -0
- package/kernel/shell.js +2 -0
- package/package.json +1 -1
- package/server/index.js +8 -0
- package/server/socket.js +24 -6
- package/server/views/browser-experimental.ejs +14 -2
- package/server/views/env_editor.ejs +1 -0
- package/server/views/fullscreen_editor.ejs +53 -8
- package/server/views/index.ejs +0 -8
- package/server/views/settings.ejs +1 -1
- package/server/views/share_editor.ejs +19 -4
|
@@ -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)
|
package/kernel/environment.js
CHANGED
|
@@ -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
package/package.json
CHANGED
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
|
-
|
|
110
|
-
delete
|
|
111
|
-
|
|
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
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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>
|
|
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
|
-
|
|
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.
|
|
246
|
+
this.write(packet.data.raw)
|
|
238
247
|
} else if (packet.data.json) {
|
|
239
|
-
this.
|
|
240
|
-
this.
|
|
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.
|
|
243
|
-
this.
|
|
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.
|
|
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) => {
|
package/server/views/index.ejs
CHANGED
|
@@ -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">
|
|
177
|
-
<
|
|
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
|
|
186
|
-
<
|
|
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'>
|