pinokiod 3.41.0 → 3.42.0

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.
Files changed (82) hide show
  1. package/kernel/api/browser/index.js +3 -1
  2. package/kernel/api/cloudflare/index.js +3 -3
  3. package/kernel/api/index.js +187 -51
  4. package/kernel/api/loading/index.js +15 -0
  5. package/kernel/api/process/index.js +7 -0
  6. package/kernel/api/shell/index.js +0 -2
  7. package/kernel/bin/browserless.js +22 -0
  8. package/kernel/bin/caddy.js +36 -4
  9. package/kernel/bin/index.js +4 -1
  10. package/kernel/bin/setup.js +38 -5
  11. package/kernel/connect/backend.js +110 -0
  12. package/kernel/connect/config.js +171 -0
  13. package/kernel/connect/index.js +18 -7
  14. package/kernel/connect/providers/huggingface/index.js +98 -0
  15. package/kernel/connect/providers/x/index.js +0 -1
  16. package/kernel/environment.js +91 -19
  17. package/kernel/git.js +46 -3
  18. package/kernel/index.js +119 -39
  19. package/kernel/peer.js +40 -5
  20. package/kernel/plugin.js +3 -2
  21. package/kernel/procs.js +27 -20
  22. package/kernel/prototype.js +30 -16
  23. package/kernel/router/common.js +1 -1
  24. package/kernel/router/connector.js +1 -3
  25. package/kernel/router/index.js +38 -4
  26. package/kernel/router/localhost_home_router.js +5 -1
  27. package/kernel/router/localhost_port_router.js +27 -1
  28. package/kernel/router/localhost_static_router.js +93 -0
  29. package/kernel/router/localhost_variable_router.js +14 -9
  30. package/kernel/router/peer_peer_router.js +3 -0
  31. package/kernel/router/peer_static_router.js +43 -0
  32. package/kernel/router/peer_variable_router.js +15 -14
  33. package/kernel/router/processor.js +26 -1
  34. package/kernel/router/rewriter.js +59 -0
  35. package/kernel/scripts/git/commit +11 -1
  36. package/kernel/shell.js +8 -3
  37. package/kernel/util.js +65 -6
  38. package/package.json +2 -1
  39. package/server/index.js +1037 -964
  40. package/server/public/common.js +382 -1
  41. package/server/public/fscreator.js +0 -1
  42. package/server/public/loading.js +17 -0
  43. package/server/public/notifyinput.js +0 -1
  44. package/server/public/opener.js +4 -2
  45. package/server/public/style.css +310 -11
  46. package/server/socket.js +7 -1
  47. package/server/views/app.ejs +1747 -351
  48. package/server/views/columns.ejs +338 -0
  49. package/server/views/connect/huggingface.ejs +353 -0
  50. package/server/views/connect/index.ejs +410 -0
  51. package/server/views/connect/x.ejs +43 -9
  52. package/server/views/connect.ejs +709 -49
  53. package/server/views/container.ejs +357 -0
  54. package/server/views/d.ejs +251 -62
  55. package/server/views/download.ejs +54 -10
  56. package/server/views/editor.ejs +11 -0
  57. package/server/views/explore.ejs +40 -15
  58. package/server/views/file_explorer.ejs +25 -246
  59. package/server/views/form.ejs +44 -1
  60. package/server/views/frame.ejs +39 -1
  61. package/server/views/github.ejs +48 -11
  62. package/server/views/help.ejs +48 -7
  63. package/server/views/index.ejs +119 -58
  64. package/server/views/index2.ejs +3 -4
  65. package/server/views/init/index.ejs +651 -197
  66. package/server/views/install.ejs +1 -1
  67. package/server/views/mini.ejs +47 -18
  68. package/server/views/net.ejs +199 -67
  69. package/server/views/network.ejs +220 -94
  70. package/server/views/network2.ejs +3 -4
  71. package/server/views/old_network.ejs +3 -3
  72. package/server/views/prototype/index.ejs +48 -11
  73. package/server/views/review.ejs +1005 -0
  74. package/server/views/rows.ejs +341 -0
  75. package/server/views/screenshots.ejs +1020 -0
  76. package/server/views/settings.ejs +160 -23
  77. package/server/views/setup.ejs +49 -7
  78. package/server/views/setup_home.ejs +43 -10
  79. package/server/views/shell.ejs +7 -1
  80. package/server/views/start.ejs +14 -9
  81. package/server/views/terminal.ejs +13 -2
  82. package/server/views/tools.ejs +1015 -0
@@ -0,0 +1,341 @@
1
+ <html>
2
+ <head>
3
+ <style>
4
+ html, body {
5
+ width: 100%;
6
+ height: 100%;
7
+ margin: 0;
8
+ }
9
+ body.single {
10
+ display: block;
11
+ }
12
+ body {
13
+ display: grid;
14
+ grid-template-rows: var(--row0, 1fr) 6px var(--row1, 1fr);
15
+ gap: 0px;
16
+ }
17
+ body iframe {
18
+ border: none;
19
+ width: 100%;
20
+ height: 100%;
21
+ }
22
+ /* Splitter (gutter) styles */
23
+ body.dark {
24
+ background: #1B1C1D;
25
+ }
26
+ body.dark .gutter {
27
+ background: #111111;
28
+ }
29
+ .gutter {
30
+ background: whitesmoke;
31
+ cursor: row-resize;
32
+ position: relative;
33
+ }
34
+ body.resizing, .gutter:hover {
35
+ cursor: row-resize;
36
+ }
37
+ body.resizing {
38
+ user-select: none;
39
+ }
40
+ /* Visible handle */
41
+ .gutter::before {
42
+ content: '';
43
+ position: absolute;
44
+ top: 50%;
45
+ left: 50%;
46
+ transform: translate(-50%, -50%);
47
+ width: 32px;
48
+ height: 4px;
49
+ border-radius: 2px;
50
+ /*
51
+ background: #bdbdbd;
52
+ */
53
+ }
54
+ .gutter:hover::before, body.resizing .gutter::before { background: #9e9e9e; }
55
+ .gutter:focus { outline: none; box-shadow: inset 0 0 0 2px #90caf9; }
56
+ </style>
57
+ </head>
58
+ <body class='<%=theme%>'>
59
+ <iframe id='row0' data-src="<%=src%>"></iframe>
60
+ <div id="gutter" class="gutter" tabindex="0" role="separator" aria-orientation="horizontal" aria-label="Resize panels" aria-valuemin="120" aria-valuemax="0" aria-valuenow="0"></div>
61
+ <iframe id='row1' data-src="<%=src%>"></iframe>
62
+
63
+ <script>
64
+ (function() {
65
+ const gutter = document.getElementById('gutter');
66
+ const topPane = document.getElementById('row0');
67
+ const bottomPane = document.getElementById('row1');
68
+ const body = document.body;
69
+ const GUTTER = gutter ? gutter.getBoundingClientRect().height || 6 : 6;
70
+ const MIN = 120; // minimum height for each pane in px
71
+
72
+ // Stable instance path for recursive panes
73
+ // Prefer parent-assigned iframe name; fallback to window.name; else 'root' for top-level
74
+ const PATH = (window.frameElement && window.frameElement.name) || window.name || 'root';
75
+ if (!window.name) { try { window.name = PATH; } catch(_) {} }
76
+ // Assign deterministic names to child panes before loading
77
+ topPane.name = `${PATH}.0`;
78
+ bottomPane.name = `${PATH}.1`;
79
+
80
+ const splitKey = `splitRatio:${PATH}`;
81
+ const KEY_STEP = 20;
82
+ const KEY_STEP_BIG = 100;
83
+ const urlKeyFor = (paneName) => `paneUrl:${paneName}`;
84
+
85
+ function setRows(topPx) {
86
+ console.log("setRows", topPx)
87
+ document.body.style.gridTemplateRows = `${topPx}px ${GUTTER}px 1fr`;
88
+ }
89
+
90
+ function computeTotal() {
91
+ const bodyRect = body.getBoundingClientRect();
92
+ return bodyRect.height - GUTTER;
93
+ }
94
+
95
+ function clamp(val, min, max) { return Math.max(min, Math.min(max, val)); }
96
+
97
+ function updateAria(topPx, total) {
98
+ if (!gutter) return;
99
+ gutter.setAttribute('aria-valuemin', String(MIN));
100
+ gutter.setAttribute('aria-valuemax', String(Math.max(MIN, total - MIN)));
101
+ gutter.setAttribute('aria-valuenow', String(Math.max(MIN, Math.min(total - MIN, Math.round(topPx)))));
102
+ }
103
+
104
+ function saveRatioFromTopPx(topPx) {
105
+ const total = computeTotal();
106
+ if (total > 0) {
107
+ const ratio = clamp(topPx / total, 0, 1);
108
+ try { sessionStorage.setItem(splitKey, String(ratio)); } catch (_) {}
109
+ }
110
+ }
111
+
112
+ function applyFromRatio(ratio) {
113
+ console.log("applyFromRatio", ratio)
114
+ const total = computeTotal();
115
+ let topPx = clamp(Math.round(total * ratio), MIN, total - MIN);
116
+ setRows(topPx);
117
+ updateAria(topPx, total);
118
+ }
119
+
120
+ // --- Per-window URL persistence with deterministic pane paths ---
121
+ function restorePaneURL(pane) {
122
+ const key = urlKeyFor(pane.name);
123
+ try {
124
+ const saved = sessionStorage.getItem(key);
125
+ const fallback = pane.getAttribute('data-src') || pane.getAttribute('src') || '';
126
+ const target = (saved && typeof saved === 'string') ? saved : fallback;
127
+ if (target && pane.src !== target) pane.src = target;
128
+ } catch (_) { /* ignore */ }
129
+ }
130
+
131
+ function attachSameOriginRouteHooks(pane) {
132
+ const key = urlKeyFor(pane.name);
133
+ try {
134
+ const cw = pane.contentWindow;
135
+ if (!cw) return;
136
+ const notify = () => {
137
+ try { sessionStorage.setItem(key, cw.location.href); } catch (_) {}
138
+ };
139
+ // Hook SPA navigations
140
+ const _ps = cw.history.pushState;
141
+ cw.history.pushState = function() { const r = _ps.apply(this, arguments); notify(); return r; };
142
+ const _rs = cw.history.replaceState;
143
+ cw.history.replaceState = function() { const r = _rs.apply(this, arguments); notify(); return r; };
144
+ cw.addEventListener('popstate', notify);
145
+ cw.addEventListener('hashchange', notify);
146
+ if (cw.document?.readyState === 'loading') cw.document.addEventListener('DOMContentLoaded', notify, { once: true });
147
+ else notify();
148
+ } catch (err) {
149
+ // Cross-origin: fall back to saving src only
150
+ try { sessionStorage.setItem(key, pane.src); } catch (_) {}
151
+ }
152
+ }
153
+
154
+ function onPaneLoadFactory(pane) {
155
+ return function onPaneLoad() {
156
+ attachSameOriginRouteHooks(pane);
157
+ };
158
+ }
159
+
160
+ // Overlay to avoid iframe stealing events in Chrome
161
+ function createOverlay() {
162
+ const el = document.createElement('div');
163
+ el.style.position = 'fixed';
164
+ el.style.inset = '0';
165
+ el.style.cursor = 'row-resize';
166
+ el.style.zIndex = '2147483647';
167
+ el.style.background = 'transparent';
168
+ return el;
169
+ }
170
+
171
+ let startY = 0;
172
+ let startTop = 0;
173
+ let total = 0;
174
+ let overlay = null;
175
+
176
+ function refreshLayout (splitKey) {
177
+ let val = sessionStorage.getItem(splitKey)
178
+ let id = splitKey.replace("splitRatio:", "")
179
+ if (val === "1" || val === "0") {
180
+ if (val === "1") {
181
+ id_to_hide = id + ".1"
182
+ } else if (val === "0") {
183
+ id_to_hide = id + ".0"
184
+ }
185
+ const el = document.querySelector(`iframe[name='${id_to_hide}']`)
186
+ el.remove()
187
+ document.body.className = "single"
188
+ document.querySelector("#gutter").remove()
189
+ }
190
+ }
191
+
192
+
193
+ function onPointerMove(e) {
194
+ const delta = e.clientY - startY;
195
+ let newTop = startTop + delta;
196
+ newTop = Math.max(MIN, Math.min(total - MIN, newTop));
197
+ setRows(newTop);
198
+ updateAria(newTop, total);
199
+ }
200
+
201
+ function endDrag(e) {
202
+ if (gutter && e && e.pointerId != null && gutter.hasPointerCapture?.(e.pointerId)) {
203
+ try { gutter.releasePointerCapture(e.pointerId); } catch (_) {}
204
+ }
205
+ window.removeEventListener('pointermove', onPointerMove, true);
206
+ window.removeEventListener('pointerup', endDrag, true);
207
+ window.removeEventListener('pointercancel', endDrag, true);
208
+ if (overlay) {
209
+ overlay.remove();
210
+ overlay = null;
211
+ }
212
+ body.classList.remove('resizing');
213
+ // Persist position as ratio
214
+ try {
215
+ const topRect = topPane.getBoundingClientRect();
216
+ saveRatioFromTopPx(topRect.height);
217
+ } catch (_) {}
218
+ }
219
+
220
+ // Restore child pane URLs before any interaction (override hardcoded src)
221
+ restorePaneURL(topPane);
222
+ restorePaneURL(bottomPane);
223
+
224
+ // Track navigations for each pane
225
+ topPane.addEventListener('load', onPaneLoadFactory(topPane));
226
+ bottomPane.addEventListener('load', onPaneLoadFactory(bottomPane));
227
+
228
+ if (gutter) {
229
+ gutter.addEventListener('pointerdown', (e) => {
230
+ e.preventDefault();
231
+ const bodyRect = body.getBoundingClientRect();
232
+ const topRect = topPane.getBoundingClientRect();
233
+ total = bodyRect.height - GUTTER; // total available for both iframes
234
+ startTop = topRect.height;
235
+ startY = e.clientY;
236
+
237
+ // Ensure we keep receiving events even over iframes
238
+ try { gutter.setPointerCapture(e.pointerId); } catch (_) {}
239
+ overlay = createOverlay();
240
+ document.body.appendChild(overlay);
241
+
242
+ window.addEventListener('pointermove', onPointerMove, true);
243
+ window.addEventListener('pointerup', endDrag, true);
244
+ window.addEventListener('pointercancel', endDrag, true);
245
+ body.classList.add('resizing');
246
+ });
247
+
248
+ // Keyboard resizing for accessibility
249
+ gutter.addEventListener('keydown', (e) => {
250
+ const { key } = e;
251
+ if (key !== 'ArrowUp' && key !== 'ArrowDown' && key !== 'Home' && key !== 'End') return;
252
+ e.preventDefault();
253
+ const totalNow = computeTotal();
254
+ const rect = topPane.getBoundingClientRect();
255
+ const step = e.shiftKey ? KEY_STEP_BIG : KEY_STEP;
256
+ let topPx = rect.height;
257
+ if (key === 'ArrowUp') topPx -= step;
258
+ else if (key === 'ArrowDown') topPx += step;
259
+ else if (key === 'Home') topPx = MIN;
260
+ else if (key === 'End') topPx = totalNow - MIN;
261
+ topPx = clamp(topPx, MIN, totalNow - MIN);
262
+ setRows(topPx);
263
+ updateAria(topPx, totalNow);
264
+ saveRatioFromTopPx(topPx);
265
+ });
266
+ }
267
+
268
+ // Initialize from saved ratio if available and set ARIA
269
+ try {
270
+ const saved = parseFloat(sessionStorage.getItem(splitKey) || '');
271
+ console.log({ saved })
272
+ if (!Number.isNaN(saved) && saved > 0 && saved < 1) {
273
+ console.log("< 1")
274
+ applyFromRatio(saved);
275
+ } else {
276
+ console.log("< 2")
277
+ updateAria(topPane.getBoundingClientRect().height, computeTotal());
278
+ refreshLayout(splitKey)
279
+ }
280
+ } catch (_) {
281
+ console.log("< 3")
282
+ updateAria(topPane.getBoundingClientRect().height, computeTotal());
283
+ }
284
+
285
+ // Re-apply on window resize to keep ratio
286
+ window.addEventListener('resize', () => {
287
+ try {
288
+ const saved = parseFloat(sessionStorage.getItem(splitKey) || '');
289
+ if (!Number.isNaN(saved) && saved > 0 && saved < 1) {
290
+ applyFromRatio(saved);
291
+ } else {
292
+ updateAria(topPane.getBoundingClientRect().height, computeTotal());
293
+ }
294
+ } catch (_) {
295
+ updateAria(topPane.getBoundingClientRect().height, computeTotal());
296
+ }
297
+ });
298
+ window.addEventListener('message', (event) => {
299
+ if (event.data && event.data.e === "close") {
300
+ // find the frame
301
+ // Find which iframe sent the message
302
+ const row0 = document.getElementById('row0');
303
+ const row1 = document.getElementById('row1');
304
+
305
+ let sourceFrameId = null;
306
+
307
+ if (event.source === row0.contentWindow) {
308
+ sourceFrameId = 'row0';
309
+ } else if (event.source === row1.contentWindow) {
310
+ sourceFrameId = 'row1';
311
+ }
312
+
313
+ console.log('Message received from iframe:', sourceFrameId);
314
+
315
+ // Or use this approach to loop through all iframes
316
+ const iframes = document.querySelectorAll('iframe');
317
+ console.log({ splitKey })
318
+ for (let iframe of iframes) {
319
+ if (event.source === iframe.contentWindow) {
320
+ // const splitKey = `splitRatio:${iframe.name}`
321
+ if (iframe.id === "row0") {
322
+ // hide row0 => ratio:; 0
323
+ // row0.src = "about:blank"
324
+ try { sessionStorage.setItem(splitKey, "0"); } catch (_) { console.log("> e", _)}
325
+ refreshLayout(splitKey)
326
+ } else if (iframe.id === "row1") {
327
+ // hide row1 => ratio:; 1
328
+ // row1.src = "about:blank"
329
+ try { sessionStorage.setItem(splitKey, "1"); } catch (_) {console.log(">>> e", _)}
330
+ refreshLayout(splitKey)
331
+ }
332
+ console.log('Message from iframe with id:', iframe.id);
333
+ break;
334
+ }
335
+ }
336
+ }
337
+ })
338
+ })();
339
+ </script>
340
+ </body>
341
+ </html>