Skip to content

feat(cli): add auto version checking and update prompt#29

Merged
utkarsh232005 merged 4 commits into
KDM-cli:mainfrom
blut-agent:fix/auto-version-check
May 17, 2026
Merged

feat(cli): add auto version checking and update prompt#29
utkarsh232005 merged 4 commits into
KDM-cli:mainfrom
blut-agent:fix/auto-version-check

Conversation

@blut-agent
Copy link
Copy Markdown
Contributor

@blut-agent blut-agent commented May 16, 2026

feat(cli): add auto version checking and update prompt

This PR implements automatic version checking when the CLI starts, addressing issue #26.

What's New

  • New utility: src/utils/version-check.ts — fetches the latest version from the npm registry and compares it with the installed version
  • Non-blocking notification: Shows a color-coded update prompt after command execution without slowing down the CLI
  • Smart messaging: Displays update type (Major/Minor/New) with current vs latest version and a direct npm install -g kdm-cli@latest command
  • Graceful degradation: Silently fails if the npm registry is unreachable — no errors for users

Example Output

When a newer version is available:

  Major update available!
  Current Version : v1.2.1
  Latest Version  : v2.0.0
  Update using    : npm install -g kdm-cli@latest

Files Changed

  • src/utils/version-check.ts — new file (version check utility)
  • src/commands/root.ts — integrated version check into CLI entry point

Summary by CodeRabbit

  • New Features
    • CLI now performs a non-blocking background version check after commands run.
    • If a newer release is found, you'll see a concise notification with the new version, update severity (major/minor/patch), and upgrade instructions.
    • The check is silent on errors and won’t disrupt normal command execution.

Review Change Stack

Introduce a structured, version-based documentation system for KDM CLI
commands. This addresses issue KDM-cli#25 by creating a dedicated docs/ directory
with versioned command documentation.

Structure:
  docs/v1.2.1/README.md          — Version overview and command index
  docs/v1.2.1/show/README.md     — show (runners, pods, containers, minikube)
  docs/v1.2.1/health/README.md   — health (pods, containers, all)
  docs/v1.2.1/watch/README.md    — watch (live monitoring)
  docs/v1.2.1/logs/README.md     — logs (container/pod logs)
  docs/v1.2.1/config/README.md   — config (setup, set, list, clear)

Each command doc includes: overview, syntax, parameters, examples,
expected output, use cases, and common errors. Version info is included
in every document for traceability.
- Create new version-check utility that fetches the latest version from npm registry
- Compares installed version with latest published version
- Displays a non-blocking, color-coded update notification when a newer version is available
- Shows update type (Major/Minor/New) with current vs latest version info
- Provides direct update command: npm install -g kdm-cli@latest
- Silently fails if the registry is unreachable (non-intrusive)
- Runs asynchronously after command execution to avoid slowing down the CLI

Addresses issue KDM-cli#26.
@blut-agent blut-agent requested a review from utkarsh232005 as a code owner May 16, 2026 06:47
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 16, 2026

📝 Walkthrough

Walkthrough

Adds a non-blocking version-check: a new utility reads the installed kdm-cli version from package.json, fetches kdm-cli@latest from the npm registry, compares semantic versions, and logs an update message when behind. The root command invokes this check asynchronously after CLI execution.

Changes

Auto-update version check

Layer / File(s) Summary
Version check utility implementation
src/utils/version-check.ts
Exports checkForUpdates(); reads local package.json for installed version, fetches kdm-cli@latest from the npm registry with a 1500ms timeout, compares versions using a numeric dot-segment comparator, derives major/minor/patch update type, and logs a formatted update message when the installed version is older. All errors are caught and ignored.
Root command integration
src/commands/root.ts
Imports checkForUpdates and invokes it non-blocking after CLI command wiring so the check runs post-execution regardless of user arguments. No other CLI behavior was changed.

⚠️ Security & Review Observations

  1. npm registry URL is inline; extract to a top-level constant and validate it.
  2. Errors are fully suppressed — consider emitting debug-level logs for failures to aid troubleshooting.
  3. No tests included: add unit tests for compareSemver, getUpdateType, getInstalledVersion fallback, and network timeout/error cases.
  4. Ensure the non-blocking Promise is safely fire-and-forget (already caught in implementation) to avoid unhandled rejection warnings.
  5. Consider rate-limiting or opt-out for telemetry/registry calls in high-frequency CLI use.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Poem

A tiny ping beyond the run,
Asking npm if work is done.
Quietly it checks the sky—
“Update waits,” a soft reply.
The CLI nods and carries on.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding automatic version checking with an update prompt to the CLI on startup.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/commands/root.ts`:
- Around line 80-81: The update check call checkForUpdates() is never reached in
the zero-argument branch because that branch calls process.exit(...); fix by
ensuring checkForUpdates() runs before terminating: either invoke
checkForUpdates() (non-blocking) prior to the process.exit call in the no-args
branch or replace the immediate process.exit(...) with a return so the flow
continues to the shared post-command teardown that calls checkForUpdates();
update the no-args handling code path (where process.exit is called) to
reference the same logic used for other branches so checkForUpdates() always
runs.

In `@src/utils/version-check.ts`:
- Around line 20-68: Add unit tests that exercise compareSemver and
getUpdateType across all branches: for compareSemver test major/minor/patch
equality and v-prefixed inputs (expect 'lt'/'gt'/'eq'); for getUpdateType verify
it returns 'major', 'minor', 'patch' (or empty string for equal) by providing
installed/latest combos that differ by major, minor, patch and with/without
leading "v"; also add tests for checkForUpdates to simulate fetch responses
(mock successful JSON with a newer version to verify console output uses the
correct typeLabel and version strings, and mock a failing fetch or non-ok
response to ensure the function silently returns) — target the functions
compareSemver, getUpdateType, and checkForUpdates when adding these focused
tests.
- Around line 38-40: The code that compares installed vs latest versions
mis-destructures the minor component: it reuses index 0 for i2 and l2 so minor
bumps are treated as patch; update the destructuring for the minor comparison in
the version-check logic (the lines that currently read const [i2] =
installed.replace(/^v/, '').split('.').map(Number); and const [l2] =
latest.replace(/^v/, '').split('.').map(Number);) to pull the second element
(minor) instead (e.g., use const [, i2] = ... and const [, l2] = ... or index
into the array) so that 1.1.0 -> 1.2.0 correctly returns 'minor'.
- Around line 46-47: The fetch in checkForUpdates() (src/utils/version-check.ts)
needs a timeout so a stalled npm-registry request doesn't keep the event loop
alive; update the call to use an AbortSignal via AbortSignal.timeout(timeoutMs)
and pass the signal to fetch (ensuring you abort/handle the thrown
DOMException), and ensure the early-return/error logging paths remain intact in
the checkForUpdates() function; then add vitest tests for checkForUpdates() that
simulate a hanging fetch (to assert the timeout triggers) and a failing response
(non-ok) to cover error handling.
🪄 Autofix (Beta)

❌ Autofix failed (check again to retry)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 30d3daaf-c928-4d8c-a830-54b53536667e

📥 Commits

Reviewing files that changed from the base of the PR and between 234ea9b and 98a7395.

⛔ Files ignored due to path filters (6)
  • docs/v1.2.1/README.md is excluded by none and included by none
  • docs/v1.2.1/config/README.md is excluded by none and included by none
  • docs/v1.2.1/health/README.md is excluded by none and included by none
  • docs/v1.2.1/logs/README.md is excluded by none and included by none
  • docs/v1.2.1/show/README.md is excluded by none and included by none
  • docs/v1.2.1/watch/README.md is excluded by none and included by none
📒 Files selected for processing (2)
  • src/commands/root.ts
  • src/utils/version-check.ts

Comment thread src/commands/root.ts
Comment on lines +80 to +81
// Non-blocking version check (fires after command execution)
checkForUpdates();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Update check is unreachable on the zero-argument flow.

Because Line 74 calls process.exit(...) in the no-args branch, Lines 80–81 never execute there.

Suggested control-flow adjustment
 const run = async () => {
   if (!process.argv.slice(2).length) {
     showWelcomeBanner('1.1.0');
@@
     } finally {
       program.outputHelp();
-      process.exit(hadError ? 1 : 0);
+      process.exitCode = hadError ? 1 : 0;
     }
+    void checkForUpdates();
+    return;
   }

   program.parse(process.argv);
-  checkForUpdates();
+  void checkForUpdates();
 };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/commands/root.ts` around lines 80 - 81, The update check call
checkForUpdates() is never reached in the zero-argument branch because that
branch calls process.exit(...); fix by ensuring checkForUpdates() runs before
terminating: either invoke checkForUpdates() (non-blocking) prior to the
process.exit call in the no-args branch or replace the immediate
process.exit(...) with a return so the flow continues to the shared post-command
teardown that calls checkForUpdates(); update the no-args handling code path
(where process.exit is called) to reference the same logic used for other
branches so checkForUpdates() always runs.

Comment on lines +20 to +68
// Compare two semver strings; returns 'lt' if a < b, 'gt' if a > b, 'eq' if equal
function compareSemver(a: string, b: string): 'lt' | 'gt' | 'eq' {
const parse = (v: string) => v.replace(/^v/, '').split('.').map(Number);
const [a1, a2, a3] = parse(a);
const [b1, b2, b3] = parse(b);
if (a1 !== b1) return a1 < b1 ? 'lt' : 'gt';
if (a2 !== b2) return a2 < b2 ? 'lt' : 'gt';
if (a3 !== b3) return a3 < b3 ? 'lt' : 'gt';
return 'eq';
}

// Determine update type for messaging
function getUpdateType(installed: string, latest: string): string {
const cmp = compareSemver(installed, latest);
if (cmp === 'eq') return '';
const [i1] = installed.replace(/^v/, '').split('.').map(Number);
const [l1] = latest.replace(/^v/, '').split('.').map(Number);
if (l1 > i1) return 'major';
const [i2] = installed.replace(/^v/, '').split('.').map(Number);
const [l2] = latest.replace(/^v/, '').split('.').map(Number);
if (l2 > i2) return 'minor';
return 'patch';
}

export async function checkForUpdates(): Promise<void> {
try {
const response = await fetch('https://registry.npmjs.org/kdm-cli/latest');
if (!response.ok) return;

const data = await response.json() as { version: string };
const latestVersion = data.version;
const installedVersion = getInstalledVersion();

const cmp = compareSemver(installedVersion, latestVersion);
if (cmp === 'lt') {
const updateType = getUpdateType(installedVersion, latestVersion);
const typeLabel = updateType === 'major' ? 'Major' : updateType === 'minor' ? 'Minor' : 'New';

console.log();
console.log(chalk.bold(chalk.yellow(` ${typeLabel} update available!`)));
console.log(chalk.white(` Current Version : v${installedVersion}`));
console.log(chalk.white(` Latest Version : v${latestVersion}`));
console.log(chalk.cyan(` Update using : npm install -g kdm-cli@latest`));
console.log();
}
} catch {
// Silently fail — version check is non-critical
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Please add focused tests for version comparison and update labeling paths.

This file introduces branch-heavy logic (compareSemver, getUpdateType, silent-fail behavior) and should be covered to avoid regressions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/version-check.ts` around lines 20 - 68, Add unit tests that
exercise compareSemver and getUpdateType across all branches: for compareSemver
test major/minor/patch equality and v-prefixed inputs (expect 'lt'/'gt'/'eq');
for getUpdateType verify it returns 'major', 'minor', 'patch' (or empty string
for equal) by providing installed/latest combos that differ by major, minor,
patch and with/without leading "v"; also add tests for checkForUpdates to
simulate fetch responses (mock successful JSON with a newer version to verify
console output uses the correct typeLabel and version strings, and mock a
failing fetch or non-ok response to ensure the function silently returns) —
target the functions compareSemver, getUpdateType, and checkForUpdates when
adding these focused tests.

Comment thread src/utils/version-check.ts Outdated
Comment thread src/utils/version-check.ts Outdated
Copy link
Copy Markdown
Member

@utkarsh232005 utkarsh232005 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You pr has 2 commits by which it is merging two different prs merge just create fresh pr or force push your current pr branch changes

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@github-actions github-actions Bot added documentation Improvements or additions to documentation frontend labels May 17, 2026
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 17, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

An unexpected error occurred while generating fixes: Not Found - https://docs.github.com/rest/git/refs#get-a-reference

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/utils/version-check.ts`:
- Around line 57-58: The code casts the registry response to `{ version: string
}` and assigns `const data`/`latestVersion` without validating the shape; update
the logic in version-check utilities (the code around `const data = await
response.json() as { version: string };` and `const latestVersion =
data.version;`) to perform runtime validation: parse the JSON into an unknown,
assert that `data` is an object and that `data.version` exists and is a string
(e.g., typeof check), and handle invalid responses by logging a clear error and
returning a safe fallback (or throwing a descriptive error) instead of relying
on the cast. Ensure the function's return type and error handling reflect this
change.
- Around line 32-48: Remove the duplicate/overlapping getUpdateType declaration
and keep the corrected implementation: the version that uses compareSemver,
parses installed and latest with default numeric parts (e.g., const [i1 = 0, i2
= 0], const [l1 = 0, l2 = 0]), returns 'major' if l1>i1, 'minor' if l2>i2,
'patch' otherwise, and returns '' when compareSemver(...) === 'eq'; ensure only
one getUpdateType function (referenced symbol: getUpdateType) remains and the
stray earlier/extra braces and trailing return are removed so the file compiles.
- Around line 10-18: Remove the duplicate/incomplete getUpdateType declaration
and keep only the complete implementation named getUpdateType (the version that
correctly destructures major/minor with defaults and returns 'minor' when
appropriate); delete the orphaned earlier lines so the file compiles. In
checkForUpdates, add a runtime guard that validates the registry response by
checking typeof data.version === 'string' and early-return if not. Add vitest
fixtures/tests covering compareSemver, getUpdateType, and checkForUpdates
including tests for timeout behavior, error states, and invalid registry
responses to ensure coverage.
🪄 Autofix (Beta)

❌ Autofix failed (check again to retry)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2e12211c-4c70-494b-8145-7f22c5f3c35d

📥 Commits

Reviewing files that changed from the base of the PR and between 98a7395 and a1beb4e.

📒 Files selected for processing (1)
  • src/utils/version-check.ts

Comment on lines +10 to +18
function getInstalledVersion(): string {
const pkgPath = join(__dirname, '..', '..', 'package.json');
try {
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
return pkg.version || '0.0.0';
} catch {
return '0.0.0';
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check build configuration and deployment structure

# Check for bundler config
fd -t f -e json -e js -e ts 'vite.config|webpack.config|esbuild|tsup.config|build.config' --exec cat {} \;

# Check package.json build script and bin entry
jq '.scripts.build, .bin' package.json

# Check if dist/ structure matches src/
if [ -d "dist" ]; then
  echo "=== dist/ structure ==="
  tree -L 3 dist/ 2>/dev/null || find dist/ -type f | head -20
fi

Repository: KDM-cli/kdm-cli

Length of output: 126


🏁 Script executed:

#!/bin/bash
# Check repository root structure
echo "=== Repository root structure ==="
ls -la | grep -E "^d|^-.*\.(json|js|ts|sh)$"

# Check if bin/ directory exists
echo ""
echo "=== Checking bin/ directory ==="
if [ -d "bin" ]; then
  ls -la bin/
  echo ""
  echo "Content of bin/kdm.js (first 30 lines):"
  head -30 bin/kdm.js
else
  echo "bin/ directory does not exist"
fi

# Check if dist/ directory exists
echo ""
echo "=== Checking dist/ directory ==="
if [ -d "dist" ]; then
  ls -la dist/
  find dist/ -type f | head -10
else
  echo "dist/ directory does not exist"
fi

# Find actual output of the build
echo ""
echo "=== Searching for .js output files ==="
find . -name "*.js" -type f ! -path "*/node_modules/*" ! -path "*/.git/*" | head -20

Repository: KDM-cli/kdm-cli

Length of output: 1155


🏁 Script executed:

#!/bin/bash
# Read the version-check.ts file
cat -n src/utils/version-check.ts

Repository: KDM-cli/kdm-cli

Length of output: 3412


Remove duplicate getUpdateType function declaration—this is a syntax error blocking compilation.

Lines 32–37 and 47–48 contain the incomplete first version; lines 38–46 are the corrected implementation. Delete lines 32–37 and the orphaned lines 47–48. Keep only the complete version (lines 38–46) which correctly destructures both major and minor versions with defaults and includes the 'minor' return case.

Additionally:

  • Line 57: No runtime validation that data.version is a string. If the registry returns unexpected data, latestVersion could be undefined. Add a check: if (typeof data.version !== 'string') return;
  • Test coverage: Add vitest fixtures for compareSemver, getUpdateType, and checkForUpdates (including timeout, error states, and registry response validation).

The __dirname-based path resolution is correct for the tsup + bin shim setup (outputs to dist/, so dist/utils/../../package.json resolves to repo root).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/version-check.ts` around lines 10 - 18, Remove the
duplicate/incomplete getUpdateType declaration and keep only the complete
implementation named getUpdateType (the version that correctly destructures
major/minor with defaults and returns 'minor' when appropriate); delete the
orphaned earlier lines so the file compiles. In checkForUpdates, add a runtime
guard that validates the registry response by checking typeof data.version ===
'string' and early-return if not. Add vitest fixtures/tests covering
compareSemver, getUpdateType, and checkForUpdates including tests for timeout
behavior, error states, and invalid registry responses to ensure coverage.

Comment on lines +32 to +48
function getUpdateType(installed: string, latest: string): string {
const cmp = compareSemver(installed, latest);
if (cmp === 'eq') return '';
const [i1] = installed.replace(/^v/, '').split('.').map(Number);
const [l1] = latest.replace(/^v/, '').split('.').map(Number);
if (l1 > i1) return 'major';
function getUpdateType(installed: string, latest: string): string {
const cmp = compareSemver(installed, latest);
if (cmp === 'eq') return '';
const [i1 = 0, i2 = 0] = installed.replace(/^v/, '').split('.').map(Number);
const [l1 = 0, l2 = 0] = latest.replace(/^v/, '').split('.').map(Number);
if (l1 > i1) return 'major';
if (l2 > i2) return 'minor';
return 'patch';
}
return 'patch';
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Critical: Duplicate function declaration prevents compilation.

Lines 32–48 contain overlapping getUpdateType declarations. Line 38 starts a second function definition before the first closes, creating invalid syntax. This appears to be a merge artifact where the corrected version (lines 38–46) was added but the original (lines 32–37, 47–48) wasn't removed.

🔧 Proposed fix: remove the duplicate and keep only the corrected version
-// Determine update type for messaging
-function getUpdateType(installed: string, latest: string): string {
-  const cmp = compareSemver(installed, latest);
-  if (cmp === 'eq') return '';
-  const [i1] = installed.replace(/^v/, '').split('.').map(Number);
-  const [l1] = latest.replace(/^v/, '').split('.').map(Number);
-  if (l1 > i1) return 'major';
+// Determine update type for messaging
 function getUpdateType(installed: string, latest: string): string {
   const cmp = compareSemver(installed, latest);
   if (cmp === 'eq') return '';
   const [i1 = 0, i2 = 0] = installed.replace(/^v/, '').split('.').map(Number);
   const [l1 = 0, l2 = 0] = latest.replace(/^v/, '').split('.').map(Number);
   if (l1 > i1) return 'major';
   if (l2 > i2) return 'minor';
   return 'patch';
 }
-  return 'patch';
-}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function getUpdateType(installed: string, latest: string): string {
const cmp = compareSemver(installed, latest);
if (cmp === 'eq') return '';
const [i1] = installed.replace(/^v/, '').split('.').map(Number);
const [l1] = latest.replace(/^v/, '').split('.').map(Number);
if (l1 > i1) return 'major';
function getUpdateType(installed: string, latest: string): string {
const cmp = compareSemver(installed, latest);
if (cmp === 'eq') return '';
const [i1 = 0, i2 = 0] = installed.replace(/^v/, '').split('.').map(Number);
const [l1 = 0, l2 = 0] = latest.replace(/^v/, '').split('.').map(Number);
if (l1 > i1) return 'major';
if (l2 > i2) return 'minor';
return 'patch';
}
return 'patch';
}
function getUpdateType(installed: string, latest: string): string {
const cmp = compareSemver(installed, latest);
if (cmp === 'eq') return '';
const [i1 = 0, i2 = 0] = installed.replace(/^v/, '').split('.').map(Number);
const [l1 = 0, l2 = 0] = latest.replace(/^v/, '').split('.').map(Number);
if (l1 > i1) return 'major';
if (l2 > i2) return 'minor';
return 'patch';
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/version-check.ts` around lines 32 - 48, Remove the
duplicate/overlapping getUpdateType declaration and keep the corrected
implementation: the version that uses compareSemver, parses installed and latest
with default numeric parts (e.g., const [i1 = 0, i2 = 0], const [l1 = 0, l2 =
0]), returns 'major' if l1>i1, 'minor' if l2>i2, 'patch' otherwise, and returns
'' when compareSemver(...) === 'eq'; ensure only one getUpdateType function
(referenced symbol: getUpdateType) remains and the stray earlier/extra braces
and trailing return are removed so the file compiles.

Comment on lines +57 to +58
const data = await response.json() as { version: string };
const latestVersion = data.version;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add runtime validation for the npm registry response.

The response is cast to { version: string } but not validated. If the registry returns malformed JSON (missing .version, wrong type, or unexpected structure), the code will attempt to compare undefined or throw during access. While the outer try-catch prevents a crash, explicit validation improves security posture and makes failure modes clear.

🛡️ Proposed defensive check
     const data = await response.json() as { version: string };
+    if (!data || typeof data.version !== 'string') return;
     const latestVersion = data.version;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/version-check.ts` around lines 57 - 58, The code casts the registry
response to `{ version: string }` and assigns `const data`/`latestVersion`
without validating the shape; update the logic in version-check utilities (the
code around `const data = await response.json() as { version: string };` and
`const latestVersion = data.version;`) to perform runtime validation: parse the
JSON into an unknown, assert that `data` is an object and that `data.version`
exists and is a string (e.g., typeof check), and handle invalid responses by
logging a clear error and returning a safe fallback (or throwing a descriptive
error) instead of relying on the cast. Ensure the function's return type and
error handling reflect this change.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 17, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

An unexpected error occurred while generating fixes: Cannot open a stacked PR on a forked repository.

@utkarsh232005 utkarsh232005 merged commit 6530e83 into KDM-cli:main May 17, 2026
5 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation frontend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants