@zohodesk/codestandard-validator 1.1.4 → 1.2.4-exp-2

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 (36) hide show
  1. package/bin/cliCI.js +0 -0
  2. package/build/ai/config.example.json +10 -0
  3. package/build/ai/ollama-service.js +403 -0
  4. package/build/ai/prompts/CODE_REVIEW_PROMPT.md +72 -0
  5. package/build/ai/prompts/PROMPT1.MD +70 -0
  6. package/build/ai/prompts/PROMPT2.md +159 -0
  7. package/build/ai/prompts/PROMPT3.md +64 -0
  8. package/build/ai/prompts/PROMPT4.md +64 -0
  9. package/build/ai/provider-factory.js +19 -0
  10. package/build/ai/providers/OllamaProvider.js +106 -0
  11. package/build/ai/render.js +157 -0
  12. package/build/ai/run-review.js +50 -0
  13. package/build/chunk/chunk_Restriction.js +202 -0
  14. package/build/hooks/Precommit/pre-commit-default.js +158 -140
  15. package/build/hooks/hook.js +6 -5
  16. package/build/lib/postinstall.js +6 -10
  17. package/build/mutation/branchDiff.js +178 -0
  18. package/build/mutation/fileResolver.js +170 -0
  19. package/build/mutation/index.js +16 -0
  20. package/build/mutation/mutatePattern.json +3 -0
  21. package/build/mutation/mutationCli.js +111 -0
  22. package/build/mutation/mutationRunner.js +208 -0
  23. package/build/mutation/reportGenerator.js +72 -0
  24. package/build/mutation/strykerWrapper.js +180 -0
  25. package/build/utils/FileAndFolderOperations/filterFiles.js +8 -6
  26. package/build/utils/FileAndFolderOperations/removeFolder.js +2 -2
  27. package/build/utils/General/Config.js +25 -0
  28. package/build/utils/General/SonarQubeUtil.js +1 -1
  29. package/jest.config.js +1 -1
  30. package/package.json +4 -1
  31. package/samples/sample-branch-mode.js +34 -0
  32. package/samples/sample-cli-entry.js +34 -0
  33. package/samples/sample-components.js +63 -0
  34. package/samples/sample-directory-mode.js +30 -0
  35. package/samples/sample-runner-direct.js +32 -0
  36. package/samples/sample-with-api.js +44 -0
@@ -0,0 +1,159 @@
1
+ # 🧠 How To Use AI Prompt Files for Code Review (Before Commit)
2
+
3
+ This document explains **how every developer should use AI prompt files** to self-review code **before committing changes**.
4
+
5
+ The goal is to:
6
+ - Catch issues early
7
+ - Reduce PR review back-and-forth
8
+ - Maintain consistent standards across the team
9
+
10
+ ---
11
+
12
+ ## šŸ“Œ Which Prompt Should I Use?
13
+
14
+ | Prompt file | When to use | Mandatory |
15
+ |------------|-------------|-----------|
16
+ | AIPrompts/code-review/UATReview.md | Before committing UAT changes | āœ… Yes |
17
+ | AIPrompts/code-review/ComponentHTMLCSSReview.md | HTML / CSS / UI changes | āœ… Yes |
18
+ | AIPrompts/code-review/MergeRequestReview.md | Before raising PR / MR | āœ… Yes |
19
+
20
+ ---
21
+
22
+
23
+ ## šŸ¤– CODEOWNERS-Based Prompt Detection
24
+
25
+ ```text
26
+ Decide which review prompt(s) must be used based on file changes.
27
+
28
+ Reference:
29
+ resources/code_owners/code_owners.yaml
30
+
31
+ Input:
32
+ - Uncommitted git diff or attached .diff file
33
+
34
+ Rules:
35
+
36
+ 1. If a **Design** change is detected
37
+ (HTML / CSS / SCSS / UI files),
38
+ - Use the rules from: AIPrompts/code-review/ComponentHTMLCSSReview.md
39
+
40
+ 2. If **UAT_StepDefinitions** or **UAT_Features** changes are detected,
41
+ - Use the rules from: AIPrompts/code-review/UATReview.md
42
+
43
+ 3. For all other changes,
44
+ decide the required prompt(s) using code_owners.yaml.
45
+ First check for any attached .diff file; otherwise, use uncommitted changes.
46
+
47
+ 4. If multiple types of files are changed,
48
+ run multiple prompts.
49
+
50
+ Output:
51
+ - List the required prompt file(s)
52
+ - Short reason for each
53
+ ```
54
+
55
+ ---
56
+
57
+
58
+ ## Review Before Commit
59
+
60
+ This ensures:
61
+ - Code follows agreed standards
62
+ - Naming and structure are correct
63
+ - CSS / HTML rules are respected
64
+ - Obvious bugs are caught early
65
+
66
+ ---
67
+
68
+ ### Step 1: Open GitHub Copilot Chat
69
+
70
+ In VS Code:
71
+ - **Mac:** `Cmd + Shift + I`
72
+ - **Windows/Linux:** `Ctrl + Shift + I`
73
+
74
+ ---
75
+
76
+ ### Step 3:
77
+ ## For UAT Review
78
+
79
+ ```text
80
+ Use the rules from:
81
+ AIPrompts/code-review/UATReview.md
82
+
83
+ Review the following uncommitted git diff.
84
+ Identify violations with file and line number.
85
+ Suggest fixes.
86
+
87
+ Here is the git diff:
88
+ Take the attached diff file or review the uncommitted changes.
89
+
90
+ Output:
91
+ - The reviewed report must be readable and neatly aligned.
92
+ - Push the detailed review output as a separate HTML file under:
93
+ AIPrompts/outputs/UATReview.md.html
94
+ ```
95
+
96
+ ---
97
+
98
+ ## šŸŽØ For HTML / CSS / UI Changes
99
+
100
+ ```text
101
+ Use the rules from:
102
+ AIPrompts/code-review/ComponentHTMLCSSReview.md
103
+
104
+ Review the following uncommitted git diff.
105
+ Focus on class naming, CSS rules, and structure.
106
+
107
+ Here is the git diff:
108
+ First check for any attached .diff file; otherwise, use uncommitted changes.
109
+
110
+ Output:
111
+ - The reviewed report must be readable and neatly aligned.
112
+ - Push the detailed review output as a separate HTML file under:
113
+ AIPrompts/outputs/ComponentHTMLCSSReview.md.html
114
+ ```
115
+
116
+ ---
117
+
118
+ ## šŸ” Before Creating PR / MR ( Merge request review)
119
+
120
+ ```text
121
+ Use the rules from:
122
+ AIPrompts/code-review/MergeRequestReview.md
123
+
124
+ Review the overall changes and provide PR-level feedback.
125
+
126
+ Here is the git diff:
127
+ Use the attached MR .diff file. If none is attached, ignore this step.
128
+
129
+ Output:
130
+ - The reviewed report must be readable and neatly aligned.
131
+ - Push the detailed review output as a separate HTML file under:
132
+ AIPrompts/outputs/MergeRequestReview.md.html
133
+ ```
134
+
135
+ ---
136
+
137
+ ### Step 3: Fix Issues
138
+
139
+ - Fix all reported issues
140
+ - Re-run `git diff`
141
+ - Re-run the review if needed
142
+
143
+ ---
144
+
145
+ ## šŸ“Œ Important Guidelines
146
+
147
+ - When modifying prompt files, please post in the team channel or have a discussion. The DRI must review the changes.
148
+ - Prompt files are the single source of truth.
149
+
150
+ ---
151
+
152
+ ## šŸŽÆ Why We Do This
153
+
154
+ - Right prompt for the right change
155
+ - Less reviewer confusion
156
+ - Faster approvals
157
+ - Shared responsibility
158
+
159
+ This is **self-verification**, designed to help everyone write better code with less friction.
@@ -0,0 +1,64 @@
1
+ # Code Review Prompt for HelpCentre Client Merge Requests
2
+
3
+ ## Overview
4
+
5
+ This document acts as the **main entry point** for reviewing Merge Requests (MRs).
6
+ It defines the mandatory pre-review checks and links to **separate, focused review documents** that should be used based on the scope of changes.
7
+
8
+ Use only the required review files depending on what the MR contains.
9
+
10
+ ---
11
+
12
+ ## Pre-Review Checklist
13
+
14
+ Before reviewing the code, confirm the following:
15
+
16
+ - MR description clearly explains the purpose and scope of changes
17
+ - Related ticket or issue is linked
18
+ - MR targets the correct branch
19
+ - No merge conflicts are present
20
+ - UAT report is attached
21
+ - If UAT is not required, the reason must be clearly explained
22
+
23
+ ---
24
+
25
+ ## Review Scope Selection
26
+
27
+ ### Components & CSS Files Review Checklist
28
+
29
+ Use this checklist **only when the MR includes**:
30
+
31
+ - React components
32
+ - HTML / JSX changes
33
+ - CSS / CSS Modules updates
34
+
35
+ āž”ļø Refer to:
36
+ **[`ComponentHTMLCSSReview.md`](./ComponentHTMLCSSReview.md)**
37
+
38
+ Review all component structure, accessibility, styling, naming conventions, and CSS rules using that file.
39
+
40
+ ---
41
+
42
+ ### UAT Files Review Checklist
43
+
44
+ Use this checklist **only when the MR includes**:
45
+
46
+ - UAT automation changes
47
+ - Feature files (`.feature`)
48
+ - Spec files (`.spec.js`)
49
+ - Page Object Models (POM)
50
+ - Assertions, selectors, or test configurations
51
+
52
+ āž”ļø Refer to:
53
+ **[`UATReview.md`](./UATReview.md)**
54
+
55
+ Review UAT folder structure, Playwright usage, locator strategy, i18n enforcement, assertions, and configuration standards using this document.
56
+
57
+ ---
58
+
59
+ ## Notes
60
+
61
+ - Do not run all review documents blindly
62
+ - Select the review file based on the **actual changes in the MR**
63
+ - If an MR includes **both UI and UAT changes**, review using **both documents**
64
+ - Any deviation from standards must be clearly documented in the MR
@@ -0,0 +1,64 @@
1
+ # Code Review Prompt for HelpCentre Client Merge Requests
2
+
3
+ ## Overview
4
+
5
+ This document acts as the **main entry point** for reviewing Merge Requests (MRs).
6
+ It defines the mandatory pre-review checks and links to **separate, focused review documents** that should be used based on the scope of changes.
7
+
8
+ Use only the required review files depending on what the MR contains.
9
+
10
+ ---
11
+
12
+ ## Pre-Review Checklist
13
+
14
+ Before reviewing the code, confirm the following:
15
+
16
+ - MR description clearly explains the purpose and scope of changes
17
+ - Related ticket or issue is linked
18
+ - MR targets the correct branch
19
+ - No merge conflicts are present
20
+ - UAT report is attached
21
+ - If UAT is not required, the reason must be clearly explained
22
+
23
+ ---
24
+
25
+ ## Review Scope Selection
26
+
27
+ ### Components & CSS Files Review Checklist
28
+
29
+ Use this checklist **only when the MR includes**:
30
+
31
+ - React components
32
+ - HTML / JSX changes
33
+ - CSS / CSS Modules updates
34
+
35
+ āž”ļø Refer to:
36
+ **[`ComponentHTMLCSSReview.md`](./ComponentHTMLCSSReview.md)**
37
+
38
+ Review all component structure, accessibility, styling, naming conventions, and CSS rules using that file.
39
+
40
+ ---
41
+
42
+ ### UAT Files Review Checklist
43
+
44
+ Use this checklist **only when the MR includes**:
45
+
46
+ - UAT automation changes
47
+ - Feature files (`.feature`)
48
+ - Spec files (`.spec.js`)
49
+ - Page Object Models (POM)
50
+ - Assertions, selectors, or test configurations
51
+
52
+ āž”ļø Refer to:
53
+ **[`UATReview.md`](./UATReview.md)**
54
+
55
+ Review UAT folder structure, Playwright usage, locator strategy, i18n enforcement, assertions, and configuration standards using this document.
56
+
57
+ ---
58
+
59
+ ## Notes
60
+
61
+ - Do not run all review documents blindly
62
+ - Select the review file based on the **actual changes in the MR**
63
+ - If an MR includes **both UI and UAT changes**, review using **both documents**
64
+ - Any deviation from standards must be clearly documented in the MR
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ const {
4
+ OllamaProvider
5
+ } = require('./providers/OllamaProvider');
6
+ function createProvider(config) {
7
+ const providerName = (config.provider || 'ollama').toLowerCase();
8
+ switch (providerName) {
9
+ case 'ollama':
10
+ return new OllamaProvider(config);
11
+ // case 'openai': return new OpenAIProvider(config);
12
+ // case 'anthropic': return new AnthropicProvider(config);
13
+ default:
14
+ throw new Error(`Unsupported provider: ${providerName}`);
15
+ }
16
+ }
17
+ module.exports = {
18
+ createProvider
19
+ };
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+
3
+ class AIProvider {
4
+ constructor(config = {}) {
5
+ this.config = config;
6
+ }
7
+ supportsStreaming() {
8
+ return false;
9
+ }
10
+ async generate(request) {
11
+ // request: { prompt, fileName?, onToken? }
12
+ throw new Error('Not implemented');
13
+ }
14
+ }
15
+ class OllamaProvider extends AIProvider {
16
+ constructor(config) {
17
+ super(config);
18
+ }
19
+ supportsStreaming() {
20
+ return !!this.config.stream;
21
+ }
22
+ async generate({
23
+ prompt,
24
+ fileName,
25
+ onToken
26
+ }) {
27
+ const url = `${this.config.baseUrl}${this.config.endpoint}`;
28
+ const body = {
29
+ model: this.config.model,
30
+ prompt,
31
+ stream: !!this.config.stream,
32
+ raw: this.config.model === 'deepseek-r1',
33
+ format: 'json',
34
+ options: {
35
+ temperature: this.config.temperature,
36
+ num_predict: this.config.maxTokens
37
+ }
38
+ };
39
+ const controller = new AbortController();
40
+ const timeout = setTimeout(() => controller.abort(), this.config.timeoutMs);
41
+ try {
42
+ const response = await fetch(url, {
43
+ method: 'POST',
44
+ headers: {
45
+ 'Content-Type': 'application/json'
46
+ },
47
+ body: JSON.stringify(body),
48
+ signal: controller.signal
49
+ });
50
+ clearTimeout(timeout);
51
+ if (!response.ok) {
52
+ throw new Error(`Ollama request failed: ${response.status} ${response.statusText}`);
53
+ }
54
+ if (this.supportsStreaming()) {
55
+ const reader = response.body.getReader();
56
+ const decoder = new TextDecoder('utf-8');
57
+ let fullText = '';
58
+ let isDone = false;
59
+ while (!isDone) {
60
+ const {
61
+ value,
62
+ done
63
+ } = await reader.read();
64
+ if (done) break;
65
+ const chunk = decoder.decode(value, {
66
+ stream: true
67
+ });
68
+ for (const line of chunk.split('\n')) {
69
+ const trimmed = line.trim();
70
+ if (!trimmed) continue;
71
+ try {
72
+ const obj = JSON.parse(trimmed);
73
+ if (obj.response) {
74
+ fullText += obj.response;
75
+ if (typeof onToken === 'function') onToken(obj.response);
76
+ }
77
+ if (obj.done) {
78
+ isDone = true;
79
+ break;
80
+ }
81
+ } catch {
82
+ // ignore partial lines
83
+ }
84
+ }
85
+ }
86
+ return {
87
+ text: fullText,
88
+ fileName
89
+ };
90
+ } else {
91
+ const data = await response.json();
92
+ const text = typeof data.response === 'string' ? data.response : '';
93
+ return {
94
+ text,
95
+ fileName
96
+ };
97
+ }
98
+ } catch (err) {
99
+ clearTimeout(timeout);
100
+ throw err;
101
+ }
102
+ }
103
+ }
104
+ module.exports = {
105
+ OllamaProvider
106
+ };
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+
3
+ const {
4
+ marked
5
+ } = require('marked');
6
+ const {
7
+ markedTerminal
8
+ } = require('marked-terminal');
9
+ marked.use(markedTerminal({
10
+ reflowText: true,
11
+ width: 80,
12
+ showSectionPrefix: false
13
+ }));
14
+
15
+ /**
16
+ * Render a markdown string to styled terminal output.
17
+ * @param {string} md - Markdown text
18
+ */
19
+ function renderMarkdown(md) {
20
+ if (!md || typeof md !== 'string') return '';
21
+ return marked.parse(md);
22
+ }
23
+
24
+ /**
25
+ * Print rendered markdown to stdout.
26
+ * @param {string} md
27
+ */
28
+ function printMarkdown(md) {
29
+ process.stdout.write(renderMarkdown(md));
30
+ }
31
+
32
+ /**
33
+ * Format a review result object as readable markdown.
34
+ * @param {Object} result
35
+ * @param {string} [fileName]
36
+ * @returns {string}
37
+ */
38
+ function formatReviewResult(result, fileName) {
39
+ if (!result) return '';
40
+ const lines = [];
41
+ if (fileName) {
42
+ lines.push(`## šŸ“„ Review: \`${fileName}\``);
43
+ }
44
+ if (result.rawResponse) {
45
+ lines.push('\n> āš ļø Could not parse structured JSON. Raw response below:\n');
46
+ // Wrap raw summary in a fenced code block if it looks like code,
47
+ // otherwise render as-is (it may already be markdown)
48
+ const summary = result.summary || '(empty)';
49
+ if (summary.includes('function ') || summary.includes('const ') || summary.includes('import ')) {
50
+ lines.push('```');
51
+ lines.push(summary);
52
+ lines.push('```');
53
+ } else {
54
+ lines.push(summary);
55
+ }
56
+ return lines.join('\n');
57
+ }
58
+ if (result.overallScore != null) {
59
+ lines.push(`### Overall Score: **${result.overallScore} / 50**\n`);
60
+ }
61
+ if (result.categories) {
62
+ lines.push('### Categories\n');
63
+ lines.push('| Category | Score |');
64
+ lines.push('|----------|-------|');
65
+ for (const [key, val] of Object.entries(result.categories)) {
66
+ const label = key.replace(/([A-Z])/g, ' $1').replace(/^./, s => s.toUpperCase());
67
+ lines.push(`| ${label} | ${val.score ?? '-'} / 10 |`);
68
+ }
69
+ lines.push('');
70
+ for (const [key, val] of Object.entries(result.categories)) {
71
+ if (val.issues && val.issues.length > 0) {
72
+ const label = key.replace(/([A-Z])/g, ' $1').replace(/^./, s => s.toUpperCase());
73
+ lines.push(`#### ${label} Issues\n`);
74
+ val.issues.forEach(issue => lines.push(`- ${issue}`));
75
+ lines.push('');
76
+ }
77
+ }
78
+ }
79
+ if (result.criticalIssues && result.criticalIssues.length > 0) {
80
+ lines.push('### 🚨 Critical Issues\n');
81
+ result.criticalIssues.forEach(issue => lines.push(`- ${issue}`));
82
+ lines.push('');
83
+ }
84
+ if (result.suggestions && result.suggestions.length > 0) {
85
+ lines.push('### šŸ’” Suggestions\n');
86
+ result.suggestions.forEach(s => lines.push(`- ${s}`));
87
+ lines.push('');
88
+ }
89
+ if (result.summary) {
90
+ lines.push(`### Summary\n\n${result.summary}\n`);
91
+ }
92
+ return lines.join('\n');
93
+ }
94
+
95
+ /**
96
+ * A streaming renderer that buffers tokens and renders complete markdown blocks.
97
+ * Usage:
98
+ * const sr = new StreamRenderer();
99
+ * onToken: token => sr.write(token);
100
+ * // after streaming ends:
101
+ * sr.flush();
102
+ */
103
+ class StreamRenderer {
104
+ constructor() {
105
+ this._buffer = '';
106
+ this._rendered = '';
107
+ }
108
+
109
+ /**
110
+ * Feed a token chunk. Renders complete paragraphs/lines as they arrive.
111
+ * @param {string} token
112
+ */
113
+ write(token) {
114
+ this._buffer += token;
115
+
116
+ // Render when we have at least one complete line (ends with \n)
117
+ const lastNewline = this._buffer.lastIndexOf('\n');
118
+ if (lastNewline !== -1) {
119
+ const ready = this._buffer.slice(0, lastNewline + 1);
120
+ this._rendered += ready;
121
+ this._buffer = this._buffer.slice(lastNewline + 1);
122
+
123
+ // Clear previous output area and re-render accumulated markdown
124
+ // For simplicity, render only the new complete lines
125
+ const output = renderMarkdown(ready);
126
+ process.stdout.write(output);
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Flush remaining buffer and render final output.
132
+ * @returns {string} The full raw text that was streamed
133
+ */
134
+ flush() {
135
+ if (this._buffer.length > 0) {
136
+ this._rendered += this._buffer;
137
+ const output = renderMarkdown(this._buffer);
138
+ process.stdout.write(output);
139
+ this._buffer = '';
140
+ }
141
+ return this._rendered;
142
+ }
143
+
144
+ /**
145
+ * Get the full raw accumulated text.
146
+ * @returns {string}
147
+ */
148
+ getRawText() {
149
+ return this._rendered + this._buffer;
150
+ }
151
+ }
152
+ module.exports = {
153
+ renderMarkdown,
154
+ printMarkdown,
155
+ formatReviewResult,
156
+ StreamRenderer
157
+ };
@@ -0,0 +1,50 @@
1
+ // const path = require('path');
2
+ // const { reviewFile, reviewFiles, reviewFolder } = require('./ollama-service');
3
+ // const { printMarkdown, formatReviewResult, StreamRenderer } = require('./render');
4
+
5
+ // const CONFIG = {
6
+ // provider: 'ollama',
7
+ // model: 'deepseek-r1:8b',
8
+ // temperature: 0.2,
9
+ // maxTokens: 4096,
10
+ // timeoutMs: 120000,
11
+ // stream: true
12
+ // };
13
+
14
+ // const PROMPT_FOLDER = path.resolve(__dirname, 'prompts');
15
+
16
+ // const REVIEW_FOLDER = '/Users/raja-17710/deskApp/linter_tools/codestandard-validator/src/mutation';
17
+
18
+ // const FOLDER_EXTENSIONS = ['.js', '.ts'];
19
+
20
+ // async function runAll() {
21
+
22
+ // printMarkdown('\n---\n\n## Folder Review\n');
23
+ // try {
24
+ // const results = await reviewFolder(REVIEW_FOLDER, {
25
+ // config: CONFIG,
26
+ // promptFolder: PROMPT_FOLDER,
27
+ // extensions: FOLDER_EXTENSIONS,
28
+ // concurrency: 1,
29
+ // streamToConsole: true,
30
+ // onResult: out => {
31
+ // // Render each completed file review as formatted markdown
32
+ // printMarkdown('\n' + formatReviewResult(out, out.fileName) + '\n');
33
+ // }
34
+ // });
35
+ // printMarkdown('\n---\n\n### Final Summary\n');
36
+ // printMarkdown(`Reviewed **${results.length}** file(s).\n`);
37
+ // } catch (err) {
38
+ // printMarkdown(`\n> āŒ **reviewFolder error:** ${err.message}\n`);
39
+ // }
40
+ // }
41
+
42
+ // runAll()
43
+ // .then(() => {
44
+ // printMarkdown('\n---\n\nāœ… **Done.**\n');
45
+ // })
46
+ // .catch(err => {
47
+ // printMarkdown(`\n> āŒ **Fatal error:** ${err.message}\n`);
48
+ // process.exit(1);
49
+ // });
50
+ "use strict";