feat(ui): highlight source server-side with a near-monochrome Shiki theme (CG-43)
The viewer's code block stops lexing with a hand-rolled dialect table and reads real TextMate grammars instead, run once in `/api/source`. Three things make that safe to depend on: * Highlighting never fails a request. A missing grammar, an oversized slice, an ESM import that did not resolve — every one of them answers `engine: 'plain'` with a reason and the source still goes out. * Identifiers survive whatever token boundaries a grammar chose. Every code token is split into identifier runs before it goes on the wire, so the graph's call-site overlay claims a token the highlighter produced rather than re-cutting the line. `assignRefs` now matches on a token's text rather than on the class a grammar gave it, so a language that scopes type names as `storage.type` still links. * The theme classifies rather than colours: its foregrounds are sentinels the server maps back to class names, and the viewer paints them from CSS custom properties — one token stream serves light and dark with no refetch, and the ramp lives only in app.css. Comments move from --ink-3 to a new --code-comment. --ink-3 measures 3.46:1 on paper and 3.00:1 on the hot-line tint, both under AA for 12.5px text; --code-comment is the smallest step along the same ramp that clears 4.5:1 on every background a code line can have, and stays quieter than the strings and numbers above it. Shipping: @shikijs/core and @shikijs/engine-javascript are runtime dependencies (no wasm, no native module); @shikijs/langs stays a devDependency and `npm run build:textmate` writes only the closure the engine's 40-odd languages reach — 56 grammars, 2.6 MB, against 11 MB for all 722. check-ui-build.mjs asserts the tree after every build and inside every release archive.
This commit is contained in:
+6
-2
@@ -20,7 +20,7 @@
|
||||
"ui"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc && npm run copy-assets && npm run build:ui && node -e \"require('fs').chmodSync('dist/bin/codegraph.js', 0o755)\"",
|
||||
"build": "tsc && npm run copy-assets && npm run build:textmate && npm run build:ui && node -e \"require('fs').chmodSync('dist/bin/codegraph.js', 0o755)\"",
|
||||
"build:ui": "npm run build --workspace ui && node scripts/check-ui-build.mjs",
|
||||
"preuninstall": "node dist/bin/uninstall.js",
|
||||
"copy-assets": "node -e \"const fs=require('fs');fs.mkdirSync('dist/db',{recursive:true});fs.copyFileSync('src/db/schema.sql','dist/db/schema.sql');fs.mkdirSync('dist/extraction/wasm',{recursive:true});fs.readdirSync('src/extraction/wasm').filter(f=>f.endsWith('.wasm')).forEach(f=>fs.copyFileSync('src/extraction/wasm/'+f,'dist/extraction/wasm/'+f))\"",
|
||||
@@ -31,7 +31,8 @@
|
||||
"test:watch": "vitest",
|
||||
"test:eval": "vitest run __tests__/evaluation/",
|
||||
"eval": "npm run build && npx tsx __tests__/evaluation/runner.ts",
|
||||
"clean": "node -e \"const fs=require('fs');fs.rmSync('dist',{recursive:true,force:true})\""
|
||||
"clean": "node -e \"const fs=require('fs');fs.rmSync('dist',{recursive:true,force:true})\"",
|
||||
"build:textmate": "node scripts/prune-grammars.mjs"
|
||||
},
|
||||
"keywords": [
|
||||
"code-intelligence",
|
||||
@@ -42,6 +43,8 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@clack/prompts": "^1.3.0",
|
||||
"@shikijs/core": "^4.4.3",
|
||||
"@shikijs/engine-javascript": "^4.4.3",
|
||||
"commander": "^14.0.2",
|
||||
"fast-string-width": "^3.0.2",
|
||||
"fast-wrap-ansi": "^0.2.0",
|
||||
@@ -53,6 +56,7 @@
|
||||
"web-tree-sitter": "^0.25.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@shikijs/langs": "^4.4.3",
|
||||
"@types/better-sqlite3": "^7.6.0",
|
||||
"@types/node": "^20.19.30",
|
||||
"@types/picomatch": "^4.0.2",
|
||||
|
||||
Reference in New Issue
Block a user