@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.
- package/bin/cliCI.js +0 -0
- package/build/ai/config.example.json +10 -0
- package/build/ai/ollama-service.js +403 -0
- package/build/ai/prompts/CODE_REVIEW_PROMPT.md +72 -0
- package/build/ai/prompts/PROMPT1.MD +70 -0
- package/build/ai/prompts/PROMPT2.md +159 -0
- package/build/ai/prompts/PROMPT3.md +64 -0
- package/build/ai/prompts/PROMPT4.md +64 -0
- package/build/ai/provider-factory.js +19 -0
- package/build/ai/providers/OllamaProvider.js +106 -0
- package/build/ai/render.js +157 -0
- package/build/ai/run-review.js +50 -0
- package/build/chunk/chunk_Restriction.js +202 -0
- package/build/hooks/Precommit/pre-commit-default.js +158 -140
- package/build/hooks/hook.js +6 -5
- package/build/lib/postinstall.js +6 -10
- package/build/mutation/branchDiff.js +178 -0
- package/build/mutation/fileResolver.js +170 -0
- package/build/mutation/index.js +16 -0
- package/build/mutation/mutatePattern.json +3 -0
- package/build/mutation/mutationCli.js +111 -0
- package/build/mutation/mutationRunner.js +208 -0
- package/build/mutation/reportGenerator.js +72 -0
- package/build/mutation/strykerWrapper.js +180 -0
- package/build/utils/FileAndFolderOperations/filterFiles.js +8 -6
- package/build/utils/FileAndFolderOperations/removeFolder.js +2 -2
- package/build/utils/General/Config.js +25 -0
- package/build/utils/General/SonarQubeUtil.js +1 -1
- package/jest.config.js +1 -1
- package/package.json +4 -1
- package/samples/sample-branch-mode.js +34 -0
- package/samples/sample-cli-entry.js +34 -0
- package/samples/sample-components.js +63 -0
- package/samples/sample-directory-mode.js +30 -0
- package/samples/sample-runner-direct.js +32 -0
- 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";
|