Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16e324102e | ||
|
|
18eba2d911 |
@@ -20,7 +20,10 @@ router.get('/:set/:file', asyncWrap(async (req, res) => {
|
|||||||
try { buf = await sets.readIcon(req.params.set, req.params.file); }
|
try { buf = await sets.readIcon(req.params.set, req.params.file); }
|
||||||
catch (e) { return res.status(e.message === 'bad_slug' ? 400 : 404).end(); }
|
catch (e) { return res.status(e.message === 'bad_slug' ? 400 : 404).end(); }
|
||||||
const ct = req.params.file.endsWith('.svg') ? 'image/svg+xml' : 'image/png';
|
const ct = req.params.file.endsWith('.svg') ? 'image/svg+xml' : 'image/png';
|
||||||
res.set('Content-Type', ct).set('Cache-Control', 'public, max-age=86400').send(buf);
|
// no-cache => browsers/CF revalidate (304 via Express's ETag when unchanged), so
|
||||||
|
// icon updates propagate immediately instead of being stuck for a day. Icons are
|
||||||
|
// tiny, so the revalidation cost is negligible.
|
||||||
|
res.set('Content-Type', ct).set('Cache-Control', 'no-cache').send(buf);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// POST /api/icon-sets/:set — owner upload: multipart files (incl .zip) and/or { url }.
|
// POST /api/icon-sets/:set — owner upload: multipart files (incl .zip) and/or { url }.
|
||||||
|
|||||||
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "void-server",
|
"name": "void-server",
|
||||||
"version": "2.5.0",
|
"version": "2.5.2",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "void-server",
|
"name": "void-server",
|
||||||
"version": "2.5.0",
|
"version": "2.5.2",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/sdk": "^1.29.0",
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
||||||
"@mozilla/readability": "^0.6.0",
|
"@mozilla/readability": "^0.6.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "void-server",
|
"name": "void-server",
|
||||||
"version": "2.5.0",
|
"version": "2.5.2",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ unicode: "ea54"
|
|||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="#e8e6ed"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 560 B After Width: | Height: | Size: 555 B |
@@ -10,7 +10,7 @@ unicode: "f1d2"
|
|||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="#e8e6ed"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 634 B After Width: | Height: | Size: 629 B |
@@ -10,7 +10,7 @@ unicode: "ea89"
|
|||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="#e8e6ed"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 533 B After Width: | Height: | Size: 528 B |
@@ -10,7 +10,7 @@ unicode: "eb64"
|
|||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="#e8e6ed"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 487 B After Width: | Height: | Size: 482 B |
@@ -10,7 +10,7 @@ unicode: "ea88"
|
|||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="#e8e6ed"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 497 B After Width: | Height: | Size: 492 B |
@@ -10,7 +10,7 @@ unicode: "ea8a"
|
|||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="#e8e6ed"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 510 B After Width: | Height: | Size: 505 B |
@@ -10,7 +10,7 @@ unicode: "ebd9"
|
|||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="#e8e6ed"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 556 B After Width: | Height: | Size: 551 B |
@@ -10,7 +10,7 @@ unicode: "eb0e"
|
|||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="#e8e6ed"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 604 B After Width: | Height: | Size: 599 B |
@@ -10,7 +10,7 @@ unicode: "eb18"
|
|||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="#e8e6ed"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 622 B After Width: | Height: | Size: 617 B |
@@ -10,7 +10,7 @@ unicode: "eb1f"
|
|||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="#e8e6ed"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 594 B After Width: | Height: | Size: 589 B |
@@ -10,7 +10,7 @@ unicode: "ed61"
|
|||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="#e8e6ed"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 599 B After Width: | Height: | Size: 594 B |
@@ -10,7 +10,7 @@ unicode: "ea8c"
|
|||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="#e8e6ed"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 513 B After Width: | Height: | Size: 508 B |
@@ -10,7 +10,7 @@ unicode: "ea8d"
|
|||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="#e8e6ed"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 475 B After Width: | Height: | Size: 470 B |
@@ -10,7 +10,7 @@ version: "3.5"
|
|||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="#e8e6ed"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 572 B After Width: | Height: | Size: 567 B |
@@ -10,7 +10,7 @@ unicode: "ebf9"
|
|||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="#e8e6ed"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 494 B After Width: | Height: | Size: 489 B |
@@ -647,14 +647,14 @@ body.drawer-open #scrim { opacity: 1; pointer-events: auto; }
|
|||||||
.sv-cluster .st-fill.bad { background: var(--bad); }
|
.sv-cluster .st-fill.bad { background: var(--bad); }
|
||||||
.sv-cluster .sv-subhdr { color: var(--muted); font-size: 10px; text-transform: uppercase; letter-spacing: .08em; margin: 11px 0 5px; font-family: var(--font-mono); }
|
.sv-cluster .sv-subhdr { color: var(--muted); font-size: 10px; text-transform: uppercase; letter-spacing: .08em; margin: 11px 0 5px; font-family: var(--font-mono); }
|
||||||
|
|
||||||
.dv-icon { width: 20px; height: 20px; object-fit: contain; opacity: .9; }
|
.dv-icon { width: 30px; height: 30px; object-fit: contain; opacity: .95; }
|
||||||
.dv-icon-fb { width: 20px; height: 20px; display: grid; place-items: center; font-size: 11px; background: var(--panel-2, #1b1b22); border-radius: 4px; }
|
.dv-icon-fb { width: 30px; height: 30px; display: grid; place-items: center; font-size: 14px; color: var(--text); background: var(--panel-2, #1b1b22); border-radius: 4px; }
|
||||||
.dv-seen { font-size: 11px; color: var(--muted, #8a8a94); }
|
.dv-seen { font-size: 11px; color: var(--muted, #8a8a94); }
|
||||||
.icon-picker { border: 1px solid var(--border, #2a2a36); border-radius: 6px; padding: 6px; margin-top: 6px; max-width: 320px; }
|
.icon-picker { border: 1px solid var(--border, #2a2a36); border-radius: 6px; padding: 6px; margin-top: 6px; max-width: 320px; }
|
||||||
.ip-tabs { display: flex; gap: 4px; margin-bottom: 6px; }
|
.ip-tabs { display: flex; gap: 4px; margin-bottom: 6px; }
|
||||||
.ip-tab.active { color: var(--accent, #ff4f2e); border-bottom: 1px solid var(--accent, #ff4f2e); }
|
.ip-tab.active { color: var(--accent, #ff4f2e); border-bottom: 1px solid var(--accent, #ff4f2e); }
|
||||||
.ip-grid { display: flex; flex-wrap: wrap; gap: 6px; }
|
.ip-grid { display: flex; flex-wrap: wrap; gap: 6px; }
|
||||||
.ip-icon { width: 34px; height: 34px; display: grid; place-items: center; background: transparent; border: 1px solid var(--border, #2a2a36); border-radius: 4px; cursor: pointer; }
|
.ip-icon { width: 40px; height: 40px; display: grid; place-items: center; background: transparent; border: 1px solid var(--border, #2a2a36); border-radius: 4px; cursor: pointer; }
|
||||||
.ip-icon img { width: 22px; height: 22px; object-fit: contain; }
|
.ip-icon img { width: 28px; height: 28px; object-fit: contain; }
|
||||||
.ip-set-hd, .isp-hd { font-size: 12px; margin: 6px 0 3px; text-transform: capitalize; }
|
.ip-set-hd, .isp-hd { font-size: 12px; margin: 6px 0 3px; text-transform: capitalize; }
|
||||||
.isp-upload { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
|
.isp-upload { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { mcpAuth } from './lib/api/middleware/mcp_auth.js';
|
|||||||
import { handleMcp } from './lib/mcp/http.js';
|
import { handleMcp } from './lib/mcp/http.js';
|
||||||
import httpProxy from 'http-proxy';
|
import httpProxy from 'http-proxy';
|
||||||
|
|
||||||
const VERSION = '2.5.0';
|
const VERSION = '2.5.2';
|
||||||
|
|
||||||
// Proxy /terminal (+ its WebSocket) to ttyd on CT 300, so the embedded terminal
|
// Proxy /terminal (+ its WebSocket) to ttyd on CT 300, so the embedded terminal
|
||||||
// works whether the Void is reached via Traefik (void2-app.hynesy.com) OR the
|
// works whether the Void is reached via Traefik (void2-app.hynesy.com) OR the
|
||||||
|
|||||||