pinokiod 3.8.152 → 3.8.1530

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/bin/git.js CHANGED
@@ -14,6 +14,7 @@ class Git {
14
14
  `conda install -y -c conda-forge ${this.cmd()}`
15
15
  ]
16
16
  }, ondata)
17
+ await fs.promises.mkdir(this.kernel.path("config/gh"), { recursive: true }).catch((e) => { })
17
18
  // if (this.kernel.platform === 'win32') {
18
19
  // let gitconfig_path = path.resolve(this.kernel.homedir, "gitconfig")
19
20
  // // check if gitconfig exists
@@ -28,18 +29,18 @@ class Git {
28
29
  // }
29
30
  }
30
31
  async installed() {
31
- return this.kernel.bin.installed.conda && this.kernel.bin.installed.conda.has("git") && this.kernel.bin.installed.conda.has("gh")
32
+ let gh_config_exists = await this.kernel.exists("config/gh")
33
+ return this.kernel.bin.installed.conda && this.kernel.bin.installed.conda.has("git") && this.kernel.bin.installed.conda.has("gh") && gh_config_exists
32
34
  }
33
35
  async uninstall(req, ondata) {
34
36
  await this.kernel.bin.exec({ message: "conda remove git gh" }, ondata)
35
37
  }
36
38
  env() {
37
- // if (this.kernel.platform === 'win32') {
38
- let gitconfig_path = path.resolve(this.kernel.homedir, "gitconfig")
39
- return {
40
- GIT_CONFIG_GLOBAL: gitconfig_path
41
- }
42
- // }
39
+ let gitconfig_path = path.resolve(this.kernel.homedir, "gitconfig")
40
+ return {
41
+ GIT_CONFIG_GLOBAL: gitconfig_path,
42
+ GH_CONFIG_DIR: this.kernel.path("config/gh")
43
+ }
43
44
  }
44
45
  async requires() {
45
46
  return ["conda"]
@@ -56,6 +56,7 @@ class Bin {
56
56
  params.cols = this.client.cols
57
57
  params.rows = this.client.rows
58
58
  }
59
+ console.log({ params })
59
60
  let response = await this.kernel.shell.run(params, null, ondata)
60
61
  return response
61
62
  }
package/kernel/loader.js CHANGED
@@ -43,14 +43,14 @@ class Loader {
43
43
  async requireJSON(filepath) {
44
44
  let config
45
45
  try { config = require(filepath) } catch (e) {
46
- console.log(e)
46
+ console.log("> load", e.message, filepath)
47
47
  }
48
48
  return config
49
49
  }
50
50
  async requireJS(filepath) {
51
51
  let config
52
52
  try { config = require(filepath) } catch (e) {
53
- console.log(e)
53
+ console.log("> load", e.message, filepath)
54
54
  }
55
55
  try {
56
56
  // if the required module is a class, return the instantiated object
package/kernel/peer.js CHANGED
@@ -132,18 +132,29 @@ class PeerDiscovery {
132
132
  // }
133
133
  }
134
134
  _isLocalLAN(ip) {
135
- return ip.startsWith('192.168.');
135
+ return ip.startsWith('192.168.') || ip.startsWith('10.') || (ip.startsWith('172.') && is172Private(ip));
136
136
  }
137
137
  _getLocalIPAddress() {
138
138
  const interfaces = os.networkInterfaces();
139
139
  for (const ifaceList of Object.values(interfaces)) {
140
140
  for (const iface of ifaceList) {
141
- if (iface.family === 'IPv4' && !iface.internal && iface.address.startsWith('192.168.')) {
142
- return iface.address;
141
+ if (iface.family === 'IPv4' && !iface.internal) {
142
+ const ip = iface.address;
143
+ if (
144
+ ip.startsWith('10.') ||
145
+ ip.startsWith('192.168.') ||
146
+ (ip.startsWith('172.') && is172Private(ip))
147
+ ) {
148
+ return ip;
149
+ }
143
150
  }
144
151
  }
145
152
  }
146
153
  return null;
154
+ function is172Private(ip) {
155
+ const secondOctet = parseInt(ip.split('.')[1], 10);
156
+ return secondOctet >= 16 && secondOctet <= 31;
157
+ }
147
158
  }
148
159
  }
149
160
 
@@ -214,7 +214,7 @@ class Router {
214
214
  let response = await axios.post('http://127.0.0.1:2019/load', this.config, {
215
215
  headers: { 'Content-Type': 'application/json' }
216
216
  })
217
- console.log("Caddy Response", { response })
217
+ // console.log("Caddy Response", { response })
218
218
  this.old_config = this.config
219
219
  } catch (e) {
220
220
  console.log("EEEEEEEEEEEEE", e)
package/kernel/shell.js CHANGED
@@ -923,6 +923,7 @@ class Shell {
923
923
  this.done = false
924
924
  this.ptyProcess = pty.spawn(this.shell, this.args, config)
925
925
  this.ptyProcess.onData((data) => {
926
+ console.log({ data, done: this.done })
926
927
  if (!this.done) {
927
928
  this.queue.push(data)
928
929
  }
@@ -985,6 +986,7 @@ class Shell {
985
986
  // automatically remove the shell from this.kernel.shells
986
987
  this.kernel.shell.rm(this.id)
987
988
  this.ondata({ raw: `\r\n\r\n██ Terminated Shell ${this.id}\r\n████\r\n` })
989
+ this.ondata({ raw: "", type: "shell.kill" })
988
990
  console.log("before cb 1")
989
991
  cb()
990
992
  } else {
@@ -994,10 +996,12 @@ class Shell {
994
996
  // automatically remove the shell from this.kernel.shells
995
997
  this.kernel.shell.rm(this.id)
996
998
  this.ondata({ raw: `\r\n\r\n██ Terminated Shell ${this.id}\r\n████\r\n` })
999
+ this.ondata({ raw: "", type: "shell.kill" })
997
1000
  }
998
1001
  } else {
999
1002
  this.kernel.shell.rm(this.id)
1000
1003
  this.ondata({ raw: `\r\n\r\n██ Terminated Shell ${this.id}\r\n████\r\n` })
1004
+ this.ondata({ raw: "", type: "shell.kill" })
1001
1005
  }
1002
1006
 
1003
1007
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "3.8.152",
3
+ "version": "3.8.1530",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/server/index.js CHANGED
@@ -1468,12 +1468,20 @@ class Server {
1468
1468
  if (rendered.venv) params.set("venv", encodeURIComponent(rendered.venv))
1469
1469
  if (rendered.input) params.set("input", true)
1470
1470
  if (rendered.callback) params.set("callback", encodeURIComponent(rendered.callback))
1471
+ if (rendered.kill) params.set("kill", encodeURIComponent(rendered.kill))
1472
+ if (rendered.done) params.set("done", encodeURIComponent(rendered.done))
1471
1473
  if (rendered.env) {
1472
1474
  for(let key in rendered.env) {
1473
1475
  let env_key = "env." + key
1474
1476
  params.set(env_key, rendered.env[key])
1475
1477
  }
1476
1478
  }
1479
+ if (rendered.conda) {
1480
+ for(let key in rendered.conda) {
1481
+ let conda_key = "conda." + key
1482
+ params.set(conda_key, rendered.conda[key])
1483
+ }
1484
+ }
1477
1485
 
1478
1486
  // deterministic shell id generation
1479
1487
  // `${api_path}_${i}_${hash}`
@@ -2464,6 +2472,43 @@ class Server {
2464
2472
  Util.openfs(req.body.path, req.body, this.kernel)
2465
2473
  res.json({ success: true })
2466
2474
  }))
2475
+ this.app.post("/keys", ex(async (req, res) => {
2476
+ let p = this.kernel.path("key.json")
2477
+ let keys = (await this.kernel.loader.load(p)).resolved
2478
+ console.log("update", req.body)
2479
+ for(let host in req.body) {
2480
+ let updated = req.body[host]
2481
+ for(let indexStr in updated) {
2482
+ let index = parseInt(indexStr)
2483
+ keys[host][index] = updated[indexStr]
2484
+ }
2485
+ }
2486
+ await fs.promises.writeFile(p, JSON.stringify(keys, null, 2))
2487
+ res.json({ success: true })
2488
+ }))
2489
+ this.app.get("/keys", ex(async (req, res) => {
2490
+ let p = this.kernel.path("key.json")
2491
+ let keys = (await this.kernel.loader.load(p)).resolved
2492
+ console.log({ keys })
2493
+ let items = []
2494
+ if (keys) {
2495
+ let sorted_keys = Object.keys(keys)
2496
+ sorted_keys.sort((a, b) => { return a > b })
2497
+ for(let key of sorted_keys) {
2498
+ console.log({ key })
2499
+ items.push({
2500
+ host: key,
2501
+ vals: keys[key]
2502
+ })
2503
+ }
2504
+ }
2505
+ res.render("keys", {
2506
+ filepath: p,
2507
+ theme: this.theme,
2508
+ agent: this.agent,
2509
+ items
2510
+ })
2511
+ }))
2467
2512
  this.app.get("/docs", ex(async (req, res) => {
2468
2513
  let url = req.query.url
2469
2514
  const possiblePaths = [
@@ -2524,6 +2569,28 @@ class Server {
2524
2569
  })
2525
2570
  }
2526
2571
  }))
2572
+ this.app.get("/github/login", ex(async (req, res) => {
2573
+ let params = new URLSearchParams()
2574
+ let delimiter
2575
+ if (this.kernel.platform === "win32") {
2576
+ delimiter = " && "; // must use &&. & doesn't necessariliy wait until the curruent command finishes
2577
+ } else {
2578
+ delimiter = " ; ";
2579
+ }
2580
+ let message = [
2581
+ "gh auth setup-git --hostname github.com --force",
2582
+ "gh auth login --web --git-protocol https"
2583
+ ].join(delimiter)
2584
+ params.set("message", encodeURIComponent(message))
2585
+ params.set("input", true)
2586
+ params.set("path", this.kernel.homedir)
2587
+ params.set("kill", "/Logged in/i")
2588
+ params.set("kill_message", "Your Github account is now connected.")
2589
+ params.set("callback", encodeURIComponent("/"))
2590
+ params.set("id", "github")
2591
+ let url = "/shell/github?" + params.toString()
2592
+ res.redirect(url)
2593
+ }))
2527
2594
  this.app.get("/shell/:id", ex(async (req, res) => {
2528
2595
  /*
2529
2596
  req.query := {
@@ -2532,6 +2599,8 @@ class Server {
2532
2599
  venv,
2533
2600
  callback,
2534
2601
  kill, // regex for killing
2602
+ on.<regex1>: <key>,
2603
+ on.<regex2>: <key>,
2535
2604
  env.<key1>,
2536
2605
  env.<key2>,
2537
2606
  ...
@@ -2543,9 +2612,15 @@ class Server {
2543
2612
  let id = decodeURIComponent(req.params.id)
2544
2613
  let cwd = this.kernel.path(this.kernel.api.filePath(decodeURIComponent(req.query.path)))
2545
2614
  let message = req.query.message ? decodeURIComponent(req.query.message) : null
2615
+ //let message = req.query.message ? req.query.message : null
2616
+ console.log({ message })
2546
2617
  let venv = req.query.venv ? decodeURIComponent(req.query.venv) : null
2547
2618
  let input = req.query.input ? true : false
2548
2619
  let callback = req.query.callback ? decodeURIComponent(req.query.callback) : null
2620
+ let kill_message = req.query.kill_message ? decodeURIComponent(req.query.kill_message) : null
2621
+ let done_message = req.query.done_message ? decodeURIComponent(req.query.done_message) : null
2622
+ let kill = req.query.kill ? decodeURIComponent(req.query.kill) : null
2623
+ let done = req.query.done ? decodeURIComponent(req.query.done) : null
2549
2624
  let env = {}
2550
2625
  for(let env_key in req.query) {
2551
2626
  if (env_key.startsWith("env.")) {
@@ -2554,6 +2629,24 @@ class Server {
2554
2629
  env[key] = req.query[env_key]
2555
2630
  }
2556
2631
  }
2632
+ let conda = {}
2633
+ let conda_exists = false
2634
+ for(let conda_key in req.query) {
2635
+ if (conda_key.startsWith("conda.")) {
2636
+ let chunks = conda_key.split(".")
2637
+ let key = chunks.slice(1).join(".")
2638
+ conda[key] = req.query[conda_key]
2639
+ conda_exists = true
2640
+ }
2641
+ }
2642
+ // let pattern = {}
2643
+ // for(let pattern_key in req.query) {
2644
+ // if (pattern_key.startsWith("pattern.")) {
2645
+ // let chunks = pattern_key.split(".")
2646
+ // let key = chunks.slice(1).join(".")
2647
+ // pattern[key] = req.query[pattern_key]
2648
+ // }
2649
+ // }
2557
2650
 
2558
2651
  let shell = this.kernel.shell.get(id)
2559
2652
  console.log({ shell })
@@ -2564,8 +2657,14 @@ class Server {
2564
2657
  cwd,
2565
2658
  message,
2566
2659
  venv,
2660
+ conda: (conda_exists ? conda: null),
2567
2661
  env,
2662
+ // pattern,
2568
2663
  input,
2664
+ kill,
2665
+ kill_message,
2666
+ done,
2667
+ done_message,
2569
2668
  callback,
2570
2669
  running: (shell ? true : false)
2571
2670
  })
@@ -2640,6 +2739,11 @@ class Server {
2640
2739
  agent: this.agent,
2641
2740
  })
2642
2741
  }))
2742
+ this.app.post("/network/reset", ex(async (req, res) => {
2743
+ let caddy_path = this.kernel.path("cache/XDG_DATA_HOME/caddy")
2744
+ await rimraf(caddy_path)
2745
+ res.json({ success: true })
2746
+ }))
2643
2747
  this.app.get("/network", ex(async (req, res) => {
2644
2748
  let { requirements, install_required, requirements_pending, error } = await this.kernel.bin.check({
2645
2749
  bin: this.kernel.bin.preset("network"),
@@ -0,0 +1,276 @@
1
+ <html class='columns'>
2
+ <head>
3
+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
4
+ <script src="/hotkeys.min.js"></script>
5
+ <script src="/ace/ace.js"></script>
6
+ <script src="/noty.js"></script>
7
+ <script src="/notyq.js"></script>
8
+ <script src="/xterm.js"></script>
9
+ <script src="/xterm-addon-fit.js"></script>
10
+ <script src="/xterm-addon-web-links.js"></script>
11
+ <script src="/xterm-theme.js"></script>
12
+ <script src="/xterm-addon-search.js"></script>
13
+ <script src="/xterm-addon-search-bar.js"></script>
14
+ <script src="/sweetalert2.js"></script>
15
+ <script src="/Socket.js"></script>
16
+ <script src="/common.js"></script>
17
+ <script src="/he.js"></script>
18
+ <script src="/opener.js"></script>
19
+ <script src="/nav.js"></script>
20
+ <script src="/autoexpand.js"></script>
21
+ <script src="/modalinput.js"></script>
22
+ <script src="/simplemodal.js"></script>
23
+ <script src="/waitmodal.js"></script>
24
+ <script src="/notifyinput.js"></script>
25
+ <script src="/report.js"></script>
26
+ <link href="/xterm.min.css" rel="stylesheet" />
27
+ <link href="/css/fontawesome.min.css" rel="stylesheet">
28
+ <link href="/css/solid.min.css" rel="stylesheet">
29
+ <link href="/css/regular.min.css" rel="stylesheet">
30
+ <link href="/css/brands.min.css" rel="stylesheet">
31
+ <link href="/style.css" rel="stylesheet"/>
32
+ <link href="/noty.css" rel="stylesheet"/>
33
+ <% if (agent === "electron") { %>
34
+ <link href="/electron.css" rel="stylesheet"/>
35
+ <% } %>
36
+ <style>
37
+ body.frozen {
38
+ display: flex;
39
+ flex-direction: column;
40
+ height: 100%;
41
+ }
42
+ #table > table {
43
+ border-left: 2px solid black;
44
+ padding-left: 5px;
45
+ margin: 10px 0;
46
+ }
47
+ .highlight {
48
+ background: yellow;
49
+ width: 100px;
50
+ }
51
+ th {
52
+ background: rgba(0,0,0,0.1);
53
+ padding: 10px;
54
+ font-size: 12px;
55
+ }
56
+ td {
57
+ font-size: 12px;
58
+ padding: 10px;
59
+ }
60
+ td.val {
61
+ background: rgba(0,0,0,0.06);
62
+ }
63
+ td.key {
64
+ background: rgba(0,0,0,0.1);
65
+ }
66
+ .button {
67
+ cursor: pointer;
68
+ background: rgba(0,0,0,0.8);
69
+ color: white;
70
+ padding: 5px 10px;
71
+ border-radius: 4px;
72
+ }
73
+ .button:hover {
74
+
75
+ }
76
+ #editor {
77
+ width: 100%;
78
+ box-sizing: border-box;
79
+ max-width: 600px;
80
+ padding: 20px;
81
+ margin: 0 auto;
82
+ }
83
+
84
+ header .btn {
85
+ font-family: Sans-serif;
86
+ display: block;
87
+ margin-left: 10px;
88
+ font-style: normal;
89
+ font-size: 12px;
90
+ font-weight: normal;
91
+ padding: 5px 10px;
92
+ }
93
+ .disabled {
94
+ opacity: 0.7;
95
+ }
96
+ body.dark .env-item input[type=text] {
97
+ background: white;
98
+ }
99
+ .env-item input[type=text] {
100
+ width: 100%;
101
+ padding: 10px;
102
+ box-sizing: border-box;
103
+ border: none;
104
+ background: rgba(0,0,100, 0.1);
105
+ }
106
+ body.dark .env-item label {
107
+ color: cornflowerblue;
108
+ }
109
+ .env-item label {
110
+ color: royalblue;
111
+ display: block;
112
+ margin-bottom: 5px;
113
+ font-weight: bold;
114
+ font-size: 18px;
115
+ }
116
+ .env-item.highlighted {
117
+ border: 5px solid red;
118
+ }
119
+ .env-item {
120
+ /*
121
+ padding-top: 10px;
122
+ padding-bottom: 30px;
123
+ */
124
+ padding: 10px;
125
+ margin-bottom: 20px;
126
+ }
127
+ body.dark .comment {
128
+ border-left: 2px solid white;
129
+ }
130
+ .comment {
131
+ opacity: 0.8;
132
+ border-left: 2px solid black;
133
+ padding-left: 10px;
134
+ }
135
+ #save {
136
+ background: royalblue;
137
+ }
138
+ a#customize {
139
+ text-decoration: underline;
140
+ cursor: pointer;
141
+ }
142
+ .e {
143
+ padding: 10px 0;
144
+ }
145
+ #editor {
146
+ padding: 20px 0;
147
+ }
148
+ .center {
149
+ display: flex;
150
+ align-items: center;
151
+ justify-content: center;
152
+ }
153
+ body {
154
+ display: block;
155
+ }
156
+ .card {
157
+ display: flex;
158
+ padding: 10px 0;
159
+ box-sizing: border-box;
160
+ }
161
+ .card img {
162
+ width: 100px;
163
+ border-radius: 10px;
164
+ }
165
+ .card .description {
166
+ opacity: 0.8;
167
+ }
168
+ .card .title {
169
+ font-weight: bold;
170
+ font-size: 30px;
171
+ letter-spacing: -1px;
172
+ }
173
+ .card .col {
174
+ padding-left: 10px;
175
+ }
176
+ h1 {
177
+ font-size: 50px;
178
+ padding-bottom: 20px;
179
+ }
180
+ footer {
181
+ background: none;
182
+ padding: 0;
183
+ text-align: right;
184
+ display: flex;
185
+ margin: 10px 0 20px 0;
186
+ }
187
+ footer .btn {
188
+ margin-left: 10px;
189
+ display: inline-block;
190
+ -webkit-appearance: button;
191
+ -moz-appearance: button;
192
+ appearance: button;
193
+
194
+ }
195
+ footer .btn.go-home {
196
+ margin-left: 0px;
197
+ }
198
+ .btn.home-button {
199
+ background: none !important;
200
+ margin: 0 !important;
201
+ font-size: 16px !important;
202
+ }
203
+ #editor {
204
+ height: auto;
205
+ }
206
+ .env-title {
207
+ font-weight: bold;
208
+ }
209
+ .env-description {
210
+ margin-bottom: 10px;
211
+ }
212
+ input[type=text] {
213
+ margin-bottom: 5px;
214
+ }
215
+ </style>
216
+ <script>
217
+ document.addEventListener("DOMContentLoaded", async () => {
218
+ const n = new N()
219
+ let updated = {}
220
+ document.addEventListener("input", (e) => {
221
+ let host = e.target.getAttribute("data-host")
222
+ let index = e.target.getAttribute("data-index")
223
+ if (!updated[host]) {
224
+ updated[host] = {}
225
+ }
226
+ updated[host][index] = e.target.value
227
+ })
228
+ document.querySelector("#save").addEventListener("click", async (e) => {
229
+ console.log({ updated })
230
+ let res = await fetch("/keys", {
231
+ method: "POST",
232
+ headers: {
233
+ "Content-Type": "application/json"
234
+ },
235
+ body: JSON.stringify(updated)
236
+ }).then((res) => {
237
+ return res.json()
238
+ })
239
+ console.log("res" ,res)
240
+ n.Noty({
241
+ text: `Updated!`
242
+ })
243
+ setTimeout(() => {
244
+ location.href = location.href
245
+ }, 1000)
246
+ })
247
+ })
248
+ </script>
249
+ </head>
250
+ <body class='<%=theme%>'>
251
+ <main>
252
+ <header class='navheader grabbable'>
253
+ <h1>
254
+ <a class='home-button home' href="/"><i class='fa-solid fa-home'></i></a>
255
+ <div class='flexible'></div>
256
+ <div class='nav-btns'>
257
+ <button class='btn' id='open-fs' data-filepath="<%=filepath%>"><i class="fa-solid fa-eye"></i> Open in File Explorer</button>
258
+ <div id='save' class='btn'>
259
+ <span class='save'><i class="fa-solid fa-check"></i> Save</span>
260
+ </div>
261
+ </div>
262
+ </h1>
263
+ </header>
264
+ <div id='editor'>
265
+ <% items.forEach((item) => { %>
266
+ <div class='env-item'>
267
+ <label for="<%=item.host%>"><%=item.host%></label>
268
+ <% item.vals.forEach((val, index) => { %>
269
+ <input data-host="<%=item.host%>" data-index="<%=index%>" type="text" value="<%=val%>">
270
+ <% }) %>
271
+ </div>
272
+ <% }) %>
273
+ </div>
274
+ </main>
275
+ </body>
276
+ </html>
@@ -214,13 +214,18 @@ a.ln:hover {
214
214
  */
215
215
  padding: 10px 0;
216
216
  }
217
- #advanced-label {
217
+ #reset-label {
218
+ color: firebrick;
219
+ }
220
+ .link-label {
221
+ margin-right: 10px;
218
222
  text-decoration: underline;
219
223
  color: royalblue;
220
224
  cursor: pointer;
221
225
  }
222
226
  .container-row table {
223
227
  width: 100%;
228
+ table-layout: fixed;
224
229
  }
225
230
  table a {
226
231
  text-decoration: none;
@@ -235,6 +240,7 @@ td:first-child, th:first-child {
235
240
  text-transform: uppercase;
236
241
  }
237
242
  .container-row th {
243
+ vertical-align: top;
238
244
  border-bottom: 1px solid rgba(0,0,0,0.05);
239
245
  text-align: left;
240
246
  padding: 20px 0;
@@ -249,6 +255,7 @@ td:first-child, th:first-child {
249
255
  vertical-align: top;
250
256
  font-size: 14px;
251
257
  padding: 5px 2px;
258
+ word-wrap: break-word;
252
259
  }
253
260
 
254
261
  .config {
@@ -440,7 +447,8 @@ input:checked + .slider:before {
440
447
  </div>
441
448
  <div class='advanced'>
442
449
  <div class='row'>
443
- <div id='advanced-label' class='label'>Advanced</div>
450
+ <div id='advanced-label' class='link-label label'>Advanced</div>
451
+ <div id='reset-label' class='link-label label'>Reset HTTPS Certificates</div>
444
452
  </div>
445
453
  <!--
446
454
  <div id='advanced-input' class='row hidden'>
@@ -595,7 +603,50 @@ input:checked + .slider:before {
595
603
  </div>
596
604
  </main>
597
605
  <script>
606
+ document.querySelector("#reset-label").addEventListener("click", async (e) => {
607
+ e.preventDefault()
608
+ e.stopPropagation()
609
+ let ok = confirm("are you sure you want to re-generate http certificates?")
610
+ if (ok) {
611
+ let r = await fetch("/network/reset", {
612
+ method: "post",
613
+ headers: {
614
+ "Content-Type": "application/json"
615
+ }
616
+ }).then((res) => {
617
+ return res.json()
618
+ })
619
+ if (r.success) {
620
+ //alert("Successfully updated the pinokio home to " + val)
621
+ document.querySelector(".loading").classList.remove("hidden")
622
+ document.querySelector(".save").classList.add("hidden")
623
+ fetch("/restart", {
624
+ method: "post"
625
+ }, () => {
626
+ })
627
+ setInterval(async () => {
628
+ try {
629
+ let res = await fetch("/check_peer").then((res) => {
630
+ return res.json()
631
+ })
632
+ if (res.success) {
633
+ document.querySelector(".loading").classList.add("hidden")
634
+ location.href = location.href
635
+ }
636
+ } catch (e) {
637
+ console.log(e)
638
+ }
639
+ }, 1000)
640
+ } else if (r.error) {
641
+ alert(r.error)
642
+ location.href = location.href
643
+ }
644
+ }
645
+
646
+ })
598
647
  document.querySelector("#advanced-label").addEventListener("click", (e) => {
648
+ e.preventDefault()
649
+ e.stopPropagation()
599
650
  //document.querySelector("#advanced-input").classList.toggle("hidden")
600
651
  Commander({
601
652
  callback: "/network",
@@ -137,9 +137,10 @@ body.dark .badge {
137
137
  font-weight: bold;
138
138
  }
139
139
  .folder-templates .folder img {
140
- width: 20px;
141
- height: 20px;
140
+ width: 30px;
141
+ height: 30px;
142
142
  margin-right: 10px;
143
+ border-radius: 10px;
143
144
  }
144
145
  .prototype-header {
145
146
  padding: 10px;
@@ -200,6 +200,11 @@ hr {
200
200
  display: inline-block;
201
201
  cursor: pointer;
202
202
  }
203
+ .keys pre {
204
+ padding: 20px;
205
+ margin-top: 20px;
206
+ background: rgba(0,0,200,0.1) !important;
207
+ }
203
208
  </style>
204
209
  <script src="/hotkeys.min.js"></script>
205
210
  <script src="/sweetalert2.js"></script>
@@ -371,6 +376,24 @@ hr {
371
376
  </div>
372
377
  </div>
373
378
  <hr/>
379
+ <div class='keys'>
380
+ <h1>Keys</h1>
381
+ <br>
382
+ <br>
383
+ <div>Keys are array values stored for unique host names, stored at <code>~/pinokio/key.json</code>, and can be set through <code>pre</code> attributes in pinokio scripts. Here's an example:</div>
384
+ <pre>{
385
+ "openai.com": [
386
+ "sk-proj-2najBvCGFx18belpjf13T3BlbkFJIAR5KXK031n41WzAsPEn"
387
+ ],
388
+ "x.com": [
389
+ "12345678-FAKEaccesstoken1234567890abcdef",
390
+ "FAKEaccesstokensecret0987654321abcdef"
391
+ ]
392
+ }</pre>
393
+ <br>
394
+ <a class='btn' href="/keys"><i class="fa-solid fa-key"></i> Edit Keys</a>
395
+ </div>
396
+ <hr/>
374
397
  <div class='advanced'>
375
398
  <h1>Advanced Settings</h1>
376
399
  <br>
@@ -205,17 +205,32 @@ document.addEventListener("DOMContentLoaded", async () => {
205
205
  //method: "kernel.bin.shell_start",
206
206
  method: "kernel.bin.exec",
207
207
  <% if (message) { %>
208
- message: "<%=message%>",
208
+ message: "<%-message%>",
209
209
  <% } %>
210
210
  <% if (venv) { %>
211
211
  venv: "<%=venv%>",
212
212
  <% } %>
213
+ <% if (kill) { %>
214
+ on: [{
215
+ event: "<%=kill%>",
216
+ kill: true
217
+ }],
218
+ <% } %>
219
+ <% if (done) { %>
220
+ on: [{
221
+ event: "<%=done%>",
222
+ done: true
223
+ }],
224
+ <% } %>
213
225
  <% if (input) { %>
214
226
  input: true,
215
227
  <% } %>
216
228
  <% if (env) { %>
217
229
  env: <%-JSON.stringify(env)%>,
218
230
  <% } %>
231
+ <% if (conda) { %>
232
+ conda: <%-JSON.stringify(conda)%>,
233
+ <% } %>
219
234
  id: "<%=id%>",
220
235
  path: "<%=cwd%>",
221
236
  client: {
@@ -279,6 +294,9 @@ document.addEventListener("DOMContentLoaded", async () => {
279
294
  this.write(JSON.stringify(packet.data.json2, null, 2).replace(/\n/g, "\r\n"))
280
295
  this.write("\r\n")
281
296
  }
297
+ if (packet.data.type === "shell.kill") {
298
+ this.socket.close()
299
+ }
282
300
  document.querySelector(".play-btn").classList.add("hidden")
283
301
  document.querySelector(".starting-btn").classList.add("hidden")
284
302
  document.querySelector(".stop-btn").classList.remove("hidden")
@@ -437,7 +455,7 @@ document.addEventListener("DOMContentLoaded", async () => {
437
455
  n.Noty(payload)
438
456
  }
439
457
  } else if (packet.type === "result") {
440
- this.socket.close()
458
+ // this.socket.close()
441
459
  } else if (packet.type === "info") {
442
460
  n.Noty({
443
461
  text: `${packet.data}`,
@@ -551,8 +569,22 @@ document.addEventListener("DOMContentLoaded", async () => {
551
569
  })
552
570
  document.querySelector(".stop-btn").classList.add("hidden")
553
571
  document.querySelector(".stopped-btn").classList.remove("hidden")
554
- <% if (callback) { %>
555
- location.href = "<%=callback%>"
572
+ <% if (kill_message) { %>
573
+ n.Noty({
574
+ text: "<%-kill_message%>",
575
+ // timeout: 3000,
576
+ <% if (callback) { %>
577
+ callbacks: {
578
+ onClose: () => {
579
+ window.open("<%=callback%>", "_blank")
580
+ }
581
+ }
582
+ <% } %>
583
+ })
584
+ <% } else { %>
585
+ <% if (callback) { %>
586
+ location.href = "<%=callback%>"
587
+ <% } %>
556
588
  <% } %>
557
589
  })
558
590
  })