css-variable-lsp 1.0.7 → 1.0.8
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/.git-blame-ignore-revs +3 -0
- package/.github/workflows/test.yml +27 -0
- package/AGENTS.md +10 -0
- package/LIMITATIONS.md +28 -8
- package/README.md +80 -75
- package/check_node_html_parser.ts +10 -0
- package/out/colorService.js +161 -155
- package/out/colorService.js.map +1 -1
- package/out/cssVariableManager.js +121 -69
- package/out/cssVariableManager.js.map +1 -1
- package/out/domTree.js +2 -9
- package/out/domTree.js.map +1 -1
- package/out/server.js +331 -96
- package/out/server.js.map +1 -1
- package/out/specificity.js +13 -13
- package/out/specificity.js.map +1 -1
- package/package.json +2 -2
- package/tsconfig.test.json +9 -0
- package/CHANGES_SUMMARY.md +0 -221
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ master ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ master ]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
test:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Setup Node
|
|
18
|
+
uses: actions/setup-node@v4
|
|
19
|
+
with:
|
|
20
|
+
node-version: 20
|
|
21
|
+
cache: npm
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: npm ci
|
|
25
|
+
|
|
26
|
+
- name: Run tests
|
|
27
|
+
run: npm test
|
package/AGENTS.md
CHANGED
|
@@ -12,23 +12,27 @@
|
|
|
12
12
|
### Quick Start
|
|
13
13
|
|
|
14
14
|
**Check for ready work:**
|
|
15
|
+
|
|
15
16
|
```bash
|
|
16
17
|
bd ready --json
|
|
17
18
|
```
|
|
18
19
|
|
|
19
20
|
**Create new issues:**
|
|
21
|
+
|
|
20
22
|
```bash
|
|
21
23
|
bd create "Issue title" -t bug|feature|task -p 0-4 --json
|
|
22
24
|
bd create "Issue title" -p 1 --deps discovered-from:bd-123 --json
|
|
23
25
|
```
|
|
24
26
|
|
|
25
27
|
**Claim and update:**
|
|
28
|
+
|
|
26
29
|
```bash
|
|
27
30
|
bd update bd-42 --status in_progress --json
|
|
28
31
|
bd update bd-42 --priority 1 --json
|
|
29
32
|
```
|
|
30
33
|
|
|
31
34
|
**Complete work:**
|
|
35
|
+
|
|
32
36
|
```bash
|
|
33
37
|
bd close bd-42 --reason "Completed" --json
|
|
34
38
|
```
|
|
@@ -62,6 +66,7 @@ bd close bd-42 --reason "Completed" --json
|
|
|
62
66
|
### Auto-Sync
|
|
63
67
|
|
|
64
68
|
bd automatically syncs with git:
|
|
69
|
+
|
|
65
70
|
- Exports to `.beads/issues.jsonl` after changes (5s debounce)
|
|
66
71
|
- Imports from JSONL when newer (e.g., after `git pull`)
|
|
67
72
|
- No manual export/import needed!
|
|
@@ -75,6 +80,7 @@ pip install beads-mcp
|
|
|
75
80
|
```
|
|
76
81
|
|
|
77
82
|
Add to MCP config (e.g., `~/.config/claude/config.json`):
|
|
83
|
+
|
|
78
84
|
```json
|
|
79
85
|
{
|
|
80
86
|
"beads": {
|
|
@@ -89,6 +95,7 @@ Then use `mcp__beads__*` functions instead of CLI commands.
|
|
|
89
95
|
### Managing AI-Generated Planning Documents
|
|
90
96
|
|
|
91
97
|
AI assistants often create planning and design documents during development:
|
|
98
|
+
|
|
92
99
|
- PLAN.md, IMPLEMENTATION.md, ARCHITECTURE.md
|
|
93
100
|
- DESIGN.md, CODEBASE_SUMMARY.md, INTEGRATION_PLAN.md
|
|
94
101
|
- TESTING_GUIDE.md, TECHNICAL_DESIGN.md, and similar files
|
|
@@ -96,18 +103,21 @@ AI assistants often create planning and design documents during development:
|
|
|
96
103
|
**Best Practice: Use a dedicated directory for these ephemeral files**
|
|
97
104
|
|
|
98
105
|
**Recommended approach:**
|
|
106
|
+
|
|
99
107
|
- Create a `history/` directory in the project root
|
|
100
108
|
- Store ALL AI-generated planning/design docs in `history/`
|
|
101
109
|
- Keep the repository root clean and focused on permanent project files
|
|
102
110
|
- Only access `history/` when explicitly asked to review past planning
|
|
103
111
|
|
|
104
112
|
**Example .gitignore entry (optional):**
|
|
113
|
+
|
|
105
114
|
```
|
|
106
115
|
# AI planning documents (ephemeral)
|
|
107
116
|
history/
|
|
108
117
|
```
|
|
109
118
|
|
|
110
119
|
**Benefits:**
|
|
120
|
+
|
|
111
121
|
- ✅ Clean repository root
|
|
112
122
|
- ✅ Clear separation between ephemeral and permanent documentation
|
|
113
123
|
- ✅ Easy to exclude from version control if desired
|
package/LIMITATIONS.md
CHANGED
|
@@ -5,12 +5,14 @@ This document outlines the current limitations of the CSS Variable Language Serv
|
|
|
5
5
|
## ✅ What We DO Handle
|
|
6
6
|
|
|
7
7
|
### Core CSS Cascade Features
|
|
8
|
+
|
|
8
9
|
- **Selector tracking**: Each variable definition tracks its CSS selector (`:root`, `div`, `.class`, etc.)
|
|
9
10
|
- **CSS Specificity**: Full specificity calculation for IDs, classes, pseudo-classes, elements
|
|
10
11
|
- **Usage context detection**: Tracks which selector a `var(--name)` usage appears in
|
|
11
12
|
- **Context-aware hover**: Shows all definitions sorted by specificity with indicator of which applies
|
|
12
13
|
|
|
13
14
|
### Advanced CSS Features ✨
|
|
15
|
+
|
|
14
16
|
- **Source order tracking**: When two selectors have equal specificity, later definitions win
|
|
15
17
|
- **!important support**: `--color: red !important` is tracked and prioritized correctly in cascade
|
|
16
18
|
- **Inline style parsing**: `style="--color: red"` attributes are parsed for variable definitions
|
|
@@ -24,29 +26,38 @@ This document outlines the current limitations of the CSS Variable Language Serv
|
|
|
24
26
|
**This is the key limitation you're asking about!**
|
|
25
27
|
|
|
26
28
|
- **No DOM structure awareness**: We don't know the actual HTML element hierarchy
|
|
29
|
+
|
|
27
30
|
- Example: Can't tell if a `div` is inside another `div` or a `section`
|
|
28
31
|
- Can't resolve parent-child relationships
|
|
29
32
|
|
|
30
33
|
- **No CSS nesting support** (CSS Nesting Module):
|
|
34
|
+
|
|
31
35
|
```css
|
|
32
36
|
.parent {
|
|
33
37
|
--color: red;
|
|
34
38
|
.child {
|
|
35
|
-
--color: blue;
|
|
39
|
+
--color: blue; /* We parse this but don't know it's nested */
|
|
36
40
|
}
|
|
37
41
|
}
|
|
38
42
|
```
|
|
39
43
|
|
|
40
44
|
- **No descendant/combinator resolution**:
|
|
41
45
|
```css
|
|
42
|
-
div .class {
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
div .class {
|
|
47
|
+
--color: blue;
|
|
48
|
+
} /* We see "div .class" but can't match it to usage context */
|
|
49
|
+
div > .class {
|
|
50
|
+
--color: green;
|
|
51
|
+
} /* Same issue */
|
|
52
|
+
.parent .child {
|
|
53
|
+
--color: red;
|
|
54
|
+
} /* We don't know .child is inside .parent */
|
|
45
55
|
```
|
|
46
56
|
|
|
47
57
|
### What This Means
|
|
48
58
|
|
|
49
59
|
Our current implementation:
|
|
60
|
+
|
|
50
61
|
1. ✅ Extracts the selector (e.g., `div`, `.class`)
|
|
51
62
|
2. ✅ Calculates specificity (e.g., `.class` > `div`)
|
|
52
63
|
3. ✅ Shows which would apply based on **exact selector match**
|
|
@@ -58,10 +69,16 @@ Our current implementation:
|
|
|
58
69
|
### Example of Current Limitation
|
|
59
70
|
|
|
60
71
|
```css
|
|
61
|
-
div {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
.inner {
|
|
72
|
+
div {
|
|
73
|
+
--color: red;
|
|
74
|
+
}
|
|
75
|
+
div .inner {
|
|
76
|
+
--color: blue;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.inner {
|
|
80
|
+
color: var(--color);
|
|
81
|
+
} /* Which color applies? */
|
|
65
82
|
```
|
|
66
83
|
|
|
67
84
|
**What we show**: Both `red` and `blue` with specificity scores
|
|
@@ -70,6 +87,7 @@ div .inner { --color: blue; }
|
|
|
70
87
|
### Other Limitations
|
|
71
88
|
|
|
72
89
|
- **Complex selectors**:
|
|
90
|
+
|
|
73
91
|
- Attribute selectors: `[data-attr="value"]` ✅ Parsed, ❌ Not matched
|
|
74
92
|
- Pseudo-classes: `:hover`, `:nth-child()` ✅ Parsed, ❌ Context not resolved
|
|
75
93
|
- Pseudo-elements: `::before`, `::after` ✅ Counted in specificity
|
|
@@ -119,10 +137,12 @@ div .inner { --color: blue; }
|
|
|
119
137
|
**You asked: "Should we also care about nesting?"**
|
|
120
138
|
|
|
121
139
|
**Answer**: YES! Nesting/hierarchy is currently our biggest limitation. We handle:
|
|
140
|
+
|
|
122
141
|
- ✅ Basic selector matching and specificity
|
|
123
142
|
- ❌ NOT actual DOM structure or nested selectors
|
|
124
143
|
|
|
125
144
|
To fully resolve which value applies, we'd need:
|
|
145
|
+
|
|
126
146
|
1. HTML DOM structure analysis
|
|
127
147
|
2. Selector combinator matching
|
|
128
148
|
3. CSS cascade simulation
|
package/README.md
CHANGED
|
@@ -1,111 +1,116 @@
|
|
|
1
1
|
# CSS Variable Language Server
|
|
2
2
|
|
|
3
|
-
A Language Server Protocol (LSP) implementation
|
|
3
|
+
A Language Server Protocol (LSP) implementation focused on CSS custom properties (variables). It indexes variables across your workspace and provides completions, hover resolution, and diagnostics.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **Context-
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
10
|
-
- **Go to
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **Color Decorations**: Shows color boxes next to CSS variables with color values (can be disabled with `--no-color-preview`).
|
|
14
|
-
- **HTML Support**: Parses `<style>` blocks and inline styles in HTML files.
|
|
7
|
+
- **Context-aware completion** in CSS property values, inside `var(...)`, and in HTML `style=""` attributes, with relevance scoring.
|
|
8
|
+
- **Workspace-wide indexing** across `.css`, `.scss`, `.sass`, `.less`, plus HTML `<style>` blocks and inline styles.
|
|
9
|
+
- **Cascade-aware hover** that orders definitions by `!important`, specificity, and source order.
|
|
10
|
+
- **Go to definition**, **find references**, and **rename** support.
|
|
11
|
+
- **Diagnostics** for undefined variables used via `var(--name)`.
|
|
12
|
+
- **Color decorations** and a color picker with hex/rgb/hsl presentations.
|
|
15
13
|
|
|
16
14
|
## Getting Started
|
|
17
15
|
|
|
18
16
|
### Prerequisites
|
|
19
17
|
|
|
20
|
-
-
|
|
21
|
-
-
|
|
18
|
+
- Node.js (ES2020-compatible; v16+ recommended)
|
|
19
|
+
- npm
|
|
22
20
|
|
|
23
|
-
###
|
|
21
|
+
### Install / Build
|
|
24
22
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
```
|
|
23
|
+
```bash
|
|
24
|
+
npm install
|
|
25
|
+
npm run compile
|
|
26
|
+
```
|
|
30
27
|
|
|
31
|
-
###
|
|
28
|
+
### Run
|
|
32
29
|
|
|
33
|
-
|
|
30
|
+
```bash
|
|
31
|
+
# via local build
|
|
32
|
+
node out/server.js --stdio
|
|
34
33
|
|
|
35
|
-
|
|
34
|
+
# or, if installed from npm
|
|
35
|
+
css-variable-lsp --stdio
|
|
36
|
+
```
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
- `--color-only-variables`: Show color boxes only next to CSS variable usages (like `var(--my-color)`), not on raw color value definitions (like `#f0f0f0`). This keeps color boxes only on the CSS variables, making them stand out more clearly.
|
|
38
|
+
### Editor Integration
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
- `CSS_LSP_COLOR_ONLY_VARIABLES=1`: Same as `--color-only-variables` flag.
|
|
40
|
+
This is a standalone LSP server. Configure it in any LSP client.
|
|
42
41
|
|
|
43
|
-
|
|
42
|
+
[VS Code extension](https://marketplace.visualstudio.com/items?itemName=miclmn451.css-variables-vscode)
|
|
44
43
|
|
|
45
|
-
|
|
46
|
-
- `--secondary-color: #f0f0f0` ← Shows color box on `#f0f0f0`
|
|
47
|
-
- `var(--secondary-color)` ← Shows resolved color box
|
|
44
|
+
[Zed extension](https://zed.dev/extensions/css-variables)
|
|
48
45
|
|
|
49
|
-
|
|
50
|
-
- `--secondary-color: #f0f0f0` ← No color box (native editor already shows this)
|
|
51
|
-
- `var(--secondary-color)` ← Shows resolved color box (unique to this extension)
|
|
46
|
+
## Configuration
|
|
52
47
|
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
# Disable all color boxes
|
|
56
|
-
css-variable-lsp --no-color-preview
|
|
48
|
+
Command-line flags:
|
|
57
49
|
|
|
58
|
-
|
|
59
|
-
|
|
50
|
+
- `--no-color-preview`
|
|
51
|
+
- `--color-only-variables` (show colors only on `var(--...)` usages)
|
|
52
|
+
- `--lookup-files "<glob>,<glob>"` (comma-separated list of glob patterns)
|
|
53
|
+
- `--lookup-file "<glob>"` (repeatable)
|
|
54
|
+
- `--path-display=relative|absolute|abbreviated`
|
|
55
|
+
- `--path-display-length=N` (only used for `abbreviated`; `0` disables shortening)
|
|
60
56
|
|
|
61
|
-
|
|
62
|
-
CSS_LSP_COLOR_ONLY_VARIABLES=1 css-variable-lsp
|
|
63
|
-
```
|
|
57
|
+
Environment variables:
|
|
64
58
|
|
|
65
|
-
|
|
59
|
+
- `CSS_LSP_COLOR_ONLY_VARIABLES=1` (same as `--color-only-variables`)
|
|
60
|
+
- `CSS_LSP_LOOKUP_FILES` (comma-separated glob patterns; ignored if CLI lookup flags are provided)
|
|
61
|
+
- `CSS_LSP_DEBUG=1` (enable debug logging)
|
|
62
|
+
- `CSS_LSP_PATH_DISPLAY=relative|absolute|abbreviated`
|
|
63
|
+
- `CSS_LSP_PATH_DISPLAY_LENGTH=1` (same as `--path-display-length`)
|
|
66
64
|
|
|
67
|
-
|
|
65
|
+
Defaults:
|
|
68
66
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
- `--path-display`: `relative`
|
|
68
|
+
- `--path-display-length`: `1`
|
|
69
|
+
- Lookup globs:
|
|
70
|
+
- `**/*.css`
|
|
71
|
+
- `**/*.scss`
|
|
72
|
+
- `**/*.sass`
|
|
73
|
+
- `**/*.less`
|
|
74
|
+
- `**/*.html`
|
|
75
|
+
- `**/*.vue`
|
|
76
|
+
- `**/*.svelte`
|
|
77
|
+
- `**/*.astro`
|
|
78
|
+
- `**/*.ripple`
|
|
79
|
+
- Ignore globs:
|
|
80
|
+
- `**/node_modules/**`
|
|
81
|
+
- `**/dist/**`
|
|
82
|
+
- `**/out/**`
|
|
83
|
+
- `**/.git/**`
|
|
72
84
|
|
|
73
|
-
|
|
74
|
-
cd server
|
|
75
|
-
npm run test:all
|
|
76
|
-
```
|
|
85
|
+
`abbreviated` mode shortens each directory segment (except the final one) to the configured length, matching fish-style prompt shortening. Lookup globs accept standard glob patterns (including brace expansions like `**/*.{css,scss}`) and the default ignore list remains in effect even when lookup globs are provided.
|
|
77
86
|
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
cd server
|
|
81
|
-
npm test # Core functionality tests
|
|
82
|
-
npx ts-node src/easyWins.test.ts # Easy wins features
|
|
83
|
-
```
|
|
87
|
+
### Completion Path Examples
|
|
84
88
|
|
|
85
|
-
|
|
89
|
+
Assume a variable is defined in `/Users/you/project/src/styles/theme.css` and your workspace root is `/Users/you/project`.
|
|
86
90
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
92
|
-
-
|
|
93
|
-
-
|
|
91
|
+
- `--path-display=relative` (default):
|
|
92
|
+
- `Defined in src/styles/theme.css`
|
|
93
|
+
- `--path-display=absolute`:
|
|
94
|
+
- `Defined in /Users/you/project/src/styles/theme.css`
|
|
95
|
+
- `--path-display=abbreviated --path-display-length=1`:
|
|
96
|
+
- `Defined in s/s/theme.css`
|
|
97
|
+
- `--path-display=abbreviated --path-display-length=2`:
|
|
98
|
+
- `Defined in sr/st/theme.css`
|
|
99
|
+
- `--path-display=abbreviated --path-display-length=0` (no shortening):
|
|
100
|
+
- `Defined in src/styles/theme.css`
|
|
94
101
|
|
|
95
|
-
|
|
96
|
-
When you hover over a CSS variable, you'll see:
|
|
97
|
-
```
|
|
98
|
-
### CSS Variable: `--primary-color`
|
|
102
|
+
## Cascade Awareness (Best-Effort)
|
|
99
103
|
|
|
100
|
-
|
|
104
|
+
Hover and color resolution use CSS cascade rules (specificity, `!important`, source order) but do not model DOM nesting or selector combinators. See `LIMITATIONS.md` for details.
|
|
101
105
|
|
|
102
|
-
|
|
103
|
-
2. `blue` from `div` (0,0,1) _(overridden by !important)_
|
|
104
|
-
3. `red` from `:root` (0,1,0) _(lower specificity)_
|
|
106
|
+
## Project Structure
|
|
105
107
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
+
- `src/` TypeScript source
|
|
109
|
+
- `out/` compiled server (npm bin entry)
|
|
110
|
+
- `LIMITATIONS.md` known limitations
|
|
108
111
|
|
|
109
|
-
##
|
|
112
|
+
## Testing
|
|
110
113
|
|
|
111
|
-
|
|
114
|
+
```bash
|
|
115
|
+
npm test
|
|
116
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { parse } from "node-html-parser";
|
|
2
|
+
|
|
3
|
+
const root = parse('<div class="foo bar"></div>');
|
|
4
|
+
const el = root.querySelector("div")!;
|
|
5
|
+
console.log("classList.length:", el.classList.length);
|
|
6
|
+
console.log("classList.value:", el.classList.value);
|
|
7
|
+
console.log("classList.values():", [...el.classList.values()]);
|
|
8
|
+
for (let i = 0; i < el.classList.length; i++) {
|
|
9
|
+
console.log(`classList.value[${i}]:`, el.classList.value[i]);
|
|
10
|
+
}
|