@savvy-web/lint-staged 0.7.3 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/878.js CHANGED
@@ -2,17 +2,298 @@ import { Args, Command, Options } from "@effect/cli";
2
2
  import { NodeContext, NodeRuntime } from "@effect/platform-node";
3
3
  import { BiomeSchemaSync, BiomeSchemaSyncLive, CheckResult, ConfigDiscovery, ConfigDiscoveryLive, ManagedSection, ManagedSectionLive, SectionDefinition, ShellSectionDefinition, SyncResult, ToolDefinition, ToolDiscovery, ToolDiscoveryLive } from "@savvy-web/silk-effects";
4
4
  import { Effect, Layer } from "effect";
5
- import { PackageManagerDetectorLive, WorkspaceRootLive } from "workspaces-effect";
5
+ import { WorkspacesLive, findWorkspaceRootSync, getWorkspacePackagesSync } from "workspaces-effect";
6
6
  import { isDeepStrictEqual } from "node:util";
7
7
  import { FileSystem } from "@effect/platform";
8
8
  import { applyEdits, modify, parse } from "jsonc-effect";
9
9
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
10
+ import { dirname, join, resolve } from "node:path";
11
+ import { execSync } from "node:child_process";
10
12
  import sort_package_json from "sort-package-json";
11
13
  import { parse as external_yaml_parse, stringify } from "yaml";
12
- import { execSync } from "node:child_process";
13
- import { dirname, join, resolve } from "node:path";
14
14
  import { format, resolveConfig } from "prettier";
15
15
  import { lint } from "yaml-lint";
16
+ const VALID_COMMAND_PATTERN = /^[\w@/-]+$/;
17
+ function validateCommandName(name) {
18
+ if (!VALID_COMMAND_PATTERN.test(name)) throw new Error(`Invalid command name: "${name}". Only alphanumeric characters, hyphens, underscores, @ and / are allowed.`);
19
+ }
20
+ class Command_Command {
21
+ static cachedPackageManager = null;
22
+ static cachedRoot = null;
23
+ static findRoot(cwd = process.cwd()) {
24
+ if (null !== Command_Command.cachedRoot) return Command_Command.cachedRoot;
25
+ let dir = resolve(cwd);
26
+ while(true){
27
+ if (existsSync(join(dir, "package.json"))) {
28
+ Command_Command.cachedRoot = dir;
29
+ return dir;
30
+ }
31
+ const parent = dirname(dir);
32
+ if (parent === dir) break;
33
+ dir = parent;
34
+ }
35
+ Command_Command.cachedRoot = cwd;
36
+ return cwd;
37
+ }
38
+ static detectPackageManager(cwd = Command_Command.findRoot()) {
39
+ if (null !== Command_Command.cachedPackageManager) return Command_Command.cachedPackageManager;
40
+ const packageJsonPath = join(cwd, "package.json");
41
+ if (!existsSync(packageJsonPath)) {
42
+ Command_Command.cachedPackageManager = "npm";
43
+ return "npm";
44
+ }
45
+ try {
46
+ const content = readFileSync(packageJsonPath, "utf-8");
47
+ const pkg = JSON.parse(content);
48
+ if (pkg.packageManager) {
49
+ const match = pkg.packageManager.match(/^(npm|pnpm|yarn|bun)@/);
50
+ if (match) {
51
+ Command_Command.cachedPackageManager = match[1];
52
+ return Command_Command.cachedPackageManager;
53
+ }
54
+ }
55
+ } catch {}
56
+ Command_Command.cachedPackageManager = "npm";
57
+ return "npm";
58
+ }
59
+ static getExecPrefix(packageManager) {
60
+ switch(packageManager){
61
+ case "pnpm":
62
+ return [
63
+ "pnpm",
64
+ "exec"
65
+ ];
66
+ case "yarn":
67
+ return [
68
+ "yarn",
69
+ "exec"
70
+ ];
71
+ case "bun":
72
+ return [
73
+ "bun",
74
+ "x",
75
+ "--no-install"
76
+ ];
77
+ default:
78
+ return [
79
+ "npx",
80
+ "--no"
81
+ ];
82
+ }
83
+ }
84
+ static clearCache() {
85
+ Command_Command.cachedPackageManager = null;
86
+ Command_Command.cachedRoot = null;
87
+ }
88
+ static isAvailable(command) {
89
+ validateCommandName(command);
90
+ try {
91
+ execSync(`command -v ${command}`, {
92
+ stdio: "ignore"
93
+ });
94
+ return true;
95
+ } catch {
96
+ return false;
97
+ }
98
+ }
99
+ static findTool(tool) {
100
+ validateCommandName(tool);
101
+ if (Command_Command.isAvailable(tool)) return {
102
+ available: true,
103
+ command: tool,
104
+ source: "global"
105
+ };
106
+ const pm = Command_Command.detectPackageManager();
107
+ const prefix = Command_Command.getExecPrefix(pm);
108
+ const execCmd = [
109
+ ...prefix,
110
+ tool
111
+ ].join(" ");
112
+ try {
113
+ execSync(`${execCmd} --version`, {
114
+ stdio: "ignore"
115
+ });
116
+ return {
117
+ available: true,
118
+ command: execCmd,
119
+ source: pm
120
+ };
121
+ } catch {}
122
+ return {
123
+ available: false,
124
+ command: void 0,
125
+ source: void 0
126
+ };
127
+ }
128
+ static requireTool(tool, errorMessage) {
129
+ const result = Command_Command.findTool(tool);
130
+ if (!result.available || !result.command) throw new Error(errorMessage ?? `Required tool '${tool}' is not available. Install it globally or add it as a dev dependency.`);
131
+ return result.command;
132
+ }
133
+ static findSavvyLint() {
134
+ const result = Command_Command.findTool("savvy-lint");
135
+ if (result.available && result.command) return result.command;
136
+ const root = Command_Command.findRoot();
137
+ return `node ${root}/dist/dev/bin/savvy-lint.js`;
138
+ }
139
+ static exec(command) {
140
+ return execSync(command, {
141
+ encoding: "utf-8"
142
+ }).trim();
143
+ }
144
+ static execSilent(command) {
145
+ try {
146
+ execSync(command, {
147
+ stdio: "ignore"
148
+ });
149
+ return true;
150
+ } catch {
151
+ return false;
152
+ }
153
+ }
154
+ }
155
+ class Filter {
156
+ static exclude(filenames, patterns) {
157
+ if (0 === patterns.length) return [
158
+ ...filenames
159
+ ];
160
+ return filenames.filter((file)=>!patterns.some((pattern)=>file.includes(pattern)));
161
+ }
162
+ static include(filenames, patterns) {
163
+ if (0 === patterns.length) return [];
164
+ return filenames.filter((file)=>patterns.some((pattern)=>file.includes(pattern)));
165
+ }
166
+ static apply(filenames, options) {
167
+ let result = [
168
+ ...filenames
169
+ ];
170
+ if (options.include && options.include.length > 0) result = Filter.include(result, options.include);
171
+ if (options.exclude && options.exclude.length > 0) result = Filter.exclude(result, options.exclude);
172
+ return result;
173
+ }
174
+ static shellEscape(filenames) {
175
+ return filenames.map((f)=>`'${f.replace(/'/g, "'\\''")}'`).join(" ");
176
+ }
177
+ }
178
+ const UNRESOLVED = Symbol("unresolved");
179
+ let cachedRoot = UNRESOLVED;
180
+ let cachedPackages = UNRESOLVED;
181
+ let cachedPaths = UNRESOLVED;
182
+ function getWorkspaceRoot() {
183
+ if (cachedRoot !== UNRESOLVED) return cachedRoot;
184
+ cachedRoot = findWorkspaceRootSync() ?? null;
185
+ return cachedRoot;
186
+ }
187
+ function getWorkspacePackages() {
188
+ if (cachedPackages !== UNRESOLVED) return cachedPackages;
189
+ const root = getWorkspaceRoot();
190
+ if (null === root) {
191
+ cachedPackages = null;
192
+ return null;
193
+ }
194
+ const all = getWorkspacePackagesSync(root) ?? [];
195
+ cachedPackages = all.filter((pkg)=>pkg.path !== root);
196
+ return cachedPackages;
197
+ }
198
+ function getWorkspacePackagePaths() {
199
+ if (cachedPaths !== UNRESOLVED) return cachedPaths;
200
+ const packages = getWorkspacePackages();
201
+ cachedPaths = packages?.map((pkg)=>pkg.path) ?? [];
202
+ return cachedPaths;
203
+ }
204
+ function isWorkspacePackagePath(filePath) {
205
+ const root = getWorkspaceRoot();
206
+ if (null === root) return true;
207
+ const dir = dirname(filePath);
208
+ if (dir === root) return true;
209
+ const packagePaths = getWorkspacePackagePaths();
210
+ return packagePaths.includes(dir);
211
+ }
212
+ function resetWorkspaceCache() {
213
+ cachedRoot = UNRESOLVED;
214
+ cachedPackages = UNRESOLVED;
215
+ cachedPaths = UNRESOLVED;
216
+ }
217
+ class Biome {
218
+ static glob = "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}";
219
+ static defaultExcludes = [
220
+ "package.json",
221
+ "package-lock.json",
222
+ "__fixtures__",
223
+ "__test__/fixtures"
224
+ ];
225
+ static CONFIG_NAMES = [
226
+ "biome.jsonc",
227
+ "biome.json"
228
+ ];
229
+ static handler = Biome.create();
230
+ static findBiome() {
231
+ const result = Command_Command.findTool("biome");
232
+ return result.command;
233
+ }
234
+ static isAvailable() {
235
+ return Command_Command.findTool("biome").available;
236
+ }
237
+ static findConfig() {
238
+ const root = getWorkspaceRoot();
239
+ const searchDir = root ?? process.cwd();
240
+ for (const name of Biome.CONFIG_NAMES){
241
+ const fullPath = join(searchDir, name);
242
+ if (existsSync(fullPath)) return fullPath;
243
+ }
244
+ }
245
+ static findAllConfigs() {
246
+ const root = getWorkspaceRoot();
247
+ const configs = [];
248
+ if (null === root) {
249
+ const cwd = process.cwd();
250
+ for (const name of Biome.CONFIG_NAMES){
251
+ const fullPath = join(cwd, name);
252
+ if (existsSync(fullPath)) {
253
+ configs.push(fullPath);
254
+ break;
255
+ }
256
+ }
257
+ return configs;
258
+ }
259
+ for (const name of Biome.CONFIG_NAMES){
260
+ const fullPath = join(root, name);
261
+ if (existsSync(fullPath)) {
262
+ configs.push(fullPath);
263
+ break;
264
+ }
265
+ }
266
+ for (const pkgPath of getWorkspacePackagePaths())for (const name of Biome.CONFIG_NAMES){
267
+ const fullPath = join(pkgPath, name);
268
+ if (existsSync(fullPath)) {
269
+ configs.push(fullPath);
270
+ break;
271
+ }
272
+ }
273
+ return configs;
274
+ }
275
+ static create(options = {}) {
276
+ const excludes = options.exclude ?? [
277
+ ...Biome.defaultExcludes
278
+ ];
279
+ const config = options.config ?? Biome.findConfig();
280
+ return (filenames)=>{
281
+ const filtered = Filter.exclude(filenames, excludes);
282
+ if (0 === filtered.length) return [];
283
+ const biomeCmd = Command_Command.requireTool("biome", "Biome is not available. Install it globally (recommended) or add @biomejs/biome as a dev dependency.");
284
+ const files = Filter.shellEscape(filtered);
285
+ const flags = options.flags ?? [];
286
+ const configFlag = config ? `--config-path=${config}` : "";
287
+ const cmd = [
288
+ `${biomeCmd} check --write --no-errors-on-unmatched`,
289
+ configFlag,
290
+ ...flags,
291
+ files
292
+ ].filter(Boolean).join(" ");
293
+ return cmd;
294
+ };
295
+ }
296
+ }
16
297
  const HUSKY_HOOK_PATH = ".husky/pre-commit";
17
298
  const POST_CHECKOUT_HOOK_PATH = ".husky/post-checkout";
18
299
  const POST_MERGE_HOOK_PATH = ".husky/post-merge";
@@ -373,25 +654,31 @@ function checkMarkdownlintConfig(content) {
373
654
  }
374
655
  function checkBiomeSchemas() {
375
656
  return Effect.gen(function*() {
376
- const version = "2.4.9";
657
+ const version = "2.4.12";
377
658
  const statuses = [];
378
659
  if (!version) return {
379
660
  statuses,
380
661
  warnings: []
381
662
  };
382
- const syncer = yield* BiomeSchemaSync;
383
- const result = yield* syncer.check(version);
663
+ const fs = yield* FileSystem.FileSystem;
384
664
  const warnings = [];
385
- for (const configPath of result.current)statuses.push({
386
- path: configPath,
387
- matches: true
388
- });
389
- for (const configPath of result.updated){
390
- statuses.push({
665
+ const expectedSchema = `https://biomejs.dev/schemas/${version}/schema.json`;
666
+ const configPaths = Biome.findAllConfigs();
667
+ for (const configPath of configPaths){
668
+ const content = yield* fs.readFileString(configPath);
669
+ const parsed = yield* parse(content);
670
+ const currentSchema = parsed.$schema;
671
+ if (currentSchema === expectedSchema) statuses.push({
391
672
  path: configPath,
392
- matches: false
673
+ matches: true
393
674
  });
394
- warnings.push(`${WARNING} ${configPath}: biome $schema is outdated.\n Run 'savvy-lint init' to update it.`);
675
+ else {
676
+ statuses.push({
677
+ path: configPath,
678
+ matches: false
679
+ });
680
+ warnings.push(`${WARNING} ${configPath}: biome $schema is outdated.\n Run 'savvy-lint init' to update it.`);
681
+ }
395
682
  }
396
683
  return {
397
684
  statuses,
@@ -438,7 +725,7 @@ const checkCommand = Command.make("check", {
438
725
  if (status.found && status.needsUpdate) warnings.push(`${WARNING} Your ${hookPath} managed section is outdated.\n Run 'savvy-lint init' to update it (preserves your custom hooks).`);
439
726
  }
440
727
  }
441
- const biomeSchemaStatus = yield* checkBiomeSchemas().pipe(Effect.catchTag("BiomeSyncError", ()=>Effect.succeed({
728
+ const biomeSchemaStatus = yield* checkBiomeSchemas().pipe(Effect.catchAll(()=>Effect.succeed({
442
729
  statuses: [],
443
730
  warnings: [
444
731
  `${WARNING} Could not check biome $schema URLs.`
@@ -509,9 +796,6 @@ const checkCommand = Command.make("check", {
509
796
  if (tsgoAvailable) yield* Effect.log(` ${CHECK_MARK} TypeScript (tsgo)`);
510
797
  else if (tscAvailable) yield* Effect.log(` ${CHECK_MARK} TypeScript (tsc)`);
511
798
  else yield* Effect.log(` ${BULLET} TypeScript: not installed`);
512
- const tsdocConfig = yield* discovery.find("tsdoc.json");
513
- if (tsdocConfig) yield* Effect.log(` ${CHECK_MARK} TSDoc (tsdoc.json found)`);
514
- else yield* Effect.log(` ${BULLET} TSDoc: no tsdoc.json found`);
515
799
  if (hasMarkdownlintConfig) if (markdownlintStatus.isUpToDate) yield* Effect.log(` ${CHECK_MARK} ${MARKDOWNLINT_CONFIG_PATH}: up-to-date`);
516
800
  else {
517
801
  const issues = [];
@@ -530,145 +814,6 @@ const checkCommand = Command.make("check", {
530
814
  if (hasIssues) yield* Effect.log(`${WARNING} Some issues found. Run 'savvy-lint init' to fix.`);
531
815
  else yield* Effect.log(`${CHECK_MARK} Lint-staged is configured correctly.`);
532
816
  })).pipe(Command.withDescription("Check current lint-staged configuration and tool availability"));
533
- const VALID_COMMAND_PATTERN = /^[\w@/-]+$/;
534
- function validateCommandName(name) {
535
- if (!VALID_COMMAND_PATTERN.test(name)) throw new Error(`Invalid command name: "${name}". Only alphanumeric characters, hyphens, underscores, @ and / are allowed.`);
536
- }
537
- class Command_Command {
538
- static cachedPackageManager = null;
539
- static cachedRoot = null;
540
- static findRoot(cwd = process.cwd()) {
541
- if (null !== Command_Command.cachedRoot) return Command_Command.cachedRoot;
542
- let dir = resolve(cwd);
543
- while(true){
544
- if (existsSync(join(dir, "package.json"))) {
545
- Command_Command.cachedRoot = dir;
546
- return dir;
547
- }
548
- const parent = dirname(dir);
549
- if (parent === dir) break;
550
- dir = parent;
551
- }
552
- Command_Command.cachedRoot = cwd;
553
- return cwd;
554
- }
555
- static detectPackageManager(cwd = Command_Command.findRoot()) {
556
- if (null !== Command_Command.cachedPackageManager) return Command_Command.cachedPackageManager;
557
- const packageJsonPath = join(cwd, "package.json");
558
- if (!existsSync(packageJsonPath)) {
559
- Command_Command.cachedPackageManager = "npm";
560
- return "npm";
561
- }
562
- try {
563
- const content = readFileSync(packageJsonPath, "utf-8");
564
- const pkg = JSON.parse(content);
565
- if (pkg.packageManager) {
566
- const match = pkg.packageManager.match(/^(npm|pnpm|yarn|bun)@/);
567
- if (match) {
568
- Command_Command.cachedPackageManager = match[1];
569
- return Command_Command.cachedPackageManager;
570
- }
571
- }
572
- } catch {}
573
- Command_Command.cachedPackageManager = "npm";
574
- return "npm";
575
- }
576
- static getExecPrefix(packageManager) {
577
- switch(packageManager){
578
- case "pnpm":
579
- return [
580
- "pnpm",
581
- "exec"
582
- ];
583
- case "yarn":
584
- return [
585
- "yarn",
586
- "exec"
587
- ];
588
- case "bun":
589
- return [
590
- "bun",
591
- "x",
592
- "--no-install"
593
- ];
594
- default:
595
- return [
596
- "npx",
597
- "--no"
598
- ];
599
- }
600
- }
601
- static clearCache() {
602
- Command_Command.cachedPackageManager = null;
603
- Command_Command.cachedRoot = null;
604
- }
605
- static isAvailable(command) {
606
- validateCommandName(command);
607
- try {
608
- execSync(`command -v ${command}`, {
609
- stdio: "ignore"
610
- });
611
- return true;
612
- } catch {
613
- return false;
614
- }
615
- }
616
- static findTool(tool) {
617
- validateCommandName(tool);
618
- if (Command_Command.isAvailable(tool)) return {
619
- available: true,
620
- command: tool,
621
- source: "global"
622
- };
623
- const pm = Command_Command.detectPackageManager();
624
- const prefix = Command_Command.getExecPrefix(pm);
625
- const execCmd = [
626
- ...prefix,
627
- tool
628
- ].join(" ");
629
- try {
630
- execSync(`${execCmd} --version`, {
631
- stdio: "ignore"
632
- });
633
- return {
634
- available: true,
635
- command: execCmd,
636
- source: pm
637
- };
638
- } catch {}
639
- return {
640
- available: false,
641
- command: void 0,
642
- source: void 0
643
- };
644
- }
645
- static requireTool(tool, errorMessage) {
646
- const result = Command_Command.findTool(tool);
647
- if (!result.available || !result.command) throw new Error(errorMessage ?? `Required tool '${tool}' is not available. Install it globally or add it as a dev dependency.`);
648
- return result.command;
649
- }
650
- static findSavvyLint() {
651
- const result = Command_Command.findTool("savvy-lint");
652
- if (result.available && result.command) return result.command;
653
- const root = Command_Command.findRoot();
654
- return `node ${root}/dist/dev/bin/savvy-lint.js`;
655
- }
656
- static exec(command) {
657
- return execSync(command, {
658
- encoding: "utf-8"
659
- }).trim();
660
- }
661
- static execSilent(command) {
662
- try {
663
- execSync(command, {
664
- stdio: "ignore"
665
- });
666
- return true;
667
- } catch {
668
- return false;
669
- }
670
- }
671
- }
672
817
  const DEFAULT_STRINGIFY_OPTIONS = {
673
818
  indent: 2,
674
819
  lineWidth: 0,
@@ -730,29 +875,6 @@ class PnpmWorkspace {
730
875
  };
731
876
  }
732
877
  }
733
- class Filter {
734
- static exclude(filenames, patterns) {
735
- if (0 === patterns.length) return [
736
- ...filenames
737
- ];
738
- return filenames.filter((file)=>!patterns.some((pattern)=>file.includes(pattern)));
739
- }
740
- static include(filenames, patterns) {
741
- if (0 === patterns.length) return [];
742
- return filenames.filter((file)=>patterns.some((pattern)=>file.includes(pattern)));
743
- }
744
- static apply(filenames, options) {
745
- let result = [
746
- ...filenames
747
- ];
748
- if (options.include && options.include.length > 0) result = Filter.include(result, options.include);
749
- if (options.exclude && options.exclude.length > 0) result = Filter.exclude(result, options.exclude);
750
- return result;
751
- }
752
- static shellEscape(filenames) {
753
- return filenames.map((f)=>`'${f.replace(/'/g, "'\\''")}'`).join(" ");
754
- }
755
- }
756
878
  class Yaml {
757
879
  static glob = "**/*.{yml,yaml}";
758
880
  static defaultExcludes = [
@@ -762,9 +884,11 @@ class Yaml {
762
884
  ];
763
885
  static handler = Yaml.create();
764
886
  static findConfig() {
765
- const libPath = "lib/configs/.yaml-lint.json";
887
+ const root = getWorkspaceRoot() ?? process.cwd();
888
+ const libPath = join(root, "lib/configs/.yaml-lint.json");
766
889
  if (existsSync(libPath)) return libPath;
767
- if (existsSync(".yaml-lint.json")) return ".yaml-lint.json";
890
+ const rootPath = join(root, ".yaml-lint.json");
891
+ if (existsSync(rootPath)) return rootPath;
768
892
  }
769
893
  static loadConfig(filepath) {
770
894
  try {
@@ -935,7 +1059,7 @@ function writeMarkdownlintConfig(fs, preset, force) {
935
1059
  }
936
1060
  function syncBiomeSchemas() {
937
1061
  return Effect.gen(function*() {
938
- const version = "2.4.9";
1062
+ const version = "2.4.12";
939
1063
  if (!version) return;
940
1064
  const syncer = yield* BiomeSchemaSync;
941
1065
  const result = yield* syncer.sync(version);
@@ -1003,9 +1127,8 @@ const initCommand = Command.make("init", {
1003
1127
  }
1004
1128
  yield* Effect.log("\nDone! Lint-staged is ready to use.");
1005
1129
  })).pipe(Command.withDescription("Initialize lint-staged configuration and husky hooks"));
1006
- const WorkspaceLive = Layer.mergeAll(PackageManagerDetectorLive, WorkspaceRootLive);
1007
1130
  const SilkLive = Layer.mergeAll(ManagedSectionLive, BiomeSchemaSyncLive, ConfigDiscoveryLive, ToolDiscoveryLive);
1008
- const AppLayer = SilkLive.pipe(Layer.provideMerge(WorkspaceLive), Layer.provideMerge(NodeContext.layer));
1131
+ const AppLayer = SilkLive.pipe(Layer.provideMerge(WorkspacesLive), Layer.provideMerge(NodeContext.layer));
1009
1132
  const rootCommand = Command.make("savvy-lint").pipe(Command.withSubcommands([
1010
1133
  initCommand,
1011
1134
  checkCommand,
@@ -1013,10 +1136,10 @@ const rootCommand = Command.make("savvy-lint").pipe(Command.withSubcommands([
1013
1136
  ]));
1014
1137
  const cli = Command.run(rootCommand, {
1015
1138
  name: "savvy-lint",
1016
- version: "0.7.3"
1139
+ version: "1.0.0"
1017
1140
  });
1018
1141
  function runCli() {
1019
1142
  const main = Effect.suspend(()=>cli(process.argv)).pipe(Effect.provide(AppLayer));
1020
1143
  NodeRuntime.runMain(main);
1021
1144
  }
1022
- export { Command_Command as Command, Filter, PnpmWorkspace, Yaml, checkCommand, fmtCommand, initCommand, rootCommand, runCli };
1145
+ export { Biome, Command_Command as Command, Filter, PnpmWorkspace, Yaml, checkCommand, fmtCommand, getWorkspacePackagePaths, getWorkspacePackages, getWorkspaceRoot, initCommand, isWorkspacePackagePath, resetWorkspaceCache, rootCommand, runCli };
package/README.md CHANGED
@@ -13,9 +13,9 @@ sensible defaults and easy customization.
13
13
  - Composable handlers for Biome, Markdown, YAML, TypeScript, and more
14
14
  - Zero-config presets for instant setup
15
15
  - CLI tool (`savvy-lint`) to bootstrap and validate your configuration
16
- - Workspace-aware TSDoc validation for public APIs
16
+ - Workspace-aware config discovery anchored to workspace root
17
17
  - Shareable Biome configuration via `@savvy-web/lint-staged/biome/silk.jsonc`
18
- - Static class API with excellent TypeScript and TSDoc support
18
+ - Static class API with excellent TypeScript support
19
19
 
20
20
  ## Installation
21
21
 
@@ -79,7 +79,7 @@ export default {
79
79
  | `Yaml` | `**/*.{yml,yaml}` | Format (Prettier) and validate (yaml-lint) |
80
80
  | `PnpmWorkspace` | `pnpm-workspace.yaml` | Sort and format |
81
81
  | `ShellScripts` | `**/*.sh` | Manage permissions |
82
- | `TypeScript` | `*.{ts,cts,mts,tsx}` | TSDoc validation + typecheck |
82
+ | `TypeScript` | `*.{ts,cts,mts,tsx}` | Type checking (tsgo/tsc) |
83
83
 
84
84
  ## CLI
85
85
 
package/biome/silk.jsonc CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "https://biomejs.dev/schemas/2.4.5/schema.json",
2
+ "$schema": "https://biomejs.dev/schemas/2.4.12/schema.json",
3
3
  "assist": {
4
4
  "actions": {
5
5
  "source": {
@@ -133,9 +133,12 @@
133
133
  "!**/.vitest",
134
134
  "!**/.coverage",
135
135
  "!coverage",
136
+ "!**/__test__/fixtures",
137
+ "!**/__test__/snapshots",
136
138
  "!**/__test__/**/fixtures",
137
139
  "!**/__test__/**/snapshots",
138
- "!**/__fixtures__"
140
+ "!**/__fixtures__",
141
+ "!**/__snapshots__"
139
142
  ]
140
143
  }
141
144
  }