specweave 0.32.2 → 0.32.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/CLAUDE.md +39 -0
- package/bin/specweave.js +34 -0
- package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.d.ts +100 -0
- package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.d.ts.map +1 -0
- package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.js +291 -0
- package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.js.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.d.ts +103 -0
- package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.d.ts.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.js +310 -0
- package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.js.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-permission-gate.d.ts +126 -0
- package/dist/plugins/specweave-jira/lib/jira-permission-gate.d.ts.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-permission-gate.js +207 -0
- package/dist/plugins/specweave-jira/lib/jira-permission-gate.js.map +1 -0
- package/dist/src/adapters/codex/README.md +1 -1
- package/dist/src/adapters/codex/adapter.js +1 -1
- package/dist/src/cli/commands/archive.d.ts +2 -0
- package/dist/src/cli/commands/archive.d.ts.map +1 -1
- package/dist/src/cli/commands/archive.js +33 -0
- package/dist/src/cli/commands/archive.js.map +1 -1
- package/dist/src/cli/commands/context.d.ts +92 -0
- package/dist/src/cli/commands/context.d.ts.map +1 -0
- package/dist/src/cli/commands/context.js +205 -0
- package/dist/src/cli/commands/context.js.map +1 -0
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +111 -69
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/helpers/init/external-import.d.ts +3 -0
- package/dist/src/cli/helpers/init/external-import.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/external-import.js +17 -4
- package/dist/src/cli/helpers/init/external-import.js.map +1 -1
- package/dist/src/cli/helpers/init/index.d.ts +1 -0
- package/dist/src/cli/helpers/init/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/index.js +2 -0
- package/dist/src/cli/helpers/init/index.js.map +1 -1
- package/dist/src/cli/helpers/init/jira-ado-auto-detect.d.ts +70 -0
- package/dist/src/cli/helpers/init/jira-ado-auto-detect.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/jira-ado-auto-detect.js +214 -4
- package/dist/src/cli/helpers/init/jira-ado-auto-detect.js.map +1 -1
- package/dist/src/cli/helpers/init/living-docs-preflight.d.ts +4 -0
- package/dist/src/cli/helpers/init/living-docs-preflight.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/living-docs-preflight.js +34 -3
- package/dist/src/cli/helpers/init/living-docs-preflight.js.map +1 -1
- package/dist/src/cli/helpers/init/testing-config.d.ts +3 -0
- package/dist/src/cli/helpers/init/testing-config.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/testing-config.js +9 -2
- package/dist/src/cli/helpers/init/testing-config.js.map +1 -1
- package/dist/src/cli/helpers/init/translation-config.d.ts +3 -0
- package/dist/src/cli/helpers/init/translation-config.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/translation-config.js +21 -4
- package/dist/src/cli/helpers/init/translation-config.js.map +1 -1
- package/dist/src/cli/helpers/init/wizard-navigation.d.ts +45 -0
- package/dist/src/cli/helpers/init/wizard-navigation.d.ts.map +1 -0
- package/dist/src/cli/helpers/init/wizard-navigation.js +97 -0
- package/dist/src/cli/helpers/init/wizard-navigation.js.map +1 -0
- package/dist/src/core/increment/increment-archiver.d.ts +25 -4
- package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
- package/dist/src/core/increment/increment-archiver.js +64 -20
- package/dist/src/core/increment/increment-archiver.js.map +1 -1
- package/dist/src/core/increment/increment-utils.d.ts +65 -0
- package/dist/src/core/increment/increment-utils.d.ts.map +1 -1
- package/dist/src/core/increment/increment-utils.js +114 -0
- package/dist/src/core/increment/increment-utils.js.map +1 -1
- package/dist/src/core/living-docs/feature-archiver.d.ts +4 -0
- package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -1
- package/dist/src/core/living-docs/feature-archiver.js +32 -10
- package/dist/src/core/living-docs/feature-archiver.js.map +1 -1
- package/dist/src/core/living-docs/feature-id-manager.d.ts.map +1 -1
- package/dist/src/core/living-docs/feature-id-manager.js +7 -3
- package/dist/src/core/living-docs/feature-id-manager.js.map +1 -1
- package/dist/src/core/living-docs/governance/ecosystem-detector.d.ts +38 -0
- package/dist/src/core/living-docs/governance/ecosystem-detector.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/ecosystem-detector.js +325 -0
- package/dist/src/core/living-docs/governance/ecosystem-detector.js.map +1 -0
- package/dist/src/core/living-docs/governance/frontend-standards-parser.d.ts +74 -0
- package/dist/src/core/living-docs/governance/frontend-standards-parser.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/frontend-standards-parser.js +366 -0
- package/dist/src/core/living-docs/governance/frontend-standards-parser.js.map +1 -0
- package/dist/src/core/living-docs/governance/go-standards-parser.d.ts +64 -0
- package/dist/src/core/living-docs/governance/go-standards-parser.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/go-standards-parser.js +229 -0
- package/dist/src/core/living-docs/governance/go-standards-parser.js.map +1 -0
- package/dist/src/core/living-docs/governance/index.d.ts +50 -0
- package/dist/src/core/living-docs/governance/index.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/index.js +56 -0
- package/dist/src/core/living-docs/governance/index.js.map +1 -0
- package/dist/src/core/living-docs/governance/java-standards-parser.d.ts +89 -0
- package/dist/src/core/living-docs/governance/java-standards-parser.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/java-standards-parser.js +356 -0
- package/dist/src/core/living-docs/governance/java-standards-parser.js.map +1 -0
- package/dist/src/core/living-docs/governance/python-standards-parser.d.ts +83 -0
- package/dist/src/core/living-docs/governance/python-standards-parser.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/python-standards-parser.js +347 -0
- package/dist/src/core/living-docs/governance/python-standards-parser.js.map +1 -0
- package/dist/src/core/living-docs/governance/standards-generator.d.ts +38 -0
- package/dist/src/core/living-docs/governance/standards-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/standards-generator.js +476 -0
- package/dist/src/core/living-docs/governance/standards-generator.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.d.ts.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js +54 -2
- package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts +5 -1
- package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js +358 -30
- package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts +44 -0
- package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.d.ts +6 -3
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +17 -8
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/living-docs/module-analyzer.d.ts +22 -0
- package/dist/src/core/living-docs/module-analyzer.d.ts.map +1 -1
- package/dist/src/core/living-docs/module-analyzer.js +123 -19
- package/dist/src/core/living-docs/module-analyzer.js.map +1 -1
- package/dist/src/core/llm/provider-factory.js +2 -2
- package/dist/src/core/llm/provider-factory.js.map +1 -1
- package/dist/src/core/llm/providers/anthropic-provider.js +1 -1
- package/dist/src/core/llm/providers/bedrock-provider.d.ts.map +1 -1
- package/dist/src/core/llm/providers/bedrock-provider.js +8 -4
- package/dist/src/core/llm/providers/bedrock-provider.js.map +1 -1
- package/dist/src/importers/jira-importer.d.ts +14 -0
- package/dist/src/importers/jira-importer.d.ts.map +1 -1
- package/dist/src/importers/jira-importer.js +75 -0
- package/dist/src/importers/jira-importer.js.map +1 -1
- package/dist/src/integrations/jira/jira-token-provider.d.ts +93 -0
- package/dist/src/integrations/jira/jira-token-provider.d.ts.map +1 -0
- package/dist/src/integrations/jira/jira-token-provider.js +160 -0
- package/dist/src/integrations/jira/jira-token-provider.js.map +1 -0
- package/dist/src/sync/ado-reconciler.d.ts +92 -0
- package/dist/src/sync/ado-reconciler.d.ts.map +1 -0
- package/dist/src/sync/ado-reconciler.js +335 -0
- package/dist/src/sync/ado-reconciler.js.map +1 -0
- package/dist/src/sync/jira-reconciler.d.ts +106 -0
- package/dist/src/sync/jira-reconciler.d.ts.map +1 -0
- package/dist/src/sync/jira-reconciler.js +405 -0
- package/dist/src/sync/jira-reconciler.js.map +1 -0
- package/dist/src/types/model-selection.d.ts +6 -4
- package/dist/src/types/model-selection.d.ts.map +1 -1
- package/dist/src/types/model-selection.js +3 -1
- package/dist/src/types/model-selection.js.map +1 -1
- package/dist/src/utils/external-tool-drift-detector.d.ts +1 -1
- package/dist/src/utils/external-tool-drift-detector.d.ts.map +1 -1
- package/dist/src/utils/external-tool-drift-detector.js +5 -4
- package/dist/src/utils/external-tool-drift-detector.js.map +1 -1
- package/dist/src/utils/feature-id-derivation.d.ts +8 -3
- package/dist/src/utils/feature-id-derivation.d.ts.map +1 -1
- package/dist/src/utils/feature-id-derivation.js +14 -6
- package/dist/src/utils/feature-id-derivation.js.map +1 -1
- package/dist/src/utils/model-selection.d.ts +3 -4
- package/dist/src/utils/model-selection.d.ts.map +1 -1
- package/dist/src/utils/model-selection.js +3 -4
- package/dist/src/utils/model-selection.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/agents/code-standards-detective/AGENT.md +48 -0
- package/plugins/specweave/commands/specweave-costs.md +4 -4
- package/plugins/specweave/commands/specweave-do.md +9 -9
- package/plugins/specweave/commands/specweave-done.md +13 -0
- package/plugins/specweave/commands/specweave-validate.md +27 -1
- package/plugins/specweave/hooks/hooks.json +10 -0
- package/plugins/specweave/hooks/spec-project-validator.sh +80 -25
- package/plugins/specweave/hooks/v2/guards/increment-duplicate-guard.sh +135 -0
- package/plugins/specweave/scripts/read-costs.sh +3 -3
- package/plugins/specweave/skills/code-standards-analyzer/SKILL.md +58 -6
- package/plugins/specweave/skills/increment-planner/SKILL.md +56 -25
- package/plugins/specweave/skills/increment-planner/templates/spec-multi-project.md +4 -2
- package/plugins/specweave/skills/increment-planner/templates/spec-single-project.md +2 -1
- package/plugins/specweave/skills/increment-planner/templates/tasks-multi-project.md +1 -1
- package/plugins/specweave/skills/increment-planner/templates/tasks-single-project.md +1 -1
- package/plugins/specweave-ado/commands/cleanup-duplicates.md +212 -0
- package/plugins/specweave-ado/commands/reconcile.md +120 -0
- package/plugins/specweave-ado/lib/ado-duplicate-detector.js +279 -0
- package/plugins/specweave-ado/lib/ado-duplicate-detector.ts +407 -0
- package/plugins/specweave-github/agents/github-manager/AGENT.md +2 -2
- package/plugins/specweave-infrastructure/skills/hetzner-provisioner/README.md +1 -1
- package/plugins/specweave-jira/agents/jira-manager/AGENT.md +1 -1
- package/plugins/specweave-jira/agents/jira-multi-project-mapper/AGENT.md +530 -0
- package/plugins/specweave-jira/agents/jira-sync-judge/AGENT.md +438 -0
- package/plugins/specweave-jira/commands/cleanup-duplicates.md +219 -0
- package/plugins/specweave-jira/commands/close.md +297 -0
- package/plugins/specweave-jira/commands/create.md +198 -0
- package/plugins/specweave-jira/commands/reconcile.md +123 -0
- package/plugins/specweave-jira/commands/status.md +215 -0
- package/plugins/specweave-jira/lib/jira-duplicate-detector.js +296 -0
- package/plugins/specweave-jira/lib/jira-duplicate-detector.ts +434 -0
- package/plugins/specweave-jira/lib/jira-permission-gate.js +160 -0
- package/plugins/specweave-jira/lib/jira-permission-gate.ts +276 -0
- package/plugins/specweave-jira/lib/jira-profile-resolver.js +222 -0
- package/plugins/specweave-jira/lib/jira-profile-resolver.ts +427 -0
- package/plugins/specweave-jira/reference/jira-specweave-mapping.md +16 -11
- package/plugins/specweave-release/commands/specweave-release-npm.md +140 -14
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frontend Standards Parser - Detect and parse React/Angular/Vue coding standards
|
|
3
|
+
*
|
|
4
|
+
* Detects framework from package.json, parses ESLint plugins, and extracts conventions
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from 'fs';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import { promisify } from 'util';
|
|
9
|
+
import { consoleLogger } from '../../../utils/logger.js';
|
|
10
|
+
const readFile = promisify(fs.readFile);
|
|
11
|
+
const stat = promisify(fs.stat);
|
|
12
|
+
const FRAMEWORK_DEPENDENCIES = {
|
|
13
|
+
react: ['react', 'react-dom', 'next', 'gatsby', '@remix-run/react', 'preact'],
|
|
14
|
+
angular: ['@angular/core', '@angular/cli'],
|
|
15
|
+
vue: ['vue', 'nuxt', '@nuxt/core', '@vue/cli-service'],
|
|
16
|
+
svelte: ['svelte', '@sveltejs/kit'],
|
|
17
|
+
none: [],
|
|
18
|
+
};
|
|
19
|
+
const STATE_MANAGEMENT_LIBS = {
|
|
20
|
+
redux: ['react'],
|
|
21
|
+
'@reduxjs/toolkit': ['react'],
|
|
22
|
+
zustand: ['react'],
|
|
23
|
+
jotai: ['react'],
|
|
24
|
+
recoil: ['react'],
|
|
25
|
+
mobx: ['react', 'vue'],
|
|
26
|
+
pinia: ['vue'],
|
|
27
|
+
vuex: ['vue'],
|
|
28
|
+
'@ngrx/store': ['angular'],
|
|
29
|
+
'@ngxs/store': ['angular'],
|
|
30
|
+
'svelte/store': ['svelte'],
|
|
31
|
+
};
|
|
32
|
+
const CSS_METHODOLOGIES = {
|
|
33
|
+
tailwindcss: 'Tailwind CSS (utility-first)',
|
|
34
|
+
'styled-components': 'styled-components (CSS-in-JS)',
|
|
35
|
+
'@emotion/react': 'Emotion (CSS-in-JS)',
|
|
36
|
+
'@emotion/styled': 'Emotion (CSS-in-JS)',
|
|
37
|
+
'sass': 'Sass/SCSS (preprocessor)',
|
|
38
|
+
'node-sass': 'Sass/SCSS (preprocessor)',
|
|
39
|
+
'less': 'Less (preprocessor)',
|
|
40
|
+
'@vanilla-extract/css': 'Vanilla Extract (zero-runtime CSS-in-TS)',
|
|
41
|
+
'css-modules': 'CSS Modules (scoped CSS)',
|
|
42
|
+
};
|
|
43
|
+
const TESTING_FRAMEWORKS = {
|
|
44
|
+
jest: 'Jest',
|
|
45
|
+
vitest: 'Vitest',
|
|
46
|
+
'@testing-library/react': 'React Testing Library',
|
|
47
|
+
'@testing-library/vue': 'Vue Testing Library',
|
|
48
|
+
'@testing-library/angular': 'Angular Testing Library',
|
|
49
|
+
cypress: 'Cypress (E2E)',
|
|
50
|
+
playwright: 'Playwright (E2E)',
|
|
51
|
+
'@playwright/test': 'Playwright (E2E)',
|
|
52
|
+
};
|
|
53
|
+
const BUNDLERS = {
|
|
54
|
+
vite: 'Vite',
|
|
55
|
+
webpack: 'webpack',
|
|
56
|
+
esbuild: 'esbuild',
|
|
57
|
+
rollup: 'Rollup',
|
|
58
|
+
parcel: 'Parcel',
|
|
59
|
+
'@angular/cli': 'Angular CLI (webpack)',
|
|
60
|
+
next: 'Next.js (webpack/turbopack)',
|
|
61
|
+
nuxt: 'Nuxt (Vite/webpack)',
|
|
62
|
+
};
|
|
63
|
+
export class FrontendStandardsParser {
|
|
64
|
+
constructor(options = {}) {
|
|
65
|
+
this.logger = options.logger ?? consoleLogger;
|
|
66
|
+
}
|
|
67
|
+
async parse(projectPath) {
|
|
68
|
+
const warnings = [];
|
|
69
|
+
const result = {
|
|
70
|
+
framework: 'none',
|
|
71
|
+
testing: { frameworks: [] },
|
|
72
|
+
eslintPlugins: [],
|
|
73
|
+
componentNaming: {
|
|
74
|
+
convention: 'PascalCase',
|
|
75
|
+
fileExtension: '.tsx',
|
|
76
|
+
},
|
|
77
|
+
warnings,
|
|
78
|
+
};
|
|
79
|
+
// Read package.json
|
|
80
|
+
const packageJsonPath = path.join(projectPath, 'package.json');
|
|
81
|
+
if (!(await this.fileExists(packageJsonPath))) {
|
|
82
|
+
warnings.push('No package.json found');
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
let packageJson;
|
|
86
|
+
try {
|
|
87
|
+
const content = await readFile(packageJsonPath, 'utf-8');
|
|
88
|
+
packageJson = JSON.parse(content);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
warnings.push(`Failed to parse package.json: ${error}`);
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
const allDeps = {
|
|
95
|
+
...packageJson.dependencies,
|
|
96
|
+
...packageJson.devDependencies,
|
|
97
|
+
};
|
|
98
|
+
// Detect framework
|
|
99
|
+
const { framework, version } = this.detectFramework(allDeps);
|
|
100
|
+
result.framework = framework;
|
|
101
|
+
result.frameworkVersion = version;
|
|
102
|
+
// Set framework-specific defaults
|
|
103
|
+
this.setFrameworkDefaults(result, framework);
|
|
104
|
+
// Detect state management
|
|
105
|
+
result.stateManagement = this.detectStateManagement(allDeps, framework);
|
|
106
|
+
// Detect CSS methodology
|
|
107
|
+
result.cssMethodology = this.detectCssMethodology(allDeps);
|
|
108
|
+
// Detect testing frameworks
|
|
109
|
+
result.testing = this.detectTesting(allDeps);
|
|
110
|
+
// Detect bundler
|
|
111
|
+
result.bundler = this.detectBundler(allDeps);
|
|
112
|
+
// Parse ESLint config for plugins
|
|
113
|
+
result.eslintPlugins = await this.detectEslintPlugins(projectPath, framework);
|
|
114
|
+
// Detect routing
|
|
115
|
+
result.routing = this.detectRouting(allDeps, framework);
|
|
116
|
+
// Framework-specific config parsing
|
|
117
|
+
if (framework === 'angular') {
|
|
118
|
+
await this.parseAngularConfig(projectPath, result);
|
|
119
|
+
}
|
|
120
|
+
else if (framework === 'vue') {
|
|
121
|
+
await this.parseVueConfig(projectPath, result);
|
|
122
|
+
}
|
|
123
|
+
this.logger.debug(`Detected frontend: ${framework} ${version ?? ''}`);
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
detectFramework(deps) {
|
|
127
|
+
for (const [framework, markers] of Object.entries(FRAMEWORK_DEPENDENCIES)) {
|
|
128
|
+
if (framework === 'none')
|
|
129
|
+
continue;
|
|
130
|
+
for (const marker of markers) {
|
|
131
|
+
if (deps[marker]) {
|
|
132
|
+
return {
|
|
133
|
+
framework: framework,
|
|
134
|
+
version: deps[marker]?.replace(/[\^~]/, ''),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return { framework: 'none' };
|
|
140
|
+
}
|
|
141
|
+
setFrameworkDefaults(result, framework) {
|
|
142
|
+
switch (framework) {
|
|
143
|
+
case 'react':
|
|
144
|
+
result.componentNaming = {
|
|
145
|
+
convention: 'PascalCase',
|
|
146
|
+
fileExtension: '.tsx',
|
|
147
|
+
folderStructure: 'components/{ComponentName}/{ComponentName}.tsx',
|
|
148
|
+
};
|
|
149
|
+
result.hooks = {
|
|
150
|
+
enabled: true,
|
|
151
|
+
customHooksPattern: 'use{Name}',
|
|
152
|
+
};
|
|
153
|
+
break;
|
|
154
|
+
case 'angular':
|
|
155
|
+
result.componentNaming = {
|
|
156
|
+
convention: 'kebab-case',
|
|
157
|
+
fileExtension: '.ts',
|
|
158
|
+
folderStructure: '{feature}/{feature}.component.ts',
|
|
159
|
+
};
|
|
160
|
+
break;
|
|
161
|
+
case 'vue':
|
|
162
|
+
result.componentNaming = {
|
|
163
|
+
convention: 'PascalCase',
|
|
164
|
+
fileExtension: '.vue',
|
|
165
|
+
folderStructure: 'components/{ComponentName}.vue',
|
|
166
|
+
};
|
|
167
|
+
break;
|
|
168
|
+
case 'svelte':
|
|
169
|
+
result.componentNaming = {
|
|
170
|
+
convention: 'PascalCase',
|
|
171
|
+
fileExtension: '.svelte',
|
|
172
|
+
folderStructure: 'components/{ComponentName}.svelte',
|
|
173
|
+
};
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
detectStateManagement(deps, framework) {
|
|
178
|
+
for (const [lib, frameworks] of Object.entries(STATE_MANAGEMENT_LIBS)) {
|
|
179
|
+
if (deps[lib] && (frameworks.includes(framework) || framework === 'none')) {
|
|
180
|
+
return {
|
|
181
|
+
name: lib,
|
|
182
|
+
version: deps[lib]?.replace(/[\^~]/, ''),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
detectCssMethodology(deps) {
|
|
189
|
+
for (const [lib, description] of Object.entries(CSS_METHODOLOGIES)) {
|
|
190
|
+
if (deps[lib]) {
|
|
191
|
+
return {
|
|
192
|
+
name: lib,
|
|
193
|
+
details: description,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
detectTesting(deps) {
|
|
200
|
+
const frameworks = [];
|
|
201
|
+
let e2e;
|
|
202
|
+
for (const [lib, name] of Object.entries(TESTING_FRAMEWORKS)) {
|
|
203
|
+
if (deps[lib]) {
|
|
204
|
+
if (name.includes('E2E')) {
|
|
205
|
+
e2e = name;
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
frameworks.push(name);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
frameworks,
|
|
214
|
+
e2e,
|
|
215
|
+
coverage: !!(deps['@vitest/coverage-v8'] || deps['jest'] || deps['c8']),
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
detectBundler(deps) {
|
|
219
|
+
for (const [lib, name] of Object.entries(BUNDLERS)) {
|
|
220
|
+
if (deps[lib]) {
|
|
221
|
+
return {
|
|
222
|
+
name,
|
|
223
|
+
version: deps[lib]?.replace(/[\^~]/, ''),
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return undefined;
|
|
228
|
+
}
|
|
229
|
+
detectRouting(deps, framework) {
|
|
230
|
+
const routingLibs = {
|
|
231
|
+
'react-router-dom': 'React Router',
|
|
232
|
+
'@tanstack/react-router': 'TanStack Router',
|
|
233
|
+
'vue-router': 'Vue Router',
|
|
234
|
+
'@angular/router': 'Angular Router',
|
|
235
|
+
};
|
|
236
|
+
for (const [lib, name] of Object.entries(routingLibs)) {
|
|
237
|
+
if (deps[lib]) {
|
|
238
|
+
return {
|
|
239
|
+
library: name,
|
|
240
|
+
version: deps[lib]?.replace(/[\^~]/, ''),
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
// Built-in routing for meta-frameworks
|
|
245
|
+
if (deps['next'])
|
|
246
|
+
return { library: 'Next.js App Router' };
|
|
247
|
+
if (deps['nuxt'])
|
|
248
|
+
return { library: 'Nuxt Router' };
|
|
249
|
+
if (deps['@sveltejs/kit'])
|
|
250
|
+
return { library: 'SvelteKit Router' };
|
|
251
|
+
return undefined;
|
|
252
|
+
}
|
|
253
|
+
async detectEslintPlugins(projectPath, framework) {
|
|
254
|
+
const eslintConfigs = [
|
|
255
|
+
'.eslintrc.json',
|
|
256
|
+
'.eslintrc.js',
|
|
257
|
+
'.eslintrc.cjs',
|
|
258
|
+
'.eslintrc.yml',
|
|
259
|
+
'eslint.config.js',
|
|
260
|
+
'eslint.config.mjs',
|
|
261
|
+
];
|
|
262
|
+
const plugins = [];
|
|
263
|
+
for (const config of eslintConfigs) {
|
|
264
|
+
const configPath = path.join(projectPath, config);
|
|
265
|
+
if (await this.fileExists(configPath)) {
|
|
266
|
+
try {
|
|
267
|
+
const content = await readFile(configPath, 'utf-8');
|
|
268
|
+
// Common framework-specific plugins
|
|
269
|
+
const frameworkPlugins = {
|
|
270
|
+
react: ['plugin:react/', 'plugin:react-hooks/', 'plugin:jsx-a11y/'],
|
|
271
|
+
angular: ['plugin:@angular-eslint/', 'plugin:@typescript-eslint/'],
|
|
272
|
+
vue: ['plugin:vue/', 'plugin:vue-scoped-css/'],
|
|
273
|
+
svelte: ['plugin:svelte/'],
|
|
274
|
+
none: [],
|
|
275
|
+
};
|
|
276
|
+
for (const plugin of frameworkPlugins[framework] ?? []) {
|
|
277
|
+
if (content.includes(plugin)) {
|
|
278
|
+
plugins.push(plugin.replace('plugin:', '').replace('/', ''));
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
// Check for common plugins
|
|
282
|
+
const commonPlugins = [
|
|
283
|
+
'import',
|
|
284
|
+
'prettier',
|
|
285
|
+
'@typescript-eslint',
|
|
286
|
+
'testing-library',
|
|
287
|
+
'jest',
|
|
288
|
+
'vitest',
|
|
289
|
+
];
|
|
290
|
+
for (const plugin of commonPlugins) {
|
|
291
|
+
if (content.includes(`"${plugin}"`) || content.includes(`'${plugin}'`)) {
|
|
292
|
+
plugins.push(plugin);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
catch {
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return Array.from(new Set(plugins)); // Remove duplicates
|
|
303
|
+
}
|
|
304
|
+
async parseAngularConfig(projectPath, result) {
|
|
305
|
+
const angularJsonPath = path.join(projectPath, 'angular.json');
|
|
306
|
+
if (!(await this.fileExists(angularJsonPath)))
|
|
307
|
+
return;
|
|
308
|
+
try {
|
|
309
|
+
const content = await readFile(angularJsonPath, 'utf-8');
|
|
310
|
+
const config = JSON.parse(content);
|
|
311
|
+
// Extract style preprocessor
|
|
312
|
+
const projects = config.projects ?? {};
|
|
313
|
+
const firstProject = Object.values(projects)[0];
|
|
314
|
+
if (firstProject?.architect?.build?.options?.styles) {
|
|
315
|
+
const styles = firstProject.architect.build.options.styles;
|
|
316
|
+
if (styles.some((s) => s.endsWith('.scss'))) {
|
|
317
|
+
result.cssMethodology = { name: 'sass', details: 'Sass/SCSS (preprocessor)' };
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
this.logger.debug('Parsed angular.json');
|
|
321
|
+
}
|
|
322
|
+
catch {
|
|
323
|
+
result.warnings.push('Failed to parse angular.json');
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
async parseVueConfig(projectPath, result) {
|
|
327
|
+
// Check for Vue config files
|
|
328
|
+
const vueConfigs = ['vue.config.js', 'vite.config.ts', 'vite.config.js', 'nuxt.config.ts'];
|
|
329
|
+
for (const config of vueConfigs) {
|
|
330
|
+
const configPath = path.join(projectPath, config);
|
|
331
|
+
if (await this.fileExists(configPath)) {
|
|
332
|
+
try {
|
|
333
|
+
const content = await readFile(configPath, 'utf-8');
|
|
334
|
+
// Detect Composition API usage
|
|
335
|
+
if (content.includes('composition') || content.includes('script setup')) {
|
|
336
|
+
result.hooks = {
|
|
337
|
+
enabled: true,
|
|
338
|
+
customHooksPattern: 'use{Name}',
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
this.logger.debug(`Parsed ${config}`);
|
|
342
|
+
}
|
|
343
|
+
catch {
|
|
344
|
+
continue;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
async fileExists(filePath) {
|
|
350
|
+
try {
|
|
351
|
+
await stat(filePath);
|
|
352
|
+
return true;
|
|
353
|
+
}
|
|
354
|
+
catch {
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Convenience function for quick frontend standards parsing
|
|
361
|
+
*/
|
|
362
|
+
export async function parseFrontendStandards(projectPath, options) {
|
|
363
|
+
const parser = new FrontendStandardsParser(options);
|
|
364
|
+
return parser.parse(projectPath);
|
|
365
|
+
}
|
|
366
|
+
//# sourceMappingURL=frontend-standards-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontend-standards-parser.js","sourceRoot":"","sources":["../../../../../src/core/living-docs/governance/frontend-standards-parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAU,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEjE,MAAM,QAAQ,GAAG,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;AACxC,MAAM,IAAI,GAAG,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;AA2DhC,MAAM,sBAAsB,GAAwC;IAClE,KAAK,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,kBAAkB,EAAE,QAAQ,CAAC;IAC7E,OAAO,EAAE,CAAC,eAAe,EAAE,cAAc,CAAC;IAC1C,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,kBAAkB,CAAC;IACtD,MAAM,EAAE,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,IAAI,EAAE,EAAE;CACT,CAAC;AAEF,MAAM,qBAAqB,GAAwC;IACjE,KAAK,EAAE,CAAC,OAAO,CAAC;IAChB,kBAAkB,EAAE,CAAC,OAAO,CAAC;IAC7B,OAAO,EAAE,CAAC,OAAO,CAAC;IAClB,KAAK,EAAE,CAAC,OAAO,CAAC;IAChB,MAAM,EAAE,CAAC,OAAO,CAAC;IACjB,IAAI,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC;IACtB,KAAK,EAAE,CAAC,KAAK,CAAC;IACd,IAAI,EAAE,CAAC,KAAK,CAAC;IACb,aAAa,EAAE,CAAC,SAAS,CAAC;IAC1B,aAAa,EAAE,CAAC,SAAS,CAAC;IAC1B,cAAc,EAAE,CAAC,QAAQ,CAAC;CAC3B,CAAC;AAEF,MAAM,iBAAiB,GAA2B;IAChD,WAAW,EAAE,8BAA8B;IAC3C,mBAAmB,EAAE,+BAA+B;IACpD,gBAAgB,EAAE,qBAAqB;IACvC,iBAAiB,EAAE,qBAAqB;IACxC,MAAM,EAAE,0BAA0B;IAClC,WAAW,EAAE,0BAA0B;IACvC,MAAM,EAAE,qBAAqB;IAC7B,sBAAsB,EAAE,0CAA0C;IAClE,aAAa,EAAE,0BAA0B;CAC1C,CAAC;AAEF,MAAM,kBAAkB,GAA2B;IACjD,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;IAChB,wBAAwB,EAAE,uBAAuB;IACjD,sBAAsB,EAAE,qBAAqB;IAC7C,0BAA0B,EAAE,yBAAyB;IACrD,OAAO,EAAE,eAAe;IACxB,UAAU,EAAE,kBAAkB;IAC9B,kBAAkB,EAAE,kBAAkB;CACvC,CAAC;AAEF,MAAM,QAAQ,GAA2B;IACvC,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;IAChB,cAAc,EAAE,uBAAuB;IACvC,IAAI,EAAE,6BAA6B;IACnC,IAAI,EAAE,qBAAqB;CAC5B,CAAC;AAEF,MAAM,OAAO,uBAAuB;IAGlC,YAAY,UAA0C,EAAE;QACtD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,WAAmB;QAC7B,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAsB;YAChC,SAAS,EAAE,MAAM;YACjB,OAAO,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;YAC3B,aAAa,EAAE,EAAE;YACjB,eAAe,EAAE;gBACf,UAAU,EAAE,YAAY;gBACxB,aAAa,EAAE,MAAM;aACtB;YACD,QAAQ;SACT,CAAC;QAEF,oBAAoB;QACpB,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QAC/D,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC;YAC9C,QAAQ,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;YACvC,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,IAAI,WAGH,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;YACzD,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,CAAC,IAAI,CAAC,iCAAiC,KAAK,EAAE,CAAC,CAAC;YACxD,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,MAAM,OAAO,GAAG;YACd,GAAG,WAAW,CAAC,YAAY;YAC3B,GAAG,WAAW,CAAC,eAAe;SAC/B,CAAC;QAEF,mBAAmB;QACnB,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAC7D,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC;QAC7B,MAAM,CAAC,gBAAgB,GAAG,OAAO,CAAC;QAElC,kCAAkC;QAClC,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAE7C,0BAA0B;QAC1B,MAAM,CAAC,eAAe,GAAG,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAExE,yBAAyB;QACzB,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAE3D,4BAA4B;QAC5B,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAE7C,iBAAiB;QACjB,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAE7C,kCAAkC;QAClC,MAAM,CAAC,aAAa,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QAE9E,iBAAiB;QACjB,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAExD,oCAAoC;QACpC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,IAAI,CAAC,kBAAkB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACrD,CAAC;aAAM,IAAI,SAAS,KAAK,KAAK,EAAE,CAAC;YAC/B,MAAM,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,SAAS,IAAI,OAAO,IAAI,EAAE,EAAE,CAAC,CAAC;QACtE,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,eAAe,CAAC,IAA4B;QAIlD,KAAK,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC,EAAE,CAAC;YAC1E,IAAI,SAAS,KAAK,MAAM;gBAAE,SAAS;YAEnC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;oBACjB,OAAO;wBACL,SAAS,EAAE,SAA8B;wBACzC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;qBAC5C,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAC/B,CAAC;IAEO,oBAAoB,CAAC,MAAyB,EAAE,SAA4B;QAClF,QAAQ,SAAS,EAAE,CAAC;YAClB,KAAK,OAAO;gBACV,MAAM,CAAC,eAAe,GAAG;oBACvB,UAAU,EAAE,YAAY;oBACxB,aAAa,EAAE,MAAM;oBACrB,eAAe,EAAE,gDAAgD;iBAClE,CAAC;gBACF,MAAM,CAAC,KAAK,GAAG;oBACb,OAAO,EAAE,IAAI;oBACb,kBAAkB,EAAE,WAAW;iBAChC,CAAC;gBACF,MAAM;YAER,KAAK,SAAS;gBACZ,MAAM,CAAC,eAAe,GAAG;oBACvB,UAAU,EAAE,YAAY;oBACxB,aAAa,EAAE,KAAK;oBACpB,eAAe,EAAE,kCAAkC;iBACpD,CAAC;gBACF,MAAM;YAER,KAAK,KAAK;gBACR,MAAM,CAAC,eAAe,GAAG;oBACvB,UAAU,EAAE,YAAY;oBACxB,aAAa,EAAE,MAAM;oBACrB,eAAe,EAAE,gCAAgC;iBAClD,CAAC;gBACF,MAAM;YAER,KAAK,QAAQ;gBACX,MAAM,CAAC,eAAe,GAAG;oBACvB,UAAU,EAAE,YAAY;oBACxB,aAAa,EAAE,SAAS;oBACxB,eAAe,EAAE,mCAAmC;iBACrD,CAAC;gBACF,MAAM;QACV,CAAC;IACH,CAAC;IAEO,qBAAqB,CAC3B,IAA4B,EAC5B,SAA4B;QAE5B,KAAK,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,qBAAqB,CAAC,EAAE,CAAC;YACtE,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,KAAK,MAAM,CAAC,EAAE,CAAC;gBAC1E,OAAO;oBACL,IAAI,EAAE,GAAG;oBACT,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;iBACzC,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,oBAAoB,CAAC,IAA4B;QACvD,KAAK,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACnE,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBACd,OAAO;oBACL,IAAI,EAAE,GAAG;oBACT,OAAO,EAAE,WAAW;iBACrB,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,aAAa,CAAC,IAA4B;QAChD,MAAM,UAAU,GAAa,EAAE,CAAC;QAChC,IAAI,GAAuB,CAAC;QAE5B,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC7D,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBACd,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;oBACzB,GAAG,GAAG,IAAI,CAAC;gBACb,CAAC;qBAAM,CAAC;oBACN,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACxB,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO;YACL,UAAU;YACV,GAAG;YACH,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;SACxE,CAAC;IACJ,CAAC;IAEO,aAAa,CAAC,IAA4B;QAChD,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnD,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBACd,OAAO;oBACL,IAAI;oBACJ,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;iBACzC,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,aAAa,CACnB,IAA4B,EAC5B,SAA4B;QAE5B,MAAM,WAAW,GAA2B;YAC1C,kBAAkB,EAAE,cAAc;YAClC,wBAAwB,EAAE,iBAAiB;YAC3C,YAAY,EAAE,YAAY;YAC1B,iBAAiB,EAAE,gBAAgB;SACpC,CAAC;QAEF,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;YACtD,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBACd,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;iBACzC,CAAC;YACJ,CAAC;QACH,CAAC;QAED,uCAAuC;QACvC,IAAI,IAAI,CAAC,MAAM,CAAC;YAAE,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC;QAC3D,IAAI,IAAI,CAAC,MAAM,CAAC;YAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;QACpD,IAAI,IAAI,CAAC,eAAe,CAAC;YAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC;QAElE,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAC/B,WAAmB,EACnB,SAA4B;QAE5B,MAAM,aAAa,GAAG;YACpB,gBAAgB;YAChB,cAAc;YACd,eAAe;YACf,eAAe;YACf,kBAAkB;YAClB,mBAAmB;SACpB,CAAC;QAEF,MAAM,OAAO,GAAa,EAAE,CAAC;QAE7B,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;YACnC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;YAClD,IAAI,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBACtC,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;oBAEpD,oCAAoC;oBACpC,MAAM,gBAAgB,GAAwC;wBAC5D,KAAK,EAAE,CAAC,eAAe,EAAE,qBAAqB,EAAE,kBAAkB,CAAC;wBACnE,OAAO,EAAE,CAAC,yBAAyB,EAAE,4BAA4B,CAAC;wBAClE,GAAG,EAAE,CAAC,aAAa,EAAE,wBAAwB,CAAC;wBAC9C,MAAM,EAAE,CAAC,gBAAgB,CAAC;wBAC1B,IAAI,EAAE,EAAE;qBACT,CAAC;oBAEF,KAAK,MAAM,MAAM,IAAI,gBAAgB,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;wBACvD,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;4BAC7B,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;wBAC/D,CAAC;oBACH,CAAC;oBAED,2BAA2B;oBAC3B,MAAM,aAAa,GAAG;wBACpB,QAAQ;wBACR,UAAU;wBACV,oBAAoB;wBACpB,iBAAiB;wBACjB,MAAM;wBACN,QAAQ;qBACT,CAAC;oBAEF,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;wBACnC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;4BACvE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;wBACvB,CAAC;oBACH,CAAC;oBAED,MAAM;gBACR,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS;gBACX,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,oBAAoB;IAC3D,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAC9B,WAAmB,EACnB,MAAyB;QAEzB,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QAC/D,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;YAAE,OAAO;QAEtD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;YACzD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAEnC,6BAA6B;YAC7B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;YACvC,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAS7C,CAAC;YAEF,IAAI,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;gBACpD,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;gBAC3D,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;oBACpD,MAAM,CAAC,cAAc,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC;gBAChF,CAAC;YACH,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAC3C,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,WAAmB,EAAE,MAAyB;QACzE,6BAA6B;QAC7B,MAAM,UAAU,GAAG,CAAC,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;QAE3F,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;YAChC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;YAClD,IAAI,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBACtC,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;oBAEpD,+BAA+B;oBAC/B,IAAI,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;wBACxE,MAAM,CAAC,KAAK,GAAG;4BACb,OAAO,EAAE,IAAI;4BACb,kBAAkB,EAAE,WAAW;yBAChC,CAAC;oBACJ,CAAC;oBAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC;gBACxC,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS;gBACX,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,UAAU,CAAC,QAAgB;QACvC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrB,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,WAAmB,EACnB,OAAwC;IAExC,MAAM,MAAM,GAAG,IAAI,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACpD,OAAO,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Go Standards Parser - Parse Go config files for coding standards
|
|
3
|
+
*
|
|
4
|
+
* Supports: go.mod, .golangci.yml/.golangci.yaml, staticcheck.conf
|
|
5
|
+
*/
|
|
6
|
+
import { Logger } from '../../../utils/logger.js';
|
|
7
|
+
export interface GoStandards {
|
|
8
|
+
goVersion: string;
|
|
9
|
+
modulePath: string;
|
|
10
|
+
linter?: GolangciLintConfig;
|
|
11
|
+
staticcheck?: StaticcheckConfig;
|
|
12
|
+
namingConventions: GoNamingConventions;
|
|
13
|
+
errorHandling: ErrorHandlingConfig;
|
|
14
|
+
formatting: FormattingConfig;
|
|
15
|
+
warnings: string[];
|
|
16
|
+
}
|
|
17
|
+
export interface GolangciLintConfig {
|
|
18
|
+
name: 'golangci-lint';
|
|
19
|
+
enabledLinters: string[];
|
|
20
|
+
disabledLinters: string[];
|
|
21
|
+
presets?: string[];
|
|
22
|
+
config: Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
export interface StaticcheckConfig {
|
|
25
|
+
enabled: boolean;
|
|
26
|
+
checks: string[];
|
|
27
|
+
}
|
|
28
|
+
export interface GoNamingConventions {
|
|
29
|
+
packages: string;
|
|
30
|
+
exported: string;
|
|
31
|
+
unexported: string;
|
|
32
|
+
interfaces: string;
|
|
33
|
+
receiverNames: string;
|
|
34
|
+
acronyms: string;
|
|
35
|
+
}
|
|
36
|
+
export interface ErrorHandlingConfig {
|
|
37
|
+
errcheckEnabled: boolean;
|
|
38
|
+
wrapperPattern?: string;
|
|
39
|
+
sentinelErrors: boolean;
|
|
40
|
+
}
|
|
41
|
+
export interface FormattingConfig {
|
|
42
|
+
gofmt: boolean;
|
|
43
|
+
goimports: boolean;
|
|
44
|
+
gofumpt: boolean;
|
|
45
|
+
}
|
|
46
|
+
export interface GoStandardsParserOptions {
|
|
47
|
+
logger?: Logger;
|
|
48
|
+
}
|
|
49
|
+
export declare class GoStandardsParser {
|
|
50
|
+
private logger;
|
|
51
|
+
constructor(options?: GoStandardsParserOptions);
|
|
52
|
+
parse(projectPath: string, configFiles: string[]): Promise<GoStandards>;
|
|
53
|
+
private parseGoMod;
|
|
54
|
+
private parseGolangciLint;
|
|
55
|
+
private parseStaticcheck;
|
|
56
|
+
private extractYamlList;
|
|
57
|
+
private extractYamlSection;
|
|
58
|
+
private fileExists;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Convenience function for quick Go standards parsing
|
|
62
|
+
*/
|
|
63
|
+
export declare function parseGoStandards(projectPath: string, configFiles: string[], options?: GoStandardsParserOptions): Promise<GoStandards>;
|
|
64
|
+
//# sourceMappingURL=go-standards-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"go-standards-parser.d.ts","sourceRoot":"","sources":["../../../../../src/core/living-docs/governance/go-standards-parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,MAAM,EAAiB,MAAM,0BAA0B,CAAC;AAKjE,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,iBAAiB,EAAE,mBAAmB,CAAC;IACvC,aAAa,EAAE,mBAAmB,CAAC;IACnC,UAAU,EAAE,gBAAgB,CAAC;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,eAAe,CAAC;IACtB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,GAAE,wBAA6B;IAI5C,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;YAiD/D,UAAU;YAsBV,iBAAiB;YAyGjB,gBAAgB;IA4B9B,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,kBAAkB;YAMZ,UAAU;CAQzB;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EAAE,EACrB,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,WAAW,CAAC,CAGtB"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Go Standards Parser - Parse Go config files for coding standards
|
|
3
|
+
*
|
|
4
|
+
* Supports: go.mod, .golangci.yml/.golangci.yaml, staticcheck.conf
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from 'fs';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import { promisify } from 'util';
|
|
9
|
+
import { consoleLogger } from '../../../utils/logger.js';
|
|
10
|
+
const readFile = promisify(fs.readFile);
|
|
11
|
+
const stat = promisify(fs.stat);
|
|
12
|
+
export class GoStandardsParser {
|
|
13
|
+
constructor(options = {}) {
|
|
14
|
+
this.logger = options.logger ?? consoleLogger;
|
|
15
|
+
}
|
|
16
|
+
async parse(projectPath, configFiles) {
|
|
17
|
+
const warnings = [];
|
|
18
|
+
const result = {
|
|
19
|
+
goVersion: '1.21', // Default
|
|
20
|
+
modulePath: '',
|
|
21
|
+
namingConventions: {
|
|
22
|
+
packages: 'lowercase (single word, no underscores)',
|
|
23
|
+
exported: 'PascalCase (MixedCaps)',
|
|
24
|
+
unexported: 'camelCase (mixedCaps)',
|
|
25
|
+
interfaces: 'PascalCase (single method: -er suffix)',
|
|
26
|
+
receiverNames: '1-2 letter abbreviation',
|
|
27
|
+
acronyms: 'Uppercase (HTTP, URL, ID)',
|
|
28
|
+
},
|
|
29
|
+
errorHandling: {
|
|
30
|
+
errcheckEnabled: false,
|
|
31
|
+
sentinelErrors: true,
|
|
32
|
+
},
|
|
33
|
+
formatting: {
|
|
34
|
+
gofmt: true,
|
|
35
|
+
goimports: false,
|
|
36
|
+
gofumpt: false,
|
|
37
|
+
},
|
|
38
|
+
warnings,
|
|
39
|
+
};
|
|
40
|
+
// Parse go.mod first
|
|
41
|
+
if (configFiles.includes('go.mod')) {
|
|
42
|
+
const goModPath = path.join(projectPath, 'go.mod');
|
|
43
|
+
await this.parseGoMod(goModPath, result);
|
|
44
|
+
}
|
|
45
|
+
// Parse golangci-lint config
|
|
46
|
+
const golangciConfig = configFiles.find((f) => f === '.golangci.yml' || f === '.golangci.yaml');
|
|
47
|
+
if (golangciConfig) {
|
|
48
|
+
const configPath = path.join(projectPath, golangciConfig);
|
|
49
|
+
await this.parseGolangciLint(configPath, result);
|
|
50
|
+
}
|
|
51
|
+
// Parse staticcheck config
|
|
52
|
+
if (configFiles.includes('staticcheck.conf')) {
|
|
53
|
+
const staticcheckPath = path.join(projectPath, 'staticcheck.conf');
|
|
54
|
+
await this.parseStaticcheck(staticcheckPath, result);
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
async parseGoMod(filePath, result) {
|
|
59
|
+
try {
|
|
60
|
+
const content = await readFile(filePath, 'utf-8');
|
|
61
|
+
// Parse module path
|
|
62
|
+
const moduleMatch = content.match(/^module\s+(.+)$/m);
|
|
63
|
+
if (moduleMatch) {
|
|
64
|
+
result.modulePath = moduleMatch[1].trim();
|
|
65
|
+
}
|
|
66
|
+
// Parse Go version
|
|
67
|
+
const versionMatch = content.match(/^go\s+(\d+\.\d+(?:\.\d+)?)$/m);
|
|
68
|
+
if (versionMatch) {
|
|
69
|
+
result.goVersion = versionMatch[1];
|
|
70
|
+
}
|
|
71
|
+
this.logger.debug(`Parsed go.mod: module=${result.modulePath}, go=${result.goVersion}`);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
result.warnings.push(`Failed to parse go.mod: ${error}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async parseGolangciLint(filePath, result) {
|
|
78
|
+
try {
|
|
79
|
+
const content = await readFile(filePath, 'utf-8');
|
|
80
|
+
const enabledLinters = [];
|
|
81
|
+
const disabledLinters = [];
|
|
82
|
+
const presets = [];
|
|
83
|
+
// Parse linters-settings section for enabled linters
|
|
84
|
+
// This is a simplified YAML parser - in production, use a proper YAML lib
|
|
85
|
+
// Check for linters.enable section
|
|
86
|
+
const enableSection = this.extractYamlList(content, 'enable');
|
|
87
|
+
if (enableSection.length > 0) {
|
|
88
|
+
enabledLinters.push(...enableSection);
|
|
89
|
+
}
|
|
90
|
+
// Check for linters.disable section
|
|
91
|
+
const disableSection = this.extractYamlList(content, 'disable');
|
|
92
|
+
if (disableSection.length > 0) {
|
|
93
|
+
disabledLinters.push(...disableSection);
|
|
94
|
+
}
|
|
95
|
+
// Check for presets
|
|
96
|
+
const presetsSection = this.extractYamlList(content, 'presets');
|
|
97
|
+
if (presetsSection.length > 0) {
|
|
98
|
+
presets.push(...presetsSection);
|
|
99
|
+
}
|
|
100
|
+
// Check for disable-all
|
|
101
|
+
if (content.includes('disable-all: true')) {
|
|
102
|
+
disabledLinters.push('all');
|
|
103
|
+
}
|
|
104
|
+
// Check for enable-all
|
|
105
|
+
if (content.includes('enable-all: true')) {
|
|
106
|
+
enabledLinters.push('all');
|
|
107
|
+
}
|
|
108
|
+
// Detect common linters from linters-settings
|
|
109
|
+
const lintersSettings = this.extractYamlSection(content, 'linters-settings');
|
|
110
|
+
if (lintersSettings) {
|
|
111
|
+
const detectedLinters = [
|
|
112
|
+
'errcheck',
|
|
113
|
+
'govet',
|
|
114
|
+
'staticcheck',
|
|
115
|
+
'gosimple',
|
|
116
|
+
'unused',
|
|
117
|
+
'ineffassign',
|
|
118
|
+
'typecheck',
|
|
119
|
+
'gofmt',
|
|
120
|
+
'goimports',
|
|
121
|
+
'gofumpt',
|
|
122
|
+
'goconst',
|
|
123
|
+
'gosec',
|
|
124
|
+
'misspell',
|
|
125
|
+
'revive',
|
|
126
|
+
'exhaustive',
|
|
127
|
+
'nilerr',
|
|
128
|
+
'wrapcheck',
|
|
129
|
+
];
|
|
130
|
+
for (const linter of detectedLinters) {
|
|
131
|
+
if (lintersSettings.includes(`${linter}:`)) {
|
|
132
|
+
if (!enabledLinters.includes(linter)) {
|
|
133
|
+
enabledLinters.push(linter);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Update error handling based on errcheck
|
|
139
|
+
if (enabledLinters.includes('errcheck') || enabledLinters.includes('all')) {
|
|
140
|
+
result.errorHandling.errcheckEnabled = true;
|
|
141
|
+
}
|
|
142
|
+
// Update formatting based on detected formatters
|
|
143
|
+
if (enabledLinters.includes('gofmt') || enabledLinters.includes('all')) {
|
|
144
|
+
result.formatting.gofmt = true;
|
|
145
|
+
}
|
|
146
|
+
if (enabledLinters.includes('goimports')) {
|
|
147
|
+
result.formatting.goimports = true;
|
|
148
|
+
}
|
|
149
|
+
if (enabledLinters.includes('gofumpt')) {
|
|
150
|
+
result.formatting.gofumpt = true;
|
|
151
|
+
}
|
|
152
|
+
// Check for wrapcheck (error wrapping)
|
|
153
|
+
if (enabledLinters.includes('wrapcheck')) {
|
|
154
|
+
result.errorHandling.wrapperPattern = 'fmt.Errorf("%w", err)';
|
|
155
|
+
}
|
|
156
|
+
result.linter = {
|
|
157
|
+
name: 'golangci-lint',
|
|
158
|
+
enabledLinters,
|
|
159
|
+
disabledLinters,
|
|
160
|
+
presets: presets.length > 0 ? presets : undefined,
|
|
161
|
+
config: {},
|
|
162
|
+
};
|
|
163
|
+
this.logger.debug(`Parsed golangci-lint: ${enabledLinters.length} enabled, ${disabledLinters.length} disabled`);
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
result.warnings.push(`Failed to parse golangci-lint config: ${error}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
async parseStaticcheck(filePath, result) {
|
|
170
|
+
try {
|
|
171
|
+
const content = await readFile(filePath, 'utf-8');
|
|
172
|
+
const checks = [];
|
|
173
|
+
// Parse checks list (TOML format)
|
|
174
|
+
const checksMatch = content.match(/checks\s*=\s*\[([^\]]+)\]/);
|
|
175
|
+
if (checksMatch) {
|
|
176
|
+
const checksList = checksMatch[1]
|
|
177
|
+
.split(',')
|
|
178
|
+
.map((s) => s.trim().replace(/["']/g, ''))
|
|
179
|
+
.filter((s) => s.length > 0);
|
|
180
|
+
checks.push(...checksList);
|
|
181
|
+
}
|
|
182
|
+
result.staticcheck = {
|
|
183
|
+
enabled: true,
|
|
184
|
+
checks,
|
|
185
|
+
};
|
|
186
|
+
this.logger.debug(`Parsed staticcheck: ${checks.length} checks configured`);
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
result.warnings.push(`Failed to parse staticcheck.conf: ${error}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// Simple YAML helpers (no external dependency)
|
|
193
|
+
extractYamlList(content, key) {
|
|
194
|
+
const result = [];
|
|
195
|
+
const regex = new RegExp(`${key}:\\s*\\n((?:\\s+-\\s+\\S+\\n?)+)`, 'g');
|
|
196
|
+
const match = content.match(regex);
|
|
197
|
+
if (match) {
|
|
198
|
+
const listContent = match[0];
|
|
199
|
+
const itemRegex = /-\s+(\S+)/g;
|
|
200
|
+
let itemMatch;
|
|
201
|
+
while ((itemMatch = itemRegex.exec(listContent)) !== null) {
|
|
202
|
+
result.push(itemMatch[1]);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return result;
|
|
206
|
+
}
|
|
207
|
+
extractYamlSection(content, sectionName) {
|
|
208
|
+
const sectionRegex = new RegExp(`^${sectionName}:([\\s\\S]*?)(?=^[a-z]|$)`, 'm');
|
|
209
|
+
const match = content.match(sectionRegex);
|
|
210
|
+
return match ? match[1] : null;
|
|
211
|
+
}
|
|
212
|
+
async fileExists(filePath) {
|
|
213
|
+
try {
|
|
214
|
+
await stat(filePath);
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Convenience function for quick Go standards parsing
|
|
224
|
+
*/
|
|
225
|
+
export async function parseGoStandards(projectPath, configFiles, options) {
|
|
226
|
+
const parser = new GoStandardsParser(options);
|
|
227
|
+
return parser.parse(projectPath, configFiles);
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=go-standards-parser.js.map
|