diff --git a/CLAUDE.md b/CLAUDE.md
index 9090721..7e84ec6 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -30,7 +30,11 @@ cli.ts CLI entry (commander). Detects jj/git, builds DiffArgs
starts the API server, spawns Vite in --dev mode.
server/
main.ts Hono server. GET /api/diff; POST/DELETE /api/viewed;
- POST/DELETE /api/comment; serves dist/web statics.
+ POST/DELETE /api/comment; GET/POST /api/theme;
+ GET /api/theme.js (pre-first-paint theme boot script
+ loaded by index.html); serves dist/web statics.
+ settings.ts Global (not per-repo) UI settings — currently just the
+ theme — in ~/.local/share/skepsis/settings.json.
diff.ts Runs `jj diff --git`/`git diff`, extracts per-file blob
hashes from index lines.
viewed.ts Viewed state, content-addressed by git blob ID — files
diff --git a/index.html b/index.html
index 38379e7..57ea737 100644
--- a/index.html
+++ b/index.html
@@ -12,6 +12,11 @@
skepsis
+
+
diff --git a/server/main.ts b/server/main.ts
index dbe1295..36613ac 100644
--- a/server/main.ts
+++ b/server/main.ts
@@ -19,6 +19,7 @@ import { getFileContents } from './fileContents.ts'
import { loadViewed, markViewed, unmarkViewed, unmarkViewedAll } from './viewed.ts'
import { insertComment, removeComment } from './comment.ts'
import { getCommentSyntaxes } from './commentSyntax.ts'
+import { loadTheme, saveTheme, themeBootScript } from './settings.ts'
import {
viewedRequestSchema,
viewedDeleteSchema,
@@ -26,12 +27,14 @@ import {
commentRequestSchema,
commentDeleteSchema,
fileContentsQuerySchema,
+ themeRequestSchema,
} from '../shared/types.ts'
import type {
DiffResponse,
FileContentsResponse,
OkResponse,
ErrorResponse,
+ ThemeResponse,
} from '../shared/types.ts'
export async function startServer(opts: {
@@ -99,6 +102,24 @@ export async function startServer(opts: {
return c.json({ ok: true } satisfies OkResponse)
})
+ app.get('/api/theme', async (c) => {
+ return c.json({ theme: await loadTheme() } satisfies ThemeResponse)
+ })
+
+ // Loaded by a render-blocking