ultracite 6.3.7 → 6.3.9

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.
@@ -237,14 +237,19 @@
237
237
  },
238
238
  "nursery": {
239
239
  "noDuplicateDependencies": "error",
240
+ "noDuplicatedSpreadProps": "error",
240
241
  "noEmptySource": "error",
242
+ "noEqualsToNull": "error",
241
243
  "noIncrementDecrement": {
242
244
  "level": "error",
243
245
  "options": {
244
246
  "allowForLoopAfterthoughts": true
245
247
  }
246
248
  },
249
+ "noLeakedRender": "error",
250
+ "noMultiStr": "error",
247
251
  "noParametersOnlyUsedInRecursion": "error",
252
+ "noProto": "error",
248
253
  "noShadow": "error",
249
254
  "noSyncScripts": "error",
250
255
  "noUnusedExpressions": "error",
@@ -258,6 +263,7 @@
258
263
  "noContinue": "off",
259
264
  "noForIn": "off",
260
265
  "noJsxLiterals": "off",
266
+ "noTernary": "off",
261
267
  "noUselessCatchBinding": "off",
262
268
  "noUnnecessaryConditions": "off",
263
269
  "useArraySortCompare": "off",
package/dist/index.d.ts CHANGED
@@ -11,7 +11,7 @@ declare const router: _trpc_server.TRPCBuiltRouter<{
11
11
  input: {
12
12
  pm?: "npm" | "yarn" | "pnpm" | "bun" | "deno" | undefined;
13
13
  editors?: ("vscode" | "zed")[] | undefined;
14
- agents?: ("zed" | "vscode-copilot" | "cursor" | "windsurf" | "claude" | "codex" | "kiro" | "cline" | "amp" | "aider" | "firebase-studio" | "open-hands" | "gemini-cli" | "junie" | "augmentcode" | "kilo-code" | "goose" | "roo-code" | "warp")[] | undefined;
14
+ agents?: ("zed" | "vscode-copilot" | "cursor" | "windsurf" | "claude" | "codex" | "kiro" | "cline" | "amp" | "aider" | "firebase-studio" | "open-hands" | "gemini-cli" | "junie" | "augmentcode" | "kilo-code" | "goose" | "roo-code" | "warp" | "droid")[] | undefined;
15
15
  hooks?: ("cursor" | "claude")[] | undefined;
16
16
  frameworks?: ("react" | "next" | "solid" | "vue" | "svelte" | "qwik" | "remix" | "angular" | "astro")[] | undefined;
17
17
  integrations?: ("husky" | "lefthook" | "lint-staged")[] | undefined;
package/dist/index.js CHANGED
@@ -117,18 +117,18 @@ ${s}`)}}});var oo,pe=O(()=>{oo=ye({"./husky.ts":()=>(de(),te(_e)),"./lefthook.ts
117
117
  `}else e+=`${o}: '${s}'
118
118
  `;return e},lo=async()=>{try{let t=ge(await K("./package.json","utf-8"));return t?t.type==="module":!1}catch{return!1}},fo=async t=>{let e=ge(await K("./package.json","utf-8"));e&&(e["lint-staged"]?e["lint-staged"]=J(e["lint-staged"],y(t)):e["lint-staged"]=y(t),await C("./package.json",JSON.stringify(e,null,2)))},po=async(t,e)=>{let o=await K(t,"utf-8"),s=ge(o);if(!s)return;let n=J(s,y(e));await C(t,JSON.stringify(n,null,2))},mo=async(t,e)=>{let o=await K(t,"utf-8"),s=ro(o);if(!s)return;let n=J(s,y(e));await C(t,co(n))},uo=async(t,e)=>{let n=(await import(so(t).href)).default||{},i=J(n,y(e)),a=`export default ${JSON.stringify(i,null,2)};
119
119
  `;await C(t,a)},go=async(t,e)=>{delete q.cache[q.resolve(`./${t}`)];let o=oo(`./${t}`),s=J(o,y(e)),n=`module.exports = ${JSON.stringify(s,null,2)};
120
- `;await C(t,n)},ue=async t=>{await C(".lintstagedrc.json",JSON.stringify(y(t),null,2))},ho=async(t,e)=>{if(t==="./package.json"){await fo(e);return}if(t.endsWith(".json")||t==="./.lintstagedrc"){await po(t,e);return}if(t.endsWith(".yaml")||t.endsWith(".yml")){await mo(t,e);return}let o=await lo();if(t.endsWith(".mjs")||t.endsWith(".js")&&o){try{await uo(t,e)}catch{await ue(e)}return}if(t.endsWith(".cjs")||t.endsWith(".js")&&!o)try{await go(t,e)}catch{await ue(e)}},E={exists:async()=>{for(let t of Ge)if(await l(t))return!0;return!1},install:async t=>{await no("lint-staged",{packageManager:t,workspace:await h()})},create:async t=>{await C(".lintstagedrc.json",JSON.stringify(y(t),null,2))},update:async t=>{let e=null;for(let o of Ge)if(await l(o)){e=o;break}if(!e){await ue(t);return}await ho(e,t)}}});import{initTRPC as _o}from"@trpc/server";import{createCli as Lo}from"trpc-cli";import r from"zod";var k={name:"ultracite",description:"The AI-ready formatter that helps you write and generate code faster.",version:"6.3.7",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.7","@types/node":"^24.10.1",tsup:"^8.5.1",turbo:"^2.6.1"},dependencies:{"@clack/prompts":"^0.11.0","@trpc/server":"^11.7.1",deepmerge:"^4.3.1",glob:"^12.0.0","jsonc-parser":"^3.3.1",nypm:"^0.6.2","trpc-cli":"^0.12.0",zod:"^4.1.12"},packageManager:"bun@1.3.2"};m();import{spawnSync as rt}from"child_process";var oe=t=>{let e=t?.[0]||[],o=t?.[1]["diagnostic-level"],s=["npx","@biomejs/biome","check","--no-errors-on-unmatched","--max-diagnostics=none"];o&&s.push(`--diagnostic-level=${o}`),e.length>0?s.push(..._(e)):s.push("./");let n=s.join(" "),i=rt(n,{stdio:"inherit",shell:!0});if(i.error)throw new Error(`Failed to run Ultracite: ${i.error.message}`);if(i.status!==0)throw new Error(`Ultracite check failed with status ${i.status??1}`)};import{spawnSync as vt}from"child_process";import{existsSync as D}from"fs";import{readFile as Re}from"fs/promises";import{join as T}from"path";import{parse as Ct}from"jsonc-parser";m();import{readFile as xe,unlink as ct,writeFile as lt}from"fs/promises";import{parse as ve}from"jsonc-parser";import{removeDependency as dt}from"nypm";var L=[".eslintrc",".eslintrc.js",".eslintrc.json",".eslintrc.yml",".eslintrc.yaml",".eslintrc.config.js","eslint.config.js","eslint.config.mjs","eslint.config.cjs",".eslintignore"],Ce=async()=>{try{let t=await xe("package.json","utf-8"),e=ve(t);if(!e||typeof e!="object")return[];let o=e.dependencies||{},s=e.devDependencies||{},n={...o,...s};return Object.keys(n).filter(i=>i.includes("eslint"))}catch{return[]}},ft=async(t,e)=>{if(e.length!==0)try{for(let o of e)await dt(o,{packageManager:t})}catch(o){console.warn(o)}},pt=async()=>{let t=[];for(let e of L)if(await l(e))try{await ct(e),t.push(e)}catch(o){console.warn(o)}return t},mt=async()=>{let t="./.vscode/settings.json";if(!await l(t))return!1;try{let e=await xe(t,"utf-8"),o=ve(e);if(!o||typeof o!="object")return!1;let s=!1,n={...o},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 n&&(delete n[a],s=!0);if("editor.codeActionsOnSave"in n){let a=n["editor.codeActionsOnSave"];if(a&&typeof a=="object"){let c=["source.fixAll.eslint","source.organizeImports.eslint"];for(let f of c)f in a&&(delete a[f],s=!0);Object.keys(a).length===0&&(n["editor.codeActionsOnSave"]=void 0)}}return s?(await lt(t,JSON.stringify(n,null,2)),!0):!1}catch(e){return console.warn(e),!1}},ut=async()=>{if((await Ce()).length>0)return!0;for(let e of L)if(await l(e))return!0;return!1},se={hasEsLint:ut,remove:async t=>{let e=await Ce();await ft(t,e);let o=await pt(),s=await mt();return{packagesRemoved:e,filesRemoved:o,vsCodeCleaned:s}}};m();import{readFile as je,unlink as gt,writeFile as ht}from"fs/promises";import{parse as Pe}from"jsonc-parser";import{removeDependency as wt}from"nypm";var H=[".prettierrc",".prettierrc.js",".prettierrc.json",".prettierrc.yml",".prettierrc.yaml",".prettierrc.config.js","prettier.config.js","prettier.config.mjs",".prettierignore"],Se=async()=>{try{let t=await je("package.json","utf-8"),e=Pe(t);if(!e||typeof e!="object")return[];let o=e.dependencies||{},s=e.devDependencies||{},n={...o,...s};return Object.keys(n).filter(i=>i.includes("prettier"))}catch{return[]}},yt=async(t,e)=>{if(e.length!==0)try{for(let o of e)await wt(o,{packageManager:t})}catch(o){console.warn(o)}},kt=async()=>{let t=[];for(let e of H)if(await l(e))try{await gt(e),t.push(e)}catch(o){console.warn(o)}return t},bt=async()=>{let t="./.vscode/settings.json";if(!await l(t))return!1;try{let e=await je(t,"utf-8"),o=Pe(e);if(!o||typeof o!="object")return!1;let s=!1,n={...o},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 c of i)c in n&&(c==="editor.defaultFormatter"&&n[c]==="esbenp.prettier-vscode"||c!=="editor.defaultFormatter")&&(delete n[c],s=!0);let a=Object.keys(n).filter(c=>c.startsWith("[")&&c.includes("javascript"));for(let c of a){let f=n[c];f&&typeof f=="object"&&"editor.defaultFormatter"in f&&f["editor.defaultFormatter"]==="esbenp.prettier-vscode"&&(delete f["editor.defaultFormatter"],s=!0,Object.keys(f).length===0&&delete n[c])}return s?(await ht(t,JSON.stringify(n,null,2)),!0):!1}catch(e){return console.warn(e),!1}},xt=async()=>{if((await Se()).length>0)return!0;for(let e of H)if(await l(e))return!0;return!1},ne={hasPrettier:xt,remove:async t=>{let e=await Se();await yt(t,e);let o=await kt(),s=await bt();return{packagesRemoved:e,filesRemoved:o,vsCodeCleaned:s}}};var jt=()=>{let t=vt("npx @biomejs/biome --version",{shell:!0,encoding:"utf-8"});return t.status===0&&t.stdout?{name:"Biome installation",status:"pass",message:`Biome is installed (${t.stdout.trim()})`}:{name:"Biome installation",status:"fail",message:"Biome is not installed or not accessible"}},Pt=async()=>{let t=T(process.cwd(),"biome.json"),e=T(process.cwd(),"biome.jsonc"),o=null;if(D(t)?o=t:D(e)&&(o=e),!o)return{name:"Biome configuration",status:"fail",message:"No biome.json or biome.jsonc file found"};try{let s=await Re(o,"utf-8"),n=Ct(s);return Array.isArray(n?.extends)&&n.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"}}},St=async()=>{let t=T(process.cwd(),"package.json");if(!D(t))return{name:"Ultracite dependency",status:"warn",message:"No package.json found"};try{let e=JSON.parse(await Re(t,"utf-8")),o=e.dependencies?.ultracite||e.devDependencies?.ultracite||e.peerDependencies?.ultracite;return o?{name:"Ultracite dependency",status:"pass",message:`Ultracite is in package.json (${o})`}:{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"}}},Rt=()=>{let t=H.some(o=>D(T(process.cwd(),o))),e=L.some(o=>D(T(process.cwd(),o)));if(t||e){let o=[];return t&&o.push("Prettier"),e&&o.push("ESLint"),{name:"Conflicting tools",status:"warn",message:`Found potentially conflicting tools: ${o.join(", ")}`}}return{name:"Conflicting tools",status:"pass",message:"No conflicting formatting/linting tools found"}},Ee=async()=>{let t=[];console.log(`\u{1FA7A} Running Ultracite doctor...
120
+ `;await C(t,n)},ue=async t=>{await C(".lintstagedrc.json",JSON.stringify(y(t),null,2))},ho=async(t,e)=>{if(t==="./package.json"){await fo(e);return}if(t.endsWith(".json")||t==="./.lintstagedrc"){await po(t,e);return}if(t.endsWith(".yaml")||t.endsWith(".yml")){await mo(t,e);return}let o=await lo();if(t.endsWith(".mjs")||t.endsWith(".js")&&o){try{await uo(t,e)}catch{await ue(e)}return}if(t.endsWith(".cjs")||t.endsWith(".js")&&!o)try{await go(t,e)}catch{await ue(e)}},E={exists:async()=>{for(let t of Ge)if(await l(t))return!0;return!1},install:async t=>{await no("lint-staged",{packageManager:t,workspace:await h()})},create:async t=>{await C(".lintstagedrc.json",JSON.stringify(y(t),null,2))},update:async t=>{let e=null;for(let o of Ge)if(await l(o)){e=o;break}if(!e){await ue(t);return}await ho(e,t)}}});import{initTRPC as _o}from"@trpc/server";import{createCli as Lo}from"trpc-cli";import r from"zod";var k={name:"ultracite",description:"The AI-ready formatter that helps you write and generate code faster.",version:"6.3.9",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.8","@types/node":"^24.10.1",tsup:"^8.5.1",turbo:"^2.6.2"},dependencies:{"@clack/prompts":"^0.11.0","@trpc/server":"^11.7.2",deepmerge:"^4.3.1",glob:"^13.0.0","jsonc-parser":"^3.3.1",nypm:"^0.6.2","trpc-cli":"^0.12.1",zod:"^4.1.13"},packageManager:"bun@1.3.3"};m();import{spawnSync as rt}from"child_process";var oe=t=>{let e=t?.[0]||[],o=t?.[1]["diagnostic-level"],s=["npx","@biomejs/biome","check","--no-errors-on-unmatched","--max-diagnostics=none"];o&&s.push(`--diagnostic-level=${o}`),e.length>0?s.push(..._(e)):s.push("./");let n=s.join(" "),i=rt(n,{stdio:"inherit",shell:!0});if(i.error)throw new Error(`Failed to run Ultracite: ${i.error.message}`);if(i.status!==0)throw new Error(`Ultracite check failed with status ${i.status??1}`)};import{spawnSync as vt}from"child_process";import{existsSync as D}from"fs";import{readFile as Re}from"fs/promises";import{join as T}from"path";import{parse as Ct}from"jsonc-parser";m();import{readFile as xe,unlink as ct,writeFile as lt}from"fs/promises";import{parse as ve}from"jsonc-parser";import{removeDependency as dt}from"nypm";var L=[".eslintrc",".eslintrc.js",".eslintrc.json",".eslintrc.yml",".eslintrc.yaml",".eslintrc.config.js","eslint.config.js","eslint.config.mjs","eslint.config.cjs",".eslintignore"],Ce=async()=>{try{let t=await xe("package.json","utf-8"),e=ve(t);if(!e||typeof e!="object")return[];let o=e.dependencies||{},s=e.devDependencies||{},n={...o,...s};return Object.keys(n).filter(i=>i.includes("eslint"))}catch{return[]}},ft=async(t,e)=>{if(e.length!==0)try{for(let o of e)await dt(o,{packageManager:t})}catch(o){console.warn(o)}},pt=async()=>{let t=[];for(let e of L)if(await l(e))try{await ct(e),t.push(e)}catch(o){console.warn(o)}return t},mt=async()=>{let t="./.vscode/settings.json";if(!await l(t))return!1;try{let e=await xe(t,"utf-8"),o=ve(e);if(!o||typeof o!="object")return!1;let s=!1,n={...o},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 n&&(delete n[a],s=!0);if("editor.codeActionsOnSave"in n){let a=n["editor.codeActionsOnSave"];if(a&&typeof a=="object"){let c=["source.fixAll.eslint","source.organizeImports.eslint"];for(let f of c)f in a&&(delete a[f],s=!0);Object.keys(a).length===0&&(n["editor.codeActionsOnSave"]=void 0)}}return s?(await lt(t,JSON.stringify(n,null,2)),!0):!1}catch(e){return console.warn(e),!1}},ut=async()=>{if((await Ce()).length>0)return!0;for(let e of L)if(await l(e))return!0;return!1},se={hasEsLint:ut,remove:async t=>{let e=await Ce();await ft(t,e);let o=await pt(),s=await mt();return{packagesRemoved:e,filesRemoved:o,vsCodeCleaned:s}}};m();import{readFile as je,unlink as gt,writeFile as ht}from"fs/promises";import{parse as Pe}from"jsonc-parser";import{removeDependency as wt}from"nypm";var H=[".prettierrc",".prettierrc.js",".prettierrc.json",".prettierrc.yml",".prettierrc.yaml",".prettierrc.config.js","prettier.config.js","prettier.config.mjs",".prettierignore"],Se=async()=>{try{let t=await je("package.json","utf-8"),e=Pe(t);if(!e||typeof e!="object")return[];let o=e.dependencies||{},s=e.devDependencies||{},n={...o,...s};return Object.keys(n).filter(i=>i.includes("prettier"))}catch{return[]}},yt=async(t,e)=>{if(e.length!==0)try{for(let o of e)await wt(o,{packageManager:t})}catch(o){console.warn(o)}},kt=async()=>{let t=[];for(let e of H)if(await l(e))try{await gt(e),t.push(e)}catch(o){console.warn(o)}return t},bt=async()=>{let t="./.vscode/settings.json";if(!await l(t))return!1;try{let e=await je(t,"utf-8"),o=Pe(e);if(!o||typeof o!="object")return!1;let s=!1,n={...o},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 c of i)c in n&&(c==="editor.defaultFormatter"&&n[c]==="esbenp.prettier-vscode"||c!=="editor.defaultFormatter")&&(delete n[c],s=!0);let a=Object.keys(n).filter(c=>c.startsWith("[")&&c.includes("javascript"));for(let c of a){let f=n[c];f&&typeof f=="object"&&"editor.defaultFormatter"in f&&f["editor.defaultFormatter"]==="esbenp.prettier-vscode"&&(delete f["editor.defaultFormatter"],s=!0,Object.keys(f).length===0&&delete n[c])}return s?(await ht(t,JSON.stringify(n,null,2)),!0):!1}catch(e){return console.warn(e),!1}},xt=async()=>{if((await Se()).length>0)return!0;for(let e of H)if(await l(e))return!0;return!1},ne={hasPrettier:xt,remove:async t=>{let e=await Se();await yt(t,e);let o=await kt(),s=await bt();return{packagesRemoved:e,filesRemoved:o,vsCodeCleaned:s}}};var jt=()=>{let t=vt("npx @biomejs/biome --version",{shell:!0,encoding:"utf-8"});return t.status===0&&t.stdout?{name:"Biome installation",status:"pass",message:`Biome is installed (${t.stdout.trim()})`}:{name:"Biome installation",status:"fail",message:"Biome is not installed or not accessible"}},Pt=async()=>{let t=T(process.cwd(),"biome.json"),e=T(process.cwd(),"biome.jsonc"),o=null;if(D(t)?o=t:D(e)&&(o=e),!o)return{name:"Biome configuration",status:"fail",message:"No biome.json or biome.jsonc file found"};try{let s=await Re(o,"utf-8"),n=Ct(s);return Array.isArray(n?.extends)&&n.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"}}},St=async()=>{let t=T(process.cwd(),"package.json");if(!D(t))return{name:"Ultracite dependency",status:"warn",message:"No package.json found"};try{let e=JSON.parse(await Re(t,"utf-8")),o=e.dependencies?.ultracite||e.devDependencies?.ultracite||e.peerDependencies?.ultracite;return o?{name:"Ultracite dependency",status:"pass",message:`Ultracite is in package.json (${o})`}:{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"}}},Rt=()=>{let t=H.some(o=>D(T(process.cwd(),o))),e=L.some(o=>D(T(process.cwd(),o)));if(t||e){let o=[];return t&&o.push("Prettier"),e&&o.push("ESLint"),{name:"Conflicting tools",status:"warn",message:`Found potentially conflicting tools: ${o.join(", ")}`}}return{name:"Conflicting tools",status:"pass",message:"No conflicting formatting/linting tools found"}},Ee=async()=>{let t=[];console.log(`\u{1FA7A} Running Ultracite doctor...
121
121
  `),t.push(jt()),t.push(await Pt()),t.push(await St()),t.push(Rt());let e=t.filter(n=>n.status==="pass").length,o=t.filter(n=>n.status==="fail").length,s=t.filter(n=>n.status==="warn").length;for(let n of t){let i;n.status==="pass"?i="\u2705":n.status==="fail"?i="\u274C":i="\u26A0\uFE0F",console.log(`${i} ${n.name}: ${n.message}`)}if(console.log(`
122
122
  \u{1F4CA} Summary:`),console.log(` ${e} passed, ${s} warnings, ${o} failed`),o>0)throw console.log(`
123
123
  \u{1F4A1} To fix issues, run: npx ultracite init`),new Error("Doctor checks failed");s>0?console.log(`
124
124
  \u{1F4A1} Some optional improvements available. Run 'npx ultracite init' to configure.`):console.log(`
125
- \u2728 Everything looks good!`)};m();import{spawnSync as Et}from"child_process";var ie=(t,e={})=>{let o=["npx","@biomejs/biome","check","--write","--no-errors-on-unmatched","--max-diagnostics=none"];e.unsafe&&o.push("--unsafe"),t.length>0?o.push(..._(t)):o.push("./");let s=o.join(" "),n=Et(s,{stdio:"inherit",shell:!0});if(n.error)throw new Error(`Failed to run Ultracite: ${n.error.message}`);if(n.status!==0)throw new Error(`Ultracite fix failed with status ${n.status??1}`)};import{packageManagers as At}from"nypm";var w={packageManagers:At.map(t=>t.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"],integrations:["husky","lefthook","lint-staged"],hooks:["cursor","claude"],frameworks:["react","next","solid","vue","svelte","qwik","remix","angular","astro"],migrations:["eslint","prettier"]};import jo from"process";import{cancel as A,intro as Po,isCancel as F,log as X,multiselect as $,spinner as u}from"@clack/prompts";import{addDevDependency as So,detectPackageManager as Ro}from"nypm";import{mkdir as Ft,readFile as $t,writeFile as W}from"fs/promises";import{dirname as Nt}from"path";var Ae={"vscode-copilot":{path:"./.github/copilot-instructions.md",header:`---
125
+ \u2728 Everything looks good!`)};m();import{spawnSync as Et}from"child_process";var ie=(t,e={})=>{let o=["npx","@biomejs/biome","check","--write","--no-errors-on-unmatched","--max-diagnostics=none"];e.unsafe&&o.push("--unsafe"),t.length>0?o.push(..._(t)):o.push("./");let s=o.join(" "),n=Et(s,{stdio:"inherit",shell:!0});if(n.error)throw new Error(`Failed to run Ultracite: ${n.error.message}`);if(n.status!==0)throw new Error(`Ultracite fix failed with status ${n.status??1}`)};import{packageManagers as At}from"nypm";var w={packageManagers:At.map(t=>t.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"],integrations:["husky","lefthook","lint-staged"],hooks:["cursor","claude"],frameworks:["react","next","solid","vue","svelte","qwik","remix","angular","astro"],migrations:["eslint","prettier"]};import jo from"process";import{cancel as A,intro as Po,isCancel as F,log as X,multiselect as $,spinner as u}from"@clack/prompts";import{addDevDependency as So,detectPackageManager as Ro}from"nypm";import{mkdir as Ft,readFile as $t,writeFile as W}from"fs/promises";import{dirname as Nt}from"path";var Ae={"vscode-copilot":{path:"./.github/copilot-instructions.md",header:`---
126
126
  applyTo: "**/*.{ts,tsx,js,jsx}"
127
127
  ---`,appendMode:!0},cursor:{path:"./.cursor/rules/ultracite.mdc",header:`---
128
128
  description: Ultracite Rules - AI-Ready Formatter and Linter
129
129
  globs: "**/*.{ts,tsx,js,jsx,json,jsonc,html,vue,svelte,astro,css,yaml,yml,graphql,gql,md,mdx,grit}"
130
130
  alwaysApply: false
131
- ---`},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}},Fe={cursor:{path:"./.cursor/hooks.json",command:"npx ultracite fix"},claude:{path:"./.claude/settings.json",command:"npx ultracite fix"}};m();var M=`# Ultracite Code Standards
131
+ ---`},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}},Fe={cursor:{path:"./.cursor/hooks.json",command:"npx ultracite fix"},claude:{path:"./.claude/settings.json",command:"npx ultracite fix"}};m();var M=`# Ultracite Code Standards
132
132
 
133
133
  This project uses **Ultracite**, a zero-config Biome preset that enforces strict code quality standards through automated formatting and linting.
134
134
 
@@ -255,4 +255,4 @@ Most formatting and common issues are automatically fixed by Biome. Run \`npx ul
255
255
 
256
256
  ${M}`:M,s=async()=>{let n=Nt(e.path);if(n!=="."){let i=n.startsWith("./")?n.slice(2):n;await Ft(i,{recursive:!0})}};return{exists:()=>l(e.path),create:async()=>{await s(),await W(e.path,o)},update:async()=>{if(await s(),e.appendMode){if(!await l(e.path)){await W(e.path,o);return}let n=await $t(e.path,"utf-8");if(n.includes(M.trim()))return;await W(e.path,`${n}
257
257
 
258
- ${M}`)}else await W(e.path,o)}}};m();import{readFile as Ot,writeFile as Ne}from"fs/promises";import Dt from"deepmerge";import{parse as Tt}from"jsonc-parser";var Oe={$schema:"./node_modules/@biomejs/biome/configuration_schema.json",extends:["ultracite/core"]},ae=async()=>await l("./biome.json")?"./biome.json":"./biome.jsonc",z={exists:async()=>{let t=await ae();return l(t)},create:async t=>{let e=await ae(),o=["ultracite/core"];if(t?.frameworks&&t.frameworks.length>0)for(let n of t.frameworks)o.push(`ultracite/${n}`);let s={...Oe,extends:o};return Ne(e,JSON.stringify(s,null,2))},update:async t=>{let e=await ae(),o=await Ot(e,"utf-8"),n=Tt(o)||{},a=[...n.extends&&Array.isArray(n.extends)?n.extends:[]];if(a.includes("ultracite/core")||a.push("ultracite/core"),t?.frameworks&&t.frameworks.length>0)for(let g of t.frameworks){let N=`ultracite/${g}`;a.includes(N)||a.push(N)}n.extends=a;let c={$schema:Oe.$schema},f=Dt(n,c);await Ne(e,JSON.stringify(f,null,2))}};import{mkdir as Mt,readFile as De,writeFile as S}from"fs/promises";import{dirname as Ut}from"path";m();var Te=t=>{let e=Fe[t],o=async()=>{let s=Ut(e.path);if(s!=="."){let n=s.startsWith("./")?s.slice(2):s;await Mt(n,{recursive:!0})}};return{exists:()=>l(e.path),create:async()=>{await o(),t==="cursor"?await S(e.path,JSON.stringify({version:1,hooks:{afterFileEdit:[{command:e.command}]}},null,2)):t==="claude"&&await S(e.path,JSON.stringify({hooks:{PostToolUse:[{matcher:"Edit|Write",hooks:[{type:"command",command:e.command}]}]}},null,2))},update:async()=>{if(await o(),t==="cursor"){if(!await l(e.path)){await S(e.path,JSON.stringify({version:1,hooks:{afterFileEdit:[{command:e.command}]}},null,2));return}let s=await De(e.path,"utf-8"),n=JSON.parse(s);n.hooks.afterFileEdit.some(a=>a.command.includes("ultracite"))||(n.hooks.afterFileEdit.push({command:e.command}),await S(e.path,JSON.stringify(n,null,2)))}else if(t==="claude"){if(!await l(e.path)){await S(e.path,JSON.stringify({hooks:{PostToolUse:[{matcher:"Edit|Write",hooks:[{type:"command",command:e.command}]}]}},null,2));return}let s=await De(e.path,"utf-8"),n=JSON.parse(s);n.hooks||(n.hooks={}),n.hooks.PostToolUse||(n.hooks.PostToolUse=[]),n.hooks.PostToolUse.some(a=>a.hooks?.some(c=>c.command.includes("ultracite")))||(n.hooks.PostToolUse.push({matcher:"Edit|Write",hooks:[{type:"command",command:e.command}]}),await S(e.path,JSON.stringify(n,null,2)))}}}};m();import{spawnSync as It}from"child_process";import{mkdir as Jt,readFile as _t,writeFile as Me}from"fs/promises";import Lt from"deepmerge";import{parse as Ht}from"jsonc-parser";var re={"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 B="./.vscode/settings.json",U={exists:()=>l(B),create:async()=>{await Jt(".vscode",{recursive:!0}),await Me(B,JSON.stringify(re,null,2))},update:async()=>{let t=await _t(B,"utf-8"),o=Ht(t)||{},s=Lt(o,re);await Me(B,JSON.stringify(s,null,2))},extension:()=>It("code --install-extension biomejs.biome",{stdio:"inherit",shell:!0})};m();import{mkdir as Wt,readFile as zt,writeFile as Ue}from"fs/promises";import Bt from"deepmerge";import{parse as Gt}from"jsonc-parser";var ce={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 G="./.zed/settings.json",V={exists:()=>l(G),create:async()=>{await Wt(".zed",{recursive:!0}),await Ue(G,JSON.stringify(ce,null,2))},update:async()=>{let t=await zt(G,"utf-8"),o=Gt(t)||{},s=Bt(o,ce);await Ue(G,JSON.stringify(s,null,2))}};de();fe();me();import{readFile as wo,writeFile as yo}from"fs/promises";import ko from"deepmerge";import{glob as bo}from"glob";import{parse as xo}from"jsonc-parser";var vo={compilerOptions:{strictNullChecks:!0}},Ve=async()=>{try{return await bo("**/tsconfig*.json",{ignore:["**/node_modules/**","**/dist/**","**/build/**","**/.next/**"],absolute:!1})}catch{return[]}},Co=async t=>{try{let e=await wo(t,"utf-8"),s=xo(e)||{},n=ko(s,vo);await yo(t,JSON.stringify(n,null,2))}catch(e){console.warn(`Failed to update ${t}:`,e)}},he={exists:async()=>(await Ve()).length>0,update:async()=>{let t=await Ve();if(t.length===0){console.warn("No tsconfig.json files found in the project");return}await Promise.all(t.map(e=>Co(e)))}};m();var Ye=k.devDependencies["@biomejs/biome"],Ke=k.version,Eo=async(t,e=!0,o=!1)=>{let s=u();o||s.start("Installing dependencies...");let n=[`ultracite@${Ke}`,`@biomejs/biome@${Ye}`];if(e)for(let i of n)await So(i,{packageManager:t,workspace:await h(),silent:o});else await b({devDependencies:{"@biomejs/biome":Ye,ultracite:Ke}});o||s.stop("Dependencies installed.")},Ao=async(t=!1)=>{let e=u();if(t||e.start("Checking for tsconfig.json files..."),await he.exists()){t||e.message("Found tsconfig.json files, updating with strictNullChecks..."),await he.update(),t||e.stop("tsconfig.json files updated.");return}t||e.stop("No tsconfig.json files found, skipping.")},Fo=async(t=!1)=>{let e=u();if(t||e.start("Checking for .vscode/settings.json..."),await U.exists()){t||e.message("settings.json found, updating..."),await U.update(),t||e.stop("settings.json updated.");return}t||e.message("settings.json not found, creating..."),await U.create(),t||(e.message("settings.json created."),e.message("Installing Biome extension..."));try{U.extension(),t||e.stop("settings.json created.")}catch(o){t||e.stop(`Failed to install Biome extension (${o}), but continuing...`)}},$o=async(t=!1)=>{let e=u();if(t||e.start("Checking for .zed/settings.json..."),await V.exists()){t||e.message("settings.json found, updating..."),await V.update(),t||e.stop("settings.json updated.");return}t||e.message("settings.json not found, creating..."),await V.create(),t||e.message("settings.json created. Install the Biome extension: https://biomejs.dev/reference/zed/")},No=async(t,e=!1)=>{let o=u();if(e||o.start("Checking for Biome configuration..."),await z.exists()){e||o.message("Biome configuration found, updating..."),await z.update({frameworks:t}),e||o.stop("Biome configuration updated.");return}e||o.message("Biome configuration not found, creating..."),await z.create({frameworks:t}),e||o.stop("Biome configuration created.")},Oo=async(t,e=!0,o=!1)=>{let s=u();if(o||(s.start("Initializing pre-commit hooks..."),s.message("Installing Husky...")),e?await x.install(t):await b({devDependencies:{husky:"latest"},scripts:{prepare:"husky"}}),o||s.message("Initializing Husky..."),x.init(t),await x.exists()){o||s.message("Pre-commit hook found, updating..."),await x.update(t),o||s.stop("Pre-commit hook updated.");return}o||s.message("Pre-commit hook not found, creating..."),await x.create(t),o||s.stop("Pre-commit hook created.")},Do=async(t,e=!0,o=!1)=>{let s=u();if(o||(s.start("Initializing lefthook..."),s.message("Installing lefthook...")),e?await R.install(t):await b({devDependencies:{lefthook:"latest"}}),await R.exists()){o||s.message("lefthook.yml found, updating..."),await R.update(t),o||s.stop("lefthook.yml updated.");return}o||s.message("lefthook.yml not found, creating..."),await R.create(t),o||s.stop("lefthook.yml created.")},To=async(t,e=!0,o=!1)=>{let s=u();if(o||(s.start("Initializing lint-staged..."),s.message("Installing lint-staged...")),e?await E.install(t):await b({devDependencies:{"lint-staged":"latest"}}),await E.exists()){o||s.message("lint-staged found, updating..."),await E.update(t),o||s.stop("lint-staged updated.");return}o||s.message("lint-staged not found, creating..."),await E.create(t),o||s.stop("lint-staged created.")},Mo=async(t,e,o=!1)=>{let s=u();o||s.start(`Checking for ${e}...`);let n=$e(t);if(await n.exists()){o||s.message(`${e} found, updating...`),await n.update(),o||s.stop(`${e} updated.`);return}o||s.message(`${e} not found, creating...`),await n.create(),o||s.stop(`${e} created.`)},Uo=async(t,e,o=!1)=>{let s=u();o||s.start(`Checking for ${e} hooks...`);let n=Te(t);if(await n.exists()){o||s.message(`${e} hooks found, updating...`),await n.update(),o||s.stop(`${e} hooks updated.`);return}o||s.message(`${e} hooks not found, creating...`),await n.create(),o||s.stop(`${e} hooks created.`)},Io=async(t,e=!1)=>{let o=u();e||o.start("Removing Prettier dependencies and configuration...");try{let s=await ne.remove(t);e||(s.packagesRemoved.length>0&&o.message(`Removed Prettier packages: ${s.packagesRemoved.join(", ")}`),s.filesRemoved.length>0&&o.message(`Removed config files: ${s.filesRemoved.join(", ")}`),s.vsCodeCleaned&&o.message("Cleaned VS Code settings"),o.stop("Prettier removed successfully."))}catch{e||o.stop("Failed to remove Prettier completely, but continuing...")}},Jo=async(t,e=!1)=>{let o=u();e||o.start("Removing ESLint dependencies and configuration...");try{let s=await se.remove(t);e||(s.packagesRemoved.length>0&&o.message(`Removed ESLint packages: ${s.packagesRemoved.join(", ")}`),s.filesRemoved.length>0&&o.message(`Removed config files: ${s.filesRemoved.join(", ")}`),s.vsCodeCleaned&&o.message("Cleaned VS Code settings"),o.stop("ESLint removed successfully."))}catch{e||o.stop("Failed to remove ESLint completely, but continuing...")}},Xe=async t=>{let e=t??{},o=e.quiet??!1;o||Po(be);try{let{pm:s}=e;if(!s){let d=await Ro(jo.cwd());if(!d)throw new Error("No package manager specified or detected");if(!o&&d.warnings)for(let p of d.warnings)X.warn(p);o||X.info(`Detected lockfile, using ${d.name}`),s=d.name}let n=e.migrate?.includes("prettier"),i=e.migrate?.includes("eslint");if(!o&&(n===void 0||i===void 0)){let d=[];if(n===void 0&&await ne.hasPrettier()&&d.push({label:"Remove Prettier (dependencies, config files, VS Code settings)",value:"prettier"}),i===void 0&&await se.hasEsLint()&&d.push({label:"Remove ESLint (dependencies, config files, VS Code settings)",value:"eslint"}),d.length>0){let p=await $({message:"Remove existing formatters/linters (recommended for clean migration)?",options:d,required:!1});if(F(p)){A("Operation cancelled.");return}n===void 0&&(n=p.includes("prettier")),i===void 0&&(i=p.includes("eslint"))}}o&&(n===void 0&&(n=!1),i===void 0&&(i=!1));let a=e.frameworks;if(a===void 0)if(o||e.pm||e.editors||e.agents||e.hooks||e.integrations!==void 0||e.migrate!==void 0)a=[];else{let p=await $({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(F(p)){A("Operation cancelled.");return}a=p}let c=e.editors;if(!c)if(o)c=[];else{let d=await $({message:"Which editors do you want to configure (recommended)?",options:[{label:"VSCode / Cursor / Windsurf",value:"vscode"},{label:"Zed",value:"zed"}],required:!1});if(F(d)){A("Operation cancelled.");return}c=d}let f=e.agents,g=e.hooks,N={"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"};if(!f)if(o)f=[];else{let d=await $({message:"Which agents do you want to enable (optional)?",options:Object.entries(N).map(([p,Q])=>({value:p,label:Q})),required:!1});if(F(d)){A("Operation cancelled.");return}f=d}let we={cursor:"Cursor",claude:"Claude Code"};if(!g)if(o)g=[];else{let d=await $({message:"Which agent hooks do you want to enable (optional)?",options:Object.entries(we).map(([p,Q])=>({value:p,label:Q})),required:!1});if(F(d)){A("Operation cancelled.");return}g=d}let P=e.integrations;if(P===void 0)if(o||e.pm||e.editors||e.agents||e.hooks||e.migrate!==void 0)P=[];else{let p=await $({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"}],required:!1});if(F(p)){A("Operation cancelled.");return}P=p}n&&await Io(s,o),i&&await Jo(s,o),await Eo(s,!e.skipInstall,o),await Ao(o),await No(a,o),c?.includes("vscode")&&await Fo(o),c?.includes("zed")&&await $o(o);for(let d of f??[])await Mo(d,N[d],o);for(let d of g??[])await Uo(d,we[d],o);P?.includes("husky")&&await Oo(s,!e.skipInstall,o),P?.includes("lefthook")&&await Do(s,!e.skipInstall,o),P?.includes("lint-staged")&&await To(s,!e.skipInstall,o),o||X.success("Successfully initialized Ultracite configuration!")}catch(s){let n=s instanceof Error?s.message:"Unknown error";throw o||X.error(`Failed to initialize Ultracite configuration: ${n}`),s}};var j=_o.meta().create(),Ho=j.router({init:j.procedure.meta({description:"Initialize Ultracite in the current directory"}).input(r.object({pm:r.enum(w.packageManagers).optional().describe("Package manager to use"),editors:r.array(r.enum(w.editorConfigs)).optional().describe("Editors to configure"),agents:r.array(r.enum(w.agents)).optional().describe("Agents to enable"),hooks:r.array(r.enum(w.hooks)).optional().describe("Hooks to enable"),frameworks:r.array(r.enum(w.frameworks)).optional().describe("Frameworks being used"),integrations:r.array(r.enum(w.integrations)).optional().describe("Additional integrations to enable"),migrate:r.array(r.enum(w.migrations)).optional().describe("Migration tools to remove (e.g., eslint, prettier). Removes dependencies, config files, and editor settings."),skipInstall:r.boolean().default(!1).describe("Skip installing dependencies"),quiet:r.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 Xe(t)}),check:j.procedure.meta({description:"Run Biome linter without fixing files"}).input(r.tuple([r.array(r.string()).optional().default([]).describe("specific files to lint"),r.object({"diagnostic-level":r.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(({input:t})=>{oe(t)}),fix:j.procedure.meta({description:"Run Biome linter and fixes files"}).input(r.tuple([r.array(r.string()).optional().default([]).describe("specific files to format"),r.object({unsafe:r.boolean().optional().describe("apply unsafe fixes")})])).mutation(({input:t})=>{let[e,o]=t;ie(e,{unsafe:o.unsafe})}),doctor:j.procedure.meta({description:"Verify your Ultracite setup and check for issues"}).query(async()=>{await Ee()}),lint:j.procedure.meta({description:"\u26A0\uFE0F DEPRECATED: Use 'check' instead - Run Biome linter without fixing files"}).input(r.array(r.string()).optional().default([]).describe("specific files to lint")).query(({input:t})=>{console.warn("\u26A0\uFE0F Warning: 'lint' command is deprecated. Please use 'check' instead."),oe([t,{}])}),format:j.procedure.meta({description:"\u26A0\uFE0F DEPRECATED: Use 'fix' instead - Run Biome linter and fixes files"}).input(r.tuple([r.array(r.string()).optional().default([]).describe("specific files to format"),r.object({unsafe:r.boolean().optional().describe("apply unsafe fixes")})])).mutation(({input:t})=>{let[e,o]=t;console.warn("\u26A0\uFE0F Warning: 'format' command is deprecated. Please use 'fix' instead."),ie(e,{unsafe:o.unsafe})})}),Wo=Lo({router:Ho,name:k.name,version:k.version,description:k.description});process.env.TEST||Wo.run();export{Ho as router};
258
+ ${M}`)}else await W(e.path,o)}}};m();import{readFile as Ot,writeFile as Ne}from"fs/promises";import Dt from"deepmerge";import{parse as Tt}from"jsonc-parser";var Oe={$schema:"./node_modules/@biomejs/biome/configuration_schema.json",extends:["ultracite/core"]},ae=async()=>await l("./biome.json")?"./biome.json":"./biome.jsonc",z={exists:async()=>{let t=await ae();return l(t)},create:async t=>{let e=await ae(),o=["ultracite/core"];if(t?.frameworks&&t.frameworks.length>0)for(let n of t.frameworks)o.push(`ultracite/${n}`);let s={...Oe,extends:o};return Ne(e,JSON.stringify(s,null,2))},update:async t=>{let e=await ae(),o=await Ot(e,"utf-8"),n=Tt(o)||{},a=[...n.extends&&Array.isArray(n.extends)?n.extends:[]];if(a.includes("ultracite/core")||a.push("ultracite/core"),t?.frameworks&&t.frameworks.length>0)for(let g of t.frameworks){let N=`ultracite/${g}`;a.includes(N)||a.push(N)}n.extends=a;let c={$schema:Oe.$schema},f=Dt(n,c);await Ne(e,JSON.stringify(f,null,2))}};import{mkdir as Mt,readFile as De,writeFile as S}from"fs/promises";import{dirname as Ut}from"path";m();var Te=t=>{let e=Fe[t],o=async()=>{let s=Ut(e.path);if(s!=="."){let n=s.startsWith("./")?s.slice(2):s;await Mt(n,{recursive:!0})}};return{exists:()=>l(e.path),create:async()=>{await o(),t==="cursor"?await S(e.path,JSON.stringify({version:1,hooks:{afterFileEdit:[{command:e.command}]}},null,2)):t==="claude"&&await S(e.path,JSON.stringify({hooks:{PostToolUse:[{matcher:"Edit|Write",hooks:[{type:"command",command:e.command}]}]}},null,2))},update:async()=>{if(await o(),t==="cursor"){if(!await l(e.path)){await S(e.path,JSON.stringify({version:1,hooks:{afterFileEdit:[{command:e.command}]}},null,2));return}let s=await De(e.path,"utf-8"),n=JSON.parse(s);n.hooks.afterFileEdit.some(a=>a.command.includes("ultracite"))||(n.hooks.afterFileEdit.push({command:e.command}),await S(e.path,JSON.stringify(n,null,2)))}else if(t==="claude"){if(!await l(e.path)){await S(e.path,JSON.stringify({hooks:{PostToolUse:[{matcher:"Edit|Write",hooks:[{type:"command",command:e.command}]}]}},null,2));return}let s=await De(e.path,"utf-8"),n=JSON.parse(s);n.hooks||(n.hooks={}),n.hooks.PostToolUse||(n.hooks.PostToolUse=[]),n.hooks.PostToolUse.some(a=>a.hooks?.some(c=>c.command.includes("ultracite")))||(n.hooks.PostToolUse.push({matcher:"Edit|Write",hooks:[{type:"command",command:e.command}]}),await S(e.path,JSON.stringify(n,null,2)))}}}};m();import{spawnSync as It}from"child_process";import{mkdir as Jt,readFile as _t,writeFile as Me}from"fs/promises";import Lt from"deepmerge";import{parse as Ht}from"jsonc-parser";var re={"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 B="./.vscode/settings.json",U={exists:()=>l(B),create:async()=>{await Jt(".vscode",{recursive:!0}),await Me(B,JSON.stringify(re,null,2))},update:async()=>{let t=await _t(B,"utf-8"),o=Ht(t)||{},s=Lt(o,re);await Me(B,JSON.stringify(s,null,2))},extension:()=>It("code --install-extension biomejs.biome",{stdio:"inherit",shell:!0})};m();import{mkdir as Wt,readFile as zt,writeFile as Ue}from"fs/promises";import Bt from"deepmerge";import{parse as Gt}from"jsonc-parser";var ce={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 G="./.zed/settings.json",V={exists:()=>l(G),create:async()=>{await Wt(".zed",{recursive:!0}),await Ue(G,JSON.stringify(ce,null,2))},update:async()=>{let t=await zt(G,"utf-8"),o=Gt(t)||{},s=Bt(o,ce);await Ue(G,JSON.stringify(s,null,2))}};de();fe();me();import{readFile as wo,writeFile as yo}from"fs/promises";import ko from"deepmerge";import{glob as bo}from"glob";import{parse as xo}from"jsonc-parser";var vo={compilerOptions:{strictNullChecks:!0}},Ve=async()=>{try{return await bo("**/tsconfig*.json",{ignore:["**/node_modules/**","**/dist/**","**/build/**","**/.next/**"],absolute:!1})}catch{return[]}},Co=async t=>{try{let e=await wo(t,"utf-8"),s=xo(e)||{},n=ko(s,vo);await yo(t,JSON.stringify(n,null,2))}catch(e){console.warn(`Failed to update ${t}:`,e)}},he={exists:async()=>(await Ve()).length>0,update:async()=>{let t=await Ve();if(t.length===0){console.warn("No tsconfig.json files found in the project");return}await Promise.all(t.map(e=>Co(e)))}};m();var Ye=k.devDependencies["@biomejs/biome"],Ke=k.version,Eo=async(t,e=!0,o=!1)=>{let s=u();o||s.start("Installing dependencies...");let n=[`ultracite@${Ke}`,`@biomejs/biome@${Ye}`];if(e)for(let i of n)await So(i,{packageManager:t,workspace:await h(),silent:o});else await b({devDependencies:{"@biomejs/biome":Ye,ultracite:Ke}});o||s.stop("Dependencies installed.")},Ao=async(t=!1)=>{let e=u();if(t||e.start("Checking for tsconfig.json files..."),await he.exists()){t||e.message("Found tsconfig.json files, updating with strictNullChecks..."),await he.update(),t||e.stop("tsconfig.json files updated.");return}t||e.stop("No tsconfig.json files found, skipping.")},Fo=async(t=!1)=>{let e=u();if(t||e.start("Checking for .vscode/settings.json..."),await U.exists()){t||e.message("settings.json found, updating..."),await U.update(),t||e.stop("settings.json updated.");return}t||e.message("settings.json not found, creating..."),await U.create(),t||(e.message("settings.json created."),e.message("Installing Biome extension..."));try{U.extension(),t||e.stop("settings.json created.")}catch(o){t||e.stop(`Failed to install Biome extension (${o}), but continuing...`)}},$o=async(t=!1)=>{let e=u();if(t||e.start("Checking for .zed/settings.json..."),await V.exists()){t||e.message("settings.json found, updating..."),await V.update(),t||e.stop("settings.json updated.");return}t||e.message("settings.json not found, creating..."),await V.create(),t||e.message("settings.json created. Install the Biome extension: https://biomejs.dev/reference/zed/")},No=async(t,e=!1)=>{let o=u();if(e||o.start("Checking for Biome configuration..."),await z.exists()){e||o.message("Biome configuration found, updating..."),await z.update({frameworks:t}),e||o.stop("Biome configuration updated.");return}e||o.message("Biome configuration not found, creating..."),await z.create({frameworks:t}),e||o.stop("Biome configuration created.")},Oo=async(t,e=!0,o=!1)=>{let s=u();if(o||(s.start("Initializing pre-commit hooks..."),s.message("Installing Husky...")),e?await x.install(t):await b({devDependencies:{husky:"latest"},scripts:{prepare:"husky"}}),o||s.message("Initializing Husky..."),x.init(t),await x.exists()){o||s.message("Pre-commit hook found, updating..."),await x.update(t),o||s.stop("Pre-commit hook updated.");return}o||s.message("Pre-commit hook not found, creating..."),await x.create(t),o||s.stop("Pre-commit hook created.")},Do=async(t,e=!0,o=!1)=>{let s=u();if(o||(s.start("Initializing lefthook..."),s.message("Installing lefthook...")),e?await R.install(t):await b({devDependencies:{lefthook:"latest"}}),await R.exists()){o||s.message("lefthook.yml found, updating..."),await R.update(t),o||s.stop("lefthook.yml updated.");return}o||s.message("lefthook.yml not found, creating..."),await R.create(t),o||s.stop("lefthook.yml created.")},To=async(t,e=!0,o=!1)=>{let s=u();if(o||(s.start("Initializing lint-staged..."),s.message("Installing lint-staged...")),e?await E.install(t):await b({devDependencies:{"lint-staged":"latest"}}),await E.exists()){o||s.message("lint-staged found, updating..."),await E.update(t),o||s.stop("lint-staged updated.");return}o||s.message("lint-staged not found, creating..."),await E.create(t),o||s.stop("lint-staged created.")},Mo=async(t,e,o=!1)=>{let s=u();o||s.start(`Checking for ${e}...`);let n=$e(t);if(await n.exists()){o||s.message(`${e} found, updating...`),await n.update(),o||s.stop(`${e} updated.`);return}o||s.message(`${e} not found, creating...`),await n.create(),o||s.stop(`${e} created.`)},Uo=async(t,e,o=!1)=>{let s=u();o||s.start(`Checking for ${e} hooks...`);let n=Te(t);if(await n.exists()){o||s.message(`${e} hooks found, updating...`),await n.update(),o||s.stop(`${e} hooks updated.`);return}o||s.message(`${e} hooks not found, creating...`),await n.create(),o||s.stop(`${e} hooks created.`)},Io=async(t,e=!1)=>{let o=u();e||o.start("Removing Prettier dependencies and configuration...");try{let s=await ne.remove(t);e||(s.packagesRemoved.length>0&&o.message(`Removed Prettier packages: ${s.packagesRemoved.join(", ")}`),s.filesRemoved.length>0&&o.message(`Removed config files: ${s.filesRemoved.join(", ")}`),s.vsCodeCleaned&&o.message("Cleaned VS Code settings"),o.stop("Prettier removed successfully."))}catch{e||o.stop("Failed to remove Prettier completely, but continuing...")}},Jo=async(t,e=!1)=>{let o=u();e||o.start("Removing ESLint dependencies and configuration...");try{let s=await se.remove(t);e||(s.packagesRemoved.length>0&&o.message(`Removed ESLint packages: ${s.packagesRemoved.join(", ")}`),s.filesRemoved.length>0&&o.message(`Removed config files: ${s.filesRemoved.join(", ")}`),s.vsCodeCleaned&&o.message("Cleaned VS Code settings"),o.stop("ESLint removed successfully."))}catch{e||o.stop("Failed to remove ESLint completely, but continuing...")}},Xe=async t=>{let e=t??{},o=e.quiet??!1;o||Po(be);try{let{pm:s}=e;if(!s){let d=await Ro(jo.cwd());if(!d)throw new Error("No package manager specified or detected");if(!o&&d.warnings)for(let p of d.warnings)X.warn(p);o||X.info(`Detected lockfile, using ${d.name}`),s=d.name}let n=e.migrate?.includes("prettier"),i=e.migrate?.includes("eslint");if(!o&&(n===void 0||i===void 0)){let d=[];if(n===void 0&&await ne.hasPrettier()&&d.push({label:"Remove Prettier (dependencies, config files, VS Code settings)",value:"prettier"}),i===void 0&&await se.hasEsLint()&&d.push({label:"Remove ESLint (dependencies, config files, VS Code settings)",value:"eslint"}),d.length>0){let p=await $({message:"Remove existing formatters/linters (recommended for clean migration)?",options:d,required:!1});if(F(p)){A("Operation cancelled.");return}n===void 0&&(n=p.includes("prettier")),i===void 0&&(i=p.includes("eslint"))}}o&&(n===void 0&&(n=!1),i===void 0&&(i=!1));let a=e.frameworks;if(a===void 0)if(o||e.pm||e.editors||e.agents||e.hooks||e.integrations!==void 0||e.migrate!==void 0)a=[];else{let p=await $({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(F(p)){A("Operation cancelled.");return}a=p}let c=e.editors;if(!c)if(o)c=[];else{let d=await $({message:"Which editors do you want to configure (recommended)?",options:[{label:"VSCode / Cursor / Windsurf",value:"vscode"},{label:"Zed",value:"zed"}],required:!1});if(F(d)){A("Operation cancelled.");return}c=d}let f=e.agents,g=e.hooks,N={"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"};if(!f)if(o)f=[];else{let d=await $({message:"Which agents do you want to enable (optional)?",options:Object.entries(N).map(([p,Q])=>({value:p,label:Q})),required:!1});if(F(d)){A("Operation cancelled.");return}f=d}let we={cursor:"Cursor",claude:"Claude Code"};if(!g)if(o)g=[];else{let d=await $({message:"Which agent hooks do you want to enable (optional)?",options:Object.entries(we).map(([p,Q])=>({value:p,label:Q})),required:!1});if(F(d)){A("Operation cancelled.");return}g=d}let P=e.integrations;if(P===void 0)if(o||e.pm||e.editors||e.agents||e.hooks||e.migrate!==void 0)P=[];else{let p=await $({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"}],required:!1});if(F(p)){A("Operation cancelled.");return}P=p}n&&await Io(s,o),i&&await Jo(s,o),await Eo(s,!e.skipInstall,o),await Ao(o),await No(a,o),c?.includes("vscode")&&await Fo(o),c?.includes("zed")&&await $o(o);for(let d of f??[])await Mo(d,N[d],o);for(let d of g??[])await Uo(d,we[d],o);P?.includes("husky")&&await Oo(s,!e.skipInstall,o),P?.includes("lefthook")&&await Do(s,!e.skipInstall,o),P?.includes("lint-staged")&&await To(s,!e.skipInstall,o),o||X.success("Successfully initialized Ultracite configuration!")}catch(s){let n=s instanceof Error?s.message:"Unknown error";throw o||X.error(`Failed to initialize Ultracite configuration: ${n}`),s}};var j=_o.meta().create(),Ho=j.router({init:j.procedure.meta({description:"Initialize Ultracite in the current directory"}).input(r.object({pm:r.enum(w.packageManagers).optional().describe("Package manager to use"),editors:r.array(r.enum(w.editorConfigs)).optional().describe("Editors to configure"),agents:r.array(r.enum(w.agents)).optional().describe("Agents to enable"),hooks:r.array(r.enum(w.hooks)).optional().describe("Hooks to enable"),frameworks:r.array(r.enum(w.frameworks)).optional().describe("Frameworks being used"),integrations:r.array(r.enum(w.integrations)).optional().describe("Additional integrations to enable"),migrate:r.array(r.enum(w.migrations)).optional().describe("Migration tools to remove (e.g., eslint, prettier). Removes dependencies, config files, and editor settings."),skipInstall:r.boolean().default(!1).describe("Skip installing dependencies"),quiet:r.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 Xe(t)}),check:j.procedure.meta({description:"Run Biome linter without fixing files"}).input(r.tuple([r.array(r.string()).optional().default([]).describe("specific files to lint"),r.object({"diagnostic-level":r.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(({input:t})=>{oe(t)}),fix:j.procedure.meta({description:"Run Biome linter and fixes files"}).input(r.tuple([r.array(r.string()).optional().default([]).describe("specific files to format"),r.object({unsafe:r.boolean().optional().describe("apply unsafe fixes")})])).mutation(({input:t})=>{let[e,o]=t;ie(e,{unsafe:o.unsafe})}),doctor:j.procedure.meta({description:"Verify your Ultracite setup and check for issues"}).query(async()=>{await Ee()}),lint:j.procedure.meta({description:"\u26A0\uFE0F DEPRECATED: Use 'check' instead - Run Biome linter without fixing files"}).input(r.array(r.string()).optional().default([]).describe("specific files to lint")).query(({input:t})=>{console.warn("\u26A0\uFE0F Warning: 'lint' command is deprecated. Please use 'check' instead."),oe([t,{}])}),format:j.procedure.meta({description:"\u26A0\uFE0F DEPRECATED: Use 'fix' instead - Run Biome linter and fixes files"}).input(r.tuple([r.array(r.string()).optional().default([]).describe("specific files to format"),r.object({unsafe:r.boolean().optional().describe("apply unsafe fixes")})])).mutation(({input:t})=>{let[e,o]=t;console.warn("\u26A0\uFE0F Warning: 'format' command is deprecated. Please use 'fix' instead."),ie(e,{unsafe:o.unsafe})})}),Wo=Lo({router:Ho,name:k.name,version:k.version,description:k.description});process.env.TEST||Wo.run();export{Ho 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.3.7",
4
+ "version": "6.3.9",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "ultracite": "dist/index.js"
@@ -41,20 +41,20 @@
41
41
  "url": "git+https://github.com/haydenbleasel/ultracite.git"
42
42
  },
43
43
  "devDependencies": {
44
- "@biomejs/biome": "2.3.7",
44
+ "@biomejs/biome": "2.3.8",
45
45
  "@types/node": "^24.10.1",
46
46
  "tsup": "^8.5.1",
47
- "turbo": "^2.6.1"
47
+ "turbo": "^2.6.2"
48
48
  },
49
49
  "dependencies": {
50
50
  "@clack/prompts": "^0.11.0",
51
- "@trpc/server": "^11.7.1",
51
+ "@trpc/server": "^11.7.2",
52
52
  "deepmerge": "^4.3.1",
53
- "glob": "^12.0.0",
53
+ "glob": "^13.0.0",
54
54
  "jsonc-parser": "^3.3.1",
55
55
  "nypm": "^0.6.2",
56
- "trpc-cli": "^0.12.0",
57
- "zod": "^4.1.12"
56
+ "trpc-cli": "^0.12.1",
57
+ "zod": "^4.1.13"
58
58
  },
59
- "packageManager": "bun@1.3.2"
59
+ "packageManager": "bun@1.3.3"
60
60
  }