pinokiod 3.181.0 → 3.183.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 (58) hide show
  1. package/kernel/util.js +15 -2
  2. package/package.json +1 -1
  3. package/server/index.js +111 -12
  4. package/server/public/common.js +433 -240
  5. package/server/public/files-app/app.css +64 -0
  6. package/server/public/files-app/app.js +87 -0
  7. package/server/public/install.js +8 -1
  8. package/server/public/layout.js +11 -1
  9. package/server/public/sound/beep.mp3 +0 -0
  10. package/server/public/sound/bell.mp3 +0 -0
  11. package/server/public/sound/bright-ring.mp3 +0 -0
  12. package/server/public/sound/clap.mp3 +0 -0
  13. package/server/public/sound/deep-ring.mp3 +0 -0
  14. package/server/public/sound/gasp.mp3 +0 -0
  15. package/server/public/sound/hehe.mp3 +0 -0
  16. package/server/public/sound/levelup.mp3 +0 -0
  17. package/server/public/sound/light-pop.mp3 +0 -0
  18. package/server/public/sound/light-ring.mp3 +0 -0
  19. package/server/public/sound/meow.mp3 +0 -0
  20. package/server/public/sound/piano.mp3 +0 -0
  21. package/server/public/sound/pop.mp3 +0 -0
  22. package/server/public/sound/uhoh.mp3 +0 -0
  23. package/server/public/sound/whistle.mp3 +0 -0
  24. package/server/public/style.css +173 -2
  25. package/server/public/tab-idle-notifier.js +697 -4
  26. package/server/public/terminal-settings.js +1131 -0
  27. package/server/public/urldropdown.css +28 -1
  28. package/server/views/{terminals.ejs → agents.ejs} +98 -30
  29. package/server/views/app.ejs +1 -0
  30. package/server/views/bootstrap.ejs +8 -0
  31. package/server/views/connect/x.ejs +1 -0
  32. package/server/views/connect.ejs +2 -1
  33. package/server/views/container.ejs +1 -0
  34. package/server/views/d.ejs +172 -18
  35. package/server/views/download.ejs +1 -0
  36. package/server/views/editor.ejs +8 -0
  37. package/server/views/explore.ejs +1 -0
  38. package/server/views/file_browser.ejs +4 -0
  39. package/server/views/form.ejs +1 -0
  40. package/server/views/frame.ejs +1 -0
  41. package/server/views/github.ejs +1 -0
  42. package/server/views/help.ejs +1 -0
  43. package/server/views/index.ejs +2 -1
  44. package/server/views/init/index.ejs +10 -1
  45. package/server/views/install.ejs +8 -0
  46. package/server/views/mini.ejs +1 -0
  47. package/server/views/net.ejs +2 -1
  48. package/server/views/network.ejs +2 -1
  49. package/server/views/pro.ejs +8 -0
  50. package/server/views/prototype/index.ejs +9 -0
  51. package/server/views/review.ejs +1 -0
  52. package/server/views/screenshots.ejs +2 -2
  53. package/server/views/settings.ejs +2 -2
  54. package/server/views/setup.ejs +1 -0
  55. package/server/views/setup_home.ejs +1 -0
  56. package/server/views/shell.ejs +8 -0
  57. package/server/views/terminal.ejs +8 -0
  58. package/server/views/tools.ejs +2 -2
@@ -167,6 +167,70 @@
167
167
  display: flex;
168
168
  flex-direction: column;
169
169
  background: var(--surface-color);
170
+ position: relative;
171
+ overflow: visible;
172
+ }
173
+
174
+ .files-app__sidebar-toggle {
175
+ position: absolute;
176
+ top: 20px;
177
+ left: 0;
178
+ transform: translateX(-50%);
179
+ display: inline-flex;
180
+ align-items: center;
181
+ justify-content: center;
182
+ width: 32px;
183
+ height: 36px;
184
+ border: 1px solid var(--border-color);
185
+ border-left: none;
186
+ border-radius: 0 8px 8px 0;
187
+ background: var(--surface-color);
188
+ color: var(--muted-color);
189
+ cursor: pointer;
190
+ transition: transform 0.2s ease, color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
191
+ box-shadow: 0 2px 6px rgba(15, 23, 42, 0.08);
192
+ z-index: 10;
193
+ }
194
+
195
+ .files-app__sidebar-toggle:hover,
196
+ .files-app__sidebar-toggle:focus-visible {
197
+ background: rgba(127, 91, 243, 0.14);
198
+ color: var(--accent-color);
199
+ }
200
+
201
+ .files-app__sidebar-toggle--collapsed {
202
+ top: 36px;
203
+ left: 8px;
204
+ transform: translateX(0);
205
+ border-left: 1px solid var(--border-color);
206
+ border-radius: 8px;
207
+ background: rgba(127, 91, 243, 0.12);
208
+ color: var(--accent-color);
209
+ box-shadow: 0 4px 12px rgba(15, 23, 42, 0.18);
210
+ }
211
+
212
+ .files-app__sidebar-toggle--collapsed:hover,
213
+ .files-app__sidebar-toggle--collapsed:focus-visible {
214
+ background: rgba(127, 91, 243, 0.18);
215
+ }
216
+
217
+ .files-app__sidebar-toggle:focus-visible {
218
+ outline: 2px solid var(--accent-color);
219
+ outline-offset: 2px;
220
+ }
221
+
222
+ .files-app--sidebar-collapsed .files-app__sidebar {
223
+ flex: 0 0 0;
224
+ width: 0;
225
+ min-width: 0;
226
+ max-width: 0;
227
+ opacity: 0;
228
+ pointer-events: none;
229
+ border-right: none;
230
+ }
231
+
232
+ .files-app--sidebar-collapsed .files-app__sidebar-scroll {
233
+ padding: 0;
170
234
  }
171
235
 
172
236
  .files-app__tabs:empty {
@@ -28,6 +28,8 @@
28
28
  }
29
29
  };
30
30
 
31
+ const SIDEBAR_STORAGE_PREFIX = 'files-app.sidebar-collapsed.';
32
+
31
33
  const FilesApp = {
32
34
  init(config) {
33
35
  if (this._initialized) {
@@ -48,14 +50,19 @@
48
50
  activePath: null,
49
51
  selectedTreePath: null,
50
52
  statusTimer: null,
53
+ sidebarCollapsed: false,
51
54
  };
52
55
 
53
56
  this.dom = {
57
+ root: document.querySelector('.files-app'),
54
58
  treeRoot: document.getElementById('files-app-tree'),
55
59
  tabs: document.getElementById('files-app-tabs'),
56
60
  editorContainer: document.getElementById('files-app-editor'),
57
61
  status: document.getElementById('files-app-status'),
58
62
  saveBtn: document.getElementById('files-app-save'),
63
+ sidebar: document.querySelector('.files-app__sidebar'),
64
+ main: document.querySelector('.files-app__main'),
65
+ sidebarToggle: document.getElementById('files-app-toggle-sidebar'),
59
66
  };
60
67
 
61
68
  this.api = createApi(config.workspace, this.state.workspaceRoot);
@@ -63,6 +70,8 @@
63
70
  this.modelist = ace.require('ace/ext/modelist');
64
71
  this.undoManagerCtor = ace.require('ace/undomanager').UndoManager;
65
72
 
73
+ setupSidebarToggle.call(this);
74
+
66
75
  this.dom.saveBtn.addEventListener('click', (event) => {
67
76
  event.preventDefault();
68
77
  this.saveActiveFile();
@@ -227,6 +236,84 @@
227
236
  },
228
237
  };
229
238
 
239
+ function setupSidebarToggle() {
240
+ if (!this.dom.sidebarToggle || !this.dom.root) {
241
+ return;
242
+ }
243
+
244
+ const storageKey = getSidebarStorageKey(this.state.workspace);
245
+ const initialCollapsed = readSidebarPreference(storageKey);
246
+ applySidebarCollapsed.call(this, initialCollapsed);
247
+
248
+ this.dom.sidebarToggle.addEventListener('click', () => {
249
+ const nextState = !this.state.sidebarCollapsed;
250
+ applySidebarCollapsed.call(this, nextState);
251
+ persistSidebarPreference(storageKey, nextState);
252
+ });
253
+
254
+ window.addEventListener('storage', (event) => {
255
+ if (event.key === storageKey) {
256
+ const newValue = event.newValue === '1';
257
+ if (newValue !== this.state.sidebarCollapsed) {
258
+ applySidebarCollapsed.call(this, newValue);
259
+ }
260
+ }
261
+ });
262
+ }
263
+
264
+ function readSidebarPreference(storageKey) {
265
+ try {
266
+ const storedValue = window.localStorage.getItem(storageKey);
267
+ return storedValue === '1';
268
+ } catch (error) {
269
+ return false;
270
+ }
271
+ }
272
+
273
+ function persistSidebarPreference(storageKey, collapsed) {
274
+ try {
275
+ window.localStorage.setItem(storageKey, collapsed ? '1' : '0');
276
+ } catch (error) {
277
+ /* ignore */
278
+ }
279
+ }
280
+
281
+ function applySidebarCollapsed(collapsed) {
282
+ this.state.sidebarCollapsed = collapsed;
283
+ if (this.dom.root) {
284
+ this.dom.root.classList.toggle('files-app--sidebar-collapsed', collapsed);
285
+ }
286
+ if (this.dom.sidebar) {
287
+ if (collapsed) {
288
+ this.dom.sidebar.setAttribute('aria-hidden', 'true');
289
+ } else {
290
+ this.dom.sidebar.removeAttribute('aria-hidden');
291
+ }
292
+ }
293
+ if (!this.dom.sidebarToggle) {
294
+ return;
295
+ }
296
+ this.dom.sidebarToggle.setAttribute('aria-expanded', String(!collapsed));
297
+ const label = collapsed ? 'Show files' : 'Hide files';
298
+ this.dom.sidebarToggle.setAttribute('aria-label', label);
299
+ this.dom.sidebarToggle.title = label;
300
+ const srText = this.dom.sidebarToggle.querySelector('.sr-only');
301
+ if (srText) {
302
+ srText.textContent = label;
303
+ }
304
+ this.dom.sidebarToggle.classList.toggle('files-app__sidebar-toggle--collapsed', collapsed);
305
+ const icon = this.dom.sidebarToggle.querySelector('i');
306
+ if (icon) {
307
+ icon.classList.toggle('fa-chevron-left', !collapsed);
308
+ icon.classList.toggle('fa-chevron-right', collapsed);
309
+ }
310
+ }
311
+
312
+ function getSidebarStorageKey(workspace) {
313
+ const scope = workspace ? String(workspace) : 'default';
314
+ return `${SIDEBAR_STORAGE_PREFIX}${scope}`;
315
+ }
316
+
230
317
  function createApi(workspace, workspaceRoot) {
231
318
  const list = async (pathPosix) => {
232
319
  const params = new URLSearchParams({ workspace });
@@ -146,7 +146,7 @@ const install = async (name, url, term, socket, options) => {
146
146
  text: `Downloaded to ~/${normalizedPath}/${name}`,
147
147
  timeout: 4000
148
148
  })
149
- location.href = "/terminals"
149
+ location.href = "/agents"
150
150
  }
151
151
  }
152
152
  }
@@ -166,7 +166,14 @@ const createTerm = async (_theme) => {
166
166
  if (res && res.config) {
167
167
  config = res.config
168
168
  }
169
+ const baseConfig = Object.assign({}, config)
170
+ if (window.PinokioTerminalSettings && typeof window.PinokioTerminalSettings.applyToConfig === 'function') {
171
+ config = window.PinokioTerminalSettings.applyToConfig(config)
172
+ }
169
173
  const term = new Terminal(config)
174
+ if (window.PinokioTerminalSettings && typeof window.PinokioTerminalSettings.register === 'function') {
175
+ window.PinokioTerminalSettings.register(term, { baseConfig })
176
+ }
170
177
  const fitAddon = new FitAddon.FitAddon();
171
178
  term.loadAddon(fitAddon);
172
179
  term.loadAddon(new WebLinksAddon.WebLinksAddon());
@@ -847,9 +847,19 @@
847
847
  setTimeout(() => node.classList.remove('show'), 2400);
848
848
  };
849
849
 
850
+ const isFalseyString = (value) => {
851
+ return typeof value === 'string' && ['false', '0', 'no', 'off'].includes(value.trim().toLowerCase());
852
+ };
853
+
850
854
  const tryPlay = (url) => {
855
+ if (!url || url === false || isFalseyString(url)) {
856
+ return;
857
+ }
851
858
  try {
852
- const src = (typeof url === 'string' && url) ? url : '/chime.mp3';
859
+ const isString = typeof url === 'string';
860
+ const trimmed = isString ? url.trim() : '';
861
+ const hasCustom = isString && trimmed.length > 0 && trimmed.toLowerCase() !== 'true';
862
+ const src = hasCustom ? url : '/chime.mp3';
853
863
  let a = window.__pinokioChimeAudio;
854
864
  if (!a) {
855
865
  a = new Audio(src);
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -161,7 +161,7 @@ body.dark .dynamic.selected {
161
161
  */
162
162
  }
163
163
  aside .tab.submenu {
164
- padding-left: 25px;
164
+ padding-left: 25px !important;
165
165
  box-sizing: border-box;
166
166
  }
167
167
  #genlog, #downloadlogs {
@@ -1132,18 +1132,189 @@ header a.path {
1132
1132
  max-width: 100%;
1133
1133
  box-sizing: border-box;
1134
1134
  }
1135
+ header,
1136
+ header h1,
1137
+ header .runner {
1138
+ overflow: visible;
1139
+ }
1135
1140
  header .runner {
1136
1141
  padding: 0 10px;
1137
1142
  box-sizing: border-box;
1138
1143
  display: flex;
1139
1144
  align-items: center;
1145
+ gap: 10px;
1146
+ width: 100%;
1147
+ flex-wrap: wrap;
1140
1148
  }
1141
1149
  header .runner .btn {
1142
1150
  padding: 5px 10px;
1143
1151
  font-size: 12px;
1144
- margin-right: 10px;
1152
+ margin-right: 0;
1145
1153
  flex-shrink: 0;
1146
1154
  }
1155
+ .terminal-config {
1156
+ position: relative;
1157
+ display: flex;
1158
+ align-items: center;
1159
+ margin-left: auto;
1160
+ margin-right: 0;
1161
+ }
1162
+ .terminal-config .terminal-config-button,
1163
+ .terminal-config .btn {
1164
+ margin-right: 0;
1165
+ }
1166
+ .terminal-config-menu {
1167
+ position: absolute;
1168
+ top: calc(100% + 8px);
1169
+ right: 0;
1170
+ min-width: 220px;
1171
+ padding: 12px;
1172
+ border-radius: 10px;
1173
+ border: 1px solid rgba(0, 0, 0, 0.12);
1174
+ background: #ffffff;
1175
+ box-shadow: 0 12px 24px rgba(0, 0, 0, 0.18);
1176
+ z-index: 1500;
1177
+ max-height: min(80vh, 560px);
1178
+ overflow-y: auto;
1179
+ }
1180
+ .terminal-config-menu .terminal-config-title {
1181
+ font-size: 11px;
1182
+ font-weight: 600;
1183
+ letter-spacing: 0.06em;
1184
+ text-transform: uppercase;
1185
+ margin-bottom: 8px;
1186
+ opacity: 0.65;
1187
+ }
1188
+ .terminal-config-menu .terminal-config-note {
1189
+ font-size: 11px;
1190
+ margin-bottom: 10px;
1191
+ opacity: 0.7;
1192
+ }
1193
+ .terminal-config-menu .terminal-config-section {
1194
+ border-top: 1px solid rgba(0, 0, 0, 0.08);
1195
+ padding-top: 12px;
1196
+ margin-top: 12px;
1197
+ display: flex;
1198
+ flex-direction: column;
1199
+ gap: 10px;
1200
+ }
1201
+ .terminal-config-menu .terminal-config-section:first-of-type {
1202
+ border-top: none;
1203
+ padding-top: 0;
1204
+ margin-top: 0;
1205
+ }
1206
+ .terminal-config-menu .terminal-config-subtitle {
1207
+ font-size: 11px;
1208
+ font-weight: 600;
1209
+ letter-spacing: 0.04em;
1210
+ text-transform: uppercase;
1211
+ opacity: 0.65;
1212
+ }
1213
+ .terminal-config-menu .terminal-config-help {
1214
+ font-size: 11px;
1215
+ opacity: 0.65;
1216
+ line-height: 1.4;
1217
+ }
1218
+ .terminal-config-menu .terminal-config-group {
1219
+ display: flex;
1220
+ flex-direction: column;
1221
+ gap: 6px;
1222
+ margin-bottom: 12px;
1223
+ }
1224
+ .terminal-config-menu .terminal-config-label {
1225
+ font-size: 11px;
1226
+ font-weight: 600;
1227
+ opacity: 0.75;
1228
+ }
1229
+ .terminal-config-menu .terminal-config-select,
1230
+ .terminal-config-menu .terminal-config-input {
1231
+ font-size: 12px;
1232
+ padding: 6px 8px;
1233
+ border-radius: 6px;
1234
+ border: 1px solid rgba(0, 0, 0, 0.18);
1235
+ background: #ffffff;
1236
+ color: inherit;
1237
+ }
1238
+ .terminal-config-menu .terminal-config-input:focus,
1239
+ .terminal-config-menu .terminal-config-select:focus {
1240
+ outline: none;
1241
+ border-color: rgba(127, 91, 243, 0.65);
1242
+ box-shadow: 0 0 0 3px rgba(127, 91, 243, 0.18);
1243
+ }
1244
+ .terminal-config-menu .terminal-config-actions {
1245
+ display: flex;
1246
+ justify-content: flex-end;
1247
+ gap: 8px;
1248
+ }
1249
+ .terminal-config-menu .terminal-config-reset {
1250
+ font-size: 11px;
1251
+ padding: 4px 10px;
1252
+ }
1253
+ .terminal-config-menu .terminal-config-theme-grid {
1254
+ display: flex;
1255
+ flex-direction: column;
1256
+ gap: 8px;
1257
+ }
1258
+ .terminal-config-menu .terminal-config-theme-row {
1259
+ display: grid;
1260
+ grid-template-columns: minmax(140px, 1fr) 32px minmax(0, 1fr) 28px;
1261
+ align-items: center;
1262
+ gap: 8px;
1263
+ }
1264
+ .terminal-config-menu .terminal-config-color-input {
1265
+ width: 32px;
1266
+ height: 32px;
1267
+ padding: 0;
1268
+ border: none;
1269
+ background: transparent;
1270
+ cursor: pointer;
1271
+ }
1272
+ .terminal-config-menu .terminal-config-color-input[data-invalid='true'] {
1273
+ opacity: 0.35;
1274
+ }
1275
+ .terminal-config-menu .terminal-config-theme-text {
1276
+ width: 100%;
1277
+ }
1278
+ .terminal-config-menu .terminal-config-theme-clear {
1279
+ padding: 4px 6px;
1280
+ font-size: 12px;
1281
+ min-width: 28px;
1282
+ }
1283
+ body.dark .terminal-config-menu {
1284
+ background: rgba(21, 22, 23, 0.96);
1285
+ border-color: rgba(255, 255, 255, 0.12);
1286
+ box-shadow: 0 14px 30px rgba(0, 0, 0, 0.35);
1287
+ }
1288
+ body.dark .terminal-config-menu .terminal-config-label,
1289
+ body.dark .terminal-config-menu .terminal-config-title,
1290
+ body.dark .terminal-config-menu .terminal-config-note {
1291
+ color: rgba(255, 255, 255, 0.85);
1292
+ opacity: 0.85;
1293
+ }
1294
+ body.dark .terminal-config-menu .terminal-config-section {
1295
+ border-color: rgba(255, 255, 255, 0.12);
1296
+ }
1297
+ body.dark .terminal-config-menu .terminal-config-help {
1298
+ color: rgba(255, 255, 255, 0.7);
1299
+ }
1300
+ body.dark .terminal-config-menu .terminal-config-select,
1301
+ body.dark .terminal-config-menu .terminal-config-input {
1302
+ background: rgba(255, 255, 255, 0.08);
1303
+ border-color: rgba(255, 255, 255, 0.16);
1304
+ color: #ffffff;
1305
+ }
1306
+ body.dark .terminal-config-menu .terminal-config-color-input {
1307
+ background: rgba(255, 255, 255, 0.08);
1308
+ border-radius: 6px;
1309
+ }
1310
+ body.dark .terminal-config-menu .terminal-config-select:focus,
1311
+ body.dark .terminal-config-menu .terminal-config-input:focus {
1312
+ border-color: rgba(127, 91, 243, 0.85);
1313
+ box-shadow: 0 0 0 3px rgba(127, 91, 243, 0.24);
1314
+ }
1315
+ .terminal-config-open .terminal-config-menu {
1316
+ display: block;
1317
+ }
1147
1318
  body.dark .memory {
1148
1319
  background: rgba(0,0,0,0.8);
1149
1320
  border-left: 5px solid white;