labgate 0.5.35 → 0.5.36
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/dist/lib/ui.html +110 -29
- package/package.json +1 -1
package/dist/lib/ui.html
CHANGED
|
@@ -4,54 +4,67 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>LabGate Settings</title>
|
|
7
|
-
<
|
|
7
|
+
<script>
|
|
8
|
+
(function canonicalizeUiPathWithTrailingSlash() {
|
|
9
|
+
try {
|
|
10
|
+
var pathname = String(window.location.pathname || '/');
|
|
11
|
+
if (!pathname || pathname === '/' || pathname.endsWith('/')) return;
|
|
12
|
+
var tail = pathname.slice(pathname.lastIndexOf('/') + 1);
|
|
13
|
+
if (!tail || tail.indexOf('.') !== -1) return;
|
|
14
|
+
window.location.replace(pathname + '/' + window.location.search + window.location.hash);
|
|
15
|
+
} catch (_err) {
|
|
16
|
+
// Best effort: continue without redirect.
|
|
17
|
+
}
|
|
18
|
+
})();
|
|
19
|
+
</script>
|
|
20
|
+
<link rel="stylesheet" href="vendor/xterm/xterm.css">
|
|
8
21
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><rect width='100' height='100' rx='20' fill='%23374151'/><text x='50' y='68' font-size='52' font-family='system-ui' font-weight='700' fill='white' text-anchor='middle'>L</text></svg>">
|
|
9
22
|
<style>
|
|
10
23
|
@font-face {
|
|
11
24
|
font-family: 'Geist';
|
|
12
|
-
src: url('
|
|
25
|
+
src: url('fonts/Geist-Regular.woff2') format('woff2');
|
|
13
26
|
font-weight: 400;
|
|
14
27
|
font-style: normal;
|
|
15
28
|
font-display: swap;
|
|
16
29
|
}
|
|
17
30
|
@font-face {
|
|
18
31
|
font-family: 'Geist';
|
|
19
|
-
src: url('
|
|
32
|
+
src: url('fonts/Geist-Medium.woff2') format('woff2');
|
|
20
33
|
font-weight: 500;
|
|
21
34
|
font-style: normal;
|
|
22
35
|
font-display: swap;
|
|
23
36
|
}
|
|
24
37
|
@font-face {
|
|
25
38
|
font-family: 'Geist';
|
|
26
|
-
src: url('
|
|
39
|
+
src: url('fonts/Geist-SemiBold.woff2') format('woff2');
|
|
27
40
|
font-weight: 600;
|
|
28
41
|
font-style: normal;
|
|
29
42
|
font-display: swap;
|
|
30
43
|
}
|
|
31
44
|
@font-face {
|
|
32
45
|
font-family: 'Geist';
|
|
33
|
-
src: url('
|
|
46
|
+
src: url('fonts/Geist-Bold.woff2') format('woff2');
|
|
34
47
|
font-weight: 700;
|
|
35
48
|
font-style: normal;
|
|
36
49
|
font-display: swap;
|
|
37
50
|
}
|
|
38
51
|
@font-face {
|
|
39
52
|
font-family: 'GeistMono';
|
|
40
|
-
src: url('
|
|
53
|
+
src: url('fonts/GeistMono-Regular.woff2') format('woff2');
|
|
41
54
|
font-weight: 400;
|
|
42
55
|
font-style: normal;
|
|
43
56
|
font-display: swap;
|
|
44
57
|
}
|
|
45
58
|
@font-face {
|
|
46
59
|
font-family: 'GeistMono';
|
|
47
|
-
src: url('
|
|
60
|
+
src: url('fonts/GeistMono-Medium.woff2') format('woff2');
|
|
48
61
|
font-weight: 500;
|
|
49
62
|
font-style: normal;
|
|
50
63
|
font-display: swap;
|
|
51
64
|
}
|
|
52
65
|
@font-face {
|
|
53
66
|
font-family: 'GeistPixelSquare';
|
|
54
|
-
src: url('
|
|
67
|
+
src: url('fonts/GeistPixel-Square.woff2') format('woff2');
|
|
55
68
|
font-weight: 400;
|
|
56
69
|
font-style: normal;
|
|
57
70
|
font-display: swap;
|
|
@@ -6895,9 +6908,9 @@
|
|
|
6895
6908
|
</div>
|
|
6896
6909
|
</div>
|
|
6897
6910
|
|
|
6898
|
-
<script src="
|
|
6899
|
-
<script src="
|
|
6900
|
-
<script src="
|
|
6911
|
+
<script src="vendor/xterm/xterm.js"></script>
|
|
6912
|
+
<script src="vendor/xterm/addon-fit.js"></script>
|
|
6913
|
+
<script src="vendor/xterm/addon-web-links.js"></script>
|
|
6901
6914
|
<script>
|
|
6902
6915
|
var config = {};
|
|
6903
6916
|
var originalConfig = '';
|
|
@@ -6966,6 +6979,76 @@ var autoCopySelectionState = {
|
|
|
6966
6979
|
lastToastAt: 0
|
|
6967
6980
|
};
|
|
6968
6981
|
|
|
6982
|
+
function getLabgateUiBasePath() {
|
|
6983
|
+
var pathname = String(window.location.pathname || '/');
|
|
6984
|
+
if (!pathname) return '/';
|
|
6985
|
+
if (pathname.charAt(0) !== '/') pathname = '/' + pathname;
|
|
6986
|
+
if (pathname === '/') return '/';
|
|
6987
|
+
if (pathname.endsWith('/')) return pathname;
|
|
6988
|
+
var tail = pathname.slice(pathname.lastIndexOf('/') + 1);
|
|
6989
|
+
if (tail && tail.indexOf('.') === -1) {
|
|
6990
|
+
return pathname + '/';
|
|
6991
|
+
}
|
|
6992
|
+
var slashIdx = pathname.lastIndexOf('/');
|
|
6993
|
+
return slashIdx >= 0 ? pathname.slice(0, slashIdx + 1) : '/';
|
|
6994
|
+
}
|
|
6995
|
+
|
|
6996
|
+
var LABGATE_UI_BASE_PATH = getLabgateUiBasePath();
|
|
6997
|
+
|
|
6998
|
+
function shouldPrefixLabgateUrl(url) {
|
|
6999
|
+
return /^\/(?:api|vendor|fonts)(?:\/|\?|$)/.test(url);
|
|
7000
|
+
}
|
|
7001
|
+
|
|
7002
|
+
function applyLabgateUiBasePath(rawPath) {
|
|
7003
|
+
if (!shouldPrefixLabgateUrl(rawPath)) return rawPath;
|
|
7004
|
+
if (LABGATE_UI_BASE_PATH === '/') return rawPath;
|
|
7005
|
+
return LABGATE_UI_BASE_PATH + rawPath.slice(1);
|
|
7006
|
+
}
|
|
7007
|
+
|
|
7008
|
+
function resolveLabgateUiUrl(url) {
|
|
7009
|
+
var raw = String(url || '');
|
|
7010
|
+
if (!raw) return raw;
|
|
7011
|
+
if (/^(?:[a-z][a-z0-9+.-]*:)?\/\//i.test(raw)) {
|
|
7012
|
+
try {
|
|
7013
|
+
var parsed = new URL(raw);
|
|
7014
|
+
if (parsed.origin !== window.location.origin) return raw;
|
|
7015
|
+
var rewrittenPath = applyLabgateUiBasePath(parsed.pathname);
|
|
7016
|
+
if (rewrittenPath === parsed.pathname) return raw;
|
|
7017
|
+
parsed.pathname = rewrittenPath;
|
|
7018
|
+
return parsed.toString();
|
|
7019
|
+
} catch (_err) {
|
|
7020
|
+
return raw;
|
|
7021
|
+
}
|
|
7022
|
+
}
|
|
7023
|
+
return applyLabgateUiBasePath(raw);
|
|
7024
|
+
}
|
|
7025
|
+
|
|
7026
|
+
function buildLabgateWebSocketUrl(pathWithQuery) {
|
|
7027
|
+
var resolved = resolveLabgateUiUrl(pathWithQuery);
|
|
7028
|
+
var wsUrl = new URL(resolved, window.location.origin);
|
|
7029
|
+
wsUrl.protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
7030
|
+
return wsUrl.toString();
|
|
7031
|
+
}
|
|
7032
|
+
|
|
7033
|
+
if (typeof window.fetch === 'function') {
|
|
7034
|
+
var nativeFetch = window.fetch.bind(window);
|
|
7035
|
+
window.fetch = function(input, init) {
|
|
7036
|
+
if (typeof input === 'string') {
|
|
7037
|
+
return nativeFetch(resolveLabgateUiUrl(input), init);
|
|
7038
|
+
}
|
|
7039
|
+
if (typeof URL !== 'undefined' && input instanceof URL) {
|
|
7040
|
+
return nativeFetch(new URL(resolveLabgateUiUrl(String(input))), init);
|
|
7041
|
+
}
|
|
7042
|
+
if (typeof Request !== 'undefined' && input instanceof Request) {
|
|
7043
|
+
var resolvedUrl = resolveLabgateUiUrl(input.url);
|
|
7044
|
+
if (resolvedUrl !== input.url) {
|
|
7045
|
+
return nativeFetch(new Request(resolvedUrl, input), init);
|
|
7046
|
+
}
|
|
7047
|
+
}
|
|
7048
|
+
return nativeFetch(input, init);
|
|
7049
|
+
};
|
|
7050
|
+
}
|
|
7051
|
+
|
|
6969
7052
|
function getCachedClaudeEmail() {
|
|
6970
7053
|
try {
|
|
6971
7054
|
return (localStorage.getItem(CLAUDE_EMAIL_CACHE_KEY) || '').trim();
|
|
@@ -7687,8 +7770,8 @@ function renderImageWidget(data, container) {
|
|
|
7687
7770
|
return;
|
|
7688
7771
|
}
|
|
7689
7772
|
var img = document.createElement('img');
|
|
7690
|
-
img.src = '/api/display/file?path=' + encodeURIComponent(path)
|
|
7691
|
-
+ '&writeToken=' + encodeURIComponent(window.LABGATE_WRITE_TOKEN || '');
|
|
7773
|
+
img.src = resolveLabgateUiUrl('/api/display/file?path=' + encodeURIComponent(path)
|
|
7774
|
+
+ '&writeToken=' + encodeURIComponent(window.LABGATE_WRITE_TOKEN || ''));
|
|
7692
7775
|
img.alt = data.alt || '';
|
|
7693
7776
|
img.style.maxWidth = '100%';
|
|
7694
7777
|
img.style.borderRadius = '6px';
|
|
@@ -7718,8 +7801,8 @@ function renderPdfWidget(data, container, opts) {
|
|
|
7718
7801
|
pdfDiv.className = 'widget-pdf';
|
|
7719
7802
|
container.appendChild(pdfDiv);
|
|
7720
7803
|
|
|
7721
|
-
var pdfUrl = '/api/display/file?path=' + encodeURIComponent(path)
|
|
7722
|
-
+ '&writeToken=' + encodeURIComponent(window.LABGATE_WRITE_TOKEN || '');
|
|
7804
|
+
var pdfUrl = resolveLabgateUiUrl('/api/display/file?path=' + encodeURIComponent(path)
|
|
7805
|
+
+ '&writeToken=' + encodeURIComponent(window.LABGATE_WRITE_TOKEN || ''));
|
|
7723
7806
|
|
|
7724
7807
|
// Use browser's built-in PDF viewer via iframe — zero dependencies, works everywhere
|
|
7725
7808
|
var iframe = document.createElement('iframe');
|
|
@@ -7877,8 +7960,8 @@ function renderMoleculeWidget(data, container, opts) {
|
|
|
7877
7960
|
if (pdbId) {
|
|
7878
7961
|
viewer.loadPdb(pdbId.toUpperCase());
|
|
7879
7962
|
} else if (path) {
|
|
7880
|
-
var fileUrl = '/api/display/file?path=' + encodeURIComponent(path)
|
|
7881
|
-
+ '&writeToken=' + encodeURIComponent(window.LABGATE_WRITE_TOKEN || '');
|
|
7963
|
+
var fileUrl = resolveLabgateUiUrl('/api/display/file?path=' + encodeURIComponent(path)
|
|
7964
|
+
+ '&writeToken=' + encodeURIComponent(window.LABGATE_WRITE_TOKEN || ''));
|
|
7882
7965
|
viewer.loadStructureFromUrl(fileUrl, 'pdb');
|
|
7883
7966
|
} else if (pdbData) {
|
|
7884
7967
|
viewer.loadStructureFromData(pdbData, 'pdb');
|
|
@@ -7954,8 +8037,8 @@ function renderFilePreviewWidget(data, container) {
|
|
|
7954
8037
|
|
|
7955
8038
|
container.innerHTML = '<div class="widget-placeholder">Loading file preview...</div>';
|
|
7956
8039
|
|
|
7957
|
-
var url = '/api/display/file?path=' + encodeURIComponent(path)
|
|
7958
|
-
+ '&writeToken=' + encodeURIComponent(window.LABGATE_WRITE_TOKEN || '');
|
|
8040
|
+
var url = resolveLabgateUiUrl('/api/display/file?path=' + encodeURIComponent(path)
|
|
8041
|
+
+ '&writeToken=' + encodeURIComponent(window.LABGATE_WRITE_TOKEN || ''));
|
|
7959
8042
|
|
|
7960
8043
|
fetch(url)
|
|
7961
8044
|
.then(function(resp) {
|
|
@@ -8222,7 +8305,7 @@ function renderTracksWidget(data, container, opts) {
|
|
|
8222
8305
|
tracksDiv.innerHTML = '';
|
|
8223
8306
|
var processedTracks = trackList.map(function(t) {
|
|
8224
8307
|
var track = Object.assign({}, t);
|
|
8225
|
-
if (track.path && !track.url) { track.url = '/api/display/file?path=' + encodeURIComponent(track.path) + '&writeToken=' + encodeURIComponent(window.LABGATE_WRITE_TOKEN || ''); delete track.path; }
|
|
8308
|
+
if (track.path && !track.url) { track.url = resolveLabgateUiUrl('/api/display/file?path=' + encodeURIComponent(track.path) + '&writeToken=' + encodeURIComponent(window.LABGATE_WRITE_TOKEN || '')); delete track.path; }
|
|
8226
8309
|
if (!track.type) track.type = 'annotation';
|
|
8227
8310
|
if (!track.displayMode) track.displayMode = 'EXPANDED';
|
|
8228
8311
|
return track;
|
|
@@ -8381,10 +8464,9 @@ function submitClaudeHeadlessPrompt(promptText) {
|
|
|
8381
8464
|
webTerm.headlessRunning = true;
|
|
8382
8465
|
updateTerminalInputAvailability();
|
|
8383
8466
|
|
|
8384
|
-
var
|
|
8385
|
-
var wsUrl = proto + '//' + location.host
|
|
8386
|
-
+ '/api/claude/ws?id=' + encodeURIComponent(sessionId)
|
|
8467
|
+
var wsPath = '/api/claude/ws?id=' + encodeURIComponent(sessionId)
|
|
8387
8468
|
+ '&writeToken=' + encodeURIComponent(LABGATE_WRITE_TOKEN);
|
|
8469
|
+
var wsUrl = buildLabgateWebSocketUrl(wsPath);
|
|
8388
8470
|
var socket = new WebSocket(wsUrl);
|
|
8389
8471
|
webTerm.headlessSocket = socket;
|
|
8390
8472
|
|
|
@@ -9530,15 +9612,14 @@ function openWebTerminalSocket(id, opts) {
|
|
|
9530
9612
|
var afterSeq = Number.isFinite(options.afterSeq) ? Math.max(0, Math.floor(options.afterSeq)) : null;
|
|
9531
9613
|
var disableLegacyReplay = !!options.disableLegacyReplay;
|
|
9532
9614
|
var attachNonce = String(options.attachNonce || '');
|
|
9533
|
-
var
|
|
9534
|
-
var wsUrl = proto + '//' + location.host
|
|
9535
|
-
+ '/api/terminal/ws?id=' + encodeURIComponent(id)
|
|
9615
|
+
var wsPath = '/api/terminal/ws?id=' + encodeURIComponent(id)
|
|
9536
9616
|
+ '&writeToken=' + encodeURIComponent(LABGATE_WRITE_TOKEN);
|
|
9537
9617
|
if (afterSeq !== null) {
|
|
9538
|
-
|
|
9618
|
+
wsPath += '&afterSeq=' + encodeURIComponent(String(afterSeq));
|
|
9539
9619
|
} else if (disableLegacyReplay) {
|
|
9540
|
-
|
|
9620
|
+
wsPath += '&replay=0';
|
|
9541
9621
|
}
|
|
9622
|
+
var wsUrl = buildLabgateWebSocketUrl(wsPath);
|
|
9542
9623
|
|
|
9543
9624
|
var socket = new WebSocket(wsUrl);
|
|
9544
9625
|
webTerm.socket = socket;
|
|
@@ -15193,7 +15274,7 @@ function handleResultsChangedEvent() {
|
|
|
15193
15274
|
function connectSSE() {
|
|
15194
15275
|
if (evtSource) return;
|
|
15195
15276
|
try {
|
|
15196
|
-
evtSource = new EventSource('/api/events');
|
|
15277
|
+
evtSource = new EventSource(resolveLabgateUiUrl('/api/events'));
|
|
15197
15278
|
evtSource.addEventListener('sessions', function(e) {
|
|
15198
15279
|
try {
|
|
15199
15280
|
var d = JSON.parse(e.data);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "labgate",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.36",
|
|
4
4
|
"description": "Secure HPC wrapper for AI coding agents (Claude-first): policy controls, Apptainer sandboxes, and SLURM workflows — https://labgate.dev",
|
|
5
5
|
"homepage": "https://labgate.dev",
|
|
6
6
|
"keywords": [
|