@next-vibe/checker 3.0.2 → 3.0.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@next-vibe/checker",
3
- "version": "3.0.2",
3
+ "version": "3.0.3",
4
4
  "description": "Standalone code quality checker (oxlint + eslint + TypeScript) for next-vibe projects",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -20,10 +20,16 @@
20
20
  "bin": {
21
21
  "vibe-check": "./bin/vibe-check.js"
22
22
  },
23
+ "exports": {
24
+ "./system/check/config/types": "./system/check/config/types.ts",
25
+ "./system/check/oxlint/types": "./system/check/oxlint/types.ts",
26
+ "./oxlint-plugins/*": "./oxlint-plugins/*"
27
+ },
23
28
  "files": [
24
29
  "bin/",
25
30
  "generated/",
26
31
  "oxlint-plugins/",
32
+ "system/",
27
33
  "check.config.ts",
28
34
  "README.md",
29
35
  "LICENSE"
@@ -0,0 +1,676 @@
1
+ /**
2
+ * Unified Check Configuration Types
3
+ *
4
+ * Centralized type definitions for all code quality tools:
5
+ * - Oxlint (fast Rust linter)
6
+ * - Prettier (code formatting)
7
+ * - TypeScript (type checking)
8
+ * - Testing (vitest/jest)
9
+ * - VSCode integration
10
+ */
11
+
12
+ // ============================================================
13
+ // Common Types
14
+ // ============================================================
15
+
16
+ export type Severity = "off" | "warn" | "error" | "allow" | "deny";
17
+
18
+ export type LintPrimitive = string | number | boolean;
19
+
20
+ export type LintConfigValue =
21
+ | LintPrimitive
22
+ | LintPrimitive[]
23
+ | readonly LintPrimitive[]
24
+ | LintConfigObject
25
+ | readonly LintConfigObject[]
26
+ | LintConfigObject[]
27
+ | (LintPrimitive | LintConfigObject)[]
28
+ | readonly (LintPrimitive | LintConfigObject)[]
29
+ | I18nPluginConfig;
30
+
31
+ export interface LintConfigObject {
32
+ [key: string]: LintConfigValue;
33
+ }
34
+
35
+ export type LintConfigElement = Record<string, LintConfigValue>;
36
+
37
+ /** JSON-compatible value type for settings files */
38
+ export type JsonValue =
39
+ | string
40
+ | number
41
+ | boolean
42
+ | null
43
+ | JsonObject
44
+ | JsonArray;
45
+ export interface JsonObject {
46
+ [key: string]: JsonValue;
47
+ }
48
+ export type JsonArray = JsonValue[];
49
+
50
+ // Forward declaration for circular reference
51
+ export interface I18nPluginConfig {
52
+ words?: {
53
+ exclude?: readonly string[] | string[];
54
+ };
55
+ "jsx-attributes"?: {
56
+ exclude?: readonly string[] | string[];
57
+ };
58
+ "object-properties"?: {
59
+ exclude?: readonly string[] | string[];
60
+ };
61
+ }
62
+
63
+ export interface RestrictedSyntaxPluginConfig {
64
+ /** Properties that commonly accept JSX/React nodes as values */
65
+ jsxAllowedProperties?: readonly string[] | string[];
66
+ }
67
+
68
+ export interface JsxCapitalizationPluginConfig {
69
+ /** Paths to exclude from jsx-capitalization rule */
70
+ excludedPaths?: readonly string[] | string[];
71
+ /** File patterns to exclude (email templates, test files) */
72
+ excludedFilePatterns?: readonly string[] | string[];
73
+ /** Typography elements that should import from typography module */
74
+ typographyElements?: readonly string[] | string[];
75
+ /** Elements with dedicated component files */
76
+ standaloneElements?: readonly string[] | string[];
77
+ /** SVG elements that need platform-independent handling */
78
+ svgElements?: readonly string[] | string[];
79
+ /** Image-related elements */
80
+ imageElements?: readonly string[] | string[];
81
+ /** Common UI elements that should have wrapper components */
82
+ commonUiElements?: readonly string[] | string[];
83
+ }
84
+
85
+ // ============================================================
86
+ // Oxlint Configuration
87
+ // ============================================================
88
+
89
+ /** JS plugin configuration with path and options */
90
+ export interface OxlintJsPlugin {
91
+ /** Path to the JS plugin file (e.g., "next-vibe/src/.../plugin/src/index.ts") */
92
+ path: string;
93
+ /** Plugin options - will be used when oxlint supports options natively */
94
+ options?:
95
+ | I18nPluginConfig
96
+ | RestrictedSyntaxPluginConfig
97
+ | JsxCapitalizationPluginConfig
98
+ | LintConfigElement;
99
+ }
100
+
101
+ /** Optional oxlint settings (shared between enabled/disabled) */
102
+ interface OxlintConfigOptions {
103
+ $schema?: string;
104
+ /** File patterns to ignore (globs) - resolves relative to config file */
105
+ ignorePatterns?: string[];
106
+ /** Extra ignore patterns applied only in non-extensive mode (pre-formatted for oxlint) */
107
+ nonExtensiveIgnorePatterns?: string[];
108
+ /** Built-in oxlint plugins (e.g., "react", "typescript", "jsx-a11y") */
109
+ plugins?: string[];
110
+ /** Custom JS plugins - string paths or objects with path+options for future oxlint native support */
111
+ jsPlugins?: (string | OxlintJsPlugin)[];
112
+ categories?: {
113
+ correctness?: Severity;
114
+ suspicious?: Severity;
115
+ pedantic?: Severity;
116
+ style?: Severity;
117
+ nursery?: Severity;
118
+ restriction?: Severity;
119
+ };
120
+ rules?: LintConfigElement;
121
+ settings?: {
122
+ "jsx-a11y"?: {
123
+ polymorphicPropName?: string | null;
124
+ components?: Record<string, string>;
125
+ attributes?: Record<string, string>;
126
+ };
127
+ next?: {
128
+ rootDir?: string[];
129
+ };
130
+ react?: {
131
+ formComponents?: string[];
132
+ linkComponents?: string[];
133
+ };
134
+ jsdoc?: {
135
+ ignorePrivate?: boolean;
136
+ ignoreInternal?: boolean;
137
+ ignoreReplacesDocs?: boolean;
138
+ overrideReplacesDocs?: boolean;
139
+ augmentsExtendsReplacesDocs?: boolean;
140
+ implementsReplacesDocs?: boolean;
141
+ exemptDestructuredRootsFromChecks?: boolean;
142
+ tagNamePreference?: Record<string, string>;
143
+ };
144
+ };
145
+ env?: {
146
+ builtin?: boolean;
147
+ };
148
+ globals?: Record<string, "readonly" | "writable" | "off">;
149
+ }
150
+
151
+ /** Oxlint disabled - no other settings required */
152
+ interface OxlintConfigDisabled {
153
+ enabled: false;
154
+ }
155
+
156
+ /** Oxlint enabled - required paths */
157
+ interface OxlintConfigEnabled extends OxlintConfigOptions {
158
+ enabled: true;
159
+ /** Path to generated oxlint config file */
160
+ configPath: string;
161
+ /** Path to cache directory for oxlint */
162
+ cachePath: string;
163
+ /** File extensions to lint (e.g., [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]) */
164
+ lintableExtensions: string[];
165
+ }
166
+
167
+ export type OxlintConfig = OxlintConfigDisabled | OxlintConfigEnabled;
168
+
169
+ // ============================================================
170
+ // Prettier Configuration
171
+ // ============================================================
172
+
173
+ /** Optional prettier settings */
174
+ interface PrettierConfigOptions {
175
+ semi?: boolean;
176
+ singleQuote?: boolean;
177
+ trailingComma?: "none" | "es5" | "all";
178
+ tabWidth?: number;
179
+ useTabs?: boolean;
180
+ printWidth?: number;
181
+ arrowParens?: "avoid" | "always";
182
+ endOfLine?: "lf" | "crlf" | "cr" | "auto";
183
+ bracketSpacing?: boolean;
184
+ jsxSingleQuote?: boolean;
185
+ jsxBracketSameLine?: boolean;
186
+ proseWrap?: "always" | "never" | "preserve";
187
+ }
188
+
189
+ /** Prettier disabled */
190
+ interface PrettierConfigDisabled {
191
+ enabled: false;
192
+ }
193
+
194
+ /** Prettier enabled - required config path */
195
+ interface PrettierConfigEnabled extends PrettierConfigOptions {
196
+ enabled: true;
197
+ /** Path to generated prettier/oxfmt config file */
198
+ configPath: string;
199
+ /** Path to generated .prettierignore file for oxfmt --ignore-path */
200
+ ignoreFilePath?: string;
201
+ }
202
+
203
+ export type PrettierConfig = PrettierConfigDisabled | PrettierConfigEnabled;
204
+
205
+ // ============================================================
206
+ // TypeScript/TypeCheck Configuration
207
+ // ============================================================
208
+
209
+ /** Typecheck disabled */
210
+ interface TypecheckConfigDisabled {
211
+ enabled: false;
212
+ }
213
+
214
+ /** Typecheck enabled */
215
+ interface TypecheckConfigEnabled {
216
+ enabled: true;
217
+ /** Path to directory for tsbuildinfo cache files */
218
+ cachePath: string;
219
+ /** Use tsgo instead of tsc for type checking (default: false uses tsc) */
220
+ useTsgo?: boolean;
221
+ /** Extra ignore patterns applied only in non-extensive mode (glob patterns for tsconfig exclude) */
222
+ nonExtensiveIgnorePatterns?: string[];
223
+ }
224
+
225
+ export type TypecheckConfig = TypecheckConfigDisabled | TypecheckConfigEnabled;
226
+
227
+ // ============================================================
228
+ // ESLint Configuration
229
+ // ============================================================
230
+
231
+ /** ESLint flat config item */
232
+ export interface EslintFlatConfigItem {
233
+ /** File patterns to match */
234
+ files?: string[];
235
+ /** Patterns to ignore */
236
+ ignores?: string[];
237
+ /** Language options including parser */
238
+ languageOptions?: {
239
+ parser?: EslintParser;
240
+ parserOptions?: EslintParserOptions;
241
+ ecmaVersion?: number | "latest";
242
+ sourceType?: "module" | "script" | "commonjs";
243
+ globals?: Record<string, "readonly" | "writable" | "off" | boolean>;
244
+ };
245
+ /** Linter options */
246
+ linterOptions?: {
247
+ reportUnusedDisableDirectives?: "off" | "warn" | "error" | boolean;
248
+ noInlineConfig?: boolean;
249
+ };
250
+ /**
251
+ * ESLint plugins - accepts any plugin shape.
252
+ *
253
+ * ESLint plugins have diverse type signatures across the ecosystem.
254
+ * We use object type for compatibility with all plugin packages.
255
+ */
256
+ plugins?: Record<string, EslintPluginLike>;
257
+ /** ESLint rules */
258
+ rules?: LintConfigElement;
259
+ /** Settings */
260
+ settings?: LintConfigElement;
261
+ }
262
+
263
+ /**
264
+ * ESLint plugin interface - accepts any valid plugin.
265
+ *
266
+ * ESLint plugins from different packages have incompatible types.
267
+ * This is a structural interface that all plugins satisfy.
268
+ */
269
+ export interface EslintPluginLike {
270
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- ESLint plugin types are too diverse
271
+ rules?: Record<string, { create: (...args: any[]) => any }>;
272
+ }
273
+
274
+ /**
275
+ * ESLint parser interface - accepts any valid parser.
276
+ *
277
+ * Parsers must have parseForESLint method that returns AST.
278
+ */
279
+ export interface EslintParser {
280
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Parser types vary across packages
281
+ parseForESLint?: (...args: any[]) => { ast: any; scopeManager?: any };
282
+ }
283
+
284
+ /** ESLint parser options */
285
+ export interface EslintParserOptions {
286
+ ecmaVersion?: number | "latest";
287
+ sourceType?: "module" | "script" | "commonjs";
288
+ ecmaFeatures?: {
289
+ jsx?: boolean;
290
+ globalReturn?: boolean;
291
+ impliedStrict?: boolean;
292
+ };
293
+ project?: string | string[];
294
+ tsconfigRootDir?: string;
295
+ [key: string]: LintConfigValue | undefined;
296
+ }
297
+
298
+ /** ESLint parse result */
299
+ export interface EslintParseResult {
300
+ ast?: LintConfigElement;
301
+ services?: LintConfigElement;
302
+ scopeManager?: LintConfigElement;
303
+ visitorKeys?: LintConfigElement;
304
+ }
305
+
306
+ /** ESLint plugin interface - matches ESLint's Plugin type */
307
+ export interface EslintPlugin {
308
+ rules?: Record<string, EslintRule>;
309
+ configs?: Record<string, EslintPluginConfig>;
310
+ processors?: Record<string, EslintProcessor>;
311
+ meta?: EslintPluginMeta;
312
+ }
313
+
314
+ /** ESLint plugin metadata */
315
+ export interface EslintPluginMeta {
316
+ name?: string;
317
+ version?: string;
318
+ }
319
+
320
+ /** ESLint plugin config (shareable config) */
321
+ export interface EslintPluginConfig {
322
+ plugins?: Record<string, EslintPlugin>;
323
+ rules?: LintConfigElement;
324
+ languageOptions?: LintConfigElement;
325
+ settings?: LintConfigElement;
326
+ }
327
+
328
+ /** ESLint processor interface */
329
+ export interface EslintProcessor {
330
+ preprocess?: (
331
+ text: string,
332
+ filename: string,
333
+ ) => Array<string | { text: string; filename: string }>;
334
+ postprocess?: (
335
+ messages: LintConfigElement[][],
336
+ filename: string,
337
+ ) => LintConfigElement[];
338
+ supportsAutofix?: boolean;
339
+ }
340
+
341
+ /** ESLint rule interface - matches ESLint's LooseRuleDefinition */
342
+ export type EslintRule = EslintRuleFunction | EslintRuleModule;
343
+
344
+ /** ESLint rule as a function */
345
+ export type EslintRuleFunction = (
346
+ context: EslintRuleContext,
347
+ ) => EslintRuleListener;
348
+
349
+ /** ESLint rule as a module with create function */
350
+ export interface EslintRuleModule {
351
+ create: EslintRuleFunction;
352
+ meta?: EslintRuleMeta;
353
+ }
354
+
355
+ /** ESLint rule context (simplified) */
356
+ export interface EslintRuleContext {
357
+ report: (descriptor: EslintReportDescriptor) => void;
358
+ options: LintConfigValue[];
359
+ getSourceCode: () => EslintSourceCode;
360
+ getFilename: () => string;
361
+ getCwd: () => string;
362
+ }
363
+
364
+ /** ESLint report descriptor */
365
+ export interface EslintReportDescriptor {
366
+ node?: LintConfigElement;
367
+ message?: string;
368
+ messageId?: string;
369
+ data?: Record<string, string | number>;
370
+ loc?: { line: number; column: number };
371
+ fix?: (fixer: EslintFixer) => EslintFix | EslintFix[] | null;
372
+ suggest?: EslintSuggestion[];
373
+ }
374
+
375
+ /** ESLint fixer */
376
+ export interface EslintFixer {
377
+ insertTextAfter: (node: LintConfigElement, text: string) => EslintFix;
378
+ insertTextBefore: (node: LintConfigElement, text: string) => EslintFix;
379
+ remove: (node: LintConfigElement) => EslintFix;
380
+ replaceText: (node: LintConfigElement, text: string) => EslintFix;
381
+ replaceTextRange: (range: [number, number], text: string) => EslintFix;
382
+ }
383
+
384
+ /** ESLint fix */
385
+ export interface EslintFix {
386
+ range: [number, number];
387
+ text: string;
388
+ }
389
+
390
+ /** ESLint suggestion */
391
+ export interface EslintSuggestion {
392
+ desc?: string;
393
+ messageId?: string;
394
+ data?: Record<string, string | number>;
395
+ fix: (fixer: EslintFixer) => EslintFix | EslintFix[] | null;
396
+ }
397
+
398
+ /** ESLint source code */
399
+ export interface EslintSourceCode {
400
+ getText: (node?: LintConfigElement) => string;
401
+ getLines: () => string[];
402
+ getAllComments: () => LintConfigElement[];
403
+ }
404
+
405
+ /** ESLint rule listener */
406
+ export interface EslintRuleListener {
407
+ [selector: string]: ((node: LintConfigElement) => void) | undefined;
408
+ }
409
+
410
+ /** ESLint rule meta */
411
+ export interface EslintRuleMeta {
412
+ type?: "problem" | "suggestion" | "layout";
413
+ docs?: {
414
+ description?: string;
415
+ recommended?: boolean | "error" | "warn";
416
+ url?: string;
417
+ };
418
+ fixable?: "code" | "whitespace";
419
+ hasSuggestions?: boolean;
420
+ schema?: LintConfigValue[];
421
+ deprecated?: boolean;
422
+ replacedBy?: string[];
423
+ messages?: Record<string, string>;
424
+ }
425
+
426
+ /** Optional ESLint settings */
427
+ interface EslintConfigOptions {
428
+ /** ESLint flat config array - directly used by eslint.config.mjs */
429
+ flatConfig?: EslintFlatConfigItem[];
430
+ /** Patterns to ignore */
431
+ ignores?: string[];
432
+ /** Extra ignore patterns applied only in non-extensive mode (pre-formatted for eslint) */
433
+ nonExtensiveIgnorePatterns?: string[];
434
+ }
435
+
436
+ /** ESLint disabled */
437
+ interface EslintConfigDisabled {
438
+ enabled: false;
439
+ }
440
+
441
+ /** ESLint enabled - required paths */
442
+ interface EslintConfigEnabled extends EslintConfigOptions {
443
+ enabled: true;
444
+ /** Path to generated ESLint config file */
445
+ configPath: string;
446
+ /** Path to cache directory for ESLint */
447
+ cachePath: string;
448
+ /** File extensions to lint (e.g., [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]) */
449
+ lintableExtensions: string[];
450
+ /** Build flat config with plugins (called from eslint.config.mjs) */
451
+ buildFlatConfig: (
452
+ reactCompilerPlugin: EslintPluginLike,
453
+ reactHooksPlugin: EslintPluginLike,
454
+ simpleImportSortPlugin: EslintPluginLike,
455
+ tseslint: { parser: EslintParser },
456
+ ) => EslintFlatConfigItem[];
457
+ }
458
+
459
+ export type EslintConfig = EslintConfigDisabled | EslintConfigEnabled;
460
+
461
+ // ============================================================
462
+ // Testing Configuration
463
+ // ============================================================
464
+
465
+ /** Optional testing settings */
466
+ interface TestingConfigOptions {
467
+ /** Command to run tests (default: "bunx vitest") */
468
+ command?: string;
469
+ /** Timeout for test runs in milliseconds */
470
+ timeout?: number;
471
+ /** Test file patterns */
472
+ include?: string[];
473
+ /** Patterns to exclude from testing */
474
+ exclude?: string[];
475
+ /** Coverage configuration */
476
+ coverage?: {
477
+ enabled?: boolean;
478
+ provider?: "v8" | "istanbul";
479
+ thresholds?: {
480
+ lines?: number;
481
+ branches?: number;
482
+ functions?: number;
483
+ statements?: number;
484
+ };
485
+ };
486
+ }
487
+
488
+ /** Testing disabled */
489
+ interface TestingConfigDisabled {
490
+ enabled: false;
491
+ }
492
+
493
+ /** Testing enabled */
494
+ interface TestingConfigEnabled extends TestingConfigOptions {
495
+ enabled: true;
496
+ }
497
+
498
+ export type TestingConfig = TestingConfigDisabled | TestingConfigEnabled;
499
+
500
+ // ============================================================
501
+ // VSCode Integration Configuration
502
+ // ============================================================
503
+
504
+ /** Optional VSCode settings */
505
+ interface VSCodeConfigOptions {
506
+ /** Whether to auto-generate VSCode settings */
507
+ autoGenerateSettings?: boolean;
508
+ /** Path to VSCode settings file */
509
+ settingsPath?: string;
510
+ /** Custom VSCode settings to merge */
511
+ settings?: {
512
+ /** Oxc extension settings */
513
+ oxc?: {
514
+ enable?: boolean;
515
+ lintRun?: "onSave" | "onType";
516
+ configPath?: string;
517
+ fmtConfigPath?: string;
518
+ fmtExperimental?: boolean;
519
+ typeAware?: boolean;
520
+ traceServer?: "off" | "messages" | "verbose";
521
+ };
522
+ /** Editor settings */
523
+ editor?: {
524
+ formatOnSave?: boolean;
525
+ defaultFormatter?: string;
526
+ codeActionsOnSave?: Record<string, "explicit" | "always" | "never">;
527
+ };
528
+ /** TypeScript settings */
529
+ typescript?: {
530
+ validateEnable?: boolean;
531
+ suggestAutoImports?: boolean;
532
+ preferTypeOnlyAutoImports?: boolean;
533
+ experimentalUseTsgo?: boolean;
534
+ };
535
+ /** File settings */
536
+ files?: {
537
+ eol?: "\n" | "\r\n";
538
+ exclude?: Record<string, boolean>;
539
+ };
540
+ /** Search settings */
541
+ search?: {
542
+ exclude?: Record<string, boolean>;
543
+ };
544
+ };
545
+ }
546
+
547
+ /** VSCode disabled */
548
+ interface VSCodeConfigDisabled {
549
+ enabled: false;
550
+ }
551
+
552
+ /** VSCode enabled */
553
+ interface VSCodeConfigEnabled extends VSCodeConfigOptions {
554
+ enabled: true;
555
+ }
556
+
557
+ export type VSCodeConfig = VSCodeConfigDisabled | VSCodeConfigEnabled;
558
+
559
+ // ============================================================
560
+ // Feature Switches
561
+ // ============================================================
562
+
563
+ export interface FeatureSwitches {
564
+ /** Enable i18n literal string checking */
565
+ i18n?: boolean;
566
+ /** Enable React-specific rules */
567
+ react?: boolean;
568
+ /** Enable accessibility rules (jsx-a11y) */
569
+ accessibility?: boolean;
570
+ /** Enable import rules */
571
+ import?: boolean;
572
+ /** Enable promise rules */
573
+ promise?: boolean;
574
+ /** Enable Node.js rules */
575
+ node?: boolean;
576
+ /** Enable pedantic rules (stricter checks) */
577
+ pedantic?: boolean;
578
+ /** Use tsgo instead of tsc for type checking */
579
+ tsgo?: boolean;
580
+ }
581
+
582
+ // ============================================================
583
+ // Vibe Check Configuration
584
+ // ============================================================
585
+
586
+ /** Vibe Check defaults */
587
+ export interface VibeCheckConfig {
588
+ /** Auto-fix issues (default: false) */
589
+ fix?: boolean;
590
+ /** Skip ESLint checks (default: false) */
591
+ skipEslint?: boolean;
592
+ /** Skip Oxlint checks (default: false) */
593
+ skipOxlint?: boolean;
594
+ /** Skip TypeScript checks (default: false) */
595
+ skipTypecheck?: boolean;
596
+ /** Timeout in seconds (default: 3600) */
597
+ timeout?: number;
598
+ /** Max issues to display per page (default: 200) */
599
+ limit?: number;
600
+ /** Max issues to display per page for MCP platform (default: 100) */
601
+ mcpLimit?: number;
602
+ /** Max files to show in summary (default: 50) */
603
+ maxFilesInSummary?: number;
604
+ /** Editor URI scheme for clickable file links (default: "vscode://file/") */
605
+ editorUriScheme?: string;
606
+ /**
607
+ * When false (default), skips test files (*.test.ts, *.test.tsx) and
608
+ * generated files (system/generated/**). Set to true for release validation
609
+ * or when you explicitly want to audit generated/test code.
610
+ * The actual ignore patterns are defined per-checker via nonExtensiveIgnorePatterns
611
+ * on oxlint, eslint, and typecheck configs (formatted by formatIgnorePatterns).
612
+ */
613
+ extensive?: boolean;
614
+ }
615
+
616
+ // ============================================================
617
+ // Unified Check Configuration
618
+ // ============================================================
619
+
620
+ export interface CheckConfig {
621
+ /** Oxlint linter configuration */
622
+ oxlint: OxlintConfig;
623
+
624
+ /** ESLint linter configuration (for rules oxlint doesn't support) */
625
+ eslint: EslintConfig;
626
+
627
+ /** Prettier formatter configuration */
628
+ prettier: PrettierConfig;
629
+
630
+ /** TypeScript type checking configuration */
631
+ typecheck: TypecheckConfig;
632
+
633
+ /** Testing configuration */
634
+ testing?: TestingConfig;
635
+
636
+ /** VSCode integration settings */
637
+ vscode: VSCodeConfig;
638
+
639
+ /** Vibe Check defaults */
640
+ vibeCheck?: VibeCheckConfig;
641
+ }
642
+
643
+ // ============================================================
644
+ // Config Repository Result Types
645
+ // ============================================================
646
+
647
+ export interface ConfigReadyResult {
648
+ ready: true;
649
+ config: CheckConfig;
650
+ regenerated: boolean;
651
+ }
652
+
653
+ export interface ConfigErrorResult {
654
+ ready: false;
655
+ error: "missing" | "exists" | "creation_failed" | "load_failed";
656
+ message: string;
657
+ configPath: string;
658
+ }
659
+
660
+ export type EnsureConfigResult = ConfigReadyResult | ConfigErrorResult;
661
+
662
+ // ============================================================
663
+ // Config Repository Internal Result Types
664
+ // ============================================================
665
+
666
+ export interface GenerateVSCodeSettingsResult {
667
+ settingsPath: string;
668
+ }
669
+
670
+ export interface CreateDefaultCheckConfigResult {
671
+ configPath: string;
672
+ }
673
+
674
+ export interface CreateDefaultMcpConfigResult {
675
+ mcpConfigPath: string;
676
+ }
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Oxlint Configuration Types
3
+ */
4
+
5
+ import type { Severity } from "../config/types";
6
+
7
+ /**
8
+ * Oxlint AST Node Types
9
+ * These types define the structure of AST nodes for Oxlint plugin development
10
+ */
11
+
12
+ // Base AST Node interface
13
+ export interface OxlintASTNode {
14
+ type: string;
15
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
+ [key: string]: any;
17
+ }
18
+
19
+ // JSX-specific AST nodes
20
+ export interface JSXIdentifier extends OxlintASTNode {
21
+ type: "JSXIdentifier" | "Identifier";
22
+ name: string;
23
+ }
24
+
25
+ export interface JSXLiteral extends OxlintASTNode {
26
+ type: "Literal";
27
+ value: string | number | boolean | null;
28
+ }
29
+
30
+ export interface JSXAttribute extends OxlintASTNode {
31
+ type: "JSXAttribute";
32
+ name: JSXIdentifier;
33
+ value?: JSXLiteral | OxlintASTNode;
34
+ }
35
+
36
+ export interface JSXText extends OxlintASTNode {
37
+ type: "JSXText";
38
+ value: string;
39
+ }
40
+
41
+ // Property node for object literals
42
+ export interface Property extends OxlintASTNode {
43
+ type: "Property";
44
+ key?: OxlintASTNode;
45
+ value?: OxlintASTNode;
46
+ computed?: boolean;
47
+ method?: boolean;
48
+ }
49
+
50
+ // TypeScript-specific nodes
51
+ export interface TSUnknownKeyword extends OxlintASTNode {
52
+ type: "TSUnknownKeyword";
53
+ }
54
+
55
+ export interface TSObjectKeyword extends OxlintASTNode {
56
+ type: "TSObjectKeyword";
57
+ }
58
+
59
+ // Statement nodes
60
+ export interface ThrowStatement extends OxlintASTNode {
61
+ type: "ThrowStatement";
62
+ argument?: OxlintASTNode;
63
+ }
64
+
65
+ // Expression nodes
66
+ export interface ParenthesizedExpression extends OxlintASTNode {
67
+ type: "ParenthesizedExpression";
68
+ expression?: OxlintASTNode;
69
+ }
70
+
71
+ // Comment interface
72
+ export interface OxlintComment {
73
+ type: "Line" | "Block";
74
+ value: string;
75
+ }
76
+
77
+ // Rule Context for plugins
78
+ export interface OxlintRuleContext {
79
+ report: (descriptor: { node: OxlintASTNode; message: string }) => void;
80
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
81
+ options?: any[];
82
+ getCommentsInside?: (node: OxlintASTNode) => OxlintComment[];
83
+ getCommentsBefore?: (node: OxlintASTNode) => OxlintComment[];
84
+ getFilename?: () => string;
85
+ filename?: string;
86
+ sourceCode?: {
87
+ getCommentsBefore?: (node: OxlintASTNode) => OxlintComment[];
88
+ getCommentsInside?: (node: OxlintASTNode) => OxlintComment[];
89
+ };
90
+ }
91
+
92
+ // Type guard helpers for AST nodes
93
+ export function isJSXIdentifier(node: OxlintASTNode): node is JSXIdentifier {
94
+ return node.type === "JSXIdentifier" || node.type === "Identifier";
95
+ }
96
+
97
+ export function isJSXLiteral(node: OxlintASTNode): node is JSXLiteral {
98
+ return node.type === "Literal";
99
+ }
100
+
101
+ export function isProperty(node: OxlintASTNode): node is Property {
102
+ return (
103
+ node.type === "Property" && typeof (node as Property).method === "boolean"
104
+ );
105
+ }
106
+
107
+ export interface OxlintLabel {
108
+ span: {
109
+ offset: number;
110
+ length: number;
111
+ line: number;
112
+ column: number;
113
+ };
114
+ message?: string;
115
+ }
116
+
117
+ export interface OxlintConfig {
118
+ $schema?: string;
119
+ plugins?: string[];
120
+ jsPlugins?: string[];
121
+ categories?: {
122
+ correctness?: Severity;
123
+ suspicious?: Severity;
124
+ pedantic?: Severity;
125
+ style?: Severity;
126
+ nursery?: Severity;
127
+ restriction?: Severity;
128
+ };
129
+ rules?: LintConfigElement;
130
+ settings?: {
131
+ "jsx-a11y"?: {
132
+ polymorphicPropName?: string | null;
133
+ components?: Record<string, string>;
134
+ attributes?: Record<string, string>;
135
+ };
136
+ next?: {
137
+ rootDir?: string[];
138
+ };
139
+ react?: {
140
+ formComponents?: string[];
141
+ linkComponents?: string[];
142
+ };
143
+ jsdoc?: {
144
+ ignorePrivate?: boolean;
145
+ ignoreInternal?: boolean;
146
+ ignoreReplacesDocs?: boolean;
147
+ overrideReplacesDocs?: boolean;
148
+ augmentsExtendsReplacesDocs?: boolean;
149
+ implementsReplacesDocs?: boolean;
150
+ exemptDestructuredRootsFromChecks?: boolean;
151
+ tagNamePreference?: Record<string, string>;
152
+ };
153
+ };
154
+ env?: {
155
+ builtin?: boolean;
156
+ };
157
+ globals?: Record<string, "readonly" | "writable" | "off">;
158
+ }
159
+
160
+ /**
161
+ * Prettier Configuration
162
+ * Aligned with project formatting standards
163
+ */
164
+ export interface PrettierConfig {
165
+ semi: boolean;
166
+ singleQuote: boolean;
167
+ trailingComma: "none" | "es5" | "all";
168
+ tabWidth: number;
169
+ useTabs: boolean;
170
+ printWidth: number;
171
+ arrowParens: "avoid" | "always";
172
+ endOfLine: "lf" | "crlf" | "cr" | "auto";
173
+ bracketSpacing: boolean;
174
+ jsxSingleQuote: boolean;
175
+ jsxBracketSameLine: boolean;
176
+ proseWrap: "always" | "never" | "preserve";
177
+ }
178
+
179
+ type LintPrimitive = string | number | boolean;
180
+
181
+ type LintConfigValue =
182
+ | LintPrimitive
183
+ | LintPrimitive[]
184
+ | LintConfigObject
185
+ | LintConfigObject[]
186
+ | (LintPrimitive | LintConfigObject)[];
187
+
188
+ interface LintConfigObject {
189
+ [key: string]: LintConfigValue;
190
+ }
191
+
192
+ type LintConfigElement = Record<string, LintConfigValue>;