ultracite 6.5.1 → 7.0.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.
Files changed (65) hide show
  1. package/README.md +1 -1
  2. package/config/biome/angular/biome.jsonc +9 -0
  3. package/config/{astro → biome/astro}/biome.jsonc +1 -1
  4. package/config/{core → biome/core}/biome.jsonc +45 -44
  5. package/config/{next → biome/next}/biome.jsonc +1 -1
  6. package/config/{qwik → biome/qwik}/biome.jsonc +1 -1
  7. package/config/{react → biome/react}/biome.jsonc +1 -1
  8. package/config/{remix → biome/remix}/biome.jsonc +1 -1
  9. package/config/{solid → biome/solid}/biome.jsonc +1 -1
  10. package/config/{svelte → biome/svelte}/biome.jsonc +1 -1
  11. package/config/{vue → biome/vue}/biome.jsonc +1 -1
  12. package/config/eslint/angular/eslint.config.mjs +18 -0
  13. package/config/eslint/angular/rules/angular.mjs +17 -0
  14. package/config/eslint/astro/eslint.config.mjs +18 -0
  15. package/config/eslint/astro/rules/astro.mjs +17 -0
  16. package/config/eslint/core/eslint.config.mjs +168 -0
  17. package/config/eslint/core/rules/compat.mjs +5 -0
  18. package/config/eslint/core/rules/cypress.mjs +17 -0
  19. package/config/eslint/core/rules/eslint-typescript.mjs +43 -0
  20. package/config/eslint/core/rules/eslint.mjs +30 -0
  21. package/config/eslint/core/rules/github.mjs +19 -0
  22. package/config/eslint/core/rules/import.mjs +44 -0
  23. package/config/eslint/core/rules/jest.mjs +17 -0
  24. package/config/eslint/core/rules/n.mjs +24 -0
  25. package/config/eslint/core/rules/prettier.mjs +5 -0
  26. package/config/eslint/core/rules/promise.mjs +20 -0
  27. package/config/eslint/core/rules/sonarjs.mjs +19 -0
  28. package/config/eslint/core/rules/storybook.mjs +17 -0
  29. package/config/eslint/core/rules/tailwindcss.mjs +22 -0
  30. package/config/eslint/core/rules/typescript.mjs +62 -0
  31. package/config/eslint/core/rules/unicorn.mjs +34 -0
  32. package/config/eslint/core/rules/unused-imports.mjs +17 -0
  33. package/config/eslint/next/eslint.config.mjs +18 -0
  34. package/config/eslint/next/rules/next.mjs +17 -0
  35. package/config/eslint/qwik/eslint.config.mjs +18 -0
  36. package/config/eslint/qwik/rules/qwik.mjs +17 -0
  37. package/config/eslint/react/eslint.config.mjs +43 -0
  38. package/config/eslint/react/rules/jsx-a11y.mjs +27 -0
  39. package/config/eslint/react/rules/query.mjs +15 -0
  40. package/config/eslint/react/rules/react-hooks.mjs +17 -0
  41. package/config/eslint/react/rules/react.mjs +46 -0
  42. package/config/eslint/remix/eslint.config.mjs +18 -0
  43. package/config/eslint/remix/rules/remix.mjs +17 -0
  44. package/config/eslint/solid/eslint.config.mjs +18 -0
  45. package/config/eslint/solid/rules/solid.mjs +17 -0
  46. package/config/eslint/svelte/eslint.config.mjs +18 -0
  47. package/config/eslint/svelte/rules/svelte.mjs +17 -0
  48. package/config/eslint/vue/eslint.config.mjs +18 -0
  49. package/config/eslint/vue/rules/vue.mjs +17 -0
  50. package/config/oxlint/angular/.oxlintrc.json +4 -0
  51. package/config/oxlint/astro/.oxlintrc.json +4 -0
  52. package/config/oxlint/core/.oxlintrc.json +92 -0
  53. package/config/oxlint/next/.oxlintrc.json +13 -0
  54. package/config/oxlint/qwik/.oxlintrc.json +4 -0
  55. package/config/oxlint/react/.oxlintrc.json +18 -0
  56. package/config/oxlint/remix/.oxlintrc.json +4 -0
  57. package/config/oxlint/solid/.oxlintrc.json +4 -0
  58. package/config/oxlint/svelte/.oxlintrc.json +4 -0
  59. package/config/oxlint/vue/.oxlintrc.json +5 -0
  60. package/config/prettier/prettier.config.mjs +14 -0
  61. package/config/stylelint/stylelint.config.mjs +38 -0
  62. package/dist/index.d.ts +6 -15
  63. package/dist/index.js +43 -174
  64. package/package.json +51 -10
  65. package/config/angular/biome.jsonc +0 -9
package/dist/index.js CHANGED
@@ -1,14 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var le=Object.defineProperty;var ht=Object.getOwnPropertyDescriptor;var yt=Object.getOwnPropertyNames;var wt=Object.prototype.hasOwnProperty;var de=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,s)=>(typeof require<"u"?require:t)[s]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')}),Ee=e=>t=>{var s=e[t];if(s)return s();throw new Error("Module not found in bundle: "+t)};var F=(e,t)=>()=>(e&&(t=e(e=0)),t);var z=(e,t)=>{for(var s in t)le(e,s,{get:t[s],enumerable:!0})},kt=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of yt(t))!wt.call(e,o)&&o!==s&&le(e,o,{get:()=>t[o],enumerable:!(n=ht(t,o))||n.enumerable});return e};var G=e=>kt(le({},"__esModule",{value:!0}),e);import{access as At,readFile as Fe,writeFile as Ft}from"fs/promises";import{parse as Nt}from"jsonc-parser";var f,C,Y,v,Ot,Dt,K,h=F(()=>{"use strict";f=async e=>{try{return await At(e),!0}catch{return!1}},C=async()=>{if(await f("pnpm-workspace.yaml"))return!0;try{let e=Nt(await Fe("package.json","utf-8"));return e?!!e.workspaces||!!e.workspace:!1}catch{return!1}},Y=`
3
- 888 888 888 88888888888 8888888b. d8888 .d8888b. 8888888 88888888888 8888888888
4
- 888 888 888 888 888 Y88b d88888 d88P Y88b 888 888 888
5
- 888 888 888 888 888 888 d88P888 888 888 888 888 888
6
- 888 888 888 888 888 d88P d88P 888 888 888 888 8888888
7
- 888 888 888 888 8888888P" d88P 888 888 888 888 888
8
- 888 888 888 888 888 T88b d88P 888 888 888 888 888 888
9
- Y88b. .d88P 888 888 888 T88b d8888888888 Y88b d88P 888 888 888
10
- "Y88888P" 88888888 888 888 T88b d88P 888 "Y8888P" 8888888 888 8888888888
11
- `,v=async({dependencies:e,devDependencies:t,scripts:s})=>{let n=await Fe("package.json","utf8"),o=JSON.parse(n),i={...o};(o.devDependencies||t)&&(i.devDependencies={...o.devDependencies,...t}),(o.dependencies||e)&&(i.dependencies={...o.dependencies,...e}),(o.scripts||s)&&(i.scripts={...o.scripts,...s}),await Ft("package.json",JSON.stringify(i,null,2))},Ot=/[ $(){}[\]&|;<>!"'`*?#~]/,Dt=/'/g,K=e=>e.map(t=>Ot.test(t)?`'${t.replace(Dt,"'\\''")}' `:t)});var st={};z(st,{husky:()=>S});import{execSync as Os}from"child_process";import{mkdir as Ds,readFile as Ms,writeFile as et}from"fs/promises";import{addDevDependency as Ts,dlxCommand as ke}from"nypm";var tt,ie,S,be=F(()=>{"use strict";h();tt=e=>`#!/bin/sh
2
+ var ht=Object.defineProperty;var Ce=Object.getOwnPropertyDescriptor;var be=Object.getOwnPropertyNames;var Ee=Object.prototype.hasOwnProperty;var wt=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,n)=>(typeof require<"u"?require:e)[n]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')}),At=t=>e=>{var n=t[e];if(n)return n();throw new Error("Module not found in bundle: "+e)};var R=(t,e)=>()=>(t&&(e=t(t=0)),e);var Q=(t,e)=>{for(var n in e)ht(t,n,{get:e[n],enumerable:!0})},je=(t,e,n,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of be(e))!Ee.call(t,o)&&o!==n&&ht(t,o,{get:()=>e[o],enumerable:!(i=Ce(e,o))||i.enumerable});return t};var Z=t=>je(ht({},"__esModule",{value:!0}),t);import{access as $e,mkdir as Se,readFile as Jt,writeFile as Oe}from"fs/promises";import{dirname as ve}from"path";import{parse as Ne}from"jsonc-parser";var c,b,x,Fe,Re,d,k,De,Le,Ae,q,m=R(()=>{"use strict";c=async t=>{try{return await $e(t),!0}catch{return!1}},b=async()=>{if(await c("pnpm-workspace.yaml"))return!0;try{let t=Ne(await Jt("package.json","utf-8"));return t?!!t.workspaces||!!t.workspace:!1}catch{return!1}},x=async({dependencies:t,devDependencies:e,scripts:n})=>{let i=await Jt("package.json","utf8"),o=JSON.parse(i),s={...o};(o.devDependencies||e)&&(s.devDependencies={...o.devDependencies,...e}),(o.dependencies||t)&&(s.dependencies={...o.dependencies,...t}),(o.scripts||n)&&(s.scripts={...o.scripts,...n}),await Oe("package.json",JSON.stringify(s,null,2))},Fe=/[ $(){}[\]&|;<>!"'`*?#~]/,Re=/'/g,d=t=>t.map(e=>Fe.test(e)?`'${e.replace(Re,"'\\''")}' `:e),k=async t=>{let e=ve(t);if(e!=="."){let n=e.startsWith("./")?e.slice(2):e;await Se(n,{recursive:!0})}},De=["./biome.json","./biome.jsonc"],Le=["./eslint.config.mjs","./eslint.config.js","./eslint.config.cjs","./eslint.config.ts","./eslint.config.mts","./eslint.config.cts"],Ae="./.oxlintrc.json",q=async()=>{for(let t of De)if(await c(t))return"biome";for(let t of Le)if(await c(t))return"eslint";return await c(Ae)?"oxlint":null}});var Gt={};Q(Gt,{husky:()=>v});import{execSync as kn}from"child_process";import{mkdir as Cn,readFile as bn,writeFile as zt}from"fs/promises";import{addDevDependency as En,dlxCommand as Et}from"nypm";var Ht,ot,v,jt=R(()=>{"use strict";m();Ht=t=>`#!/bin/sh
12
3
  # Exit on any error
13
4
  set -e
14
5
 
@@ -31,7 +22,7 @@ git stash push --quiet --keep-index --message "pre-commit-stash" || true
31
22
  STASHED=$?
32
23
 
33
24
  # Run formatter on the staged files
34
- ${e}
25
+ ${t}
35
26
  FORMAT_EXIT_CODE=$?
36
27
 
37
28
  # Restore working directory state
@@ -76,10 +67,10 @@ if [ "$STAGED_HASH" != "$NEW_STAGED_HASH" ]; then
76
67
  fi
77
68
 
78
69
  exit $FORMAT_EXIT_CODE
79
- `,ie="./.husky/pre-commit",S={exists:()=>f(ie),install:async e=>{await Ts("husky",{packageManager:e,workspace:await C(),silent:!0}),await v({scripts:{prepare:"husky"}})},init:e=>{let t=ke(e,"husky",{args:["init"]});try{Os(t,{stdio:"pipe"})}catch{}},create:async e=>{await Ds(".husky",{recursive:!0});let t=ke(e,"ultracite",{args:["fix"],short:e==="npm"}),s=tt(t);await et(ie,s)},update:async e=>{let t=await Ms(ie,"utf-8"),s=ke(e,"ultracite",{args:["fix"],short:e==="npm"}),n=tt(s);await et(ie,`${t}
80
- ${n}`)}}});var rt={};z(rt,{lefthook:()=>O});import{execSync as Us}from"child_process";import{readFile as Is,writeFile as B}from"fs/promises";import{addDevDependency as _s,dlxCommand as ot}from"nypm";var Js,Bs,it,R,nt,O,xe=F(()=>{"use strict";h();Js=/(pre-commit:\s*\n\s*jobs:\s*\n)/,Bs=/(pre-commit:\s*\n)/,it=e=>ot(e,"ultracite",{args:["fix"],short:e==="npm"}),R="./lefthook.yml",nt=e=>`pre-commit:
70
+ `,ot="./.husky/pre-commit",v={exists:()=>c(ot),install:async t=>{await En("husky",{packageManager:t,workspace:await b(),silent:!0}),await x({scripts:{prepare:"husky"}})},init:t=>{let e=Et(t,"husky",{args:["init"]});try{kn(e,{stdio:"pipe"})}catch{}},create:async t=>{await Cn(".husky",{recursive:!0});let e=Et(t,"ultracite",{args:["fix"],short:t==="npm"}),n=Ht(e);await zt(ot,n)},update:async t=>{let e=await bn(ot,"utf-8"),n=Et(t,"ultracite",{args:["fix"],short:t==="npm"}),i=Ht(n);await zt(ot,`${e}
71
+ ${i}`)}}});var Vt={};Q(Vt,{lefthook:()=>B});import{execSync as jn}from"child_process";import{readFile as Pn,writeFile as H}from"fs/promises";import{addDevDependency as $n,dlxCommand as Xt}from"nypm";var Sn,On,Kt,N,Yt,B,Pt=R(()=>{"use strict";m();Sn=/(pre-commit:\s*\n\s*jobs:\s*\n)/,On=/(pre-commit:\s*\n)/,Kt=t=>Xt(t,"ultracite",{args:["fix"],short:t==="npm"}),N="./lefthook.yml",Yt=t=>`pre-commit:
81
72
  jobs:
82
- - run: ${it(e)}
73
+ - run: ${Kt(t)}
83
74
  glob:
84
75
  - "*.js"
85
76
  - "*.jsx"
@@ -89,7 +80,7 @@ ${n}`)}}});var rt={};z(rt,{lefthook:()=>O});import{execSync as Us}from"child_pro
89
80
  - "*.jsonc"
90
81
  - "*.css"
91
82
  stage_fixed: true
92
- `,O={exists:()=>f(R),install:async e=>{await _s("lefthook",{packageManager:e,workspace:await C(),silent:!0}),await v({scripts:{prepare:"lefthook install"}});let t=ot(e,"lefthook",{args:["install"],short:e==="npm"});Us(t,{stdio:"pipe"})},create:async e=>{let t=nt(e);await B(R,t)},update:async e=>{let t=await Is(R,"utf-8"),s=it(e),n=nt(e);if(t.includes(s))return;if(t.startsWith("# EXAMPLE USAGE:")){await B(R,n);return}if(t.includes("pre-commit:"))if(t.includes("jobs:")){let i=` - run: ${s}
83
+ `,B={exists:()=>c(N),install:async t=>{await $n("lefthook",{packageManager:t,workspace:await b(),silent:!0}),await x({scripts:{prepare:"lefthook install"}});let e=Xt(t,"lefthook",{args:["install"],short:t==="npm"});jn(e,{stdio:"pipe"})},create:async t=>{let e=Yt(t);await H(N,e)},update:async t=>{let e=await Pn(N,"utf-8"),n=Kt(t),i=Yt(t);if(e.includes(n))return;if(e.startsWith("# EXAMPLE USAGE:")){await H(N,i);return}if(e.includes("pre-commit:"))if(e.includes("jobs:")){let s=` - run: ${n}
93
84
  glob:
94
85
  - "*.js"
95
86
  - "*.jsx"
@@ -98,9 +89,9 @@ ${n}`)}}});var rt={};z(rt,{lefthook:()=>O});import{execSync as Us}from"child_pro
98
89
  - "*.json"
99
90
  - "*.jsonc"
100
91
  - "*.css"
101
- stage_fixed: true`,a=t.replace(Js,`$1${i}
102
- `);await B(R,a)}else{let i=` jobs:
103
- - run: ${s}
92
+ stage_fixed: true`,r=e.replace(Sn,`$1${s}
93
+ `);await H(N,r)}else{let s=` jobs:
94
+ - run: ${n}
104
95
  glob:
105
96
  - "*.js"
106
97
  - "*.jsx"
@@ -109,173 +100,51 @@ ${n}`)}}});var rt={};z(rt,{lefthook:()=>O});import{execSync as Us}from"child_pro
109
100
  - "*.json"
110
101
  - "*.jsonc"
111
102
  - "*.css"
112
- stage_fixed: true`,a=t.replace(Bs,`$1${i}
113
- `);await B(R,a)}else await B(R,`${t}
114
- ${n}`)}}});var ct={};z(ct,{preCommit:()=>W});import{readFile as Ls,writeFile as ve}from"fs/promises";import{dlxCommand as Ws}from"nypm";var L,Hs,at,zs,W,Ce=F(()=>{"use strict";h();L="./.pre-commit-config.yaml",Hs=/^repos:\s*\n/m,at=e=>Ws(e,"ultracite",{args:["fix"],short:e==="npm"}),zs=e=>`repos:
103
+ stage_fixed: true`,r=e.replace(On,`$1${s}
104
+ `);await H(N,r)}else await H(N,`${e}
105
+ ${i}`)}}});var Zt={};Q(Zt,{preCommit:()=>Y});import{readFile as vn,writeFile as $t}from"fs/promises";import{dlxCommand as Nn}from"nypm";var G,Fn,Qt,Rn,Y,St=R(()=>{"use strict";m();G="./.pre-commit-config.yaml",Fn=/^repos:\s*\n/m,Qt=t=>Nn(t,"ultracite",{args:["fix"],short:t==="npm"}),Rn=t=>`repos:
115
106
  - repo: local
116
107
  hooks:
117
108
  - id: ultracite
118
109
  name: ultracite
119
- entry: ${at(e)}
110
+ entry: ${Qt(t)}
120
111
  language: system
121
112
  types_or: [javascript, jsx, ts, tsx, json, css]
122
113
  pass_filenames: false
123
- `,W={exists:()=>f(L),create:async e=>{let t=zs(e);await ve(L,t)},update:async e=>{let t=await Ls(L,"utf-8"),s=at(e);if(t.includes("id: ultracite"))return;let n=` - repo: local
114
+ `,Y={exists:()=>c(G),create:async t=>{let e=Rn(t);await $t(G,e)},update:async t=>{let e=await vn(G,"utf-8"),n=Qt(t);if(e.includes("id: ultracite"))return;let i=` - repo: local
124
115
  hooks:
125
116
  - id: ultracite
126
117
  name: ultracite
127
- entry: ${s}
118
+ entry: ${n}
128
119
  language: system
129
120
  types_or: [javascript, jsx, ts, tsx, json, css]
130
121
  pass_filenames: false
131
- `;if(t.includes("repos:")){let o=t.replace(Hs,`repos:
132
- ${n}`);await ve(L,o)}else await ve(L,`${t}
122
+ `;if(e.includes("repos:")){let o=e.replace(Fn,`repos:
123
+ ${i}`);await $t(G,o)}else await $t(G,`${e}
133
124
  repos:
134
- ${n}`)}}});var Gs,je=F(()=>{Gs=Ee({"./husky.ts":()=>(be(),G(st)),"./lefthook.ts":()=>(xe(),G(rt)),"./lint-staged.ts":()=>(Pe(),G(lt)),"./pre-commit.ts":()=>(Ce(),G(ct))})});var lt={};z(lt,{lintStaged:()=>D});import{readFile as re,writeFile as E}from"fs/promises";import{pathToFileURL as Vs}from"url";import H from"deepmerge";import{parse as Se}from"jsonc-parser";import{addDevDependency as Ys,dlxCommand as Ks}from"nypm";var P,dt,Xs,Qs,Zs,qs,en,tn,sn,nn,on,$e,rn,D,Pe=F(()=>{"use strict";h();je();P=e=>({"*.{js,jsx,ts,tsx,json,jsonc,css,scss,md,mdx}":[Ks(e,"ultracite",{args:["fix"],short:e==="npm"})]}),dt=["./package.json","./.lintstagedrc.json","./.lintstagedrc.js","./.lintstagedrc.cjs","./.lintstagedrc.mjs","./lint-staged.config.js","./lint-staged.config.cjs","./lint-staged.config.mjs","./.lintstagedrc.yaml","./.lintstagedrc.yml","./.lintstagedrc"],Xs=(e,t,s,n)=>{let o=e.trim();if(o.includes(":")&&!o.startsWith("-")){s&&n.length>0&&(t[s]=n);let[i,...a]=o.split(":"),r=a.join(":").trim(),c=i.trim().replace(/['"]/g,"");return r&&r!==""?(r.startsWith("[")&&r.endsWith("]")?t[c]=r.slice(1,-1).split(",").map(p=>p.trim().replace(/['"]/g,"")):t[c]=r.replace(/['"]/g,""),{newCurrentKey:null,newCurrentArray:[]}):{newCurrentKey:c,newCurrentArray:[]}}if(o.startsWith("-")&&s){let i=[...n,o.slice(1).trim().replace(/['"]/g,"")];return{newCurrentKey:s,newCurrentArray:i}}return{newCurrentKey:s,newCurrentArray:n}},Qs=e=>{let t=e.split(`
135
- `).filter(i=>i.trim()&&!i.trim().startsWith("#")),s={},n=null,o=[];for(let i of t){let a=Xs(i,s,n,o);n=a.newCurrentKey,o=a.newCurrentArray}return n&&o.length>0&&(s[n]=o),s},Zs=e=>{let t="";for(let[s,n]of Object.entries(e))if(Array.isArray(n)){t+=`${s}:
136
- `;for(let o of n)t+=` - '${o}'
137
- `}else t+=`${s}: '${n}'
138
- `;return t},qs=async()=>{try{let e=Se(await re("./package.json","utf-8"));return e?e.type==="module":!1}catch{return!1}},en=async e=>{let t=Se(await re("./package.json","utf-8"));t&&(t["lint-staged"]?t["lint-staged"]=H(t["lint-staged"],P(e)):t["lint-staged"]=P(e),await E("./package.json",JSON.stringify(t,null,2)))},tn=async(e,t)=>{let s=await re(e,"utf-8"),n=Se(s);if(!n)return;let o=H(n,P(t));await E(e,JSON.stringify(o,null,2))},sn=async(e,t)=>{let s=await re(e,"utf-8"),n=Qs(s);if(!n)return;let o=H(n,P(t));await E(e,Zs(o))},nn=async(e,t)=>{let o=(await import(Vs(e).href)).default||{},i=H(o,P(t)),a=`export default ${JSON.stringify(i,null,2)};
139
- `;await E(e,a)},on=async(e,t)=>{delete de.cache[de.resolve(`./${e}`)];let s=Gs(`./${e}`),n=H(s,P(t)),o=`module.exports = ${JSON.stringify(n,null,2)};
140
- `;await E(e,o)},$e=async e=>{await E(".lintstagedrc.json",JSON.stringify(P(e),null,2))},rn=async(e,t)=>{if(e==="./package.json"){await en(t);return}if(e.endsWith(".json")||e==="./.lintstagedrc"){await tn(e,t);return}if(e.endsWith(".yaml")||e.endsWith(".yml")){await sn(e,t);return}let s=await qs();if(e.endsWith(".mjs")||e.endsWith(".js")&&s){try{await nn(e,t)}catch{await $e(t)}return}if(e.endsWith(".cjs")||e.endsWith(".js")&&!s)try{await on(e,t)}catch{await $e(t)}},D={exists:async()=>{for(let e of dt)if(await f(e))return!0;return!1},install:async e=>{await Ys("lint-staged",{packageManager:e,workspace:await C(),silent:!0})},create:async e=>{await E(".lintstagedrc.json",JSON.stringify(P(e),null,2))},update:async e=>{let t=null;for(let s of dt)if(await f(s)){t=s;break}if(!t){await $e(e);return}await rn(t,e)}}});import{initTRPC as Fn}from"@trpc/server";import{createCli as Nn}from"trpc-cli";import d from"zod";var k={name:"ultracite",description:"The AI-ready formatter that helps you write and generate code faster.",version:"6.5.1",type:"module",bin:{ultracite:"dist/index.js"},files:["config","dist","README.md"],scripts:{build:"tsup",test:"bun test","test:coverage":"bun test --coverage"},exports:{"./*":"./config/*/biome.jsonc"},author:"Hayden Bleasel <hello@haydenbleasel.com>",bugs:{url:"https://github.com/haydenbleasel/ultracite/issues"},homepage:"https://www.ultracite.ai/",keywords:["ultracite","biome","linter","formatter","fixer"],license:"MIT",publishConfig:{access:"public",registry:"https://registry.npmjs.org/"},repository:{type:"git",url:"git+https://github.com/haydenbleasel/ultracite.git"},devDependencies:{"@biomejs/biome":"2.3.10","@types/node":"^25.0.0",tsup:"^8.5.1",turbo:"^2.6.3"},dependencies:{"@clack/prompts":"^0.11.0","@trpc/server":"^11.8.0",deepmerge:"^4.3.1",glob:"^13.0.0","jsonc-parser":"^3.3.1",nypm:"^0.6.2",picocolors:"^1.1.1","trpc-cli":"^0.12.1",zod:"^4.1.13"},packageManager:"bun@1.3.4"};import{spawnSync as Mt}from"child_process";import Tt from"process";import{detectPackageManager as Ut,dlxCommand as It}from"nypm";import l from"picocolors";var b=e=>`\x1B[38;5;208m${e}\x1B[39m`,Ae=(e,t)=>{let n=e.slice(0,t[0]).split(`
141
- `);return{line:n.length,column:(n.at(-1)?.length??0)+1}},xt=(e,t)=>{let s=e.split(`
142
- `),{line:n,column:o}=Ae(e,t),i=[],a=Math.max(1,n-1),r=Math.min(s.length,n+2);for(let c=a;c<=r;c++){let p=String(c).padStart(5," "),u=s[c-1]||"";if(c===n){i.push(`${b(">")}${l.dim(p)} ${l.gray("\u2502")} ${u}`);let x=" ".repeat(o-1),y=Math.min(t[1]-t[0],u.length-o+1),m="^".repeat(Math.max(1,y));i.push(`${l.dim(" ")} ${l.gray("\u2502")} ${x}${b(m)}`)}else i.push(` ${l.dim(p)} ${l.gray("\u2502")} ${u}`)}return i},vt=e=>{let t=e.secs*1e3+e.nanos/1e6;return t<1e3?`${Math.round(t)}ms`:`${(t/1e3).toFixed(2)}s`},Ct=l.dim("\u2500".repeat(60)),jt=e=>e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),Pt=e=>{let t=e.split("/");if(t.length<3||t[0]!=="lint")return null;let s=t.at(-1);return s?`https://biomejs.dev/linter/rules/${jt(s)}/`:null},$t=e=>["",`${b("Ultracite")} ${b(`v${k.version}`)} ${e}`],St=(e,t)=>{let s=[],n=e.changed+e.unchanged,o=e.errors+e.warnings,i=vt(e.duration);if(o>0){let r=o!==1?"errors":"error";s.push(`${l.dim("Found")} ${o} ${r}${l.dim(".")}`)}let a=n!==1?"files":"file";if(s.push(`${l.green("\u2713")} ${l.dim("Finished in")} ${i} ${l.dim("on")} ${n} ${a}${l.dim(".")}`),t==="fix"&&e.changed>0){let r=e.changed!==1?"files":"file";s.push(`${l.dim("Fixed")} ${e.changed} ${r}${l.dim(".")}`)}if(t==="fix"&&e.suggestedFixesSkipped>0){let r=e.suggestedFixesSkipped!==1?"fixes":"fix";s.push(`${l.yellow("!")} ${l.dim("Skipped")} ${e.suggestedFixesSkipped} ${l.dim("unsafe")} ${r}${l.dim(".")}`),s.push(` ${l.dim("Run with")} ${l.cyan("--unsafe")} ${l.dim("to apply them.")}`)}return s},Rt=e=>{let t=[],{location:s,category:n,description:o,advices:i}=e,a=s.path.file,r=a;if(s.span&&s.sourceCode){let{line:p,column:u}=Ae(s.sourceCode,s.span);r=`${a}:${p}:${u}`}if(t.push(`${b(r)} ${l.dim(n)}`),t.push(l.dim(o)),s.span&&s.sourceCode){t.push("");let p=xt(s.sourceCode,s.span);for(let u of p)t.push(` ${u}`)}for(let p of i.advices)if(p.log){let[u,x]=p.log,y=b(u==="info"?"i":"!"),m=l.dim(x.map(g=>g.content).join(""));t.push(""),t.push(` ${y} ${m}`)}let c=Pt(n);return c&&(t.push(""),t.push(` ${l.cyan("\u2192")} ${l.dim("Docs:")} ${l.cyan(c)}`)),t.push(""),t.push(`${Ct}`),t.push(""),t},Et=(e,t)=>{if(e.length===0)return[];let s=[""],n=t==="fix"?"Here are the issues we couldn't fix automatically:":"Issues found:";s.push(`${l.yellow(n)}`),s.push("");for(let o of e)s.push(...Rt(o));return s},V=(e,t)=>{if(!e.trim())return{output:`${b("Ultracite")} ${b(`v${k.version}`)} ${l.magenta(t)}
143
- ${l.red("Error:")} No output received from Biome. The command may have failed silently.`,hasErrors:!0};try{let s=JSON.parse(e),{summary:n,diagnostics:o}=s;return{output:[...$t(t),...St(n,t),...Et(o,t)].join(`
144
- `),hasErrors:n.errors>0}}catch{return{output:`${b("Ultracite")} ${b(`v${k.version}`)} ${l.magenta(t)}
145
- ${l.red("Error:")} Failed to parse Biome output.
146
-
147
- Raw output:
148
- ${e}`,hasErrors:!0}}};h();var fe=async e=>{let t=e?.[0]||[],s=e?.[1]["diagnostic-level"],n=["check","--no-errors-on-unmatched","--reporter=json"];s&&n.push(`--diagnostic-level=${s}`),t.length>0?n.push(...K(t)):n.push("./");let i=(await Ut(Tt.cwd()))?.name||"npm",a=It(i,"@biomejs/biome",{args:n,short:i==="npm"}),r=Mt(a,{stdio:"pipe",shell:!0,maxBuffer:100*1024*1024});if(r.error)throw new Error(`Failed to run Ultracite: ${r.error.message}`);let c=r.stdout?.toString()||"",p=r.stderr?.toString()||"",u=c.trim().startsWith("{")?c:p,{output:x,hasErrors:y}=V(u,"check");return console.log(x),{hasErrors:y}};import{spawnSync as qt}from"child_process";import{existsSync as I}from"fs";import{readFile as Ie}from"fs/promises";import{join as _}from"path";import $ from"process";import{intro as es,log as Z,outro as ue,spinner as ts}from"@clack/prompts";import{parse as ss}from"jsonc-parser";import{detectPackageManager as _e,dlxCommand as Je}from"nypm";h();import{readFile as Ne,unlink as _t,writeFile as Jt}from"fs/promises";import{parse as Oe}from"jsonc-parser";import{removeDependency as Bt}from"nypm";var X=[".eslintrc",".eslintrc.js",".eslintrc.json",".eslintrc.yml",".eslintrc.yaml",".eslintrc.config.js","eslint.config.js","eslint.config.mjs","eslint.config.cjs",".eslintignore"],De=async()=>{try{let e=await Ne("package.json","utf-8"),t=Oe(e);if(!t||typeof t!="object")return[];let s=t.dependencies||{},n=t.devDependencies||{},o={...s,...n};return Object.keys(o).filter(i=>i.includes("eslint"))}catch{return[]}},Lt=async(e,t)=>{if(t.length!==0)try{for(let s of t)await Bt(s,{packageManager:e})}catch(s){console.warn(s)}},Wt=async()=>{let e=[];for(let t of X)if(await f(t))try{await _t(t),e.push(t)}catch(s){console.warn(s)}return e},Ht=async()=>{let e="./.vscode/settings.json";if(!await f(e))return!1;try{let t=await Ne(e,"utf-8"),s=Oe(t);if(!s||typeof s!="object")return!1;let n=!1,o={...s},i=["eslint.enable","eslint.format.enable","eslint.validate","eslint.workingDirectories","eslint.codeAction.showDocumentation","eslint.run","eslint.autoFixOnSave","eslint.quiet","eslint.packageManager","eslint.options","eslint.trace.server"];for(let a of i)a in o&&(delete o[a],n=!0);if("editor.codeActionsOnSave"in o){let a=o["editor.codeActionsOnSave"];if(a&&typeof a=="object"){let r=["source.fixAll.eslint","source.organizeImports.eslint"];for(let c of r)c in a&&(delete a[c],n=!0);Object.keys(a).length===0&&(o["editor.codeActionsOnSave"]=void 0)}}return n?(await Jt(e,JSON.stringify(o,null,2)),!0):!1}catch(t){return console.warn(t),!1}},zt=async()=>{if((await De()).length>0)return!0;for(let t of X)if(await f(t))return!0;return!1},me={hasEsLint:zt,remove:async e=>{let t=await De();await Lt(e,t);let s=await Wt(),n=await Ht();return{packagesRemoved:t,filesRemoved:s,vsCodeCleaned:n}}};h();import{readFile as Me,unlink as Gt,writeFile as Vt}from"fs/promises";import{parse as Te}from"jsonc-parser";import{removeDependency as Yt}from"nypm";var Q=[".prettierrc",".prettierrc.js",".prettierrc.json",".prettierrc.yml",".prettierrc.yaml",".prettierrc.config.js","prettier.config.js","prettier.config.mjs",".prettierignore"],Ue=async()=>{try{let e=await Me("package.json","utf-8"),t=Te(e);if(!t||typeof t!="object")return[];let s=t.dependencies||{},n=t.devDependencies||{},o={...s,...n};return Object.keys(o).filter(i=>i.includes("prettier"))}catch{return[]}},Kt=async(e,t)=>{if(t.length!==0)try{for(let s of t)await Yt(s,{packageManager:e})}catch(s){console.warn(s)}},Xt=async()=>{let e=[];for(let t of Q)if(await f(t))try{await Gt(t),e.push(t)}catch(s){console.warn(s)}return e},Qt=async()=>{let e="./.vscode/settings.json";if(!await f(e))return!1;try{let t=await Me(e,"utf-8"),s=Te(t);if(!s||typeof s!="object")return!1;let n=!1,o={...s},i=["editor.defaultFormatter","prettier.enable","prettier.requireConfig","prettier.configPath","prettier.printWidth","prettier.tabWidth","prettier.useTabs","prettier.semi","prettier.singleQuote","prettier.quoteProps","prettier.trailingComma","prettier.bracketSpacing","prettier.arrowParens","prettier.endOfLine"];for(let r of i)r in o&&(r==="editor.defaultFormatter"&&o[r]==="esbenp.prettier-vscode"||r!=="editor.defaultFormatter")&&(delete o[r],n=!0);let a=Object.keys(o).filter(r=>r.startsWith("[")&&r.includes("javascript"));for(let r of a){let c=o[r];c&&typeof c=="object"&&"editor.defaultFormatter"in c&&c["editor.defaultFormatter"]==="esbenp.prettier-vscode"&&(delete c["editor.defaultFormatter"],n=!0,Object.keys(c).length===0&&delete o[r])}return n?(await Vt(e,JSON.stringify(o,null,2)),!0):!1}catch(t){return console.warn(t),!1}},Zt=async()=>{if((await Ue()).length>0)return!0;for(let t of Q)if(await f(t))return!0;return!1},pe={hasPrettier:Zt,remove:async e=>{let t=await Ue();await Kt(e,t);let s=await Xt(),n=await Qt();return{packagesRemoved:t,filesRemoved:s,vsCodeCleaned:n}}};h();var ns=async()=>{let t=(await _e($.cwd()))?.name||"npm",s=Je(t,"@biomejs/biome",{args:["--version"],short:t==="npm"}),n=qt(s,{shell:!0,encoding:"utf-8"});return n.status===0&&n.stdout?{name:"Biome installation",status:"pass",message:`Biome is installed (${n.stdout.trim()})`}:{name:"Biome installation",status:"fail",message:"Biome is not installed or not accessible"}},os=async()=>{let e=_($.cwd(),"biome.json"),t=_($.cwd(),"biome.jsonc"),s=null;if(I(e)?s=e:I(t)&&(s=t),!s)return{name:"Biome configuration",status:"fail",message:"No biome.json or biome.jsonc file found"};try{let n=await Ie(s,"utf-8"),o=ss(n);return Array.isArray(o?.extends)&&o.extends.includes("ultracite/core")?{name:"Biome configuration",status:"pass",message:"biome.json(c) extends ultracite/core"}:{name:"Biome configuration",status:"warn",message:"biome.json(c) exists but doesn't extend ultracite/core"}}catch{return{name:"Biome configuration",status:"fail",message:"Could not parse biome.json(c) file"}}},is=async()=>{let e=_($.cwd(),"package.json");if(!I(e))return{name:"Ultracite dependency",status:"warn",message:"No package.json found"};try{let t=JSON.parse(await Ie(e,"utf-8")),s=t.dependencies?.ultracite||t.devDependencies?.ultracite||t.peerDependencies?.ultracite;return s?{name:"Ultracite dependency",status:"pass",message:`Ultracite is in package.json (${s})`}:{name:"Ultracite dependency",status:"warn",message:"Ultracite not found in package.json dependencies"}}catch{return{name:"Ultracite dependency",status:"warn",message:"Could not parse package.json"}}},rs=()=>{let e=Q.some(s=>I(_($.cwd(),s))),t=X.some(s=>I(_($.cwd(),s)));if(e||t){let s=[];return e&&s.push("Prettier"),t&&s.push("ESLint"),{name:"Conflicting tools",status:"warn",message:`Found potentially conflicting tools: ${s.join(", ")}`}}return{name:"Conflicting tools",status:"pass",message:"No conflicting formatting/linting tools found"}},q=async(e,t)=>{let s=ts();s.start(`Checking ${t}...`);let n=await e();return n.status==="pass"||n.status,s.stop(n.message),n},Be=async()=>{es(Y);let t=(await _e($.cwd()))?.name||"npm",s=Je(t,"ultracite",{args:["init"],short:t==="npm"}),n=[];n.push(await q(ns,"Biome installation")),n.push(await q(os,"Biome configuration")),n.push(await q(is,"Ultracite dependency")),n.push(await q(rs,"conflicting tools"));let o=n.filter(r=>r.status==="pass").length,i=n.filter(r=>r.status==="fail").length,a=n.filter(r=>r.status==="warn").length;if(Z.info(`Summary: ${o} passed, ${a} warnings, ${i} failed`),i>0)throw Z.error(`Some checks failed. Run '${s}' to fix issues.`),ue("Doctor complete"),new Error("Doctor checks failed");if(a>0){Z.warn(`Some optional improvements available. Run '${s}' to configure.`),ue("Doctor complete");return}Z.success("Everything looks good!"),ue("Doctor complete")};import{spawnSync as as}from"child_process";import cs from"process";import{detectPackageManager as ls,dlxCommand as ds}from"nypm";h();var ge=async(e,t={})=>{let s=["check","--write","--no-errors-on-unmatched","--reporter=json"];t.unsafe&&s.push("--unsafe"),e.length>0?s.push(...K(e)):s.push("./");let o=(await ls(cs.cwd()))?.name||"npm",i=ds(o,"@biomejs/biome",{args:s,short:o==="npm"}),a=as(i,{stdio:"pipe",shell:!0,maxBuffer:100*1024*1024});if(a.error)throw new Error(`Failed to run Ultracite: ${a.error.message}`);let r=a.stdout?.toString()||"",c=a.stderr?.toString()||"",p=r.trim().startsWith("{")?r:c,{output:u,hasErrors:x}=V(p,"fix");return console.log(u),{hasErrors:x}};import{packageManagers as fs}from"nypm";var j={packageManagers:fs.map(e=>e.name),editorConfigs:["vscode","zed"],agents:["vscode-copilot","cursor","windsurf","zed","claude","codex","kiro","cline","amp","aider","firebase-studio","open-hands","gemini-cli","junie","augmentcode","kilo-code","goose","roo-code","warp","droid","antigravity"],integrations:["husky","lefthook","lint-staged","pre-commit"],hooks:["cursor","claude"],frameworks:["react","next","solid","vue","svelte","qwik","remix","angular","astro"],migrations:["eslint","prettier"]};import un from"process";import{cancel as M,intro as gn,isCancel as T,log as ae,multiselect as U,spinner as w}from"@clack/prompts";import{addDevDependency as hn,detectPackageManager as yn}from"nypm";import{mkdir as ms,readFile as ps,writeFile as ee}from"fs/promises";import{dirname as us}from"path";import{dlxCommand as gs}from"nypm";var Le={"vscode-copilot":{path:"./.github/copilot-instructions.md",header:`---
149
- applyTo: "**/*.{ts,tsx,js,jsx}"
150
- ---`,appendMode:!0},cursor:{path:"./.cursor/rules/ultracite.mdc",header:`---
151
- description: Ultracite Rules - AI-Ready Formatter and Linter
152
- globs: "**/*.{ts,tsx,js,jsx,json,jsonc,html,vue,svelte,astro,css,yaml,yml,graphql,gql,md,mdx,grit}"
153
- alwaysApply: false
154
- ---`},windsurf:{path:"./.windsurf/rules/ultracite.md"},zed:{path:"./.rules",appendMode:!0},claude:{path:"./.claude/CLAUDE.md",appendMode:!0},codex:{path:"./AGENTS.md",appendMode:!0},kiro:{path:"./.kiro/steering/ultracite.md"},cline:{path:"./.clinerules",appendMode:!0},amp:{path:"./AGENT.md",appendMode:!0},aider:{path:"./ultracite.md"},"firebase-studio":{path:"./.idx/airules.md",appendMode:!0},"open-hands":{path:"./.openhands/microagents/repo.md",appendMode:!0},"gemini-cli":{path:"./GEMINI.md",appendMode:!0},junie:{path:"./.junie/guidelines.md",appendMode:!0},augmentcode:{path:"./.augment/rules/ultracite.md"},"kilo-code":{path:"./.kilocode/rules/ultracite.md"},goose:{path:"./.goosehints",appendMode:!0},"roo-code":{path:"./.roo/rules/ultracite.md",appendMode:!0},warp:{path:"./WARP.md",appendMode:!0},droid:{path:"./AGENTS.md",appendMode:!0},antigravity:{path:"./.agent/rules/ultracite.md"}},We={cursor:{path:"./.cursor/hooks.json"},claude:{path:"./.claude/settings.json"}};h();var He=e=>`# Ultracite Code Standards
155
-
156
- This project uses **Ultracite**, a zero-config Biome preset that enforces strict code quality standards through automated formatting and linting.
157
-
158
- ## Quick Reference
159
-
160
- - **Format code**: \`${e} ultracite fix\`
161
- - **Check for issues**: \`${e} ultracite check\`
162
- - **Diagnose setup**: \`${e} ultracite doctor\`
163
-
164
- Biome (the underlying engine) provides extremely fast Rust-based linting and formatting. Most issues are automatically fixable.
165
-
166
- ---
167
-
168
- ## Core Principles
169
-
170
- Write code that is **accessible, performant, type-safe, and maintainable**. Focus on clarity and explicit intent over brevity.
171
-
172
- ### Type Safety & Explicitness
173
-
174
- - Use explicit types for function parameters and return values when they enhance clarity
175
- - Prefer \`unknown\` over \`any\` when the type is genuinely unknown
176
- - Use const assertions (\`as const\`) for immutable values and literal types
177
- - Leverage TypeScript's type narrowing instead of type assertions
178
- - Use meaningful variable names instead of magic numbers - extract constants with descriptive names
179
-
180
- ### Modern JavaScript/TypeScript
181
-
182
- - Use arrow functions for callbacks and short functions
183
- - Prefer \`for...of\` loops over \`.forEach()\` and indexed \`for\` loops
184
- - Use optional chaining (\`?.\`) and nullish coalescing (\`??\`) for safer property access
185
- - Prefer template literals over string concatenation
186
- - Use destructuring for object and array assignments
187
- - Use \`const\` by default, \`let\` only when reassignment is needed, never \`var\`
188
-
189
- ### Async & Promises
190
-
191
- - Always \`await\` promises in async functions - don't forget to use the return value
192
- - Use \`async/await\` syntax instead of promise chains for better readability
193
- - Handle errors appropriately in async code with try-catch blocks
194
- - Don't use async functions as Promise executors
195
-
196
- ### React & JSX
197
-
198
- - Use function components over class components
199
- - Call hooks at the top level only, never conditionally
200
- - Specify all dependencies in hook dependency arrays correctly
201
- - Use the \`key\` prop for elements in iterables (prefer unique IDs over array indices)
202
- - Nest children between opening and closing tags instead of passing as props
203
- - Don't define components inside other components
204
- - Use semantic HTML and ARIA attributes for accessibility:
205
- - Provide meaningful alt text for images
206
- - Use proper heading hierarchy
207
- - Add labels for form inputs
208
- - Include keyboard event handlers alongside mouse events
209
- - Use semantic elements (\`<button>\`, \`<nav>\`, etc.) instead of divs with roles
210
-
211
- ### Error Handling & Debugging
212
-
213
- - Remove \`console.log\`, \`debugger\`, and \`alert\` statements from production code
214
- - Throw \`Error\` objects with descriptive messages, not strings or other values
215
- - Use \`try-catch\` blocks meaningfully - don't catch errors just to rethrow them
216
- - Prefer early returns over nested conditionals for error cases
217
-
218
- ### Code Organization
219
-
220
- - Keep functions focused and under reasonable cognitive complexity limits
221
- - Extract complex conditions into well-named boolean variables
222
- - Use early returns to reduce nesting
223
- - Prefer simple conditionals over nested ternary operators
224
- - Group related code together and separate concerns
225
-
226
- ### Security
227
-
228
- - Add \`rel="noopener"\` when using \`target="_blank"\` on links
229
- - Avoid \`dangerouslySetInnerHTML\` unless absolutely necessary
230
- - Don't use \`eval()\` or assign directly to \`document.cookie\`
231
- - Validate and sanitize user input
232
-
233
- ### Performance
234
-
235
- - Avoid spread syntax in accumulators within loops
236
- - Use top-level regex literals instead of creating them in loops
237
- - Prefer specific imports over namespace imports
238
- - Avoid barrel files (index files that re-export everything)
239
- - Use proper image components (e.g., Next.js \`<Image>\`) over \`<img>\` tags
240
-
241
- ### Framework-Specific Guidance
242
-
243
- **Next.js:**
244
- - Use Next.js \`<Image>\` component for images
245
- - Use \`next/head\` or App Router metadata API for head elements
246
- - Use Server Components for async data fetching instead of async Client Components
247
-
248
- **React 19+:**
249
- - Use ref as a prop instead of \`React.forwardRef\`
250
-
251
- **Solid/Svelte/Vue/Qwik:**
252
- - Use \`class\` and \`for\` attributes (not \`className\` or \`htmlFor\`)
253
-
254
- ---
255
-
256
- ## Testing
257
-
258
- - Write assertions inside \`it()\` or \`test()\` blocks
259
- - Avoid done callbacks in async tests - use async/await instead
260
- - Don't use \`.only\` or \`.skip\` in committed code
261
- - Keep test suites reasonably flat - avoid excessive \`describe\` nesting
262
-
263
- ## When Biome Can't Help
264
-
265
- Biome's linter will catch most issues automatically. Focus your attention on:
266
-
267
- 1. **Business logic correctness** - Biome can't validate your algorithms
268
- 2. **Meaningful naming** - Use descriptive names for functions, variables, and types
269
- 3. **Architecture decisions** - Component structure, data flow, and API design
270
- 4. **Edge cases** - Handle boundary conditions and error states
271
- 5. **User experience** - Accessibility, performance, and usability considerations
272
- 6. **Documentation** - Add comments for complex logic, but prefer self-documenting code
273
-
274
- ---
275
-
276
- Most formatting and common issues are automatically fixed by Biome. Run \`${e} ultracite fix\` before committing to ensure compliance.
277
- `;var ze=(e,t)=>{let s=Le[e],n=gs(t,""),o=He(n),i=s.header?`${s.header}
278
-
279
- ${o}`:o,a=async()=>{let r=us(s.path);if(r!=="."){let c=r.startsWith("./")?r.slice(2):r;await ms(c,{recursive:!0})}};return{exists:()=>f(s.path),create:async()=>{await a(),await ee(s.path,i)},update:async()=>{if(await a(),s.appendMode){if(!await f(s.path)){await ee(s.path,i);return}let r=await ps(s.path,"utf-8");if(r.includes(o.trim()))return;await ee(s.path,`${r}
280
-
281
- ${o}`)}else await ee(s.path,i)}}};h();import{readFile as hs,writeFile as Ge}from"fs/promises";import ys from"deepmerge";import{parse as ws}from"jsonc-parser";var Ve={$schema:"./node_modules/@biomejs/biome/configuration_schema.json",extends:["ultracite/core"]},he=async()=>await f("./biome.json")?"./biome.json":"./biome.jsonc",te={exists:async()=>{let e=await he();return f(e)},create:async e=>{let t=await he(),s=["ultracite/core"];if(e?.frameworks&&e.frameworks.length>0)for(let o of e.frameworks)s.push(`ultracite/${o}`);let n={...Ve,extends:s};return Ge(t,JSON.stringify(n,null,2))},update:async e=>{let t=await he(),s=await hs(t,"utf-8"),o=ws(s)||{},a=[...o.extends&&Array.isArray(o.extends)?o.extends:[]];if(a.includes("ultracite/core")||a.push("ultracite/core"),e?.frameworks&&e.frameworks.length>0)for(let p of e.frameworks){let u=`ultracite/${p}`;a.includes(u)||a.push(u)}o.extends=a;let r={$schema:Ve.$schema},c=ys(o,r);await Ge(t,JSON.stringify(c,null,2))}};h();import{spawnSync as ks}from"child_process";import{mkdir as bs,readFile as xs,writeFile as Ye}from"fs/promises";import vs from"deepmerge";import{parse as Cs}from"jsonc-parser";var ye={"editor.defaultFormatter":"esbenp.prettier-vscode","[javascript]":{"editor.defaultFormatter":"biomejs.biome"},"[typescript]":{"editor.defaultFormatter":"biomejs.biome"},"[javascriptreact]":{"editor.defaultFormatter":"biomejs.biome"},"[typescriptreact]":{"editor.defaultFormatter":"biomejs.biome"},"[json]":{"editor.defaultFormatter":"biomejs.biome"},"[jsonc]":{"editor.defaultFormatter":"biomejs.biome"},"[css]":{"editor.defaultFormatter":"biomejs.biome"},"[graphql]":{"editor.defaultFormatter":"biomejs.biome"},"typescript.tsdk":"node_modules/typescript/lib","editor.formatOnSave":!0,"editor.formatOnPaste":!0,"emmet.showExpandedAbbreviation":"never","editor.codeActionsOnSave":{"source.fixAll.biome":"explicit","source.organizeImports.biome":"explicit"}};var se="./.vscode/settings.json",J={exists:()=>f(se),create:async()=>{await bs(".vscode",{recursive:!0}),await Ye(se,JSON.stringify(ye,null,2))},update:async()=>{let e=await xs(se,"utf-8"),s=Cs(e)||{},n=vs(s,ye);await Ye(se,JSON.stringify(n,null,2))},extension:()=>ks("code --install-extension biomejs.biome",{stdio:"pipe",shell:!0})};h();import{mkdir as js,readFile as Ps,writeFile as Ke}from"fs/promises";import $s from"deepmerge";import{parse as Ss}from"jsonc-parser";var we={formatter:"language_server",format_on_save:"on",languages:{JavaScript:{formatter:{language_server:{name:"biome"}},code_actions_on_format:{"source.fixAll.biome":!0,"source.organizeImports.biome":!0}},TypeScript:{formatter:{language_server:{name:"biome"}},code_actions_on_format:{"source.fixAll.biome":!0,"source.organizeImports.biome":!0}},TSX:{formatter:{language_server:{name:"biome"}},code_actions_on_format:{"source.fixAll.biome":!0,"source.organizeImports.biome":!0}}},lsp:{"typescript-language-server":{settings:{typescript:{preferences:{includePackageJsonAutoImports:"on"}}}}}};var ne="./.zed/settings.json",oe={exists:()=>f(ne),create:async()=>{await js(".zed",{recursive:!0}),await Ke(ne,JSON.stringify(we,null,2))},update:async()=>{let e=await Ps(ne,"utf-8"),s=Ss(e)||{},n=$s(s,we);await Ke(ne,JSON.stringify(n,null,2))}};import{mkdir as Rs,readFile as Xe,writeFile as N}from"fs/promises";import{dirname as Es}from"path";import{dlxCommand as As}from"nypm";h();var Qe=e=>({version:1,hooks:{afterFileEdit:[{command:e}]}}),Ze=e=>({hooks:{PostToolUse:[{matcher:"Edit|Write",hooks:[{type:"command",command:e}]}]}}),Fs=async(e,t)=>{if(!await f(e)){await N(e,JSON.stringify(Qe(t),null,2));return}let s=await Xe(e,"utf-8"),n=JSON.parse(s);n.hooks.afterFileEdit.some(i=>i.command.includes("ultracite"))||(n.hooks.afterFileEdit.push({command:t}),await N(e,JSON.stringify(n,null,2)))},Ns=async(e,t)=>{if(!await f(e)){await N(e,JSON.stringify(Ze(t),null,2));return}let s=await Xe(e,"utf-8"),n=JSON.parse(s);n.hooks||(n.hooks={}),n.hooks.PostToolUse||(n.hooks.PostToolUse=[]),n.hooks.PostToolUse.some(i=>i.hooks?.some(a=>a.command.includes("ultracite")))||(n.hooks.PostToolUse.push({matcher:"Edit|Write",hooks:[{type:"command",command:t}]}),await N(e,JSON.stringify(n,null,2)))},qe=(e,t)=>{let s=We[e],n=As(t,"ultracite",{args:["fix"],short:t==="npm"}),o=async()=>{let i=Es(s.path);if(i!=="."){let a=i.startsWith("./")?i.slice(2):i;await Rs(a,{recursive:!0})}};return{exists:()=>f(s.path),create:async()=>{await o(),e==="cursor"?await N(s.path,JSON.stringify(Qe(n),null,2)):e==="claude"&&await N(s.path,JSON.stringify(Ze(n),null,2))},update:async()=>{await o(),e==="cursor"?await Fs(s.path,n):e==="claude"&&await Ns(s.path,n)}}};be();xe();Pe();Ce();import{readFile as an,writeFile as ft}from"fs/promises";import{glob as cn}from"glob";import{applyEdits as ln,modify as dn,parse as fn}from"jsonc-parser";var mt=async()=>{try{return await cn("**/tsconfig*.json",{ignore:["**/node_modules/**","**/dist/**","**/build/**","**/.next/**"],absolute:!1})}catch{return[]}},mn=e=>{if(!e)return!1;let t=e.compilerOptions;return t?t.strict===!0||t.strictNullChecks===!0:!1},pn=async e=>{try{let t=await an(e,"utf-8"),s=fn(t);if(mn(s))return;if(s===void 0){await ft(e,JSON.stringify({compilerOptions:{strictNullChecks:!0}},null,2));return}let o=dn(t,["compilerOptions","strictNullChecks"],!0,{formattingOptions:{tabSize:2,insertSpaces:!0}}),i=ln(t,o);await ft(e,i)}catch(t){console.warn(`Failed to update ${e}:`,t)}},Re={exists:async()=>(await mt()).length>0,update:async()=>{let e=await mt();if(e.length===0){console.warn("No tsconfig.json files found in the project");return}await Promise.all(e.map(t=>pn(t)))}};h();var pt=k.devDependencies["@biomejs/biome"],ut=k.version,wn=async(e,t=!0,s=!1)=>{let n=w();s||n.start("Installing dependencies...");let o=[`ultracite@${ut}`,`@biomejs/biome@${pt}`];if(t)for(let i of o)await hn(i,{packageManager:e,workspace:await C(),silent:!0});else await v({devDependencies:{"@biomejs/biome":pt,ultracite:ut}});s||n.stop("Dependencies installed.")},kn=async(e=!1)=>{let t=w();if(e||t.start("Checking for tsconfig.json files..."),await Re.exists()){e||t.message("Found tsconfig.json files, updating with strictNullChecks..."),await Re.update(),e||t.stop("tsconfig.json files updated.");return}e||t.stop("No tsconfig.json files found, skipping.")},bn=async(e=!1)=>{let t=w();if(e||t.start("Checking for .vscode/settings.json..."),await J.exists()){e||t.message("settings.json found, updating..."),await J.update(),e||t.stop("settings.json updated.");return}e||t.message("settings.json not found, creating..."),await J.create(),e||(t.message("settings.json created."),t.message("Installing Biome extension..."));try{let s=J.extension();e||(s.status===0?t.stop("settings.json created and Biome extension installed."):t.stop("settings.json created. Install Biome extension manually."))}catch{e||t.stop("settings.json created. Install Biome extension manually.")}},xn=async(e=!1)=>{let t=w();if(e||t.start("Checking for .zed/settings.json..."),await oe.exists()){e||t.message("settings.json found, updating..."),await oe.update(),e||t.stop("settings.json updated.");return}e||t.message("settings.json not found, creating..."),await oe.create(),e||t.message("settings.json created. Install the Biome extension: https://biomejs.dev/reference/zed/")},vn=async(e,t=!1)=>{let s=w();if(t||s.start("Checking for Biome configuration..."),await te.exists()){t||s.message("Biome configuration found, updating..."),await te.update({frameworks:e}),t||s.stop("Biome configuration updated.");return}t||s.message("Biome configuration not found, creating..."),await te.create({frameworks:e}),t||s.stop("Biome configuration created.")},Cn=async(e,t=!0,s=!1)=>{let n=w();if(s||(n.start("Initializing pre-commit hooks..."),n.message("Installing Husky...")),t?await S.install(e):await v({devDependencies:{husky:"latest"},scripts:{prepare:"husky"}}),s||n.message("Initializing Husky..."),S.init(e),await S.exists()){s||n.message("Pre-commit hook found, updating..."),await S.update(e),s||n.stop("Pre-commit hook updated.");return}s||n.message("Pre-commit hook not found, creating..."),await S.create(e),s||n.stop("Pre-commit hook created.")},jn=async(e,t=!0,s=!1)=>{let n=w();if(s||(n.start("Initializing lefthook..."),n.message("Installing lefthook...")),t?await O.install(e):await v({devDependencies:{lefthook:"latest"}}),await O.exists()){s||n.message("lefthook.yml found, updating..."),await O.update(e),s||n.stop("lefthook.yml updated.");return}s||n.message("lefthook.yml not found, creating..."),await O.create(e),s||n.stop("lefthook.yml created.")},Pn=async(e,t=!0,s=!1)=>{let n=w();if(s||(n.start("Initializing lint-staged..."),n.message("Installing lint-staged...")),t?await D.install(e):await v({devDependencies:{"lint-staged":"latest"}}),await D.exists()){s||n.message("lint-staged found, updating..."),await D.update(e),s||n.stop("lint-staged updated.");return}s||n.message("lint-staged not found, creating..."),await D.create(e),s||n.stop("lint-staged created.")},$n=async(e,t=!1)=>{let s=w();if(t||s.start("Initializing pre-commit..."),await W.exists()){t||s.message(".pre-commit-config.yaml found, updating..."),await W.update(e),t||s.stop(".pre-commit-config.yaml updated.");return}t||s.message(".pre-commit-config.yaml not found, creating..."),await W.create(e),t||s.stop(".pre-commit-config.yaml created.")},Sn=async(e,t,s,n=!1)=>{let o=w();n||o.start(`Checking for ${t}...`);let i=ze(e,s);if(await i.exists()){n||o.message(`${t} found, updating...`),await i.update(),n||o.stop(`${t} updated.`);return}n||o.message(`${t} not found, creating...`),await i.create(),n||o.stop(`${t} created.`)},Rn=async(e,t,s,n=!1)=>{let o=w();n||o.start(`Checking for ${t} hooks...`);let i=qe(e,s);if(await i.exists()){n||o.message(`${t} hooks found, updating...`),await i.update(),n||o.stop(`${t} hooks updated.`);return}n||o.message(`${t} hooks not found, creating...`),await i.create(),n||o.stop(`${t} hooks created.`)},En=async(e,t=!1)=>{let s=w();t||s.start("Removing Prettier dependencies and configuration...");try{let n=await pe.remove(e);t||(n.packagesRemoved.length>0&&s.message(`Removed Prettier packages: ${n.packagesRemoved.join(", ")}`),n.filesRemoved.length>0&&s.message(`Removed config files: ${n.filesRemoved.join(", ")}`),n.vsCodeCleaned&&s.message("Cleaned VS Code settings"),s.stop("Prettier removed successfully."))}catch{t||s.stop("Failed to remove Prettier completely, but continuing...")}},An=async(e,t=!1)=>{let s=w();t||s.start("Removing ESLint dependencies and configuration...");try{let n=await me.remove(e);t||(n.packagesRemoved.length>0&&s.message(`Removed ESLint packages: ${n.packagesRemoved.join(", ")}`),n.filesRemoved.length>0&&s.message(`Removed config files: ${n.filesRemoved.join(", ")}`),n.vsCodeCleaned&&s.message("Cleaned VS Code settings"),s.stop("ESLint removed successfully."))}catch{t||s.stop("Failed to remove ESLint completely, but continuing...")}},gt=async e=>{let t=e??{},s=t.quiet??!1;s||gn(Y);try{let{pm:n}=t;if(!n){let m=await yn(un.cwd());if(!m)throw new Error("No package manager specified or detected");if(!s&&m.warnings)for(let g of m.warnings)ae.warn(g);s||ae.info(`Detected lockfile, using ${m.name}`),n=m.name}let o=t.migrate?.includes("prettier"),i=t.migrate?.includes("eslint");if(!s&&(o===void 0||i===void 0)){let m=[];if(o===void 0&&await pe.hasPrettier()&&m.push({label:"Remove Prettier (dependencies, config files, VS Code settings)",value:"prettier"}),i===void 0&&await me.hasEsLint()&&m.push({label:"Remove ESLint (dependencies, config files, VS Code settings)",value:"eslint"}),m.length>0){let g=await U({message:"Remove existing formatters/linters (recommended for clean migration)?",options:m,required:!1});if(T(g)){M("Operation cancelled.");return}o===void 0&&(o=g.includes("prettier")),i===void 0&&(i=g.includes("eslint"))}}s&&(o===void 0&&(o=!1),i===void 0&&(i=!1));let a=t.frameworks;if(a===void 0)if(s||t.pm||t.editors||t.agents||t.hooks||t.integrations!==void 0||t.migrate!==void 0)a=[];else{let g=await U({message:"Which frameworks are you using (optional)?",options:[{label:"React",value:"react"},{label:"Next.js",value:"next"},{label:"Solid",value:"solid"},{label:"Vue",value:"vue"},{label:"Svelte",value:"svelte"},{label:"Qwik",value:"qwik"},{label:"Angular",value:"angular"},{label:"Remix / TanStack Router / React Router",value:"remix"},{label:"Astro",value:"astro"}],required:!1});if(T(g)){M("Operation cancelled.");return}a=g}let r=t.editors;if(!r)if(s)r=[];else{let m=await U({message:"Which editors do you want to configure (recommended)?",options:[{label:"VSCode / Cursor / Windsurf",value:"vscode"},{label:"Zed",value:"zed"}],required:!1});if(T(m)){M("Operation cancelled.");return}r=m}let c=t.agents,p=t.hooks,u={"vscode-copilot":"GitHub Copilot (VSCode)",cursor:"Cursor",windsurf:"Windsurf",zed:"Zed",claude:"Claude Code",codex:"OpenAI Codex / Jules / OpenCode",kiro:"Kiro IDE",cline:"Cline",amp:"AMP",aider:"Aider","firebase-studio":"Firebase Studio","open-hands":"Open Hands","gemini-cli":"Gemini CLI",junie:"Junie",augmentcode:"Augment Code","kilo-code":"Kilo Code",goose:"Codename Goose","roo-code":"Roo Code",warp:"Warp",droid:"Droid",antigravity:"Antigravity"};if(!c)if(s)c=[];else{let m=await U({message:"Which agents do you want to enable (optional)?",options:Object.entries(u).map(([g,ce])=>({value:g,label:ce})),required:!1});if(T(m)){M("Operation cancelled.");return}c=m}let x={cursor:"Cursor",claude:"Claude Code"};if(!p)if(s)p=[];else{let m=await U({message:"Which agent hooks do you want to enable (optional)?",options:Object.entries(x).map(([g,ce])=>({value:g,label:ce})),required:!1});if(T(m)){M("Operation cancelled.");return}p=m}let y=t.integrations;if(y===void 0)if(s||t.pm||t.editors||t.agents||t.hooks||t.migrate!==void 0)y=[];else{let g=await U({message:"Would you like any of the following (optional)?",options:[{label:"Husky pre-commit hook",value:"husky"},{label:"Lefthook pre-commit hook",value:"lefthook"},{label:"Lint-staged",value:"lint-staged"},{label:"pre-commit (Python framework)",value:"pre-commit"}],required:!1});if(T(g)){M("Operation cancelled.");return}y=g}o&&await En(n,s),i&&await An(n,s),await wn(n,!t.skipInstall,s),await kn(s),await vn(a,s),r?.includes("vscode")&&await bn(s),r?.includes("zed")&&await xn(s);for(let m of c??[])await Sn(m,u[m],n,s);for(let m of p??[])await Rn(m,x[m],n,s);y?.includes("husky")&&await Cn(n,!t.skipInstall,s),y?.includes("lefthook")&&await jn(n,!t.skipInstall,s),y?.includes("lint-staged")&&await Pn(n,!t.skipInstall,s),y?.includes("pre-commit")&&await $n(n,s),s||ae.success("Successfully initialized Ultracite configuration!")}catch(n){let o=n instanceof Error?n.message:"Unknown error";throw s||ae.error(`Failed to initialize Ultracite configuration: ${o}`),n}};var A=Fn.meta().create(),On=A.router({init:A.procedure.meta({description:"Initialize Ultracite in the current directory"}).input(d.object({pm:d.enum(j.packageManagers).optional().describe("Package manager to use"),editors:d.array(d.enum(j.editorConfigs)).optional().describe("Editors to configure"),agents:d.array(d.enum(j.agents)).optional().describe("Agents to enable"),hooks:d.array(d.enum(j.hooks)).optional().describe("Hooks to enable"),frameworks:d.array(d.enum(j.frameworks)).optional().describe("Frameworks being used"),integrations:d.array(d.enum(j.integrations)).optional().describe("Additional integrations to enable"),migrate:d.array(d.enum(j.migrations)).optional().describe("Migration tools to remove (e.g., eslint, prettier). Removes dependencies, config files, and editor settings."),skipInstall:d.boolean().default(!1).describe("Skip installing dependencies"),quiet:d.boolean().default(process.env.CI==="true"||process.env.CI==="1").describe("Suppress all interactive prompts and visual output. Automatically enabled in CI environments.")})).mutation(async({input:e})=>{await gt(e)}),check:A.procedure.meta({description:"Run Biome linter without fixing files"}).input(d.tuple([d.array(d.string()).optional().default([]).describe("specific files to lint"),d.object({"diagnostic-level":d.enum(["info","warn","error"]).optional().describe("level of diagnostics to show. In order, from the lowest to the most important: info, warn, error.")})]).optional()).query(async({input:e})=>{await fe(e)}),fix:A.procedure.meta({description:"Run Biome linter and fixes files"}).input(d.tuple([d.array(d.string()).optional().default([]).describe("specific files to format"),d.object({unsafe:d.boolean().optional().describe("apply unsafe fixes")})]).optional()).mutation(async({input:e})=>{let[t,s]=e??[[],{}];await ge(t,{unsafe:s.unsafe})}),doctor:A.procedure.meta({description:"Verify your Ultracite setup and check for issues"}).query(async()=>{await Be()}),lint:A.procedure.meta({description:"\u26A0\uFE0F DEPRECATED: Use 'check' instead - Run Biome linter without fixing files"}).input(d.array(d.string()).optional().default([]).describe("specific files to lint")).query(async({input:e})=>{console.warn("\u26A0\uFE0F Warning: 'lint' command is deprecated. Please use 'check' instead."),await fe([e,{}])}),format:A.procedure.meta({description:"\u26A0\uFE0F DEPRECATED: Use 'fix' instead - Run Biome linter and fixes files"}).input(d.tuple([d.array(d.string()).optional().default([]).describe("specific files to format"),d.object({unsafe:d.boolean().optional().describe("apply unsafe fixes")})]).optional()).mutation(async({input:e})=>{let[t,s]=e??[[],{}];console.warn("\u26A0\uFE0F Warning: 'format' command is deprecated. Please use 'fix' instead."),await ge(t,{unsafe:s.unsafe})})}),Dn=Nn({router:On,name:k.name,version:k.version,description:k.description});process.env.TEST||Dn.run();export{On as router};
125
+ ${i}`)}}});var Dn,Ot=R(()=>{Dn=At({"./husky.ts":()=>(jt(),Z(Gt)),"./lefthook.ts":()=>(Pt(),Z(Vt)),"./lint-staged.ts":()=>(vt(),Z(qt)),"./pre-commit.ts":()=>(St(),Z(Zt))})});var qt={};Q(qt,{lintStaged:()=>W});import{readFile as st,writeFile as F}from"fs/promises";import{pathToFileURL as Ln}from"url";import X from"deepmerge";import{parse as Ft}from"jsonc-parser";import{addDevDependency as An,dlxCommand as Jn}from"nypm";var j,te,Tn,In,Mn,_n,Bn,Wn,Un,zn,Hn,Nt,Gn,W,vt=R(()=>{"use strict";m();Ot();j=t=>({"*.{js,jsx,ts,tsx,json,jsonc,css,scss,md,mdx}":[Jn(t,"ultracite",{args:["fix"],short:t==="npm"})]}),te=["./package.json","./.lintstagedrc.json","./.lintstagedrc.js","./.lintstagedrc.cjs","./.lintstagedrc.mjs","./lint-staged.config.js","./lint-staged.config.cjs","./lint-staged.config.mjs","./.lintstagedrc.yaml","./.lintstagedrc.yml","./.lintstagedrc"],Tn=(t,e,n,i)=>{let o=t.trim();if(o.includes(":")&&!o.startsWith("-")){n&&i.length>0&&(e[n]=i);let[s,...r]=o.split(":"),a=r.join(":").trim(),p=s.trim().replace(/['"]/g,"");return a&&a!==""?(a.startsWith("[")&&a.endsWith("]")?e[p]=a.slice(1,-1).split(",").map(h=>h.trim().replace(/['"]/g,"")):e[p]=a.replace(/['"]/g,""),{newCurrentKey:null,newCurrentArray:[]}):{newCurrentKey:p,newCurrentArray:[]}}if(o.startsWith("-")&&n){let s=[...i,o.slice(1).trim().replace(/['"]/g,"")];return{newCurrentKey:n,newCurrentArray:s}}return{newCurrentKey:n,newCurrentArray:i}},In=t=>{let e=t.split(`
126
+ `).filter(s=>s.trim()&&!s.trim().startsWith("#")),n={},i=null,o=[];for(let s of e){let r=Tn(s,n,i,o);i=r.newCurrentKey,o=r.newCurrentArray}return i&&o.length>0&&(n[i]=o),n},Mn=t=>{let e="";for(let[n,i]of Object.entries(t))if(Array.isArray(i)){e+=`${n}:
127
+ `;for(let o of i)e+=` - '${o}'
128
+ `}else e+=`${n}: '${i}'
129
+ `;return e},_n=async()=>{try{let t=Ft(await st("./package.json","utf-8"));return t?t.type==="module":!1}catch{return!1}},Bn=async t=>{let e=Ft(await st("./package.json","utf-8"));e&&(e["lint-staged"]?e["lint-staged"]=X(e["lint-staged"],j(t)):e["lint-staged"]=j(t),await F("./package.json",JSON.stringify(e,null,2)))},Wn=async(t,e)=>{let n=await st(t,"utf-8"),i=Ft(n);if(!i)return;let o=X(i,j(e));await F(t,JSON.stringify(o,null,2))},Un=async(t,e)=>{let n=await st(t,"utf-8"),i=In(n);if(!i)return;let o=X(i,j(e));await F(t,Mn(o))},zn=async(t,e)=>{let o=(await import(Ln(t).href)).default||{},s=X(o,j(e)),r=`export default ${JSON.stringify(s,null,2)};
130
+ `;await F(t,r)},Hn=async(t,e)=>{delete wt.cache[wt.resolve(`./${t}`)];let n=Dn(`./${t}`),i=X(n,j(e)),o=`module.exports = ${JSON.stringify(i,null,2)};
131
+ `;await F(t,o)},Nt=async t=>{await F(".lintstagedrc.json",JSON.stringify(j(t),null,2))},Gn=async(t,e)=>{if(t==="./package.json"){await Bn(e);return}if(t.endsWith(".json")||t==="./.lintstagedrc"){await Wn(t,e);return}if(t.endsWith(".yaml")||t.endsWith(".yml")){await Un(t,e);return}let n=await _n();if(t.endsWith(".mjs")||t.endsWith(".js")&&n){try{await zn(t,e)}catch{await Nt(e)}return}if(t.endsWith(".cjs")||t.endsWith(".js")&&!n)try{await Hn(t,e)}catch{await Nt(e)}},W={exists:async()=>{for(let t of te)if(await c(t))return!0;return!1},install:async t=>{await An("lint-staged",{packageManager:t,workspace:await b(),silent:!0})},create:async t=>{await F(".lintstagedrc.json",JSON.stringify(j(t),null,2))},update:async t=>{let e=null;for(let n of te)if(await c(n)){e=n;break}if(!e){await Nt(t);return}await Gn(e,t)}}});import{options as C}from"@repo/data/options";import{initTRPC as Bi}from"@trpc/server";import{packageManagers as Wi}from"nypm";import{createCli as Ui}from"trpc-cli";import f from"zod";var y={name:"ultracite",description:"The AI-ready formatter that helps you write and generate code faster.",version:"7.0.0",type:"module",bin:{ultracite:"dist/index.js"},files:["config","dist","README.md"],scripts:{build:"tsup",test:"bun test","test:coverage":"bun test --coverage"},exports:{"./biome/*":"./config/biome/*/biome.jsonc","./eslint/*":"./config/eslint/*/eslint.config.mjs","./oxlint/*":"./config/oxlint/*/.oxlintrc.json","./prettier":"./config/prettier/prettier.config.mjs","./stylelint":"./config/stylelint/stylelint.config.mjs","./*":"./config/*/biome.jsonc"},author:"Hayden Bleasel <hello@haydenbleasel.com>",bugs:{url:"https://github.com/haydenbleasel/ultracite/issues"},homepage:"https://www.ultracite.ai/",keywords:["ultracite","biome","linter","formatter","fixer"],license:"MIT",publishConfig:{access:"public",registry:"https://registry.npmjs.org/"},repository:{type:"git",url:"git+https://github.com/haydenbleasel/ultracite.git"},devDependencies:{"@biomejs/biome":"catalog:","@eslint/js":"^9.39.2","@next/eslint-plugin-next":"^16.1.1","@tanstack/eslint-plugin-query":"^5.91.2","@types/node":"catalog:","@typescript-eslint/eslint-plugin":"^8.51.0","@typescript-eslint/parser":"^8.51.0","eslint-config-prettier":"^10.1.8","eslint-import-resolver-typescript":"^4.4.4","eslint-plugin-angular":"^5.0.0","eslint-plugin-astro":"^1.5.0","eslint-plugin-compat":"^6.0.2","eslint-plugin-cypress":"^5.2.0","eslint-plugin-github":"6.0.0","eslint-plugin-html":"^8.1.3","eslint-plugin-import":"^2.32.0","eslint-plugin-jest":"^29.12.0","eslint-plugin-jsx-a11y":"^6.10.2","eslint-plugin-n":"^17.23.1","eslint-plugin-prettier":"^5.5.4","eslint-plugin-promise":"^7.2.1","eslint-plugin-qwik":"^1.18.0","eslint-plugin-react":"^7.37.5","eslint-plugin-react-hooks":"^7.0.1","eslint-plugin-remix":"^1.1.1","eslint-plugin-solid":"^0.14.5","eslint-plugin-sonarjs":"^3.0.5","eslint-plugin-storybook":"^10.1.11","eslint-plugin-svelte":"^3.13.1","eslint-plugin-tailwindcss":"^3.18.2","eslint-plugin-unicorn":"^62.0.0","eslint-plugin-unused-imports":"^4.3.0","eslint-plugin-vue":"^10.6.2",globals:"^16.5.0","prettier-plugin-tailwindcss":"^0.7.2","stylelint-config-idiomatic-order":"^10.0.0","stylelint-config-standard":"^39.0.1","stylelint-prettier":"^5.0.3",tsup:"^8.5.1"},dependencies:{"@clack/prompts":"^0.11.0","@trpc/server":"^11.8.1","@repo/data":"workspace:*",deepmerge:"catalog:",glob:"^13.0.0","jsonc-parser":"^3.3.1",nypm:"^0.6.2",oxlint:"^1.36.0","trpc-cli":"^0.12.1",zod:"catalog:"},packageManager:"bun@1.3.5"};m();import{spawnSync as D}from"child_process";import L from"process";import{detectPackageManager as A,dlxCommand as J}from"nypm";var Je=async(t,e)=>{let n=["check","--no-errors-on-unmatched"];e&&n.push(`--diagnostic-level=${e}`),t.length>0?n.push(...d(t)):n.push("./");let o=(await A(L.cwd()))?.name||"npm",s=J(o,"@biomejs/biome",{args:n,short:o==="npm"}),r=D(s,{stdio:"inherit",shell:!0});if(r.error)throw new Error(`Failed to run Biome: ${r.error.message}`);return{hasErrors:r.status!==0}},Te=async t=>{let e=t.length>0?d(t):["."],i=(await A(L.cwd()))?.name||"npm",o=J(i,"eslint",{args:e,short:i==="npm"}),s=D(o,{stdio:"inherit",shell:!0});if(s.error)throw new Error(`Failed to run ESLint: ${s.error.message}`);return{hasErrors:s.status!==0}},Ie=async t=>{let e=["--check",...t.length>0?d(t):["."]],i=(await A(L.cwd()))?.name||"npm",o=J(i,"prettier",{args:e,short:i==="npm"}),s=D(o,{stdio:"inherit",shell:!0});if(s.error)throw new Error(`Failed to run Prettier: ${s.error.message}`);return{hasErrors:s.status!==0}},Me=async t=>{let e=t.length>0?d(t):["."],i=(await A(L.cwd()))?.name||"npm",o=J(i,"stylelint",{args:e,short:i==="npm"}),s=D(o,{stdio:"inherit",shell:!0});if(s.error)throw new Error(`Failed to run Stylelint: ${s.error.message}`);return{hasErrors:s.status!==0}},_e=async t=>{let e=t.length>0?d(t):["."],i=(await A(L.cwd()))?.name||"npm",o=J(i,"oxlint",{args:e,short:i==="npm"}),s=D(o,{stdio:"inherit",shell:!0});if(s.error)throw new Error(`Failed to run Oxlint: ${s.error.message}`);return{hasErrors:s.status!==0}},Be=async t=>{let e=["--check",...t.length>0?d(t):["."]],i=(await A(L.cwd()))?.name||"npm",o=J(i,"oxfmt",{args:e,short:i==="npm"}),s=D(o,{stdio:"inherit",shell:!0});if(s.error)throw new Error(`Failed to run oxfmt: ${s.error.message}`);return{hasErrors:s.status!==0}},Tt=async t=>{let e=t?.[0]||[],n=t?.[1]["diagnostic-level"],o=t?.[1].linter||await q();if(!o)throw new Error("No linter configuration found. Run `ultracite init` to set up a linter.");switch(o){case"eslint":{let s=await Ie(e),r=await Te(e),a=await Me(e);return{hasErrors:s.hasErrors||r.hasErrors||a.hasErrors}}case"oxlint":{let s=await Be(e),r=await _e(e);return{hasErrors:s.hasErrors||r.hasErrors}}default:return Je(e,n)}};import{spawnSync as xt}from"child_process";import{existsSync as S}from"fs";import{readFile as et}from"fs/promises";import{join as O}from"path";import w from"process";import{intro as We,log as tt,outro as yt,spinner as Ue}from"@clack/prompts";import{parse as It}from"jsonc-parser";import{detectPackageManager as nt,dlxCommand as it}from"nypm";var ze=[".prettierrc",".prettierrc.js",".prettierrc.cjs",".prettierrc.mjs",".prettierrc.json",".prettierrc.yaml",".prettierrc.yml","prettier.config.js","prettier.config.mjs","prettier.config.cjs"],He=[".eslintrc",".eslintrc.js",".eslintrc.cjs",".eslintrc.mjs",".eslintrc.json",".eslintrc.yaml",".eslintrc.yml","eslint.config.js","eslint.config.mjs","eslint.config.cjs","eslint.config.ts","eslint.config.mts","eslint.config.cts"],Ge=async()=>{let e=(await nt(w.cwd()))?.name||"npm",n=it(e,"@biomejs/biome",{args:["--version"],short:e==="npm"}),i=xt(n,{shell:!0,encoding:"utf-8"});return i.status===0&&i.stdout?{name:"Biome installation",status:"pass",message:`Biome is installed (${i.stdout.trim()})`}:{name:"Biome installation",status:"fail",message:"Biome is not installed or not accessible"}},Ye=async()=>{let e=(await nt(w.cwd()))?.name||"npm",n=it(e,"eslint",{args:["--version"],short:e==="npm"}),i=xt(n,{shell:!0,encoding:"utf-8"});return i.status===0&&i.stdout?{name:"ESLint installation",status:"pass",message:`ESLint is installed (${i.stdout.trim()})`}:{name:"ESLint installation",status:"warn",message:"ESLint is not installed (optional)"}},Xe=async()=>{let e=(await nt(w.cwd()))?.name||"npm",n=it(e,"oxlint",{args:["--version"],short:e==="npm"}),i=xt(n,{shell:!0,encoding:"utf-8"});return i.status===0&&i.stdout?{name:"Oxlint installation",status:"pass",message:`Oxlint is installed (${i.stdout.trim()})`}:{name:"Oxlint installation",status:"warn",message:"Oxlint is not installed (optional)"}},Ke=async()=>{let t=O(w.cwd(),"biome.json"),e=O(w.cwd(),"biome.jsonc"),n=null;if(S(t)?n=t:S(e)&&(n=e),!n)return{name:"Biome configuration",status:"warn",message:"No biome.json or biome.jsonc file found"};try{let i=await et(n,"utf-8"),o=It(i);return Array.isArray(o?.extends)&&o.extends.includes("ultracite/biome/core")?{name:"Biome configuration",status:"pass",message:"biome.json(c) extends ultracite/biome/core"}:{name:"Biome configuration",status:"warn",message:"biome.json(c) exists but doesn't extend ultracite/biome/core"}}catch{return{name:"Biome configuration",status:"fail",message:"Could not parse biome.json(c) file"}}},Ve=async()=>{let t=["eslint.config.mjs","eslint.config.js","eslint.config.cjs","eslint.config.ts","eslint.config.mts","eslint.config.cts"],e=null;for(let n of t){let i=O(w.cwd(),n);if(S(i)){e=i;break}}if(!e)return{name:"ESLint configuration",status:"warn",message:"No eslint.config.* file found (optional)"};try{return(await et(e,"utf-8")).includes("ultracite/eslint")?{name:"ESLint configuration",status:"pass",message:"eslint.config.* imports ultracite/eslint"}:{name:"ESLint configuration",status:"warn",message:"eslint.config.* exists but doesn't import ultracite/eslint"}}catch{return{name:"ESLint configuration",status:"fail",message:"Could not read eslint.config.* file"}}},Qe=async()=>{let t=O(w.cwd(),".oxlintrc.json");if(!S(t))return{name:"Oxlint configuration",status:"warn",message:"No .oxlintrc.json file found (optional)"};try{let e=await et(t,"utf-8"),n=It(e);return Array.isArray(n?.extends)&&n.extends.includes("ultracite/oxlint/core")?{name:"Oxlint configuration",status:"pass",message:".oxlintrc.json extends ultracite/oxlint/core"}:{name:"Oxlint configuration",status:"warn",message:".oxlintrc.json exists but doesn't extend ultracite/oxlint/core"}}catch{return{name:"Oxlint configuration",status:"fail",message:"Could not parse .oxlintrc.json file"}}},Ze=async()=>{let t=O(w.cwd(),"package.json");if(!S(t))return{name:"Ultracite dependency",status:"warn",message:"No package.json found"};try{let e=JSON.parse(await et(t,"utf-8")),n=e.dependencies?.ultracite||e.devDependencies?.ultracite||e.peerDependencies?.ultracite;return n?{name:"Ultracite dependency",status:"pass",message:`Ultracite is in package.json (${n})`}:{name:"Ultracite dependency",status:"warn",message:"Ultracite not found in package.json dependencies"}}catch{return{name:"Ultracite dependency",status:"warn",message:"Could not parse package.json"}}},qe=()=>{let t=ze.some(i=>S(O(w.cwd(),i))),n=He.filter(i=>!i.startsWith("eslint.config")).some(i=>S(O(w.cwd(),i)));if(t||n){let i=[];return t&&i.push("Prettier"),n&&i.push("ESLint (legacy config)"),{name:"Conflicting tools",status:"warn",message:`Found potentially conflicting tools: ${i.join(", ")}`}}return{name:"Conflicting tools",status:"pass",message:"No conflicting formatting/linting tools found"}},E=async(t,e)=>{let n=Ue();n.start(`Checking ${e}...`);let i=await t();return i.status==="pass"||i.status,n.stop(i.message),i},Mt=async()=>{We(`Ultracite v${y.version} Doctor`);let e=(await nt(w.cwd()))?.name||"npm",n=it(e,"ultracite",{args:["init"],short:e==="npm"}),i=[];i.push(await E(Ge,"Biome installation")),i.push(await E(Ye,"ESLint installation")),i.push(await E(Xe,"Oxlint installation")),i.push(await E(Ke,"Biome configuration")),i.push(await E(Ve,"ESLint configuration")),i.push(await E(Qe,"Oxlint configuration")),i.push(await E(Ze,"Ultracite dependency")),i.push(await E(qe,"conflicting tools"));let o=i.filter(a=>a.status==="pass").length,s=i.filter(a=>a.status==="fail").length,r=i.filter(a=>a.status==="warn").length;if(tt.info(`Summary: ${o} passed, ${r} warnings, ${s} failed`),s>0)throw tt.error(`Some checks failed. Run '${n}' to fix issues.`),yt("Doctor complete"),new Error("Doctor checks failed");if(r>0){tt.warn(`Some optional improvements available. Run '${n}' to configure.`),yt("Doctor complete");return}tt.success("Everything looks good!"),yt("Doctor complete")};m();import{spawnSync as T}from"child_process";import I from"process";import{detectPackageManager as M,dlxCommand as _}from"nypm";var tn=async(t,e)=>{let n=["check","--write","--no-errors-on-unmatched"];e&&n.push("--unsafe"),t.length>0?n.push(...d(t)):n.push("./");let o=(await M(I.cwd()))?.name||"npm",s=_(o,"@biomejs/biome",{args:n,short:o==="npm"}),r=T(s,{stdio:"inherit",shell:!0});if(r.error)throw new Error(`Failed to run Biome: ${r.error.message}`);return{hasErrors:r.status!==0}},en=async t=>{let e=["--fix",...t.length>0?d(t):["."]],i=(await M(I.cwd()))?.name||"npm",o=_(i,"eslint",{args:e,short:i==="npm"}),s=T(o,{stdio:"inherit",shell:!0});if(s.error)throw new Error(`Failed to run ESLint: ${s.error.message}`);return{hasErrors:s.status!==0}},nn=async t=>{let e=["--write",...t.length>0?d(t):["."]],i=(await M(I.cwd()))?.name||"npm",o=_(i,"prettier",{args:e,short:i==="npm"}),s=T(o,{stdio:"inherit",shell:!0});if(s.error)throw new Error(`Failed to run Prettier: ${s.error.message}`);return{hasErrors:s.status!==0}},on=async t=>{let e=["--fix",...t.length>0?d(t):["."]],i=(await M(I.cwd()))?.name||"npm",o=_(i,"stylelint",{args:e,short:i==="npm"}),s=T(o,{stdio:"inherit",shell:!0});if(s.error)throw new Error(`Failed to run Stylelint: ${s.error.message}`);return{hasErrors:s.status!==0}},sn=async t=>{let e=["--fix",...t.length>0?d(t):["."]],i=(await M(I.cwd()))?.name||"npm",o=_(i,"oxlint",{args:e,short:i==="npm"}),s=T(o,{stdio:"inherit",shell:!0});if(s.error)throw new Error(`Failed to run Oxlint: ${s.error.message}`);return{hasErrors:s.status!==0}},rn=async t=>{let e=["--write",...t.length>0?d(t):["."]],i=(await M(I.cwd()))?.name||"npm",o=_(i,"oxfmt",{args:e,short:i==="npm"}),s=T(o,{stdio:"inherit",shell:!0});if(s.error)throw new Error(`Failed to run oxfmt: ${s.error.message}`);return{hasErrors:s.status!==0}},_t=async(t,e={})=>{let n=e.linter||await q();if(!n)throw new Error("No linter configuration found. Run `ultracite init` to set up a linter.");switch(n){case"eslint":{let i=await nn(t),o=await en(t),s=await on(t);return{hasErrors:i.hasErrors||o.hasErrors||s.hasErrors}}case"oxlint":{let i=await rn(t),o=await sn(t);return{hasErrors:i.hasErrors||o.hasErrors}}default:return tn(t,e.unsafe)}};import xi from"process";import{cancel as U,intro as ki,isCancel as z,log as ut,multiselect as K,select as Ci,spinner as g}from"@clack/prompts";import{agents as bi}from"@repo/data/agents";import{editors as xe}from"@repo/data/editors";import{providers as Ei}from"@repo/data/providers";import{addDevDependency as ji,detectPackageManager as Pi}from"nypm";m();import{readFile as an,writeFile as kt}from"fs/promises";import{agents as cn}from"@repo/data/agents";import{getRules as ln}from"@repo/data/rules";import{dlxCommand as fn}from"nypm";var Bt=(t,e)=>{let n=cn.find(r=>r.id===t);if(!n)throw new Error(`Agent "${t}" not found`);let i=fn(e,""),o=ln(i),s=n.config.header?`${n.config.header}
132
+
133
+ ${o}`:o;return{exists:()=>c(n.config.path),create:async()=>{await k(n.config.path),await kt(n.config.path,s)},update:async()=>{await k(n.config.path);let r=await c(n.config.path);if(!(n.config.appendMode&&r)){await kt(n.config.path,s);return}let a=await an(n.config.path,"utf-8");a.includes(o.trim())||await kt(n.config.path,`${a}
134
+
135
+ ${o}`)}}};m();import{spawnSync as mn}from"child_process";import{readFile as pn,writeFile as Ct}from"fs/promises";import{editors as gn}from"@repo/data/editors";import un from"deepmerge";import{parse as dn}from"jsonc-parser";var Wt=(t,e="biome")=>{let n=gn.find(o=>o.id===t);if(!n)throw new Error(`Editor "${t}" not found`);let i=n.config.getContent(e);return{exists:()=>c(n.config.path),create:async()=>{await k(n.config.path),await Ct(n.config.path,JSON.stringify(i,null,2))},update:async()=>{if(await k(n.config.path),!await c(n.config.path)){await Ct(n.config.path,JSON.stringify(i,null,2));return}let s=await pn(n.config.path,"utf-8"),a=dn(s)||{},p=un(a,i);await Ct(n.config.path,JSON.stringify(p,null,2))},extension:n.config.extensionCommand?o=>mn(`${n.config.extensionCommand} ${o}`,{stdio:"pipe",shell:!0}):void 0}};m();import{readFile as hn,writeFile as bt}from"fs/promises";import{editors as wn}from"@repo/data/editors";import yn from"deepmerge";import{dlxCommand as xn}from"nypm";var Ut=(t,e)=>{let n=wn.find(a=>a.id===t);if(!n)throw new Error(`Editor "${t}" not found`);if(!n.hooks)throw new Error(`Editor "${t}" does not support hooks`);let i=xn(e,"ultracite",{args:["fix"],short:e==="npm"}),o=n.hooks.getContent(i),s=a=>JSON.stringify(a).includes("ultracite"),r=async()=>{if(!n.hooks?.path)throw new Error(`Editor "${t}" does not support hooks`);if(!await c(n.hooks.path)){await bt(n.hooks.path,JSON.stringify(o,null,2));return}let p=await hn(n.hooks.path,"utf-8"),h=JSON.parse(p);if(!s(h)){let P=yn(h,o);await bt(n.hooks.path,JSON.stringify(P,null,2))}};return{exists:()=>n.hooks?.path?c(n.hooks.path):!1,create:async()=>{if(!n.hooks?.path)throw new Error(`Editor "${t}" does not support hooks`);await k(n.hooks.path),await bt(n.hooks.path,JSON.stringify(o,null,2))},update:async()=>{if(!n.hooks?.path)throw new Error(`Editor "${t}" does not support hooks`);await k(n.hooks.path),await r()}}};jt();Pt();vt();St();m();import{readFile as Yn,writeFile as ee}from"fs/promises";import Xn from"deepmerge";import{parse as Kn}from"jsonc-parser";var ne={$schema:"./node_modules/@biomejs/biome/configuration_schema.json",extends:["ultracite/biome/core"]},Rt=async()=>await c("./biome.json")?"./biome.json":"./biome.jsonc",rt={exists:async()=>{let t=await Rt();return c(t)},create:async t=>{let e=await Rt(),n=["ultracite/biome/core"];if(t?.frameworks&&t.frameworks.length>0)for(let o of t.frameworks)n.push(`ultracite/biome/${o}`);let i={...ne,extends:n};return ee(e,JSON.stringify(i,null,2))},update:async t=>{let e=await Rt(),n=await Yn(e,"utf-8"),o=Kn(n)||{},r=[...o.extends&&Array.isArray(o.extends)?o.extends:[]];if(r.includes("ultracite/biome/core")||r.push("ultracite/biome/core"),t?.frameworks&&t.frameworks.length>0)for(let h of t.frameworks){let P=`ultracite/biome/${h}`;r.includes(P)||r.push(P)}o.extends=r;let a={$schema:ne.$schema},p=Xn(o,a);await ee(e,JSON.stringify(p,null,2))}};m();import{writeFile as ie}from"fs/promises";var Vn=["./eslint.config.mjs","./eslint.config.js","./eslint.config.cjs","./eslint.config.ts","./eslint.config.mts","./eslint.config.cts"],oe="./eslint.config.mjs",Qn=async()=>{for(let t of Vn)if(await c(t))return t;return null},se=t=>{let e=['import core from "ultracite/eslint/core";'],n=["...core"];if(t?.frameworks&&t.frameworks.length>0)for(let i of t.frameworks)e.push(`import ${i} from "ultracite/eslint/${i}";`),n.push(`...${i}`);return`${e.join(`
136
+ `)}
137
+
138
+ export default [
139
+ ${n.join(`,
140
+ `)},
141
+ ];
142
+ `},at={exists:async()=>await Qn()!==null,create:async t=>{let e=se(t);await ie(oe,e)},update:async t=>{let e=se(t);await ie(oe,e)}};m();import{readFile as Zn,writeFile as re}from"fs/promises";import qn from"deepmerge";import{parse as ti}from"jsonc-parser";var ct="./.oxfmtrc.jsonc",ae={$schema:"./node_modules/oxfmt/configuration_schema.json",printWidth:80,tabWidth:2,useTabs:!1,semi:!0,singleQuote:!1,quoteProps:"as-needed",jsxSingleQuote:!1,trailingComma:"es5",bracketSpacing:!0,bracketSameLine:!1,arrowParens:"always",endOfLine:"lf",experimentalSortPackageJson:!0,experimentalSortImports:{ignoreCase:!0,newlinesBetween:!0,order:"asc"}},lt={exists:async()=>await c(ct),create:async()=>{let t=`// Ultracite oxfmt Configuration
143
+ // https://oxc.rs/docs/guide/usage/formatter/config-file-reference.html
144
+ ${JSON.stringify(ae,null,2)}
145
+ `;return await re(ct,t)},update:async()=>{let t=await Zn(ct,"utf-8"),n=ti(t)||{},i=qn(n,ae),o=`// Ultracite oxfmt Configuration
146
+ // https://oxc.rs/docs/guide/usage/formatter/config-file-reference.html
147
+ ${JSON.stringify(i,null,2)}
148
+ `;await re(ct,o)}};m();import{readFile as ei,writeFile as ce}from"fs/promises";import ni from"deepmerge";import{parse as ii}from"jsonc-parser";var ft="./.oxlintrc.json",le={$schema:"./node_modules/oxlint/configuration_schema.json",extends:["ultracite/oxlint/core"]},mt={exists:async()=>await c(ft),create:async t=>{let e=["ultracite/oxlint/core"];if(t?.frameworks&&t.frameworks.length>0)for(let i of t.frameworks)e.push(`ultracite/oxlint/${i}`);let n={...le,extends:e};return await ce(ft,JSON.stringify(n,null,2))},update:async t=>{let e=await ei(ft,"utf-8"),i=ii(e)||{},s=[...i.extends&&Array.isArray(i.extends)?i.extends:[]];if(s.includes("ultracite/oxlint/core")||s.push("ultracite/oxlint/core"),t?.frameworks&&t.frameworks.length>0)for(let p of t.frameworks){let h=`ultracite/oxlint/${p}`;s.includes(h)||s.push(h)}i.extends=s;let r={$schema:le.$schema},a=ni(i,r);await ce(ft,JSON.stringify(a,null,2))}};m();import{readFile as oi,writeFile as fe}from"fs/promises";var si=["./.prettierrc.mjs","./prettier.config.mjs","./.prettierrc.mts","./prettier.config.mts","./.prettierrc.cjs","./prettier.config.cjs","./.prettierrc.cts","./prettier.config.cts","./.prettierrc.js","./prettier.config.js","./.prettierrc.ts","./prettier.config.ts","./.prettierrc","./.prettierrc.json","./.prettierrc.json5","./.prettierrc.yml","./.prettierrc.yaml","./.prettierrc.toml"],me="./prettier.config.mjs",ri=async()=>{try{return"prettier"in JSON.parse(await oi("./package.json","utf-8"))}catch{return!1}},ai=async()=>{if(await ri())return"./package.json";for(let t of si)if(await c(t))return t;return null},pe=()=>`export { default } from "ultracite/prettier";
149
+ `,pt={exists:async()=>await ai()!==null,create:async()=>{let t=pe();await fe(me,t)},update:async()=>{let t=pe();await fe(me,t)}};m();import{readFile as ci,writeFile as ge}from"fs/promises";var li=["./.stylelintrc.mjs","./stylelint.config.mjs","./.stylelintrc.cjs","./stylelint.config.cjs","./.stylelintrc.js","./stylelint.config.js","./.stylelintrc","./.stylelintrc.json","./.stylelintrc.yml","./.stylelintrc.yaml"],ue="./stylelint.config.mjs",fi=async()=>{try{return"stylelint"in JSON.parse(await ci("./package.json","utf-8"))}catch{return!1}},mi=async()=>{if(await fi())return"./package.json";for(let t of li)if(await c(t))return t;return null},de=()=>`export { default } from "ultracite/stylelint";
150
+ `,gt={exists:async()=>await mi()!==null,create:async()=>{let t=de();await ge(ue,t)},update:async()=>{let t=de();await ge(ue,t)}};import{readFile as pi,writeFile as he}from"fs/promises";import{glob as gi}from"glob";import{applyEdits as ui,modify as di,parse as hi}from"jsonc-parser";var we=async()=>{try{return await gi("**/tsconfig*.json",{ignore:["**/node_modules/**","**/dist/**","**/build/**","**/.next/**"],absolute:!1})}catch{return[]}},wi=t=>{if(!t)return!1;let e=t.compilerOptions;return e?e.strict===!0||e.strictNullChecks===!0:!1},yi=async t=>{try{let e=await pi(t,"utf-8"),n=hi(e);if(wi(n))return;if(n===void 0){await he(t,JSON.stringify({compilerOptions:{strictNullChecks:!0}},null,2));return}let o=di(e,["compilerOptions","strictNullChecks"],!0,{formattingOptions:{tabSize:2,insertSpaces:!0}}),s=ui(e,o);await he(t,s)}catch(e){console.warn(`Failed to update ${t}:`,e)}},Dt={exists:async()=>(await we()).length>0,update:async()=>{let t=await we();if(t.length===0){console.warn("No tsconfig.json files found in the project");return}await Promise.all(t.map(e=>yi(e)))}};m();var ye=y.devDependencies["@biomejs/biome"],Lt=y.version,$i=async(t,e="biome",n=!0,i=!1)=>{let o=g();i||o.start("Installing dependencies...");let s=[`ultracite@${Lt}`];if(e==="biome"&&s.push(`@biomejs/biome@${ye}`),e==="eslint"&&(s.push("eslint@latest"),s.push("prettier@latest"),s.push("stylelint@latest")),e==="oxlint"&&(s.push("oxlint@latest"),s.push("oxfmt@latest")),n)for(let r of s)await ji(r,{packageManager:t,workspace:await b(),silent:!0});else{let r={ultracite:Lt};e==="biome"&&(r["@biomejs/biome"]=ye),e==="eslint"&&(r.eslint="latest",r.prettier="latest",r.stylelint="latest"),e==="oxlint"&&(r.oxlint="latest",r.oxfmt="latest"),await x({devDependencies:r})}i||o.stop("Dependencies installed.")},Si=async(t=!1)=>{let e=g();if(t||e.start("Checking for tsconfig.json files..."),await Dt.exists()){t||e.message("Found tsconfig.json files, updating with strictNullChecks..."),await Dt.update(),t||e.stop("tsconfig.json files updated.");return}t||e.stop("No tsconfig.json files found, skipping.")},Oi=async(t,e="biome",n=!1)=>{let i=xe.find(r=>r.id===t);if(!i)throw new Error(`Editor "${t}" not found`);let o=Wt(t,e),s=g();if(n||s.start(`Checking for ${i.config.path}...`),await o.exists()){n||s.message(`${i.config.path} found, updating...`),await o.update(),n||s.stop(`${i.config.path} updated.`);return}if(n||s.message(`${i.config.path} not found, creating...`),await o.create(),o.extension){let r=Ei.find(a=>a.id===e)?.vscodeExtensionId;if(!r)throw new Error(`Linter extension not found for ${e}`);n||s.message(`Installing ${r} extension...`);try{if(o.extension(r).status===0){n||s.stop(`${i.config.path} created and ${r} extension installed.`);return}}catch{}n||s.stop(`${i.config.path} created. Install ${r} extension manually.`);return}n||(t==="zed"?s.stop(`${i.config.path} created. Install the Biome extension: https://biomejs.dev/reference/zed/`):s.stop(`${i.config.path} created.`))},vi=async(t,e=!1)=>{let n=g();if(e||n.start("Checking for Biome configuration..."),await rt.exists()){e||n.message("Biome configuration found, updating..."),await rt.update({frameworks:t}),e||n.stop("Biome configuration updated.");return}e||n.message("Biome configuration not found, creating..."),await rt.create({frameworks:t}),e||n.stop("Biome configuration created.")},Ni=async(t,e=!1)=>{let n=g();if(e||n.start("Checking for ESLint configuration..."),await at.exists()){e||n.message("ESLint configuration found, updating..."),await at.update({frameworks:t}),e||n.stop("ESLint configuration updated.");return}e||n.message("ESLint configuration not found, creating..."),await at.create({frameworks:t}),e||n.stop("ESLint configuration created.")},Fi=async(t,e=!1)=>{let n=g();if(e||n.start("Checking for Oxlint configuration..."),await mt.exists()){e||n.message("Oxlint configuration found, updating..."),await mt.update({frameworks:t}),e||n.stop("Oxlint configuration updated.");return}e||n.message("Oxlint configuration not found, creating..."),await mt.create({frameworks:t}),e||n.stop("Oxlint configuration created.")},Ri=async(t=!1)=>{let e=g();if(t||e.start("Checking for Prettier configuration..."),await pt.exists()){t||e.message("Prettier configuration found, updating..."),await pt.update(),t||e.stop("Prettier configuration updated.");return}t||e.message("Prettier configuration not found, creating..."),await pt.create(),t||e.stop("Prettier configuration created.")},Di=async(t=!1)=>{let e=g();if(t||e.start("Checking for Stylelint configuration..."),await gt.exists()){t||e.message("Stylelint configuration found, updating..."),await gt.update(),t||e.stop("Stylelint configuration updated.");return}t||e.message("Stylelint configuration not found, creating..."),await gt.create(),t||e.stop("Stylelint configuration created.")},Li=async(t=!1)=>{let e=g();if(t||e.start("Checking for oxfmt configuration..."),await lt.exists()){t||e.message("oxfmt configuration found, updating..."),await lt.update(),t||e.stop("oxfmt configuration updated.");return}t||e.message("oxfmt configuration not found, creating..."),await lt.create(),t||e.stop("oxfmt configuration created.")},Ai=async(t,e=!0,n=!1)=>{let i=g();if(n||(i.start("Initializing pre-commit hooks..."),i.message("Installing Husky...")),e?await v.install(t):await x({devDependencies:{husky:"latest"},scripts:{prepare:"husky"}}),n||i.message("Initializing Husky..."),v.init(t),await v.exists()){n||i.message("Pre-commit hook found, updating..."),await v.update(t),n||i.stop("Pre-commit hook updated.");return}n||i.message("Pre-commit hook not found, creating..."),await v.create(t),n||i.stop("Pre-commit hook created.")},Ji=async(t,e=!0,n=!1)=>{let i=g();if(n||(i.start("Initializing lefthook..."),i.message("Installing lefthook...")),e?await B.install(t):await x({devDependencies:{lefthook:"latest"}}),await B.exists()){n||i.message("lefthook.yml found, updating..."),await B.update(t),n||i.stop("lefthook.yml updated.");return}n||i.message("lefthook.yml not found, creating..."),await B.create(t),n||i.stop("lefthook.yml created.")},Ti=async(t,e=!0,n=!1)=>{let i=g();if(n||(i.start("Initializing lint-staged..."),i.message("Installing lint-staged...")),e?await W.install(t):await x({devDependencies:{"lint-staged":"latest"}}),await W.exists()){n||i.message("lint-staged found, updating..."),await W.update(t),n||i.stop("lint-staged updated.");return}n||i.message("lint-staged not found, creating..."),await W.create(t),n||i.stop("lint-staged created.")},Ii=async(t,e=!1)=>{let n=g();if(e||n.start("Initializing pre-commit..."),await Y.exists()){e||n.message(".pre-commit-config.yaml found, updating..."),await Y.update(t),e||n.stop(".pre-commit-config.yaml updated.");return}e||n.message(".pre-commit-config.yaml not found, creating..."),await Y.create(t),e||n.stop(".pre-commit-config.yaml created.")},Mi=async(t,e,n,i=!1)=>{let o=g();i||o.start(`Checking for ${e}...`);let s=Bt(t,n);if(await s.exists()){i||o.message(`${e} found, updating...`),await s.update(),i||o.stop(`${e} updated.`);return}i||o.message(`${e} not found, creating...`),await s.create(),i||o.stop(`${e} created.`)},_i=async(t,e,n,i=!1)=>{let o=g();i||o.start(`Checking for ${e} hooks...`);let s=Ut(t,n);if(await s.exists()){i||o.message(`${e} hooks found, updating...`),await s.update(),i||o.stop(`${e} hooks updated.`);return}i||o.message(`${e} hooks not found, creating...`),await s.create(),i||o.stop(`${e} hooks created.`)},ke=async t=>{let e=t??{},n=e.quiet??!1;n||ki(`Ultracite v${Lt} Initialization`);try{let{pm:i}=e;if(!i){let l=await Pi(xi.cwd());if(!l)throw new Error("No package manager specified or detected");if(!n&&l.warnings)for(let u of l.warnings)ut.warn(u);n||ut.info(`Detected lockfile, using ${l.name}`),i=l.name}let o=e.linter;if(o===void 0)if(n||e.pm||e.editors||e.agents||e.hooks||e.integrations!==void 0||e.frameworks!==void 0)o="biome";else{let u=await Ci({message:"Which linter do you want to use?",options:[{label:"Biome (Recommended)",value:"biome"},{label:"ESLint + Prettier + Stylelint",value:"eslint"},{label:"Oxlint + Oxfmt",value:"oxlint"}]});if(z(u)){U("Operation cancelled.");return}o=u}let s=e.frameworks;if(s===void 0)if(n||e.pm||e.editors||e.agents||e.hooks||e.integrations!==void 0)s=[];else{let u=await K({message:"Which frameworks are you using (optional)?",options:[{label:"React",value:"react"},{label:"Next.js",value:"next"},{label:"Solid",value:"solid"},{label:"Vue",value:"vue"},{label:"Svelte",value:"svelte"},{label:"Qwik",value:"qwik"},{label:"Angular",value:"angular"},{label:"Remix / TanStack Router / React Router",value:"remix"},{label:"Astro",value:"astro"}],required:!1});if(z(u)){U("Operation cancelled.");return}s=u}let r=e.editors;if(!r)if(n)r=[];else{let l=await K({message:"Which editors do you want to configure (recommended)?",options:[{label:"VSCode / Cursor / Windsurf",value:"vscode"},{label:"Zed",value:"zed"}],required:!1});if(z(l)){U("Operation cancelled.");return}r=l}let a=e.agents,p=e.hooks,h=Object.fromEntries(bi.map(l=>[l.id,l.name]));if(!a)if(n)a=[];else{let l=await K({message:"Which agents do you want to enable (optional)?",options:Object.entries(h).map(([u,dt])=>({value:u,label:dt})),required:!1});if(z(l)){U("Operation cancelled.");return}a=l}let P=Object.fromEntries(xe.filter(l=>l.hooks).map(l=>[l.id,l.name]));if(!p)if(n)p=[];else{let l=await K({message:"Which agent hooks do you want to enable (optional)?",options:Object.entries(P).map(([u,dt])=>({value:u,label:dt})),required:!1});if(z(l)){U("Operation cancelled.");return}p=l}let $=e.integrations;if($===void 0)if(n||e.pm||e.editors||e.agents||e.hooks)$=[];else{let u=await K({message:"Would you like any of the following (optional)?",options:[{label:"Husky pre-commit hook",value:"husky"},{label:"Lefthook pre-commit hook",value:"lefthook"},{label:"Lint-staged",value:"lint-staged"},{label:"pre-commit (Python framework)",value:"pre-commit"}],required:!1});if(z(u)){U("Operation cancelled.");return}$=u}await $i(i,o,!e.skipInstall,n),await Si(n),o==="biome"&&await vi(s,n),o==="eslint"&&(await Ni(s,n),await Ri(n),await Di(n)),o==="oxlint"&&(await Fi(s,n),await Li(n));for(let l of r??[])await Oi(l,o,n);for(let l of a??[])await Mi(l,h[l],i,n);for(let l of p??[])await _i(l,P[l],i,n);$?.includes("husky")&&await Ai(i,!e.skipInstall,n),$?.includes("lefthook")&&await Ji(i,!e.skipInstall,n),$?.includes("lint-staged")&&await Ti(i,!e.skipInstall,n),$?.includes("pre-commit")&&await Ii(i,n),n||ut.success("Successfully initialized Ultracite configuration!")}catch(i){let o=i instanceof Error?i.message:"Unknown error";throw n||ut.error(`Failed to initialize Ultracite configuration: ${o}`),i}};var V=Bi.meta().create(),zi=V.router({init:V.procedure.meta({description:"Initialize Ultracite in the current directory"}).input(f.object({pm:f.enum(Wi.map(t=>t.name)).optional().describe("Package manager to use"),linter:f.enum(C.linters).optional().describe("Linter / formatter to use"),editors:f.array(f.enum(C.editorConfigs)).optional().describe("Editors to configure"),agents:f.array(f.enum(C.agents)).optional().describe("Agents to enable"),hooks:f.array(f.enum(C.hooks)).optional().describe("Hooks to enable"),frameworks:f.array(f.enum(C.frameworks)).optional().describe("Frameworks being used"),integrations:f.array(f.enum(C.integrations)).optional().describe("Additional integrations to enable"),migrate:f.array(f.enum(C.migrations)).optional().describe("Migration tools to remove (e.g., eslint, prettier). Removes dependencies, config files, and editor settings."),skipInstall:f.boolean().default(!1).describe("Skip installing dependencies"),quiet:f.boolean().default(process.env.CI==="true"||process.env.CI==="1").describe("Suppress all interactive prompts and visual output. Automatically enabled in CI environments.")})).mutation(async({input:t})=>{await ke(t)}),check:V.procedure.meta({description:"Run linter without fixing files"}).input(f.tuple([f.array(f.string()).optional().default([]).describe("specific files to lint"),f.object({"diagnostic-level":f.enum(["info","warn","error"]).optional().describe("level of diagnostics to show. In order, from the lowest to the most important: info, warn, error."),linter:f.enum(C.linters).optional().describe("linter to use (biome, eslint, or oxlint)")})]).optional()).query(async({input:t})=>{await Tt(t)}),fix:V.procedure.meta({description:"Run linter and fix files"}).input(f.tuple([f.array(f.string()).optional().default([]).describe("specific files to format"),f.object({unsafe:f.boolean().optional().describe("apply unsafe fixes"),linter:f.enum(C.linters).optional().describe("linter to use (biome, eslint, or oxlint)")})]).optional()).mutation(async({input:t})=>{let[e,n]=t??[[],{}];await _t(e,{unsafe:n.unsafe,linter:n.linter})}),doctor:V.procedure.meta({description:"Verify your Ultracite setup and check for issues"}).query(async()=>{await Mt()})}),Hi=Ui({router:zi,name:y.name,version:y.version,description:y.description});process.env.TEST||Hi.run();export{zi as router};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ultracite",
3
3
  "description": "The AI-ready formatter that helps you write and generate code faster.",
4
- "version": "6.5.1",
4
+ "version": "7.0.0",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "ultracite": "dist/index.js"
@@ -17,6 +17,11 @@
17
17
  "test:coverage": "bun test --coverage"
18
18
  },
19
19
  "exports": {
20
+ "./biome/*": "./config/biome/*/biome.jsonc",
21
+ "./eslint/*": "./config/eslint/*/eslint.config.mjs",
22
+ "./oxlint/*": "./config/oxlint/*/.oxlintrc.json",
23
+ "./prettier": "./config/prettier/prettier.config.mjs",
24
+ "./stylelint": "./config/stylelint/stylelint.config.mjs",
20
25
  "./*": "./config/*/biome.jsonc"
21
26
  },
22
27
  "author": "Hayden Bleasel <hello@haydenbleasel.com>",
@@ -41,21 +46,57 @@
41
46
  "url": "git+https://github.com/haydenbleasel/ultracite.git"
42
47
  },
43
48
  "devDependencies": {
44
- "@biomejs/biome": "2.3.10",
45
- "@types/node": "^25.0.0",
46
- "tsup": "^8.5.1",
47
- "turbo": "^2.6.3"
49
+ "@biomejs/biome": "catalog:",
50
+ "@eslint/js": "^9.39.2",
51
+ "@next/eslint-plugin-next": "^16.1.1",
52
+ "@tanstack/eslint-plugin-query": "^5.91.2",
53
+ "@types/node": "catalog:",
54
+ "@typescript-eslint/eslint-plugin": "^8.51.0",
55
+ "@typescript-eslint/parser": "^8.51.0",
56
+ "eslint-config-prettier": "^10.1.8",
57
+ "eslint-import-resolver-typescript": "^4.4.4",
58
+ "eslint-plugin-angular": "^5.0.0",
59
+ "eslint-plugin-astro": "^1.5.0",
60
+ "eslint-plugin-compat": "^6.0.2",
61
+ "eslint-plugin-cypress": "^5.2.0",
62
+ "eslint-plugin-github": "6.0.0",
63
+ "eslint-plugin-html": "^8.1.3",
64
+ "eslint-plugin-import": "^2.32.0",
65
+ "eslint-plugin-jest": "^29.12.0",
66
+ "eslint-plugin-jsx-a11y": "^6.10.2",
67
+ "eslint-plugin-n": "^17.23.1",
68
+ "eslint-plugin-prettier": "^5.5.4",
69
+ "eslint-plugin-promise": "^7.2.1",
70
+ "eslint-plugin-qwik": "^1.18.0",
71
+ "eslint-plugin-react": "^7.37.5",
72
+ "eslint-plugin-react-hooks": "^7.0.1",
73
+ "eslint-plugin-remix": "^1.1.1",
74
+ "eslint-plugin-solid": "^0.14.5",
75
+ "eslint-plugin-sonarjs": "^3.0.5",
76
+ "eslint-plugin-storybook": "^10.1.11",
77
+ "eslint-plugin-svelte": "^3.13.1",
78
+ "eslint-plugin-tailwindcss": "^3.18.2",
79
+ "eslint-plugin-unicorn": "^62.0.0",
80
+ "eslint-plugin-unused-imports": "^4.3.0",
81
+ "eslint-plugin-vue": "^10.6.2",
82
+ "globals": "^16.5.0",
83
+ "prettier-plugin-tailwindcss": "^0.7.2",
84
+ "stylelint-config-idiomatic-order": "^10.0.0",
85
+ "stylelint-config-standard": "^39.0.1",
86
+ "stylelint-prettier": "^5.0.3",
87
+ "tsup": "^8.5.1"
48
88
  },
49
89
  "dependencies": {
50
90
  "@clack/prompts": "^0.11.0",
51
- "@trpc/server": "^11.8.0",
52
- "deepmerge": "^4.3.1",
91
+ "@trpc/server": "^11.8.1",
92
+ "@repo/data": "workspace:*",
93
+ "deepmerge": "catalog:",
53
94
  "glob": "^13.0.0",
54
95
  "jsonc-parser": "^3.3.1",
55
96
  "nypm": "^0.6.2",
56
- "picocolors": "^1.1.1",
97
+ "oxlint": "^1.36.0",
57
98
  "trpc-cli": "^0.12.1",
58
- "zod": "^4.1.13"
99
+ "zod": "catalog:"
59
100
  },
60
- "packageManager": "bun@1.3.4"
101
+ "packageManager": "bun@1.3.5"
61
102
  }
@@ -1,9 +0,0 @@
1
- {
2
- "root": false,
3
- "$schema": "../../node_modules/@biomejs/biome/configuration_schema.json",
4
- "html": {
5
- "parser": {
6
- "interpolation": true
7
- }
8
- }
9
- }