tailwint 1.1.9 → 1.1.11

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/README.md CHANGED
@@ -2,6 +2,10 @@
2
2
  <img src="assets/header.svg" alt="tailwint">
3
3
  </p>
4
4
 
5
+ <p align="center">
6
+ <strong>tail</strong>wind + l<strong>int</strong> = <strong>tailwint</strong> ~≈∼〜 a tiny linter for your Tailwind CSS
7
+ </p>
8
+
5
9
  <p align="center">
6
10
  <a href="https://www.npmjs.com/package/tailwint"><img src="https://img.shields.io/npm/v/tailwint?color=0ea5e9&label=npm" alt="npm version"></a>
7
11
  <a href="https://github.com/peterwangsc/tailwint/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/tailwint?color=a78bfa" alt="license"></a>
@@ -10,7 +14,7 @@
10
14
 
11
15
  ---
12
16
 
13
- The same diagnostics VS Code shows — but from the command line. Catches class conflicts, suggests canonical rewrites, and auto-fixes everything. Built on the official `@tailwindcss/language-server`.
17
+ The same diagnostics VS Code shows — but from the command line. Catches class conflicts, suggests canonical rewrites, and auto-fixes everything. Powered by the official `@tailwindcss/language-server` — not a custom parser, not a regex hack.
14
18
 
15
19
  **Works with Tailwind CSS v4.**
16
20
 
@@ -156,11 +160,11 @@ const exitCode = await run({
156
160
 
157
161
  tailwint exits with meaningful codes for CI pipelines:
158
162
 
159
- | Exit code | Meaning |
160
- | --------- | ------------------------------------------------- |
161
- | `0` | No issues found, or all issues fixed with `--fix` |
162
- | `1` | Issues found (without `--fix`) |
163
- | `2` | Fatal error (language server not found, crash) |
163
+ | Exit code | Meaning |
164
+ | --------- | ---------------------------------------------------------------- |
165
+ | `0` | No issues found, or all issues fixed with `--fix` |
166
+ | `1` | Issues found, or unfixable issues remain after `--fix` |
167
+ | `2` | Fatal error (language server not found, crash) |
164
168
 
165
169
  ### GitHub Actions
166
170
 
package/dist/edits.d.ts CHANGED
@@ -15,4 +15,8 @@ export interface TextEdit {
15
15
  newText: string;
16
16
  }
17
17
  export declare function applyEdits(content: string, edits: TextEdit[]): string;
18
- export declare function fixFile(filePath: string, initialDiags: any[], fileContents: Map<string, string>, version: Map<string, number>, onPass?: (pass: number) => void): Promise<number>;
18
+ export interface FixResult {
19
+ initial: number;
20
+ remaining: number;
21
+ }
22
+ export declare function fixFile(filePath: string, initialDiags: any[], fileContents: Map<string, string>, version: Map<string, number>, onPass?: (pass: number) => void): Promise<FixResult>;
package/dist/edits.js CHANGED
@@ -1,2 +1,2 @@
1
- import{writeFileSync as v}from"fs";import{send as D,notify as $,fileUri as B,waitForDiagnostic as k}from"./lsp.js";function C(t,n){if(n.length===0)return t;const r=[0];for(let e=0;e<t.length;e++)t[e]===`
2
- `&&r.push(e+1);function c(e,o){return e>=r.length?t.length:Math.min(r[e]+o,t.length)}const a=n.map(e=>({start:c(e.range.start.line,e.range.start.character),end:c(e.range.end.line,e.range.end.character),newText:e.newText}));a.sort((e,o)=>e.start-o.start);const u=[];let i=0;for(const e of a)e.start>i&&u.push(t.slice(i,e.start)),u.push(e.newText),i=e.end;return i<t.length&&u.push(t.slice(i)),u.join("")}function M(t){return`${t.start.line}:${t.start.character}-${t.end.line}:${t.end.character}`}function b(t,n){return t.line<n.line||t.line===n.line&&t.character<=n.character}function A(t,n){return b(t.range.start,n.range.start)&&b(n.range.end,t.range.end)}function F(t){const n=[];for(const r of t)t.some(a=>a!==r&&A(a,r))||n.push(r);return n}async function O(t,n,r,c,a){const u=process.env.DEBUG==="1",i=B(t);let e=r.get(t),o=c.get(t);const y=n.length;let g=n;for(let d=0;g.length>0;d++){a?.(d+1),u&&console.error(` pass ${d+1}: ${g.length} remaining`);const E=await Promise.all(g.map(s=>D("textDocument/codeAction",{textDocument:{uri:i},range:s.range,context:{diagnostics:[s],only:["quickfix"]}}).catch(()=>null))),m=new Map;for(let s=0;s<g.length;s++){const f=E[s];if(!f||f.length===0)continue;const h=f[0],x=h.edit?.changes?.[i]||h.edit?.documentChanges?.[0]?.edits||[];if(x.length!==0)for(const p of x){const w=M(p.range);m.set(w,p)}}let l=[...m.values()];if(l.length===0)break;l=F(l);const T=e;if(e=C(e,l),e===T)break;o++,$("textDocument/didChange",{textDocument:{uri:i,version:o},contentChanges:[{text:e}]}),g=(await k(i)).filter(s=>s.severity===1||s.severity===2)}return e!==r.get(t)&&(v(t,e),r.set(t,e),c.set(t,o)),y}export{C as applyEdits,O as fixFile};
1
+ import{writeFileSync as v}from"fs";import{send as D,notify as $,fileUri as B,waitForDiagnostic as F}from"./lsp.js";function k(t,n){if(n.length===0)return t;const r=[0];for(let e=0;e<t.length;e++)t[e]===`
2
+ `&&r.push(e+1);function c(e,o){return e>=r.length?t.length:Math.min(r[e]+o,t.length)}const a=n.map(e=>({start:c(e.range.start.line,e.range.start.character),end:c(e.range.end.line,e.range.end.character),newText:e.newText}));a.sort((e,o)=>e.start-o.start);const u=[];let i=0;for(const e of a)e.start>i&&u.push(t.slice(i,e.start)),u.push(e.newText),i=e.end;return i<t.length&&u.push(t.slice(i)),u.join("")}function C(t){return`${t.start.line}:${t.start.character}-${t.end.line}:${t.end.character}`}function b(t,n){return t.line<n.line||t.line===n.line&&t.character<=n.character}function M(t,n){return b(t.range.start,n.range.start)&&b(n.range.end,t.range.end)}function R(t){const n=[];for(const r of t)t.some(a=>a!==r&&M(a,r))||n.push(r);return n}async function G(t,n,r,c,a){const u=process.env.DEBUG==="1",i=B(t);let e=r.get(t),o=c.get(t);const y=n.length;let l=n;for(let d=0;l.length>0;d++){a?.(d+1),u&&console.error(` pass ${d+1}: ${l.length} remaining`);const E=await Promise.all(l.map(s=>D("textDocument/codeAction",{textDocument:{uri:i},range:s.range,context:{diagnostics:[s],only:["quickfix"]}}).catch(()=>null))),m=new Map;for(let s=0;s<l.length;s++){const f=E[s];if(!f||f.length===0)continue;const h=f[0],x=h.edit?.changes?.[i]||h.edit?.documentChanges?.[0]?.edits||[];if(x.length!==0)for(const p of x){const w=C(p.range);m.set(w,p)}}let g=[...m.values()];if(g.length===0)break;g=R(g);const T=e;if(e=k(e,g),e===T)break;o++,$("textDocument/didChange",{textDocument:{uri:i,version:o},contentChanges:[{text:e}]}),l=(await F(i)).filter(s=>s.severity===1||s.severity===2)}return e!==r.get(t)&&(v(t,e),r.set(t,e),c.set(t,o)),{initial:y,remaining:l.length}}export{k as applyEdits,G as fixFile};
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{resolve as ne,relative as M}from"path";import{readFileSync as re}from"fs";import{glob as ie}from"glob";import{startServer as le,send as ce,notify as _,shutdown as C,fileUri as F,langId as $e,diagnosticsReceived as I,settledProjects as ae,brokenProjects as de,warnings as fe,waitForAllProjects as ge,resetState as ue}from"./lsp.js";import{fixFile as pe}from"./edits.js";import{prescanCssFiles as me}from"./prescan.js";import{c as e,setTitle as a,windTrail as r,braille as A,windWave as v,dots as V,tick as y,advanceTick as we,startSpinner as j,progressBar as E,banner as he,fileBadge as q,diagLine as xe,rainbowText as be,celebrationAnimation as G}from"./ui.js";import{applyEdits as Ae}from"./edits.js";const ve=["**/*.{tsx,jsx,html,vue,svelte,astro,mdx,css}"];async function Me(S={}){ue();const T=Date.now(),d=ne(S.cwd||process.cwd()),K=S.fix??!1,Y=S.patterns??ve,L=new Set;for(const t of Y){const o=await ie(t,{cwd:d,absolute:!0,nodir:!0,ignore:["**/node_modules/**","**/dist/**","**/build/**","**/out/**","**/coverage/**","**/public/**","**/tmp/**","**/.tmp/**","**/.cache/**","**/vendor/**","**/storybook-static/**","**/.next/**","**/.nuxt/**","**/.output/**","**/.svelte-kit/**","**/.astro/**","**/.vercel/**","**/.expo/**"]});for(const s of o)L.add(s)}const P=[...L];if(await he(),P.length===0){const o="the wind blows",s="but there is nothing here",n="~ no files matched ~",i=Math.floor((54-s.length-2)/2),c=54-n.length-8,$=4,b=50-o.length-2,g=i,w=54-i-s.length-2,h=c,u=54-c-n.length-2;return console.error(` ${r($)} ${e.dim}${o}${e.reset} ${r(b,4)}`),console.error(` ${r(g,2)} ${e.dim}${s}${e.reset} ${r(w,7)}`),console.error(` ${r(h,5)} ${e.dim}${e.italic}${n}${e.reset} ${r(u,9)}`),console.error(""),0}a("tailwint ~ booting...");const H=j(()=>(a(`tailwint ~ booting${".".repeat(Date.now()%4)}`),` ${A()} ${e.dim}booting language server${V()}${e.reset} ${r(24,y)}`));le(d),await ce("initialize",{processId:process.pid,rootUri:F(d),capabilities:{textDocument:{publishDiagnostics:{relatedInformation:!0},codeAction:{codeActionLiteralSupport:{codeActionKind:{valueSet:["quickfix"]}}}},workspace:{workspaceFolders:!0,configuration:!0}},workspaceFolders:[{uri:F(d),name:"workspace"}]}),_("initialized",{}),H(),console.error(` ${e.green}\u2714${e.reset} ${e.dim}language server ready${e.reset} ${r(30)}`);const p=me(P),U=new Map,B=new Map,k=p.unrelatedCssFiles.size;let f=0;for(const t of P){if(p.unrelatedCssFiles.has(t))continue;let o;try{o=re(t,"utf-8")}catch{continue}U.set(t,o),B.set(t,1),_("textDocument/didOpen",{textDocument:{uri:F(t),languageId:$e(t),version:1,text:o}}),f++}const O=`sent ${f} file${f===1?"":"s"} to lsp`,J=52-O.length-1;if(console.error(` ${e.green}\u2714${e.reset} ${e.dim}${O}${e.reset} ${r(J)}`),k>0){const t=`${k} file${k===1?"":"s"} skipped`,o=52-t.length-1;console.error(` ${e.dim}\u2500${e.reset} ${e.dim}${t}${e.reset} ${r(o)}`);for(const s of p.unrelatedCssFiles){const n=M(d,s);console.error(` ${e.dim}${q(n)}${e.reset}`)}}a("tailwint ~ scanning...");const Q=j(()=>{const t=I.size,o=ae+de,s=t>0?"scanning":"initializing";a(`tailwint ~ ${s} ${o}/${p.maxProjects}`);const n=f>0?Math.round(t/f*100):0,x=E(n,18,!0),i=String(f),c=String(t).padStart(i.length),$=25+s.length+3+1-2,b=Math.max(0,54-$),g=`${c}/${i}`,w=" ".repeat(Math.max(0,25-g.length-1)),h="files received",u=w.length+g.length+1+h.length+1-2,D=Math.max(0,54-u);return` ${A()} ${x} ${e.dim}${s}${V()}${e.reset} ${r(b,y)}
2
- ${w}${e.bold}${g}${e.reset} ${e.dim}${h}${e.reset} ${r(D,y+3)}`},80);await ge(p.predictedRoots,p.maxProjects),Q();for(const t of fe)console.error(` ${e.yellow}\u26A0${e.reset} ${e.dim}${t}${e.reset}`);const z=I.size,R=`${z}/${f} files received`,Z=52-R.length-1;console.error(` ${e.green}\u2714${e.reset} ${e.dim}${R}${e.reset} ${r(Z)}`),console.error("");let m=0;const l=new Map;for(const t of P){const s=(I.get(F(t))||[]).filter(n=>n.severity===1||n.severity===2);s.length>0&&(l.set(t,s),m+=s.length)}const N=[...l.values()].flat().filter(t=>t.code==="cssConflict").length,ee=m-N;if(m===0){const t=((Date.now()-T)/1e3).toFixed(1);return a("tailwint \u2714 all clear"),await G(),console.error(` ${e.green}\u2714${e.reset} ${e.bold}${z}${e.reset} files scanned ${e.dim}// ${be("all clear")} ${e.dim}${t}s${e.reset}`),console.error(""),await C(),0}console.error(` ${e.bold}${e.white}${z}${e.reset} files scanned ${e.dim}//${e.reset} ${e.orange}${e.bold}${N}${e.reset}${e.orange} conflicts${e.reset} ${e.dim}\u2502${e.reset} ${e.yellow}${e.bold}${ee}${e.reset}${e.yellow} canonical${e.reset}`),console.error("");let W=0;for(const[t,o]of l){W>0&&console.log(` ${e.dim}${v()}${e.reset}`),W++;const s=M(d,t);console.log(` ${e.dim}\u250C${e.reset} ${q(s)} ${e.dim}(${o.length})${e.reset}`);for(const n of o)console.log(xe(n));console.log(` ${e.dim}\u2514${r(3)}${e.reset}`),we()}if(K){console.error(""),console.error(` ${e.bgCyan}${e.bold} \u2699 FIX ${e.reset} ${e.dim}conflicts first, then canonical${e.reset}`),console.error("");let t=0,o=0;for(const[n,x]of l){o++;const i=M(d,n);let c=0;const $=i.includes("/")?i.slice(i.lastIndexOf("/")+1):i;a(`tailwint ~ fixing ${$} (${o}/${l.size})`);const b=j(()=>{const u=Math.round((o-1+c/10)/l.size*100),D=E(u,18,!0),X=`pass ${c}`,oe=22+$.length+1+X.length+3+1,se=Math.max(0,56-oe);return` ${A()} ${D} ${e.bold}${e.white}${$}${e.reset} ${e.dim}${X}${V()}${e.reset} ${r(se,y)}`}),g=await pe(n,x,U,B,u=>{c=u});b(),t+=g;const w=Math.round(o/l.size*100),h=E(w,18);console.error(` ${e.green}\u2714${e.reset} ${h} ${e.bold}${e.white}${$}${e.reset} ${e.green}${x.length} fixed${e.reset}`)}console.error("");const s=((Date.now()-T)/1e3).toFixed(1);return a(`tailwint \u2714 fixed ${t} issues`),await G(),console.error(` ${v()} ${e.bgGreen}${e.bold} \u2714 FIXED ${e.reset} ${e.green}${e.bold}${t}${e.reset} of ${e.bold}${m}${e.reset} issues across ${e.bold}${l.size}${e.reset} files ${e.dim}${s}s${e.reset} ${v()}`),console.error(""),await C(),0}const te=((Date.now()-T)/1e3).toFixed(1);return a(`tailwint \u2718 ${m} issues`),console.log(""),console.log(` ${v()} ${e.bgRed}${e.bold} \u2718 FAIL ${e.reset} ${e.red}${e.bold}${m}${e.reset} issues in ${e.bold}${l.size}${e.reset} files ${e.dim}${te}s${e.reset} ${v()}`),console.log(` ${e.dim}run with ${e.white}--fix${e.dim} to auto-fix${e.reset}`),console.log(""),await C(),1}export{Ae as applyEdits,Me as run};
1
+ import{resolve as ce,relative as C}from"path";import{readFileSync as $e}from"fs";import{glob as ae}from"glob";import{startServer as de,send as fe,notify as q,shutdown as I,fileUri as y,langId as ge,diagnosticsReceived as A,settledProjects as ue,brokenProjects as me,warnings as pe,waitForAllProjects as we,resetState as he}from"./lsp.js";import{fixFile as xe}from"./edits.js";import{prescanCssFiles as be}from"./prescan.js";import{c as e,setTitle as d,windTrail as n,braille as V,windWave as b,dots as j,tick as F,advanceTick as ve,startSpinner as E,progressBar as L,banner as Pe,fileBadge as G,diagLine as ye,rainbowText as Fe,celebrationAnimation as K}from"./ui.js";import{applyEdits as Le}from"./edits.js";const ke=["**/*.{tsx,jsx,html,vue,svelte,astro,mdx,css}"];async function Ve(k={}){he();const S=Date.now(),f=ce(k.cwd||process.cwd()),Y=k.fix??!1,H=k.patterns??ke,U=new Set;for(const t of H){const o=await ae(t,{cwd:f,absolute:!0,nodir:!0,ignore:["**/node_modules/**","**/dist/**","**/build/**","**/out/**","**/coverage/**","**/public/**","**/tmp/**","**/.tmp/**","**/.cache/**","**/vendor/**","**/storybook-static/**","**/.next/**","**/.nuxt/**","**/.output/**","**/.svelte-kit/**","**/.astro/**","**/.vercel/**","**/.expo/**"]});for(const s of o)U.add(s)}const v=[...U];if(await Pe(),v.length===0){const o="the wind blows",s="but there is nothing here",r="~ no files matched ~",$=Math.floor((54-s.length-2)/2),w=54-r.length-8,a=4,u=50-o.length-2,i=$,h=54-$-s.length-2,l=w,x=54-w-r.length-2;return console.error(` ${n(a)} ${e.dim}${o}${e.reset} ${n(u,4)}`),console.error(` ${n(i,2)} ${e.dim}${s}${e.reset} ${n(h,7)}`),console.error(` ${n(l,5)} ${e.dim}${e.italic}${r}${e.reset} ${n(x,9)}`),console.error(""),0}d("tailwint ~ booting...");const J=E(()=>(d(`tailwint ~ booting${".".repeat(Date.now()%4)}`),` ${V()} ${e.dim}booting language server${j()}${e.reset} ${n(24,F)}`));de(f),await fe("initialize",{processId:process.pid,rootUri:y(f),capabilities:{textDocument:{publishDiagnostics:{relatedInformation:!0},codeAction:{codeActionLiteralSupport:{codeActionKind:{valueSet:["quickfix"]}}}},workspace:{workspaceFolders:!0,configuration:!0}},workspaceFolders:[{uri:y(f),name:"workspace"}]}),q("initialized",{}),J(),console.error(` ${e.green}\u2714${e.reset} ${e.dim}language server ready${e.reset} ${n(30)}`);const m=be(v),B=new Map,N=new Map,T=m.unrelatedCssFiles.size;let g=0;for(const t of v){if(m.unrelatedCssFiles.has(t))continue;let o;try{o=$e(t,"utf-8")}catch{continue}B.set(t,o),N.set(t,1),q("textDocument/didOpen",{textDocument:{uri:y(t),languageId:ge(t),version:1,text:o}}),g++}const O=`sent ${g} file${g===1?"":"s"} to lsp`,Q=52-O.length-1;if(console.error(` ${e.green}\u2714${e.reset} ${e.dim}${O}${e.reset} ${n(Q)}`),T>0){const t=`${T} file${T===1?"":"s"} skipped`,o=52-t.length-1;console.error(` ${e.dim}\u2500${e.reset} ${e.dim}${t}${e.reset} ${n(o)}`);for(const s of m.unrelatedCssFiles){const r=C(f,s);console.error(` ${e.dim}${G(r)}${e.reset}`)}}d("tailwint ~ scanning...");const Z=E(()=>{const t=A.size,o=ue+me,s=t>0?"scanning":"initializing";d(`tailwint ~ ${s} ${o}/${m.maxProjects}`);const r=g>0?Math.round(t/g*100):0,P=L(r,18,!0),$=String(g),w=String(t).padStart($.length),a=25+s.length+3+1-2,u=Math.max(0,54-a),i=`${w}/${$}`,h=" ".repeat(Math.max(0,25-i.length-1)),l="files received",x=h.length+i.length+1+l.length+1-2,D=Math.max(0,54-x);return` ${V()} ${P} ${e.dim}${s}${j()}${e.reset} ${n(u,F)}
2
+ ${h}${e.bold}${i}${e.reset} ${e.dim}${l}${e.reset} ${n(D,F+3)}`},80);await we(m.predictedRoots,m.maxProjects),Z();for(const t of pe)console.error(` ${e.yellow}\u26A0${e.reset} ${e.dim}${t}${e.reset}`);const z=A.size,R=`${z}/${g} files received`,ee=52-R.length-1;console.error(` ${e.green}\u2714${e.reset} ${e.dim}${R}${e.reset} ${n(ee)}`),console.error("");let p=0;const c=new Map;for(const t of v){const s=(A.get(y(t))||[]).filter(r=>r.severity===1||r.severity===2);s.length>0&&(c.set(t,s),p+=s.length)}const W=[...c.values()].flat().filter(t=>t.code==="cssConflict").length,te=p-W;if(p===0){const t=((Date.now()-S)/1e3).toFixed(1);return d("tailwint \u2714 all clear"),await K(),console.error(` ${e.green}\u2714${e.reset} ${e.bold}${z}${e.reset} files scanned ${e.dim}// ${Fe("all clear")} ${e.dim}${t}s${e.reset}`),console.error(""),await I(),0}console.error(` ${e.bold}${e.white}${z}${e.reset} files scanned ${e.dim}//${e.reset} ${e.orange}${e.bold}${W}${e.reset}${e.orange} conflicts${e.reset} ${e.dim}\u2502${e.reset} ${e.yellow}${e.bold}${te}${e.reset}${e.yellow} canonical${e.reset}`),console.error("");let X=0;for(const[t,o]of c){X>0&&console.log(` ${e.dim}${b()}${e.reset}`),X++;const s=C(f,t);console.log(` ${e.dim}\u250C${e.reset} ${G(s)} ${e.dim}(${o.length})${e.reset}`);for(const r of o)console.log(ye(r));console.log(` ${e.dim}\u2514${n(3)}${e.reset}`),ve()}if(Y){console.error(""),console.error(` ${e.bgCyan}${e.bold} \u2699 FIX ${e.reset} ${e.dim}conflicts first, then canonical${e.reset}`),console.error("");let t=0,o=0,s=0;for(const[$,w]of c){s++;const a=C(f,$);let u=0;const i=a.includes("/")?a.slice(a.lastIndexOf("/")+1):a;d(`tailwint ~ fixing ${i} (${s}/${c.size})`);const h=E(()=>{const M=Math.round((s-1+u/10)/c.size*100),re=L(M,18,!0),_=`pass ${u}`,ie=22+i.length+1+_.length+3+1,le=Math.max(0,56-ie);return` ${V()} ${re} ${e.bold}${e.white}${i}${e.reset} ${e.dim}${_}${j()}${e.reset} ${n(le,F)}`}),l=await xe($,w,B,N,M=>{u=M});h();const x=l.initial-l.remaining;t+=x,o+=l.remaining;const D=Math.round(s/c.size*100),oe=L(D,18),ne=l.remaining>0?` ${e.dim}(${l.remaining} skipped)${e.reset}`:"";console.error(` ${e.green}\u2714${e.reset} ${oe} ${e.bold}${e.white}${i}${e.reset} ${e.green}${x} fixed${e.reset}${ne}`)}console.error("");const r=((Date.now()-S)/1e3).toFixed(1);d(`tailwint \u2714 fixed ${t} issues`),await K();const P=o>0?` ${e.dim}(${o} unfixable)${e.reset}`:"";return console.error(` ${b()} ${e.bgGreen}${e.bold} \u2714 FIXED ${e.reset} ${e.green}${e.bold}${t}${e.reset} of ${e.bold}${p}${e.reset} issues across ${e.bold}${c.size}${e.reset} files ${e.dim}${r}s${e.reset}${P} ${b()}`),console.error(""),await I(),o>0?1:0}const se=((Date.now()-S)/1e3).toFixed(1);return d(`tailwint \u2718 ${p} issues`),console.log(""),console.log(` ${b()} ${e.bgRed}${e.bold} \u2718 FAIL ${e.reset} ${e.red}${e.bold}${p}${e.reset} issues in ${e.bold}${c.size}${e.reset} files ${e.dim}${se}s${e.reset} ${b()}`),console.log(` ${e.dim}run with ${e.white}--fix${e.dim} to auto-fix${e.reset}`),console.log(""),await I(),1}export{Le as applyEdits,Ve as run};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tailwint",
3
- "version": "1.1.9",
4
- "description": "Tailwind CSS linter for CI — drives the official language server to catch class issues and auto-fix them",
3
+ "version": "1.1.11",
4
+ "description": "Tiny Tailwind CSS linter and auto-fixer for CI — powered by the official language server, not regex",
5
5
  "license": "MIT",
6
6
  "author": "Peter Wang",
7
7
  "homepage": "https://github.com/peterwangsc/tailwint",
@@ -13,16 +13,24 @@
13
13
  "keywords": [
14
14
  "tailwindcss",
15
15
  "tailwind",
16
+ "tailwind-lint",
16
17
  "lint",
17
18
  "linter",
19
+ "cli",
18
20
  "ci",
21
+ "ci-cd",
19
22
  "autofix",
20
23
  "language-server",
21
24
  "lsp",
22
25
  "tailwind-v4",
23
26
  "css",
24
27
  "diagnostics",
25
- "code-quality"
28
+ "code-quality",
29
+ "class-conflicts",
30
+ "canonical",
31
+ "github-actions",
32
+ "pre-commit",
33
+ "static-analysis"
26
34
  ],
27
35
  "engines": {
28
36
  "node": ">=18"