diff --git a/docs/codacy-rules-ai.yaml b/docs/codacy-rules-ai.yaml
index cccebf7..d58dc0b 100644
--- a/docs/codacy-rules-ai.yaml
+++ b/docs/codacy-rules-ai.yaml
@@ -12,7 +12,7 @@ rules:
$CLIENT.GenerateContentAsync(model: "$MODEL", ...)
- metavariable-regex:
metavariable: $MODEL
- regex: ""
+ regex:
metadata:
category: security
subcategory: ai
@@ -20,5 +20,5 @@ rules:
technology:
- csharp
impact: MEDIUM
- confidence: MEDIUM
+ confidence: LOW
likelihood: MEDIUM
\ No newline at end of file
diff --git a/docs/codacy-rules-i18n.yaml b/docs/codacy-rules-i18n.yaml
index 60d30d6..cba4477 100644
--- a/docs/codacy-rules-i18n.yaml
+++ b/docs/codacy-rules-i18n.yaml
@@ -38,6 +38,90 @@ rules:
technology:
- java
impact: MEDIUM
- confidence: HIGH
+ confidence: LOW
likelihood: HIGH
+
+ - id: codacy.js.i18n.no-hardcoded-alert-concat
+ severity: WARNING
+ languages:
+ - js
+ - ts
+ pattern-either:
+ # Direct hardcoded alert strings
+ - pattern: alert("...")
+ - pattern: window.alert("...")
+ # String concatenation in alerts
+ - pattern: alert("..." + ...)
+ - pattern: alert(... + "...")
+ - pattern: window.alert("..." + ...)
+ - pattern: window.alert(... + "...")
+ pattern-not: alert(t(...))
+ message: >-
+ Avoid hardcoded or concatenated strings in alerts. Use an i18n translation function (e.g., t("key")) with interpolation.
+ metadata:
+ category: codestyle
+ subcategory: i18n
+ description: Flags hardcoded and concatenated strings in alert dialogs to enforce localization
+ technology:
+ - javascript
+ - typescript
+ impact: MEDIUM
+ confidence: LOW
+ likelihood: HIGH
+
+ - id: codacy.js.i18n.no-hardcoded-locale-date
+ severity: WARNING
+ languages:
+ - js
+ - ts
+ pattern-regex: "\\.(toLocale(Date|Time)?String)\\(\"[^\"]+\""
+ message: Avoid hardcoded locale strings in date/time formatting.
+ metadata:
+ category: codestyle
+ subcategory: i18n
+ description: Flags explicit locale strings in date/time formatting which can break localization
+ technology:
+ - javascript
+ - typescript
+ impact: MEDIUM
+ confidence: LOW
+ likelihood: HIGH
+
+ - id: codacy.js.i18n.no-hardcoded-number-format
+ severity: WARNING
+ languages:
+ - js
+ - ts
+ pattern-regex: "\\.toFixed\\([^)]*\\)"
+ message: >-
+ Avoid using toFixed for user-visible number formatting. Use locale-aware formatting or translation helpers.
+ metadata:
+ category: codestyle
+ subcategory: i18n
+ description: Flags toFixed used for UI number formatting; recommends locale-aware alternatives
+ technology:
+ - javascript
+ - typescript
+ impact: MEDIUM
+ confidence: LOW
+ likelihood: HIGH
+
+ - id: codacy.js.i18n.no-raw-jsx-text
+ severity: WARNING
+ languages:
+ - js
+ - ts
+ pattern-regex: "<(h1|h2|h3|h4|h5|h6|p|span|div|td|th)[^>]*>[^<{]*[A-Za-z][^<{]*\\1>"
+ message: >-
+ Avoid raw text in JSX for user-facing content. Use i18n translation functions (e.g., t("key")) with interpolation.
+ metadata:
+ category: codestyle
+ subcategory: i18n
+ description: Flags raw text nodes in JSX elements to enforce localization of UI strings
+ technology:
+ - javascript
+ - typescript
+ impact: MEDIUM
+ confidence: LOW
+ likelihood: MEDIUM
\ No newline at end of file
diff --git a/docs/multiple-tests/ai/patterns.xml b/docs/multiple-tests/ai/patterns.xml
index 6821449..e87962a 100644
--- a/docs/multiple-tests/ai/patterns.xml
+++ b/docs/multiple-tests/ai/patterns.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/docs/multiple-tests/ai/results.xml b/docs/multiple-tests/ai/results.xml
index bd884b1..cf09e18 100644
--- a/docs/multiple-tests/ai/results.xml
+++ b/docs/multiple-tests/ai/results.xml
@@ -2,7 +2,7 @@
diff --git a/docs/multiple-tests/ai/src/cs/GeminiExample.cs b/docs/multiple-tests/ai/src/cs/GeminiExample.cs
index e6324f3..b487990 100644
--- a/docs/multiple-tests/ai/src/cs/GeminiExample.cs
+++ b/docs/multiple-tests/ai/src/cs/GeminiExample.cs
@@ -7,6 +7,9 @@ public static async Task main() {
// The client gets the API key from the environment variable `GEMINI_API_KEY`.
var client = new Client();
var response = await client.Models.GenerateContentAsync(
+ model: "deepseek-v3.2", contents: "Explain how AI works in a few words"
+ );
+ var response2 = await client.Models.GenerateContentAsync(
model: "gemini-2.5-flash", contents: "Explain how AI works in a few words"
);
Console.WriteLine(response.Candidates[0].Content.Parts[0].Text);
diff --git a/docs/multiple-tests/i18n/patterns.xml b/docs/multiple-tests/i18n/patterns.xml
index 3b9847d..823ff8c 100644
--- a/docs/multiple-tests/i18n/patterns.xml
+++ b/docs/multiple-tests/i18n/patterns.xml
@@ -1,4 +1,7 @@
+
+
+
\ No newline at end of file
diff --git a/docs/multiple-tests/i18n/results.xml b/docs/multiple-tests/i18n/results.xml
index 800463d..a1bdcb0 100644
--- a/docs/multiple-tests/i18n/results.xml
+++ b/docs/multiple-tests/i18n/results.xml
@@ -29,5 +29,21 @@
message="Use localized messages instead of hardcoded strings."
severity="warning" />
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/internal/tool/configuration.go b/internal/tool/configuration.go
index 2730760..8bb2346 100644
--- a/internal/tool/configuration.go
+++ b/internal/tool/configuration.go
@@ -167,9 +167,9 @@ func replaceParameterPlaceholders(line string, pattern *codacy.Pattern) string {
paramName := matches[1]
// Convert UPPER_CASE to camelCase to match parameter name format
formattedParamName := formatParameterName(paramName)
-
// Find the parameter in the pattern
for _, param := range pattern.Parameters {
+
if param.Name == formattedParamName {
// Use Value if set, otherwise use Default
value := param.Value
@@ -177,7 +177,13 @@ func replaceParameterPlaceholders(line string, pattern *codacy.Pattern) string {
value = param.Default
}
if value != nil {
- return fmt.Sprintf("%v", value)
+ valueStr := fmt.Sprintf("%v", value)
+
+ // If parameter name ends with _ALLOW_LIST, convert comma-separated list to regex pattern
+ if strings.HasSuffix(paramName, "_ALLOW_LIST") {
+ return convertListToRegex(valueStr, false)
+ }
+ return valueStr
}
}
}
@@ -189,6 +195,27 @@ func replaceParameterPlaceholders(line string, pattern *codacy.Pattern) string {
return result
}
+// convertListToRegex converts a comma-separated list into a regex alternation pattern
+// Example: "gemini-2.5-flash,gpt-3.5-turbo,old-llama-model" -> "^(gemini-2\\.5-flash|gpt-3\\.5-turbo|old-llama-model)$"
+func convertListToRegex(list string, include bool) string {
+ // Split by comma and trim spaces
+ items := strings.Split(list, ",")
+ for i, item := range items {
+ // Trim whitespace
+ item = strings.TrimSpace(item)
+ // Escape dots for regex
+ item = strings.ReplaceAll(item, ".", "\\.")
+ items[i] = item
+ }
+
+ // Join with pipe separator and wrap in regex anchors
+ if include {
+ return fmt.Sprintf("^(%s)$", strings.Join(items, "|"))
+ }
+
+ return fmt.Sprintf("^(?!(%s)$).*", strings.Join(items, "|"))
+}
+
// formatParameterName converts UPPER_CASE to camelCase
func formatParameterName(name string) string {
parts := strings.Split(strings.ToLower(name), "_")