Skip to content

Refactor install script and add websocat support - #347

Merged
gnh1201 merged 8 commits into
masterfrom
dev
Nov 21, 2025
Merged

gnh1201 merged 8 commits into
masterfrom
dev

Conversation

@gnh1201

@gnh1201 gnh1201 commented Nov 21, 2025

Copy link
Copy Markdown
Owner

Refactored helper functions for clarity and consistency, including renaming and parameter changes. Added support for downloading and installing websocat, updated artifact URLs and extraction logic, and improved architecture-specific handling for optional tools. Enhanced output messages and error handling throughout the script.

Summary by Sourcery

Refactor the PowerShell install script for consistency and clarity, enhance logging and error handling, update per-architecture artifact management, and add support for downloading and installing websocat.

New Features:

  • Add websocat support with per-architecture download and extraction

Bug Fixes:

  • Fix typo in download failure message

Enhancements:

  • Rename and standardize helper functions and parameters for clarity
  • Improve output messages and error handling throughout the script
  • Update artifact URL assignments per architecture and adjust download/extraction order
  • Introduce skip messages for optional tools when not available on the current architecture

Summary by CodeRabbit

  • Refactor

    • Installation and extraction flow reorganized with clearer destination semantics, updated temporary workspace and cleanup, and final success message revised.
  • Chores

    • Standardized parameter names and attribute formatting across public commands; extraction and architecture-specific install logic simplified.
  • New Features

    • Runtime now prefers a bundled/default executable when present with architecture-based fallback; app data path casing normalized and version strings bumped.

✏️ Tip: You can customize this high-level summary in your review settings.

Refactored helper functions for clarity and consistency, including renaming and parameter changes. Added support for downloading and installing websocat, updated artifact URLs and extraction logic, and improved architecture-specific handling for optional tools. Enhanced output messages and error handling throughout the script.
@sourcery-ai

sourcery-ai Bot commented Nov 21, 2025

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Refactors installer script by standardizing helper functions (renaming parameters and generalizing extraction routines), introduces websocat support with per-architecture conditional download/extract, updates artifact URLs and handling, and enhances logging and error handling.

Sequence diagram for architecture-specific download and install including websocat

sequenceDiagram
    participant Script
    participant "Python"
    participant "curl"
    participant "YARA" as YARA
    participant "WAMR" as WAMR
    participant "websocat" as websocat
    participant "artifacts" as artifacts
    Script->>"Python": Download-File
    Script->>"curl": Download-File
    alt If YARAUrl exists
        Script->>YARA: Download-File
    else
        Script->>YARA: Skip download
    end
    alt If WamrUrl exists
        Script->>WAMR: Download-File
    else
        Script->>WAMR: Skip download
    end
    alt If WebsocatUrl exists
        Script->>websocat: Download-File
    else
        Script->>websocat: Skip download
    end
    alt If ArtifactsUrl exists
        Script->>artifacts: Download-File
    else
        Script->>artifacts: Skip download
    end
    Script->>"Python": Extract-CompressedFile
    Script->>"curl": Extract-CompressedFile
    alt If YARAUrl exists
        Script->>YARA: Extract-CompressedFile
    else
        Script->>YARA: Skip install
    end
    alt If WamrUrl exists
        Script->>WAMR: Extract-TarGzArchive
    else
        Script->>WAMR: Skip install
    end
    alt If WebsocatUrl exists
        Script->>websocat: Extract-CompressedFile
    else
        Script->>websocat: Skip install
    end
    alt If ArtifactsUrl exists
        Script->>artifacts: Extract-CompressedFile
    else
        Script->>artifacts: Skip install
    end
Loading

Class diagram for refactored helper functions in install script

classDiagram
    class Ensure_EmptyDirectory {
        +Path: string
        +Ensure directory exists
        +Remove file if exists
    }
    class Download_File {
        +Url: string
        +DestinationPath: string
        +Download file with error handling
    }
    class Extract_CompressedFile {
        +CompressedPath: string
        +DestinationDirectory: string
        +Extract ZIP/Archive
        +Flatten single root directory
        +Move multiple entries
    }
    class Extract_TarGzArchive {
        +ArchivePath: string
        +DestinationDirectory: string
        +Extract TAR.GZ using tar
    }
    Ensure_EmptyDirectory <|-- Extract_CompressedFile
    Ensure_EmptyDirectory <|-- Extract_TarGzArchive
Loading

File-Level Changes

Change Details Files
Refactor helper functions for consistency
  • Renamed Extract-Zip and Extract-TarGz to general Extract-CompressedFile and Extract-TarGzArchive
  • Standardized parameter names (e.g. -Destination to -DestinationPath) and formatting
  • Replaced temporary folder variables with clearer names
  • Unified debug logs and expanded error messages in extraction routines
  • Adjusted Ensure-EmptyDirectory comments and parameter spacing
afterInstall.ps1
Add conditional websocat support
  • Defined WebsocatUrl per architecture
  • Introduced $WebsocatCompressed variable and integrated into download phase
  • Added Extract-CompressedFile call for websocat in install phase
  • Included Write-Host messages for websocat URL and skipped cases
afterInstall.ps1
Update artifact URLs and extraction handling
  • Moved ArtifactsUrl assignments into architecture switch
  • Renamed artifacts temp variable to $ArtifactsCompressed
  • Conditionally download and extract artifacts under new logic
  • Changed artifacts extraction into bin folder using general extraction function
afterInstall.ps1
Improve architecture-specific optional tool logic
  • Unified skip logic and messaging for YARA, WAMR, websocat, artifacts
  • Wrapped optional downloads and installs in clear if/else blocks
  • Reordered download/extract sequence to handle websocat before artifacts
  • Ensured null URL variables trigger skip messages
afterInstall.ps1
Enhance output formatting and error handling
  • Standardized Write-Host indentation and labels
  • Improved error messages in catch blocks with exception details
  • Added debug output for Expand-Archive and tar commands
  • Refined final success message to improve clarity
afterInstall.ps1

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Nov 21, 2025

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@gnh1201 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 10 minutes and 15 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 77dc2b8 and a51e9ff.

📒 Files selected for processing (1)
  • setup.iss (1 hunks)

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Renames extraction helpers and multiple parameters in afterInstall.ps1, updates download/extraction call sites, adds architecture-aware conditional downloads/skips and adjusted temp/cleanup naming, and bumps/adjusts version strings and AppData path usage in lib/websocket.js, lib/system.js, and lib/chrome.js.

Changes

Cohort / File(s) Change Summary
PowerShell installer
afterInstall.ps1
Renamed extraction functions and parameters (Extract-ZipExtract-CompressedFile: ZipPathCompressedPath, DestDirDestinationDirectory; Extract-TarGzExtract-TarGzArchive: TarGzPathArchivePath). Renamed Download-File parameter DestinationDestinationPath. Adjusted Parameter attribute spacing, updated call sites and log prompts, changed temp extraction/cleanup naming, added arch-specific conditional downloads/skips for optional components (YARA, WAMR, websocat, artifacts), and updated final message to “Installation completed successfully.”
Websocket helper
lib/websocket.js
Added dependency on lib/file, added file-existence check for an app-data websocat.exe and used it when present; preserved arch-based bundled fallback when absent. Updated setBinPath logic and bumped exports.VERSIONINFO to v0.2.4 with minor text/capitalization tweak.
System helper
lib/system.js
Updated getAppDataDir path casing from \\WelsonJS to \\welsonjs and bumped exports.VERSIONINFO from 0.1.6 to 0.1.7.
Chrome helper
lib/chrome.js
Changed user-data directory fallback to use SYS.getAppDataDir() (centralized app data path) when setUserDataDir receives null. Bumped exports.VERSIONINFO from 0.5.3 to 0.5.4.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User
  participant Installer as afterInstall.ps1
  participant FS as Filesystem
  participant Net as Downloader
  participant WS as lib/websocket.js
  participant SYS as lib/system.js

  User->>Installer: run installer
  Installer->>FS: Ensure-EmptyDirectory(DestinationDirectory)
  Installer->>Net: Download-File(Url, DestinationPath)
  Net-->>Installer: file/archive
  alt compressed archive (zip)
    Installer->>Installer: Extract-CompressedFile(CompressedPath, DestinationDirectory)
  else tar.gz
    Installer->>Installer: Extract-TarGzArchive(ArchivePath, DestinationDirectory)
  end
  alt optional component supported by arch
    Installer->>Net: Download optional component
    Net-->>Installer: optional archive
    Installer->>Installer: Extract -> DestinationDirectory
  else not supported by arch
    Installer->>User: log "skipping optional component for this architecture"
  end
  Installer->>FS: cleanup temp extraction dirs
  WS->>FS: check app-data for websocat.exe (via SYS.getAppDataDir)
  alt websocat exists
    WS->>Installer: setBinPath(app-data websocat.exe)
  else not exists
    WS->>Installer: pick bundled 64/32-bit binary
  end
  SYS->>FS: return AppDataDir (note: path casing changed)
  Installer->>User: "Installation completed successfully."
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Verify all renamed functions/parameters are updated at every call site in afterInstall.ps1.
  • Confirm architecture gating logic and skip messages for optional components.
  • Validate temp extraction and cleanup paths match new DestinationDirectory naming.
  • Check lib/websocket.js file-existence check and fallback binary selection behavior.
  • Confirm lib/system.js AppData path casing change aligns with platform expectations and usages (and lib/chrome.js changes use SYS.getAppDataDir correctly).

Possibly related PRs

Suggested labels

enhancement

Poem

🐰
I hopped through scripts with clever paws,
Renamed the zips and fixed the laws,
Paths set tidy, bins in sight,
Optional bits skip by arch at night,
Installation done — I nibble a carrot bright 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main changes: refactoring helper functions in the install script and adding websocat support across the changeset.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@qodo-code-review

qodo-code-review Bot commented Nov 21, 2025

Copy link
Copy Markdown
Contributor

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🔴
Unsigned downloads execution

Description: The script downloads and extracts executables from unauthenticated HTTP(S) URLs (Python,
curl, YARA, WAMR, websocat, artifacts) without validating signatures or checksums,
allowing MITM or supply-chain tampering to execute arbitrary code during installation.
afterInstall.ps1 [191-241]

Referred Code
    # Python embeddable (x64)
    $PythonUrl    = "https://www.python.org/ftp/python/3.13.9/python-3.13.9-embeddable-amd64.zip"

    # curl (x64, mingw)
    $CurlUrl      = "https://curl.se/windows/latest.cgi?p=win64-mingw.zip"

    # YARA (x64)
    $YaraUrl      = "https://github.com/VirusTotal/yara/releases/download/v4.5.5/yara-4.5.5-2368-win64.zip"

    # WAMR (x64)
    $WamrUrl      = "https://github.com/bytecodealliance/wasm-micro-runtime/releases/download/WAMR-2.4.3/iwasm-2.4.3-x86_64-windows-2022.tar.gz"

    # websocat (x64)
    $WebsocatUrl  = "https://catswords.blob.core.windows.net/welsonjs/websocat-1.14.0.x86_64-pc-windows-gnu.zip"

    # WelsonJS binary artifacts (x86 compatible)
    $ArtifactsUrl = "https://catswords.blob.core.windows.net/welsonjs/artifacts.zip"
}

"arm64" {
    # Python embeddable (ARM64)


 ... (clipped 30 lines)
Archive traversal risk

Description: Archives from untrusted remote sources are extracted and their contents moved into
application directories without path sanitization or validation, which could allow archive
traversal (e.g., crafted entries with .. or absolute paths) to overwrite unintended files
if Expand-Archive/tar extraction is not constrained or validated.
afterInstall.ps1 [333-368]

Referred Code
Extract-CompressedFile -CompressedPath $PythonCompressed -DestinationDirectory (Join-Path $TargetDir "python")

# curl
Extract-CompressedFile -CompressedPath $CurlCompressed   -DestinationDirectory (Join-Path $TargetDir "curl")

# YARA
if ($YaraUrl) {
    Extract-CompressedFile -CompressedPath $YaraCompressed -DestinationDirectory (Join-Path $TargetDir "yara")
}
else {
    Write-Host "[*] YARA installation skipped on this architecture."
}

# WAMR (TAR.GZ)
if ($WamrUrl) {
    Extract-TarGzArchive -ArchivePath $WamrArchive -DestinationDirectory (Join-Path $TargetDir "wamr")
}
else {
    Write-Host "[*] WAMR installation skipped on this architecture."
}



 ... (clipped 15 lines)
Incomplete artifact reuse

Description: Error message typo "[FATAL] Download phase faled." aside, failures exit with code 1 after
partial downloads but previously downloaded files remain in $TmpDir and may be used later
if the script is re-run, risking use of incomplete or attacker-swapped artifacts without
integrity verification.
afterInstall.ps1 [282-320]

Referred Code
Download-File -Url $PythonUrl -DestinationPath $PythonCompressed

# curl
Download-File -Url $CurlUrl -DestinationPath $CurlCompressed

# YARA (optional)
if ($YaraUrl) {
    Download-File -Url $YaraUrl -DestinationPath $YaraCompressed
}
else
{
    Write-Host "[*] YARA download skipped on this architecture."
}

# WAMR (optional)
if ($WamrUrl) {
    Download-File -Url $WamrUrl -DestinationPath $WamrArchive
}
else
{
    Write-Host "[*] WAMR download skipped on this architecture."


 ... (clipped 18 lines)
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

🔴
Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
No integrity checks: External downloads are performed and executed without integrity verification (e.g.,
checksums/signatures) or strict URL validation, which risks tampering and violates
security-first input handling.

Referred Code
try {
    # Python
    Download-File -Url $PythonUrl -DestinationPath $PythonCompressed

    # curl
    Download-File -Url $CurlUrl -DestinationPath $CurlCompressed

    # YARA (optional)
    if ($YaraUrl) {
        Download-File -Url $YaraUrl -DestinationPath $YaraCompressed
    }
    else
    {
        Write-Host "[*] YARA download skipped on this architecture."
    }

    # WAMR (optional)
    if ($WamrUrl) {
        Download-File -Url $WamrUrl -DestinationPath $WamrArchive
    }
    else


 ... (clipped 69 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
No audit logs: The script performs downloads, extractions, and installations without emitting structured
audit logs tying actions to a user ID and outcome beyond console messages, which may not
satisfy comprehensive audit trail requirements.

Referred Code
# ================================
# DOWNLOAD FILES (websocat before artifacts)
# ================================
$PythonCompressed    = Join-Path $TmpDir "python.zip"
$CurlCompressed      = Join-Path $TmpDir "curl.zip"
$YaraCompressed      = Join-Path $TmpDir "yara.zip"
$WamrArchive         = Join-Path $TmpDir "wamr.tar.gz"
$WebsocatCompressed  = Join-Path $TmpDir "websocat.zip"
$ArtifactsCompressed = Join-Path $TmpDir "artifacts.zip"

try {
    # Python
    Download-File -Url $PythonUrl -DestinationPath $PythonCompressed

    # curl
    Download-File -Url $CurlUrl -DestinationPath $CurlCompressed

    # YARA (optional)
    if ($YaraUrl) {
        Download-File -Url $YaraUrl -DestinationPath $YaraCompressed
    }


 ... (clipped 91 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Generic fatal errors: Catch blocks emit generic messages and then exit without structured context (e.g., which
file/URL/paths failed in a machine-parseable way), and downloads/extractions rely on URLs
without explicit validation of inputs or checksum verification.

Referred Code
}
catch {
    Write-Host "[FATAL] Download phase faled."
    Write-Host $_.Exception.Message
    exit 1
}


# ================================
# EXTRACT / INSTALL (websocat before artifacts)
# ================================
try {
    # Python
    Extract-CompressedFile -CompressedPath $PythonCompressed -DestinationDirectory (Join-Path $TargetDir "python")

    # curl
    Extract-CompressedFile -CompressedPath $CurlCompressed   -DestinationDirectory (Join-Path $TargetDir "curl")

    # YARA
    if ($YaraUrl) {
        Extract-CompressedFile -CompressedPath $YaraCompressed -DestinationDirectory (Join-Path $TargetDir "yara")


 ... (clipped 34 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status:
Unstructured logs: Logging is plain console text without structured format, which may hinder auditing; while
no sensitive data is printed, URLs and paths are echoed and there is no guarantee that
secrets won’t be logged if included in URLs.

Referred Code
Write-Host "[*] Python URL    : $PythonUrl"
Write-Host "[*] curl URL      : $CurlUrl"
if ($YaraUrl) {
    Write-Host "[*] YARA URL      : $YaraUrl"
} else {
    Write-Host "[*] YARA          : skipped on this architecture"
}
if ($WamrUrl) {
    Write-Host "[*] WAMR URL      : $WamrUrl"
} else {
    Write-Host "[*] WAMR          : skipped on this architecture"
}
if ($WebsocatUrl) {
    Write-Host "[*] websocat URL  : $WebsocatUrl"
} else {
    Write-Host "[*] websocat      : skipped on this architecture"
}
if ($ArtifactsUrl) {
    Write-Host "[*] artifacts URL : $ArtifactsUrl"
} else {
    Write-Host "[*] artifacts     : skipped on this architecture"


 ... (clipped 108 lines)

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@sourcery-ai sourcery-ai Bot left a comment

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.

Hey there - I've reviewed your changes - here's some feedback:

  • The repeated pattern of checking optional URLs and invoking Download-File/Extract could be refactored into a data-driven loop or helper to reduce boilerplate and ensure consistent skip messages.
  • Correct the typo in the FATAL download error message (“faled” → “failed”) to prevent confusion when diagnosing failures.
  • Consider validating each download URL before starting the download phase to catch misconfigurations early and surface clear errors.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The repeated pattern of checking optional URLs and invoking Download-File/Extract could be refactored into a data-driven loop or helper to reduce boilerplate and ensure consistent skip messages.
- Correct the typo in the FATAL download error message (“faled” → “failed”) to prevent confusion when diagnosing failures.
- Consider validating each download URL before starting the download phase to catch misconfigurations early and surface clear errors.

## Individual Comments

### Comment 1
<location> `afterInstall.ps1:322` </location>
<code_context>
 }
 catch {
-    Write-Host "[FATAL] Download phase failed."
+    Write-Host "[FATAL] Download phase faled."
+    Write-Host $_.Exception.Message
     exit 1
</code_context>

<issue_to_address>
**issue (typo):** Typo in error message: 'faled' should be 'failed'.

Please update the error message to use the correct spelling.

```suggestion
    Write-Host "[FATAL] Download phase failed."
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread afterInstall.ps1 Outdated
@qodo-code-review

qodo-code-review Bot commented Nov 21, 2025

Copy link
Copy Markdown
Contributor

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Adopt a data-driven installation approach

Refactor the repetitive download and extraction logic for optional tools into a
data-driven approach. Define tools in a configuration list and process them
within a loop to improve scalability and maintainability.

Examples:

afterInstall.ps1 [287-319]
    # YARA (optional)
    if ($YaraUrl) {
        Download-File -Url $YaraUrl -DestinationPath $YaraCompressed
    }
    else
    {
        Write-Host "[*] YARA download skipped on this architecture."
    }

    # WAMR (optional)

 ... (clipped 23 lines)
afterInstall.ps1 [338-368]
    # YARA
    if ($YaraUrl) {
        Extract-CompressedFile -CompressedPath $YaraCompressed -DestinationDirectory (Join-Path $TargetDir "yara")
    }
    else {
        Write-Host "[*] YARA installation skipped on this architecture."
    }

    # WAMR (TAR.GZ)
    if ($WamrUrl) {

 ... (clipped 21 lines)

Solution Walkthrough:

Before:

# Download phase
if ($YaraUrl) {
    Download-File -Url $YaraUrl -DestinationPath $YaraCompressed
} else {
    Write-Host "[*] YARA download skipped..."
}
if ($WamrUrl) {
    Download-File -Url $WamrUrl -DestinationPath $WamrArchive
} else {
    Write-Host "[*] WAMR download skipped..."
}
# ... more blocks for websocat, artifacts

# Extraction phase
if ($YaraUrl) {
    Extract-CompressedFile -CompressedPath $YaraCompressed ...
} else {
    Write-Host "[*] YARA installation skipped..."
}
# ... more blocks for other tools

After:

$tools = @(
    @{ Name = "YARA"; Url = $YaraUrl; Type = "zip"; ... },
    @{ Name = "WAMR"; Url = $WamrUrl; Type = "targz"; ... },
    @{ Name = "websocat"; Url = $WebsocatUrl; Type = "zip"; ... }
)

# Download phase
foreach ($tool in $tools) {
    if ($tool.Url) {
        Download-File -Url $tool.Url -DestinationPath $tool.LocalPath
    } else {
        Write-Host "[*] $($tool.Name) download skipped..."
    }
}

# Extraction phase
foreach ($tool in $tools) {
    if ($tool.Url) {
        # ... logic to call correct extraction function
    }
}
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies significant code duplication in the download and extraction logic for optional tools, and proposing a data-driven approach would greatly improve the script's scalability and maintainability.

High
Possible issue
Improve error handling for exceptions
Suggestion Impact:The catch block was updated to type-check $_ and print either Exception.Message or the raw value, exactly as suggested.

code diff:

@@ -369,7 +369,11 @@
 }
 catch {
     Write-Host "[FATAL] Extraction/installation phase failed."
-    Write-Host $_.Exception.Message
+    if ($_ -is [System.Exception]) {
+        Write-Host $_.Exception.Message
+    } else {
+        Write-Host $_
+    }
     exit 1

Modify the catch block to handle both exception objects and simple string errors
by checking the type of $ before attempting to access $.Exception.Message.

afterInstall.ps1 [370-374]

 catch {
     Write-Host "[FATAL] Extraction/installation phase failed."
-    Write-Host $_.Exception.Message
+    if ($_ -is [System.Exception]) {
+        Write-Host $_.Exception.Message
+    } else {
+        Write-Host $_
+    }
     exit 1
 }

[Suggestion processed]

Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a bug where a thrown string from Extract-TarGzArchive would cause the final catch block to suppress the actual error message, and provides a robust fix.

Medium
Ensure hidden files are extracted
Suggestion Impact:The commit added the -Force parameter to the Get-ChildItem call, ensuring hidden files are included during flattening.

code diff:

-        $innerItems = Get-ChildItem -LiteralPath $entries[0].FullName
+        $innerItems = Get-ChildItem -LiteralPath $entries[0].FullName -Force

Add the -Force parameter to the Get-ChildItem call within the
Extract-CompressedFile function to ensure hidden files and directories are moved
when flattening an archive with a single root directory.

afterInstall.ps1 [116-123]

 if ($entries.Count -eq 1 -and $entries[0].PSIsContainer) {
     # Single root directory inside archive -> flatten
     Write-Host "[*] Archive has a single root directory. Flattening..."
-    $innerItems = Get-ChildItem -LiteralPath $entries[0].FullName
+    $innerItems = Get-ChildItem -LiteralPath $entries[0].FullName -Force
     foreach ($item in $innerItems) {
         Move-Item -LiteralPath $item.FullName -Destination $DestinationDirectory -Force
     }
 }

[Suggestion processed]

Suggestion importance[1-10]: 7

__

Why: The suggestion correctly points out that hidden files are not being moved, which could lead to an incomplete installation, and proposes adding the -Force parameter to Get-ChildItem to fix it.

Medium
Fix typo in error message
Suggestion Impact:The commit corrected the typo in the fatal download phase message from "faled" to "failed" and also enhanced exception output handling.

code diff:

-    Write-Host "[FATAL] Download phase faled."
-    Write-Host $_.Exception.Message
+    Write-Host "[FATAL] Download phase failed."
+    if ($_ -is [System.Exception]) {
+        Write-Host $_.Exception.Message
+    } else {
+        Write-Host $_
+    }
     exit 1

Correct the typo "faled" to "failed" in the fatal error message for the download
phase to improve error reporting clarity.

afterInstall.ps1 [321-325]

 catch {
-    Write-Host "[FATAL] Download phase faled."
+    Write-Host "[FATAL] Download phase failed."
     Write-Host $_.Exception.Message
     exit 1
 }

[Suggestion processed]

Suggestion importance[1-10]: 3

__

Why: The suggestion correctly identifies and fixes a typo in an error message, which improves the script's professionalism and clarity during failures.

Low
Learned
best practice
Validate inputs before download

Validate that $Url is an absolute HTTP(S) URL and $DestinationPath is a valid
non-empty path before invoking the download, and return early with a clear error
if invalid.

afterInstall.ps1 [53-75]

 function Download-File {
     param(
         [Parameter(Mandatory = $true)]
         [string]$Url,
         [Parameter(Mandatory = $true)]
         [string]$DestinationPath
     )
+
+    if ([string]::IsNullOrWhiteSpace($Url) -or -not ($Url -match '^https?://')) {
+        throw "Invalid URL: '$Url'"
+    }
+    if ([string]::IsNullOrWhiteSpace($DestinationPath)) {
+        throw "Invalid destination path."
+    }
 
     Write-Host "[*] Downloading file..."
     Write-Host "    URL : $Url"
     Write-Host "    OUT : $DestinationPath"
 
     try {
         Invoke-WebRequest -Uri $Url -OutFile $DestinationPath -UseBasicParsing -ErrorAction Stop
         Write-Host "[OK] Download completed."
         Write-Host ""
     }
     catch {
         Write-Host "[ERROR] Failed to download: $Url"
         Write-Host $_.Exception.Message
         throw
     }
 }
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why:
Relevant best practice - Prefer specific input validation and early returns to guard against invalid, NaN/Infinity, null, or empty inputs before computation or member access.

Low
  • Update

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
afterInstall.ps1 (1)

271-271: Clarify the ordering requirement or remove the comment.

The comments at lines 271 and 329 state "websocat before artifacts" but no explicit dependency between these components is evident in the code. If there's a specific reason websocat must be downloaded/installed before artifacts, please document it. Otherwise, consider removing these comments as they may cause confusion.

Also applies to: 329-329

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4f6040d and ef966df.

📒 Files selected for processing (1)
  • afterInstall.ps1 (5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Sourcery review
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (4)
afterInstall.ps1 (4)

34-176: LGTM! Well-executed refactoring of helper functions.

The function renames and parameter name changes significantly improve code clarity and follow PowerShell naming conventions more closely. All usages have been updated consistently throughout the script.


331-374: LGTM! Extraction and installation logic is well-structured.

The conditional extraction logic for optional components is clear and consistent with the download phase. All function calls correctly use the refactored function names and parameters.


229-229: No issues found. The URL is valid and accessible.

The curl URL at line 229 returns an HTTP 302 redirect with proper headers, confirming the file exists at SourceForge. The date "2025-11-09" in the filename is not in the future—relative to the current system date of November 21, 2025, it is in the past. The original review comment's concern about the date was based on an incorrect assumption. The code is correct as written.


192-208: All URLs verified as accessible and valid.

The verification confirms all download URLs return successful responses: Python, curl, YARA, WAMR, websocat, and artifacts URLs are all accessible with appropriate HTTP 200 or 302 responses. Content-Length headers confirm file availability for Azure blob storage resources. No issues detected.

Comment thread afterInstall.ps1 Outdated
Comment thread afterInstall.ps1
Co-authored-by: qodo-merge-pro[bot] <151058649+qodo-merge-pro[bot]@users.noreply.github.com>
Comment thread afterInstall.ps1
Co-authored-by: qodo-merge-pro[bot] <151058649+qodo-merge-pro[bot]@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

♻️ Duplicate comments (1)
afterInstall.ps1 (1)

322-322: Fix typo in error message.

🧹 Nitpick comments (2)
afterInstall.ps1 (2)

287-319: Consider abstracting repetitive conditional download logic.

The conditional download pattern is repeated for YARA, WAMR, websocat, and artifacts. While the current implementation is correct and clear, you could reduce duplication with a helper function.

Example approach:

function Download-Optional {
    param(
        [Parameter(Mandatory = $true)]
        [string]$Name,
        [Parameter(Mandatory = $false)]
        [string]$Url,
        [Parameter(Mandatory = $true)]
        [string]$DestinationPath
    )
    
    if ($Url) {
        Download-File -Url $Url -DestinationPath $DestinationPath
    }
    else {
        Write-Host "[*] $Name download skipped on this architecture."
    }
}

Then use it as:

Download-Optional -Name "YARA" -Url $YaraUrl -DestinationPath $YaraCompressed
Download-Optional -Name "WAMR" -Url $WamrUrl -DestinationPath $WamrArchive
Download-Optional -Name "websocat" -Url $WebsocatUrl -DestinationPath $WebsocatCompressed
Download-Optional -Name "artifacts" -Url $ArtifactsUrl -DestinationPath $ArtifactsCompressed

338-368: Conditional extraction logic is correct; consider similar abstraction.

The extraction phase correctly mirrors the download phase with proper conditional logic. Similar to the download phase, this could benefit from the same abstraction pattern if you choose to refactor.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ef966df and f2f16d7.

📒 Files selected for processing (1)
  • afterInstall.ps1 (5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Sourcery review
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (2)
afterInstall.ps1 (2)

34-176: Helper function refactoring looks good.

The renaming and parameter standardization improves clarity and consistency. The extraction logic correctly handles both single-root and multi-root archives, and the -Force flag at line 119 ensures hidden files are extracted.


380-380: Improved success message is more accurate.

The updated message "Installation completed successfully." is more appropriate than "All tools installed successfully." since some optional tools may be skipped based on architecture.

Comment thread afterInstall.ps1
# WAMR (x64 only)
$WamrUrl = "https://github.com/bytecodealliance/wasm-micro-runtime/releases/download/WAMR-2.4.3/iwasm-2.4.3-x86_64-windows-2022.tar.gz"
# websocat (x64)
$WebsocatUrl = "https://catswords.blob.core.windows.net/welsonjs/websocat-1.14.0.x86_64-pc-windows-gnu.zip"

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 | 🟡 Minor

🧩 Analysis chain

Verify websocat download URLs exist and are accessible.

The websocat URLs point to Azure Blob Storage. Ensure these URLs are valid and publicly accessible.

Also applies to: 238-238


🏁 Script executed:

#!/bin/bash
# Description: Verify websocat download URLs are accessible

echo "Testing x64 websocat URL..."
curl -I "https://catswords.blob.core.windows.net/welsonjs/websocat-1.14.0.x86_64-pc-windows-gnu.zip" 2>&1 | head -n 1

echo ""
echo "Testing x86 websocat URL..."
curl -I "https://catswords.blob.core.windows.net/welsonjs/websocat-1.14.0.i686-pc-windows-gnu.zip" 2>&1 | head -n 1

Length of output: 216


Replace custom Azure Blob Storage URLs with official GitHub release URLs for improved reliability.

The websocat binaries are being downloaded from a custom Azure Blob Storage account (catswords.blob.core.windows.net) that cannot be verified to exist or be publicly accessible. Official websocat 1.14.0 binaries are available on GitHub releases:

  • x64: https://github.com/vi/websocat/releases/download/v1.14.0/websocat.x86_64-pc-windows-gnu.exe
  • x86: https://github.com/vi/websocat/releases/download/v1.14.0/websocat.i686-pc-windows-gnu.exe

Consider updating lines 204 and 238 to use the official GitHub URLs for better reliability and maintainability, or document why the custom blob storage is necessary.

🤖 Prompt for AI Agents
In afterInstall.ps1 around lines 204 and 238, the script downloads websocat from
a custom Azure Blob Storage URL which is not verifiable; replace those blob URLs
with the official GitHub release URLs for websocat v1.14.0 (use the x64 GitHub
URL for the x86_64 target and the i686 GitHub URL for the x86 target) or, if the
custom blob is required, add a comment explaining why and ensure the blob is
publicly accessible and trustworthy; update the two lines accordingly so they
point to the official GitHub release assets (or include the documented
justification).

Comment thread afterInstall.ps1 Outdated
Comment on lines +272 to +323
catch {
Write-Host "[FATAL] Download phase failed."
Write-Host "[FATAL] Download phase faled."
Write-Host $_.Exception.Message

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.

Suggestion: Fix typo in error message

Suggested change
catch {
Write-Host "[FATAL] Download phase failed."
Write-Host "[FATAL] Download phase faled."
Write-Host $_.Exception.Message
catch {
Write-Host "[FATAL] Download phase failed."
Write-Host $_.Exception.Message

Enhanced error reporting by checking if caught errors are System.Exception and printing the appropriate message. This provides clearer output for both exception and non-exception error types during file download, extraction, and main script execution.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (2)
afterInstall.ps1 (2)

81-87: Function naming: "Extract-CompressedFile" is too generic for ZIP-specific functionality.

The function is renamed from Extract-Zip to Extract-CompressedFile, but it specifically uses Expand-Archive, which only works with ZIP files in PowerShell. The generic name "CompressedFile" suggests it could handle other formats (e.g., RAR, 7z), but it cannot.

Consider either:

  1. Reverting to Extract-Zip or using Extract-ZipArchive for consistency with Extract-TarGzArchive.
  2. If a generic name is desired, document in comments that only ZIP format is supported.

378-384: Clarify artifacts extraction to bin/ directory.

Unlike other components that extract to their own subdirectories (e.g., python/, curl/, yara/), artifacts extract directly to the bin/ directory. This suggests the artifacts.zip contains executable binaries that should be available in a common bin path.

Consider adding a comment explaining that artifacts contain shared binaries to make the directory choice clear.

     # artifacts
     if ($ArtifactsUrl) {
+        # Extract WelsonJS binary artifacts to shared bin/ directory
         Extract-CompressedFile -CompressedPath $ArtifactsCompressed -DestinationDirectory (Join-Path $TargetDir "bin")
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9b6fa4d and 49ebde6.

📒 Files selected for processing (1)
  • afterInstall.ps1 (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Sourcery review
🔇 Additional comments (6)
afterInstall.ps1 (6)

72-76: LGTM: Improved error handling with exception type check.

The error handling now checks whether $_ is a System.Exception before accessing .Exception.Message, preventing potential errors if $_ is not an exception object.


127-127: LGTM: Hidden files are now included in extraction.

The addition of the -Force parameter to Get-ChildItem ensures hidden files are extracted from the archive.


292-332: LGTM: Clean conditional download logic with consistent skip messaging.

The download phase correctly handles optional components with architecture-aware conditional logic and provides clear skip messages when components are not available for the current architecture.


400-400: LGTM: Updated success message is more accurate.

The message "Installation completed successfully." is more appropriate than "All tools installed successfully." since optional components may be skipped based on architecture.


219-219: Artifacts.zip URL is publicly accessible and operational.

Verification confirms the Azure Blob Storage URL returns HTTP 200 OK with a valid blob file (37.5 MB). The artifacts download for both architectures is currently functional.


241-241: The curl URL is correct—no changes needed.

The latest curl for Windows x86 on SourceForge is curl 8.17.0, which was uploaded on 2025-11-09. The date in the URL is not a typo; it reflects the actual upload date of the current latest version.

Comment thread afterInstall.ps1
Refactored default WebSocket executable path selection to check for a user-specific installation before falling back to architecture-based defaults. Updated comments for clarity and incremented version to 0.2.4.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lib/websocket.js (1)

23-39: Default path casing must match afterInstall.ps1 configuration.

The enhanced logic is sound, but verification reveals a path casing inconsistency. afterInstall.ps1 installs websocat to %APPDATA%\welsonjs\websocat, while websocket.js expects %APPDATA%\WelsonJS\websocat (as returned by SYS.getAppDataDir()). While Windows resolves this due to case-insensitivity, the inconsistent casing creates a maintenance issue.

Fix the casing inconsistency:

Either update afterInstall.ps1 to use "WelsonJS" (to match SYS.getAppDataDir()), or update SYS.getAppDataDir() to use lowercase "welsonjs". Recommend standardizing on "WelsonJS" since it's already hardcoded in SYS.getAppDataDir().

Also apply the modernization improvements:

  • Use const instead of var for default_websocat_path and arch (lines 27, 31)
  • Use template literals for Windows paths to improve readability
🧹 Nitpick comments (1)
lib/websocket.js (1)

16-16: Prefer const for module imports.

The FILE module import should use const instead of var for consistency with modern JavaScript best practices, as module imports are immutable constants.

Apply this diff:

-var FILE = require("lib/file");
+const FILE = require("lib/file");
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 49ebde6 and fd3a34f.

📒 Files selected for processing (1)
  • lib/websocket.js (3 hunks)
🧰 Additional context used
🪛 GitHub Check: SonarCloud Code Analysis
lib/websocket.js

[failure] 27-27: Unexpected var, use let or const instead.

See more on https://sonarcloud.io/project/issues?id=gnh1201_welsonjs&issues=AZql2aKBdloVWrH34fWh&open=AZql2aKBdloVWrH34fWh&pullRequest=347


[warning] 27-27: String.raw should be used to avoid escaping \.

See more on https://sonarcloud.io/project/issues?id=gnh1201_welsonjs&issues=AZql2aKBdloVWrH34fWi&open=AZql2aKBdloVWrH34fWi&pullRequest=347

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Sourcery review
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (2)
lib/websocket.js (2)

1-13: Documentation improvements enhance clarity.

The updated header comments add a helpful compatibility note directing users to the WelsonJS Launcher for more fine-grained WebSocket control, while clarifying this file exists for backward compatibility. The references provide useful context.


79-79: Appropriate version bump for new functionality.

The version increment from 0.2.3 to 0.2.4 correctly reflects the enhanced setBinPath functionality. The minor text adjustments improve consistency.

Changed the app data directory from 'WelsonJS' to 'welsonjs' for consistency. Bumped VERSIONINFO to 0.1.7 to reflect the update.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fd3a34f and 5d907e3.

📒 Files selected for processing (1)
  • lib/system.js (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Sourcery review
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (1)
lib/system.js (1)

227-227: LGTM!

The version bump from 0.1.6 to 0.1.7 is appropriate for this release.

Comment thread lib/system.js

function getAppDataDir() {
return getEnvString("APPDATA") + "\\WelsonJS";
return getEnvString("APPDATA") + "\\welsonjs";

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

🧩 Analysis chain

Verify migration strategy for existing installations.

The AppData path case change from "\\WelsonJS" to "\\welsonjs" will cause the application to use a different directory. On Windows, although the filesystem is case-insensitive for lookups, it is case-preserving, meaning existing installations with data in %APPDATA%\WelsonJS will not automatically be found at %APPDATA%\welsonjs. This could lead to:

  • Loss of user data, configurations, or cached files
  • Breaking existing installations without a clear migration path
  • Silent failures if the code expects to find previously stored data

Ensure that a migration strategy is in place (e.g., checking for the old directory and copying/moving data to the new location) or document this as a breaking change requiring manual user action.

Run the following script to verify what data is stored in this directory and if migration logic exists:


🏁 Script executed:

#!/bin/bash
# Description: Check usage of getAppDataDir and verify if migration logic exists

# Search for all usages of getAppDataDir to understand what data is stored
echo "=== Searching for getAppDataDir usage ==="
rg -n "getAppDataDir" -A 3 -B 1

# Search for any migration logic or references to the old "WelsonJS" path
echo -e "\n=== Searching for references to old WelsonJS path ==="
rg -n "WelsonJS" --type js

# Search for any code that might handle directory migration
echo -e "\n=== Searching for potential migration logic ==="
rg -n -i "(migrate|migration|old.*path|rename.*dir)" --type js

Length of output: 301835


Fix path case inconsistency and provide migration guidance for AppData directory change.

The verification confirms a critical inconsistency: lib/chrome.js:114 contains a hardcoded reference to the OLD path %APPDATA%\WelsonJS\, while lib/system.js:41 changes the path to lowercase \welsonjs. This creates mixed-case behavior where:

  1. Direct inconsistency: Modules using getAppDataDir() (http.js, ovftool.js, python3.js, wamr.js, websocket.js) will use the new path \welsonjs, but chrome.js bypasses this by hardcoding the old uppercase path
  2. No migration logic: The script found no code handling the path transition for existing installations
  3. Breaking change: On Windows case-preserving filesystems, existing data in %APPDATA%\WelsonJS will not be found

Required fixes:

  • lib/chrome.js:114: Update hardcoded path from "\\WelsonJS\\" to use SYS.getAppDataDir() + "\\" for consistency
  • Add migration logic (e.g., in system initialization): Check if old path exists, and if new path doesn't, copy/move data from %APPDATA%\WelsonJS to %APPDATA%\welsonjs
  • Document this as a breaking change in release notes if no migration is provided
🤖 Prompt for AI Agents
In lib/system.js around line 41 and lib/chrome.js at line 114, there is a case
mismatch between the new AppData path "\\welsonjs" and the hardcoded
"\\WelsonJS\\" in chrome.js which breaks installs on case-preserving Windows
filesystems; update chrome.js to stop hardcoding the path and call
SYS.getAppDataDir() + "\\" instead, and in system initialization add migration
logic that checks if the old path (%APPDATA%\WelsonJS) exists and the new path
(%APPDATA%\welsonjs) does not, then atomically move or copy the contents
(preserving permissions and handling errors) to the new directory with safe
retries and logging; if you choose not to implement automatic migration, add an
explicit release-note entry marking this as a breaking change and instruct users
how to manually move their data.

Replaced usage of SYS.getEnvString("APPDATA") with SYS.getAppDataDir() for determining the user data directory. Updated VERSIONINFO to 0.5.4 to reflect the change.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5d907e3 and 77dc2b8.

📒 Files selected for processing (1)
  • lib/chrome.js (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Sourcery review
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (1)
lib/chrome.js (1)

1501-1501: LGTM! Version bump is appropriate.

The version increment from 0.5.3 to 0.5.4 is appropriate given the functional changes to the user data directory management.

Comment thread lib/chrome.js
this.userDataDir = dirname;
} else {
this.userDataDir = SYS.getEnvString("APPDATA") + "\\WelsonJS\\" + publisherName.get() + "_user_profile";
this.userDataDir = SYS.getAppDataDir() + "\\" + publisherName.get() + "_user_profile";

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

🧩 Analysis chain

Verify the SYS.getAppDataDir() implementation and assess backward compatibility.

The change from a hardcoded environment variable path to SYS.getAppDataDir() centralizes path management, which improves maintainability. However, please verify:

  1. That SYS.getAppDataDir() is correctly implemented in lib/system.js and returns the expected path
  2. Whether this creates a breaking change for existing users with profiles in the old location
  3. If migration is needed, ensure users are informed or an automatic migration path exists

Run the following script to verify the implementation:


🏁 Script executed:

#!/bin/bash
# Verify SYS.getAppDataDir() implementation and usage

# Check if getAppDataDir is defined in system.js
echo "Checking for getAppDataDir implementation:"
rg -n -A 5 "getAppDataDir\s*[:=]?\s*function" --type=js

# Check all usages of getAppDataDir in the codebase
echo -e "\nChecking all usages of getAppDataDir:"
rg -n "getAppDataDir\s*\(\)" --type=js -C 2

Length of output: 1955


🏁 Script executed:

#!/bin/bash
# Verify SYS object export and getAppDataDir membership

# Check system.js exports and SYS object definition
echo "Checking system.js for SYS object definition and exports:"
rg -n "module\.exports|exports\[|SYS\s*[=:]|SYS\." lib/system.js -A 2 -B 2

# Check how chrome.js imports/uses SYS
echo -e "\nChecking chrome.js imports and SYS usage:"
head -30 lib/chrome.js | rg -n "require|SYS|system"

# Check if there's any migration or backward compatibility code
echo -e "\nSearching for migration or backward compatibility logic:"
rg -n "migration|backward|compat|profile.*path|userData" --type=js -i | head -20

Length of output: 1938


🏁 Script executed:

#!/bin/bash
# Verify SYS object export and getAppDataDir membership

# Check system.js exports and SYS object definition
echo "Checking system.js for SYS object definition and exports:"
rg -n "module\.exports|exports\[|SYS\s*[=:]|function.*getAppDataDir" lib/system.js -A 2 -B 1

# Check how chrome.js imports/uses SYS and first 50 lines
echo -e "\nChecking chrome.js imports and initial setup:"
head -50 lib/chrome.js | rg -n "require|SYS"

# Check if there's old userDataDir logic or environment variable fallback
echo -e "\nSearching for old userDataDir patterns or LOCALAPPDATA:"
rg -n "LOCALAPPDATA|USERPROFILE|userDataDir" lib/chrome.js -i -B 2 -A 2

Length of output: 6613


🏁 Script executed:

#!/bin/bash
# Verify getAppDataDir export and check previous implementation

# Check system.js module.exports
echo "Checking system.js module.exports:"
rg -n "module\.exports\s*[={]" lib/system.js -A 20

# Check if getAppDataDir is explicitly exported
echo -e "\nSearching for getAppDataDir in exports:"
rg -n "getAppDataDir" lib/system.js

# Get git diff to see what line 114 was before
echo -e "\nSearching git history for chrome.js changes:"
git log --oneline -n 5 -- lib/chrome.js 2>/dev/null || echo "Git history not available"

# Check the actual git diff for the specific line
echo -e "\nChecking git diff for lib/chrome.js:"
git diff HEAD~1 lib/chrome.js 2>/dev/null | head -100 || echo "Git diff not available"

Length of output: 1468


Fix path case-sensitivity to maintain backward compatibility.

The verification confirms SYS.getAppDataDir() is properly implemented and exported. However, the change introduces a breaking change: the git diff reveals the previous implementation used "\\WelsonJS\\" (capital letters), while getAppDataDir() returns "\\welsonjs" (lowercase). This creates two different paths:

  • Old: APPDATA\WelsonJS\<publisherName>_user_profile
  • New: APPDATA\welsonjs\<publisherName>_user_profile

Existing user profiles will not be found by the new code. Either align the case in getAppDataDir() to return "\\WelsonJS\\", or add migration logic to move profiles from the old location to the new location.

🤖 Prompt for AI Agents
In lib/chrome.js around line 114, the assignment of userDataDir uses
SYS.getAppDataDir() which returns a lowercase path ("\\welsonjs") but older
installs used a capitalized "\\WelsonJS\\", causing user profiles to be missed;
fix by either (A) normalizing to the legacy casing: call a helper that returns
the legacy-cased base (or adjust getAppDataDir() to return "\\WelsonJS\\") so
userDataDir continues to point to the original folder, or (B) implement
migration: detect existence of the old-path
(APPDATA\WelsonJS\<publisher>_user_profile) and if present move/rename its
contents to the new-path returned by getAppDataDir(), ensuring permissions and
atomicity, and log the migration outcome; pick one approach and apply it
consistently across startup code.

Changed the registry command for opening scripts to reference WelsonJS.Launcher.exe in the 'bin' subdirectory instead of the root application directory. This ensures the correct executable path is used after installation.
@sonarqubecloud

Copy link
Copy Markdown

@gnh1201
gnh1201 merged commit 6af55ec into master Nov 21, 2025
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant