frontend-guardian-core 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/LICENSE +21 -0
  2. package/bin/fg-core.js +1238 -0
  3. package/bin/watch-mode.js +123 -0
  4. package/dist/engine/cache.d.ts +68 -0
  5. package/dist/engine/cache.d.ts.map +1 -0
  6. package/dist/engine/cache.js +164 -0
  7. package/dist/engine/cache.js.map +1 -0
  8. package/dist/engine/rule-engine.d.ts +135 -0
  9. package/dist/engine/rule-engine.d.ts.map +1 -0
  10. package/dist/engine/rule-engine.js +716 -0
  11. package/dist/engine/rule-engine.js.map +1 -0
  12. package/dist/formatters/github-annotation.d.ts +36 -0
  13. package/dist/formatters/github-annotation.d.ts.map +1 -0
  14. package/dist/formatters/github-annotation.js +122 -0
  15. package/dist/formatters/github-annotation.js.map +1 -0
  16. package/dist/formatters/pr-comment.d.ts +43 -0
  17. package/dist/formatters/pr-comment.d.ts.map +1 -0
  18. package/dist/formatters/pr-comment.js +171 -0
  19. package/dist/formatters/pr-comment.js.map +1 -0
  20. package/dist/formatters/sarif.d.ts +104 -0
  21. package/dist/formatters/sarif.d.ts.map +1 -0
  22. package/dist/formatters/sarif.js +130 -0
  23. package/dist/formatters/sarif.js.map +1 -0
  24. package/dist/index.d.ts +46 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +108 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/integrations/base.d.ts +44 -0
  29. package/dist/integrations/base.d.ts.map +1 -0
  30. package/dist/integrations/base.js +104 -0
  31. package/dist/integrations/base.js.map +1 -0
  32. package/dist/integrations/eslint.d.ts +8 -0
  33. package/dist/integrations/eslint.d.ts.map +1 -0
  34. package/dist/integrations/eslint.js +67 -0
  35. package/dist/integrations/eslint.js.map +1 -0
  36. package/dist/integrations/formatter.d.ts +35 -0
  37. package/dist/integrations/formatter.d.ts.map +1 -0
  38. package/dist/integrations/formatter.js +182 -0
  39. package/dist/integrations/formatter.js.map +1 -0
  40. package/dist/integrations/index.d.ts +17 -0
  41. package/dist/integrations/index.d.ts.map +1 -0
  42. package/dist/integrations/index.js +25 -0
  43. package/dist/integrations/index.js.map +1 -0
  44. package/dist/integrations/stylelint.d.ts +8 -0
  45. package/dist/integrations/stylelint.d.ts.map +1 -0
  46. package/dist/integrations/stylelint.js +59 -0
  47. package/dist/integrations/stylelint.js.map +1 -0
  48. package/dist/integrations/typescript.d.ts +8 -0
  49. package/dist/integrations/typescript.d.ts.map +1 -0
  50. package/dist/integrations/typescript.js +92 -0
  51. package/dist/integrations/typescript.js.map +1 -0
  52. package/dist/rules/registry.d.ts +83 -0
  53. package/dist/rules/registry.d.ts.map +1 -0
  54. package/dist/rules/registry.js +205 -0
  55. package/dist/rules/registry.js.map +1 -0
  56. package/dist/scanners/a11y-scanner.d.ts +14 -0
  57. package/dist/scanners/a11y-scanner.d.ts.map +1 -0
  58. package/dist/scanners/a11y-scanner.js +781 -0
  59. package/dist/scanners/a11y-scanner.js.map +1 -0
  60. package/dist/scanners/component-scanner.d.ts +12 -0
  61. package/dist/scanners/component-scanner.d.ts.map +1 -0
  62. package/dist/scanners/component-scanner.js +304 -0
  63. package/dist/scanners/component-scanner.js.map +1 -0
  64. package/dist/scanners/cross-file-scanner.d.ts +18 -0
  65. package/dist/scanners/cross-file-scanner.d.ts.map +1 -0
  66. package/dist/scanners/cross-file-scanner.js +684 -0
  67. package/dist/scanners/cross-file-scanner.js.map +1 -0
  68. package/dist/scanners/hooks-scanner.d.ts +15 -0
  69. package/dist/scanners/hooks-scanner.d.ts.map +1 -0
  70. package/dist/scanners/hooks-scanner.js +670 -0
  71. package/dist/scanners/hooks-scanner.js.map +1 -0
  72. package/dist/scanners/i18n-scanner.d.ts +13 -0
  73. package/dist/scanners/i18n-scanner.d.ts.map +1 -0
  74. package/dist/scanners/i18n-scanner.js +535 -0
  75. package/dist/scanners/i18n-scanner.js.map +1 -0
  76. package/dist/scanners/naming-scanner.d.ts +19 -0
  77. package/dist/scanners/naming-scanner.d.ts.map +1 -0
  78. package/dist/scanners/naming-scanner.js +746 -0
  79. package/dist/scanners/naming-scanner.js.map +1 -0
  80. package/dist/scanners/performance-scanner.d.ts +7 -0
  81. package/dist/scanners/performance-scanner.d.ts.map +1 -0
  82. package/dist/scanners/performance-scanner.js +402 -0
  83. package/dist/scanners/performance-scanner.js.map +1 -0
  84. package/dist/scanners/platform-scanner.d.ts +15 -0
  85. package/dist/scanners/platform-scanner.d.ts.map +1 -0
  86. package/dist/scanners/platform-scanner.js +320 -0
  87. package/dist/scanners/platform-scanner.js.map +1 -0
  88. package/dist/scanners/security-scanner.d.ts +7 -0
  89. package/dist/scanners/security-scanner.d.ts.map +1 -0
  90. package/dist/scanners/security-scanner.js +349 -0
  91. package/dist/scanners/security-scanner.js.map +1 -0
  92. package/dist/scanners/svelte-scanner.d.ts +14 -0
  93. package/dist/scanners/svelte-scanner.d.ts.map +1 -0
  94. package/dist/scanners/svelte-scanner.js +228 -0
  95. package/dist/scanners/svelte-scanner.js.map +1 -0
  96. package/dist/types.d.ts +343 -0
  97. package/dist/types.d.ts.map +1 -0
  98. package/dist/types.js +6 -0
  99. package/dist/types.js.map +1 -0
  100. package/dist/utils/ast-parser.d.ts +21 -0
  101. package/dist/utils/ast-parser.d.ts.map +1 -0
  102. package/dist/utils/ast-parser.js +119 -0
  103. package/dist/utils/ast-parser.js.map +1 -0
  104. package/dist/utils/baseline.d.ts +89 -0
  105. package/dist/utils/baseline.d.ts.map +1 -0
  106. package/dist/utils/baseline.js +156 -0
  107. package/dist/utils/baseline.js.map +1 -0
  108. package/dist/utils/ci-generator.d.ts +34 -0
  109. package/dist/utils/ci-generator.d.ts.map +1 -0
  110. package/dist/utils/ci-generator.js +194 -0
  111. package/dist/utils/ci-generator.js.map +1 -0
  112. package/dist/utils/common.d.ts +8 -0
  113. package/dist/utils/common.d.ts.map +1 -0
  114. package/dist/utils/common.js +38 -0
  115. package/dist/utils/common.js.map +1 -0
  116. package/dist/utils/concurrent.d.ts +16 -0
  117. package/dist/utils/concurrent.d.ts.map +1 -0
  118. package/dist/utils/concurrent.js +49 -0
  119. package/dist/utils/concurrent.js.map +1 -0
  120. package/dist/utils/config-loader.d.ts +8 -0
  121. package/dist/utils/config-loader.d.ts.map +1 -0
  122. package/dist/utils/config-loader.js +154 -0
  123. package/dist/utils/config-loader.js.map +1 -0
  124. package/dist/utils/fix-bot.d.ts +36 -0
  125. package/dist/utils/fix-bot.d.ts.map +1 -0
  126. package/dist/utils/fix-bot.js +274 -0
  127. package/dist/utils/fix-bot.js.map +1 -0
  128. package/dist/utils/git-hooks.d.ts +55 -0
  129. package/dist/utils/git-hooks.d.ts.map +1 -0
  130. package/dist/utils/git-hooks.js +318 -0
  131. package/dist/utils/git-hooks.js.map +1 -0
  132. package/dist/utils/history-report.d.ts +72 -0
  133. package/dist/utils/history-report.d.ts.map +1 -0
  134. package/dist/utils/history-report.js +144 -0
  135. package/dist/utils/history-report.js.map +1 -0
  136. package/dist/utils/init-config.d.ts +23 -0
  137. package/dist/utils/init-config.d.ts.map +1 -0
  138. package/dist/utils/init-config.js +146 -0
  139. package/dist/utils/init-config.js.map +1 -0
  140. package/dist/utils/pr-publisher.d.ts +64 -0
  141. package/dist/utils/pr-publisher.d.ts.map +1 -0
  142. package/dist/utils/pr-publisher.js +265 -0
  143. package/dist/utils/pr-publisher.js.map +1 -0
  144. package/dist/utils/project-detector.d.ts +20 -0
  145. package/dist/utils/project-detector.d.ts.map +1 -0
  146. package/dist/utils/project-detector.js +342 -0
  147. package/dist/utils/project-detector.js.map +1 -0
  148. package/dist/utils/report-uploader.d.ts +35 -0
  149. package/dist/utils/report-uploader.d.ts.map +1 -0
  150. package/dist/utils/report-uploader.js +106 -0
  151. package/dist/utils/report-uploader.js.map +1 -0
  152. package/package.json +78 -0
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ /**
3
+ * SARIF (Static Analysis Results Interchange Format) 格式化器
4
+ *
5
+ * 将 frontend-guardian 的 Issue 列表转换为 SARIF 2.1.0 JSON 格式,
6
+ * 可被 GitHub Security tab、Azure DevOps 等 CI/CD 平台消费。
7
+ *
8
+ * 规范参考:https://docs.oasis-open.org/sarif/sarif/v2.1.0/cs01/sarif-v2.1.0-cs01.html
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.generateSarif = generateSarif;
12
+ exports.formatSarif = formatSarif;
13
+ /** severity → SARIF level 映射 */
14
+ function severityToLevel(severity) {
15
+ switch (severity) {
16
+ case "critical":
17
+ return "error";
18
+ case "warning":
19
+ return "warning";
20
+ case "suggestion":
21
+ return "note";
22
+ }
23
+ }
24
+ /** 构建 SARIF 规则定义(去重) */
25
+ function buildRules(issues) {
26
+ const seen = new Set();
27
+ const rules = [];
28
+ for (const issue of issues) {
29
+ if (seen.has(issue.ruleId))
30
+ continue;
31
+ seen.add(issue.ruleId);
32
+ rules.push({
33
+ id: issue.ruleId,
34
+ name: issue.ruleId,
35
+ shortDescription: { text: issue.title },
36
+ fullDescription: { text: issue.description },
37
+ defaultConfiguration: { level: severityToLevel(issue.severity) },
38
+ });
39
+ }
40
+ return rules;
41
+ }
42
+ /** 构建 SARIF 结果条目 */
43
+ function buildResult(issue, ruleIndexMap) {
44
+ const result = {
45
+ ruleId: issue.ruleId,
46
+ ruleIndex: ruleIndexMap.get(issue.ruleId),
47
+ message: { text: `${issue.title}: ${issue.description}` },
48
+ level: severityToLevel(issue.severity),
49
+ locations: [
50
+ {
51
+ physicalLocation: {
52
+ artifactLocation: {
53
+ uri: issue.file,
54
+ uriBaseId: "PROJECT_ROOT",
55
+ },
56
+ region: {
57
+ startLine: issue.line,
58
+ startColumn: issue.column,
59
+ endLine: issue.endLine,
60
+ endColumn: issue.endColumn,
61
+ ...(issue.source ? { snippet: { text: issue.source } } : {}),
62
+ },
63
+ },
64
+ },
65
+ ],
66
+ };
67
+ // 如果有 fix 信息,也加入 SARIF fixes
68
+ if (issue.fix) {
69
+ result.fixes = [
70
+ {
71
+ description: { text: issue.title },
72
+ artifactChanges: [
73
+ {
74
+ artifactLocation: { uri: issue.file },
75
+ replacements: [
76
+ {
77
+ deletedRegion: {
78
+ startLine: issue.fix.start.line,
79
+ startColumn: issue.fix.start.column,
80
+ endLine: issue.fix.end.line,
81
+ endColumn: issue.fix.end.column,
82
+ },
83
+ insertedContent: { text: issue.fix.text },
84
+ },
85
+ ],
86
+ },
87
+ ],
88
+ },
89
+ ];
90
+ }
91
+ return result;
92
+ }
93
+ /** 生成 SARIF 报告 */
94
+ function generateSarif(issues, options = {}) {
95
+ const rules = buildRules(issues);
96
+ const ruleIndexMap = new Map();
97
+ rules.forEach((r, i) => ruleIndexMap.set(r.id, i));
98
+ const results = issues.map((issue) => buildResult(issue, ruleIndexMap));
99
+ const run = {
100
+ tool: {
101
+ driver: {
102
+ name: options.toolName || "Frontend Guardian",
103
+ version: options.toolVersion || "2.3.0",
104
+ informationUri: "https://github.com/wzm111/frontend-guardian",
105
+ rules,
106
+ },
107
+ },
108
+ results,
109
+ ...(options.projectDir
110
+ ? {
111
+ invocations: [
112
+ {
113
+ executionSuccessful: true,
114
+ workingDirectory: { uri: options.projectDir },
115
+ },
116
+ ],
117
+ }
118
+ : {}),
119
+ };
120
+ return {
121
+ $schema: "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
122
+ version: "2.1.0",
123
+ runs: [run],
124
+ };
125
+ }
126
+ /** 将 SARIF 报告序列化为 JSON 字符串 */
127
+ function formatSarif(issues, options) {
128
+ return JSON.stringify(generateSarif(issues, options), null, 2);
129
+ }
130
+ //# sourceMappingURL=sarif.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sarif.js","sourceRoot":"","sources":["../../src/formatters/sarif.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Frontend Guardian Core — 主索引
3
+ * 导出所有公共 API
4
+ */
5
+ export { RuleEngine, createEngine } from "./engine/rule-engine.js";
6
+ export type { EngineOptions } from "./engine/rule-engine.js";
7
+ export { SmartCache } from "./engine/cache.js";
8
+ export type { CacheEntry, CacheManifest } from "./engine/cache.js";
9
+ export { RuleRegistry, createRegistry } from "./rules/registry.js";
10
+ export type { Rule, RuleContext, RuleConfig, CustomRuleConfig, Issue, Severity, ScanResult, ProjectConfig, ProjectMeta, RuleUtils, Fix, Position, ImportInfo, ParseOptions, Framework, Platform, ComponentLib, RuleCategory, } from "./types.js";
11
+ export { parseAST, getImports, hasImport, walkAST } from "./utils/ast-parser.js";
12
+ export { detectProjectMeta } from "./utils/project-detector.js";
13
+ export { loadConfig } from "./utils/config-loader.js";
14
+ export { initConfig, generateDefaultConfig } from "./utils/init-config.js";
15
+ export { installGitHooks, uninstallGitHooks, hasGitHook, detectHusky } from "./utils/git-hooks.js";
16
+ export { generateCIConfig, detectCIProvider } from "./utils/ci-generator.js";
17
+ export type { CIProvider, CIGeneratorOptions } from "./utils/ci-generator.js";
18
+ export { HistoryReport } from "./utils/history-report.js";
19
+ export type { HistoryEntry, TrendAnalysis } from "./utils/history-report.js";
20
+ export { uploadReport, detectUploadConfig } from "./utils/report-uploader.js";
21
+ export type { UploadConfig, UploadResult } from "./utils/report-uploader.js";
22
+ export { runFixBot, detectFixBotConfig } from "./utils/fix-bot.js";
23
+ export type { FixBotConfig, FixBotResult } from "./utils/fix-bot.js";
24
+ export { BaselineManager, compareWithBaseline, generateBaseline, loadBaseline, saveBaseline, toBaselineIssue } from "./utils/baseline.js";
25
+ export type { BaselineFile, BaselineIssue, BaselineResult } from "./utils/baseline.js";
26
+ export { generateSarif, formatSarif } from "./formatters/sarif.js";
27
+ export type { SarifReport } from "./formatters/sarif.js";
28
+ export { formatIssueAnnotation, formatIssuesAnnotations, formatAllAnnotations, isGitHubActions, writeJobSummary, } from "./formatters/github-annotation.js";
29
+ export { generatePRComment, generatePRCommentSummary, COMMENT_MARKER, isGuardianComment, } from "./formatters/pr-comment.js";
30
+ export type { CommentMeta } from "./formatters/pr-comment.js";
31
+ export { GitHubPRPublisher, GitLabMRPublisher, detectPublisherConfig, createPublisher, autoPublishComment, } from "./utils/pr-publisher.js";
32
+ export type { PublishResult, PublisherConfig, PRPublisher } from "./utils/pr-publisher.js";
33
+ export { allExternalTools, eslintIntegration, typescriptIntegration, stylelintIntegration, runAllExternalTools, } from "./integrations/index.js";
34
+ export type { ExternalTool, ExternalToolResult } from "./integrations/index.js";
35
+ export { i18nRules } from "./scanners/i18n-scanner.js";
36
+ export { performanceRules } from "./scanners/performance-scanner.js";
37
+ export { a11yRules } from "./scanners/a11y-scanner.js";
38
+ export { securityRules } from "./scanners/security-scanner.js";
39
+ export { namingRules } from "./scanners/naming-scanner.js";
40
+ export { crossFileRules } from "./scanners/cross-file-scanner.js";
41
+ export { componentRules } from "./scanners/component-scanner.js";
42
+ export { hooksRules } from "./scanners/hooks-scanner.js";
43
+ export { platformRules } from "./scanners/platform-scanner.js";
44
+ export { svelteRules } from "./scanners/svelte-scanner.js";
45
+ export { getFileExt, getJSXTagName } from "./utils/common.js";
46
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ /**
3
+ * Frontend Guardian Core — 主索引
4
+ * 导出所有公共 API
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.stylelintIntegration = exports.typescriptIntegration = exports.eslintIntegration = exports.allExternalTools = exports.autoPublishComment = exports.createPublisher = exports.detectPublisherConfig = exports.GitLabMRPublisher = exports.GitHubPRPublisher = exports.isGuardianComment = exports.COMMENT_MARKER = exports.generatePRCommentSummary = exports.generatePRComment = exports.writeJobSummary = exports.isGitHubActions = exports.formatAllAnnotations = exports.formatIssuesAnnotations = exports.formatIssueAnnotation = exports.formatSarif = exports.generateSarif = exports.toBaselineIssue = exports.saveBaseline = exports.loadBaseline = exports.generateBaseline = exports.compareWithBaseline = exports.BaselineManager = exports.detectFixBotConfig = exports.runFixBot = exports.detectUploadConfig = exports.uploadReport = exports.HistoryReport = exports.detectCIProvider = exports.generateCIConfig = exports.detectHusky = exports.hasGitHook = exports.uninstallGitHooks = exports.installGitHooks = exports.generateDefaultConfig = exports.initConfig = exports.loadConfig = exports.detectProjectMeta = exports.walkAST = exports.hasImport = exports.getImports = exports.parseAST = exports.createRegistry = exports.RuleRegistry = exports.SmartCache = exports.createEngine = exports.RuleEngine = void 0;
8
+ exports.getJSXTagName = exports.getFileExt = exports.svelteRules = exports.platformRules = exports.hooksRules = exports.componentRules = exports.crossFileRules = exports.namingRules = exports.securityRules = exports.a11yRules = exports.performanceRules = exports.i18nRules = exports.runAllExternalTools = void 0;
9
+ var rule_engine_js_1 = require("./engine/rule-engine.js");
10
+ Object.defineProperty(exports, "RuleEngine", { enumerable: true, get: function () { return rule_engine_js_1.RuleEngine; } });
11
+ Object.defineProperty(exports, "createEngine", { enumerable: true, get: function () { return rule_engine_js_1.createEngine; } });
12
+ var cache_js_1 = require("./engine/cache.js");
13
+ Object.defineProperty(exports, "SmartCache", { enumerable: true, get: function () { return cache_js_1.SmartCache; } });
14
+ var registry_js_1 = require("./rules/registry.js");
15
+ Object.defineProperty(exports, "RuleRegistry", { enumerable: true, get: function () { return registry_js_1.RuleRegistry; } });
16
+ Object.defineProperty(exports, "createRegistry", { enumerable: true, get: function () { return registry_js_1.createRegistry; } });
17
+ var ast_parser_js_1 = require("./utils/ast-parser.js");
18
+ Object.defineProperty(exports, "parseAST", { enumerable: true, get: function () { return ast_parser_js_1.parseAST; } });
19
+ Object.defineProperty(exports, "getImports", { enumerable: true, get: function () { return ast_parser_js_1.getImports; } });
20
+ Object.defineProperty(exports, "hasImport", { enumerable: true, get: function () { return ast_parser_js_1.hasImport; } });
21
+ Object.defineProperty(exports, "walkAST", { enumerable: true, get: function () { return ast_parser_js_1.walkAST; } });
22
+ var project_detector_js_1 = require("./utils/project-detector.js");
23
+ Object.defineProperty(exports, "detectProjectMeta", { enumerable: true, get: function () { return project_detector_js_1.detectProjectMeta; } });
24
+ var config_loader_js_1 = require("./utils/config-loader.js");
25
+ Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return config_loader_js_1.loadConfig; } });
26
+ var init_config_js_1 = require("./utils/init-config.js");
27
+ Object.defineProperty(exports, "initConfig", { enumerable: true, get: function () { return init_config_js_1.initConfig; } });
28
+ Object.defineProperty(exports, "generateDefaultConfig", { enumerable: true, get: function () { return init_config_js_1.generateDefaultConfig; } });
29
+ var git_hooks_js_1 = require("./utils/git-hooks.js");
30
+ Object.defineProperty(exports, "installGitHooks", { enumerable: true, get: function () { return git_hooks_js_1.installGitHooks; } });
31
+ Object.defineProperty(exports, "uninstallGitHooks", { enumerable: true, get: function () { return git_hooks_js_1.uninstallGitHooks; } });
32
+ Object.defineProperty(exports, "hasGitHook", { enumerable: true, get: function () { return git_hooks_js_1.hasGitHook; } });
33
+ Object.defineProperty(exports, "detectHusky", { enumerable: true, get: function () { return git_hooks_js_1.detectHusky; } });
34
+ var ci_generator_js_1 = require("./utils/ci-generator.js");
35
+ Object.defineProperty(exports, "generateCIConfig", { enumerable: true, get: function () { return ci_generator_js_1.generateCIConfig; } });
36
+ Object.defineProperty(exports, "detectCIProvider", { enumerable: true, get: function () { return ci_generator_js_1.detectCIProvider; } });
37
+ var history_report_js_1 = require("./utils/history-report.js");
38
+ Object.defineProperty(exports, "HistoryReport", { enumerable: true, get: function () { return history_report_js_1.HistoryReport; } });
39
+ // v2.5.0: 报告上传
40
+ var report_uploader_js_1 = require("./utils/report-uploader.js");
41
+ Object.defineProperty(exports, "uploadReport", { enumerable: true, get: function () { return report_uploader_js_1.uploadReport; } });
42
+ Object.defineProperty(exports, "detectUploadConfig", { enumerable: true, get: function () { return report_uploader_js_1.detectUploadConfig; } });
43
+ // v2.6.0: 自动修复 Bot
44
+ var fix_bot_js_1 = require("./utils/fix-bot.js");
45
+ Object.defineProperty(exports, "runFixBot", { enumerable: true, get: function () { return fix_bot_js_1.runFixBot; } });
46
+ Object.defineProperty(exports, "detectFixBotConfig", { enumerable: true, get: function () { return fix_bot_js_1.detectFixBotConfig; } });
47
+ // Phase v2.3.0: Baseline 管理
48
+ var baseline_js_1 = require("./utils/baseline.js");
49
+ Object.defineProperty(exports, "BaselineManager", { enumerable: true, get: function () { return baseline_js_1.BaselineManager; } });
50
+ Object.defineProperty(exports, "compareWithBaseline", { enumerable: true, get: function () { return baseline_js_1.compareWithBaseline; } });
51
+ Object.defineProperty(exports, "generateBaseline", { enumerable: true, get: function () { return baseline_js_1.generateBaseline; } });
52
+ Object.defineProperty(exports, "loadBaseline", { enumerable: true, get: function () { return baseline_js_1.loadBaseline; } });
53
+ Object.defineProperty(exports, "saveBaseline", { enumerable: true, get: function () { return baseline_js_1.saveBaseline; } });
54
+ Object.defineProperty(exports, "toBaselineIssue", { enumerable: true, get: function () { return baseline_js_1.toBaselineIssue; } });
55
+ // Phase v2.3.0: SARIF 格式化
56
+ var sarif_js_1 = require("./formatters/sarif.js");
57
+ Object.defineProperty(exports, "generateSarif", { enumerable: true, get: function () { return sarif_js_1.generateSarif; } });
58
+ Object.defineProperty(exports, "formatSarif", { enumerable: true, get: function () { return sarif_js_1.formatSarif; } });
59
+ // Phase v2.3.0: GitHub Actions Annotation
60
+ var github_annotation_js_1 = require("./formatters/github-annotation.js");
61
+ Object.defineProperty(exports, "formatIssueAnnotation", { enumerable: true, get: function () { return github_annotation_js_1.formatIssueAnnotation; } });
62
+ Object.defineProperty(exports, "formatIssuesAnnotations", { enumerable: true, get: function () { return github_annotation_js_1.formatIssuesAnnotations; } });
63
+ Object.defineProperty(exports, "formatAllAnnotations", { enumerable: true, get: function () { return github_annotation_js_1.formatAllAnnotations; } });
64
+ Object.defineProperty(exports, "isGitHubActions", { enumerable: true, get: function () { return github_annotation_js_1.isGitHubActions; } });
65
+ Object.defineProperty(exports, "writeJobSummary", { enumerable: true, get: function () { return github_annotation_js_1.writeJobSummary; } });
66
+ // v2.5.0: PR/MR 评论发布
67
+ var pr_comment_js_1 = require("./formatters/pr-comment.js");
68
+ Object.defineProperty(exports, "generatePRComment", { enumerable: true, get: function () { return pr_comment_js_1.generatePRComment; } });
69
+ Object.defineProperty(exports, "generatePRCommentSummary", { enumerable: true, get: function () { return pr_comment_js_1.generatePRCommentSummary; } });
70
+ Object.defineProperty(exports, "COMMENT_MARKER", { enumerable: true, get: function () { return pr_comment_js_1.COMMENT_MARKER; } });
71
+ Object.defineProperty(exports, "isGuardianComment", { enumerable: true, get: function () { return pr_comment_js_1.isGuardianComment; } });
72
+ var pr_publisher_js_1 = require("./utils/pr-publisher.js");
73
+ Object.defineProperty(exports, "GitHubPRPublisher", { enumerable: true, get: function () { return pr_publisher_js_1.GitHubPRPublisher; } });
74
+ Object.defineProperty(exports, "GitLabMRPublisher", { enumerable: true, get: function () { return pr_publisher_js_1.GitLabMRPublisher; } });
75
+ Object.defineProperty(exports, "detectPublisherConfig", { enumerable: true, get: function () { return pr_publisher_js_1.detectPublisherConfig; } });
76
+ Object.defineProperty(exports, "createPublisher", { enumerable: true, get: function () { return pr_publisher_js_1.createPublisher; } });
77
+ Object.defineProperty(exports, "autoPublishComment", { enumerable: true, get: function () { return pr_publisher_js_1.autoPublishComment; } });
78
+ // Phase 4: 外部工具集成
79
+ var index_js_1 = require("./integrations/index.js");
80
+ Object.defineProperty(exports, "allExternalTools", { enumerable: true, get: function () { return index_js_1.allExternalTools; } });
81
+ Object.defineProperty(exports, "eslintIntegration", { enumerable: true, get: function () { return index_js_1.eslintIntegration; } });
82
+ Object.defineProperty(exports, "typescriptIntegration", { enumerable: true, get: function () { return index_js_1.typescriptIntegration; } });
83
+ Object.defineProperty(exports, "stylelintIntegration", { enumerable: true, get: function () { return index_js_1.stylelintIntegration; } });
84
+ Object.defineProperty(exports, "runAllExternalTools", { enumerable: true, get: function () { return index_js_1.runAllExternalTools; } });
85
+ var i18n_scanner_js_1 = require("./scanners/i18n-scanner.js");
86
+ Object.defineProperty(exports, "i18nRules", { enumerable: true, get: function () { return i18n_scanner_js_1.i18nRules; } });
87
+ var performance_scanner_js_1 = require("./scanners/performance-scanner.js");
88
+ Object.defineProperty(exports, "performanceRules", { enumerable: true, get: function () { return performance_scanner_js_1.performanceRules; } });
89
+ var a11y_scanner_js_1 = require("./scanners/a11y-scanner.js");
90
+ Object.defineProperty(exports, "a11yRules", { enumerable: true, get: function () { return a11y_scanner_js_1.a11yRules; } });
91
+ var security_scanner_js_1 = require("./scanners/security-scanner.js");
92
+ Object.defineProperty(exports, "securityRules", { enumerable: true, get: function () { return security_scanner_js_1.securityRules; } });
93
+ var naming_scanner_js_1 = require("./scanners/naming-scanner.js");
94
+ Object.defineProperty(exports, "namingRules", { enumerable: true, get: function () { return naming_scanner_js_1.namingRules; } });
95
+ var cross_file_scanner_js_1 = require("./scanners/cross-file-scanner.js");
96
+ Object.defineProperty(exports, "crossFileRules", { enumerable: true, get: function () { return cross_file_scanner_js_1.crossFileRules; } });
97
+ var component_scanner_js_1 = require("./scanners/component-scanner.js");
98
+ Object.defineProperty(exports, "componentRules", { enumerable: true, get: function () { return component_scanner_js_1.componentRules; } });
99
+ var hooks_scanner_js_1 = require("./scanners/hooks-scanner.js");
100
+ Object.defineProperty(exports, "hooksRules", { enumerable: true, get: function () { return hooks_scanner_js_1.hooksRules; } });
101
+ var platform_scanner_js_1 = require("./scanners/platform-scanner.js");
102
+ Object.defineProperty(exports, "platformRules", { enumerable: true, get: function () { return platform_scanner_js_1.platformRules; } });
103
+ var svelte_scanner_js_1 = require("./scanners/svelte-scanner.js");
104
+ Object.defineProperty(exports, "svelteRules", { enumerable: true, get: function () { return svelte_scanner_js_1.svelteRules; } });
105
+ var common_js_1 = require("./utils/common.js");
106
+ Object.defineProperty(exports, "getFileExt", { enumerable: true, get: function () { return common_js_1.getFileExt; } });
107
+ Object.defineProperty(exports, "getJSXTagName", { enumerable: true, get: function () { return common_js_1.getJSXTagName; } });
108
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;AAEH,0DAAmE;AAA1D,4GAAA,UAAU,OAAA;AAAE,8GAAA,YAAY,OAAA;AAEjC,8CAA+C;AAAtC,sGAAA,UAAU,OAAA;AAEnB,mDAAmE;AAA1D,2GAAA,YAAY,OAAA;AAAE,6GAAA,cAAc,OAAA;AAsBrC,uDAAiF;AAAxE,yGAAA,QAAQ,OAAA;AAAE,2GAAA,UAAU,OAAA;AAAE,0GAAA,SAAS,OAAA;AAAE,wGAAA,OAAO,OAAA;AACjD,mEAAgE;AAAvD,wHAAA,iBAAiB,OAAA;AAC1B,6DAAsD;AAA7C,8GAAA,UAAU,OAAA;AACnB,yDAA2E;AAAlE,4GAAA,UAAU,OAAA;AAAE,uHAAA,qBAAqB,OAAA;AAC1C,qDAAmG;AAA1F,+GAAA,eAAe,OAAA;AAAE,iHAAA,iBAAiB,OAAA;AAAE,0GAAA,UAAU,OAAA;AAAE,2GAAA,WAAW,OAAA;AACpE,2DAA6E;AAApE,mHAAA,gBAAgB,OAAA;AAAE,mHAAA,gBAAgB,OAAA;AAE3C,+DAA0D;AAAjD,kHAAA,aAAa,OAAA;AAGtB,eAAe;AACf,iEAA8E;AAArE,kHAAA,YAAY,OAAA;AAAE,wHAAA,kBAAkB,OAAA;AAGzC,mBAAmB;AACnB,iDAAmE;AAA1D,uGAAA,SAAS,OAAA;AAAE,gHAAA,kBAAkB,OAAA;AAGtC,4BAA4B;AAC5B,mDAA0I;AAAjI,8GAAA,eAAe,OAAA;AAAE,kHAAA,mBAAmB,OAAA;AAAE,+GAAA,gBAAgB,OAAA;AAAE,2GAAA,YAAY,OAAA;AAAE,2GAAA,YAAY,OAAA;AAAE,8GAAA,eAAe,OAAA;AAG5G,0BAA0B;AAC1B,kDAAmE;AAA1D,yGAAA,aAAa,OAAA;AAAE,uGAAA,WAAW,OAAA;AAGnC,0CAA0C;AAC1C,0EAM2C;AALvC,6HAAA,qBAAqB,OAAA;AACrB,+HAAA,uBAAuB,OAAA;AACvB,4HAAA,oBAAoB,OAAA;AACpB,uHAAA,eAAe,OAAA;AACf,uHAAA,eAAe,OAAA;AAGnB,qBAAqB;AACrB,4DAKoC;AAJhC,kHAAA,iBAAiB,OAAA;AACjB,yHAAA,wBAAwB,OAAA;AACxB,+GAAA,cAAc,OAAA;AACd,kHAAA,iBAAiB,OAAA;AAIrB,2DAMiC;AAL7B,oHAAA,iBAAiB,OAAA;AACjB,oHAAA,iBAAiB,OAAA;AACjB,wHAAA,qBAAqB,OAAA;AACrB,kHAAA,eAAe,OAAA;AACf,qHAAA,kBAAkB,OAAA;AAItB,kBAAkB;AAClB,oDAMiC;AAL7B,4GAAA,gBAAgB,OAAA;AAChB,6GAAA,iBAAiB,OAAA;AACjB,iHAAA,qBAAqB,OAAA;AACrB,gHAAA,oBAAoB,OAAA;AACpB,+GAAA,mBAAmB,OAAA;AAIvB,8DAAuD;AAA9C,4GAAA,SAAS,OAAA;AAElB,4EAAqE;AAA5D,0HAAA,gBAAgB,OAAA;AACzB,8DAAuD;AAA9C,4GAAA,SAAS,OAAA;AAClB,sEAA+D;AAAtD,oHAAA,aAAa,OAAA;AACtB,kEAA2D;AAAlD,gHAAA,WAAW,OAAA;AACpB,0EAAkE;AAAzD,uHAAA,cAAc,OAAA;AACvB,wEAAiE;AAAxD,sHAAA,cAAc,OAAA;AACvB,gEAAyD;AAAhD,8GAAA,UAAU,OAAA;AACnB,sEAA+D;AAAtD,oHAAA,aAAa,OAAA;AACtB,kEAA2D;AAAlD,gHAAA,WAAW,OAAA;AACpB,+CAA8D;AAArD,uGAAA,UAAU,OAAA;AAAE,0GAAA,aAAa,OAAA"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * 外部工具集成基础层
3
+ *
4
+ * Phase 4 核心能力:将 ESLint / TypeScript / Stylelint 等外部工具的输出
5
+ * 统一转换为 frontend-guardian 的 Issue 格式,实现一站式治理。
6
+ */
7
+ import type { Issue, Severity } from "../types.js";
8
+ /** 外部工具集成接口 */
9
+ export interface ExternalTool {
10
+ /** 工具名称 */
11
+ name: string;
12
+ /** 检测该工具是否可在项目中使用 */
13
+ isAvailable(projectDir: string): boolean;
14
+ /** 执行检查并返回统一 Issue 列表 */
15
+ run(projectDir: string, files?: string[]): Issue[];
16
+ }
17
+ /** 外部工具执行结果 */
18
+ export interface ExternalToolResult {
19
+ tool: string;
20
+ issues: Issue[];
21
+ duration: number;
22
+ stdout?: string;
23
+ stderr?: string;
24
+ }
25
+ /**
26
+ * 执行 shell 命令并捕获输出
27
+ * @returns stdout 内容,失败时返回 null
28
+ */
29
+ export declare function runCommand(cmd: string, cwd: string, timeoutMs?: number): string | null;
30
+ /**
31
+ * 将 ESLint severity (1/2) 映射为 frontend-guardian Severity
32
+ */
33
+ export declare function eslintSeverityToFg(severity: number): Severity;
34
+ /**
35
+ * 检查项目是否安装了某 npm 包(本地或全局)
36
+ */
37
+ export declare function hasPackage(projectDir: string, pkgName: string): boolean;
38
+ /**
39
+ * 检查项目中是否有配置文件
40
+ */
41
+ export declare function hasConfigFile(projectDir: string, filenames: string[]): boolean;
42
+ /** 运行所有可用的外部工具 */
43
+ export declare function runAllExternalTools(projectDir: string, tools: ExternalTool[], files?: string[]): ExternalToolResult[];
44
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/integrations/base.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGlD,eAAe;AACf,MAAM,WAAW,YAAY;IACzB,WAAW;IACX,IAAI,EAAE,MAAM,CAAC;IACb,qBAAqB;IACrB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;IACzC,yBAAyB;IACzB,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;CACtD;AAED,eAAe;AACf,MAAM,WAAW,kBAAkB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,SAAQ,GAAG,MAAM,GAAG,IAAI,CAerF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAS7D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAOvE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAU9E;AAED,kBAAkB;AAClB,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,kBAAkB,EAAE,CA6BrH"}
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ /**
3
+ * 外部工具集成基础层
4
+ *
5
+ * Phase 4 核心能力:将 ESLint / TypeScript / Stylelint 等外部工具的输出
6
+ * 统一转换为 frontend-guardian 的 Issue 格式,实现一站式治理。
7
+ */
8
+ var __importDefault = (this && this.__importDefault) || function (mod) {
9
+ return (mod && mod.__esModule) ? mod : { "default": mod };
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.runCommand = runCommand;
13
+ exports.eslintSeverityToFg = eslintSeverityToFg;
14
+ exports.hasPackage = hasPackage;
15
+ exports.hasConfigFile = hasConfigFile;
16
+ exports.runAllExternalTools = runAllExternalTools;
17
+ const node_child_process_1 = require("node:child_process");
18
+ const picocolors_1 = __importDefault(require("picocolors"));
19
+ /**
20
+ * 执行 shell 命令并捕获输出
21
+ * @returns stdout 内容,失败时返回 null
22
+ */
23
+ function runCommand(cmd, cwd, timeoutMs = 60000) {
24
+ try {
25
+ return (0, node_child_process_1.execSync)(cmd, {
26
+ cwd,
27
+ encoding: "utf-8",
28
+ timeout: timeoutMs,
29
+ stdio: ["pipe", "pipe", "pipe"],
30
+ });
31
+ }
32
+ catch (err) {
33
+ // 很多 linter 在发现问题时返回非零退出码,但 stdout 仍有有效输出
34
+ if (err.stdout) {
35
+ return err.stdout;
36
+ }
37
+ return null;
38
+ }
39
+ }
40
+ /**
41
+ * 将 ESLint severity (1/2) 映射为 frontend-guardian Severity
42
+ */
43
+ function eslintSeverityToFg(severity) {
44
+ switch (severity) {
45
+ case 2:
46
+ return "critical";
47
+ case 1:
48
+ return "warning";
49
+ default:
50
+ return "suggestion";
51
+ }
52
+ }
53
+ /**
54
+ * 检查项目是否安装了某 npm 包(本地或全局)
55
+ */
56
+ function hasPackage(projectDir, pkgName) {
57
+ const result = runCommand(`npx --no-install ${pkgName} --version 2>/dev/null || echo "NOT_FOUND"`, projectDir, 5000);
58
+ return result !== null && !result.includes("NOT_FOUND") && !result.includes("cannot find");
59
+ }
60
+ /**
61
+ * 检查项目中是否有配置文件
62
+ */
63
+ function hasConfigFile(projectDir, filenames) {
64
+ for (const name of filenames) {
65
+ try {
66
+ (0, node_child_process_1.execSync)(`test -f "${name}"`, { cwd: projectDir, stdio: "ignore" });
67
+ return true;
68
+ }
69
+ catch {
70
+ // continue
71
+ }
72
+ }
73
+ return false;
74
+ }
75
+ /** 运行所有可用的外部工具 */
76
+ function runAllExternalTools(projectDir, tools, files) {
77
+ const results = [];
78
+ for (const tool of tools) {
79
+ if (!tool.isAvailable(projectDir)) {
80
+ continue;
81
+ }
82
+ const start = Date.now();
83
+ try {
84
+ const issues = tool.run(projectDir, files);
85
+ results.push({
86
+ tool: tool.name,
87
+ issues,
88
+ duration: Date.now() - start,
89
+ });
90
+ console.log(picocolors_1.default.blue(`🔌 [${tool.name}] 发现 ${issues.length} 个问题`));
91
+ }
92
+ catch (err) {
93
+ results.push({
94
+ tool: tool.name,
95
+ issues: [],
96
+ duration: Date.now() - start,
97
+ stderr: String(err),
98
+ });
99
+ console.log(picocolors_1.default.yellow(`⚠️ [${tool.name}] 执行失败: ${err}`));
100
+ }
101
+ }
102
+ return results;
103
+ }
104
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/integrations/base.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * ESLint 集成
3
+ *
4
+ * 调用 npx eslint --format json 并解析为 Issue 格式
5
+ */
6
+ import type { ExternalTool } from "./base.js";
7
+ export declare const eslintIntegration: ExternalTool;
8
+ //# sourceMappingURL=eslint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eslint.d.ts","sourceRoot":"","sources":["../../src/integrations/eslint.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAkC9C,eAAO,MAAM,iBAAiB,EAAE,YAmE/B,CAAC"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ /**
3
+ * ESLint 集成
4
+ *
5
+ * 调用 npx eslint --format json 并解析为 Issue 格式
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.eslintIntegration = void 0;
9
+ const base_js_1 = require("./base.js");
10
+ exports.eslintIntegration = {
11
+ name: "ESLint",
12
+ isAvailable(projectDir) {
13
+ return (0, base_js_1.hasPackage)(projectDir, "eslint");
14
+ },
15
+ run(projectDir, files) {
16
+ const target = files && files.length > 0 ? files.join(" ") : "src/";
17
+ const stdout = (0, base_js_1.runCommand)(`npx eslint --format json --no-error-on-unmatched-pattern ${target}`, projectDir, 120000);
18
+ if (!stdout) {
19
+ return [];
20
+ }
21
+ let results;
22
+ try {
23
+ results = JSON.parse(stdout);
24
+ }
25
+ catch {
26
+ return [];
27
+ }
28
+ const issues = [];
29
+ for (const result of results) {
30
+ for (const msg of result.messages) {
31
+ if (!msg.ruleId)
32
+ continue; // 忽略解析错误(ruleId 为 null)
33
+ const severity = (0, base_js_1.eslintSeverityToFg)(msg.severity);
34
+ // 构建 Fix(如果 ESLint 提供了)
35
+ let fix = undefined;
36
+ if (msg.fix) {
37
+ // ESLint fix 使用字符偏移,我们需要转换为行列
38
+ // 简单处理:使用 line/column 作为起始位置
39
+ fix = {
40
+ text: msg.fix.text,
41
+ start: { line: msg.line, column: msg.column },
42
+ end: { line: msg.endLine || msg.line, column: msg.endColumn || msg.column + 1 },
43
+ };
44
+ }
45
+ issues.push({
46
+ ruleId: `eslint-${msg.ruleId}`,
47
+ title: msg.ruleId,
48
+ description: msg.message,
49
+ severity,
50
+ file: result.filePath,
51
+ line: msg.line,
52
+ column: msg.column,
53
+ endLine: msg.endLine,
54
+ endColumn: msg.endColumn,
55
+ fix,
56
+ meta: {
57
+ tool: "eslint",
58
+ fixable: !!msg.fix,
59
+ suggestions: msg.suggestions?.map((s) => s.desc) || [],
60
+ },
61
+ });
62
+ }
63
+ }
64
+ return issues;
65
+ },
66
+ };
67
+ //# sourceMappingURL=eslint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eslint.js","sourceRoot":"","sources":["../../src/integrations/eslint.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAIH,uCAAuE;AAiC1D,QAAA,iBAAiB,GAAiB;IAC3C,IAAI,EAAE,QAAQ;IAEd,WAAW,CAAC,UAAkB;QAC1B,OAAO,IAAA,oBAAU,EAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC5C,CAAC;IAED,GAAG,CAAC,UAAkB,EAAE,KAAgB;QACpC,MAAM,MAAM,GAAG,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QACpE,MAAM,MAAM,GAAG,IAAA,oBAAU,EACrB,4DAA4D,MAAM,EAAE,EACpE,UAAU,EACV,MAAM,CACT,CAAC;QAEF,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,OAAO,EAAE,CAAC;QACd,CAAC;QAED,IAAI,OAAuB,CAAC;QAC5B,IAAI,CAAC;YACD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,EAAE,CAAC;QACd,CAAC;QAED,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC3B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBAChC,IAAI,CAAC,GAAG,CAAC,MAAM;oBAAE,SAAS,CAAC,wBAAwB;gBAEnD,MAAM,QAAQ,GAAG,IAAA,4BAAkB,EAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBAElD,wBAAwB;gBACxB,IAAI,GAAG,GAAiB,SAAS,CAAC;gBAClC,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC;oBACV,8BAA8B;oBAC9B,6BAA6B;oBAC7B,GAAG,GAAG;wBACF,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI;wBAClB,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE;wBAC7C,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE;qBAClF,CAAC;gBACN,CAAC;gBAED,MAAM,CAAC,IAAI,CAAC;oBACR,MAAM,EAAE,UAAU,GAAG,CAAC,MAAM,EAAE;oBAC9B,KAAK,EAAE,GAAG,CAAC,MAAM;oBACjB,WAAW,EAAE,GAAG,CAAC,OAAO;oBACxB,QAAQ;oBACR,IAAI,EAAE,MAAM,CAAC,QAAQ;oBACrB,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,MAAM,EAAE,GAAG,CAAC,MAAM;oBAClB,OAAO,EAAE,GAAG,CAAC,OAAO;oBACpB,SAAS,EAAE,GAAG,CAAC,SAAS;oBACxB,GAAG;oBACH,IAAI,EAAE;wBACF,IAAI,EAAE,QAAQ;wBACd,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG;wBAClB,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE;qBACzD;iBACJ,CAAC,CAAC;YACP,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Formatter Integration — 代码格式化器集成
3
+ *
4
+ * 功能:
5
+ * 1. 自动检测项目使用的格式化工具(Biome / Prettier)
6
+ * 2. 使用项目已有配置,无配置时回退到默认
7
+ * 3. 支持 --format 单独运行,或 --fix --format 修复后自动格式化
8
+ *
9
+ * 检测优先级:
10
+ * 1. biome.json / biome.jsonc → Biome
11
+ * 2. .prettierrc / prettier.config.* → Prettier
12
+ * 3. 无配置 → 默认 Biome(4空格/120字符/双引号)
13
+ */
14
+ export interface FormatResult {
15
+ /** 格式化器名称 */
16
+ formatter: string;
17
+ /** 格式化文件数 */
18
+ formatted: number;
19
+ /** 未变更文件数 */
20
+ unchanged: number;
21
+ /** 错误信息 */
22
+ errors: string[];
23
+ /** 耗时 ms */
24
+ duration: number;
25
+ }
26
+ export interface FormatterTool {
27
+ name: string;
28
+ isAvailable(projectDir: string): boolean;
29
+ format(projectDir: string, files?: string[]): FormatResult;
30
+ }
31
+ /** 检测项目使用的格式化器 */
32
+ export declare function detectFormatter(projectDir: string): FormatterTool | null;
33
+ /** 运行格式化 */
34
+ export declare function runFormat(projectDir: string, files?: string[]): FormatResult;
35
+ //# sourceMappingURL=formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../src/integrations/formatter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,MAAM,WAAW,YAAY;IACzB,aAAa;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW;IACX,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY;IACZ,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;IACzC,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC;CAC9D;AAED,kBAAkB;AAClB,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAYxE;AAED,YAAY;AACZ,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,YAAY,CAY5E"}