pinokiod 7.3.9 → 7.3.11

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 (52) hide show
  1. package/kernel/bin/brew.js +12 -2
  2. package/kernel/bin/caddy.js +24 -20
  3. package/kernel/bin/huggingface.js +2 -2
  4. package/kernel/bin/setup.js +2 -3
  5. package/kernel/bin/uv.js +13 -6
  6. package/kernel/connect/index.js +5 -1
  7. package/kernel/connect/providers/huggingface/index.js +213 -75
  8. package/kernel/environment.js +16 -1
  9. package/kernel/router/localhost_home_router.js +7 -0
  10. package/kernel/shell.js +1 -5
  11. package/kernel/util.js +1 -0
  12. package/package.json +1 -1
  13. package/server/index.js +75 -33
  14. package/server/public/common.js +52 -88
  15. package/server/public/install.js +20 -2
  16. package/server/public/layout.js +1 -1
  17. package/server/public/nav.js +3 -1
  18. package/server/public/style.css +1455 -521
  19. package/server/public/tab-link-popover.css +162 -18
  20. package/server/public/tab-link-popover.js +230 -21
  21. package/server/public/task-launcher.css +182 -91
  22. package/server/public/terminal-settings.js +227 -50
  23. package/server/public/universal-launcher.css +42 -33
  24. package/server/public/urldropdown.css +284 -0
  25. package/server/views/app.ejs +1718 -352
  26. package/server/views/autolaunch.ejs +4 -5
  27. package/server/views/checkpoints.ejs +223 -50
  28. package/server/views/connect/huggingface.ejs +406 -325
  29. package/server/views/connect.ejs +0 -1
  30. package/server/views/github.ejs +277 -324
  31. package/server/views/index.ejs +65 -8
  32. package/server/views/install.ejs +134 -65
  33. package/server/views/logs.ejs +9 -8
  34. package/server/views/net.ejs +341 -64
  35. package/server/views/network.ejs +85 -63
  36. package/server/views/partials/main_sidebar.ejs +249 -24
  37. package/server/views/plugins.ejs +141 -3
  38. package/server/views/settings.ejs +103 -7
  39. package/server/views/setup.ejs +0 -5
  40. package/server/views/skills.ejs +0 -1
  41. package/server/views/task_list.ejs +0 -1
  42. package/server/views/terminal.ejs +285 -60
  43. package/server/views/terminals.ejs +346 -6
  44. package/server/views/tools.ejs +828 -1691
  45. package/test/caddy-install.test.js +53 -0
  46. package/test/connect-setup.test.js +16 -0
  47. package/test/github-connection.test.js +1 -1
  48. package/test/huggingface-bin.test.js +4 -4
  49. package/test/huggingface-connect.test.js +73 -0
  50. package/test/main-sidebar.test.js +31 -0
  51. package/test/shell-run-template.test.js +5 -1
  52. package/test/uv-bin.test.js +29 -0
@@ -106,56 +106,103 @@ td.key {
106
106
  }
107
107
  header.navheader2 {
108
108
  position: relative;
109
- padding: 10px 0;
109
+ padding: 8px 0;
110
110
  }
111
111
  .navheader2 .runner .btn {
112
112
  display: inline-flex;
113
113
  align-items: center;
114
114
  justify-content: center;
115
- gap: 7px;
116
- height: 22px;
117
- padding: 0 8px !important;
118
- border: 1px solid rgba(15, 23, 42, 0.16);
119
- border-radius: 3px;
120
- background: linear-gradient(180deg, rgba(60, 67, 92, 0.96), rgba(49, 55, 78, 0.96));
121
- box-shadow: inset 0 1px 0 rgba(255,255,255,0.06);
122
- color: rgba(255,255,255,0.96);
115
+ gap: 6px;
116
+ height: 24px;
117
+ min-height: 24px;
118
+ padding: 0 9px !important;
119
+ border: 1px solid rgba(15, 23, 42, 0.12);
120
+ border-radius: 6px;
121
+ background: rgba(255, 255, 255, 0.72);
122
+ box-shadow: none;
123
+ color: rgba(17, 24, 39, 0.88);
123
124
  font-size: 12px;
124
125
  font-weight: 600;
125
126
  line-height: 1;
126
127
  text-decoration: none;
127
128
  box-sizing: border-box;
128
- transition: background 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease;
129
+ transition: background-color 0.14s ease, border-color 0.14s ease, color 0.14s ease, box-shadow 0.14s ease, transform 0.14s ease;
129
130
  }
130
131
  .navheader2 .runner .btn:hover {
131
- border-color: rgba(111, 143, 255, 0.32);
132
- background: linear-gradient(180deg, rgba(67, 74, 101, 0.98), rgba(55, 62, 86, 0.98));
132
+ border-color: rgba(15, 23, 42, 0.18);
133
+ background: rgba(15, 23, 42, 0.04);
134
+ color: rgba(17, 24, 39, 0.96);
133
135
  }
134
136
  .navheader2 .runner .btn:focus-visible {
135
137
  outline: none;
136
- box-shadow: 0 0 0 3px rgba(66, 113, 174, 0.2), inset 0 1px 0 rgba(255,255,255,0.06);
138
+ box-shadow: 0 0 0 2px rgba(10, 132, 255, 0.2);
137
139
  }
138
140
  .navheader2 .runner .btn:active {
139
141
  transform: translateY(1px);
140
142
  }
143
+ .navheader2 .runner .btn i {
144
+ font-size: 12px;
145
+ line-height: 1;
146
+ }
141
147
  .navheader2 .runner .run > span {
142
148
  display: inline-flex;
143
149
  align-items: center;
144
- gap: 7px;
150
+ gap: 6px;
151
+ }
152
+ .navheader2 .runner .terminal-utility-button {
153
+ position: relative;
154
+ width: 24px;
155
+ min-width: 24px;
156
+ padding: 0 !important;
157
+ gap: 0;
158
+ }
159
+ .terminal-tooltip {
160
+ position: fixed;
161
+ left: 0;
162
+ top: 0;
163
+ z-index: 2147483000;
164
+ max-width: calc(100vw - 16px);
165
+ padding: 5px 8px;
166
+ border-radius: 6px;
167
+ background: rgba(17, 24, 39, 0.96);
168
+ box-shadow: 0 8px 20px rgba(15, 23, 42, 0.18);
169
+ color: #fff;
170
+ font-size: 11px;
171
+ font-weight: 500;
172
+ line-height: 1.2;
173
+ white-space: nowrap;
174
+ pointer-events: none;
175
+ opacity: 0;
176
+ visibility: hidden;
177
+ transition: opacity 0.12s ease, transform 0.12s ease, visibility 0.12s ease;
178
+ transform: translateY(-2px);
179
+ }
180
+ .terminal-tooltip.is-visible {
181
+ opacity: 1;
182
+ visibility: visible;
183
+ transform: translateY(0);
184
+ }
185
+ .navheader2 .runner .terminal-config-button .terminal-config-label {
186
+ display: inline-flex;
187
+ align-items: center;
188
+ justify-content: center;
145
189
  }
146
190
  body.dark .navheader2 .runner .btn {
147
- border-color: rgba(255,255,255,0.12);
148
- background: linear-gradient(180deg, rgba(255,255,255,0.11), rgba(255,255,255,0.07));
149
- box-shadow: inset 0 1px 0 rgba(255,255,255,0.05);
191
+ border-color: rgba(255, 255, 255, 0.1);
192
+ background: rgba(255, 255, 255, 0.045);
193
+ box-shadow: none;
194
+ color: rgba(248, 250, 252, 0.88);
150
195
  }
151
196
  body.dark .navheader2 .runner .btn:hover {
152
- border-color: rgba(111, 143, 255, 0.28);
153
- background: linear-gradient(180deg, rgba(255,255,255,0.14), rgba(255,255,255,0.1));
197
+ border-color: rgba(255, 255, 255, 0.18);
198
+ background: rgba(255, 255, 255, 0.08);
199
+ color: rgba(248, 250, 252, 0.96);
154
200
  }
155
201
  .protection-toggle {
156
202
  display: inline-flex;
157
203
  align-items: center;
158
- gap: 8px;
204
+ gap: 6px;
205
+ padding: 0 7px !important;
159
206
  white-space: nowrap;
160
207
  }
161
208
  .protection-toggle.is-saving {
@@ -168,51 +215,52 @@ body.dark .navheader2 .runner .btn:hover {
168
215
  .protection-toggle-copy {
169
216
  display: inline-flex;
170
217
  align-items: center;
171
- gap: 7px;
218
+ gap: 5px;
172
219
  min-width: 0;
173
220
  }
174
221
  .protection-toggle-icon-wrap {
175
- width: 16px;
176
- height: 16px;
177
- border-radius: 4px;
222
+ width: 14px;
223
+ height: 14px;
224
+ border-radius: 3px;
178
225
  display: inline-flex;
179
226
  align-items: center;
180
227
  justify-content: center;
181
- background: rgba(126, 155, 255, 0.14);
182
- box-shadow: inset 0 0 0 1px rgba(126, 155, 255, 0.14);
228
+ background: transparent;
229
+ box-shadow: none;
183
230
  flex-shrink: 0;
184
231
  }
185
232
  .protection-toggle-icon {
186
- color: #89a6ff;
233
+ color: rgba(75, 85, 99, 0.86);
187
234
  font-size: 10px;
188
235
  }
189
236
  .protection-toggle-label {
190
237
  font-weight: 600;
191
- letter-spacing: 0.01em;
238
+ letter-spacing: 0;
192
239
  }
193
240
  .protection-toggle-state {
194
241
  display: inline-flex;
195
242
  align-items: center;
196
243
  justify-content: center;
197
- min-width: 24px;
198
- padding: 1px 5px;
244
+ min-width: 22px;
245
+ height: 14px;
246
+ padding: 0 5px;
199
247
  border-radius: 999px;
200
- background: rgba(255,255,255,0.08);
201
- box-shadow: inset 0 0 0 1px rgba(255,255,255,0.08);
202
- color: rgba(255,255,255,0.84);
248
+ background: rgba(217, 119, 6, 0.1);
249
+ box-shadow: none;
250
+ color: #a16207;
203
251
  font-size: 9px;
204
252
  font-weight: 700;
205
- letter-spacing: 0.06em;
253
+ letter-spacing: 0.04em;
206
254
  text-transform: uppercase;
207
255
  line-height: 1;
208
256
  }
209
257
  .protection-toggle-switch {
210
258
  position: relative;
211
- width: 24px;
212
- height: 14px;
259
+ width: 22px;
260
+ height: 12px;
213
261
  border-radius: 999px;
214
- background: rgba(255,255,255,0.1);
215
- box-shadow: inset 0 0 0 1px rgba(255,255,255,0.1);
262
+ background: rgba(15, 23, 42, 0.08);
263
+ box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.08);
216
264
  flex-shrink: 0;
217
265
  transition: background 0.2s ease, box-shadow 0.2s ease;
218
266
  }
@@ -221,11 +269,11 @@ body.dark .navheader2 .runner .btn:hover {
221
269
  position: absolute;
222
270
  top: 2px;
223
271
  left: 2px;
224
- width: 10px;
225
- height: 10px;
272
+ width: 8px;
273
+ height: 8px;
226
274
  border-radius: 999px;
227
- background: rgba(255,255,255,0.94);
228
- box-shadow: 0 1px 3px rgba(0,0,0,0.22);
275
+ background: rgba(255, 255, 255, 0.98);
276
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
229
277
  transition: transform 0.2s ease;
230
278
  }
231
279
  .protection-toggle[aria-checked="true"] .protection-toggle-switch::after {
@@ -235,42 +283,78 @@ body.dark .navheader2 .runner .btn:hover {
235
283
  transform: translateX(0);
236
284
  }
237
285
  .protection-toggle[aria-checked="true"] .protection-toggle-state {
238
- background: rgba(111, 143, 255, 0.16);
239
- box-shadow: inset 0 0 0 1px rgba(111, 143, 255, 0.18);
240
- color: #e2eaff;
286
+ background: rgba(37, 99, 235, 0.12);
287
+ box-shadow: none;
288
+ color: #2563eb;
241
289
  }
242
290
  .protection-toggle[aria-checked="true"] .protection-toggle-switch {
243
- background: rgba(111, 143, 255, 0.24);
244
- box-shadow: inset 0 0 0 1px rgba(111, 143, 255, 0.34);
291
+ background: rgba(37, 99, 235, 0.18);
292
+ box-shadow: inset 0 0 0 1px rgba(37, 99, 235, 0.24);
245
293
  }
246
294
  .protection-toggle[aria-checked="false"] .protection-toggle-icon-wrap {
247
- background: rgba(217, 119, 6, 0.16);
248
- box-shadow: inset 0 0 0 1px rgba(217, 119, 6, 0.2);
295
+ background: transparent;
296
+ box-shadow: none;
249
297
  }
250
298
  .protection-toggle[aria-checked="false"] .protection-toggle-icon {
251
- color: #f0ba61;
299
+ color: #b45309;
252
300
  }
253
301
  .protection-toggle[aria-checked="false"] .protection-toggle-state {
254
- background: rgba(217, 119, 6, 0.16);
255
- box-shadow: inset 0 0 0 1px rgba(217, 119, 6, 0.2);
256
- color: #f7ca81;
302
+ background: rgba(217, 119, 6, 0.1);
303
+ box-shadow: none;
304
+ color: #a16207;
257
305
  }
258
306
  .protection-toggle[aria-checked="false"] .protection-toggle-switch {
259
- background: rgba(217, 119, 6, 0.18);
260
- box-shadow: inset 0 0 0 1px rgba(217, 119, 6, 0.24);
307
+ background: rgba(217, 119, 6, 0.12);
308
+ box-shadow: inset 0 0 0 1px rgba(217, 119, 6, 0.18);
309
+ }
310
+ body.dark .protection-toggle-icon {
311
+ color: rgba(209, 213, 219, 0.86);
312
+ }
313
+ body.dark .protection-toggle-state {
314
+ background: rgba(245, 158, 11, 0.12);
315
+ color: #f0b45f;
316
+ }
317
+ body.dark .protection-toggle-switch {
318
+ background: rgba(255, 255, 255, 0.1);
319
+ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12);
320
+ }
321
+ body.dark .protection-toggle[aria-checked="true"] .protection-toggle-state {
322
+ background: rgba(96, 165, 250, 0.16);
323
+ color: #93c5fd;
324
+ }
325
+ body.dark .protection-toggle[aria-checked="true"] .protection-toggle-switch {
326
+ background: rgba(96, 165, 250, 0.22);
327
+ box-shadow: inset 0 0 0 1px rgba(96, 165, 250, 0.3);
328
+ }
329
+ body.dark .protection-toggle[aria-checked="false"] .protection-toggle-icon {
330
+ color: #f0b45f;
331
+ }
332
+ body.dark .protection-toggle[aria-checked="false"] .protection-toggle-state {
333
+ background: rgba(245, 158, 11, 0.12);
334
+ color: #f0b45f;
335
+ }
336
+ body.dark .protection-toggle[aria-checked="false"] .protection-toggle-switch {
337
+ background: rgba(245, 158, 11, 0.14);
338
+ box-shadow: inset 0 0 0 1px rgba(245, 158, 11, 0.2);
261
339
  }
262
340
  @media (max-width: 640px) {
263
341
  .navheader2 .runner .btn {
264
- height: 22px;
342
+ height: 24px;
265
343
  padding: 0 8px !important;
266
- border-radius: 3px;
344
+ border-radius: 6px;
345
+ }
346
+ .navheader2 .runner .terminal-utility-button {
347
+ width: 24px;
348
+ min-width: 24px;
349
+ padding: 0 !important;
267
350
  }
268
351
  .protection-toggle-copy {
269
- gap: 6px;
352
+ gap: 5px;
270
353
  }
271
354
  }
272
355
  @media (prefers-reduced-motion: reduce) {
273
356
  .navheader2 .runner .btn,
357
+ .terminal-tooltip,
274
358
  .protection-toggle,
275
359
  .protection-toggle-switch,
276
360
  .protection-toggle-switch::after {
@@ -426,7 +510,7 @@ body.has-full-navbar .navheader2 .runner {
426
510
  --ai-consent-secondary-border: rgba(15, 23, 42, 0.12);
427
511
  --ai-consent-secondary-hover: rgba(15, 23, 42, 0.08);
428
512
  --ai-consent-link: #6c7ea5;
429
- width: min(520px, 100%);
513
+ width: min(520px, calc(100% - 32px));
430
514
  max-height: calc(100vh - 32px);
431
515
  max-height: calc(100dvh - 32px);
432
516
  background: var(--ai-consent-surface);
@@ -651,6 +735,147 @@ body.dark .ai-manage-item {
651
735
  display: flex;
652
736
  justify-content: flex-end;
653
737
  }
738
+ /* Minimal modal normalization for AI consent and access management. */
739
+ .ai-consent-modal {
740
+ --ai-consent-surface: #ffffff;
741
+ --ai-consent-border: rgba(24, 24, 27, 0.12);
742
+ --ai-consent-shadow: 0 18px 50px rgba(15, 23, 42, 0.16);
743
+ --ai-consent-text: #18181b;
744
+ --ai-consent-muted: #71717a;
745
+ --ai-consent-soft: #52525b;
746
+ --ai-consent-panel: rgba(24, 24, 27, 0.03);
747
+ --ai-consent-panel-border: rgba(24, 24, 27, 0.1);
748
+ --ai-consent-icon-fg: #52525b;
749
+ --ai-consent-primary-bg: #18181b;
750
+ --ai-consent-primary-text: #ffffff;
751
+ --ai-consent-primary-border: #18181b;
752
+ --ai-consent-primary-hover: #27272a;
753
+ --ai-consent-secondary-bg: transparent;
754
+ --ai-consent-secondary-border: rgba(24, 24, 27, 0.12);
755
+ --ai-consent-secondary-hover: rgba(24, 24, 27, 0.06);
756
+ --ai-consent-link: #52525b;
757
+ border-radius: 8px;
758
+ padding: 18px;
759
+ box-shadow: var(--ai-consent-shadow);
760
+ opacity: 1;
761
+ filter: none;
762
+ }
763
+
764
+ body.dark .ai-consent-modal {
765
+ --ai-consent-surface: #1b1c1d;
766
+ --ai-consent-border: rgba(255, 255, 255, 0.1);
767
+ --ai-consent-shadow: 0 24px 72px rgba(0, 0, 0, 0.42);
768
+ --ai-consent-text: rgba(250, 250, 250, 0.94);
769
+ --ai-consent-muted: rgba(229, 231, 235, 0.62);
770
+ --ai-consent-soft: rgba(229, 231, 235, 0.7);
771
+ --ai-consent-panel: rgba(255, 255, 255, 0.04);
772
+ --ai-consent-panel-border: rgba(255, 255, 255, 0.09);
773
+ --ai-consent-icon-fg: rgba(229, 231, 235, 0.76);
774
+ --ai-consent-primary-bg: rgba(250, 250, 250, 0.94);
775
+ --ai-consent-primary-text: #1b1c1d;
776
+ --ai-consent-primary-border: rgba(250, 250, 250, 0.94);
777
+ --ai-consent-primary-hover: #ffffff;
778
+ --ai-consent-secondary-bg: transparent;
779
+ --ai-consent-secondary-border: rgba(255, 255, 255, 0.1);
780
+ --ai-consent-secondary-hover: rgba(255, 255, 255, 0.07);
781
+ --ai-consent-link: rgba(229, 231, 235, 0.7);
782
+ }
783
+
784
+ .ai-consent-header {
785
+ gap: 10px;
786
+ margin-bottom: 12px;
787
+ }
788
+
789
+ .ai-consent-icon {
790
+ width: 32px;
791
+ height: 32px;
792
+ border-radius: 7px;
793
+ font-size: 14px;
794
+ }
795
+
796
+ .ai-consent-title {
797
+ font-size: 16px;
798
+ line-height: 1.25;
799
+ font-weight: 600;
800
+ color: var(--ai-consent-text);
801
+ }
802
+
803
+ .ai-consent-desc,
804
+ .ai-consent-list li,
805
+ .ai-consent-remember {
806
+ font-size: 13px;
807
+ color: var(--ai-consent-muted);
808
+ }
809
+
810
+ .ai-consent-list strong,
811
+ .ai-consent-scope {
812
+ color: var(--ai-consent-text);
813
+ }
814
+
815
+ .ai-consent-list {
816
+ margin-bottom: 14px;
817
+ padding: 10px 12px 10px 18px;
818
+ border-radius: 7px;
819
+ }
820
+
821
+ .ai-btn-primary,
822
+ .ai-btn-secondary {
823
+ min-height: 32px;
824
+ padding: 0 12px;
825
+ border-radius: 6px;
826
+ box-shadow: none;
827
+ font-size: 13px;
828
+ font-weight: 600;
829
+ }
830
+
831
+ .ai-btn-secondary:focus-visible,
832
+ .ai-btn-primary:focus-visible,
833
+ .ai-consent-manage:focus-visible {
834
+ outline: 2px solid color-mix(in srgb, var(--ai-consent-text) 28%, transparent);
835
+ outline-offset: 2px;
836
+ }
837
+
838
+ .ai-manage-sheet,
839
+ body.dark .ai-manage-sheet {
840
+ background: var(--ai-consent-surface, #ffffff);
841
+ color: var(--ai-consent-text, #18181b);
842
+ border: 1px solid var(--ai-consent-border, rgba(24, 24, 27, 0.12));
843
+ border-radius: 8px;
844
+ box-shadow: var(--ai-consent-shadow, 0 18px 50px rgba(15, 23, 42, 0.16));
845
+ }
846
+
847
+ body.dark .ai-manage-sheet {
848
+ background: #1b1c1d;
849
+ color: rgba(250, 250, 250, 0.94);
850
+ border-color: rgba(255, 255, 255, 0.1);
851
+ box-shadow: 0 24px 72px rgba(0, 0, 0, 0.42);
852
+ }
853
+
854
+ .ai-manage-header h3 {
855
+ font-size: 14px;
856
+ font-weight: 600;
857
+ }
858
+
859
+ #ai-manage-close {
860
+ width: 28px;
861
+ height: 28px;
862
+ border-radius: 6px;
863
+ color: var(--ai-consent-muted, #71717a);
864
+ }
865
+
866
+ #ai-manage-close:hover,
867
+ #ai-manage-close:focus-visible {
868
+ background: var(--ai-consent-panel, rgba(24, 24, 27, 0.04));
869
+ color: var(--ai-consent-text, #18181b);
870
+ outline: none;
871
+ }
872
+
873
+ body.dark #ai-manage-close:hover,
874
+ body.dark #ai-manage-close:focus-visible {
875
+ background: rgba(255, 255, 255, 0.07);
876
+ color: rgba(250, 250, 250, 0.94);
877
+ }
878
+
654
879
  @keyframes ai-pop {
655
880
  from { transform: translateY(8px) scale(0.98); opacity: 0; }
656
881
  to { transform: none; opacity: 1; }
@@ -2393,10 +2618,10 @@ document.addEventListener("DOMContentLoaded", async () => {
2393
2618
  config = window.PinokioTerminalSettings.applyToConfig(config)
2394
2619
  }
2395
2620
  const term = new Terminal(config)
2621
+ term.open(document.querySelector("#terminal"))
2396
2622
  if (window.PinokioTerminalSettings && typeof window.PinokioTerminalSettings.register === 'function') {
2397
2623
  window.PinokioTerminalSettings.register(term, { baseConfig })
2398
2624
  }
2399
- term.open(document.querySelector("#terminal"))
2400
2625
  const terminalContainer = document.querySelector("#terminal")
2401
2626
  const dropOverlay = document.createElement("div")
2402
2627
  dropOverlay.className = "terminal-drop-overlay"