ai-or-die 0.1.24 → 0.1.26
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/.github/workflows/ci.yml +1 -0
- package/docs/README.md +14 -0
- package/docs/history/file-browser-bugs.md +111 -0
- package/docs/specs/client-app.md +12 -2
- package/package.json +1 -1
- package/scripts/build-sea.js +2 -7
- package/src/public/app.js +5 -6
- package/src/public/fonts/MesloLGSNerdFont-Bold.woff2 +0 -0
- package/src/public/fonts/MesloLGSNerdFont-BoldItalic.woff2 +0 -0
- package/src/public/fonts/MesloLGSNerdFont-Italic.woff2 +0 -0
- package/src/public/fonts/MesloLGSNerdFont-Regular.woff2 +0 -0
- package/src/public/fonts.css +58 -0
- package/src/public/index.html +4 -3
- package/src/public/service-worker.js +3 -1
- package/src/public/splits.js +3 -1
- package/src/public/tokens.css +1 -1
- package/src/server.js +2 -1
package/.github/workflows/ci.yml
CHANGED
package/docs/README.md
CHANGED
|
@@ -16,6 +16,9 @@ Central documentation for the ai-or-die project -- a Node.js web application tha
|
|
|
16
16
|
- [Authentication](specs/authentication.md)
|
|
17
17
|
- [Client Application](specs/client-app.md)
|
|
18
18
|
- [Usage Analytics](specs/usage-analytics.md)
|
|
19
|
+
- [Image Paste](specs/image-paste.md)
|
|
20
|
+
- [File Browser](specs/file-browser.md)
|
|
21
|
+
- [E2E Testing](specs/e2e-testing.md)
|
|
19
22
|
|
|
20
23
|
## Architecture Decision Records
|
|
21
24
|
|
|
@@ -24,6 +27,11 @@ Central documentation for the ai-or-die project -- a Node.js web application tha
|
|
|
24
27
|
- [ADR-0002: DevTunnels over ngrok](adrs/0002-devtunnels-over-ngrok.md)
|
|
25
28
|
- [ADR-0003: Multi-Tool Architecture](adrs/0003-multi-tool-architecture.md)
|
|
26
29
|
- [ADR-0004: Cross-Platform Support](adrs/0004-cross-platform-support.md)
|
|
30
|
+
- [ADR-0005: Single Binary Distribution](adrs/0005-single-binary-distribution.md)
|
|
31
|
+
- [ADR-0006: Test-Driven Bug Fixes](adrs/0006-test-driven-bug-fixes.md)
|
|
32
|
+
- [ADR-0007: Design Token System](adrs/0007-design-token-system.md)
|
|
33
|
+
- [ADR-0008: E2E Parallelization](adrs/0008-e2e-parallelization.md)
|
|
34
|
+
- [ADR-0008: File Browser Architecture](adrs/0008-file-browser-architecture.md)
|
|
27
35
|
|
|
28
36
|
## Agent Instructions
|
|
29
37
|
|
|
@@ -31,7 +39,13 @@ Central documentation for the ai-or-die project -- a Node.js web application tha
|
|
|
31
39
|
- [Research & Web](agent-instructions/01-research-and-web.md)
|
|
32
40
|
- [Testing & Validation](agent-instructions/02-testing-and-validation.md)
|
|
33
41
|
- [Tooling & Pipelines](agent-instructions/03-tooling-and-pipelines.md)
|
|
42
|
+
- [Handoff Protocol](agent-instructions/04-handoff-protocol.md)
|
|
43
|
+
- [Defensive Coding](agent-instructions/05-defensive-coding.md)
|
|
44
|
+
- [CI-First Testing](agent-instructions/06-ci-first-testing.md)
|
|
45
|
+
- [Documentation Hygiene](agent-instructions/07-docs-hygiene.md)
|
|
46
|
+
- [Multi-Agent Consultation](agent-instructions/08-multi-agent-consultation.md)
|
|
34
47
|
|
|
35
48
|
## History
|
|
36
49
|
|
|
37
50
|
- [Changelog](history/README.md)
|
|
51
|
+
- [File Browser Bugs](history/file-browser-bugs.md)
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# File Browser: Bugs Found During CI (2026-02-07)
|
|
2
|
+
|
|
3
|
+
9 bugs caught during file browser implementation — 4 by E2E tests on GitHub runners, 3 by UX reviewer subagent, 2 by architect reviewer subagent. All were real code bugs, not test bugs.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Panel z-index below terminal overlay
|
|
8
|
+
|
|
9
|
+
**What Happened:** E2E tests on CI could not click file browser panel items. Playwright reported the terminal overlay (`#overlay`, z-index 5000) was intercepting pointer events.
|
|
10
|
+
|
|
11
|
+
**Root Cause:** The file browser panel used `z-index: var(--z-sticky)` (1100), which is below the terminal overlay at 5000. The overlay briefly appears during connection setup.
|
|
12
|
+
|
|
13
|
+
**Fix:** Set panel z-index to 5001 (above overlay).
|
|
14
|
+
|
|
15
|
+
**Watch For:** Any new panel or modal must check its z-index against the terminal overlay (5000) and the existing z-index scale in `tokens.css`.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 2. Panel missing tabindex for keyboard focus
|
|
20
|
+
|
|
21
|
+
**What Happened:** E2E Escape key test failed — pressing Escape did not close the panel.
|
|
22
|
+
|
|
23
|
+
**Root Cause:** The panel `<div>` had no `tabindex` attribute. Without it, `element.focus()` has no effect and `keydown` events never fire on the element.
|
|
24
|
+
|
|
25
|
+
**Fix:** Added `tabindex="-1"` to the panel div.
|
|
26
|
+
|
|
27
|
+
**Watch For:** Any container that needs to receive keyboard focus must have `tabindex="-1"`. This includes modals, panels, dialogs, and any div with a `keydown` listener.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 3. No document-level Escape fallback
|
|
32
|
+
|
|
33
|
+
**What Happened:** Even with tabindex fix, Escape was unreliable when focus was elsewhere (e.g., terminal, body).
|
|
34
|
+
|
|
35
|
+
**Root Cause:** The panel's `keydown` listener only fires when the panel or a child has focus. If the user clicks elsewhere, Escape goes to the focused element, not the panel.
|
|
36
|
+
|
|
37
|
+
**Fix:** Added a `document.addEventListener('keydown', ...)` fallback that checks `if (panel._open && e.key === 'Escape')`.
|
|
38
|
+
|
|
39
|
+
**Watch For:** Keyboard shortcuts that should work globally need document-level listeners, not just component-level ones. Panel-level handlers are for internal keyboard navigation; document-level handlers are for global shortcuts.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 4. Status bar "Saving..." never visible
|
|
44
|
+
|
|
45
|
+
**What Happened:** UX reviewer found that during saves, the status bar showed "Editing" instead of "Saving...".
|
|
46
|
+
|
|
47
|
+
**Root Cause:** The ternary in `_updateCursorPosition` was `this._dirty ? 'Editing' : (this._saving ? 'Saving...' : 'Ready')`. Since `_dirty` is true during the save (cleared on success), the `_saving` branch was never reached.
|
|
48
|
+
|
|
49
|
+
**Fix:** Swapped to `this._saving ? 'Saving...' : (this._dirty ? 'Editing' : 'Ready')`.
|
|
50
|
+
|
|
51
|
+
**Watch For:** When multiple boolean flags control display state, check the evaluation order. The most important/transient state should be checked first.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 5. Escape double-fire between panel and Ace Editor
|
|
56
|
+
|
|
57
|
+
**What Happened:** UX reviewer found that pressing Escape while Ace's search bar was open would close both the search bar AND the editor simultaneously.
|
|
58
|
+
|
|
59
|
+
**Root Cause:** Ace's Escape command closes its search bar, but the DOM event still propagates to the panel's `keydown` handler, which then calls `editorPanel.close()`.
|
|
60
|
+
|
|
61
|
+
**Fix:** Panel-level handler now returns early when `_currentView === 'editor'` (delegates to Ace). Document-level fallback checks for visible `.ace_search` before closing.
|
|
62
|
+
|
|
63
|
+
**Watch For:** When embedding a third-party editor (Ace, Monaco, CodeMirror), its keyboard handling operates independently of DOM event propagation. The outer container must check whether the editor consumed the event before acting.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 6. Screen reader announcements defined but never called
|
|
68
|
+
|
|
69
|
+
**What Happened:** UX reviewer found `FileEditorPanel._announceToScreenReader()` was defined at line 523 but never invoked anywhere in the file.
|
|
70
|
+
|
|
71
|
+
**Root Cause:** The method was written but calls were not added at the key state transitions (save start, save success, save failure, conflict detected).
|
|
72
|
+
|
|
73
|
+
**Fix:** Added `_announceToScreenReader()` calls at 4 points: save start ("Saving"), save success ("File saved"), save failure ("Save failed"), conflict ("File was modified externally").
|
|
74
|
+
|
|
75
|
+
**Watch For:** Any method that updates visual status should also announce to screen readers. Add a grep check: every status-changing method should have a corresponding `_announceToScreenReader` call.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 7. CSS/JS class name mismatch (30+ selectors)
|
|
80
|
+
|
|
81
|
+
**What Happened:** Architect reviewer found the entire panel rendered unstyled because CSS and JS used different naming conventions.
|
|
82
|
+
|
|
83
|
+
**Root Cause:** `file-browser.css` was written by one subagent using `file-browser-*` prefix, while `file-browser.js` was written by another subagent using `fb-*` prefix. Neither checked the other's naming convention.
|
|
84
|
+
|
|
85
|
+
**Fix:** Rewrote CSS to use `fb-*` prefix matching the JS, and added ~30 missing selectors.
|
|
86
|
+
|
|
87
|
+
**Watch For:** When CSS and JS are written by different agents (or in parallel), establish the naming convention upfront. Add a pre-merge check: grep all `className` assignments in JS and verify each has a corresponding CSS selector.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## 8. _showConflictDialog silently drops parameter
|
|
92
|
+
|
|
93
|
+
**What Happened:** Architect reviewer found that the 409 conflict response data (containing `currentHash`) was passed to `_showConflictDialog(d)` but the method signature was `function ()` with no parameter.
|
|
94
|
+
|
|
95
|
+
**Root Cause:** The function signature omitted the parameter. JavaScript doesn't error on extra arguments, so the data was silently discarded.
|
|
96
|
+
|
|
97
|
+
**Fix:** Added `conflictData` parameter and used `conflictData.currentHash` to store the server's hash.
|
|
98
|
+
|
|
99
|
+
**Watch For:** When a function is called with arguments, verify the callee's signature accepts them. This is easy to miss in vanilla JS without TypeScript.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## 9. Search bar CSS display:none vs JS style.display conflict
|
|
104
|
+
|
|
105
|
+
**What Happened:** E2E search filter test failed — the search input was "hidden" despite JS toggling its display.
|
|
106
|
+
|
|
107
|
+
**Root Cause:** CSS had `.fb-search-bar { display: none; }` and `.fb-search-bar.visible { display: block; }`. But JS was using `element.style.display = ''` (empty string) to show it. When inline `style.display` is empty, the CSS `display: none` rule takes precedence, so the element stays hidden.
|
|
108
|
+
|
|
109
|
+
**Fix:** Changed JS to use `classList.add('visible')` / `classList.remove('visible')` instead of inline style.
|
|
110
|
+
|
|
111
|
+
**Watch For:** Never mix CSS class-based visibility (`display: none` in stylesheet) with inline `style.display` toggling. Pick one mechanism. CSS classes are preferred because they keep styling in CSS.
|
package/docs/specs/client-app.md
CHANGED
|
@@ -13,7 +13,7 @@ The frontend is a single-page application served from `src/public/`. It runs ent
|
|
|
13
13
|
| xterm-addon-web-links | 0.9.0 | unpkg CDN | Clickable URLs in terminal output |
|
|
14
14
|
| xterm-addon-unicode11 | 0.6.0 | unpkg CDN | Unicode 11 character width support for Nerd Font / powerline glyphs |
|
|
15
15
|
| JetBrains Mono | -- | Google Fonts | Monospace font for terminal (fallback) |
|
|
16
|
-
| MesloLGS Nerd Font |
|
|
16
|
+
| MesloLGS Nerd Font | v3.3.0 | Self-hosted WOFF2 + jsDelivr CDN fallback | Primary terminal font with Nerd Font glyphs |
|
|
17
17
|
| Inter | -- | Google Fonts | UI font for headers, tabs, controls |
|
|
18
18
|
| clipboard-handler.js | -- | Local | Keyboard shortcuts (Ctrl+C/V) and clipboard utility functions |
|
|
19
19
|
|
|
@@ -119,7 +119,7 @@ The main application controller. Instantiated once on page load.
|
|
|
119
119
|
cursor: '#f0f6fc',
|
|
120
120
|
// Full 16-color ANSI palette configured
|
|
121
121
|
},
|
|
122
|
-
fontFamily: "reads from CSS --font-mono token; defaults to 'MesloLGS Nerd Font', 'JetBrains Mono', monospace",
|
|
122
|
+
fontFamily: "reads from CSS --font-mono token; defaults to 'MesloLGS Nerd Font', 'MesloLGS NF', 'JetBrains Mono', monospace",
|
|
123
123
|
fontSize: 14, // 13 on mobile
|
|
124
124
|
lineHeight: 1.2,
|
|
125
125
|
scrollback: 10000,
|
|
@@ -129,6 +129,16 @@ The main application controller. Instantiated once on page load.
|
|
|
129
129
|
|
|
130
130
|
The terminal auto-resizes via `FitAddon` triggered by a `ResizeObserver` on the terminal container, debounced to prevent excessive resize messages.
|
|
131
131
|
|
|
132
|
+
### Font Loading Strategy
|
|
133
|
+
|
|
134
|
+
Font declarations live in `src/public/fonts.css` with a three-tier source strategy:
|
|
135
|
+
|
|
136
|
+
1. **`local()`** — user's installed font (supports both Nerd Fonts v2 "MesloLGS NF" and v3 "MesloLGS Nerd Font" naming)
|
|
137
|
+
2. **Self-hosted WOFF2** — `src/public/fonts/MesloLGSNerdFont-*.woff2` (4 variants: Regular, Bold, Italic, BoldItalic)
|
|
138
|
+
3. **CDN fallback** — jsDelivr CDN pinned to `mshaugh/nerdfont-webfonts@v3.3.0`
|
|
139
|
+
|
|
140
|
+
The Regular weight is preloaded via `<link rel="preload">` for fast availability. After all fonts settle (`document.fonts.ready`), the terminal is refreshed to re-render with the correct glyphs.
|
|
141
|
+
|
|
132
142
|
### Folder Browser
|
|
133
143
|
|
|
134
144
|
A modal dialog for selecting working directories:
|
package/package.json
CHANGED
package/scripts/build-sea.js
CHANGED
|
@@ -56,14 +56,9 @@ async function bundle() {
|
|
|
56
56
|
function collectAssets() {
|
|
57
57
|
const assets = {};
|
|
58
58
|
|
|
59
|
-
// Static web assets
|
|
59
|
+
// Static web assets (recursive to include fonts/ and components/ subdirectories)
|
|
60
60
|
const publicDir = path.join(ROOT, 'src', 'public');
|
|
61
|
-
|
|
62
|
-
const fullPath = path.join(publicDir, file);
|
|
63
|
-
if (fs.statSync(fullPath).isFile()) {
|
|
64
|
-
assets[`public/${file}`] = fullPath;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
61
|
+
collectFilesRecursive(publicDir, 'public', assets);
|
|
67
62
|
|
|
68
63
|
// Platform-specific native addon files
|
|
69
64
|
const ptyPkgName = `node-pty-${PLATFORM}-${ARCH}`;
|
package/src/public/app.js
CHANGED
|
@@ -364,14 +364,13 @@ class ClaudeCodeWebInterface {
|
|
|
364
364
|
this.terminal.open(document.getElementById('terminal'));
|
|
365
365
|
this.fitTerminal();
|
|
366
366
|
|
|
367
|
-
// Re-render terminal when
|
|
368
|
-
if (document.fonts
|
|
369
|
-
document.fonts.
|
|
367
|
+
// Re-render terminal when fonts finish loading
|
|
368
|
+
if (document.fonts) {
|
|
369
|
+
document.fonts.ready.then(() => {
|
|
370
|
+
const loaded = document.fonts.check('14px "MesloLGS Nerd Font"');
|
|
371
|
+
console.log(loaded ? '[Font] MesloLGS Nerd Font loaded' : '[Font] Using fallback font');
|
|
370
372
|
this.terminal.refresh(0, this.terminal.rows - 1);
|
|
371
373
|
this.fitTerminal();
|
|
372
|
-
}).catch(() => {
|
|
373
|
-
// Font not available — still refresh in case fallback font loaded late
|
|
374
|
-
this.terminal.refresh(0, this.terminal.rows - 1);
|
|
375
374
|
});
|
|
376
375
|
}
|
|
377
376
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/* ============================================================
|
|
2
|
+
Nerd Font Loading — MesloLGS Nerd Font
|
|
3
|
+
Three-tier source: local install > self-hosted WOFF2 > CDN WOFF2
|
|
4
|
+
CDN pinned to v3.3.0 for reproducibility.
|
|
5
|
+
============================================================ */
|
|
6
|
+
|
|
7
|
+
@font-face {
|
|
8
|
+
font-family: 'MesloLGS Nerd Font';
|
|
9
|
+
font-style: normal;
|
|
10
|
+
font-weight: 400;
|
|
11
|
+
font-stretch: normal;
|
|
12
|
+
font-display: swap;
|
|
13
|
+
src: local('MesloLGS Nerd Font'),
|
|
14
|
+
local('MesloLGS NF'),
|
|
15
|
+
local('MesloLGSNerdFont-Regular'),
|
|
16
|
+
local('MesloLGS Nerd Font Regular'),
|
|
17
|
+
url('fonts/MesloLGSNerdFont-Regular.woff2') format('woff2'),
|
|
18
|
+
url('https://cdn.jsdelivr.net/gh/mshaugh/nerdfont-webfonts@v3.3.0/build/fonts/MesloLGSNerdFont-Regular.woff2') format('woff2');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@font-face {
|
|
22
|
+
font-family: 'MesloLGS Nerd Font';
|
|
23
|
+
font-style: italic;
|
|
24
|
+
font-weight: 400;
|
|
25
|
+
font-stretch: normal;
|
|
26
|
+
font-display: swap;
|
|
27
|
+
src: local('MesloLGS Nerd Font Italic'),
|
|
28
|
+
local('MesloLGS NF Italic'),
|
|
29
|
+
local('MesloLGSNerdFont-Italic'),
|
|
30
|
+
url('fonts/MesloLGSNerdFont-Italic.woff2') format('woff2'),
|
|
31
|
+
url('https://cdn.jsdelivr.net/gh/mshaugh/nerdfont-webfonts@v3.3.0/build/fonts/MesloLGSNerdFont-Italic.woff2') format('woff2');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@font-face {
|
|
35
|
+
font-family: 'MesloLGS Nerd Font';
|
|
36
|
+
font-style: normal;
|
|
37
|
+
font-weight: 700;
|
|
38
|
+
font-stretch: normal;
|
|
39
|
+
font-display: swap;
|
|
40
|
+
src: local('MesloLGS Nerd Font Bold'),
|
|
41
|
+
local('MesloLGS NF Bold'),
|
|
42
|
+
local('MesloLGSNerdFont-Bold'),
|
|
43
|
+
url('fonts/MesloLGSNerdFont-Bold.woff2') format('woff2'),
|
|
44
|
+
url('https://cdn.jsdelivr.net/gh/mshaugh/nerdfont-webfonts@v3.3.0/build/fonts/MesloLGSNerdFont-Bold.woff2') format('woff2');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@font-face {
|
|
48
|
+
font-family: 'MesloLGS Nerd Font';
|
|
49
|
+
font-style: italic;
|
|
50
|
+
font-weight: 700;
|
|
51
|
+
font-stretch: normal;
|
|
52
|
+
font-display: swap;
|
|
53
|
+
src: local('MesloLGS Nerd Font Bold Italic'),
|
|
54
|
+
local('MesloLGS NF Bold Italic'),
|
|
55
|
+
local('MesloLGSNerdFont-BoldItalic'),
|
|
56
|
+
url('fonts/MesloLGSNerdFont-BoldItalic.woff2') format('woff2'),
|
|
57
|
+
url('https://cdn.jsdelivr.net/gh/mshaugh/nerdfont-webfonts@v3.3.0/build/fonts/MesloLGSNerdFont-BoldItalic.woff2') format('woff2');
|
|
58
|
+
}
|
package/src/public/index.html
CHANGED
|
@@ -39,6 +39,8 @@
|
|
|
39
39
|
} catch (_) { /* ignore */ }
|
|
40
40
|
})();
|
|
41
41
|
</script>
|
|
42
|
+
<link rel="preload" href="fonts/MesloLGSNerdFont-Regular.woff2" as="font" type="font/woff2" crossorigin>
|
|
43
|
+
<link rel="stylesheet" href="fonts.css">
|
|
42
44
|
<link rel="stylesheet" href="tokens.css">
|
|
43
45
|
<link rel="stylesheet" href="base.css">
|
|
44
46
|
<link rel="stylesheet" href="components/tabs.css">
|
|
@@ -53,9 +55,8 @@
|
|
|
53
55
|
<link rel="stylesheet" href="style.css">
|
|
54
56
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
55
57
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
58
|
+
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
|
|
56
59
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
|
|
57
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/mshaugh/nerdfont-webfonts@latest/build/meslo-nerd-font.css" media="print" onload="this.media='all'">
|
|
58
|
-
<noscript><link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/mshaugh/nerdfont-webfonts@latest/build/meslo-nerd-font.css"></noscript>
|
|
59
60
|
<script src="https://unpkg.com/xterm@5.3.0/lib/xterm.js"></script>
|
|
60
61
|
<script src="https://unpkg.com/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.js"></script>
|
|
61
62
|
<script src="https://unpkg.com/xterm-addon-web-links@0.9.0/lib/xterm-addon-web-links.js"></script>
|
|
@@ -236,7 +237,7 @@
|
|
|
236
237
|
<div class="setting-group">
|
|
237
238
|
<label for="fontFamily">Font:</label>
|
|
238
239
|
<select id="fontFamily">
|
|
239
|
-
<option value="'MesloLGS Nerd Font', 'Meslo Nerd Font', monospace">Meslo Nerd Font</option>
|
|
240
|
+
<option value="'MesloLGS Nerd Font', 'MesloLGS NF', 'Meslo Nerd Font', monospace">Meslo Nerd Font</option>
|
|
240
241
|
<option value="'JetBrains Mono', monospace">JetBrains Mono</option>
|
|
241
242
|
<option value="'Fira Code', monospace">Fira Code</option>
|
|
242
243
|
<option value="'Cascadia Code', monospace">Cascadia Code</option>
|
package/src/public/splits.js
CHANGED
|
@@ -33,7 +33,9 @@ class Split {
|
|
|
33
33
|
|
|
34
34
|
// Initialize xterm.js terminal
|
|
35
35
|
this.terminal = new Terminal({
|
|
36
|
-
fontFamily: this.app?.terminal?.options?.fontFamily
|
|
36
|
+
fontFamily: this.app?.terminal?.options?.fontFamily
|
|
37
|
+
|| getComputedStyle(document.documentElement).getPropertyValue('--font-mono').trim()
|
|
38
|
+
|| "'MesloLGS Nerd Font', 'MesloLGS NF', 'JetBrains Mono', monospace",
|
|
37
39
|
fontSize: this.app?.terminal?.options?.fontSize || 14,
|
|
38
40
|
cursorBlink: true,
|
|
39
41
|
convertEol: true,
|
package/src/public/tokens.css
CHANGED
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
|
|
51
51
|
/* --- Typography --- */
|
|
52
52
|
--font-sans: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
|
|
53
|
-
--font-mono: 'MesloLGS Nerd Font', 'Meslo Nerd Font', 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
|
|
53
|
+
--font-mono: 'MesloLGS Nerd Font', 'MesloLGS NF', 'Meslo Nerd Font', 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
|
|
54
54
|
|
|
55
55
|
--text-xs: 0.6875rem; /* 11px */
|
|
56
56
|
--text-sm: 0.75rem; /* 12px */
|
package/src/server.js
CHANGED
|
@@ -995,7 +995,8 @@ class ClaudeCodeWebServer {
|
|
|
995
995
|
'.json': 'application/json',
|
|
996
996
|
'.png': 'image/png',
|
|
997
997
|
'.svg': 'image/svg+xml',
|
|
998
|
-
'.ico': 'image/x-icon'
|
|
998
|
+
'.ico': 'image/x-icon',
|
|
999
|
+
'.woff2': 'font/woff2'
|
|
999
1000
|
};
|
|
1000
1001
|
res.setHeader('Content-Type', mimeTypes[ext] || 'application/octet-stream');
|
|
1001
1002
|
res.send(data);
|