ultracite 7.9.0 → 7.9.1

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.
@@ -1,9 +1,9 @@
1
1
  import typescript from "@typescript-eslint/eslint-plugin";
2
2
  // biome-ignore lint/performance/noNamespaceImport: Required for ESLint parser compatibility
3
- import * as typescriptParser from "@typescript-eslint/parser";
3
+ import * as typescriptParser from "@typescript-eslint/parser"; // oxlint-disable-line sonarjs/no-wildcard-import -- required for ESLint parser compatibility
4
4
  import eslintPrettier from "eslint-config-prettier";
5
5
  // biome-ignore lint/performance/noNamespaceImport: Required for ESLint plugin compatibility
6
- import * as importTypescriptResolver from "eslint-import-resolver-typescript";
6
+ import * as importTypescriptResolver from "eslint-import-resolver-typescript"; // oxlint-disable-line sonarjs/no-wildcard-import -- required for ESLint resolver compatibility
7
7
  import compat from "eslint-plugin-compat";
8
8
  import cypress from "eslint-plugin-cypress";
9
9
  import github from "eslint-plugin-github";
@@ -152,6 +152,17 @@ const config = [
152
152
  "html/javascript-tag-names": ["script", "Script"],
153
153
  },
154
154
  },
155
+ {
156
+ // Repeated string literals (test titles, expected values) are normal and
157
+ // idiomatic in test files. Mirrors the oxlint core test override.
158
+ files: [
159
+ "**/*.{test,spec}.{ts,tsx,js,jsx}",
160
+ "**/__tests__/**/*.{ts,tsx,js,jsx}",
161
+ ],
162
+ rules: {
163
+ "sonarjs/no-duplicate-string": "off",
164
+ },
165
+ },
155
166
  ];
156
167
 
157
168
  export default config;
@@ -10,11 +10,14 @@ const baseRules = Object.fromEntries(
10
10
  availableKeys.map((key) => [`github/${key}`, "error"])
11
11
  );
12
12
 
13
- // Overrides mirror the oxlint github preset (config/oxlint/github), which
14
- // is the benchmark for rule decisions across linters.
13
+ // Overrides mirror the oxlint core preset (config/oxlint/core), which is the
14
+ // benchmark for rule decisions across linters.
15
15
  const overrideRules = {
16
16
  // Conflicts with unicorn/prefer-dom-node-dataset, which is the benchmark.
17
17
  "github/no-dataset": "off",
18
+ // oxlint's JS plugin bridge misreads module-scoped declarations (e.g. Astro
19
+ // frontmatter) as implicit globals. Off in both linters to keep parity.
20
+ "github/no-implicit-buggy-globals": "off",
18
21
  "github/unescaped-html-literal": "off",
19
22
  };
20
23
 
@@ -10,8 +10,8 @@ const baseRules = Object.fromEntries(
10
10
  availableKeys.map((key) => [`sonarjs/${key}`, "error"])
11
11
  );
12
12
 
13
- // Overrides mirror the oxlint sonarjs preset (config/oxlint/sonarjs), which
14
- // is the benchmark for rule decisions across linters.
13
+ // Overrides mirror the oxlint core preset (config/oxlint/core), which is the
14
+ // benchmark for rule decisions across linters.
15
15
  const overrideRules = {
16
16
  // Fights the formatter (arrowParentheses: always).
17
17
  "sonarjs/arrow-function-convention": "off",
@@ -22,11 +22,18 @@ const overrideRules = {
22
22
  "sonarjs/elseif-without-else": "off",
23
23
  // Requires a headerFormat option; errors on every file without one.
24
24
  "sonarjs/file-header": "off",
25
+ // Fires on any file whose name differs from an exported class, which is
26
+ // noise for config and module files that export objects, not classes.
27
+ "sonarjs/file-name-differ-from-class": "off",
25
28
  // The preset disables max-lines everywhere.
26
29
  "sonarjs/max-lines": "off",
27
30
  "sonarjs/max-lines-per-function": "off",
28
31
  // Duplicate of max-depth, which is off.
29
32
  "sonarjs/nested-control-flow": "off",
33
+ // No dependency-manifest resolution in oxlint's JS plugin bridge, so this
34
+ // flags builtin (bun:test) and workspace imports as missing dependencies.
35
+ // Off in both linters to keep parity.
36
+ "sonarjs/no-implicit-dependencies": "off",
30
37
  // Conflicts with sort-keys.
31
38
  "sonarjs/shorthand-property-grouping": "off",
32
39
  };
@@ -17,10 +17,20 @@ export default defineConfig({
17
17
  ],
18
18
  rules: {
19
19
  "no-empty-function": "off",
20
+ // Repeated string literals (test titles, expected values) are normal
21
+ // and idiomatic in test files.
22
+ "sonarjs/no-duplicate-string": "off",
20
23
  "promise/prefer-await-to-then": "off",
21
24
  },
22
25
  },
23
26
  ],
27
+ // eslint-plugin-github and eslint-plugin-sonarjs run through oxlint's JS
28
+ // plugin support to close the gap with the ESLint preset. Rules that require
29
+ // type information are not supported by the JS plugin bridge and are excluded.
30
+ jsPlugins: [
31
+ { name: "github", specifier: "eslint-plugin-github" },
32
+ { name: "sonarjs", specifier: "eslint-plugin-sonarjs" },
33
+ ],
24
34
  plugins: [
25
35
  "eslint",
26
36
  "typescript",
@@ -223,6 +233,36 @@ export default defineConfig({
223
233
  "vars-on-top": "error",
224
234
  yoda: "error",
225
235
 
236
+ // ── github ─────────────────────────────────────────────────────────
237
+ "github/a11y-aria-label-is-well-formatted": "error",
238
+ "github/a11y-no-title-attribute": "error",
239
+ "github/a11y-no-visually-hidden-interactive-element": "error",
240
+ "github/a11y-role-supports-aria-props": "error",
241
+ "github/a11y-svg-has-accessible-name": "error",
242
+ "github/array-foreach": "error",
243
+ "github/async-currenttarget": "error",
244
+ "github/async-preventdefault": "error",
245
+ "github/authenticity-token": "error",
246
+ "github/filenames-match-regex": "error",
247
+ "github/get-attribute": "error",
248
+ "github/js-class-name": "error",
249
+ "github/no-blur": "error",
250
+ "github/no-d-none": "error",
251
+ // Conflicts with unicorn/prefer-dom-node-dataset, which is the benchmark.
252
+ "github/no-dataset": "off",
253
+ "github/no-dynamic-script-tag": "error",
254
+ // The JS plugin bridge misreads module-scoped declarations (e.g. Astro
255
+ // frontmatter) as implicit globals, producing false positives.
256
+ "github/no-implicit-buggy-globals": "off",
257
+ "github/no-inner-html": "error",
258
+ "github/no-innerText": "error",
259
+ "github/no-then": "error",
260
+ "github/no-useless-passive": "error",
261
+ "github/prefer-observers": "error",
262
+ "github/require-passive-events": "error",
263
+ // Mirrors the ESLint preset.
264
+ "github/unescaped-html-literal": "off",
265
+
226
266
  // ── import ─────────────────────────────────────────────────────────
227
267
  "import/consistent-type-specifier-style": ["error", "prefer-top-level"],
228
268
  "import/default": "error",
@@ -336,6 +376,207 @@ export default defineConfig({
336
376
  "promise/spec-only": "error",
337
377
  "promise/valid-params": "error",
338
378
 
379
+ // ── sonarjs ────────────────────────────────────────────────────────
380
+ // These sonarjs rules exist in eslint-plugin-sonarjs but oxlint's JS
381
+ // plugin bridge does not register them, so listing them fails config
382
+ // parsing. They are intentionally omitted here (still enabled in the
383
+ // ESLint preset): async-test-assertions, hooks-before-test-cases,
384
+ // no-duplicate-test-title, no-empty-test-title, no-floating-point-equality,
385
+ // no-forced-browser-interaction, no-trivial-assertions,
386
+ // prefer-specific-assertions, super-linear-regex.
387
+ "sonarjs/arguments-usage": "error",
388
+ "sonarjs/array-constructor": "error",
389
+ // Fights the formatter (arrowParentheses: always).
390
+ "sonarjs/arrow-function-convention": "off",
391
+ "sonarjs/aws-apigateway-public-api": "error",
392
+ "sonarjs/aws-ec2-rds-dms-public": "error",
393
+ "sonarjs/aws-ec2-unencrypted-ebs-volume": "error",
394
+ "sonarjs/aws-efs-unencrypted": "error",
395
+ "sonarjs/aws-iam-all-privileges": "error",
396
+ "sonarjs/aws-iam-all-resources-accessible": "error",
397
+ "sonarjs/aws-iam-privilege-escalation": "error",
398
+ "sonarjs/aws-iam-public-access": "error",
399
+ "sonarjs/aws-opensearchservice-domain": "error",
400
+ "sonarjs/aws-rds-unencrypted-databases": "error",
401
+ "sonarjs/aws-restricted-ip-admin-access": "error",
402
+ "sonarjs/aws-s3-bucket-granted-access": "error",
403
+ "sonarjs/aws-s3-bucket-insecure-http": "error",
404
+ "sonarjs/aws-s3-bucket-public-access": "error",
405
+ "sonarjs/aws-s3-bucket-versioning": "error",
406
+ "sonarjs/aws-sagemaker-unencrypted-notebook": "error",
407
+ "sonarjs/aws-sns-unencrypted-topics": "error",
408
+ "sonarjs/aws-sqs-unencrypted-queue": "error",
409
+ "sonarjs/block-scoped-var": "error",
410
+ "sonarjs/bool-param-default": "error",
411
+ "sonarjs/call-argument-line": "error",
412
+ "sonarjs/chai-determinate-assertion": "error",
413
+ "sonarjs/class-name": "error",
414
+ "sonarjs/code-eval": "error",
415
+ // Matches Biome's noExcessiveCognitiveComplexity limit.
416
+ "sonarjs/cognitive-complexity": ["error", 20],
417
+ "sonarjs/comma-or-logical-or-case": "error",
418
+ "sonarjs/comment-regex": "error",
419
+ "sonarjs/constructor-for-side-effects": "error",
420
+ "sonarjs/content-length": "error",
421
+ "sonarjs/content-security-policy": "error",
422
+ "sonarjs/cookie-no-httponly": "error",
423
+ "sonarjs/cors": "error",
424
+ "sonarjs/csrf": "error",
425
+ // Duplicate of the core complexity rule.
426
+ "sonarjs/cyclomatic-complexity": "off",
427
+ "sonarjs/declarations-in-global-scope": "error",
428
+ "sonarjs/destructuring-assignment-syntax": "error",
429
+ "sonarjs/disabled-timeout": "error",
430
+ "sonarjs/dynamically-constructed-templates": "error",
431
+ // Mirrors the ESLint preset.
432
+ "sonarjs/elseif-without-else": "off",
433
+ "sonarjs/encryption-secure-mode": "error",
434
+ "sonarjs/expression-complexity": "error",
435
+ // Requires a headerFormat option; errors on every file without one.
436
+ "sonarjs/file-header": "off",
437
+ // Fires on any file whose name differs from an exported class, which is
438
+ // noise for config and module files that export objects, not classes.
439
+ "sonarjs/file-name-differ-from-class": "off",
440
+ "sonarjs/file-permissions": "error",
441
+ "sonarjs/file-uploads": "error",
442
+ "sonarjs/fixme-tag": "error",
443
+ "sonarjs/for-in": "error",
444
+ "sonarjs/for-loop-increment-sign": "error",
445
+ "sonarjs/function-inside-loop": "error",
446
+ "sonarjs/function-name": "error",
447
+ "sonarjs/future-reserved-words": "error",
448
+ "sonarjs/generator-without-yield": "error",
449
+ "sonarjs/hardcoded-secret-signatures": "error",
450
+ "sonarjs/hashing": "error",
451
+ "sonarjs/inconsistent-function-call": "error",
452
+ "sonarjs/insecure-cookie": "error",
453
+ "sonarjs/insecure-jwt-token": "error",
454
+ "sonarjs/inverted-assertion-arguments": "error",
455
+ "sonarjs/label-position": "error",
456
+ "sonarjs/link-with-target-blank": "error",
457
+ // The preset disables max-lines everywhere.
458
+ "sonarjs/max-lines": "off",
459
+ // The preset disables max-lines-per-function everywhere.
460
+ "sonarjs/max-lines-per-function": "off",
461
+ "sonarjs/max-switch-cases": "error",
462
+ "sonarjs/max-union-size": "error",
463
+ "sonarjs/misplaced-loop-counter": "error",
464
+ // Duplicate of max-depth, which is off.
465
+ "sonarjs/nested-control-flow": "off",
466
+ "sonarjs/no-all-duplicated-branches": "error",
467
+ "sonarjs/no-angular-bypass-sanitization": "error",
468
+ "sonarjs/no-built-in-override": "error",
469
+ "sonarjs/no-case-label-in-switch": "error",
470
+ "sonarjs/no-clear-text-protocols": "error",
471
+ "sonarjs/no-code-after-done": "error",
472
+ "sonarjs/no-collapsible-if": "error",
473
+ "sonarjs/no-commented-code": "error",
474
+ "sonarjs/no-dead-store": "error",
475
+ "sonarjs/no-delete-var": "error",
476
+ "sonarjs/no-duplicate-in-composite": "error",
477
+ "sonarjs/no-duplicate-string": "error",
478
+ "sonarjs/no-duplicated-branches": "error",
479
+ "sonarjs/no-element-overwrite": "error",
480
+ "sonarjs/no-empty-collection": "error",
481
+ "sonarjs/no-empty-test-file": "error",
482
+ "sonarjs/no-equals-in-for-termination": "error",
483
+ "sonarjs/no-exclusive-tests": "error",
484
+ "sonarjs/no-extra-arguments": "error",
485
+ "sonarjs/no-fallthrough": "error",
486
+ "sonarjs/no-function-declaration-in-block": "error",
487
+ "sonarjs/no-global-this": "error",
488
+ "sonarjs/no-globals-shadowing": "error",
489
+ "sonarjs/no-gratuitous-expressions": "error",
490
+ "sonarjs/no-hardcoded-ip": "error",
491
+ "sonarjs/no-hardcoded-passwords": "error",
492
+ "sonarjs/no-hardcoded-secrets": "error",
493
+ "sonarjs/no-hook-setter-in-body": "error",
494
+ "sonarjs/no-identical-conditions": "error",
495
+ "sonarjs/no-identical-expressions": "error",
496
+ "sonarjs/no-identical-functions": "error",
497
+ "sonarjs/no-ignored-exceptions": "error",
498
+ // The JS plugin bridge has no dependency-manifest resolution, so this
499
+ // flags builtin (bun:test) and workspace imports as missing dependencies.
500
+ "sonarjs/no-implicit-dependencies": "off",
501
+ "sonarjs/no-implicit-global": "error",
502
+ "sonarjs/no-incomplete-assertions": "error",
503
+ "sonarjs/no-internal-api-use": "error",
504
+ "sonarjs/no-invariant-returns": "error",
505
+ "sonarjs/no-inverted-boolean-check": "error",
506
+ "sonarjs/no-labels": "error",
507
+ "sonarjs/no-literal-call": "error",
508
+ "sonarjs/no-mime-sniff": "error",
509
+ "sonarjs/no-nested-assignment": "error",
510
+ "sonarjs/no-nested-conditional": "error",
511
+ "sonarjs/no-nested-functions": "error",
512
+ "sonarjs/no-nested-incdec": "error",
513
+ "sonarjs/no-nested-switch": "error",
514
+ "sonarjs/no-nested-template-literals": "error",
515
+ "sonarjs/no-os-command-from-path": "error",
516
+ "sonarjs/no-parameter-reassignment": "error",
517
+ "sonarjs/no-primitive-wrappers": "error",
518
+ "sonarjs/no-redundant-assignments": "error",
519
+ "sonarjs/no-redundant-boolean": "error",
520
+ "sonarjs/no-redundant-jump": "error",
521
+ // The jsPlugins bridge provides no globals, so every identifier is flagged.
522
+ "sonarjs/no-reference-error": "off",
523
+ "sonarjs/no-referrer-policy": "error",
524
+ "sonarjs/no-same-argument-assert": "error",
525
+ "sonarjs/no-same-line-conditional": "error",
526
+ "sonarjs/no-session-cookies-on-static-assets": "error",
527
+ "sonarjs/no-skipped-tests": "error",
528
+ "sonarjs/no-sonar-comments": "error",
529
+ "sonarjs/no-table-as-layout": "error",
530
+ "sonarjs/no-undefined-assignment": "error",
531
+ "sonarjs/no-unenclosed-multiline-block": "error",
532
+ "sonarjs/no-uniq-key": "error",
533
+ "sonarjs/no-unthrown-error": "error",
534
+ "sonarjs/no-unused-collection": "error",
535
+ "sonarjs/no-unused-function-argument": "error",
536
+ "sonarjs/no-unused-vars": "error",
537
+ "sonarjs/no-use-of-empty-return-value": "error",
538
+ "sonarjs/no-useless-catch": "error",
539
+ "sonarjs/no-useless-increment": "error",
540
+ "sonarjs/no-useless-react-setstate": "error",
541
+ "sonarjs/no-variable-usage-before-declaration": "error",
542
+ "sonarjs/no-weak-cipher": "error",
543
+ "sonarjs/no-weak-keys": "error",
544
+ "sonarjs/no-wildcard-import": "error",
545
+ "sonarjs/non-existent-operator": "error",
546
+ "sonarjs/object-alt-content": "error",
547
+ "sonarjs/prefer-default-last": "error",
548
+ "sonarjs/prefer-object-literal": "error",
549
+ "sonarjs/prefer-promise-shorthand": "error",
550
+ "sonarjs/prefer-single-boolean-return": "error",
551
+ "sonarjs/prefer-type-guard": "error",
552
+ "sonarjs/prefer-while": "error",
553
+ "sonarjs/production-debug": "error",
554
+ "sonarjs/pseudo-random": "error",
555
+ "sonarjs/public-static-readonly": "error",
556
+ "sonarjs/publicly-writable-directories": "error",
557
+ "sonarjs/redundant-type-aliases": "error",
558
+ "sonarjs/review-blockchain-mnemonic": "error",
559
+ "sonarjs/session-regeneration": "error",
560
+ // Conflicts with sort-keys.
561
+ "sonarjs/shorthand-property-grouping": "off",
562
+ "sonarjs/stable-tests": "error",
563
+ "sonarjs/stateful-regex": "error",
564
+ "sonarjs/strict-transport-security": "error",
565
+ "sonarjs/table-header": "error",
566
+ "sonarjs/table-header-reference": "error",
567
+ "sonarjs/test-check-exception": "error",
568
+ "sonarjs/todo-tag": "error",
569
+ "sonarjs/too-many-break-or-continue-in-loop": "error",
570
+ "sonarjs/unverified-certificate": "error",
571
+ "sonarjs/unverified-hostname": "error",
572
+ "sonarjs/updated-const-var": "error",
573
+ "sonarjs/updated-loop-counter": "error",
574
+ "sonarjs/use-type-alias": "error",
575
+ "sonarjs/variable-name": "error",
576
+ "sonarjs/weak-ssl": "error",
577
+ "sonarjs/x-powered-by": "error",
578
+ "sonarjs/xml-parser-xxe": "error",
579
+
339
580
  // ── typescript ─────────────────────────────────────────────────────
340
581
  "typescript/adjacent-overload-signatures": "error",
341
582
  "typescript/array-type": "error",
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import{createRequire as Ub}from"node:module";var Qb=Ub(import.meta.url);import T0 from"node:process";import{Command as rG}from"commander";var W={name:"ultracite",version:"7.9.0",description:"The AI-ready formatter that helps you write and generate code faster.",keywords:["biome","fixer","formatter","linter","ultracite"],homepage:"https://www.ultracite.ai/",bugs:{url:"https://github.com/haydenbleasel/ultracite/issues"},license:"MIT",author:"Hayden Bleasel <hello@haydenbleasel.com>",repository:{type:"git",url:"git+https://github.com/haydenbleasel/ultracite.git"},bin:{ultracite:"dist/index.js"},files:["config","dist","README.md"],type:"module",exports:{"./biome/*":"./config/biome/*/biome.jsonc","./eslint/*":"./config/eslint/*/eslint.config.mjs","./oxlint/*":{types:"./config/oxlint/*/index.d.mts",default:"./config/oxlint/*/index.mjs"},"./oxfmt":{types:"./config/oxfmt/index.d.mts",default:"./config/oxfmt/index.mjs"},"./prettier":"./config/prettier/prettier.config.mjs","./stylelint":"./config/stylelint/stylelint.config.mjs"},publishConfig:{access:"public",registry:"https://registry.npmjs.org/"},scripts:{prebuild:"bun run scripts/generate-dts.ts",build:"tsgo --noEmit && bun run build.ts",test:"bun test","test:coverage":"bun test --coverage",bench:"bun run benchmarks/cli.bench.ts",types:"tsgo --noEmit"},dependencies:{"@clack/prompts":"^1.5.1","@typescript-eslint/utils":"^8.62.1",commander:"^15.0.0","cross-spawn":"^7.0.6",deepmerge:"^4.3.1",glob:"^13.0.6","jsonc-parser":"^3.3.1",nypm:"^0.6.6",yaml:"^2.9.0",zod:"^4.4.3"},devDependencies:{"@angular-eslint/eslint-plugin":"^22.0.0","@biomejs/biome":"2.5.2","@darraghor/eslint-plugin-nestjs-typed":"^7.2.5","@eslint/js":"^10.0.0","@next/eslint-plugin-next":"^16.2.10","@tanstack/eslint-plugin-query":"^5.101.2","@tanstack/eslint-plugin-router":"^1.162.0","@tanstack/eslint-plugin-start":"^0.1.0","@types/bun":"^1.3.14","@types/cross-spawn":"^6.0.6","@types/node":"^25.9.2","@typescript-eslint/eslint-plugin":"^8.62.1","@typescript-eslint/parser":"^8.62.1","@vitest/eslint-plugin":"^1.6.21",eslint:"^10.0.0","eslint-config-prettier":"^10.1.8","eslint-import-resolver-typescript":"^4.4.5","eslint-plugin-astro":"^2.1.1","eslint-plugin-compat":"^7.0.2","eslint-plugin-cypress":"^6.4.2","eslint-plugin-github":"6.0.0","eslint-plugin-html":"^8.1.4","eslint-plugin-import-x":"^4.17.1","eslint-plugin-jest":"^29.15.4","eslint-plugin-jsdoc":"^63.0.11","eslint-plugin-jsx-a11y":"^6.10.2","eslint-plugin-n":"^18.2.1","eslint-plugin-prettier":"^5.5.6","eslint-plugin-promise":"^7.3.0","eslint-plugin-qwik":"^1.20.0","eslint-plugin-react":"^7.37.5","eslint-plugin-react-doctor":"^0.7.1","eslint-plugin-react-hooks":"^7.1.1","eslint-plugin-remix":"^1.1.1","eslint-plugin-solid":"^0.14.5","eslint-plugin-sonarjs":"^4.1.0","eslint-plugin-storybook":"^10.4.6","eslint-plugin-svelte":"^3.20.0","eslint-plugin-unicorn":"^70.0.0","eslint-plugin-unused-imports":"^4.4.1","eslint-plugin-vue":"^10.9.2",globals:"^17.7.0",oxlint:"^1.68.0","oxlint-plugin-react-doctor":"^0.7.1","prettier-plugin-astro":"^0.14.1","prettier-plugin-svelte":"^4.1.0","prettier-plugin-tailwindcss":"^0.8.0","stylelint-config-idiomatic-order":"^10.0.0","stylelint-config-standard":"^40.0.0","stylelint-prettier":"^5.0.3"},peerDependencies:{oxfmt:">=0.1.0",oxlint:"^1.0.0"},peerDependenciesMeta:{oxfmt:{optional:!0},oxlint:{optional:!0}},packageManager:"bun@1.3.14"};import{existsSync as Zb}from"node:fs";import zb from"node:path";var Xb=(b,y,G)=>{let H=G?.indexOf(b)??-1;if(!G||H===-1)return y;return G.slice(H+1)},K0=(b)=>b.map((y)=>y.startsWith("-")?`./${y}`:y),x0="**/*.{css,scss,sass,less}",Tb=[".css",".scss",".sass",".less"],ob=(b)=>{let y=b.toLowerCase();return Tb.some((G)=>y.endsWith(G))},V0=(b)=>{if(b.length===0)return[x0];let y=[];for(let G of b){if(ob(G)){y.push(G);continue}if(zb.extname(G)===""){let H=G.replace(/\/+$/u,"");y.push(H==="."||H===""?x0:`${H}/${x0}`)}}return y},F0=({commandName:b,parsedArgs:y,pathExists:G=Zb,rawArgs:H})=>{let A=Xb(b,y,H),$=A.indexOf("--");if($!==-1)return{files:A.slice($+1),passthrough:A.slice(0,$)};let v=[],U=[];for(let X of A){if(X.startsWith("-")&&!G(X)){U.push(X);continue}v.push(X)}return{files:v,passthrough:U}};import{sync as Kb}from"cross-spawn";class q extends Error{commandName;exitCode;name="LinterExitError";constructor(b,y){super(`${b} exited with code ${y}`);this.commandName=b,this.exitCode=y}}var V=(b,y,G)=>Kb(b,y,{...G,shell:!1}),_=(b,y)=>{if(y.error)throw Error(`Failed to run ${b}: ${y.error.message}`);if(y.status===null)throw Error(`${b} was killed by signal ${y.signal??"unknown"}`);if(y.status!==0)throw new q(b,y.status)},C=(b)=>{let y=null;for(let G of b)try{G()}catch(H){if(H instanceof q){y??=H;continue}throw H}if(y)throw new q(y.commandName,y.exitCode)};import{accessSync as Eb,lstatSync as e0,mkdirSync as _b,realpathSync as b1}from"node:fs";import{readFile as Db,writeFile as Ob}from"node:fs/promises";import D from"node:path";import M0 from"node:process";import{glob as Rb}from"glob";import jb from"yaml";import{readFileSync as Vb}from"node:fs";import{readFile as Bb}from"node:fs/promises";import{parse as t0}from"jsonc-parser";import{z as T}from"zod";var Yb=T.looseObject({dependencies:T.record(T.string(),T.string()).optional(),devDependencies:T.record(T.string(),T.string()).optional(),"lint-staged":T.unknown().optional(),name:T.string().optional(),peerDependencies:T.record(T.string(),T.string()).optional(),prettier:T.unknown().optional(),scripts:T.record(T.string(),T.string()).optional(),stylelint:T.unknown().optional(),type:T.string().optional(),version:T.string().optional(),workspace:T.unknown().optional(),workspaces:T.union([T.array(T.string()),T.record(T.string(),T.unknown())]).optional()}),f=(b)=>{let y=t0(b),G=Yb.safeParse(y);return G.success?G.data:void 0},x=(b="package.json")=>{try{let y=Vb(b,"utf-8");return f(y)}catch{return}},l=async(b="package.json")=>{try{let y=await Bb(b,"utf-8");return f(y)}catch{return}},g0=T.looseObject({extends:T.array(T.string()).optional()}),a0=T.looseObject({compilerOptions:T.looseObject({strict:T.boolean().optional(),strictNullChecks:T.boolean().optional()}).optional()}),B0=(b,y)=>{let G=t0(b),H=y.safeParse(G);return H.success?H.data:void 0};var z=(b)=>{try{return Eb(b),!0}catch{return!1}},F=()=>{if(z("pnpm-workspace.yaml"))return!0;let b=x();if(!b)return!1;return!!b.workspaces||!!b.workspace},j=(b)=>{let y=D.dirname(b);if(y!=="."){let G=y.startsWith("./")?y.slice(2):y;_b(G,{recursive:!0})}},m0=(b,y)=>{let G=D.relative(y,b);return G===""||!G.startsWith("..")&&!D.isAbsolute(G)},h0=(b)=>typeof b1==="function"?b1(b):D.resolve(b),Nb=(b)=>{let y=b;while(!0)try{return h0(y)}catch(G){if(G.code!=="ENOENT")throw G;let H=D.dirname(y);if(H===y)return D.resolve(y);y=H}},Sb=(b)=>{let y=h0(M0.cwd()),G=D.resolve(M0.cwd(),b);if(!m0(G,y))throw Error(`Refusing to write outside project: ${b}`);let H=D.dirname(G),A=Nb(H);if(!m0(A,y))throw Error(`Refusing to write through directory outside project: ${b}`);try{if((typeof e0==="function"?e0(G):void 0)?.isSymbolicLink())throw Error(`Refusing to write through symbolic link: ${b}`);let v=h0(G);if(!m0(v,y))throw Error(`Refusing to write outside project: ${b}`)}catch($){if($.code==="ENOENT")return;throw $}},Q=async(b,y)=>{Sb(b),j(b),await Ob(b,y)},R=async({dependencies:b,devDependencies:y,scripts:G,type:H})=>{let A=await l();if(!A)throw Error("Failed to parse package.json: file is missing or invalid");let $={...A};if(H)$.type=H;if(A.devDependencies||y)$.devDependencies={...A.devDependencies,...y};if(A.dependencies||b)$.dependencies={...A.dependencies,...b};if(A.scripts||G)$.scripts={...A.scripts,...G};await Q("package.json",`${JSON.stringify($,null,2)}
3
- `)},y1=/^[a-z][a-z0-9-]*$/u,N=(b)=>{if(!y1.test(b))throw Error(`Invalid framework name "${b}": must match ${y1}`);return b},m=["biome.json","biome.jsonc",".biome.json",".biome.jsonc"],p=["eslint.config.mjs","eslint.config.js","eslint.config.cjs","eslint.config.ts","eslint.config.mts","eslint.config.cts"],H1=[".eslintrc",".eslintrc.json",".eslintrc.js",".eslintrc.cjs",".eslintrc.yaml",".eslintrc.yml"],r=[".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"],k=[".stylelintrc.mjs","stylelint.config.mjs",".stylelintrc.cjs","stylelint.config.cjs",".stylelintrc.js","stylelint.config.js",".stylelintrc",".stylelintrc.json",".stylelintrc.yml",".stylelintrc.yaml"],p0=[".oxlintrc.json","oxlint.config.ts"],A1=["oxfmt.config.ts"],Lb={"@angular/core":["angular"],"@builder.io/qwik":["qwik"],"@nestjs/core":["nestjs"],"@qwik.dev/core":["qwik"],"@remix-run/node":["remix"],"@remix-run/react":["react","remix"],"@tanstack/react-query":["react","tanstack"],"@tanstack/react-router":["react","tanstack"],"@tanstack/react-start":["react","tanstack"],astro:["astro"],jest:["jest"],next:["react","next"],nuxt:["vue"],react:["react"],"react-router":["react","remix"],"solid-js":["solid"],svelte:["svelte"],vitest:["vitest"],vue:["vue"]},G1=(b)=>{if(!b)return[];return[...Object.keys(b.dependencies??{}),...Object.keys(b.devDependencies??{}),...Object.keys(b.peerDependencies??{})]},wb=async(b)=>{let y=new Set,G=b?.workspaces;if(Array.isArray(G))for(let H of G)y.add(H);else if(G&&typeof G==="object"){let{packages:H}=G;if(Array.isArray(H)){for(let A of H)if(typeof A==="string")y.add(A)}}if(z("pnpm-workspace.yaml"))try{let H=await Db("pnpm-workspace.yaml","utf-8"),A=jb.parse(H);if(Array.isArray(A?.packages)){for(let $ of A.packages)if(typeof $==="string")y.add($)}}catch{}return[...y]},$1=async()=>{let b=new Set;try{let y=await l(),G=new Set(G1(y)),H=await wb(y);if(H.length>0){let A=await Rb(H.map((v)=>`${v.replace(/\/+$/u,"")}/package.json`),{absolute:!1,ignore:["**/node_modules/**"]}),$=await Promise.all(A.map((v)=>l(v)));for(let v of $)for(let U of G1(v))G.add(U)}for(let A of G){let $=Lb[A];if($)for(let v of $)b.add(v)}}catch{}return[...b]},n=(b=M0.cwd())=>{let y=b;while(!0){for(let H of m)if(z(D.join(y,H)))return"biome";for(let H of p)if(z(D.join(y,H)))return"eslint";for(let H of p0)if(z(D.join(y,H)))return"oxlint";let G=D.dirname(y);if(G===y)break;y=G}return null};var Ib=(b,y)=>{let G=["check","--no-errors-on-unmatched",...y];if(b.length>0)G.push(...b);else G.push("./");let H=V("biome",G,{stdio:"inherit"});_("Biome",H)},ub=(b,y)=>{let G=[...y,...b.length>0?b:["."]],H=V("eslint",G,{stdio:"inherit"});_("ESLint",H)},Jb=(b,y)=>{let G=["--check",...y,...b.length>0?b:["."]],H=V("prettier",G,{stdio:"inherit"});_("Prettier",H)},db=(b,y)=>{let G=V0(b);if(G.length===0)return;let H=[...y,"--allow-empty-input",...G],A=V("stylelint",H,{stdio:"inherit"});_("Stylelint",A)},xb=(b,y)=>{let G=[...y,...b.length>0?b:["."]],H=V("oxlint",G,{stdio:"inherit"});_("Oxlint",H)},Fb=(b,y)=>{let G=["--check",...y,...b.length>0?b:["."]],H=V("oxfmt",G,{stdio:"inherit"});_("oxfmt",H)},v1=(b=[],y=[])=>{let G=n(),H=K0(b);if(!G)throw Error("No linter configuration found. Run `ultracite init` to set up a linter.");switch(G){case"eslint":{C([()=>Jb(H,[]),()=>ub(H,y),()=>db(H,[])]);break}case"oxlint":{C([()=>Fb(H,[]),()=>xb(H,y)]);break}default:Ib(H,y)}};import{existsSync as w,readFileSync as E0}from"node:fs";import I from"node:path";import u from"node:process";import{intro as mb,log as L,outro as Y0,spinner as Mb}from"@clack/prompts";import{parse as hb}from"jsonc-parser";var s=(b,y)=>{let G=V(b,["--version"],{encoding:"utf-8"});if(G.status===0&&G.stdout)return{message:`${b} is installed (${String(G.stdout).trim()})`,name:`${b} installation`,status:"pass"};return{message:`${b} is not installed${y?"":" (optional)"}`,name:`${b} installation`,status:y?"fail":"warn"}},pb=()=>{let b=null,y=null;for(let G of m){let H=I.join(u.cwd(),G);if(w(H)){b=H,y=G;break}}if(!b)return{message:`No Biome config file found (expected one of: ${m.join(", ")})`,name:"Biome configuration",status:"fail"};try{let G=E0(b,"utf-8"),H=hb(G);if(Array.isArray(H?.extends)&&H.extends.includes("ultracite/biome/core"))return{message:`${y} extends ultracite/biome/core`,name:"Biome configuration",status:"pass"};return{message:`${y} exists but doesn't extend ultracite/biome/core`,name:"Biome configuration",status:"warn"}}catch{return{message:`Could not parse ${y} file`,name:"Biome configuration",status:"fail"}}},cb=()=>{let b=null;for(let y of p){let G=I.join(u.cwd(),y);if(w(G)){b=G;break}}if(!b)return{message:"No eslint.config.* file found",name:"ESLint configuration",status:"fail"};try{if(E0(b,"utf-8").includes("ultracite/eslint"))return{message:"eslint.config.* imports ultracite/eslint",name:"ESLint configuration",status:"pass"};return{message:"eslint.config.* exists but doesn't import ultracite/eslint",name:"ESLint configuration",status:"warn"}}catch{return{message:"Could not read eslint.config.* file",name:"ESLint configuration",status:"fail"}}},Pb=()=>{for(let b of r)if(w(I.join(u.cwd(),b)))return{message:`Prettier configuration found (${b})`,name:"Prettier configuration",status:"pass"};return{message:"No Prettier configuration found",name:"Prettier configuration",status:"fail"}},qb=()=>{for(let b of k)if(w(I.join(u.cwd(),b)))return{message:`Stylelint configuration found (${b})`,name:"Stylelint configuration",status:"pass"};return{message:"No Stylelint configuration found",name:"Stylelint configuration",status:"warn"}},Cb=()=>{let b=I.join(u.cwd(),"oxlint.config.ts");if(!w(b))return{message:"No oxlint.config.ts file found",name:"Oxlint configuration",status:"fail"};try{if(E0(b,"utf-8").includes("ultracite/oxlint/"))return{message:"oxlint.config.ts extends ultracite oxlint config",name:"Oxlint configuration",status:"pass"};return{message:"oxlint.config.ts exists but doesn't extend ultracite config",name:"Oxlint configuration",status:"warn"}}catch{return{message:"Could not read oxlint.config.ts file",name:"Oxlint configuration",status:"fail"}}},fb=()=>{let b=I.join(u.cwd(),"oxfmt.config.ts");if(!w(b))return{message:"No oxfmt.config.ts file found",name:"oxfmt configuration",status:"fail"};try{if(E0(b,"utf-8").includes("ultracite/oxfmt"))return{message:"oxfmt.config.ts extends ultracite oxfmt config",name:"oxfmt configuration",status:"pass"};return{message:"oxfmt.config.ts exists but doesn't extend ultracite config",name:"oxfmt configuration",status:"warn"}}catch{return{message:"Could not read oxfmt.config.ts file",name:"oxfmt configuration",status:"fail"}}},lb=()=>{let b=I.join(u.cwd(),"package.json");if(!w(b))return{message:"No package.json found",name:"Ultracite dependency",status:"warn"};let y=x(b);if(!y)return{message:"Could not parse package.json",name:"Ultracite dependency",status:"warn"};let G=y.dependencies?.ultracite||y.devDependencies?.ultracite||y.peerDependencies?.ultracite;if(G)return{message:`Ultracite is in package.json (${G})`,name:"Ultracite dependency",status:"pass"};return{message:"Ultracite not found in package.json dependencies",name:"Ultracite dependency",status:"warn"}},rb=(b)=>{let y=[];if(b!=="eslint"){if([".prettierrc",".prettierrc.js",".prettierrc.cjs",".prettierrc.mjs",".prettierrc.json",".prettierrc.yaml",".prettierrc.yml","prettier.config.js","prettier.config.mjs","prettier.config.cjs"].some((A)=>w(I.join(u.cwd(),A))))y.push("Prettier")}if([".eslintrc",".eslintrc.js",".eslintrc.cjs",".eslintrc.mjs",".eslintrc.json",".eslintrc.yaml",".eslintrc.yml"].some((H)=>w(I.join(u.cwd(),H))))y.push("ESLint (legacy config)");if(y.length>0)return{message:`Found potentially conflicting tools: ${y.join(", ")}`,name:"Conflicting tools",status:"warn"};return{message:"No conflicting formatting/linting tools found",name:"Conflicting tools",status:"pass"}},kb=(b)=>{let y=[];switch(b){case"biome":{y.push({fn:()=>s("biome",!0),name:"Biome installation"},{fn:pb,name:"Biome configuration"});break}case"eslint":{y.push({fn:()=>s("eslint",!0),name:"ESLint installation"},{fn:cb,name:"ESLint configuration"},{fn:()=>s("prettier",!0),name:"Prettier installation"},{fn:Pb,name:"Prettier configuration"},{fn:()=>s("stylelint",!1),name:"Stylelint installation"},{fn:qb,name:"Stylelint configuration"});break}case"oxlint":{y.push({fn:()=>s("oxlint",!0),name:"Oxlint installation"},{fn:Cb,name:"Oxlint configuration"},{fn:()=>s("oxfmt",!0),name:"oxfmt installation"},{fn:fb,name:"oxfmt configuration"});break}default:break}return y.push({fn:lb,name:"Ultracite dependency"},{fn:()=>rb(b),name:"Conflicting tools"}),y},U1=()=>{mb(`Ultracite v${W.version} Doctor`);let b=n();if(!b)throw L.error("No linter configuration found. Run `ultracite init` to set up a linter."),Y0("Doctor complete"),Error("Doctor checks failed");L.info(`Detected linter: ${b}`);let y=Mb();y.start("Running diagnostics...");let H=kb(b).map(({fn:U})=>U());y.stop("Diagnostics complete.");for(let U of H)if(U.status==="pass")L.success(U.message);else if(U.status==="warn")L.warn(U.message);else L.error(U.message);let A=H.filter((U)=>U.status==="pass").length,$=H.filter((U)=>U.status==="fail").length,v=H.filter((U)=>U.status==="warn").length;if(L.info(`Summary: ${A} passed, ${v} warnings, ${$} failed`),$>0)throw L.error("Some checks failed. Run 'ultracite init' to fix issues."),Y0("Doctor complete"),Error("Doctor checks failed");if(v>0){L.warn("Some optional improvements available. Run 'ultracite init' to configure."),Y0("Doctor complete");return}L.success("Everything looks good!"),Y0("Doctor complete")};var nb=(b,y)=>{let G=["check","--write","--no-errors-on-unmatched",...y];if(b.length>0)G.push(...b);else G.push("./");let H=V("biome",G,{stdio:"inherit"});_("Biome",H)},sb=(b,y)=>{let G=["--fix",...y,...b.length>0?b:["."]],H=V("eslint",G,{stdio:"inherit"});_("ESLint",H)},ib=(b,y)=>{let G=["--write",...y,...b.length>0?b:["."]],H=V("prettier",G,{stdio:"inherit"});_("Prettier",H)},tb=(b,y)=>{let G=V0(b);if(G.length===0)return;let H=["--fix",...y,"--allow-empty-input",...G],A=V("stylelint",H,{stdio:"inherit"});_("Stylelint",A)},gb=(b,y)=>{let G=y.includes("--unsafe"),H=y.filter((v)=>v!=="--unsafe"),A=[G?"--fix-dangerously":"--fix",...H,...b.length>0?b:["."]],$=V("oxlint",A,{stdio:"inherit"});_("Oxlint",$)},ab=(b,y)=>{let G=["--write",...y,...b.length>0?b:["."]],H=V("oxfmt",G,{stdio:"inherit"});_("oxfmt",H)},Q1=(b,y=[])=>{let G=n(),H=K0(b);if(!G)throw Error("No linter configuration found. Run `ultracite init` to set up a linter.");switch(G){case"eslint":{C([()=>ib(H,[]),()=>sb(H,y),()=>tb(H,[])]);break}case"oxlint":{C([()=>ab(H,[]),()=>gb(H,y)]);break}default:nb(H,y)}};import EG from"node:process";import{cancel as a,intro as _G,isCancel as e,log as z0,multiselect as X0,select as DG,spinner as Y}from"@clack/prompts";import{addDevDependency as OG,detectPackageManager as RG}from"nypm";import{readFile as eb}from"node:fs/promises";import{dlxCommand as by}from"nypm";var c0=(b,y)=>`# Ultracite Code Standards
2
+ import{createRequire as xb}from"node:module";var Sb=xb(import.meta.url);import D1 from"node:process";import{Command as Y$}from"commander";var z={name:"ultracite",version:"7.9.1",description:"The AI-ready formatter that helps you write and generate code faster.",keywords:["biome","fixer","formatter","linter","ultracite"],homepage:"https://www.ultracite.ai/",bugs:{url:"https://github.com/haydenbleasel/ultracite/issues"},license:"MIT",author:"Hayden Bleasel <hello@haydenbleasel.com>",repository:{type:"git",url:"git+https://github.com/haydenbleasel/ultracite.git"},bin:{ultracite:"dist/index.js"},files:["config","dist","README.md"],type:"module",exports:{"./biome/*":"./config/biome/*/biome.jsonc","./eslint/*":"./config/eslint/*/eslint.config.mjs","./oxlint/*":{types:"./config/oxlint/*/index.d.mts",default:"./config/oxlint/*/index.mjs"},"./oxfmt":{types:"./config/oxfmt/index.d.mts",default:"./config/oxfmt/index.mjs"},"./prettier":"./config/prettier/prettier.config.mjs","./stylelint":"./config/stylelint/stylelint.config.mjs"},publishConfig:{access:"public",registry:"https://registry.npmjs.org/"},scripts:{prebuild:"bun run scripts/generate-dts.ts",build:"tsgo --noEmit && bun run build.ts",test:"bun test","test:coverage":"bun test --coverage",bench:"bun run benchmarks/cli.bench.ts",types:"tsgo --noEmit"},dependencies:{"@clack/prompts":"^1.5.1","@typescript-eslint/utils":"^8.62.1",commander:"^15.0.0","cross-spawn":"^7.0.6",deepmerge:"^4.3.1",glob:"^13.0.6","jsonc-parser":"^3.3.1",nypm:"^0.6.6",yaml:"^2.9.0",zod:"^4.4.3"},devDependencies:{"@angular-eslint/eslint-plugin":"^22.0.0","@biomejs/biome":"2.5.2","@darraghor/eslint-plugin-nestjs-typed":"^7.2.5","@eslint/js":"^10.0.0","@next/eslint-plugin-next":"^16.2.10","@tanstack/eslint-plugin-query":"^5.101.2","@tanstack/eslint-plugin-router":"^1.162.0","@tanstack/eslint-plugin-start":"^0.1.0","@types/bun":"^1.3.14","@types/cross-spawn":"^6.0.6","@types/node":"^25.9.2","@typescript-eslint/eslint-plugin":"^8.62.1","@typescript-eslint/parser":"^8.62.1","@vitest/eslint-plugin":"^1.6.21",eslint:"^10.0.0","eslint-config-prettier":"^10.1.8","eslint-import-resolver-typescript":"^4.4.5","eslint-plugin-astro":"^2.1.1","eslint-plugin-compat":"^7.0.2","eslint-plugin-cypress":"^6.4.2","eslint-plugin-github":"6.0.0","eslint-plugin-html":"^8.1.4","eslint-plugin-import-x":"^4.17.1","eslint-plugin-jest":"^29.15.4","eslint-plugin-jsdoc":"^63.0.11","eslint-plugin-jsx-a11y":"^6.10.2","eslint-plugin-n":"^18.2.1","eslint-plugin-prettier":"^5.5.6","eslint-plugin-promise":"^7.3.0","eslint-plugin-qwik":"^1.20.0","eslint-plugin-react":"^7.37.5","eslint-plugin-react-doctor":"^0.7.1","eslint-plugin-react-hooks":"^7.1.1","eslint-plugin-remix":"^1.1.1","eslint-plugin-solid":"^0.14.5","eslint-plugin-sonarjs":"^4.1.0","eslint-plugin-storybook":"^10.4.6","eslint-plugin-svelte":"^3.20.0","eslint-plugin-unicorn":"^70.0.0","eslint-plugin-unused-imports":"^4.4.1","eslint-plugin-vue":"^10.9.2",globals:"^17.7.0",oxlint:"^1.72.0","oxlint-plugin-react-doctor":"^0.7.1","prettier-plugin-astro":"^0.14.1","prettier-plugin-svelte":"^4.1.0","prettier-plugin-tailwindcss":"^0.8.0","stylelint-config-idiomatic-order":"^10.0.0","stylelint-config-standard":"^40.0.0","stylelint-prettier":"^5.0.3"},peerDependencies:{oxfmt:">=0.1.0",oxlint:"^1.0.0"},peerDependenciesMeta:{oxfmt:{optional:!0},oxlint:{optional:!0}},packageManager:"bun@1.3.14"};import{existsSync as Ib}from"node:fs";import mb from"node:path";var _b=(b,y,$)=>{let G=$?.indexOf(b)??-1;if(!$||G===-1)return y;return $.slice(G+1)},L1=(b)=>b.map((y)=>y.startsWith("-")?`./${y}`:y),n1="**/*.{css,scss,sass,less}",Fb=[".css",".scss",".sass",".less"],hb=(b)=>{let y=b.toLowerCase();return Fb.some(($)=>y.endsWith($))},x1=(b)=>{if(b.length===0)return[n1];let y=[];for(let $ of b){if(hb($)){y.push($);continue}if(mb.extname($)===""){let G=$.replace(/\/+$/u,"");y.push(G==="."||G===""?n1:`${G}/${n1}`)}}return y},k1=({commandName:b,parsedArgs:y,pathExists:$=Ib,rawArgs:G})=>{let v=_b(b,y,G),U=v.indexOf("--");if(U!==-1)return{files:v.slice(U+1),passthrough:v.slice(0,U)};let Q=[],W=[];for(let o of v){if(o.startsWith("-")&&!$(o)){W.push(o);continue}Q.push(o)}return{files:Q,passthrough:W}};import{sync as Ob}from"cross-spawn";class r extends Error{commandName;exitCode;name="LinterExitError";constructor(b,y){super(`${b} exited with code ${y}`);this.commandName=b,this.exitCode=y}}var j=(b,y,$)=>Ob(b,y,{...$,shell:!1}),d=(b,y)=>{if(y.error)throw Error(`Failed to run ${b}: ${y.error.message}`);if(y.status===null)throw Error(`${b} was killed by signal ${y.signal??"unknown"}`);if(y.status!==0)throw new r(b,y.status)},n=(b)=>{let y=null;for(let $ of b)try{$()}catch(G){if(G instanceof r){y??=G;continue}throw G}if(y)throw new r(y.commandName,y.exitCode)};import{accessSync as cb,lstatSync as w0,mkdirSync as qb,realpathSync as u0}from"node:fs";import{readFile as Pb,writeFile as fb}from"node:fs/promises";import D from"node:path";import C1 from"node:process";import{glob as Mb}from"glob";import lb from"yaml";import{readFileSync as Tb}from"node:fs";import{readFile as Eb}from"node:fs/promises";import{parse as j0}from"jsonc-parser";import{z as V}from"zod";var pb=V.looseObject({dependencies:V.record(V.string(),V.string()).optional(),devDependencies:V.record(V.string(),V.string()).optional(),"lint-staged":V.unknown().optional(),name:V.string().optional(),peerDependencies:V.record(V.string(),V.string()).optional(),prettier:V.unknown().optional(),scripts:V.record(V.string(),V.string()).optional(),stylelint:V.unknown().optional(),type:V.string().optional(),version:V.string().optional(),workspace:V.unknown().optional(),workspaces:V.union([V.array(V.string()),V.record(V.string(),V.unknown())]).optional()}),k=(b)=>{let y=j0(b),$=pb.safeParse(y);return $.success?$.data:void 0},p=(b="package.json")=>{try{let y=Tb(b,"utf-8");return k(y)}catch{return}},s=async(b="package.json")=>{try{let y=await Eb(b,"utf-8");return k(y)}catch{return}},K0=V.looseObject({extends:V.array(V.string()).optional()}),A0=V.looseObject({compilerOptions:V.looseObject({strict:V.boolean().optional(),strictNullChecks:V.boolean().optional()}).optional()}),S1=(b,y)=>{let $=j0(b),G=y.safeParse($);return G.success?G.data:void 0};var i1="pnpm-workspace.yaml",H=(b)=>{try{return cb(b),!0}catch{return!1}},c=()=>{if(H(i1))return!0;let b=p();if(!b)return!1;return!!b.workspaces||!!b.workspace},x=(b)=>{let y=D.dirname(b);if(y!=="."){let $=y.startsWith("./")?y.slice(2):y;qb($,{recursive:!0})}},s1=(b,y)=>{let $=D.relative(y,b);return $===""||!$.startsWith("..")&&!D.isAbsolute($)},t1=(b)=>typeof u0==="function"?u0(b):D.resolve(b),rb=(b)=>{let y=b;while(!0)try{return t1(y)}catch($){if($.code!=="ENOENT")throw $;let G=D.dirname(y);if(G===y)return D.resolve(y);y=G}},nb=(b)=>{let y=t1(C1.cwd()),$=D.resolve(C1.cwd(),b);if(!s1($,y))throw Error(`Refusing to write outside project: ${b}`);let G=D.dirname($),v=rb(G);if(!s1(v,y))throw Error(`Refusing to write through directory outside project: ${b}`);try{if((typeof w0==="function"?w0($):void 0)?.isSymbolicLink())throw Error(`Refusing to write through symbolic link: ${b}`);let Q=t1($);if(!s1(Q,y))throw Error(`Refusing to write outside project: ${b}`)}catch(U){if(U.code==="ENOENT")return;throw U}},Z=async(b,y)=>{nb(b),x(b),await fb(b,y)},L=async({dependencies:b,devDependencies:y,scripts:$,type:G})=>{let v=await s();if(!v)throw Error("Failed to parse package.json: file is missing or invalid");let U={...v};if(G)U.type=G;if(v.devDependencies||y)U.devDependencies={...v.devDependencies,...y};if(v.dependencies||b)U.dependencies={...v.dependencies,...b};if(v.scripts||$)U.scripts={...v.scripts,...$};await Z("package.json",`${JSON.stringify(U,null,2)}
3
+ `)},d0=/^[a-z][a-z0-9-]*$/u,S=(b)=>{if(!d0.test(b))throw Error(`Invalid framework name "${b}": must match ${d0}`);return b},q=["biome.json","biome.jsonc",".biome.json",".biome.jsonc"],M=["eslint.config.mjs","eslint.config.js","eslint.config.cjs","eslint.config.ts","eslint.config.mts","eslint.config.cts"],D0=[".eslintrc",".eslintrc.json",".eslintrc.js",".eslintrc.cjs",".eslintrc.yaml",".eslintrc.yml"],C=[".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"],i=[".stylelintrc.mjs","stylelint.config.mjs",".stylelintrc.cjs","stylelint.config.cjs",".stylelintrc.js","stylelint.config.js",".stylelintrc",".stylelintrc.json",".stylelintrc.yml",".stylelintrc.yaml"],g1=[".oxlintrc.json","oxlint.config.ts"],N0=["oxfmt.config.ts"],kb={"@angular/core":["angular"],"@builder.io/qwik":["qwik"],"@nestjs/core":["nestjs"],"@qwik.dev/core":["qwik"],"@remix-run/node":["remix"],"@remix-run/react":["react","remix"],"@tanstack/react-query":["react","tanstack"],"@tanstack/react-router":["react","tanstack"],"@tanstack/react-start":["react","tanstack"],astro:["astro"],jest:["jest"],next:["react","next"],nuxt:["vue"],react:["react"],"react-router":["react","remix"],"solid-js":["solid"],svelte:["svelte"],vitest:["vitest"],vue:["vue"]},J0=(b)=>{if(!b)return[];return[...Object.keys(b.dependencies??{}),...Object.keys(b.devDependencies??{}),...Object.keys(b.peerDependencies??{})]},sb=async(b)=>{let y=new Set,$=b?.workspaces;if(Array.isArray($))for(let G of $)y.add(G);else if($&&typeof $==="object"){let{packages:G}=$;if(Array.isArray(G)){for(let v of G)if(typeof v==="string")y.add(v)}}if(H(i1))try{let G=await Pb(i1,"utf-8"),v=lb.parse(G);if(Array.isArray(v?.packages)){for(let U of v.packages)if(typeof U==="string")y.add(U)}}catch{}return[...y]},L0=async()=>{let b=new Set;try{let y=await s(),$=new Set(J0(y)),G=await sb(y);if(G.length>0){let v=await Mb(G.map((Q)=>`${Q.replace(/\/+$/u,"")}/package.json`),{absolute:!1,ignore:["**/node_modules/**"]}),U=await Promise.all(v.map((Q)=>s(Q)));for(let Q of U)for(let W of J0(Q))$.add(W)}for(let v of $){let U=kb[v];if(U)for(let Q of U)b.add(Q)}}catch{}return[...b]},t=(b=C1.cwd())=>{let y=b;while(!0){for(let G of q)if(H(D.join(y,G)))return"biome";for(let G of M)if(H(D.join(y,G)))return"eslint";for(let G of g1)if(H(D.join(y,G)))return"oxlint";let $=D.dirname(y);if($===y)break;y=$}return null};var Cb=(b,y)=>{let $=["check","--no-errors-on-unmatched",...y];if(b.length>0)$.push(...b);else $.push("./");let G=j("biome",$,{stdio:"inherit"});d("Biome",G)},ib=(b,y)=>{let $=[...y,...b.length>0?b:["."]],G=j("eslint",$,{stdio:"inherit"});d("ESLint",G)},tb=(b,y)=>{let $=["--check",...y,...b.length>0?b:["."]],G=j("prettier",$,{stdio:"inherit"});d("Prettier",G)},gb=(b,y)=>{let $=x1(b);if($.length===0)return;let G=[...y,"--allow-empty-input",...$],v=j("stylelint",G,{stdio:"inherit"});d("Stylelint",v)},ab=(b,y)=>{let $=[...y,...b.length>0?b:["."]],G=j("oxlint",$,{stdio:"inherit"});d("Oxlint",G)},eb=(b,y)=>{let $=["--check",...y,...b.length>0?b:["."]],G=j("oxfmt",$,{stdio:"inherit"});d("oxfmt",G)},x0=(b=[],y=[])=>{let $=t(),G=L1(b);if(!$)throw Error("No linter configuration found. Run `ultracite init` to set up a linter.");switch($){case"eslint":{n([()=>tb(G,[]),()=>ib(G,y),()=>gb(G,[])]);break}case"oxlint":{n([()=>eb(G,[]),()=>ab(G,y)]);break}default:Cb(G,y)}};import{existsSync as m,readFileSync as m1}from"node:fs";import _ from"node:path";import F from"node:process";import{intro as by,log as I,outro as R1,spinner as yy}from"@clack/prompts";import{parse as $y}from"jsonc-parser";var U1="Biome configuration",Q1="ESLint configuration",a1="Prettier configuration",e1="Stylelint configuration",W1="Oxlint configuration",Z1="oxfmt configuration",z1="Ultracite dependency",b0="Conflicting tools",I1="Doctor complete",g=(b,y)=>{let $=j(b,["--version"],{encoding:"utf-8"});if($.status===0&&$.stdout)return{message:`${b} is installed (${String($.stdout).trim()})`,name:`${b} installation`,status:"pass"};return{message:`${b} is not installed${y?"":" (optional)"}`,name:`${b} installation`,status:y?"fail":"warn"}},Gy=()=>{let b=null,y=null;for(let $ of q){let G=_.join(F.cwd(),$);if(m(G)){b=G,y=$;break}}if(!b)return{message:`No Biome config file found (expected one of: ${q.join(", ")})`,name:U1,status:"fail"};try{let $=m1(b,"utf-8"),G=$y($);if(Array.isArray(G?.extends)&&G.extends.includes("ultracite/biome/core"))return{message:`${y} extends ultracite/biome/core`,name:U1,status:"pass"};return{message:`${y} exists but doesn't extend ultracite/biome/core`,name:U1,status:"warn"}}catch{return{message:`Could not parse ${y} file`,name:U1,status:"fail"}}},vy=()=>{let b=null;for(let y of M){let $=_.join(F.cwd(),y);if(m($)){b=$;break}}if(!b)return{message:"No eslint.config.* file found",name:Q1,status:"fail"};try{if(m1(b,"utf-8").includes("ultracite/eslint"))return{message:"eslint.config.* imports ultracite/eslint",name:Q1,status:"pass"};return{message:"eslint.config.* exists but doesn't import ultracite/eslint",name:Q1,status:"warn"}}catch{return{message:"Could not read eslint.config.* file",name:Q1,status:"fail"}}},Uy=()=>{for(let b of C)if(m(_.join(F.cwd(),b)))return{message:`Prettier configuration found (${b})`,name:a1,status:"pass"};return{message:"No Prettier configuration found",name:a1,status:"fail"}},Qy=()=>{for(let b of i)if(m(_.join(F.cwd(),b)))return{message:`Stylelint configuration found (${b})`,name:e1,status:"pass"};return{message:"No Stylelint configuration found",name:e1,status:"warn"}},Wy=()=>{let b=_.join(F.cwd(),"oxlint.config.ts");if(!m(b))return{message:"No oxlint.config.ts file found",name:W1,status:"fail"};try{if(m1(b,"utf-8").includes("ultracite/oxlint/"))return{message:"oxlint.config.ts extends ultracite oxlint config",name:W1,status:"pass"};return{message:"oxlint.config.ts exists but doesn't extend ultracite config",name:W1,status:"warn"}}catch{return{message:"Could not read oxlint.config.ts file",name:W1,status:"fail"}}},Zy=()=>{let b=_.join(F.cwd(),"oxfmt.config.ts");if(!m(b))return{message:"No oxfmt.config.ts file found",name:Z1,status:"fail"};try{if(m1(b,"utf-8").includes("ultracite/oxfmt"))return{message:"oxfmt.config.ts extends ultracite oxfmt config",name:Z1,status:"pass"};return{message:"oxfmt.config.ts exists but doesn't extend ultracite config",name:Z1,status:"warn"}}catch{return{message:"Could not read oxfmt.config.ts file",name:Z1,status:"fail"}}},zy=()=>{let b=_.join(F.cwd(),"package.json");if(!m(b))return{message:"No package.json found",name:z1,status:"warn"};let y=p(b);if(!y)return{message:"Could not parse package.json",name:z1,status:"warn"};let $=y.dependencies?.ultracite||y.devDependencies?.ultracite||y.peerDependencies?.ultracite;if($)return{message:`Ultracite is in package.json (${$})`,name:z1,status:"pass"};return{message:"Ultracite not found in package.json dependencies",name:z1,status:"warn"}},Yy=(b)=>{let y=[];if(b!=="eslint"){if([".prettierrc",".prettierrc.js",".prettierrc.cjs",".prettierrc.mjs",".prettierrc.json",".prettierrc.yaml",".prettierrc.yml","prettier.config.js","prettier.config.mjs","prettier.config.cjs"].some((v)=>m(_.join(F.cwd(),v))))y.push("Prettier")}if([".eslintrc",".eslintrc.js",".eslintrc.cjs",".eslintrc.mjs",".eslintrc.json",".eslintrc.yaml",".eslintrc.yml"].some((G)=>m(_.join(F.cwd(),G))))y.push("ESLint (legacy config)");if(y.length>0)return{message:`Found potentially conflicting tools: ${y.join(", ")}`,name:b0,status:"warn"};return{message:"No conflicting formatting/linting tools found",name:b0,status:"pass"}},Hy=(b)=>{let y=[];switch(b){case"biome":{y.push({fn:()=>g("biome",!0),name:"Biome installation"},{fn:Gy,name:U1});break}case"eslint":{y.push({fn:()=>g("eslint",!0),name:"ESLint installation"},{fn:vy,name:Q1},{fn:()=>g("prettier",!0),name:"Prettier installation"},{fn:Uy,name:a1},{fn:()=>g("stylelint",!1),name:"Stylelint installation"},{fn:Qy,name:e1});break}case"oxlint":{y.push({fn:()=>g("oxlint",!0),name:"Oxlint installation"},{fn:Wy,name:W1},{fn:()=>g("oxfmt",!0),name:"oxfmt installation"},{fn:Zy,name:Z1});break}default:break}return y.push({fn:zy,name:z1},{fn:()=>Yy(b),name:b0}),y},S0=()=>{by(`Ultracite v${z.version} Doctor`);let b=t();if(!b)throw I.error("No linter configuration found. Run `ultracite init` to set up a linter."),R1(I1),Error("Doctor checks failed");I.info(`Detected linter: ${b}`);let y=yy();y.start("Running diagnostics...");let G=Hy(b).map(({fn:W})=>W());y.stop("Diagnostics complete.");for(let W of G)if(W.status==="pass")I.success(W.message);else if(W.status==="warn")I.warn(W.message);else I.error(W.message);let v=G.filter((W)=>W.status==="pass").length,U=G.filter((W)=>W.status==="fail").length,Q=G.filter((W)=>W.status==="warn").length;if(I.info(`Summary: ${v} passed, ${Q} warnings, ${U} failed`),U>0)throw I.error("Some checks failed. Run 'ultracite init' to fix issues."),R1(I1),Error("Doctor checks failed");if(Q>0){I.warn("Some optional improvements available. Run 'ultracite init' to configure."),R1(I1);return}I.success("Everything looks good!"),R1(I1)};var oy=(b,y)=>{let $=["check","--write","--no-errors-on-unmatched",...y];if(b.length>0)$.push(...b);else $.push("./");let G=j("biome",$,{stdio:"inherit"});d("Biome",G)},Vy=(b,y)=>{let $=["--fix",...y,...b.length>0?b:["."]],G=j("eslint",$,{stdio:"inherit"});d("ESLint",G)},By=(b,y)=>{let $=["--write",...y,...b.length>0?b:["."]],G=j("prettier",$,{stdio:"inherit"});d("Prettier",G)},Xy=(b,y)=>{let $=x1(b);if($.length===0)return;let G=["--fix",...y,"--allow-empty-input",...$],v=j("stylelint",G,{stdio:"inherit"});d("Stylelint",v)},jy=(b,y)=>{let $=y.includes("--unsafe"),G=y.filter((Q)=>Q!=="--unsafe"),v=[$?"--fix-dangerously":"--fix",...G,...b.length>0?b:["."]],U=j("oxlint",v,{stdio:"inherit"});d("Oxlint",U)},Ky=(b,y)=>{let $=["--write",...y,...b.length>0?b:["."]],G=j("oxfmt",$,{stdio:"inherit"});d("oxfmt",G)},R0=(b,y=[])=>{let $=t(),G=L1(b);if(!$)throw Error("No linter configuration found. Run `ultracite init` to set up a linter.");switch($){case"eslint":{n([()=>By(G,[]),()=>Vy(G,y),()=>Xy(G,[])]);break}case"oxlint":{n([()=>Ky(G,[]),()=>jy(G,y)]);break}default:oy(G,y)}};import c2 from"node:process";import{cancel as y1,intro as q2,isCancel as $1,log as d1,multiselect as J1,select as P2,spinner as w}from"@clack/prompts";import{addDevDependency as f2,detectPackageManager as M2}from"nypm";import{readFile as Ay}from"node:fs/promises";import{dlxCommand as wy}from"nypm";var y0=(b,y)=>`# Ultracite Code Standards
4
4
 
5
5
  This project uses **Ultracite**, a zero-config preset that enforces strict code quality standards through automated formatting and linting.
6
6
 
@@ -123,19 +123,19 @@ ${y}'s linter will catch most issues automatically. Focus your attention on:
123
123
  ---
124
124
 
125
125
  Most formatting and common issues are automatically fixed by ${y}. Run \`${b} ultracite fix\` before committing to ensure compliance.
126
- `;var c=[{config:{appendMode:!0,path:".claude/CLAUDE.md"},hooks:{getContent:(b)=>({hooks:{PostToolUse:[{hooks:[{command:b,type:"command"}],matcher:"Write|Edit"}]}}),path:".claude/settings.json"},id:"claude",name:"Claude Code"},{config:{appendMode:!0,path:"AGENTS.md"},id:"codex",name:"Codex"},{config:{appendMode:!0,path:"AGENTS.md"},id:"jules",name:"Jules"},{config:{appendMode:!0,path:"replit.md"},id:"replit",name:"Replit Agent"},{config:{appendMode:!0,path:"AGENTS.md"},id:"devin",name:"Devin"},{config:{appendMode:!0,path:"AGENTS.md"},id:"lovable",name:"Lovable"},{config:{appendMode:!0,path:"AGENTS.md"},id:"zencoder",name:"Zencoder"},{config:{appendMode:!0,path:"AGENTS.md"},id:"ona",name:"Ona"},{config:{appendMode:!0,path:"AGENTS.md"},id:"openclaw",name:"OpenClaw"},{config:{appendMode:!0,path:"AGENTS.md"},id:"continue",name:"Continue"},{config:{appendMode:!0,path:"AGENTS.md"},id:"snowflake-cortex",name:"Snowflake Cortex"},{config:{appendMode:!0,path:"AGENTS.md"},id:"deepagents",name:"Deepagents"},{config:{appendMode:!0,path:"AGENTS.md"},id:"qoder",name:"Qoder"},{config:{appendMode:!0,path:"AGENTS.md"},id:"kimi-cli",name:"Kimi CLI"},{config:{appendMode:!0,path:"AGENTS.md"},id:"mcpjam",name:"MCPJam"},{config:{appendMode:!0,path:"AGENTS.md"},id:"mux",name:"Mux"},{config:{appendMode:!0,path:"AGENTS.md"},id:"pi",name:"Pi"},{config:{appendMode:!0,path:"AGENTS.md"},id:"adal",name:"AdaL"},{config:{appendMode:!0,path:"AGENTS.md"},hooks:{getContent:(b)=>({hooks:{PostToolUse:[{command:b,type:"command"}]}}),path:".github/hooks/ultracite.json"},id:"copilot",name:"GitHub Copilot"},{config:{appendMode:!0,path:"AGENTS.md"},id:"cline",name:"Cline"},{config:{appendMode:!0,path:"AGENTS.md"},id:"amp",name:"AMP"},{config:{path:"ultracite.md"},id:"aider",name:"Aider"},{config:{appendMode:!0,path:"AGENTS.md"},id:"firebase-studio",name:"Firebase Studio"},{config:{appendMode:!0,path:"AGENTS.md"},id:"open-hands",name:"OpenHands"},{config:{appendMode:!0,path:"GEMINI.md"},id:"gemini",name:"Gemini"},{config:{appendMode:!0,path:"AGENTS.md"},id:"junie",name:"Junie"},{config:{appendMode:!0,path:"AGENTS.md"},id:"augmentcode",name:"Augment Code"},{config:{appendMode:!0,path:"AGENTS.md"},id:"bob",name:"IBM Bob"},{config:{appendMode:!0,path:"AGENTS.md"},id:"kilo-code",name:"Kilo Code"},{config:{appendMode:!0,path:"AGENTS.md"},id:"goose",name:"Goose"},{config:{appendMode:!0,path:".roo/rules/ultracite.md"},id:"roo-code",name:"Roo Code"},{config:{appendMode:!0,path:"AGENTS.md"},id:"warp",name:"Warp"},{config:{appendMode:!0,path:"AGENTS.md"},id:"droid",name:"Droid"},{config:{appendMode:!0,path:"AGENTS.md"},id:"opencode",name:"OpenCode"},{config:{appendMode:!0,path:"AGENTS.md"},id:"crush",name:"Crush"},{config:{appendMode:!0,path:"AGENTS.md"},id:"qwen",name:"Qwen Code"},{config:{appendMode:!0,path:".amazonq/rules/ultracite.md"},id:"amazon-q-cli",name:"Amazon Q CLI"},{config:{path:"firebender.json"},id:"firebender",name:"Firebender"},{config:{appendMode:!0,path:"AGENTS.md"},id:"cursor-cli",name:"Cursor CLI"},{config:{appendMode:!0,path:"AGENTS.md"},id:"mistral-vibe",name:"Mistral Vibe"},{config:{appendMode:!0,path:"AGENTS.md"},id:"vercel",name:"Vercel Agent"}];var _0=[{id:"biome",name:"Biome",vscodeExtensionId:"biomejs.biome"},{id:"eslint",name:"ESLint + Prettier + Stylelint",vscodeExtensionId:"dbaeumer.vscode-eslint"},{id:"oxlint",name:"Oxlint + Oxfmt",vscodeExtensionId:"oxc.oxc-vscode"}];var W1=(b)=>b.replace(/ Code$/u,"").replace(/ Agent$/u,""),yy=(b,y)=>{if(b==="AGENTS.md"&&y.length>1){let H=y.slice(0,3),A=y.length>H.length?", and more":"";return`Universal (creates ${b} for ${H.join(", ")}${A})`}let[G]=y;return`${G} (creates ${b})`},Z1=()=>{let b=new Map;for(let G of c){let H=b.get(G.config.path)??[];H.push(G),b.set(G.config.path,H)}return[...b.entries()].map(([G,H])=>{let[A]=H,$=H.map((U)=>W1(U.name)),v=G==="AGENTS.md"&&H.length>1;return{agentIds:H.map((U)=>U.id),displayName:v?"Universal":W1(A.name),id:v?"universal":A.id,path:G,promptLabel:yy(G,$),representativeAgentId:A.id}}).toSorted((G,H)=>{if(G.path==="AGENTS.md")return-1;if(H.path==="AGENTS.md")return 1;return 0})},z1=(b,y,G)=>{let H=c.find((X)=>X.id===b);if(!H)throw Error(`Agent "${b}" not found`);let A=_0.find((X)=>X.id===G);if(!A)throw Error(`Provider "${G}" not found`);let $=by(y,""),v=c0($,A.name),U=H.config.header?`${H.config.header}
126
+ `;var l=[{config:{appendMode:!0,path:".claude/CLAUDE.md"},hooks:{getContent:(b)=>({hooks:{PostToolUse:[{hooks:[{command:b,type:"command"}],matcher:"Write|Edit"}]}}),path:".claude/settings.json"},id:"claude",name:"Claude Code"},{config:{appendMode:!0,path:"AGENTS.md"},id:"codex",name:"Codex"},{config:{appendMode:!0,path:"AGENTS.md"},id:"jules",name:"Jules"},{config:{appendMode:!0,path:"replit.md"},id:"replit",name:"Replit Agent"},{config:{appendMode:!0,path:"AGENTS.md"},id:"devin",name:"Devin"},{config:{appendMode:!0,path:"AGENTS.md"},id:"lovable",name:"Lovable"},{config:{appendMode:!0,path:"AGENTS.md"},id:"zencoder",name:"Zencoder"},{config:{appendMode:!0,path:"AGENTS.md"},id:"ona",name:"Ona"},{config:{appendMode:!0,path:"AGENTS.md"},id:"openclaw",name:"OpenClaw"},{config:{appendMode:!0,path:"AGENTS.md"},id:"continue",name:"Continue"},{config:{appendMode:!0,path:"AGENTS.md"},id:"snowflake-cortex",name:"Snowflake Cortex"},{config:{appendMode:!0,path:"AGENTS.md"},id:"deepagents",name:"Deepagents"},{config:{appendMode:!0,path:"AGENTS.md"},id:"qoder",name:"Qoder"},{config:{appendMode:!0,path:"AGENTS.md"},id:"kimi-cli",name:"Kimi CLI"},{config:{appendMode:!0,path:"AGENTS.md"},id:"mcpjam",name:"MCPJam"},{config:{appendMode:!0,path:"AGENTS.md"},id:"mux",name:"Mux"},{config:{appendMode:!0,path:"AGENTS.md"},id:"pi",name:"Pi"},{config:{appendMode:!0,path:"AGENTS.md"},id:"adal",name:"AdaL"},{config:{appendMode:!0,path:"AGENTS.md"},hooks:{getContent:(b)=>({hooks:{PostToolUse:[{command:b,type:"command"}]}}),path:".github/hooks/ultracite.json"},id:"copilot",name:"GitHub Copilot"},{config:{appendMode:!0,path:"AGENTS.md"},id:"cline",name:"Cline"},{config:{appendMode:!0,path:"AGENTS.md"},id:"amp",name:"AMP"},{config:{path:"ultracite.md"},id:"aider",name:"Aider"},{config:{appendMode:!0,path:"AGENTS.md"},id:"firebase-studio",name:"Firebase Studio"},{config:{appendMode:!0,path:"AGENTS.md"},id:"open-hands",name:"OpenHands"},{config:{appendMode:!0,path:"GEMINI.md"},id:"gemini",name:"Gemini"},{config:{appendMode:!0,path:"AGENTS.md"},id:"junie",name:"Junie"},{config:{appendMode:!0,path:"AGENTS.md"},id:"augmentcode",name:"Augment Code"},{config:{appendMode:!0,path:"AGENTS.md"},id:"bob",name:"IBM Bob"},{config:{appendMode:!0,path:"AGENTS.md"},id:"kilo-code",name:"Kilo Code"},{config:{appendMode:!0,path:"AGENTS.md"},id:"goose",name:"Goose"},{config:{appendMode:!0,path:".roo/rules/ultracite.md"},id:"roo-code",name:"Roo Code"},{config:{appendMode:!0,path:"AGENTS.md"},id:"warp",name:"Warp"},{config:{appendMode:!0,path:"AGENTS.md"},id:"droid",name:"Droid"},{config:{appendMode:!0,path:"AGENTS.md"},id:"opencode",name:"OpenCode"},{config:{appendMode:!0,path:"AGENTS.md"},id:"crush",name:"Crush"},{config:{appendMode:!0,path:"AGENTS.md"},id:"qwen",name:"Qwen Code"},{config:{appendMode:!0,path:".amazonq/rules/ultracite.md"},id:"amazon-q-cli",name:"Amazon Q CLI"},{config:{path:"firebender.json"},id:"firebender",name:"Firebender"},{config:{appendMode:!0,path:"AGENTS.md"},id:"cursor-cli",name:"Cursor CLI"},{config:{appendMode:!0,path:"AGENTS.md"},id:"mistral-vibe",name:"Mistral Vibe"},{config:{appendMode:!0,path:"AGENTS.md"},id:"vercel",name:"Vercel Agent"}];var _1=[{id:"biome",name:"Biome",vscodeExtensionId:"biomejs.biome"},{id:"eslint",name:"ESLint + Prettier + Stylelint",vscodeExtensionId:"dbaeumer.vscode-eslint"},{id:"oxlint",name:"Oxlint + Oxfmt",vscodeExtensionId:"oxc.oxc-vscode"}];var I0=(b)=>b.replace(/ Code$/u,"").replace(/ Agent$/u,""),uy=(b,y)=>{if(b==="AGENTS.md"&&y.length>1){let G=y.slice(0,3),v=y.length>G.length?", and more":"";return`Universal (creates ${b} for ${G.join(", ")}${v})`}let[$]=y;return`${$} (creates ${b})`},m0=()=>{let b=new Map;for(let $ of l){let G=b.get($.config.path)??[];G.push($),b.set($.config.path,G)}return[...b.entries()].map(([$,G])=>{let[v]=G,U=G.map((W)=>I0(W.name)),Q=$==="AGENTS.md"&&G.length>1;return{agentIds:G.map((W)=>W.id),displayName:Q?"Universal":I0(v.name),id:Q?"universal":v.id,path:$,promptLabel:uy($,U),representativeAgentId:v.id}}).toSorted(($,G)=>{if($.path==="AGENTS.md")return-1;if(G.path==="AGENTS.md")return 1;return 0})},_0=(b,y,$)=>{let G=l.find((o)=>o.id===b);if(!G)throw Error(`Agent "${b}" not found`);let v=_1.find((o)=>o.id===$);if(!v)throw Error(`Provider "${$}" not found`);let U=wy(y,""),Q=y0(U,v.name),W=G.config.header?`${G.config.header}
127
127
 
128
- ${v}`:v;return{create:async()=>{j(H.config.path),await Q(H.config.path,U)},exists:()=>z(H.config.path),update:async()=>{j(H.config.path);let X=z(H.config.path);if(!(H.config.appendMode&&X)){await Q(H.config.path,U);return}let o=await eb(H.config.path,"utf-8");if(o.includes(v.trim()))return;await Q(H.config.path,`${o}
128
+ ${Q}`:Q;return{create:async()=>{x(G.config.path),await Z(G.config.path,W)},exists:()=>H(G.config.path),update:async()=>{x(G.config.path);let o=H(G.config.path);if(!(G.config.appendMode&&o)){await Z(G.config.path,W);return}let B=await Ay(G.config.path,"utf-8");if(B.includes(Q.trim()))return;await Z(G.config.path,`${B}
129
129
 
130
- ${v}`)}}};import i from"deepmerge";var D0={"editor.defaultFormatter":"esbenp.prettier-vscode","editor.formatOnPaste":!0,"editor.formatOnSave":!0,"emmet.showExpandedAbbreviation":"never","js/ts.tsdk.path":"node_modules/typescript/lib","js/ts.tsdk.promptToUseWorkspaceVersion":!0},Gy={"[css]":{"editor.defaultFormatter":"biomejs.biome"},"[graphql]":{"editor.defaultFormatter":"biomejs.biome"},"[html]":{"editor.defaultFormatter":"biomejs.biome"},"[javascript]":{"editor.defaultFormatter":"biomejs.biome"},"[javascriptreact]":{"editor.defaultFormatter":"biomejs.biome"},"[json]":{"editor.defaultFormatter":"biomejs.biome"},"[jsonc]":{"editor.defaultFormatter":"biomejs.biome"},"[markdown]":{"editor.defaultFormatter":"biomejs.biome"},"[mdx]":{"editor.defaultFormatter":"biomejs.biome"},"[svelte]":{"editor.defaultFormatter":"biomejs.biome"},"[typescript]":{"editor.defaultFormatter":"biomejs.biome"},"[typescriptreact]":{"editor.defaultFormatter":"biomejs.biome"},"[vue]":{"editor.defaultFormatter":"biomejs.biome"},"[yaml]":{"editor.defaultFormatter":"biomejs.biome"},"editor.codeActionsOnSave":{"source.fixAll.biome":"explicit","source.organizeImports.biome":"explicit"}},Hy={"[css]":{"editor.defaultFormatter":"oxc.oxc-vscode"},"[graphql]":{"editor.defaultFormatter":"oxc.oxc-vscode"},"[handlebars]":{"editor.defaultFormatter":"oxc.oxc-vscode"},"[html]":{"editor.defaultFormatter":"oxc.oxc-vscode"},"[javascript]":{"editor.defaultFormatter":"oxc.oxc-vscode"},"[javascriptreact]":{"editor.defaultFormatter":"oxc.oxc-vscode"},"[json]":{"editor.defaultFormatter":"oxc.oxc-vscode"},"[jsonc]":{"editor.defaultFormatter":"oxc.oxc-vscode"},"[less]":{"editor.defaultFormatter":"oxc.oxc-vscode"},"[markdown]":{"editor.defaultFormatter":"oxc.oxc-vscode"},"[scss]":{"editor.defaultFormatter":"oxc.oxc-vscode"},"[typescript]":{"editor.defaultFormatter":"oxc.oxc-vscode"},"[typescriptreact]":{"editor.defaultFormatter":"oxc.oxc-vscode"},"[vue-html]":{"editor.defaultFormatter":"oxc.oxc-vscode"},"[vue]":{"editor.defaultFormatter":"oxc.oxc-vscode"},"[yaml]":{"editor.defaultFormatter":"oxc.oxc-vscode"},"editor.codeActionsOnSave":{"source.fixAll.oxc":"explicit"}},Ay={"editor.codeActionsOnSave":{"source.fixAll.eslint":"explicit","source.organizeImports":"explicit"}},J=(b="biome")=>{switch(b){case"biome":return i(D0,Gy);case"eslint":return i(D0,Ay);case"oxlint":return i(D0,Hy);default:return D0}},O0={format_on_save:"on",formatter:"language_server",lsp:{"typescript-language-server":{settings:{typescript:{preferences:{includePackageJsonAutoImports:"on"}}}}}},$y={languages:{JavaScript:{code_actions_on_format:{"source.fixAll.biome":!0,"source.organizeImports.biome":!0},formatter:{language_server:{name:"biome"}}},TSX:{code_actions_on_format:{"source.fixAll.biome":!0,"source.organizeImports.biome":!0},formatter:{language_server:{name:"biome"}}},TypeScript:{code_actions_on_format:{"source.fixAll.biome":!0,"source.organizeImports.biome":!0},formatter:{language_server:{name:"biome"}}}}},vy={languages:{JavaScript:{code_actions_on_format:{"source.fixAll.eslint":!0,"source.organizeImports.eslint":!0},formatter:{language_server:{name:"eslint"}}},TSX:{code_actions_on_format:{"source.fixAll.eslint":!0,"source.organizeImports.eslint":!0},formatter:{language_server:{name:"eslint"}}},TypeScript:{code_actions_on_format:{"source.fixAll.eslint":!0,"source.organizeImports.eslint":!0},formatter:{language_server:{name:"eslint"}}}}},Uy={languages:{JavaScript:{code_actions_on_format:{"source.fixAll.oxc":!0,"source.organizeImports.oxc":!0},formatter:{language_server:{name:"oxfmt"}}},TSX:{code_actions_on_format:{"source.fixAll.oxc":!0,"source.organizeImports.oxc":!0},formatter:{language_server:{name:"oxfmt"}}},TypeScript:{code_actions_on_format:{"source.fixAll.oxc":!0,"source.organizeImports.oxc":!0},formatter:{language_server:{name:"oxfmt"}}}},lsp:{oxfmt:{initialization_options:{settings:{configPath:null,flags:{},"fmt.configPath":null,"fmt.experimental":!0,run:"onSave",typeAware:!1,unusedDisableDirectives:!1}}},oxlint:{initialization_options:{settings:{disableNestedConfig:!1,fixKind:"safe_fix",run:"onType",typeAware:!0,unusedDisableDirectives:"deny"}}}}},Qy=(b="biome")=>{switch(b){case"biome":return i(O0,$y);case"eslint":return i(O0,vy);case"oxlint":return i(O0,Uy);default:return O0}},M=[{config:{extensionCommand:"code --install-extension",getContent:J,path:".vscode/settings.json"},id:"vscode",name:"Visual Studio Code"},{config:{extensionCommand:"code --install-extension",getContent:J,path:".vscode/settings.json"},hooks:{getContent:(b)=>({hooks:{afterFileEdit:[{command:b}]},version:1}),path:".cursor/hooks.json"},id:"cursor",name:"Cursor"},{config:{extensionCommand:"code --install-extension",getContent:J,path:".vscode/settings.json"},hooks:{getContent:(b)=>({hooks:{post_write_code:[{command:b,show_output:!0}]}}),path:".windsurf/hooks.json"},id:"windsurf",name:"Windsurf"},{config:{extensionCommand:"code --install-extension",getContent:J,path:".vscode/settings.json"},hooks:{getContent:(b)=>({hooks:{PostToolUse:[{hooks:[{command:b,timeout:20,type:"command"}],matcher:"Write|Edit"}]}}),path:".codebuddy/settings.json"},id:"codebuddy",name:"CodeBuddy"},{config:{extensionCommand:"code --install-extension",getContent:J,path:".vscode/settings.json"},id:"antigravity",name:"Antigravity"},{config:{extensionCommand:"code --install-extension",getContent:J,path:".vscode/settings.json"},id:"bob",name:"IBM Bob"},{config:{extensionCommand:"code --install-extension",getContent:J,path:".vscode/settings.json"},id:"kiro",name:"Kiro"},{config:{extensionCommand:"code --install-extension",getContent:J,path:".vscode/settings.json"},id:"trae",name:"Trae"},{config:{extensionCommand:"code --install-extension",getContent:J,path:".vscode/settings.json"},id:"void",name:"Void"},{config:{getContent:Qy,path:".zed/settings.json"},id:"zed",name:"Zed"}];var Wy=(b)=>Boolean(b.hooks),Zy=(b)=>Boolean(b.hooks),zy=()=>M.flatMap((b)=>Wy(b)?[{hooks:b.hooks,id:b.id,name:b.name}]:[]),Xy=()=>c.flatMap((b)=>Zy(b)?[{hooks:b.hooks,id:b.id,name:b.name}]:[]),y0=[...zy(),...Xy()];import{readFile as Ty}from"node:fs/promises";import{sync as oy}from"cross-spawn";import Ky from"deepmerge";import{parse as Vy}from"jsonc-parser";var X1=(b,y="biome")=>{let G=M.find((A)=>A.id===b);if(!G)throw Error(`Editor "${b}" not found`);let H=G.config.getContent(y);return{create:async()=>{j(G.config.path),await Q(G.config.path,`${JSON.stringify(H,null,2)}
131
- `)},exists:()=>z(G.config.path),extension:G.config.extensionCommand?(A)=>{let[$,...v]=G.config.extensionCommand.split(" ");return oy($,[...v,A],{stdio:"pipe"})}:void 0,update:async()=>{if(j(G.config.path),!z(G.config.path)){await Q(G.config.path,`${JSON.stringify(H,null,2)}
132
- `);return}let $=await Ty(G.config.path,"utf-8"),U=Vy($)||{},X=Ky(U,H);await Q(G.config.path,`${JSON.stringify(X,null,2)}
133
- `)}}};var By=(b,y)=>{if(y.length>1){let H=y.slice(0,3),A=y.length>H.length?", and more":"";return`Universal (creates ${b} for ${H.join(", ")}${A})`}let[G]=y;return`${G} (creates ${b})`},T1=()=>{let b=new Map;for(let G of M){let H=b.get(G.config.path)??[];H.push(G),b.set(G.config.path,H)}return[...b.entries()].map(([G,H])=>{let[A]=H,$=H.map((U)=>U.name),v=H.length>1;return{displayName:v?"Universal":A.name,editorIds:H.map((U)=>U.id),id:v?"universal":A.id,path:G,promptLabel:By(G,$),representativeEditorId:A.id}}).toSorted((G,H)=>{if(G.id==="universal")return-1;if(H.id==="universal")return 1;return 0})};import{readFile as Ey}from"node:fs/promises";import _y from"deepmerge";import{parse as Dy}from"jsonc-parser";import{runScriptCommand as Oy}from"nypm";var o1=["npm","yarn","pnpm","bun","deno"],Yy=(b)=>o1.includes(b),G0=(b)=>{if(Yy(b))return b;throw Error(`Unsupported package manager "${b}". Supported package managers: ${o1.join(", ")}.`)},K1=(b)=>{let y=G0(b.name);return{...b,command:y,name:y}};var Ry=(b)=>typeof b==="object"&&b!==null&&!Array.isArray(b),jy=(b,y=[])=>{let G=G0(b),H=G==="npm"&&y.length>0?["--",...y]:y;return Oy(G,"fix",{args:H})},V1=(b,y,G="biome")=>{let H=y0.find((o)=>o.id===b);if(!H)throw Error(`Hook integration "${b}" not found`);let $=jy(y,G==="biome"?["--skip=correctness/noUnusedImports"]:[]),v=H.hooks.getContent($),U=(o)=>{let B=JSON.stringify(o);return B.includes("ultracite")||B.includes($)},X=async()=>{if(!z(H.hooks.path)){await Q(H.hooks.path,`${JSON.stringify(v,null,2)}
134
- `);return}let B=await Ey(H.hooks.path,"utf-8"),O=Dy(B),E=Ry(O)?O:{};if(!U(E)){let S=_y(E,v);await Q(H.hooks.path,`${JSON.stringify(S,null,2)}
135
- `)}};return{create:async()=>{j(H.hooks.path),await Q(H.hooks.path,`${JSON.stringify(v,null,2)}
136
- `)},exists:()=>z(H.hooks.path),update:async()=>{j(H.hooks.path),await X()}}};import{mkdir as Ny,readFile as Sy}from"node:fs/promises";import{addDevDependency as Ly,dlxCommand as H0}from"nypm";var B1=(b)=>`#!/bin/sh
130
+ ${Q}`)}}};import a from"deepmerge";var F1={"editor.defaultFormatter":"esbenp.prettier-vscode","editor.formatOnPaste":!0,"editor.formatOnSave":!0,"emmet.showExpandedAbbreviation":"never","js/ts.tsdk.path":"node_modules/typescript/lib","js/ts.tsdk.promptToUseWorkspaceVersion":!0},J="biomejs.biome",A="oxc.oxc-vscode",h="code --install-extension",O=".vscode/settings.json",dy={"[css]":{"editor.defaultFormatter":J},"[graphql]":{"editor.defaultFormatter":J},"[html]":{"editor.defaultFormatter":J},"[javascript]":{"editor.defaultFormatter":J},"[javascriptreact]":{"editor.defaultFormatter":J},"[json]":{"editor.defaultFormatter":J},"[jsonc]":{"editor.defaultFormatter":J},"[markdown]":{"editor.defaultFormatter":J},"[mdx]":{"editor.defaultFormatter":J},"[svelte]":{"editor.defaultFormatter":J},"[typescript]":{"editor.defaultFormatter":J},"[typescriptreact]":{"editor.defaultFormatter":J},"[vue]":{"editor.defaultFormatter":J},"[yaml]":{"editor.defaultFormatter":J},"editor.codeActionsOnSave":{"source.fixAll.biome":"explicit","source.organizeImports.biome":"explicit"}},Jy={"[css]":{"editor.defaultFormatter":A},"[graphql]":{"editor.defaultFormatter":A},"[handlebars]":{"editor.defaultFormatter":A},"[html]":{"editor.defaultFormatter":A},"[javascript]":{"editor.defaultFormatter":A},"[javascriptreact]":{"editor.defaultFormatter":A},"[json]":{"editor.defaultFormatter":A},"[jsonc]":{"editor.defaultFormatter":A},"[less]":{"editor.defaultFormatter":A},"[markdown]":{"editor.defaultFormatter":A},"[scss]":{"editor.defaultFormatter":A},"[typescript]":{"editor.defaultFormatter":A},"[typescriptreact]":{"editor.defaultFormatter":A},"[vue-html]":{"editor.defaultFormatter":A},"[vue]":{"editor.defaultFormatter":A},"[yaml]":{"editor.defaultFormatter":A},"editor.codeActionsOnSave":{"source.fixAll.oxc":"explicit"}},Dy={"editor.codeActionsOnSave":{"source.fixAll.eslint":"explicit","source.organizeImports":"explicit"}},T=(b="biome")=>{switch(b){case"biome":return a(F1,dy);case"eslint":return a(F1,Dy);case"oxlint":return a(F1,Jy);default:return F1}},h1={format_on_save:"on",formatter:"language_server",lsp:{"typescript-language-server":{settings:{typescript:{preferences:{includePackageJsonAutoImports:"on"}}}}}},Ny={languages:{JavaScript:{code_actions_on_format:{"source.fixAll.biome":!0,"source.organizeImports.biome":!0},formatter:{language_server:{name:"biome"}}},TSX:{code_actions_on_format:{"source.fixAll.biome":!0,"source.organizeImports.biome":!0},formatter:{language_server:{name:"biome"}}},TypeScript:{code_actions_on_format:{"source.fixAll.biome":!0,"source.organizeImports.biome":!0},formatter:{language_server:{name:"biome"}}}}},Ly={languages:{JavaScript:{code_actions_on_format:{"source.fixAll.eslint":!0,"source.organizeImports.eslint":!0},formatter:{language_server:{name:"eslint"}}},TSX:{code_actions_on_format:{"source.fixAll.eslint":!0,"source.organizeImports.eslint":!0},formatter:{language_server:{name:"eslint"}}},TypeScript:{code_actions_on_format:{"source.fixAll.eslint":!0,"source.organizeImports.eslint":!0},formatter:{language_server:{name:"eslint"}}}}},xy={languages:{JavaScript:{code_actions_on_format:{"source.fixAll.oxc":!0,"source.organizeImports.oxc":!0},formatter:{language_server:{name:"oxfmt"}}},TSX:{code_actions_on_format:{"source.fixAll.oxc":!0,"source.organizeImports.oxc":!0},formatter:{language_server:{name:"oxfmt"}}},TypeScript:{code_actions_on_format:{"source.fixAll.oxc":!0,"source.organizeImports.oxc":!0},formatter:{language_server:{name:"oxfmt"}}}},lsp:{oxfmt:{initialization_options:{settings:{configPath:null,flags:{},"fmt.configPath":null,"fmt.experimental":!0,run:"onSave",typeAware:!1,unusedDisableDirectives:!1}}},oxlint:{initialization_options:{settings:{disableNestedConfig:!1,fixKind:"safe_fix",run:"onType",typeAware:!0,unusedDisableDirectives:"deny"}}}}},Sy=(b="biome")=>{switch(b){case"biome":return a(h1,Ny);case"eslint":return a(h1,Ly);case"oxlint":return a(h1,xy);default:return h1}},P=[{config:{extensionCommand:h,getContent:T,path:O},id:"vscode",name:"Visual Studio Code"},{config:{extensionCommand:h,getContent:T,path:O},hooks:{getContent:(b)=>({hooks:{afterFileEdit:[{command:b}]},version:1}),path:".cursor/hooks.json"},id:"cursor",name:"Cursor"},{config:{extensionCommand:h,getContent:T,path:O},hooks:{getContent:(b)=>({hooks:{post_write_code:[{command:b,show_output:!0}]}}),path:".windsurf/hooks.json"},id:"windsurf",name:"Windsurf"},{config:{extensionCommand:h,getContent:T,path:O},hooks:{getContent:(b)=>({hooks:{PostToolUse:[{hooks:[{command:b,timeout:20,type:"command"}],matcher:"Write|Edit"}]}}),path:".codebuddy/settings.json"},id:"codebuddy",name:"CodeBuddy"},{config:{extensionCommand:h,getContent:T,path:O},id:"antigravity",name:"Antigravity"},{config:{extensionCommand:h,getContent:T,path:O},id:"bob",name:"IBM Bob"},{config:{extensionCommand:h,getContent:T,path:O},id:"kiro",name:"Kiro"},{config:{extensionCommand:h,getContent:T,path:O},id:"trae",name:"Trae"},{config:{extensionCommand:h,getContent:T,path:O},id:"void",name:"Void"},{config:{getContent:Sy,path:".zed/settings.json"},id:"zed",name:"Zed"}];var Ry=(b)=>Boolean(b.hooks),Iy=(b)=>Boolean(b.hooks),my=()=>P.flatMap((b)=>Ry(b)?[{hooks:b.hooks,id:b.id,name:b.name}]:[]),_y=()=>l.flatMap((b)=>Iy(b)?[{hooks:b.hooks,id:b.id,name:b.name}]:[]),Y1=[...my(),..._y()];import{readFile as Fy}from"node:fs/promises";import{sync as hy}from"cross-spawn";import Oy from"deepmerge";import{parse as Ty}from"jsonc-parser";var F0=(b,y="biome")=>{let $=P.find((v)=>v.id===b);if(!$)throw Error(`Editor "${b}" not found`);let G=$.config.getContent(y);return{create:async()=>{x($.config.path),await Z($.config.path,`${JSON.stringify(G,null,2)}
131
+ `)},exists:()=>H($.config.path),extension:$.config.extensionCommand?(v)=>{let[U,...Q]=$.config.extensionCommand.split(" ");return hy(U,[...Q,v],{stdio:"pipe"})}:void 0,update:async()=>{if(x($.config.path),!H($.config.path)){await Z($.config.path,`${JSON.stringify(G,null,2)}
132
+ `);return}let U=await Fy($.config.path,"utf-8"),W=Ty(U)||{},o=Oy(W,G);await Z($.config.path,`${JSON.stringify(o,null,2)}
133
+ `)}}};var Ey=(b,y)=>{if(y.length>1){let G=y.slice(0,3),v=y.length>G.length?", and more":"";return`Universal (creates ${b} for ${G.join(", ")}${v})`}let[$]=y;return`${$} (creates ${b})`},h0=()=>{let b=new Map;for(let $ of P){let G=b.get($.config.path)??[];G.push($),b.set($.config.path,G)}return[...b.entries()].map(([$,G])=>{let[v]=G,U=G.map((W)=>W.name),Q=G.length>1;return{displayName:Q?"Universal":v.name,editorIds:G.map((W)=>W.id),id:Q?"universal":v.id,path:$,promptLabel:Ey($,U),representativeEditorId:v.id}}).toSorted(($,G)=>{if($.id==="universal")return-1;if(G.id==="universal")return 1;return 0})};import{readFile as cy}from"node:fs/promises";import qy from"deepmerge";import{parse as Py}from"jsonc-parser";import{runScriptCommand as fy}from"nypm";var O0=["npm","yarn","pnpm","bun","deno"],py=(b)=>O0.includes(b),H1=(b)=>{if(py(b))return b;throw Error(`Unsupported package manager "${b}". Supported package managers: ${O0.join(", ")}.`)},T0=(b)=>{let y=H1(b.name);return{...b,command:y,name:y}};var My=(b)=>typeof b==="object"&&b!==null&&!Array.isArray(b),ly=(b,y=[])=>{let $=H1(b),G=$==="npm"&&y.length>0?["--",...y]:y;return fy($,"fix",{args:G})},E0=(b,y,$="biome")=>{let G=Y1.find((B)=>B.id===b);if(!G)throw Error(`Hook integration "${b}" not found`);let U=ly(y,$==="biome"?["--skip=correctness/noUnusedImports"]:[]),Q=G.hooks.getContent(U),W=(B)=>{let K=JSON.stringify(B);return K.includes("ultracite")||K.includes(U)},o=async()=>{if(!H(G.hooks.path)){await Z(G.hooks.path,`${JSON.stringify(Q,null,2)}
134
+ `);return}let K=await cy(G.hooks.path,"utf-8"),N=Py(K),u=My(N)?N:{};if(!W(u)){let R=qy(u,Q);await Z(G.hooks.path,`${JSON.stringify(R,null,2)}
135
+ `)}};return{create:async()=>{x(G.hooks.path),await Z(G.hooks.path,`${JSON.stringify(Q,null,2)}
136
+ `)},exists:()=>H(G.hooks.path),update:async()=>{x(G.hooks.path),await o()}}};import{mkdir as ry,readFile as ny}from"node:fs/promises";import{addDevDependency as ky,dlxCommand as o1}from"nypm";var p0=(b)=>`#!/bin/sh
137
137
  ${b}
138
- `,Y1=(b)=>`#!/bin/sh
138
+ `,c0=(b)=>`#!/bin/sh
139
139
  # Check if there are any staged files
140
140
  STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR)
141
141
  if [ -z "$STAGED_FILES" ]; then
@@ -160,18 +160,18 @@ if [ $FORMAT_EXIT_CODE -ne 0 ]; then
160
160
  fi
161
161
 
162
162
  echo "✨ Files formatted by Ultracite"
163
- `,A0="./.husky/pre-commit",q0="# ultracite",E1="# ultracite end",P0=(b)=>`${q0}
164
- ${b}${E1}`,wy=(b,y)=>{let G=b.indexOf(E1,y+1);if(G!==-1)return G+1;let H=b.findIndex((A,$)=>$>y&&A.includes("Files formatted by Ultracite"));if(H!==-1)return H+1;return b.length},t={create:async(b,y=!1)=>{await Ny(".husky",{recursive:!0});let G;if(y){let H=H0(b,"lint-staged",{short:b==="npm"});G=B1(H)}else{let H=H0(b,"ultracite",{args:["fix"],short:b==="npm"});G=Y1(H)}await Q(A0,`${P0(G)}
165
- `)},exists:()=>z(A0),init:(b)=>{let[y,...G]=H0(b,"husky",{args:["init"]}).split(" "),H=V(y,G,{stdio:"pipe"});if(H.error||H.status!==null&&H.status!==0);},install:async(b)=>{await Ly("husky",{corepack:!1,packageManager:b,silent:!0,workspace:F()&&b.name!=="npm"}),await R({scripts:{prepare:"husky"}})},update:async(b,y=!1)=>{let G=await Sy(A0,"utf-8"),H;if(y){let A=H0(b,"lint-staged",{short:b==="npm"});H=B1(A)}else{let A=H0(b,"ultracite",{args:["fix"],short:b==="npm"});H=Y1(A)}if(G.includes(q0)){let A=G.split(`
166
- `),$=A.indexOf(q0),v=wy(A,$),U=A.slice(0,$).join(`
167
- `),X=A.slice(v).join(`
168
- `).replace(/^\n+/u,"").replace(/\n+$/u,""),o=[U,P0(H),X].filter((B)=>B!=="");await Q(A0,`${o.join(`
163
+ `,V1="./.husky/pre-commit",G0="# ultracite",q0="# ultracite end",$0=(b)=>`${G0}
164
+ ${b}${q0}`,sy=(b,y)=>{let $=b.indexOf(q0,y+1);if($!==-1)return $+1;let G=b.findIndex((v,U)=>U>y&&v.includes("Files formatted by Ultracite"));if(G!==-1)return G+1;return b.length},e={create:async(b,y=!1)=>{await ry(".husky",{recursive:!0});let $;if(y){let G=o1(b,"lint-staged",{short:b==="npm"});$=p0(G)}else{let G=o1(b,"ultracite",{args:["fix"],short:b==="npm"});$=c0(G)}await Z(V1,`${$0($)}
165
+ `)},exists:()=>H(V1),init:(b)=>{let[y,...$]=o1(b,"husky",{args:["init"]}).split(" "),G=j(y,$,{stdio:"pipe"});if(G.error||G.status!==null&&G.status!==0);},install:async(b)=>{await ky("husky",{corepack:!1,packageManager:b,silent:!0,workspace:c()&&b.name!=="npm"}),await L({scripts:{prepare:"husky"}})},update:async(b,y=!1)=>{let $=await ny(V1,"utf-8"),G;if(y){let v=o1(b,"lint-staged",{short:b==="npm"});G=p0(v)}else{let v=o1(b,"ultracite",{args:["fix"],short:b==="npm"});G=c0(v)}if($.includes(G0)){let v=$.split(`
166
+ `),U=v.indexOf(G0),Q=sy(v,U),W=v.slice(0,U).join(`
167
+ `),o=v.slice(Q).join(`
168
+ `).replace(/^\n+/u,"").replace(/\n+$/u,""),B=[W,$0(G),o].filter((K)=>K!=="");await Z(V1,`${B.join(`
169
169
  `)}
170
- `)}else{let A=G.replace(/\n+$/u,"");await Q(A0,`${A}
171
- ${P0(H)}
172
- `)}}};import{execSync as Iy}from"node:child_process";import{readFile as uy}from"node:fs/promises";import{addDevDependency as Jy,dlxCommand as D1}from"nypm";var dy=/(?<preCommitJobs>pre-commit:\s*\n\s*jobs:\s*\n)/u,xy=/(?<preCommit>pre-commit:\s*\n)/u,O1=(b)=>D1(b,"ultracite",{args:["fix"],short:b==="npm"}),g="./lefthook.yml",_1=(b)=>`pre-commit:
170
+ `)}else{let v=$.replace(/\n+$/u,"");await Z(V1,`${v}
171
+ ${$0(G)}
172
+ `)}}};import{execSync as Cy}from"node:child_process";import{readFile as iy}from"node:fs/promises";import{addDevDependency as ty,dlxCommand as f0}from"nypm";var gy=/(?<preCommitJobs>pre-commit:\s*\n\s*jobs:\s*\n)/u,ay=/(?<preCommit>pre-commit:\s*\n)/u,M0=(b)=>f0(b,"ultracite",{args:["fix"],short:b==="npm"}),b1="./lefthook.yml",P0=(b)=>`pre-commit:
173
173
  jobs:
174
- - run: ${O1(b)}
174
+ - run: ${M0(b)}
175
175
  glob:
176
176
  - "**/*.js"
177
177
  - "**/*.jsx"
@@ -181,7 +181,7 @@ ${P0(H)}
181
181
  - "**/*.jsonc"
182
182
  - "**/*.css"
183
183
  stage_fixed: true
184
- `,$0={create:async(b)=>{let y=_1(b);await Q(g,y)},exists:()=>z(g),install:async(b)=>{await Jy("lefthook",{corepack:!1,packageManager:b,silent:!0,workspace:F()&&b.name!=="npm"}),await R({scripts:{prepare:"lefthook install"}});let y=D1(b.name,"lefthook",{args:["install"],short:b.name==="npm"});try{Iy(y,{stdio:"pipe"})}catch{}},update:async(b)=>{let y=await uy(g,"utf-8"),G=O1(b),H=_1(b);if(y.includes(G))return;if(y.startsWith("# EXAMPLE USAGE:")){await Q(g,H);return}if(y.includes("pre-commit:")){let $;if(y.includes("jobs:")){let v=` - run: ${G}
184
+ `,B1={create:async(b)=>{let y=P0(b);await Z(b1,y)},exists:()=>H(b1),install:async(b)=>{await ty("lefthook",{corepack:!1,packageManager:b,silent:!0,workspace:c()&&b.name!=="npm"}),await L({scripts:{prepare:"lefthook install"}});let y=f0(b.name,"lefthook",{args:["install"],short:b.name==="npm"});try{Cy(y,{stdio:"pipe"})}catch{}},update:async(b)=>{let y=await iy(b1,"utf-8"),$=M0(b),G=P0(b);if(y.includes($))return;if(y.startsWith("# EXAMPLE USAGE:")){await Z(b1,G);return}if(y.includes("pre-commit:")){let U;if(y.includes("jobs:")){let Q=` - run: ${$}
185
185
  glob:
186
186
  - "**/*.js"
187
187
  - "**/*.jsx"
@@ -190,9 +190,9 @@ ${P0(H)}
190
190
  - "**/*.json"
191
191
  - "**/*.jsonc"
192
192
  - "**/*.css"
193
- stage_fixed: true`;$=y.replace(dy,`$<preCommitJobs>${v}
194
- `)}else{let v=` jobs:
195
- - run: ${G}
193
+ stage_fixed: true`;U=y.replace(gy,`$<preCommitJobs>${Q}
194
+ `)}else{let Q=` jobs:
195
+ - run: ${$}
196
196
  glob:
197
197
  - "**/*.js"
198
198
  - "**/*.jsx"
@@ -201,63 +201,63 @@ ${P0(H)}
201
201
  - "**/*.json"
202
202
  - "**/*.jsonc"
203
203
  - "**/*.css"
204
- stage_fixed: true`;$=y.replace(xy,`$<preCommit>${v}
205
- `)}await Q(g,$)}else await Q(g,`${y}
206
- ${H}`)}};import{readFile as v0}from"node:fs/promises";import{pathToFileURL as S1}from"node:url";import U0 from"deepmerge";import{parse as Fy}from"jsonc-parser";import{addDevDependency as my,dlxCommand as My}from"nypm";import R1 from"yaml";var h=(b)=>({"*.{js,jsx,ts,tsx,json,jsonc,css,scss,md,mdx}":[My(b,"ultracite",{args:["fix"],short:b==="npm"})]}),j1=["./.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"],Q0=(b)=>JSON.stringify(b).includes("ultracite"),N1=async()=>{try{let b=await v0("./package.json","utf-8");return f(b)?.["lint-staged"]}catch{return}},hy=async()=>{try{let b=await v0("./package.json","utf-8");return f(b)?.type==="module"}catch{return!1}},py=async(b)=>{let y=await v0("./package.json","utf-8"),G=f(y);if(!G)return;if(Q0(G["lint-staged"]))return;G["lint-staged"]=G["lint-staged"]?U0(G["lint-staged"],h(b)):h(b),await Q("./package.json",`${JSON.stringify(G,null,2)}
207
- `)},cy=async(b,y)=>{let G=await v0(b,"utf-8"),H=Fy(G);if(!H)return;if(Q0(H))return;let A=U0(H,h(y));await Q(b,`${JSON.stringify(A,null,2)}
208
- `)},Py=(b)=>b.replaceAll(/^(?<key>[*?{[][^\n:]*):(?<rest>.*)$/gmu,(y,G,H)=>`'${G}':${H}`),qy=async(b,y)=>{let G=await v0(b,"utf-8"),H=Py(G),A;try{A=R1.parse(H)}catch{return}if(!A)return;if(Q0(A))return;let $=U0(A,h(y));await Q(b,R1.stringify($))},Cy=async(b,y)=>{let A=(await import(S1(b).href)).default||{};if(Q0(A))return;let $=U0(A,h(y)),v=`export default ${JSON.stringify($,null,2)};
209
- `;await Q(b,v)},fy=async(b,y)=>{let H=await import(`${S1(b).href}?t=${Date.now()}`),A=H.default||H;if(Q0(A))return;let $=U0(A,h(y)),v=`module.exports = ${JSON.stringify($,null,2)};
210
- `;await Q(b,v)},C0=async(b)=>{await Q(".lintstagedrc.json",`${JSON.stringify(h(b),null,2)}
211
- `)},ly=async(b,y)=>{if(b.endsWith(".json")||b==="./.lintstagedrc"){await cy(b,y);return}if(b.endsWith(".yaml")||b.endsWith(".yml")){await qy(b,y);return}let G=await hy();if(b.endsWith(".mjs")||b.endsWith(".js")&&G){try{await Cy(b,y)}catch{await C0(y)}return}if(b.endsWith(".cjs")||b.endsWith(".js")&&!G)try{await fy(b,y)}catch{await C0(y)}},W0={create:async(b)=>{await Q(".lintstagedrc.json",`${JSON.stringify(h(b),null,2)}
212
- `)},exists:async()=>{if(await N1())return!0;return j1.some((b)=>z(b))},install:async(b)=>{await my("lint-staged",{corepack:!1,packageManager:b,silent:!0,workspace:F()&&b.name!=="npm"})},update:async(b)=>{if(await N1()){await py(b);return}let y=j1.find((G)=>z(G));if(!y){await C0(b);return}await ly(y,b)}};import{readFile as ry}from"node:fs/promises";import{dlxCommand as ky}from"nypm";var Z0="./.pre-commit-config.yaml",ny=/^repos:\s*\n/mu,L1=(b)=>ky(b,"ultracite",{args:["fix"],short:b==="npm"}),sy=(b)=>`repos:
204
+ stage_fixed: true`;U=y.replace(ay,`$<preCommit>${Q}
205
+ `)}await Z(b1,U)}else await Z(b1,`${y}
206
+ ${G}`)}};import{readFile as X1}from"node:fs/promises";import{pathToFileURL as k0}from"node:url";import j1 from"deepmerge";import{parse as ey}from"jsonc-parser";import{addDevDependency as b2,dlxCommand as y2}from"nypm";import l0 from"yaml";var O1="./package.json",f=(b)=>({"*.{js,jsx,ts,tsx,json,jsonc,css,scss,md,mdx}":[y2(b,"ultracite",{args:["fix"],short:b==="npm"})]}),r0=["./.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"],K1=(b)=>JSON.stringify(b).includes("ultracite"),n0=async()=>{try{let b=await X1(O1,"utf-8");return k(b)?.["lint-staged"]}catch{return}},$2=async()=>{try{let b=await X1(O1,"utf-8");return k(b)?.type==="module"}catch{return!1}},G2=async(b)=>{let y=await X1(O1,"utf-8"),$=k(y);if(!$)return;if(K1($["lint-staged"]))return;$["lint-staged"]=$["lint-staged"]?j1($["lint-staged"],f(b)):f(b),await Z(O1,`${JSON.stringify($,null,2)}
207
+ `)},v2=async(b,y)=>{let $=await X1(b,"utf-8"),G=ey($);if(!G)return;if(K1(G))return;let v=j1(G,f(y));await Z(b,`${JSON.stringify(v,null,2)}
208
+ `)},U2=(b)=>b.replaceAll(/^(?<key>[*?{[][^\n:]*):(?<rest>.*)$/gmu,(y,$,G)=>`'${$}':${G}`),Q2=async(b,y)=>{let $=await X1(b,"utf-8"),G=U2($),v;try{v=l0.parse(G)}catch{return}if(!v)return;if(K1(v))return;let U=j1(v,f(y));await Z(b,l0.stringify(U))},W2=async(b,y)=>{let v=(await import(k0(b).href)).default||{};if(K1(v))return;let U=j1(v,f(y)),Q=`export default ${JSON.stringify(U,null,2)};
209
+ `;await Z(b,Q)},Z2=async(b,y)=>{let G=await import(`${k0(b).href}?t=${Date.now()}`),v=G.default||G;if(K1(v))return;let U=j1(v,f(y)),Q=`module.exports = ${JSON.stringify(U,null,2)};
210
+ `;await Z(b,Q)},v0=async(b)=>{await Z(".lintstagedrc.json",`${JSON.stringify(f(b),null,2)}
211
+ `)},z2=async(b,y)=>{if(b.endsWith(".json")||b==="./.lintstagedrc"){await v2(b,y);return}if(b.endsWith(".yaml")||b.endsWith(".yml")){await Q2(b,y);return}let $=await $2();if(b.endsWith(".mjs")||b.endsWith(".js")&&$){try{await W2(b,y)}catch{await v0(y)}return}if(b.endsWith(".cjs")||b.endsWith(".js")&&!$)try{await Z2(b,y)}catch{await v0(y)}},A1={create:async(b)=>{await Z(".lintstagedrc.json",`${JSON.stringify(f(b),null,2)}
212
+ `)},exists:async()=>{if(await n0())return!0;return r0.some((b)=>H(b))},install:async(b)=>{await b2("lint-staged",{corepack:!1,packageManager:b,silent:!0,workspace:c()&&b.name!=="npm"})},update:async(b)=>{if(await n0()){await G2(b);return}let y=r0.find(($)=>H($));if(!y){await v0(b);return}await z2(y,b)}};import{readFile as Y2}from"node:fs/promises";import{dlxCommand as H2}from"nypm";var w1="./.pre-commit-config.yaml",o2=/^repos:\s*\n/mu,s0=(b)=>H2(b,"ultracite",{args:["fix"],short:b==="npm"}),V2=(b)=>`repos:
213
213
  - repo: local
214
214
  hooks:
215
215
  - id: ultracite
216
216
  name: ultracite
217
- entry: ${L1(b)}
217
+ entry: ${s0(b)}
218
218
  language: system
219
219
  types_or: [javascript, jsx, ts, tsx, json, css]
220
220
  pass_filenames: false
221
- `,R0={create:async(b)=>{let y=sy(b);await Q(Z0,y)},exists:()=>z(Z0),update:async(b)=>{let y=await ry(Z0,"utf-8"),G=L1(b);if(y.includes("id: ultracite"))return;let H=` - repo: local
221
+ `,T1={create:async(b)=>{let y=V2(b);await Z(w1,y)},exists:()=>H(w1),update:async(b)=>{let y=await Y2(w1,"utf-8"),$=s0(b);if(y.includes("id: ultracite"))return;let G=` - repo: local
222
222
  hooks:
223
223
  - id: ultracite
224
224
  name: ultracite
225
- entry: ${G}
225
+ entry: ${$}
226
226
  language: system
227
227
  types_or: [javascript, jsx, ts, tsx, json, css]
228
228
  pass_filenames: false
229
- `;if(y.includes("repos:")){let A=y.replace(ny,`repos:
230
- ${H}`);await Q(Z0,A)}else await Q(Z0,`${y}
229
+ `;if(y.includes("repos:")){let v=y.replace(o2,`repos:
230
+ ${G}`);await Z(w1,v)}else await Z(w1,`${y}
231
231
  repos:
232
- ${H}`)}};import{readFile as iy}from"node:fs/promises";import ty from"deepmerge";var w1={$schema:"./node_modules/@biomejs/biome/configuration_schema.json",extends:["ultracite/biome/core"]},gy=/^ultracite\/(?!biome\/)(?<rest>.+)$/u,f0=()=>{for(let b of m)if(z(`./${b}`))return`./${b}`;return"./biome.jsonc"},j0={create:(b)=>{let y=f0(),G=["ultracite/biome/core"];if(b?.typeAware)G.push("ultracite/biome/type-aware");if(b?.frameworks&&b.frameworks.length>0)for(let A of b.frameworks){let $=N(A);G.push(`ultracite/biome/${$}`)}let H={...w1,extends:G};return Q(y,`${JSON.stringify(H,null,2)}
233
- `)},exists:()=>{let b=f0();return z(b)},update:async(b)=>{let y=f0(),G=await iy(y,"utf-8"),A=B0(G,g0)||{},v=(A.extends??[]).map((E)=>{let S=gy.exec(E);return S?`ultracite/biome/${S[1]}`:E}),U=[...new Set(v)],X=new Set(U),o=(E)=>{if(!X.has(E))X.add(E),U.push(E)};if(o("ultracite/biome/core"),b?.typeAware)o("ultracite/biome/type-aware");if(b?.frameworks&&b.frameworks.length>0)for(let E of b.frameworks)o(`ultracite/biome/${N(E)}`);A.extends=U;let B={$schema:w1.$schema},O=ty(A,B);await Q(y,`${JSON.stringify(O,null,2)}
234
- `)}};var ay=p.map((b)=>`./${b}`),I1="./eslint.config.mjs",u1=()=>{for(let b of ay)if(z(b))return b;return null},J1=(b)=>{let y=['import core from "ultracite/eslint/core";'],G=["...core"];if(b?.frameworks&&b.frameworks.length>0)for(let H of b.frameworks){let A=N(H);y.push(`import ${A} from "ultracite/eslint/${A}";`),G.push(`...${A}`)}return`${y.join(`
232
+ ${G}`)}};import{readFile as B2}from"node:fs/promises";import X2 from"deepmerge";var Q0="ultracite/biome/core",C0={$schema:"./node_modules/@biomejs/biome/configuration_schema.json",extends:[Q0]},j2=/^ultracite\/(?!biome\/)(?<rest>.+)$/u,U0=()=>{for(let b of q)if(H(`./${b}`))return`./${b}`;return"./biome.jsonc"},E1={create:(b)=>{let y=U0(),$=[Q0];if(b?.typeAware)$.push("ultracite/biome/type-aware");if(b?.frameworks&&b.frameworks.length>0)for(let v of b.frameworks){let U=S(v);$.push(`ultracite/biome/${U}`)}let G={...C0,extends:$};return Z(y,`${JSON.stringify(G,null,2)}
233
+ `)},exists:()=>{let b=U0();return H(b)},update:async(b)=>{let y=U0(),$=await B2(y,"utf-8"),v=S1($,K0)||{},Q=(v.extends??[]).map((u)=>{let R=j2.exec(u);return R?`ultracite/biome/${R[1]}`:u}),W=[...new Set(Q)],o=new Set(W),B=(u)=>{if(!o.has(u))o.add(u),W.push(u)};if(B(Q0),b?.typeAware)B("ultracite/biome/type-aware");if(b?.frameworks&&b.frameworks.length>0)for(let u of b.frameworks)B(`ultracite/biome/${S(u)}`);v.extends=W;let K={$schema:C0.$schema},N=X2(v,K);await Z(y,`${JSON.stringify(N,null,2)}
234
+ `)}};var K2=M.map((b)=>`./${b}`),i0="./eslint.config.mjs",t0=()=>{for(let b of K2)if(H(b))return b;return null},g0=(b)=>{let y=['import core from "ultracite/eslint/core";'],$=["...core"];if(b?.frameworks&&b.frameworks.length>0)for(let G of b.frameworks){let v=S(G);y.push(`import ${v} from "ultracite/eslint/${v}";`),$.push(`...${v}`)}return`${y.join(`
235
235
  `)}
236
236
 
237
237
  export default [
238
- ${G.join(`,
238
+ ${$.join(`,
239
239
  `)},
240
240
  ];
241
- `},N0={create:async(b)=>{let y=J1(b);await Q(I1,y)},exists:()=>{return u1()!==null},update:async(b)=>{let y=J1(b);await Q(u1()??I1,y)}};var l0="./oxfmt.config.ts",d1=`import { defineConfig } from "oxfmt";
241
+ `},p1={create:async(b)=>{let y=g0(b);await Z(i0,y)},exists:()=>{return t0()!==null},update:async(b)=>{let y=g0(b);await Z(t0()??i0,y)}};var W0="./oxfmt.config.ts",a0=`import { defineConfig } from "oxfmt";
242
242
  import ultracite from "ultracite/oxfmt";
243
243
 
244
244
  export default defineConfig({
245
245
  ...ultracite,
246
246
  });
247
- `,S0={create:async()=>await Q(l0,d1),exists:()=>z(l0),update:async()=>await Q(l0,d1)};import{readFile as ey}from"node:fs/promises";var L0="./oxlint.config.ts",P=(b)=>`ultracite/oxlint/${b}`,x1=(b)=>{let y=b.split("/").pop()??b;return y==="core"?"core":y},F1=(b)=>{let y=['import { defineConfig } from "oxlint";',...b.map((H)=>`import ${x1(H)} from "${H}";`)].join(`
248
- `),G=b.map((H)=>x1(H)).join(", ");return`${y}
247
+ `,c1={create:async()=>await Z(W0,a0),exists:()=>H(W0),update:async()=>await Z(W0,a0)};import{readFile as A2}from"node:fs/promises";var q1="./oxlint.config.ts",u1=(b)=>`ultracite/oxlint/${b}`,e0=(b)=>{let y=b.split("/").pop()??b;return y==="core"?"core":y},bb=(b)=>{let y=['import { defineConfig } from "oxlint";',...b.map((G)=>`import ${e0(G)} from "${G}";`)].join(`
248
+ `),$=b.map((G)=>e0(G)).join(", ");return`${y}
249
249
 
250
250
  export default defineConfig({
251
- extends: [${G}],
251
+ extends: [${$}],
252
252
  ignorePatterns: core.ignorePatterns,
253
253
  });
254
- `},m1=["github","sonarjs"],w0={create:async(b)=>{let y=[P("core"),...m1.map(P)];if(b?.frameworks&&b.frameworks.length>0)for(let G of b.frameworks){let H=N(G);y.push(P(H))}return await Q(L0,F1(y))},exists:()=>z(L0),update:async(b)=>{let y=await ey(L0,"utf-8"),G=[],H=y.matchAll(/import \w+ from ["'](?<source>[^"']+)["']/gu);for(let v of H)if(v[1].startsWith("ultracite/oxlint/"))G.push(v[1].replace(/\/index\.[tj]s$/u,""));if(G.length===0){let v=y.match(/extends:\s*\[(?<body>[\s\S]*?)\]/u);if(v?.[1]){let U=v[1].matchAll(/"(?<value>[^"]+)"/gu);for(let X of U){let o=X[1].replace(/^\.\/node_modules\/ultracite\/config\/oxlint\//u,"ultracite/oxlint/");G.push(o)}}}if(G.length===0&&y.includes("ultracite/oxlint"))console.warn("Warning: could not parse existing extends from oxlint.config.ts. The file will be regenerated.");let A=(v)=>G.some((U)=>U===P(v)),$=[...G];if(!A("core"))$.push(P("core"));for(let v of m1)if(!A(v))$.push(P(v));if(b?.frameworks&&b.frameworks.length>0)for(let v of b.frameworks){let U=N(v);if(!A(U))$.push(P(U))}await Q(L0,F1($))}};var bG=r.map((b)=>`./${b}`),r0="./prettier.config.mjs",yG=()=>{return x("./package.json")?.prettier!==void 0},M1=()=>{if(yG())return"./package.json";for(let b of bG)if(z(b))return b;return null},h1={astro:"prettier-plugin-astro",svelte:"prettier-plugin-svelte"},p1=(b)=>{let y=[];if(b?.frameworks)for(let G of b.frameworks){let H=N(G);if(H in h1)y.push(h1[H])}return y.push("prettier-plugin-tailwindcss"),`import config from "ultracite/prettier";
254
+ `},P1={create:async(b)=>{let y=[u1("core")];if(b?.frameworks&&b.frameworks.length>0)for(let $ of b.frameworks){let G=S($);y.push(u1(G))}return await Z(q1,bb(y))},exists:()=>H(q1),update:async(b)=>{let y=await A2(q1,"utf-8"),$=[],G=y.matchAll(/import \w+ from ["'](?<source>[^"']+)["']/gu);for(let Q of G)if(Q[1].startsWith("ultracite/oxlint/"))$.push(Q[1].replace(/\/index\.[tj]s$/u,""));if($.length===0){let Q=y.match(/extends:\s*\[(?<body>[\s\S]*?)\]/u);if(Q?.[1]){let W=Q[1].matchAll(/"(?<value>[^"]+)"/gu);for(let o of W){let B=o[1].replace(/^\.\/node_modules\/ultracite\/config\/oxlint\//u,"ultracite/oxlint/");$.push(B)}}}if($.length===0&&y.includes("ultracite/oxlint"))console.warn("Warning: could not parse existing extends from oxlint.config.ts. The file will be regenerated.");let v=(Q)=>$.some((W)=>W===u1(Q)),U=[...$];if(!v("core"))U.push(u1("core"));if(b?.frameworks&&b.frameworks.length>0)for(let Q of b.frameworks){let W=S(Q);if(!v(W))U.push(u1(W))}await Z(q1,bb(U))}};var z0="./package.json",w2=C.map((b)=>`./${b}`),Z0="./prettier.config.mjs",u2=()=>{return p(z0)?.prettier!==void 0},yb=()=>{if(u2())return z0;for(let b of w2)if(H(b))return b;return null},$b={astro:"prettier-plugin-astro",svelte:"prettier-plugin-svelte"},Gb=(b)=>{let y=[];if(b?.frameworks)for(let $ of b.frameworks){let G=S($);if(G in $b)y.push($b[G])}return y.push("prettier-plugin-tailwindcss"),`import config from "ultracite/prettier";
255
255
 
256
256
  export default {
257
257
  ...config,
258
- plugins: [${y.map((G)=>`"${G}"`).join(", ")}],
258
+ plugins: [${y.map(($)=>`"${$}"`).join(", ")}],
259
259
  };
260
- `},I0={create:async(b)=>{let y=p1(b);await Q(r0,y)},exists:()=>{return M1()!==null},update:async(b)=>{let y=p1(b),G=M1();await Q(G==="./package.json"?r0:G??r0,y)}};var GG=k.map((b)=>`./${b}`),k0="./stylelint.config.mjs",HG=()=>{return x("./package.json")?.stylelint!==void 0},c1=()=>{if(HG())return"./package.json";for(let b of GG)if(z(b))return b;return null},P1=()=>`export { default } from "ultracite/stylelint";
261
- `,u0={create:async()=>{let b=P1();await Q(k0,b)},exists:()=>{return c1()!==null},update:async()=>{let b=P1(),y=c1();await Q(y==="./package.json"?k0:y??k0,b)}};import{isCancel as AG,select as $G,spinner as vG}from"@clack/prompts";import{dlxCommand as C1}from"nypm";var UG="haydenbleasel/ultracite",QG="ultracite",f1=(b)=>C1(b,"skills",{args:["add",UG],short:b==="npm"}),WG=(b,y=!1)=>C1(b,"skills",{args:y?["list","-g","--json"]:["list","--json"],short:b==="npm"}),q1=(b,y=!1)=>{let G=WG(b,y),[H,...A]=G.split(" "),$=V(H,A,{encoding:"utf-8",stdio:"pipe"});if($.error||$.status!==0||!$.stdout)return!1;try{return JSON.parse(typeof $.stdout==="string"?$.stdout:$.stdout.toString("utf-8")).some((U)=>U.name===QG)}catch{return!1}},ZG=(b)=>q1(b)||q1(b,!0),zG=async()=>{let b=await $G({message:"Do you want to install the Ultracite skill?",options:[{label:"Yes, install it",value:"install"},{label:"No, I'll do it later",value:"skip"}]});return!AG(b)&&b==="install"},l1=(b)=>f1(b),r1=async({packageManager:b,quiet:y=!1,shouldInstall:G})=>{if(G===void 0&&!y&&ZG(b))return!0;if(!(G??(!y&&await zG())))return!1;let A=f1(b),[$,...v]=A.split(" "),U=vG();if(!y)U.start("Installing the Ultracite skill...");let X=V($,v,{stdio:"pipe"}),o=!X.error&&X.status===0;if(!y)U.stop(o?"Ultracite skill installed.":"Couldn't install the Ultracite skill automatically.");return o};import{readFile as XG}from"node:fs/promises";import{log as TG}from"@clack/prompts";import{glob as oG}from"glob";import{applyEdits as KG,modify as VG}from"jsonc-parser";var k1=async()=>{try{return await oG("**/tsconfig*.json",{absolute:!1,ignore:["**/node_modules/**","**/dist/**","**/build/**","**/.next/**"]})}catch{return[]}},BG=(b)=>{if(!b?.compilerOptions)return!1;if(b.compilerOptions.strict===!0)return!0;return b.compilerOptions.strictNullChecks===!0},YG=async(b)=>{try{let y=await XG(b,"utf-8"),G=B0(y,a0);if(BG(G))return;if(G===void 0){await Q(b,`${JSON.stringify({compilerOptions:{strictNullChecks:!0}},null,2)}
262
- `);return}let A=VG(y,["compilerOptions","strictNullChecks"],!0,{formattingOptions:{insertSpaces:!0,tabSize:2}}),$=KG(y,A);await Q(b,$)}catch(y){TG.warn(`Failed to update ${b}: ${y instanceof Error?y.message:y}`)}},n0={exists:async()=>{return(await k1()).length>0},update:async()=>{let b=await k1();if(b.length===0)return;await Promise.all(b.map((y)=>YG(y)))}};var i1=W.devDependencies["@biomejs/biome"],s0=W.version,n1="^10.0.0",t1={"@eslint/js":n1,"@typescript-eslint/eslint-plugin":W.devDependencies["@typescript-eslint/eslint-plugin"],"@typescript-eslint/parser":W.devDependencies["@typescript-eslint/parser"],eslint:n1,"eslint-config-prettier":W.devDependencies["eslint-config-prettier"],"eslint-import-resolver-typescript":W.devDependencies["eslint-import-resolver-typescript"],"eslint-plugin-compat":W.devDependencies["eslint-plugin-compat"],"eslint-plugin-cypress":W.devDependencies["eslint-plugin-cypress"],"eslint-plugin-github":W.devDependencies["eslint-plugin-github"],"eslint-plugin-html":W.devDependencies["eslint-plugin-html"],"eslint-plugin-import-x":W.devDependencies["eslint-plugin-import-x"],"eslint-plugin-jsdoc":W.devDependencies["eslint-plugin-jsdoc"],"eslint-plugin-n":W.devDependencies["eslint-plugin-n"],"eslint-plugin-prettier":W.devDependencies["eslint-plugin-prettier"],"eslint-plugin-promise":W.devDependencies["eslint-plugin-promise"],"eslint-plugin-sonarjs":W.devDependencies["eslint-plugin-sonarjs"],"eslint-plugin-storybook":W.devDependencies["eslint-plugin-storybook"],"eslint-plugin-unicorn":W.devDependencies["eslint-plugin-unicorn"],"eslint-plugin-unused-imports":W.devDependencies["eslint-plugin-unused-imports"],globals:W.devDependencies.globals,prettier:"latest","prettier-plugin-tailwindcss":W.devDependencies["prettier-plugin-tailwindcss"],stylelint:"latest"},g1={angular:{"@angular-eslint/eslint-plugin":"latest"},astro:{"eslint-plugin-astro":W.devDependencies["eslint-plugin-astro"],"prettier-plugin-astro":W.devDependencies["prettier-plugin-astro"]},jest:{"eslint-plugin-jest":W.devDependencies["eslint-plugin-jest"]},next:{"@next/eslint-plugin-next":W.devDependencies["@next/eslint-plugin-next"],"eslint-plugin-react-doctor":W.devDependencies["eslint-plugin-react-doctor"]},qwik:{"eslint-plugin-qwik":W.devDependencies["eslint-plugin-qwik"]},react:{"eslint-plugin-jsx-a11y":W.devDependencies["eslint-plugin-jsx-a11y"],"eslint-plugin-react":W.devDependencies["eslint-plugin-react"],"eslint-plugin-react-doctor":W.devDependencies["eslint-plugin-react-doctor"],"eslint-plugin-react-hooks":W.devDependencies["eslint-plugin-react-hooks"]},remix:{"eslint-plugin-remix":W.devDependencies["eslint-plugin-remix"]},solid:{"eslint-plugin-solid":W.devDependencies["eslint-plugin-solid"]},svelte:{"eslint-plugin-svelte":W.devDependencies["eslint-plugin-svelte"],"prettier-plugin-svelte":W.devDependencies["prettier-plugin-svelte"]},tanstack:{"@tanstack/eslint-plugin-query":W.devDependencies["@tanstack/eslint-plugin-query"],"@tanstack/eslint-plugin-router":W.devDependencies["@tanstack/eslint-plugin-router"],"@tanstack/eslint-plugin-start":W.devDependencies["@tanstack/eslint-plugin-start"],"eslint-plugin-react-doctor":W.devDependencies["eslint-plugin-react-doctor"]},vitest:{"@vitest/eslint-plugin":W.devDependencies["@vitest/eslint-plugin"]},vue:{"eslint-plugin-vue":W.devDependencies["eslint-plugin-vue"]}},a1=(b)=>{let y={...t1};for(let G of b)Object.assign(y,g1[G]);return y},i0={"eslint-plugin-github":W.devDependencies["eslint-plugin-github"],"eslint-plugin-sonarjs":W.devDependencies["eslint-plugin-sonarjs"]},jG={next:{"oxlint-plugin-react-doctor":W.devDependencies["oxlint-plugin-react-doctor"]},react:{"oxlint-plugin-react-doctor":W.devDependencies["oxlint-plugin-react-doctor"]},tanstack:{"oxlint-plugin-react-doctor":W.devDependencies["oxlint-plugin-react-doctor"]}},e1=(b)=>{let y={};for(let G of b)Object.assign(y,jG[G]);return y},NG=(b,y,G)=>{let H={ultracite:s0};if(b==="biome")H["@biomejs/biome"]=i1;if(b==="eslint")Object.assign(H,a1(G));if(b==="oxlint"){if(H.oxlint="latest",H.oxfmt="latest",y)H["oxlint-tsgolint"]="latest";Object.assign(H,i0,e1(G))}return H},SG=new Set([...Object.keys(t1),...Object.values(g1).flatMap((b)=>Object.keys(b??{}))]),s1={biome:new Set(["@biomejs/biome"]),eslint:SG,oxlint:new Set(["oxfmt","oxlint","oxlint-plugin-react-doctor","oxlint-tsgolint",...Object.keys(i0)])},LG=async(b)=>{let y=b.startsWith("./")?b:`./${b}`;if(!z(y))return!1;let{rm:G}=await import("node:fs/promises");return await G(y,{force:!0}),!0},wG=async(b)=>{let y=await l();if(!y)return!1;let G=new Set;for(let[$,v]of Object.entries(s1))if($!==b)for(let U of v)G.add(U);for(let $ of s1[b])G.delete($);let H=!1,A={...y};for(let $ of["dependencies","devDependencies","peerDependencies"]){let v=A[$];if(!v)continue;let U=Object.entries(v),X=U.filter(([B])=>!G.has(B));if(X.length!==U.length)H=!0;let o=Object.fromEntries(X);A[$]=o}if("prettier"in A)delete A.prettier,H=!0;if("stylelint"in A)delete A.stylelint,H=!0;if(!H)return!1;return await Q("package.json",`${JSON.stringify(A,null,2)}
263
- `),!0},IG=async(b,y=!1)=>{let G=Y();if(!y)G.start("Checking for stale linter configuration...");let H=new Set;if(b!=="biome")for(let U of m)H.add(U);if(b!=="eslint"){for(let U of p)H.add(U);for(let U of r)H.add(U);for(let U of k)H.add(U)}for(let U of H1)H.add(U);if(b!=="oxlint"){for(let U of p0)H.add(U);for(let U of A1)H.add(U)}let[A,$]=await Promise.all([Promise.all([...H].map((U)=>LG(U))),wG(b)]),v=A.some(Boolean)||$;if(!y)G.stop(v?"Stale linter configuration migrated.":"No stale linter configuration found.")},uG=async(b,y="biome",G=!0,H=!1,A=!1,$=["react"])=>{let v=Y();if(!H)v.start("Installing dependencies...");let U=[`ultracite@${s0}`];if(y==="biome")U.push(`@biomejs/biome@${i1}`);if(y==="eslint")U.push(...Object.entries(a1($)).map(([o,B])=>`${o}@${B}`));if(y==="oxlint"){if(U.push("oxlint@latest","oxfmt@latest",...Object.entries(i0).map(([o,B])=>`${o}@${B}`),...Object.entries(e1($)).map(([o,B])=>`${o}@${B}`)),A)U.push("oxlint-tsgolint@latest")}let X={check:"ultracite check",fix:"ultracite fix"};if(G)await OG(U,{corepack:!1,packageManager:b,silent:!0,workspace:F()&&b.name!=="npm"}),await R({scripts:X});else{let o=NG(y,A,$);await R({devDependencies:o,scripts:X})}if(!H)v.stop("Dependencies installed.")},JG=async(b=!1)=>{let y=Y();if(!b)y.start("Checking for tsconfig.json files...");if(await n0.exists()){if(!b)y.message("Found tsconfig.json files, updating with strictNullChecks...");if(await n0.update(),!b)y.stop("tsconfig.json files updated.");return}if(!b)y.stop("No tsconfig.json files found, skipping.")},bb=async(b,y="biome",G=!1)=>{let H=M.find((v)=>v.id===b);if(!H)throw Error(`Editor "${b}" not found`);let A=X1(b,y),$=Y();if(!G)$.start(`Checking for ${H.config.path}...`);if(await A.exists()){if(!G)$.message(`${H.config.path} found, updating...`);if(await A.update(),!G)$.stop(`${H.config.path} updated.`);return}if(!G)$.message(`${H.config.path} not found, creating...`);if(await A.create(),A.extension){let v=_0.find((U)=>U.id===y)?.vscodeExtensionId;if(!v)throw Error(`Linter extension not found for ${y}`);if(!G)$.message(`Installing ${v} extension...`);try{if(A.extension(v).status===0){if(!G)$.stop(`${H.config.path} created and ${v} extension installed.`);return}}catch{}if(!G)$.stop(`${H.config.path} created. Install ${v} extension manually.`);return}if(!G)if(b==="zed")$.stop(`${H.config.path} created. Install the Biome extension: https://biomejs.dev/reference/zed/`);else $.stop(`${H.config.path} created.`)},dG=async(b,y=!1,G=!1)=>{let H=Y();if(!y)H.start("Checking for Biome configuration...");if(await j0.exists()){if(!y)H.message("Biome configuration found, updating...");if(await j0.update({frameworks:b,typeAware:G}),!y)H.stop("Biome configuration updated.");return}if(!y)H.message("Biome configuration not found, creating...");if(await j0.create({frameworks:b,typeAware:G}),!y)H.stop("Biome configuration created.")},xG=async(b,y=!1)=>{let G=Y();if(!y)G.start("Checking for ESLint configuration...");if(await N0.exists()){if(!y)G.message("ESLint configuration found, updating...");if(await N0.update({frameworks:b}),!y)G.stop("ESLint configuration updated.");return}if(!y)G.message("ESLint configuration not found, creating...");if(await N0.create({frameworks:b}),!y)G.stop("ESLint configuration created.")},FG=async(b,y=!1)=>{let G=Y();if(!y)G.start("Checking for Oxlint configuration...");if(await w0.exists()){if(!y)G.message("Oxlint configuration found, updating...");if(await w0.update({frameworks:b}),!y)G.stop("Oxlint configuration updated.");return}if(!y)G.message("Oxlint configuration not found, creating...");if(await w0.create({frameworks:b}),!y)G.stop("Oxlint configuration created.")},mG=async(b,y=!1)=>{let G=Y();if(!y)G.start("Checking for Prettier configuration...");if(await I0.exists()){if(!y)G.message("Prettier configuration found, updating...");if(await I0.update({frameworks:b}),!y)G.stop("Prettier configuration updated.");return}if(!y)G.message("Prettier configuration not found, creating...");if(await I0.create({frameworks:b}),!y)G.stop("Prettier configuration created.")},MG=async(b=!1)=>{let y=Y();if(!b)y.start("Checking for Stylelint configuration...");if(await u0.exists()){if(!b)y.message("Stylelint configuration found, updating...");if(await u0.update(),!b)y.stop("Stylelint configuration updated.");return}if(!b)y.message("Stylelint configuration not found, creating...");if(await u0.create(),!b)y.stop("Stylelint configuration created.")},hG=async(b=!1)=>{let y=Y();if(!b)y.start("Checking for oxfmt configuration...");if(await S0.exists()){if(!b)y.message("oxfmt configuration found, updating...");if(await S0.update(),!b)y.stop("oxfmt configuration updated.");return}if(!b)y.message("oxfmt configuration not found, creating...");if(await S0.create(),!b)y.stop("oxfmt configuration created.")},pG=async(b,y=!0,G=!1,H=!1)=>{let A=Y();if(!G)A.start("Initializing pre-commit hooks..."),A.message("Installing Husky...");if(await(y?t.install(b):R({devDependencies:{husky:"latest"},scripts:{prepare:"husky"}})),!G)A.message("Initializing Husky...");if(t.init(b.name),await t.exists()){if(!G)A.message("Pre-commit hook found, updating...");if(await t.update(b.name,H),!G)A.stop("Pre-commit hook updated.");return}if(!G)A.message("Pre-commit hook not found, creating...");if(await t.create(b.name,H),!G)A.stop("Pre-commit hook created.")},cG=async(b,y=!0,G=!1)=>{let H=Y();if(!G)H.start("Initializing lefthook..."),H.message("Installing lefthook...");if(await(y?$0.install(b):R({devDependencies:{lefthook:"latest"}})),await $0.exists()){if(!G)H.message("lefthook.yml found, updating...");if(await $0.update(b.name),!G)H.stop("lefthook.yml updated.");return}if(!G)H.message("lefthook.yml not found, creating...");if(await $0.create(b.name),!G)H.stop("lefthook.yml created.")},PG=async(b,y=!0,G=!1)=>{let H=Y();if(!G)H.start("Initializing lint-staged..."),H.message("Installing lint-staged...");if(await(y?W0.install(b):R({devDependencies:{"lint-staged":"latest"}})),await W0.exists()){if(!G)H.message("lint-staged found, updating...");if(await W0.update(b.name),!G)H.stop("lint-staged updated.");return}if(!G)H.message("lint-staged not found, creating...");if(await W0.create(b.name),!G)H.stop("lint-staged created.")},qG=async(b,y=!1)=>{let G=Y();if(!y)G.start("Initializing pre-commit...");if(await R0.exists()){if(!y)G.message(".pre-commit-config.yaml found, updating...");if(await R0.update(b),!y)G.stop(".pre-commit-config.yaml updated.");return}if(!y)G.message(".pre-commit-config.yaml not found, creating...");if(await R0.create(b),!y)G.stop(".pre-commit-config.yaml created.")},yb=async(b,y,G,H,A=!1)=>{let $=Y();if(!A)$.start(`Checking for ${y}...`);let v=z1(b,G,H);if(await v.exists()){if(!A)$.message(`${y} found, updating...`);if(await v.update(),!A)$.stop(`${y} updated.`);return}if(!A)$.message(`${y} not found, creating...`);if(await v.create(),!A)$.stop(`${y} created.`)},CG=async(b,y,G,H=!1)=>{let A=`${b.displayName} (${b.path})`;await yb(b.representativeAgentId,A,y,G,H)},fG=async(b,y="biome",G=!1)=>{await bb(b.representativeEditorId,y,G)},lG=async(b,y,G="biome",H=!1)=>{let A=Y(),$=y0.find((U)=>U.id===b)?.name??b;if(!H)A.start(`Checking for ${$} hooks...`);let v=V1(b,y,G);if(await v.exists()){if(!H)A.message(`${$} hooks found, updating...`);if(await v.update(),!H)A.stop(`${$} hooks updated.`);return}if(!H)A.message(`${$} hooks not found, creating...`);if(await v.create(),!H)A.stop(`${$} hooks created.`)},Gb=async(b)=>{let y=b??{},G=y.quiet??!1;if(!G)_G(`Ultracite v${s0} Initialization`);try{let H,A;if(y.pm)H=G0(y.pm),A={command:H,name:H};else{let Z=await RG(EG.cwd());if(!Z)throw Error("No package manager specified or detected");if(!G&&Z.warnings)for(let K of Z.warnings)z0.warn(K);if(!G)z0.info(`Detected lockfile, using ${Z.name}`);A=K1(Z),H=A.name}let{linter:$}=y;if($===void 0)if(G||y.pm||y.editors||y.agents||y.hooks||y.integrations!==void 0||y.frameworks!==void 0)$="biome";else{let K=await DG({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(e(K)){a("Operation cancelled.");return}$=K}let{frameworks:v}=y;if(v===void 0)if(G||y.pm||y.editors||y.agents||y.hooks||y.integrations!==void 0)v=[];else{let K=await $1(),o0=await X0({initialValues: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 / React Router (file-route conventions)",value:"remix"},{label:"TanStack (Query, Router, Start)",value:"tanstack"},{label:"Astro",value:"astro"},{label:"NestJS",value:"nestjs"},{label:"Jest",value:"jest"},{label:"Vitest / Bun",value:"vitest"}],required:!1});if(e(o0)){a("Operation cancelled.");return}v=o0}let U=y.editors,X=[],o=T1(),B=o.find((Z)=>Z.id==="universal");if(!U){if(!G){let Z=await X0({message:"Which editors do you want to configure (recommended)?",options:o.map((K)=>({label:K.promptLabel,value:K.id})),required:!1});if(e(Z)){a("Operation cancelled.");return}X=o.filter((K)=>Z.includes(K.id))}U=[]}else if(U.includes("universal")&&B){X=[B];let Z=new Set(B.editorIds);U=U.filter((K)=>K!=="universal"&&!Z.has(K))}let{agents:O}=y,E=[],{hooks:S}=y,J0=Z1(),d0=J0.find((Z)=>Z.id==="universal"),Ab=Object.fromEntries(c.map((Z)=>[Z.id,Z.name]));if(!O)if(G)O=[];else{let Z=await X0({message:"Which agent files do you want to add (optional)?",options:J0.map((K)=>({label:K.promptLabel,value:K.id})),required:!1});if(e(Z)){a("Operation cancelled.");return}E=J0.filter((K)=>Z.includes(K.id))}else if(O.includes("universal")&&d0){E=[d0];let Z=new Set(d0.agentIds);O=O.filter((K)=>K!=="universal"&&!Z.has(K))}let $b=Object.fromEntries(y0.map((Z)=>[Z.id,Z.name]));if(!S)if(G)S=[];else{let Z=await X0({message:"Which agent hooks do you want to enable (optional)?",options:Object.entries($b).map(([K,o0])=>({label:o0,value:K})),required:!1});if(e(Z)){a("Operation cancelled.");return}S=Z}let{integrations:d}=y;if(d===void 0)if(G||y.pm||y.editors||y.agents||y.hooks)d=[];else{let K=await X0({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(e(K)){a("Operation cancelled.");return}d=K}if(await uG(A,$,!y.skipInstall,G,y["type-aware"],v),await JG(G),await IG($,G),$==="biome")await dG(v,G,y["type-aware"]);if($==="eslint")await xG(v,G),await mG(v,G),await MG(G);if($==="oxlint")await R({type:"module"}),await FG(v,G),await hG(G);if(await Promise.all(X.map((Z)=>fG(Z,$,G))),await Promise.all((U??[]).map((Z)=>bb(Z,$,G))),await Promise.all(E.map((Z)=>CG(Z,H,$,G))),await Promise.all((O??[]).map((Z)=>yb(Z,Ab[Z],H,$,G))),await Promise.all((S??[]).map((Z)=>lG(Z,H,$,G))),d?.includes("husky")){let Z=d?.includes("lint-staged")??!1;await pG(A,!y.skipInstall,G,Z)}if(d?.includes("lefthook"))await cG(A,!y.skipInstall,G);if(d?.includes("lint-staged"))await PG(A,!y.skipInstall,G);if(d?.includes("pre-commit"))await qG(H,G);if(!G)z0.success("Successfully initialized Ultracite!");let vb=await r1({packageManager:H,quiet:G,shouldInstall:y.installSkill});if(!G&&!vb)z0.info(`You can install the Ultracite skill later with \`${l1(H)}\`.`)}catch(H){let A=H instanceof Error?H.message:"Unknown error";if(!G)z0.error(`Failed to initialize Ultracite configuration: ${A}`);throw H}};var b0=new rG,Hb=(b)=>b.parent?.rawArgs;b0.name("ultracite").version(W.version,"-v, --version").description(W.description);b0.command("init").description("Initialize Ultracite in the current directory").option("--pm <pm>","Package manager to use").option("--linter <linter>","Linter to use").option("--editors <editors...>","Editors to configure (use universal for .vscode/settings.json)").option("--agents <agents...>","Agents to enable (use universal for AGENTS.md)").option("--hooks <hooks...>","Hooks to enable").option("--frameworks <frameworks...>","Frameworks being used").option("--integrations <integrations...>","Integrations to enable").option("--install-skill","Install the reusable Ultracite skill after setup").option("--type-aware","Enable type-aware linting (enables project/scanner rules)").option("--skip-install","Skip installing dependencies").option("--quiet","Suppress interactive prompts").action(async(b)=>{await Gb({agents:b.agents,editors:b.editors,frameworks:b.frameworks,hooks:b.hooks,installSkill:b.installSkill,integrations:b.integrations,linter:b.linter,pm:b.pm,quiet:b.quiet??(T0.env.CI==="true"||T0.env.CI==="1"),skipInstall:b.skipInstall,"type-aware":b.typeAware})});b0.command("check").argument("[files...]","Files to check").description("Run linter without fixing files. Unknown options are passed to the underlying linter.").allowUnknownOption().action(async(b,y,G)=>{let{files:H,passthrough:A}=F0({commandName:"check",parsedArgs:b,rawArgs:Hb(G)});await v1(H,A)});b0.command("fix").argument("[files...]","Files to fix").description("Run linter and fix files. Unknown options are passed to the underlying linter.").allowUnknownOption().action(async(b,y,G)=>{let{files:H,passthrough:A}=F0({commandName:"fix",parsedArgs:b,rawArgs:Hb(G)});await Q1(H,A)});b0.command("doctor").description("Verify your Ultracite setup").action(async()=>{await U1()});if(!T0.env.TEST)try{await b0.parseAsync()}catch(b){if(b instanceof q)T0.exit(b.exitCode);if(b instanceof Error&&b.message==="Doctor checks failed")T0.exit(1);throw b}export{b0 as program};
260
+ `},f1={create:async(b)=>{let y=Gb(b);await Z(Z0,y)},exists:()=>{return yb()!==null},update:async(b)=>{let y=Gb(b),$=yb();await Z($===z0?Z0:$??Z0,y)}};var H0="./package.json",d2=i.map((b)=>`./${b}`),Y0="./stylelint.config.mjs",J2=()=>{return p(H0)?.stylelint!==void 0},vb=()=>{if(J2())return H0;for(let b of d2)if(H(b))return b;return null},Ub=()=>`export { default } from "ultracite/stylelint";
261
+ `,M1={create:async()=>{let b=Ub();await Z(Y0,b)},exists:()=>{return vb()!==null},update:async()=>{let b=Ub(),y=vb();await Z(y===H0?Y0:y??Y0,b)}};import{isCancel as D2,select as N2,spinner as L2}from"@clack/prompts";import{dlxCommand as Wb}from"nypm";var x2="haydenbleasel/ultracite",S2="ultracite",Zb=(b)=>Wb(b,"skills",{args:["add",x2],short:b==="npm"}),R2=(b,y=!1)=>Wb(b,"skills",{args:y?["list","-g","--json"]:["list","--json"],short:b==="npm"}),Qb=(b,y=!1)=>{let $=R2(b,y),[G,...v]=$.split(" "),U=j(G,v,{encoding:"utf-8",stdio:"pipe"});if(U.error||U.status!==0||!U.stdout)return!1;try{return JSON.parse(typeof U.stdout==="string"?U.stdout:U.stdout.toString("utf-8")).some((W)=>W.name===S2)}catch{return!1}},I2=(b)=>Qb(b)||Qb(b,!0),m2=async()=>{let b=await N2({message:"Do you want to install the Ultracite skill?",options:[{label:"Yes, install it",value:"install"},{label:"No, I'll do it later",value:"skip"}]});return!D2(b)&&b==="install"},zb=(b)=>Zb(b),Yb=async({packageManager:b,quiet:y=!1,shouldInstall:$})=>{if($===void 0&&!y&&I2(b))return!0;if(!($??(!y&&await m2())))return!1;let v=Zb(b),[U,...Q]=v.split(" "),W=L2();if(!y)W.start("Installing the Ultracite skill...");let o=j(U,Q,{stdio:"pipe"}),B=!o.error&&o.status===0;if(!y)W.stop(B?"Ultracite skill installed.":"Couldn't install the Ultracite skill automatically.");return B};import{readFile as _2}from"node:fs/promises";import{log as F2}from"@clack/prompts";import{glob as h2}from"glob";import{applyEdits as O2,modify as T2}from"jsonc-parser";var Hb=async()=>{try{return await h2("**/tsconfig*.json",{absolute:!1,ignore:["**/node_modules/**","**/dist/**","**/build/**","**/.next/**"]})}catch{return[]}},E2=(b)=>{if(!b?.compilerOptions)return!1;if(b.compilerOptions.strict===!0)return!0;return b.compilerOptions.strictNullChecks===!0},p2=async(b)=>{try{let y=await _2(b,"utf-8"),$=S1(y,A0);if(E2($))return;if($===void 0){await Z(b,`${JSON.stringify({compilerOptions:{strictNullChecks:!0}},null,2)}
262
+ `);return}let v=T2(y,["compilerOptions","strictNullChecks"],!0,{formattingOptions:{insertSpaces:!0,tabSize:2}}),U=O2(y,v);await Z(b,U)}catch(y){F2.warn(`Failed to update ${b}: ${y instanceof Error?y.message:y}`)}},o0={exists:async()=>{return(await Hb()).length>0},update:async()=>{let b=await Hb();if(b.length===0)return;await Promise.all(b.map((y)=>p2(y)))}};var Bb=z.devDependencies["@biomejs/biome"],B0=z.version,G1="Operation cancelled.",V0="lint-staged",ob="^10.0.0",Xb={"@eslint/js":ob,"@typescript-eslint/eslint-plugin":z.devDependencies["@typescript-eslint/eslint-plugin"],"@typescript-eslint/parser":z.devDependencies["@typescript-eslint/parser"],eslint:ob,"eslint-config-prettier":z.devDependencies["eslint-config-prettier"],"eslint-import-resolver-typescript":z.devDependencies["eslint-import-resolver-typescript"],"eslint-plugin-compat":z.devDependencies["eslint-plugin-compat"],"eslint-plugin-cypress":z.devDependencies["eslint-plugin-cypress"],"eslint-plugin-github":z.devDependencies["eslint-plugin-github"],"eslint-plugin-html":z.devDependencies["eslint-plugin-html"],"eslint-plugin-import-x":z.devDependencies["eslint-plugin-import-x"],"eslint-plugin-jsdoc":z.devDependencies["eslint-plugin-jsdoc"],"eslint-plugin-n":z.devDependencies["eslint-plugin-n"],"eslint-plugin-prettier":z.devDependencies["eslint-plugin-prettier"],"eslint-plugin-promise":z.devDependencies["eslint-plugin-promise"],"eslint-plugin-sonarjs":z.devDependencies["eslint-plugin-sonarjs"],"eslint-plugin-storybook":z.devDependencies["eslint-plugin-storybook"],"eslint-plugin-unicorn":z.devDependencies["eslint-plugin-unicorn"],"eslint-plugin-unused-imports":z.devDependencies["eslint-plugin-unused-imports"],globals:z.devDependencies.globals,prettier:"latest","prettier-plugin-tailwindcss":z.devDependencies["prettier-plugin-tailwindcss"],stylelint:"latest"},jb={angular:{"@angular-eslint/eslint-plugin":"latest"},astro:{"eslint-plugin-astro":z.devDependencies["eslint-plugin-astro"],"prettier-plugin-astro":z.devDependencies["prettier-plugin-astro"]},jest:{"eslint-plugin-jest":z.devDependencies["eslint-plugin-jest"]},next:{"@next/eslint-plugin-next":z.devDependencies["@next/eslint-plugin-next"],"eslint-plugin-react-doctor":z.devDependencies["eslint-plugin-react-doctor"]},qwik:{"eslint-plugin-qwik":z.devDependencies["eslint-plugin-qwik"]},react:{"eslint-plugin-jsx-a11y":z.devDependencies["eslint-plugin-jsx-a11y"],"eslint-plugin-react":z.devDependencies["eslint-plugin-react"],"eslint-plugin-react-doctor":z.devDependencies["eslint-plugin-react-doctor"],"eslint-plugin-react-hooks":z.devDependencies["eslint-plugin-react-hooks"]},remix:{"eslint-plugin-remix":z.devDependencies["eslint-plugin-remix"]},solid:{"eslint-plugin-solid":z.devDependencies["eslint-plugin-solid"]},svelte:{"eslint-plugin-svelte":z.devDependencies["eslint-plugin-svelte"],"prettier-plugin-svelte":z.devDependencies["prettier-plugin-svelte"]},tanstack:{"@tanstack/eslint-plugin-query":z.devDependencies["@tanstack/eslint-plugin-query"],"@tanstack/eslint-plugin-router":z.devDependencies["@tanstack/eslint-plugin-router"],"@tanstack/eslint-plugin-start":z.devDependencies["@tanstack/eslint-plugin-start"],"eslint-plugin-react-doctor":z.devDependencies["eslint-plugin-react-doctor"]},vitest:{"@vitest/eslint-plugin":z.devDependencies["@vitest/eslint-plugin"]},vue:{"eslint-plugin-vue":z.devDependencies["eslint-plugin-vue"]}},Kb=(b)=>{let y={...Xb};for(let $ of b)Object.assign(y,jb[$]);return y},X0={"eslint-plugin-github":z.devDependencies["eslint-plugin-github"],"eslint-plugin-sonarjs":z.devDependencies["eslint-plugin-sonarjs"]},l2={next:{"oxlint-plugin-react-doctor":z.devDependencies["oxlint-plugin-react-doctor"]},react:{"oxlint-plugin-react-doctor":z.devDependencies["oxlint-plugin-react-doctor"]},tanstack:{"oxlint-plugin-react-doctor":z.devDependencies["oxlint-plugin-react-doctor"]}},Ab=(b)=>{let y={};for(let $ of b)Object.assign(y,l2[$]);return y},r2=(b,y,$)=>{let G={ultracite:B0};if(b==="biome")G["@biomejs/biome"]=Bb;if(b==="eslint")Object.assign(G,Kb($));if(b==="oxlint"){if(G.oxlint="latest",G.oxfmt="latest",y)G["oxlint-tsgolint"]="latest";Object.assign(G,X0,Ab($))}return G},n2=new Set([...Object.keys(Xb),...Object.values(jb).flatMap((b)=>Object.keys(b??{}))]),Vb={biome:new Set(["@biomejs/biome"]),eslint:n2,oxlint:new Set(["oxfmt","oxlint","oxlint-plugin-react-doctor","oxlint-tsgolint",...Object.keys(X0)])},k2=async(b)=>{let y=b.startsWith("./")?b:`./${b}`;if(!H(y))return!1;let{rm:$}=await import("node:fs/promises");return await $(y,{force:!0}),!0},s2=async(b)=>{let y=await s();if(!y)return!1;let $=new Set;for(let[U,Q]of Object.entries(Vb))if(U!==b)for(let W of Q)$.add(W);for(let U of Vb[b])$.delete(U);let G=!1,v={...y};for(let U of["dependencies","devDependencies","peerDependencies"]){let Q=v[U];if(!Q)continue;let W=Object.entries(Q),o=W.filter(([K])=>!$.has(K));if(o.length!==W.length)G=!0;let B=Object.fromEntries(o);v[U]=B}if("prettier"in v)delete v.prettier,G=!0;if("stylelint"in v)delete v.stylelint,G=!0;if(!G)return!1;return await Z("package.json",`${JSON.stringify(v,null,2)}
263
+ `),!0},C2=async(b,y=!1)=>{let $=w();if(!y)$.start("Checking for stale linter configuration...");let G=new Set;if(b!=="biome")for(let W of q)G.add(W);if(b!=="eslint"){for(let W of M)G.add(W);for(let W of C)G.add(W);for(let W of i)G.add(W)}for(let W of D0)G.add(W);if(b!=="oxlint"){for(let W of g1)G.add(W);for(let W of N0)G.add(W)}let[v,U]=await Promise.all([Promise.all([...G].map((W)=>k2(W))),s2(b)]),Q=v.some(Boolean)||U;if(!y)$.stop(Q?"Stale linter configuration migrated.":"No stale linter configuration found.")},i2=async(b,y="biome",$=!0,G=!1,v=!1,U=["react"])=>{let Q=w();if(!G)Q.start("Installing dependencies...");let W=[`ultracite@${B0}`];if(y==="biome")W.push(`@biomejs/biome@${Bb}`);if(y==="eslint")W.push(...Object.entries(Kb(U)).map(([B,K])=>`${B}@${K}`));if(y==="oxlint"){if(W.push("oxlint@latest","oxfmt@latest",...Object.entries(X0).map(([B,K])=>`${B}@${K}`),...Object.entries(Ab(U)).map(([B,K])=>`${B}@${K}`)),v)W.push("oxlint-tsgolint@latest")}let o={check:"ultracite check",fix:"ultracite fix"};if($)await f2(W,{corepack:!1,packageManager:b,silent:!0,workspace:c()&&b.name!=="npm"}),await L({scripts:o});else{let B=r2(y,v,U);await L({devDependencies:B,scripts:o})}if(!G)Q.stop("Dependencies installed.")},t2=async(b=!1)=>{let y=w();if(!b)y.start("Checking for tsconfig.json files...");if(await o0.exists()){if(!b)y.message("Found tsconfig.json files, updating with strictNullChecks...");if(await o0.update(),!b)y.stop("tsconfig.json files updated.");return}if(!b)y.stop("No tsconfig.json files found, skipping.")},wb=async(b,y="biome",$=!1)=>{let G=P.find((Q)=>Q.id===b);if(!G)throw Error(`Editor "${b}" not found`);let v=F0(b,y),U=w();if(!$)U.start(`Checking for ${G.config.path}...`);if(await v.exists()){if(!$)U.message(`${G.config.path} found, updating...`);if(await v.update(),!$)U.stop(`${G.config.path} updated.`);return}if(!$)U.message(`${G.config.path} not found, creating...`);if(await v.create(),v.extension){let Q=_1.find((W)=>W.id===y)?.vscodeExtensionId;if(!Q)throw Error(`Linter extension not found for ${y}`);if(!$)U.message(`Installing ${Q} extension...`);try{if(v.extension(Q).status===0){if(!$)U.stop(`${G.config.path} created and ${Q} extension installed.`);return}}catch{}if(!$)U.stop(`${G.config.path} created. Install ${Q} extension manually.`);return}if(!$)if(b==="zed")U.stop(`${G.config.path} created. Install the Biome extension: https://biomejs.dev/reference/zed/`);else U.stop(`${G.config.path} created.`)},g2=async(b,y=!1,$=!1)=>{let G=w();if(!y)G.start("Checking for Biome configuration...");if(await E1.exists()){if(!y)G.message("Biome configuration found, updating...");if(await E1.update({frameworks:b,typeAware:$}),!y)G.stop("Biome configuration updated.");return}if(!y)G.message("Biome configuration not found, creating...");if(await E1.create({frameworks:b,typeAware:$}),!y)G.stop("Biome configuration created.")},a2=async(b,y=!1)=>{let $=w();if(!y)$.start("Checking for ESLint configuration...");if(await p1.exists()){if(!y)$.message("ESLint configuration found, updating...");if(await p1.update({frameworks:b}),!y)$.stop("ESLint configuration updated.");return}if(!y)$.message("ESLint configuration not found, creating...");if(await p1.create({frameworks:b}),!y)$.stop("ESLint configuration created.")},e2=async(b,y=!1)=>{let $=w();if(!y)$.start("Checking for Oxlint configuration...");if(await P1.exists()){if(!y)$.message("Oxlint configuration found, updating...");if(await P1.update({frameworks:b}),!y)$.stop("Oxlint configuration updated.");return}if(!y)$.message("Oxlint configuration not found, creating...");if(await P1.create({frameworks:b}),!y)$.stop("Oxlint configuration created.")},b$=async(b,y=!1)=>{let $=w();if(!y)$.start("Checking for Prettier configuration...");if(await f1.exists()){if(!y)$.message("Prettier configuration found, updating...");if(await f1.update({frameworks:b}),!y)$.stop("Prettier configuration updated.");return}if(!y)$.message("Prettier configuration not found, creating...");if(await f1.create({frameworks:b}),!y)$.stop("Prettier configuration created.")},y$=async(b=!1)=>{let y=w();if(!b)y.start("Checking for Stylelint configuration...");if(await M1.exists()){if(!b)y.message("Stylelint configuration found, updating...");if(await M1.update(),!b)y.stop("Stylelint configuration updated.");return}if(!b)y.message("Stylelint configuration not found, creating...");if(await M1.create(),!b)y.stop("Stylelint configuration created.")},$$=async(b=!1)=>{let y=w();if(!b)y.start("Checking for oxfmt configuration...");if(await c1.exists()){if(!b)y.message("oxfmt configuration found, updating...");if(await c1.update(),!b)y.stop("oxfmt configuration updated.");return}if(!b)y.message("oxfmt configuration not found, creating...");if(await c1.create(),!b)y.stop("oxfmt configuration created.")},G$=async(b,y=!0,$=!1,G=!1)=>{let v=w();if(!$)v.start("Initializing pre-commit hooks..."),v.message("Installing Husky...");if(await(y?e.install(b):L({devDependencies:{husky:"latest"},scripts:{prepare:"husky"}})),!$)v.message("Initializing Husky...");if(e.init(b.name),await e.exists()){if(!$)v.message("Pre-commit hook found, updating...");if(await e.update(b.name,G),!$)v.stop("Pre-commit hook updated.");return}if(!$)v.message("Pre-commit hook not found, creating...");if(await e.create(b.name,G),!$)v.stop("Pre-commit hook created.")},v$=async(b,y=!0,$=!1)=>{let G=w();if(!$)G.start("Initializing lefthook..."),G.message("Installing lefthook...");if(await(y?B1.install(b):L({devDependencies:{lefthook:"latest"}})),await B1.exists()){if(!$)G.message("lefthook.yml found, updating...");if(await B1.update(b.name),!$)G.stop("lefthook.yml updated.");return}if(!$)G.message("lefthook.yml not found, creating...");if(await B1.create(b.name),!$)G.stop("lefthook.yml created.")},U$=async(b,y=!0,$=!1)=>{let G=w();if(!$)G.start("Initializing lint-staged..."),G.message("Installing lint-staged...");if(await(y?A1.install(b):L({devDependencies:{"lint-staged":"latest"}})),await A1.exists()){if(!$)G.message("lint-staged found, updating...");if(await A1.update(b.name),!$)G.stop("lint-staged updated.");return}if(!$)G.message("lint-staged not found, creating...");if(await A1.create(b.name),!$)G.stop("lint-staged created.")},Q$=async(b,y=!1)=>{let $=w();if(!y)$.start("Initializing pre-commit...");if(await T1.exists()){if(!y)$.message(".pre-commit-config.yaml found, updating...");if(await T1.update(b),!y)$.stop(".pre-commit-config.yaml updated.");return}if(!y)$.message(".pre-commit-config.yaml not found, creating...");if(await T1.create(b),!y)$.stop(".pre-commit-config.yaml created.")},ub=async(b,y,$,G,v=!1)=>{let U=w();if(!v)U.start(`Checking for ${y}...`);let Q=_0(b,$,G);if(await Q.exists()){if(!v)U.message(`${y} found, updating...`);if(await Q.update(),!v)U.stop(`${y} updated.`);return}if(!v)U.message(`${y} not found, creating...`);if(await Q.create(),!v)U.stop(`${y} created.`)},W$=async(b,y,$,G=!1)=>{let v=`${b.displayName} (${b.path})`;await ub(b.representativeAgentId,v,y,$,G)},Z$=async(b,y="biome",$=!1)=>{await wb(b.representativeEditorId,y,$)},z$=async(b,y,$="biome",G=!1)=>{let v=w(),U=Y1.find((W)=>W.id===b)?.name??b;if(!G)v.start(`Checking for ${U} hooks...`);let Q=E0(b,y,$);if(await Q.exists()){if(!G)v.message(`${U} hooks found, updating...`);if(await Q.update(),!G)v.stop(`${U} hooks updated.`);return}if(!G)v.message(`${U} hooks not found, creating...`);if(await Q.create(),!G)v.stop(`${U} hooks created.`)},db=async(b)=>{let y=b??{},$=y.quiet??!1;if(!$)q2(`Ultracite v${B0} Initialization`);try{let G,v;if(y.pm)G=H1(y.pm),v={command:G,name:G};else{let Y=await M2(c2.cwd());if(!Y)throw Error("No package manager specified or detected");if(!$&&Y.warnings)for(let X of Y.warnings)d1.warn(X);if(!$)d1.info(`Detected lockfile, using ${Y.name}`);v=T0(Y),G=v.name}let{linter:U}=y;if(U===void 0)if($||y.pm||y.editors||y.agents||y.hooks||y.integrations!==void 0||y.frameworks!==void 0)U="biome";else{let X=await P2({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($1(X)){y1(G1);return}U=X}let{frameworks:Q}=y;if(Q===void 0)if($||y.pm||y.editors||y.agents||y.hooks||y.integrations!==void 0)Q=[];else{let X=await L0(),N1=await J1({initialValues:X,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 / React Router (file-route conventions)",value:"remix"},{label:"TanStack (Query, Router, Start)",value:"tanstack"},{label:"Astro",value:"astro"},{label:"NestJS",value:"nestjs"},{label:"Jest",value:"jest"},{label:"Vitest / Bun",value:"vitest"}],required:!1});if($1(N1)){y1(G1);return}Q=N1}let W=y.editors,o=[],B=h0(),K=B.find((Y)=>Y.id==="universal");if(!W){if(!$){let Y=await J1({message:"Which editors do you want to configure (recommended)?",options:B.map((X)=>({label:X.promptLabel,value:X.id})),required:!1});if($1(Y)){y1(G1);return}o=B.filter((X)=>Y.includes(X.id))}W=[]}else if(W.includes("universal")&&K){o=[K];let Y=new Set(K.editorIds);W=W.filter((X)=>X!=="universal"&&!Y.has(X))}let{agents:N}=y,u=[],{hooks:R}=y,l1=m0(),r1=l1.find((Y)=>Y.id==="universal"),Db=Object.fromEntries(l.map((Y)=>[Y.id,Y.name]));if(!N)if($)N=[];else{let Y=await J1({message:"Which agent files do you want to add (optional)?",options:l1.map((X)=>({label:X.promptLabel,value:X.id})),required:!1});if($1(Y)){y1(G1);return}u=l1.filter((X)=>Y.includes(X.id))}else if(N.includes("universal")&&r1){u=[r1];let Y=new Set(r1.agentIds);N=N.filter((X)=>X!=="universal"&&!Y.has(X))}let Nb=Object.fromEntries(Y1.map((Y)=>[Y.id,Y.name]));if(!R)if($)R=[];else{let Y=await J1({message:"Which agent hooks do you want to enable (optional)?",options:Object.entries(Nb).map(([X,N1])=>({label:N1,value:X})),required:!1});if($1(Y)){y1(G1);return}R=Y}let{integrations:E}=y;if(E===void 0)if($||y.pm||y.editors||y.agents||y.hooks)E=[];else{let X=await J1({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:V0},{label:"pre-commit (Python framework)",value:"pre-commit"}],required:!1});if($1(X)){y1(G1);return}E=X}if(await i2(v,U,!y.skipInstall,$,y["type-aware"],Q),await t2($),await C2(U,$),U==="biome")await g2(Q,$,y["type-aware"]);if(U==="eslint")await a2(Q,$),await b$(Q,$),await y$($);if(U==="oxlint")await L({type:"module"}),await e2(Q,$),await $$($);if(await Promise.all(o.map((Y)=>Z$(Y,U,$))),await Promise.all((W??[]).map((Y)=>wb(Y,U,$))),await Promise.all(u.map((Y)=>W$(Y,G,U,$))),await Promise.all((N??[]).map((Y)=>ub(Y,Db[Y],G,U,$))),await Promise.all((R??[]).map((Y)=>z$(Y,G,U,$))),E?.includes("husky")){let Y=E?.includes(V0)??!1;await G$(v,!y.skipInstall,$,Y)}if(E?.includes("lefthook"))await v$(v,!y.skipInstall,$);if(E?.includes(V0))await U$(v,!y.skipInstall,$);if(E?.includes("pre-commit"))await Q$(G,$);if(!$)d1.success("Successfully initialized Ultracite!");let Lb=await Yb({packageManager:G,quiet:$,shouldInstall:y.installSkill});if(!$&&!Lb)d1.info(`You can install the Ultracite skill later with \`${zb(G)}\`.`)}catch(G){let v=G instanceof Error?G.message:"Unknown error";if(!$)d1.error(`Failed to initialize Ultracite configuration: ${v}`);throw G}};var v1=new Y$,Jb=(b)=>b.parent?.rawArgs;v1.name("ultracite").version(z.version,"-v, --version").description(z.description);v1.command("init").description("Initialize Ultracite in the current directory").option("--pm <pm>","Package manager to use").option("--linter <linter>","Linter to use").option("--editors <editors...>","Editors to configure (use universal for .vscode/settings.json)").option("--agents <agents...>","Agents to enable (use universal for AGENTS.md)").option("--hooks <hooks...>","Hooks to enable").option("--frameworks <frameworks...>","Frameworks being used").option("--integrations <integrations...>","Integrations to enable").option("--install-skill","Install the reusable Ultracite skill after setup").option("--type-aware","Enable type-aware linting (enables project/scanner rules)").option("--skip-install","Skip installing dependencies").option("--quiet","Suppress interactive prompts").action(async(b)=>{await db({agents:b.agents,editors:b.editors,frameworks:b.frameworks,hooks:b.hooks,installSkill:b.installSkill,integrations:b.integrations,linter:b.linter,pm:b.pm,quiet:b.quiet??(D1.env.CI==="true"||D1.env.CI==="1"),skipInstall:b.skipInstall,"type-aware":b.typeAware})});v1.command("check").argument("[files...]","Files to check").description("Run linter without fixing files. Unknown options are passed to the underlying linter.").allowUnknownOption().action(async(b,y,$)=>{let{files:G,passthrough:v}=k1({commandName:"check",parsedArgs:b,rawArgs:Jb($)});await x0(G,v)});v1.command("fix").argument("[files...]","Files to fix").description("Run linter and fix files. Unknown options are passed to the underlying linter.").allowUnknownOption().action(async(b,y,$)=>{let{files:G,passthrough:v}=k1({commandName:"fix",parsedArgs:b,rawArgs:Jb($)});await R0(G,v)});v1.command("doctor").description("Verify your Ultracite setup").action(async()=>{await S0()});if(!D1.env.TEST)try{await v1.parseAsync()}catch(b){if(b instanceof r)D1.exit(b.exitCode);if(b instanceof Error&&b.message==="Doctor checks failed")D1.exit(1);throw b}export{v1 as program};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultracite",
3
- "version": "7.9.0",
3
+ "version": "7.9.1",
4
4
  "description": "The AI-ready formatter that helps you write and generate code faster.",
5
5
  "keywords": [
6
6
  "biome",
@@ -109,7 +109,7 @@
109
109
  "eslint-plugin-unused-imports": "^4.4.1",
110
110
  "eslint-plugin-vue": "^10.9.2",
111
111
  "globals": "^17.7.0",
112
- "oxlint": "^1.68.0",
112
+ "oxlint": "^1.72.0",
113
113
  "oxlint-plugin-react-doctor": "^0.7.1",
114
114
  "prettier-plugin-astro": "^0.14.1",
115
115
  "prettier-plugin-svelte": "^4.1.0",
@@ -1,5 +0,0 @@
1
- import type { OxlintConfig } from "oxlint";
2
-
3
- declare const config: OxlintConfig;
4
-
5
- export default config;
@@ -1,36 +0,0 @@
1
- import { defineConfig } from "oxlint";
2
-
3
- // Runs eslint-plugin-github through oxlint's JS plugin support to close
4
- // the gap with the ESLint preset. Rules that require type information are
5
- // not supported by the JS plugin bridge and are excluded.
6
- export default defineConfig({
7
- jsPlugins: [{ name: "github", specifier: "eslint-plugin-github" }],
8
- rules: {
9
- "github/a11y-aria-label-is-well-formatted": "error",
10
- "github/a11y-no-title-attribute": "error",
11
- "github/a11y-no-visually-hidden-interactive-element": "error",
12
- "github/a11y-role-supports-aria-props": "error",
13
- "github/a11y-svg-has-accessible-name": "error",
14
- "github/array-foreach": "error",
15
- "github/async-currenttarget": "error",
16
- "github/async-preventdefault": "error",
17
- "github/authenticity-token": "error",
18
- "github/filenames-match-regex": "error",
19
- "github/get-attribute": "error",
20
- "github/js-class-name": "error",
21
- "github/no-blur": "error",
22
- "github/no-d-none": "error",
23
- // Conflicts with unicorn/prefer-dom-node-dataset, which is the benchmark.
24
- "github/no-dataset": "off",
25
- "github/no-dynamic-script-tag": "error",
26
- "github/no-implicit-buggy-globals": "error",
27
- "github/no-inner-html": "error",
28
- "github/no-innerText": "error",
29
- "github/no-then": "error",
30
- "github/no-useless-passive": "error",
31
- "github/prefer-observers": "error",
32
- "github/require-passive-events": "error",
33
- // Mirrors the ESLint preset.
34
- "github/unescaped-html-literal": "off",
35
- },
36
- });
@@ -1,5 +0,0 @@
1
- import type { OxlintConfig } from "oxlint";
2
-
3
- declare const config: OxlintConfig;
4
-
5
- export default config;
@@ -1,207 +0,0 @@
1
- import { defineConfig } from "oxlint";
2
-
3
- // Runs eslint-plugin-sonarjs through oxlint's JS plugin support to close
4
- // the gap with the ESLint preset. Rules that require type information are
5
- // not supported by the JS plugin bridge and are excluded.
6
- export default defineConfig({
7
- jsPlugins: [{ name: "sonarjs", specifier: "eslint-plugin-sonarjs" }],
8
- rules: {
9
- "sonarjs/arguments-usage": "error",
10
- "sonarjs/array-constructor": "error",
11
- // Fights the formatter (arrowParentheses: always).
12
- "sonarjs/arrow-function-convention": "off",
13
- "sonarjs/async-test-assertions": "error",
14
- "sonarjs/aws-apigateway-public-api": "error",
15
- "sonarjs/aws-ec2-rds-dms-public": "error",
16
- "sonarjs/aws-ec2-unencrypted-ebs-volume": "error",
17
- "sonarjs/aws-efs-unencrypted": "error",
18
- "sonarjs/aws-iam-all-privileges": "error",
19
- "sonarjs/aws-iam-all-resources-accessible": "error",
20
- "sonarjs/aws-iam-privilege-escalation": "error",
21
- "sonarjs/aws-iam-public-access": "error",
22
- "sonarjs/aws-opensearchservice-domain": "error",
23
- "sonarjs/aws-rds-unencrypted-databases": "error",
24
- "sonarjs/aws-restricted-ip-admin-access": "error",
25
- "sonarjs/aws-s3-bucket-granted-access": "error",
26
- "sonarjs/aws-s3-bucket-insecure-http": "error",
27
- "sonarjs/aws-s3-bucket-public-access": "error",
28
- "sonarjs/aws-s3-bucket-versioning": "error",
29
- "sonarjs/aws-sagemaker-unencrypted-notebook": "error",
30
- "sonarjs/aws-sns-unencrypted-topics": "error",
31
- "sonarjs/aws-sqs-unencrypted-queue": "error",
32
- "sonarjs/block-scoped-var": "error",
33
- "sonarjs/bool-param-default": "error",
34
- "sonarjs/call-argument-line": "error",
35
- "sonarjs/chai-determinate-assertion": "error",
36
- "sonarjs/class-name": "error",
37
- "sonarjs/code-eval": "error",
38
- // Matches Biome's noExcessiveCognitiveComplexity limit.
39
- "sonarjs/cognitive-complexity": ["error", 20],
40
- "sonarjs/comma-or-logical-or-case": "error",
41
- "sonarjs/comment-regex": "error",
42
- "sonarjs/constructor-for-side-effects": "error",
43
- "sonarjs/content-length": "error",
44
- "sonarjs/content-security-policy": "error",
45
- "sonarjs/cookie-no-httponly": "error",
46
- "sonarjs/cors": "error",
47
- "sonarjs/csrf": "error",
48
- // Duplicate of the core complexity rule.
49
- "sonarjs/cyclomatic-complexity": "off",
50
- "sonarjs/declarations-in-global-scope": "error",
51
- "sonarjs/destructuring-assignment-syntax": "error",
52
- "sonarjs/disabled-timeout": "error",
53
- "sonarjs/dynamically-constructed-templates": "error",
54
- // Mirrors the ESLint preset.
55
- "sonarjs/elseif-without-else": "off",
56
- "sonarjs/encryption-secure-mode": "error",
57
- "sonarjs/expression-complexity": "error",
58
- // Requires a headerFormat option; errors on every file without one.
59
- "sonarjs/file-header": "off",
60
- "sonarjs/file-name-differ-from-class": "error",
61
- "sonarjs/file-permissions": "error",
62
- "sonarjs/file-uploads": "error",
63
- "sonarjs/fixme-tag": "error",
64
- "sonarjs/for-in": "error",
65
- "sonarjs/for-loop-increment-sign": "error",
66
- "sonarjs/function-inside-loop": "error",
67
- "sonarjs/function-name": "error",
68
- "sonarjs/future-reserved-words": "error",
69
- "sonarjs/generator-without-yield": "error",
70
- "sonarjs/hardcoded-secret-signatures": "error",
71
- "sonarjs/hashing": "error",
72
- "sonarjs/hooks-before-test-cases": "error",
73
- "sonarjs/inconsistent-function-call": "error",
74
- "sonarjs/insecure-cookie": "error",
75
- "sonarjs/insecure-jwt-token": "error",
76
- "sonarjs/inverted-assertion-arguments": "error",
77
- "sonarjs/label-position": "error",
78
- "sonarjs/link-with-target-blank": "error",
79
- // The preset disables max-lines everywhere.
80
- "sonarjs/max-lines": "off",
81
- // The preset disables max-lines-per-function everywhere.
82
- "sonarjs/max-lines-per-function": "off",
83
- "sonarjs/max-switch-cases": "error",
84
- "sonarjs/max-union-size": "error",
85
- "sonarjs/misplaced-loop-counter": "error",
86
- // Duplicate of max-depth, which is off.
87
- "sonarjs/nested-control-flow": "off",
88
- "sonarjs/no-all-duplicated-branches": "error",
89
- "sonarjs/no-angular-bypass-sanitization": "error",
90
- "sonarjs/no-built-in-override": "error",
91
- "sonarjs/no-case-label-in-switch": "error",
92
- "sonarjs/no-clear-text-protocols": "error",
93
- "sonarjs/no-code-after-done": "error",
94
- "sonarjs/no-collapsible-if": "error",
95
- "sonarjs/no-commented-code": "error",
96
- "sonarjs/no-dead-store": "error",
97
- "sonarjs/no-delete-var": "error",
98
- "sonarjs/no-duplicate-in-composite": "error",
99
- "sonarjs/no-duplicate-string": "error",
100
- "sonarjs/no-duplicate-test-title": "error",
101
- "sonarjs/no-duplicated-branches": "error",
102
- "sonarjs/no-element-overwrite": "error",
103
- "sonarjs/no-empty-collection": "error",
104
- "sonarjs/no-empty-test-file": "error",
105
- "sonarjs/no-empty-test-title": "error",
106
- "sonarjs/no-equals-in-for-termination": "error",
107
- "sonarjs/no-exclusive-tests": "error",
108
- "sonarjs/no-extra-arguments": "error",
109
- "sonarjs/no-fallthrough": "error",
110
- "sonarjs/no-floating-point-equality": "error",
111
- "sonarjs/no-forced-browser-interaction": "error",
112
- "sonarjs/no-function-declaration-in-block": "error",
113
- "sonarjs/no-global-this": "error",
114
- "sonarjs/no-globals-shadowing": "error",
115
- "sonarjs/no-gratuitous-expressions": "error",
116
- "sonarjs/no-hardcoded-ip": "error",
117
- "sonarjs/no-hardcoded-passwords": "error",
118
- "sonarjs/no-hardcoded-secrets": "error",
119
- "sonarjs/no-hook-setter-in-body": "error",
120
- "sonarjs/no-identical-conditions": "error",
121
- "sonarjs/no-identical-expressions": "error",
122
- "sonarjs/no-identical-functions": "error",
123
- "sonarjs/no-ignored-exceptions": "error",
124
- "sonarjs/no-implicit-dependencies": "error",
125
- "sonarjs/no-implicit-global": "error",
126
- "sonarjs/no-incomplete-assertions": "error",
127
- "sonarjs/no-internal-api-use": "error",
128
- "sonarjs/no-invariant-returns": "error",
129
- "sonarjs/no-inverted-boolean-check": "error",
130
- "sonarjs/no-labels": "error",
131
- "sonarjs/no-literal-call": "error",
132
- "sonarjs/no-mime-sniff": "error",
133
- "sonarjs/no-nested-assignment": "error",
134
- "sonarjs/no-nested-conditional": "error",
135
- "sonarjs/no-nested-functions": "error",
136
- "sonarjs/no-nested-incdec": "error",
137
- "sonarjs/no-nested-switch": "error",
138
- "sonarjs/no-nested-template-literals": "error",
139
- "sonarjs/no-os-command-from-path": "error",
140
- "sonarjs/no-parameter-reassignment": "error",
141
- "sonarjs/no-primitive-wrappers": "error",
142
- "sonarjs/no-redundant-assignments": "error",
143
- "sonarjs/no-redundant-boolean": "error",
144
- "sonarjs/no-redundant-jump": "error",
145
- // The jsPlugins bridge provides no globals, so every identifier is flagged.
146
- "sonarjs/no-reference-error": "off",
147
- "sonarjs/no-referrer-policy": "error",
148
- "sonarjs/no-same-argument-assert": "error",
149
- "sonarjs/no-same-line-conditional": "error",
150
- "sonarjs/no-session-cookies-on-static-assets": "error",
151
- "sonarjs/no-skipped-tests": "error",
152
- "sonarjs/no-sonar-comments": "error",
153
- "sonarjs/no-table-as-layout": "error",
154
- "sonarjs/no-trivial-assertions": "error",
155
- "sonarjs/no-undefined-assignment": "error",
156
- "sonarjs/no-unenclosed-multiline-block": "error",
157
- "sonarjs/no-uniq-key": "error",
158
- "sonarjs/no-unthrown-error": "error",
159
- "sonarjs/no-unused-collection": "error",
160
- "sonarjs/no-unused-function-argument": "error",
161
- "sonarjs/no-unused-vars": "error",
162
- "sonarjs/no-use-of-empty-return-value": "error",
163
- "sonarjs/no-useless-catch": "error",
164
- "sonarjs/no-useless-increment": "error",
165
- "sonarjs/no-useless-react-setstate": "error",
166
- "sonarjs/no-variable-usage-before-declaration": "error",
167
- "sonarjs/no-weak-cipher": "error",
168
- "sonarjs/no-weak-keys": "error",
169
- "sonarjs/no-wildcard-import": "error",
170
- "sonarjs/non-existent-operator": "error",
171
- "sonarjs/object-alt-content": "error",
172
- "sonarjs/prefer-default-last": "error",
173
- "sonarjs/prefer-object-literal": "error",
174
- "sonarjs/prefer-promise-shorthand": "error",
175
- "sonarjs/prefer-single-boolean-return": "error",
176
- "sonarjs/prefer-specific-assertions": "error",
177
- "sonarjs/prefer-type-guard": "error",
178
- "sonarjs/prefer-while": "error",
179
- "sonarjs/production-debug": "error",
180
- "sonarjs/pseudo-random": "error",
181
- "sonarjs/public-static-readonly": "error",
182
- "sonarjs/publicly-writable-directories": "error",
183
- "sonarjs/redundant-type-aliases": "error",
184
- "sonarjs/review-blockchain-mnemonic": "error",
185
- "sonarjs/session-regeneration": "error",
186
- // Conflicts with sort-keys.
187
- "sonarjs/shorthand-property-grouping": "off",
188
- "sonarjs/stable-tests": "error",
189
- "sonarjs/stateful-regex": "error",
190
- "sonarjs/strict-transport-security": "error",
191
- "sonarjs/super-linear-regex": "error",
192
- "sonarjs/table-header": "error",
193
- "sonarjs/table-header-reference": "error",
194
- "sonarjs/test-check-exception": "error",
195
- "sonarjs/todo-tag": "error",
196
- "sonarjs/too-many-break-or-continue-in-loop": "error",
197
- "sonarjs/unverified-certificate": "error",
198
- "sonarjs/unverified-hostname": "error",
199
- "sonarjs/updated-const-var": "error",
200
- "sonarjs/updated-loop-counter": "error",
201
- "sonarjs/use-type-alias": "error",
202
- "sonarjs/variable-name": "error",
203
- "sonarjs/weak-ssl": "error",
204
- "sonarjs/x-powered-by": "error",
205
- "sonarjs/xml-parser-xxe": "error",
206
- },
207
- });