rainbowindex 0.2.1 → 0.3.0

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/CHANGELOG.md CHANGED
@@ -5,6 +5,160 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.3.0] - 2026-08-14
9
+
10
+ ### Added — editor tooling API (phase 2)
11
+
12
+ - **`ClassCandidate.callId`** — helper/safelist candidates now carry the
13
+ identity of the call they were collected from: candidates from the same
14
+ call share one id, distinct calls get distinct ids. This is the grouping
15
+ key merge tooling needs to run `analyzeMerge()` over one `ri(…)` call's
16
+ classes without mixing neighbouring calls. Feature-detect via the new
17
+ `"candidate-call-ids"` entry in `editorCapabilities`.
18
+ - **`ri()` joins the scanned class helpers** — the scanner now walks `ri(…)`
19
+ calls like `clsx`/`cn`/`twMerge`, so their arguments get `helper` origin,
20
+ a helper name, and a call id (previously they were only caught by the
21
+ whole-file literal scan as `plain` candidates). `CLASS_HELPER_NAMES`
22
+ includes `"ri"` accordingly.
23
+ - **Value typos get suggestions** — the class inspector's suggestion corpus
24
+ now includes the enumerated completion universe, so `validate()` suggests
25
+ concrete neighbours for functional-value typos (`bg-blu-500` →
26
+ `bg-blue-500`, `bg-thme-500` → `bg-theme-500`) instead of staying silent.
27
+
28
+ ### Fixed
29
+
30
+ - **`--optimize` CLI flag** — the README documented `--optimize` but the CLI
31
+ rejected it with "Unknown option". It is now accepted as an alias of
32
+ `--minify` (both run the same LightningCSS minification +
33
+ browser-fallback pass).
34
+
35
+ ## [0.2.2] - 2026-08-13
36
+
37
+ ### Added — editor tooling API (phase 1)
38
+
39
+ - **`rainbowindex/editor` entry** — a new IO-free subpath export for editor
40
+ integrations (VS Code and beyond). Pure computation only: no filesystem,
41
+ network, or module-level mutation, so it runs in browser-based editor hosts
42
+ (vscode.dev) as-is. Ships a version handshake (`version`,
43
+ `EDITOR_API_VERSION`, `editorCapabilities`) so extensions can
44
+ feature-detect whatever version the workspace has installed.
45
+ - **`extractClassCandidates()`** — position-aware variant of the source
46
+ scanner. Returns every class candidate with its absolute source span, its
47
+ collection origin (`attribute` / `helper` / `safelist` / `plain`, with the
48
+ helper name when applicable), and — for variant-group members — the span of
49
+ the group prefix plus the member token inside the braces, so editors can
50
+ squiggle and edit individual members of `hover:{…}` groups. The value set
51
+ is guaranteed identical to `extractClassesFromSource()`; build output is
52
+ byte-for-byte unchanged.
53
+ - **CSS entry detection exports** — `CSS_ENTRY_CANDIDATES` (the CLI/Vite
54
+ probe order, now a pure shared module) plus re-exported `hasRIActivation()`
55
+ and `RI_IMPORT_SPECIFIERS`, letting editor hosts locate the project's CSS
56
+ input with their own file access.
57
+ - **Scanner context exports** — `CLASS_HELPER_NAMES` / `VARIANT_HELPER_NAMES`
58
+ so completion-context detection in editors matches the scanner's behavior.
59
+ - **`analyzeProjectCSS()`** — the theme-only front half of `compileProject`
60
+ (CSS input string → `ResolvedTheme` + directives + warnings), now exported
61
+ for editors. No file IO, no font resolution — cheap enough to re-run on
62
+ every CSS-entry change.
63
+ - **`createClassInspector(theme)`** — single-class validation and
64
+ explanation running the exact resolution the compiler performs, giving the
65
+ intentionally-silent RI-1001 a voice in editors. `validate()` reports
66
+ `unknown-utility` / `unknown-variant` / `invalid-arbitrary` with the
67
+ offending fragment and an OSA-distance typo suggestion (`felx` → `flex`,
68
+ including custom `@utility` and `@custom` names); `explain()` returns the
69
+ parsed structure, root declarations, escaped selector, full rule CSS, and
70
+ sort key. Instances cache per-theme state and resolutions, so
71
+ per-keystroke validation is cheap. Guaranteed: `validate(cls).ok` exactly
72
+ when `compile([cls])` emits a rule.
73
+ - **`listVariants(theme)`** — enumerates every concrete variant the theme
74
+ resolves (pseudo-classes, pseudo-elements, media, breakpoints, container
75
+ queries, special selectors, custom `@custom` variants) plus the open-ended
76
+ pattern families (`data-`, `aria-`, `group-`, …), each tagged with a kind
77
+ and what it wraps. Every concrete entry is guaranteed to resolve.
78
+ - **`parseUtility()` / `findClosest()`** — the class parser (structured
79
+ `ParsedUtility`) and the OSA typo suggester, exported for editor use.
80
+ - **`createEditorSession({ css })`** — the façade an editor holds per
81
+ workspace: theme analysis, inspector, enumeration, token introspection,
82
+ merge snapshot, candidate extraction, and swatches behind one object whose
83
+ caches invalidate together on `setCss()`.
84
+ - **Color swatches** — `resolveColorSwatch(theme, name, stop)` resolves a
85
+ theme color to concrete light/dark values using the same OKLCH math as the
86
+ emitted CSS variables (the dark-mirror computation is now shared via
87
+ `computeDarkStop`), plus `oklchToHex`/`cssColorToHex` conversion for
88
+ completion swatches; handles generative palettes, explicit values, hex,
89
+ light/dark pairs, aliases, and the semantic paper/ink colors.
90
+ `listThemeTokens(theme)` returns one render-ready view of every token
91
+ namespace for sidebar chips.
92
+ - **Structured diagnostics with source spans** — `analyzeProjectCSS()` now
93
+ additionally returns `diagnostics`: the same messages as `warnings`, in the
94
+ same order, each with the parsed `RI-NNNN` code, a severity derived from
95
+ the documented code-range convention (0xxx/2xxx → error), and a
96
+ [start, end) span into the CSS input where the emitter knew one. Directive
97
+ parse problems (`RI-1011/1012/1036/1202`) anchor at their exact site;
98
+ resolver problems anchor at the directive whose body produced them (via
99
+ new opt-in attribution in `resolveDirectives`); post-loop validations stay
100
+ unattributed. `Diagnostic`, `severityForCode()`, `warningCode()`, and
101
+ `diagnosticFromWarning()` ship from `rainbowindex/editor` so editors can
102
+ structure any legacy warning stream. The string arrays remain unchanged
103
+ everywhere.
104
+ - **`analyzeMerge(classes, snapshot?)`** — explains `ri()`'s right-most-wins
105
+ conflict resolution for a pre-tokenized class list: the merged `output`,
106
+ which indices survive, and — for every dropped class — the ascending
107
+ indices of the survivors that claimed its properties (joint domination
108
+ like `text-lg` overridden by `[font-size:16px]` + `leading-tight` lists
109
+ both winners). Runs the exact scan `ri()` runs, via an optional trace that
110
+ costs the hot path one falsy check per property. Powers "this class is
111
+ overridden" editor diagnostics.
112
+ - **`createThemeSnapshot(theme)`** — builds a `CompilationSnapshot` straight
113
+ from a resolved theme (custom text sizes, font slots, color names, custom
114
+ utility property claims) without a compile pass, for theme-accurate
115
+ `analyzeMerge()`/`createRi()` in editors. The registration logic is now
116
+ shared with the compile loop (`registerThemeOnContext`).
117
+ - **`enumerateClassNames(theme)`** — the finite completion universe: every
118
+ static utility, every theme-token expansion (colors × stops, text sizes,
119
+ rounded, shadows, weights, …), and custom `@utility` entries, ~3,400
120
+ classes on the default theme in ~12 ms. Candidates come from a generous
121
+ per-root value-space table (`UTILITY_VALUE_SPACES`) and are then probed
122
+ through the real utility resolver, so every enumerated class is valid by
123
+ construction; infinite families (the spacing scale, numeric values,
124
+ functional custom utilities) are returned as templates. Tests enforce the
125
+ reverse direction: every dispatch root must declare a value space, and
126
+ every merge-table static must enumerate.
127
+
128
+ ### Changed
129
+
130
+ - **`generate-types` rewritten on top of `enumerateClassNames`** — the CLI's
131
+ generated `rainbowindex-env.d.ts` now covers the full utility surface
132
+ (previously a hand-maintained subset: 8 color roots, spacing, text, fonts,
133
+ sizing) and a complete `Variant` union driven by `listVariants`. Plain
134
+ classes are checked against the enumerated finite union plus
135
+ spacing/numeric templates; variant-prefixed classes validate the variant
136
+ name (misspelled variants like `hver:` are now compile errors in strict
137
+ mode).
138
+ - **Fixed: generated types failed to compile** — the previous
139
+ `rainbowindex-env.d.ts` defined `RainbowClass` with a circular
140
+ `Exclude<RainbowClass, …>` self-reference, which TypeScript rejects
141
+ (TS2456), silently breaking `ri()` autocomplete in strict projects. The
142
+ new two-tier `RainbowBase`/`RainbowClass` shape compiles cleanly (~0.7 s
143
+ for a ~3,400-literal union).
144
+ - `[RI-1501]`/`[RI-1502]` (fluid typography) now flow into compile warnings
145
+ when a warning sink is present instead of only the dev console; the dev
146
+ console remains the fallback.
147
+ - Internal: activation detection moved from `directives/index.ts` into a pure
148
+ leaf module (`directives/activation.ts`) so the editor entry and browser
149
+ bundles don't pull the directive resolver's Node-only font machinery into
150
+ their module graph. All existing import paths keep working via re-exports.
151
+ - Internal: `analyzeProjectCSS` moved from `project/pipeline.ts` into a pure
152
+ leaf module (`project/analyze.ts`), and `compileUtility` gained an optional
153
+ failure-detail out-param — both re-exported/behavior-identical, byte-for-
154
+ byte identical CSS output.
155
+ - Internal: the pure font model (types + slot/face factories) moved from the
156
+ `font-providers` barrel into `font-providers/model.ts`; directive parsing
157
+ now imports it (and the font-family safety constants) from leaf modules,
158
+ making the editor entry's module graph structurally free of `node:*`
159
+ imports rather than relying on tree-shaking. The barrel re-exports the
160
+ model, so existing importers are unaffected.
161
+
8
162
  ## [0.2.1] - 2026-07-28
9
163
 
10
164
  ### Added — diagnostics
package/LICENSE CHANGED
@@ -19,4 +19,4 @@ Software.
19
19
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
20
20
  WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
21
21
  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22
- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -80,8 +80,7 @@ Common flags:
80
80
  | --- | --- |
81
81
  | `-o`, `--output <file>` | Output CSS file path. Required with `--watch`. |
82
82
  | `--watch` | Re-run on source-file changes (chokidar). |
83
- | `--minify` | Minify output via LightningCSS. |
84
- | `--optimize` | Minification + browser-fallback passes. |
83
+ | `--minify` | Minification + browser-fallback passes via LightningCSS. `--optimize` is an accepted alias. |
85
84
  | `--css <file>` | CSS input with directives. Auto-detected if omitted. |
86
85
  | `--strict` | Drop the string escape hatch in generated types. |
87
86
  | `--template <name>` | Vite template to scaffold (default: `react-ts`). |
@@ -298,6 +297,40 @@ If you call `ri()` while a compilation is still in progress (e.g. inside a
298
297
  server-rendering pass that triggers a fresh compile), the runtime emits a
299
298
  throttled `[RI-2004]` warning. That's your signal to switch to `createRi()`.
300
299
 
300
+ ## Editor tooling API
301
+
302
+ `rainbowindex/editor` is an IO-free toolkit for editor integrations — pure
303
+ computation (strings in, structures out) with no `node:*` imports anywhere in
304
+ its module graph, so it runs in browser-based editor hosts (vscode.dev)
305
+ exactly as it does in Node. The host reads files; the entry supplies the
306
+ semantics. Feature-detect via `editorCapabilities` rather than versions —
307
+ integrations load whatever version the workspace has installed.
308
+
309
+ ```ts
310
+ import { createEditorSession } from "rainbowindex/editor";
311
+
312
+ const session = createEditorSession({ css: themeCss });
313
+
314
+ session.diagnostics; // positioned problems in the CSS input
315
+ session.inspector.validate("felx"); // { ok: false, reason: "unknown-utility", suggestion: "flex" }
316
+ session.inspector.explain("sm:px-4"); // parsed structure + generated CSS + sort key
317
+ session.enumerate(); // ~3,400 probe-verified completions + templates
318
+ session.analyzeMerge(["px-2", "px-4"]); // which classes ri() drops, and who overrode them
319
+ session.swatch("brand", 500); // light/dark oklch + hex for completions
320
+ session.extractCandidates(source, path); // class tokens with exact source spans
321
+ session.setCss(nextCss); // theme changed → all caches invalidate together
322
+ ```
323
+
324
+ Everything the session wraps is also exported à la carte —
325
+ `analyzeProjectCSS`, `createClassInspector`, `listVariants`,
326
+ `enumerateClassNames`, `analyzeMerge` + `createThemeSnapshot`,
327
+ `resolveColorSwatch` / `listThemeTokens`, `extractClassCandidates`, and the
328
+ CSS-entry detection helpers (`CSS_ENTRY_CANDIDATES`, `hasRIActivation`).
329
+ Guarantees worth knowing: `validate(cls).ok` exactly when the compiler emits
330
+ a rule for `cls`; every enumerated class is probe-verified against the real
331
+ resolver; `analyzeMerge(...).output` is identical to `ri()`'s result; and
332
+ swatches use the same OKLCH math as the emitted CSS variables.
333
+
301
334
  ## Environment variables
302
335
 
303
336
  | Variable | Effect |
package/dist/browser.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- export { C as ColorDefinition, a as CompilationContext, b as CompilationSnapshot, D as DEFAULT_TEXT_SIZES, F as FluidConfig, T as TextSize, c as Theme, d as createCompilationContext, e as createRi, f as defaultTheme, g as finalizeCompilationContext, r as registerColorNames, h as registerCustomFontFamilies, i as registerCustomTextSizes, j as registerCustomUtility, k as ri, s as safelist } from './safelist-DRk1XXxi.js';
1
+ export { C as ColorDefinition, a as CompilationContext, b as CompilationSnapshot, D as DEFAULT_TEXT_SIZES, F as FluidConfig, T as TextSize, c as Theme, d as createCompilationContext, e as createRi, f as defaultTheme, g as finalizeCompilationContext, r as registerColorNames, h as registerCustomFontFamilies, i as registerCustomTextSizes, j as registerCustomUtility, k as ri } from './index-CfDtWufj.js';
2
+ export { s as safelist } from './safelist-CH3_PywB.js';
2
3
 
3
4
  declare function browserEntryUnavailable(): never;
4
5
 
package/dist/browser.mjs CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  registerCustomTextSizes,
14
14
  registerCustomUtility,
15
15
  ri
16
- } from "./chunk-5N4GPK26.mjs";
16
+ } from "./chunk-SOMDX7V6.mjs";
17
17
 
18
18
  // src/entries/browser.ts
19
19
  function browserEntryUnavailable() {
@@ -1,3 +1,9 @@
1
+ import {
2
+ collectProjectClasses,
3
+ finalizeProjectCompilation,
4
+ resolveGoogleFonts,
5
+ validateGlobPattern
6
+ } from "./chunk-AZXWJ625.mjs";
1
7
  import {
2
8
  APPLY_ALIASES,
3
9
  DEFAULT_PROPERTY_GROUP,
@@ -6,10 +12,8 @@ import {
6
12
  PROPERTY_GROUPS,
7
13
  RI_IMPORT_SPECIFIER_ALTERNATION,
8
14
  analyzeProjectCSS,
9
- collectProjectClasses,
10
15
  compileCSSFunctions,
11
16
  expandVariantGroups,
12
- finalizeProjectCompilation,
13
17
  forEachApplyClass,
14
18
  getCustomUtility,
15
19
  hasApplyLikeDirective,
@@ -17,11 +21,9 @@ import {
17
21
  hasRIActivation,
18
22
  parseUtility,
19
23
  pushWarningsDeduped,
20
- resolveGoogleFonts,
21
24
  resolveUtilityDeclarations,
22
- resolveVariant,
23
- validateGlobPattern
24
- } from "./chunk-RPXZ3O6R.mjs";
25
+ resolveVariant
26
+ } from "./chunk-IE6N76PW.mjs";
25
27
 
26
28
  // src/integrations/postcss/index.ts
27
29
  import postcss from "postcss";