sudeshi-code-review 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # Sudeshi Code Review
2
2
 
3
- A TypeScript and React code-review CLI that scans JavaScript and TypeScript repositories for selected security patterns and produces a Markdown report. Optional AI-assisted analysis is powered by Sarvam AI.
3
+ A TypeScript and React code-review CLI that scans JavaScript and TypeScript repositories for selected security patterns and produces Markdown or JSON reports. Optional AI-assisted analysis is powered by Sarvam AI.
4
4
 
5
5
  ## Features
6
6
 
7
- - Scans JavaScript and TypeScript repositories.
7
+ - Scans JavaScript and TypeScript repositories, including JSX and TSX source files.
8
8
  - Detects selected dangerous HTML insertion patterns, hardcoded secrets, and JavaScript URLs in JSX links.
9
- - Reports findings with severity and evidence in Markdown.
9
+ - Reports findings with severity and evidence in Markdown or JSON, with support for saving reports to a file.
10
10
  - Works without an AI API key using deterministic rules.
11
11
  - Supports optional Sarvam AI analysis using your own API key.
12
12
  - Includes automated tests for scanning, rules, reporting, and AI-provider behavior.
@@ -50,7 +50,51 @@ Show the installed version:
50
50
  sudeshi-code-review --version
51
51
  ```
52
52
 
53
- Provide a repository directory when running a scan. Review the report and validate findings before acting on them.
53
+ ### Choose a report format and destination
54
+
55
+ Interactive terminals display a formatted terminal summary by default. When output is redirected or the process is non-interactive, the default report is Markdown.
56
+
57
+ Generate machine-readable JSON:
58
+
59
+ ```bash
60
+ sudeshi-code-review /path/to/repository --format json
61
+ ```
62
+
63
+ Save a Markdown report:
64
+
65
+ ```bash
66
+ sudeshi-code-review /path/to/repository --output report.md
67
+ ```
68
+
69
+ Save a JSON report:
70
+
71
+ ```bash
72
+ sudeshi-code-review /path/to/repository --format json --output report.json
73
+ ```
74
+
75
+ The repository path comes first; place options after it. Use `--help` for the complete list of options and examples.
76
+
77
+ Review findings and validate them before acting on them.
78
+
79
+ ### Terminal output
80
+
81
+ Interactive terminals display a formatted summary with severity-colored findings and confidence details. Color output is automatically disabled when stdout is not an interactive terminal or when the `NO_COLOR` environment variable is set. JSON selected with `--format json` remains machine-readable and contains no terminal styling.
82
+
83
+ Disable terminal colors explicitly:
84
+
85
+ **Git Bash**
86
+
87
+ ```bash
88
+ export NO_COLOR=1
89
+ sudeshi-code-review /path/to/repository
90
+ ```
91
+
92
+ **PowerShell**
93
+
94
+ ```powershell
95
+ $env:NO_COLOR = "1"
96
+ sudeshi-code-review "C:\path\to\repository"
97
+ ```
54
98
 
55
99
  ## Optional AI-assisted review
56
100
 
@@ -82,7 +126,15 @@ When AI review is enabled, selected source context is sent to Sarvam AI for anal
82
126
  | `hardcoded-secret` | Detects selected hardcoded credential patterns. |
83
127
  | `unsafe-link` | Detects JavaScript URLs in JSX link targets. |
84
128
 
85
- These rules cover selected patterns, not every possible instance of these issues.
129
+ These rules cover selected patterns, not every possible instance of these issues. Repository scanning supports `.js`, `.jsx`, `.ts`, and `.tsx` source files.
130
+
131
+ ### Detection scope and interpretation
132
+
133
+ - **`dangerous-html`:** Flags selected uses of `dangerouslySetInnerHTML`. The rule detects the HTML-insertion sink; it does not establish that the supplied value is attacker-controlled or prove that an exploitable XSS vulnerability exists. A narrowly scoped static JSON-LD case is exempted by the rule.
134
+ - **`hardcoded-secret`:** Detects non-empty static strings and static template literals assigned to supported secret-like variable names or object-property keys, including quoted and statically computed property keys. Database URL values are flagged when they contain embedded username and password credentials. Detected secret literals are redacted from finding evidence, but arbitrary secret formats and dynamically constructed values are outside the rule's coverage.
135
+ - **`unsafe-link`:** Detects statically identifiable `javascript:` URLs in JSX `href` attributes, including direct string expressions, static template expressions, and supported locally resolvable variable values. It does not perform comprehensive data-flow analysis of dynamic values.
136
+
137
+ Finding severity describes the potential impact of a matched pattern. Rule confidence describes confidence in the pattern match; neither value proves exploitability or attacker control. Review the source context before treating a finding as a confirmed vulnerability.
86
138
 
87
139
  ## Limitations and responsible use
88
140
 
@@ -93,7 +145,7 @@ Sudeshi Code Review is a focused static-analysis tool—not a complete security
93
145
  - Detection is limited to the currently implemented JavaScript and TypeScript rules.
94
146
  - A clean report does not establish that a repository is secure.
95
147
  - AI assessments can be inaccurate and require human review.
96
- - Source-context redaction before AI analysis has limitations, particularly with interpolated template literals. Do not assume all sensitive source content will be removed before it is sent to an AI provider.
148
+ - AI-context redaction is best-effort. It attempts to redact recognized secret values in supported code patterns and selected repeated occurrences, but cannot guarantee that every secret will be detected or removed. Dynamically constructed values and syntax the implementation does not recognize may still be sent to the configured AI provider.
97
149
  - Review the privacy implications before enabling AI review on private or sensitive repositories.
98
150
 
99
151
  ## Development
@@ -0,0 +1,9 @@
1
+ import ts from 'typescript';
2
+ /**
3
+ * Create an AST using the language variant appropriate for the input file.
4
+ *
5
+ * JavaScript files use JSX parsing so React code that keeps JSX in `.js` files
6
+ * is analyzed as well. TypeScript's JSX variant is reserved for `.tsx`.
7
+ */
8
+ export declare function createSourceFile(filePath: string, content: string): ts.SourceFile;
9
+ //# sourceMappingURL=createSourceFile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createSourceFile.d.ts","sourceRoot":"","sources":["../../src/analyzer/createSourceFile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,EAAE,CAAC,UAAU,CAiBf"}
@@ -0,0 +1,17 @@
1
+ import ts from 'typescript';
2
+ /**
3
+ * Create an AST using the language variant appropriate for the input file.
4
+ *
5
+ * JavaScript files use JSX parsing so React code that keeps JSX in `.js` files
6
+ * is analyzed as well. TypeScript's JSX variant is reserved for `.tsx`.
7
+ */
8
+ export function createSourceFile(filePath, content) {
9
+ const extension = filePath.slice(filePath.lastIndexOf('.')).toLowerCase();
10
+ const scriptKind = extension === '.tsx'
11
+ ? ts.ScriptKind.TSX
12
+ : extension === '.jsx' || extension === '.js'
13
+ ? ts.ScriptKind.JSX
14
+ : ts.ScriptKind.TS;
15
+ return ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true, scriptKind);
16
+ }
17
+ //# sourceMappingURL=createSourceFile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createSourceFile.js","sourceRoot":"","sources":["../../src/analyzer/createSourceFile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAAgB,EAChB,OAAe;IAEf,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAE1E,MAAM,UAAU,GACd,SAAS,KAAK,MAAM;QAClB,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG;QACnB,CAAC,CAAC,SAAS,KAAK,MAAM,IAAI,SAAS,KAAK,KAAK;YAC3C,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG;YACnB,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;IAEzB,OAAO,EAAE,CAAC,gBAAgB,CACxB,QAAQ,EACR,OAAO,EACP,EAAE,CAAC,YAAY,CAAC,MAAM,EACtB,IAAI,EACJ,UAAU,CACX,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"dangerousHtml.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/dangerousHtml.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,eAAO,MAAM,iBAAiB,EAAE,IAqM/B,CAAC"}
1
+ {"version":3,"file":"dangerousHtml.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/dangerousHtml.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGvC,eAAO,MAAM,iBAAiB,EAAE,IA+L/B,CAAC"}
@@ -1,8 +1,9 @@
1
1
  import ts from 'typescript';
2
+ import { createSourceFile } from '../createSourceFile.js';
2
3
  export const dangerousHtmlRule = (file) => {
3
4
  const lines = file.content.split('\n');
4
5
  const findings = [];
5
- const sourceFile = ts.createSourceFile(file.path, file.content, ts.ScriptTarget.Latest, true, file.path.endsWith('.tsx') ? ts.ScriptKind.TSX : ts.ScriptKind.TS);
6
+ const sourceFile = createSourceFile(file.path, file.content);
6
7
  function findDeclarationInScope(node, name) {
7
8
  let current = node.parent;
8
9
  while (current) {
@@ -1 +1 @@
1
- {"version":3,"file":"dangerousHtml.js","sourceRoot":"","sources":["../../../src/analyzer/rules/dangerousHtml.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dangerousHtml.js","sourceRoot":"","sources":["../../../src/analyzer/rules/dangerousHtml.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"hardcodedSecret.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/hardcodedSecret.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AA8BvC,eAAO,MAAM,mBAAmB,EAAE,IA4FjC,CAAC"}
1
+ {"version":3,"file":"hardcodedSecret.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/hardcodedSecret.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAyDvC,eAAO,MAAM,mBAAmB,EAAE,IA2GjC,CAAC"}
@@ -1,75 +1,109 @@
1
1
  import ts from 'typescript';
2
+ import { createSourceFile } from '../createSourceFile.js';
2
3
  const SECRET_NAME_PATTERN = /^(apiKey|api_key|paymentApiKey|accessToken|access_token|internalToken|internal_token|databaseUrl|database_url|password|secret|clientSecret|client_secret|token)$/i;
3
4
  function isStaticSecretString(node) {
4
5
  return ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node);
5
6
  }
6
- function redactSecretEvidence(line, value, literalText) {
7
+ function getStaticPropertyName(name) {
8
+ if (ts.isIdentifier(name) ||
9
+ ts.isStringLiteral(name) ||
10
+ ts.isNoSubstitutionTemplateLiteral(name)) {
11
+ return name.text;
12
+ }
13
+ if (ts.isComputedPropertyName(name) &&
14
+ isStaticSecretString(name.expression)) {
15
+ return name.expression.text;
16
+ }
17
+ return undefined;
18
+ }
19
+ function isCredentialedDatabaseUrl(value) {
20
+ return /^[a-z][a-z0-9+.-]*:\/\/[^/@:]+:[^/@]+@/i.test(value);
21
+ }
22
+ function shouldReportSecret(name, value) {
7
23
  if (!value) {
8
- return line;
24
+ return false;
9
25
  }
10
- if (literalText) {
11
- return line.replace(literalText, literalText[0] + '[REDACTED]' + literalText[0]);
26
+ if (/^(databaseUrl|database_url)$/i.test(name) &&
27
+ !isCredentialedDatabaseUrl(value)) {
28
+ return false;
12
29
  }
13
- return line.replace(value, '[REDACTED]');
30
+ return true;
14
31
  }
15
32
  export const hardcodedSecretRule = (file) => {
16
- const findings = [];
17
- const sourceFile = ts.createSourceFile(file.path, file.content, ts.ScriptTarget.Latest, true, file.path.endsWith('.tsx') ? ts.ScriptKind.TSX : ts.ScriptKind.TS);
33
+ const sourceFile = createSourceFile(file.path, file.content);
34
+ const sourceLines = file.content.split(/\r?\n/);
35
+ const occurrences = [];
36
+ const staticLiterals = [];
37
+ function getLine(node) {
38
+ return sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile))
39
+ .line;
40
+ }
41
+ function addOccurrence(literal) {
42
+ occurrences.push({ line: getLine(literal), literal });
43
+ }
18
44
  function visit(node) {
45
+ if ((ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) &&
46
+ node.text) {
47
+ staticLiterals.push({ line: getLine(node), literal: node });
48
+ }
19
49
  if (ts.isVariableDeclaration(node) &&
20
50
  ts.isIdentifier(node.name) &&
21
51
  SECRET_NAME_PATTERN.test(node.name.text) &&
22
52
  node.initializer &&
23
- isStaticSecretString(node.initializer)) {
24
- const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
25
- const value = node.initializer.text;
26
- if (value) {
27
- findings.push({
28
- id: 'hardcoded-secret',
29
- category: 'security',
30
- severity: 'high',
31
- confidence: 1,
32
- file: file.path,
33
- line: line + 1,
34
- rule: 'hardcoded-secret',
35
- message: 'A hardcoded secret may be present',
36
- evidence: redactSecretEvidence(file.content.split('\n')[line]?.trim() ?? '', value, node.initializer.getText(sourceFile)),
37
- requiresAIReview: true,
38
- });
39
- }
53
+ isStaticSecretString(node.initializer) &&
54
+ shouldReportSecret(node.name.text, node.initializer.text)) {
55
+ addOccurrence(node.initializer);
40
56
  }
41
- if (ts.isPropertyAssignment(node) &&
42
- ts.isIdentifier(node.name) &&
43
- SECRET_NAME_PATTERN.test(node.name.text) &&
44
- isStaticSecretString(node.initializer)) {
45
- const propertyName = node.name.text;
46
- const value = node.initializer.text;
47
- if (!value) {
48
- ts.forEachChild(node, visit);
49
- return;
50
- }
51
- if (/^(databaseUrl|database_url)$/i.test(propertyName) &&
52
- !/^[a-z][a-z0-9+.-]*:\/\/[^/@:]+:[^/@]+@/i.test(value)) {
53
- ts.forEachChild(node, visit);
54
- return;
57
+ if (ts.isPropertyAssignment(node)) {
58
+ const propertyName = getStaticPropertyName(node.name);
59
+ if (propertyName &&
60
+ SECRET_NAME_PATTERN.test(propertyName) &&
61
+ isStaticSecretString(node.initializer) &&
62
+ shouldReportSecret(propertyName, node.initializer.text)) {
63
+ addOccurrence(node.initializer);
55
64
  }
56
- const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
57
- findings.push({
58
- id: 'hardcoded-secret',
59
- category: 'security',
60
- severity: 'high',
61
- confidence: 1,
62
- file: file.path,
63
- line: line + 1,
64
- rule: 'hardcoded-secret',
65
- message: 'A hardcoded secret may be present',
66
- evidence: redactSecretEvidence(file.content.split('\n')[line]?.trim() ?? '', value, node.initializer.getText(sourceFile)),
67
- requiresAIReview: true,
68
- });
69
65
  }
70
66
  ts.forEachChild(node, visit);
71
67
  }
68
+ function redactEvidence(line) {
69
+ let evidence = sourceLines[line] ?? '';
70
+ const secretValues = new Set(occurrences
71
+ .filter((occurrence) => occurrence.line === line)
72
+ .map(({ literal }) => literal.text));
73
+ const literalsToRedact = staticLiterals
74
+ .filter((occurrence) => occurrence.line === line && secretValues.has(occurrence.literal.text))
75
+ .sort((left, right) => right.literal.getStart(sourceFile) -
76
+ left.literal.getStart(sourceFile));
77
+ const lineStart = sourceFile.getPositionOfLineAndCharacter(line, 0);
78
+ const lineEnd = lineStart + evidence.length;
79
+ for (const { literal } of literalsToRedact) {
80
+ const literalStart = literal.getStart(sourceFile);
81
+ const literalEnd = literal.getEnd();
82
+ const start = Math.max(literalStart, lineStart) - lineStart;
83
+ const end = Math.min(literalEnd, lineEnd) - lineStart;
84
+ if (start >= end) {
85
+ continue;
86
+ }
87
+ const quote = literal.getText(sourceFile)[0] ?? "'";
88
+ evidence =
89
+ evidence.slice(0, start) +
90
+ `${quote}[REDACTED]${quote}` +
91
+ evidence.slice(end);
92
+ }
93
+ return evidence.trim();
94
+ }
72
95
  visit(sourceFile);
73
- return findings;
96
+ return occurrences.map(({ line }) => ({
97
+ id: 'hardcoded-secret',
98
+ category: 'security',
99
+ severity: 'high',
100
+ confidence: 1,
101
+ file: file.path,
102
+ line: line + 1,
103
+ rule: 'hardcoded-secret',
104
+ message: 'A hardcoded secret may be present',
105
+ evidence: redactEvidence(line),
106
+ requiresAIReview: true,
107
+ }));
74
108
  };
75
109
  //# sourceMappingURL=hardcodedSecret.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hardcodedSecret.js","sourceRoot":"","sources":["../../../src/analyzer/rules/hardcodedSecret.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hardcodedSecret.js","sourceRoot":"","sources":["../../../src/analyzer/rules/hardcodedSecret.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"unsafeLink.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/unsafeLink.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,eAAO,MAAM,cAAc,EAAE,IA+F5B,CAAC"}
1
+ {"version":3,"file":"unsafeLink.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/unsafeLink.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGvC,eAAO,MAAM,cAAc,EAAE,IAyK5B,CAAC"}
@@ -1,28 +1,66 @@
1
1
  import ts from 'typescript';
2
+ import { createSourceFile } from '../createSourceFile.js';
2
3
  export const unsafeLinkRule = (file) => {
3
4
  const findings = [];
4
- const sourceFile = ts.createSourceFile(file.path, file.content, ts.ScriptTarget.Latest, true, file.path.endsWith('.tsx') ? ts.ScriptKind.TSX : ts.ScriptKind.TS);
5
+ const sourceFile = createSourceFile(file.path, file.content);
6
+ function unwrapParentheses(node) {
7
+ let expression = node;
8
+ while (ts.isParenthesizedExpression(expression)) {
9
+ expression = expression.expression;
10
+ }
11
+ return expression;
12
+ }
5
13
  function isDangerousString(node) {
6
- return ((ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) &&
7
- /^\s*javascript\s*:/i.test(node.text));
14
+ const expression = unwrapParentheses(node);
15
+ if (!ts.isStringLiteral(expression) &&
16
+ !ts.isNoSubstitutionTemplateLiteral(expression)) {
17
+ return false;
18
+ }
19
+ // The URL parser removes ASCII tabs and newlines before scheme parsing,
20
+ // but an ordinary space inside the scheme makes it a different URL.
21
+ const normalizedValue = expression.text.replace(/[\t\n\r]/g, '');
22
+ return /^\s*javascript:/i.test(normalizedValue);
23
+ }
24
+ function bindingContainsName(bindingName, name) {
25
+ if (ts.isIdentifier(bindingName)) {
26
+ return bindingName.text === name;
27
+ }
28
+ return bindingName.elements.some((element) => ts.isBindingElement(element) && bindingContainsName(element.name, name));
29
+ }
30
+ function isFunctionLike(node) {
31
+ return (ts.isFunctionDeclaration(node) ||
32
+ ts.isFunctionExpression(node) ||
33
+ ts.isArrowFunction(node) ||
34
+ ts.isMethodDeclaration(node) ||
35
+ ts.isConstructorDeclaration(node) ||
36
+ ts.isGetAccessorDeclaration(node) ||
37
+ ts.isSetAccessorDeclaration(node));
8
38
  }
9
39
  function findVisibleDeclaration(reference) {
10
40
  let current = reference.parent;
11
41
  while (current) {
12
42
  if (ts.isBlock(current) || ts.isSourceFile(current)) {
13
- for (const statement of current.statements) {
14
- if (!ts.isVariableStatement(statement))
15
- continue;
16
- for (const declaration of statement.declarationList.declarations) {
17
- if (ts.isIdentifier(declaration.name) &&
18
- declaration.name.text === reference.text &&
19
- declaration.initializer &&
20
- declaration.getStart(sourceFile) < reference.getStart(sourceFile)) {
21
- return declaration;
22
- }
43
+ const declarations = current.statements.flatMap((statement) => {
44
+ if (!ts.isVariableStatement(statement)) {
45
+ return [];
23
46
  }
47
+ return statement.declarationList.declarations.filter((declaration) => ts.isIdentifier(declaration.name) &&
48
+ declaration.name.text === reference.text);
49
+ });
50
+ if (declarations.length > 0) {
51
+ const precedingDeclaration = declarations
52
+ .filter((declaration) => declaration.getStart(sourceFile) <
53
+ reference.getStart(sourceFile))
54
+ .at(-1);
55
+ // A later declaration still shadows outer bindings in this scope.
56
+ return precedingDeclaration;
24
57
  }
25
58
  }
59
+ if (isFunctionLike(current) &&
60
+ current.parameters.some((parameter) => bindingContainsName(parameter.name, reference.text))) {
61
+ // A parameter shadows same-named declarations in outer scopes.
62
+ return undefined;
63
+ }
26
64
  current = current.parent;
27
65
  }
28
66
  return undefined;
@@ -34,11 +72,15 @@ export const unsafeLinkRule = (file) => {
34
72
  node.initializer) {
35
73
  let dangerous = false;
36
74
  if (ts.isStringLiteral(node.initializer)) {
37
- dangerous = /^\s*javascript\s*:/i.test(node.initializer.text);
75
+ dangerous = isDangerousString(node.initializer);
38
76
  }
39
- else if (ts.isJsxExpression(node.initializer)) {
40
- const expression = node.initializer.expression;
41
- if (expression && ts.isIdentifier(expression)) {
77
+ else if (ts.isJsxExpression(node.initializer) &&
78
+ node.initializer.expression) {
79
+ const expression = unwrapParentheses(node.initializer.expression);
80
+ if (isDangerousString(expression)) {
81
+ dangerous = true;
82
+ }
83
+ else if (ts.isIdentifier(expression)) {
42
84
  const declaration = findVisibleDeclaration(expression);
43
85
  dangerous = Boolean(declaration?.initializer &&
44
86
  isDangerousString(declaration.initializer));
@@ -55,7 +97,7 @@ export const unsafeLinkRule = (file) => {
55
97
  line: line + 1,
56
98
  rule: 'unsafe-link',
57
99
  message: 'JavaScript URLs in links can execute code when activated.',
58
- evidence: file.content.split('\n')[line]?.trim() ?? '',
100
+ evidence: file.content.split(/\r?\n/)[line]?.trim() ?? '',
59
101
  requiresAIReview: true,
60
102
  });
61
103
  }
@@ -1 +1 @@
1
- {"version":3,"file":"unsafeLink.js","sourceRoot":"","sources":["../../../src/analyzer/rules/unsafeLink.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"unsafeLink.js","sourceRoot":"","sources":["../../../src/analyzer/rules/unsafeLink.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,IAAI,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACtF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAK3D,OAAO,KAAK,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAQjF,KAAK,eAAe,GAAG;IACrB,cAAc,EAAE,OAAO,qBAAqB,CAAC;IAC7C,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,OAAO,EAAE,CAAC;IAC5C,YAAY,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;CACjD,CAAC;AAQF,wBAAsB,MAAM,CAC1B,IAAI,EAAE,MAAM,EAAE,EACd,YAAY,GAAE,eAQb,GACA,OAAO,CAAC,IAAI,CAAC,CAwIf"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,IAAI,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACtF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAK3D,OAAO,KAAK,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAQjF,KAAK,eAAe,GAAG;IACrB,cAAc,EAAE,OAAO,qBAAqB,CAAC;IAC7C,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,OAAO,EAAE,CAAC;IAC5C,YAAY,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;CACjD,CAAC;AAQF,wBAAsB,MAAM,CAC1B,IAAI,EAAE,MAAM,EAAE,EACd,YAAY,GAAE,eAQb,GACA,OAAO,CAAC,IAAI,CAAC,CAgJf"}
package/dist/cli.js CHANGED
@@ -29,16 +29,24 @@ export async function runCLI(args, dependencies = {
29
29
  'Sudeshi Code Review',
30
30
  '',
31
31
  'Usage:',
32
- ' sudeshi-code-review <repository-path>',
32
+ ' sudeshi-code-review <repository-path> [options]',
33
+ ' sudeshi-code-review --help',
34
+ ' sudeshi-code-review --version',
33
35
  '',
34
36
  'Options:',
35
- ' -h, --help Show this help message',
36
- ' -v, --version Show the installed version',
37
- ' --format <format> Report format: markdown or json (default: markdown)',
38
- ' --output <path> Save the report to a file instead of stdout',
37
+ ' -h, --help Show this help message',
38
+ ' -v, --version Show the installed version',
39
+ ' --format <format> Report format: markdown or json (default: markdown)',
40
+ ' --output <path> Save the report to a file instead of stdout',
41
+ '',
42
+ 'Examples:',
43
+ ' sudeshi-code-review ./my-app',
44
+ ' sudeshi-code-review ./my-app --format json',
45
+ ' sudeshi-code-review ./my-app --format json --output report.json',
39
46
  '',
40
47
  'Environment:',
41
- ' SARVAM_API_KEY Optional API key for AI-assisted review',
48
+ ' SARVAM_API_KEY Optional API key for AI-assisted review',
49
+ ' NO_COLOR Disable terminal colors when set',
42
50
  '',
43
51
  ].join('\n'));
44
52
  return;
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,10 @@
1
1
  import type { ReviewResult } from '../review/reviewEngine.js';
2
- export declare function generateTerminalReport(result: ReviewResult): string;
2
+ type TerminalReportOptions = {
3
+ /** Override automatic terminal color detection, primarily for tests. */
4
+ color?: boolean;
5
+ /** Override the output width, primarily for tests. */
6
+ width?: number;
7
+ };
8
+ export declare function generateTerminalReport(result: ReviewResult, options?: TerminalReportOptions): string;
9
+ export {};
3
10
  //# sourceMappingURL=terminalReporter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"terminalReporter.d.ts","sourceRoot":"","sources":["../../src/reporting/terminalReporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CA2CnE"}
1
+ {"version":3,"file":"terminalReporter.d.ts","sourceRoot":"","sources":["../../src/reporting/terminalReporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAY9D,KAAK,qBAAqB,GAAG;IAC3B,wEAAwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAgFF,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE,qBAA0B,GAClC,MAAM,CAyFR"}
@@ -1,4 +1,75 @@
1
- export function generateTerminalReport(result) {
1
+ const ANSI = {
2
+ reset: '\u001b[0m',
3
+ bold: '\u001b[1m',
4
+ dim: '\u001b[2m',
5
+ cyan: '\u001b[36m',
6
+ green: '\u001b[32m',
7
+ yellow: '\u001b[33m',
8
+ red: '\u001b[31m',
9
+ };
10
+ function shouldUseColor() {
11
+ return (Boolean(process.stdout.isTTY) &&
12
+ !('NO_COLOR' in process.env) &&
13
+ process.env.FORCE_COLOR !== '0');
14
+ }
15
+ function paint(text, color, enabled) {
16
+ return enabled ? `${color}${text}${ANSI.reset}` : text;
17
+ }
18
+ function paintSeverity(severity, enabled) {
19
+ const color = severity === 'high'
20
+ ? ANSI.red
21
+ : severity === 'medium'
22
+ ? ANSI.yellow
23
+ : ANSI.cyan;
24
+ return paint(severity.toUpperCase(), `${ANSI.bold}${color}`, enabled);
25
+ }
26
+ /**
27
+ * Wrap plain text to a maximum line width. Long words such as file paths
28
+ * are split when necessary so they cannot overflow a narrow terminal.
29
+ */
30
+ function wrapText(text, width) {
31
+ const safeWidth = Math.max(1, width);
32
+ const words = text.split(/\s+/).filter(Boolean);
33
+ const lines = [];
34
+ let line = '';
35
+ for (const word of words) {
36
+ if (word.length > safeWidth) {
37
+ if (line) {
38
+ lines.push(line);
39
+ line = '';
40
+ }
41
+ // Split long tokens without adding spaces between their chunks.
42
+ for (let offset = 0; offset < word.length; offset += safeWidth) {
43
+ lines.push(word.slice(offset, offset + safeWidth));
44
+ }
45
+ continue;
46
+ }
47
+ if (!line) {
48
+ line = word;
49
+ }
50
+ else if (line.length + 1 + word.length <= safeWidth) {
51
+ line += ` ${word}`;
52
+ }
53
+ else {
54
+ lines.push(line);
55
+ line = word;
56
+ }
57
+ }
58
+ if (line) {
59
+ lines.push(line);
60
+ }
61
+ return lines.length ? lines : [''];
62
+ }
63
+ function appendWrapped(lines, text, width, indent = ' ') {
64
+ const contentWidth = Math.max(1, width - indent.length);
65
+ for (const line of wrapText(text, contentWidth)) {
66
+ lines.push(`${indent}${line}`);
67
+ }
68
+ }
69
+ export function generateTerminalReport(result, options = {}) {
70
+ const color = options.color ?? shouldUseColor();
71
+ const width = Math.max(1, Math.floor(options.width ?? process.stdout.columns ?? 80));
72
+ const divider = '─'.repeat(Math.min(width, 80));
2
73
  const counts = {
3
74
  high: result.findings.filter((finding) => finding.severity === 'high')
4
75
  .length,
@@ -7,24 +78,34 @@ export function generateTerminalReport(result) {
7
78
  low: result.findings.filter((finding) => finding.severity === 'low').length,
8
79
  };
9
80
  const lines = [
10
- 'SUDESHI CODE REVIEW',
11
- '===================',
81
+ paint('SUDESHI CODE REVIEW', `${ANSI.bold}${ANSI.cyan}`, color),
82
+ paint(divider, ANSI.dim, color),
12
83
  '',
13
- `Review complete in ${(result.durationMs / 1000).toFixed(2)}s`,
14
- `${result.filesScanned} files scanned · ${result.findings.length} findings`,
84
+ `${paint('✓', ANSI.green, color)} Review complete in ${(result.durationMs / 1000).toFixed(2)}s`,
85
+ `${paint(String(result.filesScanned), ANSI.cyan, color)} files scanned · ${paint(String(result.findings.length), result.findings.length ? ANSI.yellow : ANSI.green, color)} findings`,
15
86
  '',
16
- `Severity: ${counts.high} high · ${counts.medium} medium · ${counts.low} low`,
87
+ `Severity ${paint(`${counts.high} high`, ANSI.red, color)} · ${paint(`${counts.medium} medium`, ANSI.yellow, color)} · ${paint(`${counts.low} low`, ANSI.cyan, color)}`,
17
88
  ];
18
89
  if (result.findings.length === 0) {
19
- lines.push('', 'No findings detected.');
90
+ lines.push('', paint(divider, ANSI.dim, color), '', paint('✓ No findings detected.', `${ANSI.bold}${ANSI.green}`, color));
20
91
  return lines.join('\n');
21
92
  }
93
+ lines.push('', paint('FINDINGS', `${ANSI.bold}${ANSI.cyan}`, color), paint(divider, ANSI.dim, color));
22
94
  for (const finding of result.findings) {
23
- lines.push('', `[${finding.severity.toUpperCase()}] ${finding.rule}`, ` ${finding.file}:${finding.line}`, ` ${finding.message}`, ` Confidence: ${Math.round(finding.confidence * 100)}%`);
95
+ lines.push('', `${paintSeverity(finding.severity, color)} ${paint(finding.rule, ANSI.bold, color)}`);
96
+ appendWrapped(lines, `${finding.file}:${finding.line}`, width);
97
+ appendWrapped(lines, finding.message, width);
98
+ appendWrapped(lines, `Confidence: ${Math.round(finding.confidence * 100)}%`, width);
24
99
  if (finding.aiReview) {
25
- lines.push(` AI assessment: ${finding.aiReview.valid ? 'Valid finding' : 'Possible false positive'}`, ` AI confidence: ${Math.round(finding.aiReview.confidence * 100)}%`, ` Recommendation: ${finding.aiReview.recommendation}`);
100
+ const assessment = finding.aiReview.valid
101
+ ? 'Valid finding'
102
+ : 'Possible false positive';
103
+ appendWrapped(lines, `AI assessment: ${assessment}`, width);
104
+ appendWrapped(lines, `AI confidence: ${Math.round(finding.aiReview.confidence * 100)}%`, width);
105
+ appendWrapped(lines, `Recommendation: ${finding.aiReview.recommendation}`, width);
26
106
  }
27
107
  }
108
+ lines.push('', paint(divider, ANSI.dim, color));
28
109
  return lines.join('\n');
29
110
  }
30
111
  //# sourceMappingURL=terminalReporter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"terminalReporter.js","sourceRoot":"","sources":["../../src/reporting/terminalReporter.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,sBAAsB,CAAC,MAAoB;IACzD,MAAM,MAAM,GAAG;QACb,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,KAAK,MAAM,CAAC;aACnE,MAAM;QACT,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC;aACvE,MAAM;QACT,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,KAAK,KAAK,CAAC,CAAC,MAAM;KAC5E,CAAC;IAEF,MAAM,KAAK,GAAG;QACZ,qBAAqB;QACrB,qBAAqB;QACrB,EAAE;QACF,sBAAsB,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;QAC9D,GAAG,MAAM,CAAC,YAAY,oBAAoB,MAAM,CAAC,QAAQ,CAAC,MAAM,WAAW;QAC3E,EAAE;QACF,aAAa,MAAM,CAAC,IAAI,WAAW,MAAM,CAAC,MAAM,aAAa,MAAM,CAAC,GAAG,MAAM;KAC9E,CAAC;IAEF,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,uBAAuB,CAAC,CAAC;QACxC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACtC,KAAK,CAAC,IAAI,CACR,EAAE,EACF,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,IAAI,EAAE,EACrD,KAAK,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE,EACnC,KAAK,OAAO,CAAC,OAAO,EAAE,EACtB,iBAAiB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,CACzD,CAAC;QAEF,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,KAAK,CAAC,IAAI,CACR,oBAAoB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,yBAAyB,EAAE,EAC1F,oBAAoB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,EACpE,qBAAqB,OAAO,CAAC,QAAQ,CAAC,cAAc,EAAE,CACvD,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"terminalReporter.js","sourceRoot":"","sources":["../../src/reporting/terminalReporter.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,8 @@ export declare class ReviewEngine {
17
17
  private readonly config;
18
18
  constructor(config: ReviewEngineConfig);
19
19
  private redactHardcodedSecret;
20
+ private redactShortSecretOccurrences;
21
+ private redactKnownSecretValues;
20
22
  private redactSecretValue;
21
23
  review(input: ReviewInput): Promise<ReviewResult>;
22
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"reviewEngine.d.ts","sourceRoot":"","sources":["../../src/review/reviewEngine.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAG5D,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,KAAK,kBAAkB,GAAG;IACxB,QAAQ,EAAE,UAAU,CAAC;CACtB,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB,CAAC;AAaF,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,kBAAkB;IAEvD,OAAO,CAAC,qBAAqB;IAoE7B,OAAO,CAAC,iBAAiB;IAcnB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CA8DxD"}
1
+ {"version":3,"file":"reviewEngine.d.ts","sourceRoot":"","sources":["../../src/review/reviewEngine.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAG5D,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,KAAK,kBAAkB,GAAG;IACxB,QAAQ,EAAE,UAAU,CAAC;CACtB,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB,CAAC;AAyEF,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,kBAAkB;IAEvD,OAAO,CAAC,qBAAqB;IA2I7B,OAAO,CAAC,4BAA4B;IAkHpC,OAAO,CAAC,uBAAuB;IA6B/B,OAAO,CAAC,iBAAiB;IAkBnB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CA+FxD"}
@@ -1,6 +1,8 @@
1
1
  import ts from 'typescript';
2
2
  import { buildContext } from '../context/buildContext.js';
3
3
  const SECRET_ASSIGNMENT_PATTERN = String.raw `\b([\w$]*(?:api[_-]?key|password|secret|client[_-]?secret|token|database[_-]?url))\s*(=|:)\s*(?:(['"])((?:\\.|[^\\])*?)\3|(\`)((?:\\.|(?!\$\{)[^\\])*?)\5)`;
4
+ const MINIMUM_GLOBAL_REDACTION_LENGTH = 4;
5
+ const REDACTION_SENTINEL = '\u0000SUDESHI_SECRET_REDACTION_SENTINEL_7F3A\u0000';
4
6
  function createSecretAssignmentRegex(global = false) {
5
7
  return new RegExp(SECRET_ASSIGNMENT_PATTERN, global ? 'gi' : 'i');
6
8
  }
@@ -8,12 +10,51 @@ function extractSecretValue(evidence) {
8
10
  const match = evidence?.match(createSecretAssignmentRegex());
9
11
  return match?.[4] ?? match?.[6];
10
12
  }
13
+ function escapeRegExp(value) {
14
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
15
+ }
16
+ function getStaticPropertyName(name) {
17
+ if (ts.isIdentifier(name) ||
18
+ ts.isStringLiteral(name) ||
19
+ ts.isNoSubstitutionTemplateLiteral(name)) {
20
+ return name.text;
21
+ }
22
+ if (ts.isComputedPropertyName(name)) {
23
+ const expression = name.expression;
24
+ if (ts.isStringLiteral(expression) ||
25
+ ts.isNoSubstitutionTemplateLiteral(expression)) {
26
+ return expression.text;
27
+ }
28
+ }
29
+ return undefined;
30
+ }
31
+ function hasStandaloneSecret(value, secret) {
32
+ if (!/^[\w$]+$/.test(secret)) {
33
+ return value === secret;
34
+ }
35
+ const pattern = new RegExp(`(?<![\\w$])${escapeRegExp(secret)}(?![\\w$])`);
36
+ return pattern.test(value);
37
+ }
38
+ function redactStandaloneSecret(value, secret) {
39
+ if (!/^[\w$]+$/.test(secret)) {
40
+ return value === secret ? '[REDACTED]' : value;
41
+ }
42
+ if (secret.length === 1) {
43
+ // A single character is too ambiguous to replace throughout prose/comments.
44
+ return value === secret ? '[REDACTED]' : value;
45
+ }
46
+ const pattern = new RegExp(`(?<![\\w$])${escapeRegExp(secret)}(?![\\w$])`, 'g');
47
+ return value
48
+ .split(REDACTION_SENTINEL)
49
+ .map((segment) => segment.replace(pattern, REDACTION_SENTINEL))
50
+ .join(REDACTION_SENTINEL);
51
+ }
11
52
  export class ReviewEngine {
12
53
  config;
13
54
  constructor(config) {
14
55
  this.config = config;
15
56
  }
16
- redactHardcodedSecret(source, filePath = 'source.ts') {
57
+ redactHardcodedSecret(source, filePath = 'source.ts', collectedSecretValues) {
17
58
  const scriptKind = filePath.endsWith('.tsx')
18
59
  ? ts.ScriptKind.TSX
19
60
  : filePath.endsWith('.jsx')
@@ -24,6 +65,22 @@ export class ReviewEngine {
24
65
  const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, scriptKind);
25
66
  const secretNamePattern = /(?:api[_-]?key|password|secret|client[_-]?secret|token|database[_-]?url)/i;
26
67
  const edits = [];
68
+ const secretValues = collectedSecretValues ?? new Set();
69
+ function collectSecretValueParts(valueNode) {
70
+ if (ts.isStringLiteral(valueNode) ||
71
+ ts.isNoSubstitutionTemplateLiteral(valueNode)) {
72
+ if (valueNode.text && valueNode.text !== '[REDACTED]') {
73
+ secretValues.add(valueNode.text);
74
+ }
75
+ // Keep both decoded and source spellings (e.g. escaped quotes).
76
+ const rawValue = valueNode.getText(sourceFile).slice(1, -1);
77
+ if (rawValue && rawValue !== '[REDACTED]') {
78
+ secretValues.add(rawValue);
79
+ }
80
+ }
81
+ // This also visits string literals nested inside template expressions.
82
+ ts.forEachChild(valueNode, collectSecretValueParts);
83
+ }
27
84
  function visit(node) {
28
85
  let name;
29
86
  let initializer;
@@ -31,8 +88,8 @@ export class ReviewEngine {
31
88
  name = node.name.text;
32
89
  initializer = node.initializer;
33
90
  }
34
- else if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name)) {
35
- name = node.name.text;
91
+ else if (ts.isPropertyAssignment(node)) {
92
+ name = getStaticPropertyName(node.name);
36
93
  initializer = node.initializer;
37
94
  }
38
95
  if (name &&
@@ -41,29 +98,164 @@ export class ReviewEngine {
41
98
  (ts.isStringLiteral(initializer) ||
42
99
  ts.isNoSubstitutionTemplateLiteral(initializer) ||
43
100
  ts.isTemplateExpression(initializer))) {
44
- edits.push({
101
+ const edit = {
45
102
  start: initializer.getStart(sourceFile),
46
103
  end: initializer.getEnd(),
104
+ };
105
+ // The AST traversal is parent-first. If this initializer overlaps an
106
+ // edit already selected for an outer secret initializer, do not add a
107
+ // second edit: applying overlapping ranges with original offsets can
108
+ // leave part of the outer template in the AI-bound source. Still
109
+ // collect nested literals so repeated values can be redacted elsewhere.
110
+ const overlapsExistingEdit = edits.some((existing) => edit.start < existing.end && existing.start < edit.end);
111
+ if (!overlapsExistingEdit) {
112
+ edits.push(edit);
113
+ }
114
+ collectSecretValueParts(initializer);
115
+ }
116
+ ts.forEachChild(node, visit);
117
+ }
118
+ visit(sourceFile);
119
+ let redactedSource = source;
120
+ // Replace the complete initializer, regardless of its length or syntax.
121
+ for (const edit of edits.sort((a, b) => b.start - a.start)) {
122
+ redactedSource =
123
+ redactedSource.slice(0, edit.start) +
124
+ "'" +
125
+ REDACTION_SENTINEL +
126
+ "'" +
127
+ redactedSource.slice(edit.end);
128
+ }
129
+ // The detector's evidence may already be redacted. Preserve known literal
130
+ // values and remove longer repeated occurrences elsewhere in AI-bound text.
131
+ // Short values are handled separately with literal- and token-aware matching.
132
+ const valuesToRedact = [...secretValues]
133
+ .filter((value) => value.length >= MINIMUM_GLOBAL_REDACTION_LENGTH)
134
+ .sort((a, b) => b.length - a.length);
135
+ for (const value of valuesToRedact) {
136
+ redactedSource = redactedSource
137
+ .split(REDACTION_SENTINEL)
138
+ .map((segment) => segment.replaceAll(value, REDACTION_SENTINEL))
139
+ .join(REDACTION_SENTINEL);
140
+ }
141
+ // Short values need narrower handling: redact matching string literals and
142
+ // bounded comment tokens instead of replacing arbitrary substrings in code.
143
+ const shortValues = [...secretValues]
144
+ .filter((value) => value.length > 0 && value.length < MINIMUM_GLOBAL_REDACTION_LENGTH)
145
+ .sort((a, b) => b.length - a.length);
146
+ for (const value of shortValues) {
147
+ redactedSource = this.redactShortSecretOccurrences(redactedSource, value, filePath);
148
+ }
149
+ return redactedSource.replaceAll(REDACTION_SENTINEL, '[REDACTED]');
150
+ }
151
+ redactShortSecretOccurrences(source, secret, filePath) {
152
+ const scriptKind = filePath.endsWith('.tsx')
153
+ ? ts.ScriptKind.TSX
154
+ : filePath.endsWith('.jsx')
155
+ ? ts.ScriptKind.JSX
156
+ : filePath.endsWith('.js')
157
+ ? ts.ScriptKind.JS
158
+ : ts.ScriptKind.TS;
159
+ const languageVariant = scriptKind === ts.ScriptKind.TSX || scriptKind === ts.ScriptKind.JSX
160
+ ? ts.LanguageVariant.JSX
161
+ : ts.LanguageVariant.Standard;
162
+ const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, scriptKind);
163
+ const edits = [];
164
+ function visit(node) {
165
+ if ((ts.isTemplateHead(node) ||
166
+ ts.isTemplateMiddle(node) ||
167
+ ts.isTemplateTail(node)) &&
168
+ !node.text.includes(REDACTION_SENTINEL) &&
169
+ hasStandaloneSecret(node.text, secret)) {
170
+ // Replace only the static template chunk, preserving delimiters such
171
+ // as `${` and `}` so the resulting template remains syntactically valid.
172
+ const start = node.getStart(sourceFile) + 1;
173
+ const suffixLength = ts.isTemplateTail(node) ? 1 : 2;
174
+ const end = node.getEnd() - suffixLength;
175
+ edits.push({
176
+ start,
177
+ end,
178
+ replacement: REDACTION_SENTINEL,
179
+ });
180
+ }
181
+ else if ((ts.isStringLiteral(node) ||
182
+ ts.isNoSubstitutionTemplateLiteral(node)) &&
183
+ !node.text.includes(REDACTION_SENTINEL) &&
184
+ hasStandaloneSecret(node.text, secret)) {
185
+ const raw = node.getText(sourceFile);
186
+ const quote = raw[0] ?? "'";
187
+ edits.push({
188
+ start: node.getStart(sourceFile),
189
+ end: node.getEnd(),
190
+ replacement: `${quote}${REDACTION_SENTINEL}${quote}`,
47
191
  });
48
192
  }
49
193
  ts.forEachChild(node, visit);
50
194
  }
51
195
  visit(sourceFile);
196
+ // Comments are trivia rather than AST nodes, so scan them separately. For
197
+ // single-character values, skip comment-wide replacement to avoid erasing
198
+ // ordinary prose; exact matching string literals are still handled above.
199
+ if (secret.length >= 2 && /^[\w$]+$/.test(secret)) {
200
+ const scanner = ts.createScanner(ts.ScriptTarget.Latest, false, languageVariant, source);
201
+ while (true) {
202
+ const token = scanner.scan();
203
+ if (token === ts.SyntaxKind.EndOfFileToken) {
204
+ break;
205
+ }
206
+ if (token !== ts.SyntaxKind.SingleLineCommentTrivia &&
207
+ token !== ts.SyntaxKind.MultiLineCommentTrivia) {
208
+ continue;
209
+ }
210
+ const comment = scanner.getTokenText();
211
+ const redactedComment = redactStandaloneSecret(comment, secret);
212
+ if (redactedComment !== comment) {
213
+ edits.push({
214
+ start: scanner.getTokenPos(),
215
+ end: scanner.getTextPos(),
216
+ replacement: redactedComment,
217
+ });
218
+ }
219
+ }
220
+ }
52
221
  let redactedSource = source;
53
222
  for (const edit of edits.sort((a, b) => b.start - a.start)) {
54
223
  redactedSource =
55
224
  redactedSource.slice(0, edit.start) +
56
- "'[REDACTED]'" +
225
+ edit.replacement +
57
226
  redactedSource.slice(edit.end);
58
227
  }
59
228
  return redactedSource;
60
229
  }
230
+ redactKnownSecretValues(value, secretValues) {
231
+ let redactedValue = value;
232
+ const valuesToRedact = [...secretValues]
233
+ .filter((secret) => secret.length > 0)
234
+ .sort((a, b) => b.length - a.length);
235
+ for (const secret of valuesToRedact) {
236
+ if (secret.length >= MINIMUM_GLOBAL_REDACTION_LENGTH) {
237
+ redactedValue = redactedValue.replaceAll(secret, '[REDACTED]');
238
+ }
239
+ else if (secret.length >= 2 && /^[\w$]+$/.test(secret)) {
240
+ const pattern = new RegExp(`(?<![\\w$])${escapeRegExp(secret)}(?![\\w$])`, 'g');
241
+ redactedValue = redactedValue.replace(pattern, '[REDACTED]');
242
+ }
243
+ else if (redactedValue === secret) {
244
+ // For one-character or punctuation-only values, only redact an exact
245
+ // field match; broad replacement would have excessive false positives.
246
+ redactedValue = '[REDACTED]';
247
+ }
248
+ }
249
+ return redactedValue;
250
+ }
61
251
  redactSecretValue(source, finding) {
62
252
  if (finding.rule !== 'hardcoded-secret') {
63
253
  return source;
64
254
  }
65
255
  const secret = extractSecretValue(finding.evidence);
66
- if (!secret) {
256
+ if (!secret ||
257
+ secret === '[REDACTED]' ||
258
+ secret.length < MINIMUM_GLOBAL_REDACTION_LENGTH) {
67
259
  return source;
68
260
  }
69
261
  return source.replaceAll(secret, '[REDACTED]');
@@ -83,14 +275,28 @@ export class ReviewEngine {
83
275
  !extractSecretValue(finding.evidence)) {
84
276
  continue;
85
277
  }
278
+ const secretValues = new Set();
279
+ const secretFromEvidence = extractSecretValue(finding.evidence);
280
+ if (secretFromEvidence && secretFromEvidence !== '[REDACTED]') {
281
+ secretValues.add(secretFromEvidence);
282
+ }
86
283
  const safeSourceFile = {
87
284
  ...sourceFile,
88
- content: this.redactSecretValue(this.redactHardcodedSecret(sourceFile.content, sourceFile.path), finding),
285
+ content: this.redactSecretValue(this.redactHardcodedSecret(sourceFile.content, sourceFile.path, secretValues), finding),
89
286
  };
90
287
  const safeFinding = {
91
288
  ...finding,
289
+ file: this.redactKnownSecretValues(finding.file, secretValues),
290
+ message: this.redactKnownSecretValues(finding.message, secretValues),
92
291
  ...(finding.evidence !== undefined && {
93
- evidence: this.redactSecretValue(this.redactHardcodedSecret(finding.evidence, sourceFile.path), finding),
292
+ evidence: this.redactKnownSecretValues(this.redactSecretValue(this.redactHardcodedSecret(finding.evidence, sourceFile.path, secretValues), finding), secretValues),
293
+ }),
294
+ ...(finding.aiReview && {
295
+ aiReview: {
296
+ ...finding.aiReview,
297
+ reason: this.redactKnownSecretValues(finding.aiReview.reason, secretValues),
298
+ recommendation: this.redactKnownSecretValues(finding.aiReview.recommendation, secretValues),
299
+ },
94
300
  }),
95
301
  };
96
302
  const context = buildContext(safeSourceFile, safeFinding);
@@ -1 +1 @@
1
- {"version":3,"file":"reviewEngine.js","sourceRoot":"","sources":["../../src/review/reviewEngine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reviewEngine.js","sourceRoot":"","sources":["../../src/review/reviewEngine.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sudeshi-code-review",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "A TypeScript and React code review CLI with security rules and optional Sarvam AI analysis.",
5
5
  "homepage": "https://github.com/sriram23/sudeshi-code-review#readme",
6
6
  "bugs": {
@@ -13,7 +13,6 @@
13
13
  "license": "MIT",
14
14
  "author": "Sriram B",
15
15
  "type": "module",
16
- "main": "./dist/index.js",
17
16
  "scripts": {
18
17
  "build": "tsc",
19
18
  "test": "vitest run",