Skip to content

🔄 Sync with upstream NPKill - #1

Merged
manascb1344 merged 37 commits into
mainfrom
sync/upstream-20251023-065251
Oct 23, 2025
Merged

manascb1344 merged 37 commits into
mainfrom
sync/upstream-20251023-065251

Conversation

@manascb1344

@manascb1344 manascb1344 commented Oct 23, 2025 •

Copy link
Copy Markdown
Owner

🔄 Upstream Sync

This PR brings the latest changes from the upstream NPKill repository.

Upstream commit: f243b02b92a8e1eec67d90d8e127dc9291e75ff9
Sync timestamp: Thu Oct 23 06:52:51 UTC 2025

Changes included:

f243b02 Merge pull request voidcosmos#227 from voidcosmos/perf/colors2ad0897 perf: replace 'colors' by 'picocolors' libraryf167e68 Merge pull request voidcosmos#226 from voidcosmos/feat/help-panel1a115a2 refactor(help): move help components to help directoryb3bcf7e feat(help): implement help sections1065ba3 feat(help): implement 'help' panel structure8eb8440 Merge pull request voidcosmos#225 from voidcosmos/feat/improve-help99181e4 feat(help): improve '--help' output adding headers and more information9223324 Merge pull request voidcosmos#224 from voidcosmos/chore/deps4618af8 Merge pull request voidcosmos#223 from voidcosmos/feat/profiles

Review checklist:

  • Review all changes for compatibility with UVKill
  • Test that Python virtual environment detection still works
  • Verify that UVKill-specific modifications are preserved
  • Update version number if needed
  • Test the build and functionality

Auto-generated by GitHub Actions 🤖


Summary by cubic

Sync with upstream NPKill to add profiles-based targeting, a revamped Help UI, and switch to picocolors for faster terminal rendering. Default scanning now uses the “node” profile, expanding targets beyond node_modules.

  • New Features

    • Profiles: -p/--profiles to select presets (e.g., node, python, java, all); lists available profiles when used without a value and warns on unknown names.
    • Help: New interactive Help panel with clearer sections and 80-char width; cleaner command descriptions.
    • Results: Adds brief descriptions for many folder types; improves result details and placeholders when data isn’t ready.
    • Docs/Tests: Added docs/profiles.md and tests for the profiles service; README updated.
  • Migration

    • Default behavior now scans the “node” profile (more targets than only node_modules). To mimic the old behavior, pass -t node_modules.

Summary by CodeRabbit

  • New Features

    • Added -p / --profiles option to select cleanup targets for specific ecosystems (Node.js, Python, Java, etc.).
    • Introduced interactive help interface with multiple sections for better navigation and learning.
  • Documentation

    • Added comprehensive profiles documentation explaining available cleanup profiles.
    • Enhanced help system with detailed sections on shortcuts, warnings, and tips.
  • Improvements

    • Updated visual styling for better terminal rendering.
    • Refined terminal state handling during exit.
    • Updated dependency libraries for better performance and compatibility.

zaldih added 30 commits October 18, 2025 17:41
Optimize, update, and fix dependencies
@coderabbitai

coderabbitai Bot commented Oct 23, 2025 •

Copy link
Copy Markdown

Walkthrough

This PR introduces profile-based target selection for CLI cleanup operations, replaces the deprecated colors library with picocolors across all UI components, restructures the help UI system into a dedicated subdirectory with enhanced interactivity, and updates multiple dependencies including development tooling.

Changes

Cohort / File(s) Summary
Configuration & Documentation
.gitignore, README.md, docs/profiles.md
Added docs/private to gitignore; documented new --profiles CLI option; added comprehensive profiles documentation covering 18 ecosystems with safe-to-delete directories.
Dependency Management
package.json
Updated core dependencies (ansi-escapes 7.1.1, added picocolors 1.1.1, removed colors/node-emoji); upgraded devDependencies (eslint, typescript-eslint, @stryker-mutator, @jest/globals, commitlint, ts-jest, etc.); removed legacy build tools.
Profiles Feature Implementation
src/cli/services/profiles.service.ts, src/cli/interfaces/profiles.interface.ts, src/constants/profiles.constants.ts, src/constants/result-descriptions.constants.ts
New ProfilesService with methods to retrieve profiles, validate profile names, and aggregate targets; added TARGETS_PROFILE interface; defined DEFAULT_PROFILE and DEFAULT_PROFILES constant with 18 ecosystem-specific cleanup configurations; moved RESULT_TYPE_INFO to new result-descriptions constants file.
CLI Controller & Config
src/cli/cli.controller.ts, src/cli/interfaces/config.interface.ts, src/cli/models/start-parameters.model.ts, src/constants/cli.constants.ts, src/constants/main.constants.ts, src/constants/index.ts
Integrated ProfilesService into CLI controller; added profiles property to IConfig; added getStrings() method to StartParameters; updated CLI constants with --profiles option and new help content; added MAX_WIDTH UI constraint; extended public exports for profiles and result-descriptions constants.
Colors Library Replacement
src/cli/ui/components/general.ui.ts, src/cli/ui/components/header/header.ui.ts, src/cli/ui/components/header/stats.ui.ts, src/cli/ui/components/header/status.ui.ts, src/cli/ui/components/logs.ui.ts, src/cli/ui/components/options.ui.ts, src/cli/ui/components/result-details.ui.ts, src/cli/ui/components/results.ui.ts, src/constants/options.constants.ts, src/constants/status.constants.ts
Replaced all colors library imports and usage with picocolors (aliased as pc); updated color function calls to picocolors API (e.g., colors.bold.gray() → pc.bold(pc.gray())); changed "Space released" to "Space saved" in general UI.
Help UI Restructuring & Enhancement
src/cli/ui/components/help-command.ui.ts (removed), src/cli/ui/components/help.ui.ts (removed), src/cli/ui/components/help/help-command.ui.ts (added), src/cli/ui/components/help/help.ui.ts (added), src/cli/ui/components/help/help.constants.ts (added), src/cli/ui/index.ts
Reorganized help UI components into dedicated help/ subdirectory; removed old HelpUi and HelpCommandUi classes; added new HelpUi with interactive navigation (up/down to switch sections, j/k/page keys to scroll), new HelpCommandUi for command rendering, and new help.constants with HELP_SECTIONS data containing multi-section formatted help content.
Service & Main Entry Point
src/cli/services/index.ts, src/main.ts
Added ProfilesService to services index exports; wired ProfilesService into CliController constructor in main initialization.
CLI Controller Tests
tests/cli/cli.controller.test.ts
Added ProfilesService mock with getAvailableProfilesToPrint, getBadProfiles, getTargetsFromProfiles methods; updated test fixtures to use 'target-folder' instead of 'targets'; reset DEFAULT_CONFIG between tests; updated help UI import path.
New Profiles Service Tests
tests/cli/services/profiles.service.test.ts
Added comprehensive test suite for ProfilesService covering profile listing with default markers, profile validation, target aggregation, deduplication, and special "all" profile handling.
Test Updates
tests/cli/services/scan.service.test.ts, tests/core/services/files/files.service.test.ts
Extended scan.service tests with DEFAULT_PROFILE in IConfig mock; updated file.service tests to use Uint8Array instead of Buffer.alloc.

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI as CLI Controller
    participant ProfilesService
    participant Config

    User->>CLI: Invoke with --profiles option
    CLI->>ProfilesService: getBadProfiles(provided_profiles)
    alt Invalid profiles
        ProfilesService-->>CLI: returns bad profile names
        CLI-->>User: Exit with error message
    else Valid profiles
        ProfilesService-->>CLI: returns empty array
        CLI->>ProfilesService: getTargetsFromProfiles(profile_names)
        ProfilesService-->>CLI: returns aggregated targets
        CLI->>Config: Store resolved targets and profile names
        CLI->>User: Proceed with cleanup using resolved targets
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

This PR introduces a new feature (profiles system with service and logic), performs a systematic library replacement across multiple UI components, restructures the help UI module with enhanced interactivity, updates numerous dependencies, and modifies the CLI controller's initialization flow. While the library replacement is repetitive across files, the heterogeneous nature of the feature additions, structural changes, and test updates necessitates separate reasoning for different areas.

Poem

🐰 Profiles unfold like clover leaves so green,
Colors fade to picocolors, crisp and clean,
Help now dances in organized delight,
Targets aggregate from node to haskell's height,
The cleanup path grows smarter, true, and right! 🌟

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "🔄 Sync with upstream NPKill" is directly related to the changeset's primary objective, which according to the PR description is to "bring the latest changes from the upstream NPKill repository." The title accurately identifies that this is a synchronization of upstream changes and specifies the source repository (NPKill). While the changeset includes multiple types of modifications—such as new profile features, help panel improvements, a library migration from 'colors' to 'picocolors', dependency updates, and documentation changes—these are all components of a single upstream sync rather than separate concerns. The title is concise, clear, and specific enough for teammates scanning history to understand that this PR integrates upstream changes.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sync/upstream-20251023-065251

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 8

Caution

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

⚠️ Outside diff range comments (3)
src/constants/main.constants.ts (1)

14-16: Change warningColor to 'yellowBright' to match picocolors API

Picocolors v1.1.1 supports bright color variants like yellowBright, but not brightYellow. The current value 'brightYellow' will cause runtime errors at lines 300 and 338 of src/cli/ui/components/results.ui.ts when the code attempts to access pc['brightYellow'], which does not exist.

Update line 15 in src/constants/main.constants.ts:

warningColor: 'yellowBright',
src/constants/cli.constants.ts (2)

62-65: Small copy nits in option descriptions

  • “Dont” → “Don’t”
  • “Ej.” → “e.g.”
-    description: 'Dont check for updates on startup.',
+    description: "Don't check for updates on startup.",
@@
-      'Specify the name of the directories you want to search for. You can define multiple targets separating with comma. Ej. `-t node_modules,.cache`.',
+      'Specify the directory names to search. Define multiple targets separated by commas, e.g., `-t node_modules,.cache`.',

Also applies to: 76-77


51-55: Duplicate short flag "-s" for size-unit and sort options requires immediate fix

The duplicate -s flag is confirmed at lines 51 and 70 in src/constants/cli.constants.ts. Reassign size-unit to use -u instead:

  {
-   arg: ['-s', '--size-unit'],
+   arg: ['-u', '--size-unit'],
    description:
      'Set the unit for displaying folder sizes. Options: auto (default), mb, gb. With auto, sizes < 1024MB are shown in MB, larger sizes in GB.',
    name: 'size-unit',
  },
  {
    arg: ['-s', '--sort'],
    description:
      'Sort results by: size, path or last-mod (last time the most recent file was modified in the workspace)',
    name: 'sort-by',
  },

Existing tests use long-form flags (e.g., --sort-by, --sort=size), so this change carries minimal breakage risk.

🧹 Nitpick comments (9)
src/cli/ui/components/help/help.constants.ts (1)

141-183: Remove stale commented code referencing ‘colors’

These blocks reference the old colors library and add noise. Either port them to picocolors or delete.

Also applies to: 205-216

src/constants/cli.constants.ts (1)

107-144: Consider accessibility/contrast for headers

Black-on-yellow may be hard to read in some terminals/themes. Optional: use dim/bold without background, or make configurable.

src/cli/ui/components/help/help-command.ui.ts (2)

49-59: Use join(', ') instead of reduce

Simpler and avoids edge-cases.

-      const args = option.arg.reduce((text, arg) => text + ', ' + arg);
+      const args = option.arg.join(', ');

18-20: render() throws; ensure it’s never called

Currently show() prints directly. If any future path calls render(), this will crash. Consider a no-op render or delegate to show().

-  render(): void {
-    throw new Error('Method not implemented.');
-  }
+  render(): void {
+    this.show();
+  }
src/cli/services/profiles.service.ts (2)

6-13: Improve targets line readability

Add a space after commas.

-        pc.gray(` ${profile.targets.join(pc.italic(','))}\n\n`);
+        pc.gray(` ${profile.targets.join(pc.italic(', '))}\n\n`);

15-23: Comment doesn’t match behavior

The docstring mentions “dont have targets,” but code only validates existence. Align the comment or extend validation.

-  /** Return an array of invalid profile names (if not exist or dont have targets). */
+  /** Return an array of invalid profile names (names not present in DEFAULT_PROFILES). */
src/cli/ui/components/help/help.ui.ts (1)

167-176: Index/content padding may misalign with emojis and box-drawing chars

getStringWidth() uses .length; combined with emojis (e.g., 👋, 📊) can misalign boxes. Adopting string-width will fix it.

Also applies to: 210-220

src/cli/cli.controller.ts (1)

262-283: Mutual exclusion UX: when both --profiles and --target-folder are present

You print to console then exit. Consider printing suggested command usage and examples (e.g., “Use either --profiles or --target-folder”). Improves UX.

tests/cli/cli.controller.test.ts (1)

148-152: LGTM with suggestions.

The ProfilesService mock is properly integrated into the test setup. However, consider adding assertions to verify that getTargetsFromProfiles is called with the expected profiles when the controller initializes with different parameter combinations.

Also applies to: 163-167, 184-184

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 40d302c and f243b02.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (37)
  • .gitignore (1 hunks)
  • README.md (1 hunks)
  • docs/profiles.md (1 hunks)
  • package.json (1 hunks)
  • src/cli/cli.controller.ts (10 hunks)
  • src/cli/interfaces/config.interface.ts (1 hunks)
  • src/cli/interfaces/profiles.interface.ts (1 hunks)
  • src/cli/models/start-parameters.model.ts (1 hunks)
  • src/cli/services/index.ts (1 hunks)
  • src/cli/services/profiles.service.ts (1 hunks)
  • src/cli/ui/components/general.ui.ts (1 hunks)
  • src/cli/ui/components/header/header.ui.ts (4 hunks)
  • src/cli/ui/components/header/stats.ui.ts (3 hunks)
  • src/cli/ui/components/header/status.ui.ts (4 hunks)
  • src/cli/ui/components/help-command.ui.ts (0 hunks)
  • src/cli/ui/components/help.ui.ts (0 hunks)
  • src/cli/ui/components/help/help-command.ui.ts (1 hunks)
  • src/cli/ui/components/help/help.constants.ts (1 hunks)
  • src/cli/ui/components/help/help.ui.ts (1 hunks)
  • src/cli/ui/components/logs.ui.ts (3 hunks)
  • src/cli/ui/components/options.ui.ts (4 hunks)
  • src/cli/ui/components/result-details.ui.ts (6 hunks)
  • src/cli/ui/components/results.ui.ts (12 hunks)
  • src/cli/ui/index.ts (1 hunks)
  • src/constants/cli.constants.ts (3 hunks)
  • src/constants/index.ts (1 hunks)
  • src/constants/main.constants.ts (3 hunks)
  • src/constants/messages.constants.ts (0 hunks)
  • src/constants/options.constants.ts (1 hunks)
  • src/constants/profiles.constants.ts (1 hunks)
  • src/constants/result-descriptions.constants.ts (1 hunks)
  • src/constants/status.constants.ts (1 hunks)
  • src/main.ts (2 hunks)
  • tests/cli/cli.controller.test.ts (10 hunks)
  • tests/cli/services/profiles.service.test.ts (1 hunks)
  • tests/cli/services/scan.service.test.ts (2 hunks)
  • tests/core/services/files/files.service.test.ts (1 hunks)
💤 Files with no reviewable changes (3)
  • src/constants/messages.constants.ts
  • src/cli/ui/components/help-command.ui.ts
  • src/cli/ui/components/help.ui.ts
🧰 Additional context used
🪛 Biome (2.1.2)
src/cli/ui/components/help/help.ui.ts

[error] 234-234: Unexpected control character in a regular expression.

Control characters are unusual and potentially incorrect inputs, so they are disallowed.

(lint/suspicious/noControlCharactersInRegex)

🪛 LanguageTool
docs/profiles.md

[style] ~85-~85: Consider replacing this word to strengthen your wording.
Context: ...leting is a common troubleshooting step and clears the build cache. Regenerated by ...

(AND_THAT)

🔇 Additional comments (45)
tests/core/services/files/files.service.test.ts (1)

257-257: LGTM! Functionally equivalent refactor to standard JavaScript API.

The change from Buffer.alloc() to new Uint8Array() is functionally equivalent for this test helper. Both create zero-filled arrays of the specified size, and fs.writeFileSync accepts both types. This aligns with using standard JavaScript APIs rather than Node.js-specific ones.

Note: This test suite is currently skipped (xdescribe on line 243), so the change has no immediate execution impact.

src/cli/interfaces/config.interface.ts (1)

2-2: LGTM! Clean addition for profiles feature.

The addition of the profiles property to the IConfig interface is straightforward and aligns with the PR objectives to introduce profile-based target selection.

src/constants/status.constants.ts (1)

1-8: LGTM! Clean migration to picocolors.

The replacement of the deprecated colors library with picocolors is correctly implemented. All color method calls have been properly updated to use the new pc alias.

src/cli/ui/components/general.ui.ts (1)

4-14: LGTM! Consistent color library migration and improved messaging.

The changes correctly migrate from colors to picocolors and improve the exit message wording from "Space released" to "Space saved". The mapping of colors['gray'] to pc.dim is appropriate.

src/cli/models/start-parameters.model.ts (1)

22-29: LGTM! Clean utility method for parsing comma-separated values.

The getStrings method correctly handles the common case of parsing comma-separated CLI option values. Edge cases (missing key, boolean values) are appropriately handled by returning an empty array.

src/cli/ui/components/header/status.ui.ts (4)

2-2: LGTM! Consistent color library migration.

The import has been correctly updated to use picocolors as part of the repository-wide migration from the deprecated colors library.


68-68: LGTM! Color styling correctly updated.

The color method calls have been properly updated to use the pc alias for picocolors.


92-92: LGTM! Color styling correctly updated.

The color method call has been properly updated to use the pc alias.


222-222: LGTM! Color styling correctly updated.

The color method call has been properly updated to use the pc alias.

.gitignore (1)

11-11: LGTM! Appropriate exclusion for private documentation.

Adding docs/private to .gitignore is a sensible change to exclude internal documentation from version control.

src/cli/ui/components/header/stats.ui.ts (3)

5-5: LGTM! Consistent color library migration.

The import has been correctly updated to use picocolors as part of the repository-wide migration.


84-84: LGTM! Dynamic color access correctly updated.

The dynamic property access pattern has been properly updated from colors[updateColor] to pc[updateColor], maintaining the same behavior with the new library.


105-105: LGTM! Color styling correctly updated.

The color method call has been properly updated to use the pc alias.

src/cli/ui/components/logs.ui.ts (2)

3-3: LGTM: Picocolors import

The migration from colors to picocolors is correctly implemented throughout this file.


131-138: LGTM: Color styling correctly migrated

The dynamic color lookup pc[color] with values 'white' and 'red' is correct for picocolors API.

package.json (1)

49-53: LGTM: Dependencies updated for picocolors migration

The addition of picocolors and removal of legacy colors library aligns with the codebase migration. Dependency versions are appropriately pinned.

src/constants/result-descriptions.constants.ts (2)

1-5: Important: Lowercase key requirement

The comment correctly notes that keys must be lowercase to match the lookup logic. This is critical since src/cli/ui/components/result-details.ui.ts line 173 uses folderName.toLowerCase() for lookups.


181-200: LGTM: Python virtual environment support maintained

Python-related entries (venv, env, __pycache__, .pytest_cache, etc.) are well-documented, confirming that UVKill-specific Python virtual environment detection features are preserved in this upstream sync.

Based on PR objectives.

src/cli/ui/components/result-details.ui.ts (2)

173-174: LGTM: Correct lowercase key lookup

The toLowerCase() call correctly matches the requirement documented in src/constants/result-descriptions.constants.ts (line 3).


183-212: Well-designed warning extraction and rendering

The regex-based WARNING section extraction and separate yellow-highlighted rendering is a nice UX enhancement. The pattern correctly handles multiline descriptions with the s flag.

src/constants/main.constants.ts (2)

12-12: LGTM: Profile support integration

The profiles field addition with DEFAULT_PROFILE correctly integrates the new profile feature.


42-42: LGTM: UI layout constant addition

The MAX_WIDTH: 80 addition supports consistent width constraints for help UI rendering.

src/cli/services/index.ts (1)

8-8: LGTM: ProfilesService export

The export correctly adds the new ProfilesService to the public service API.

tests/cli/services/scan.service.test.ts (1)

11-11: LGTM: Test configuration updated for profile support

The mock configuration correctly includes the new profiles field with DEFAULT_PROFILE, maintaining test compatibility with the profile feature.

Also applies to: 23-23

src/cli/interfaces/profiles.interface.ts (1)

1-5: LGTM! Clean interface definition.

The TARGETS_PROFILE interface is well-structured with clear, self-documenting fields.

src/constants/index.ts (1)

8-9: LGTM! Standard re-exports.

The new module exports follow the existing barrel export pattern consistently.

src/constants/options.constants.ts (2)

1-1: LGTM! Migration to picocolors.

Replacing the deprecated colors library with picocolors is a good modernization step. Picocolors is lighter, faster, and more actively maintained.


4-15: LGTM! Correct picocolors API usage.

The transformation from chained color methods (colors.bold.underline(...)) to composed function calls (pc.bold(pc.underline(...))) is correct and maintains the same visual output.

src/cli/ui/components/options.ui.ts (2)

5-5: LGTM! Picocolors migration.

Consistent with the broader color library migration across the codebase.


248-248: LGTM! Correct picocolors composition.

All color styling has been correctly migrated from chained colors.* calls to composed pc.* function calls, maintaining visual equivalence.

Also applies to: 271-272, 290-291

src/cli/ui/components/header/header.ui.ts (2)

10-10: LGTM! Picocolors migration.

Aligns with the project-wide color library upgrade.


37-37: LGTM! Comprehensive picocolors integration.

All header styling has been correctly migrated to picocolors with proper function composition for multi-level styling effects.

Also applies to: 42-42, 49-49, 57-57, 61-61, 70-70, 81-82

docs/profiles.md (1)

128-132: Warning documented for generic folder names.

Good practice documenting that Library on macOS can match the system ~/Library folder, and that Obj is a generic name. These warnings help prevent accidental deletion of critical system directories.

src/cli/ui/index.ts (1)

4-5: Help UI refactoring verified as complete. The export paths correctly point to the new help/ subdirectory structure and follow the project's established convention of using .js extensions in exports. No stale imports referencing old paths remain in the codebase.

src/main.ts (1)

5-5: This review comment is based on an incorrect premise and should be disregarded.

This is the official NPKill repository (https://github.com/zaldih/npkill), not a UVKill fork. NPKill is designed to find and remove node_modules directories, and DEFAULT_PROFILE = 'node' is the correct default. The concerns about Python virtual environment detection and compatibility with UVKill are not applicable to this codebase.

Likely an incorrect or invalid review comment.

src/cli/ui/components/help/help.constants.ts (1)

17-31: Branding: Should this say “UVKill” instead of “npkill”?

Sync pulls upstream copy. If UVKill intentionally keeps “npkill”, ignore. Otherwise, consider rebranding in help texts.

Also applies to: 261-276

src/constants/profiles.constants.ts (1)

4-4: Default profile is “node” — confirm UVKill’s desired default

UVKill users may expect Python-related targets by default. If you intend to keep parity with upstream, fine; else consider DEFAULT_PROFILE = 'python' or documenting the default prominently.

src/cli/cli.controller.ts (4)

337-371: Defaulting to profile “node” when neither flag is set — confirm for UVKill

This changes discovery behavior vs UVKill’s Python focus. If intentional, document prominently. If not, consider DEFAULT_PROFILE = 'python' or prompting the user on first run.


695-709: Graceful exit path mirrors error path — good. Minor: print final newline only once

resetConsoleState prints a newline; quit() also prints messages. Ensure no extra blank lines in non-TTY contexts.


526-529: Colors → picocolors migration here looks correct

Replacing update message with pc.magenta is OK.


251-261: Help display uses HelpCommandUi.show() then exitGracefully()

This avoids leaving the terminal in raw mode—good. Ensure show() never calls render() (which currently throws in HelpCommandUi).

tests/cli/cli.controller.test.ts (4)

14-15: LGTM!

The new imports for ProfilesService and DEFAULT_CONFIG are necessary for the profile-based target selection feature introduced in this PR.


48-48: LGTM!

The updated mock path correctly reflects the help UI restructuring into the help/ subdirectory.


285-289: LGTM!

The parameter name updates from targets to 'target-folder' are applied consistently across all test scenarios and align with the new profile-based target selection functionality.

Also applies to: 299-303, 325-328, 342-342


233-238: All reset values are correct—no issues found.

The hardcoded reset values in the afterEach hook match the actual DEFAULT_CONFIG defaults exactly: jsonStream, jsonSimple, deleteAll, dryRun are all correctly reset to false, and sortBy is correctly reset to 'none'. The cleanup logic prevents test pollution as intended.

Comment thread docs/profiles.md
Comment on lines +1 to +17
# Profiles

This document defines built-in profiles for npkill. A profile is a named preset of "safe-to-delete" directories for a given ecosystem.

While these directories are **generally safe to delete**, it all depends on their context. Therefore, it is important to verify the result shown before deleting it. However, we have tried to maintain a conservative list.

- Profiles are opt-in via `--profiles` (comma-separated). Example: `--profiles node,python`.
- Only directory base names are matched (the last path segment) (more advanced heuristics will be implemented in the future).
- All targets below are rebuildable caches, dependencies, or compiled outputs. So doesnt should have any problem deleting it. But before delete, peek if is secure to remove for your case.

Default behavior

- By default (no `--profiles`), npkill use the `node` profile.

Special profile: all

- `all` includes every target listed in all profiles below. Use with care if you want a full clean sweep.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Update documentation for UVKill context.

This documentation was imported from upstream NPKill and needs UVKill-specific updates:

  1. Line 13 states the default is the node profile, but UVKill is focused on Python virtual environments
  2. The documentation should brand this as UVKill and clarify that the default profile should be python (not node)
  3. Consider reordering sections to prioritize Python ecosystem over Node.js for UVKill users

Apply these changes to align with UVKill's Python focus:

 # Profiles
 
-This document defines built-in profiles for npkill. A profile is a named preset of "safe-to-delete" directories for a given ecosystem.
+This document defines built-in profiles for uvkill. A profile is a named preset of "safe-to-delete" directories for a given ecosystem.
 
 While these directories are **generally safe to delete**, it all depends on their context. Therefore, it is important to verify the result shown before deleting it. However, we have tried to maintain a conservative list.
 
 - Profiles are opt-in via `--profiles` (comma-separated). Example: `--profiles node,python`.
 - Only directory base names are matched (the last path segment) (more advanced heuristics will be implemented in the future).
 - All targets below are rebuildable caches, dependencies, or compiled outputs. So doesnt should have any problem deleting it. But before delete, peek if is secure to remove for your case.
 
 Default behavior
 
-- By default (no `--profiles`), npkill use the `node` profile.
+- By default (no `--profiles`), uvkill uses the `python` profile (targeting Python virtual environments).
 
 Special profile: all
 
 - `all` includes every target listed in all profiles below. Use with care if you want a full clean sweep.
 
-## node (default)
+## python (default)
+
+(move Python profile content here)
+
+## node

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In docs/profiles.md around lines 1 to 17, update the imported NPKill wording to
UVKill: replace occurrences of "npkill" with "UVKill", change the default
profile mention on line 13 from `node` to `python`, reorder or rephrase the
document to prioritize the Python ecosystem (mention python first, then node),
and correct the awkward sentence about deletion (fix grammar and clarify intent
— e.g., "so it should be safe to delete, but verify before removing"). Ensure
the `--profiles` flag description remains accurate and that the "all" profile
note still applies.

Comment thread docs/profiles.md
Comment on lines +48 to +61
## python

- `__pycache__`: Python bytecode files. Deleting is safe as they are regenerated by Python automatically.
- `.pytest_cache`: pytest's cache for test results and metadata. Deleting may slow down the next test run. Regenerated automatically by pytest.
- `.mypy_cache`: mypy's cache for type-checking results. Deleting forces a full re-check. Regenerated automatically by mypy.
- `.ruff_cache`: Ruff linter's cache. Deleting forces a full re-lint. Regenerated automatically by Ruff.
- `.tox`: tox's virtual environments and test artifacts. Deleting removes isolated testing environments. Regenerated by running `tox`.
- `.nox`: nox's virtual environments and session data. Deleting removes isolated session environments. Regenerated by running `nox`.
- `.pytype`: pytype's cache for static analysis. Deleting forces a full re-analysis. Regenerated automatically by pytype.
- `.pyre`: Pyre type checker's cache. Deleting forces a full re-check. Regenerated automatically by Pyre.
- `htmlcov`: HTML code coverage reports. Deleting removes historical coverage data. Regenerated by running coverage tools (e.g., `coverage html`).
- `.venv`: Python virtual environment. Deleting removes all installed packages and the isolated environment. Regenerated by creating a new virtual environment (e.g., `python -m venv .venv`).
- `venv`: Same as `.venv`. Deleting removes the virtual environment. Regenerated similarly.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Python profile should be the default for UVKill.

Since UVKill is specifically designed for Python virtual environments, the Python profile section should be promoted to the primary/default profile position in the documentation, and the implementation should match.

🤖 Prompt for AI Agents
In docs/profiles.md around lines 48 to 61, the Python profile must be promoted
to the primary/default profile in docs and code: move the entire "python"
section to the top of the profiles list, add a short explicit note that "python"
is the default profile, and update any examples that reference the default
profile accordingly; then make the implementation match by setting the runtime
default profile to "python" in the profile-loading/config code (the default
value in the profiles map or config loader), and ensure any CLI help text or
README reflects this change.

Comment thread README.md

| ARGUMENT | DESCRIPTION |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| -p, --profiles | Allows you to select the [profile](./docs/profiles.md) (set of targets) to use. If no option is specified, the available ones will be listed.. _(**node** by default)_. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix double period typo.

There's a double period in the profiles option description.

Apply this diff:

--p, --profiles                   | Allows you to select the [profile](./docs/profiles.md) (set of targets) to use. If no option is specified, the available ones will be listed.. _(**node** by default)_.             |
+-p, --profiles                   | Allows you to select the [profile](./docs/profiles.md) (set of targets) to use. If no option is specified, the available ones will be listed. _(**node** by default)_.             |
📝 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
| -p, --profiles | Allows you to select the [profile](./docs/profiles.md) (set of targets) to use. If no option is specified, the available ones will be listed.. _(**node** by default)_. |
| -p, --profiles | Allows you to select the [profile](./docs/profiles.md) (set of targets) to use. If no option is specified, the available ones will be listed. _(**node** by default)_. |
🤖 Prompt for AI Agents
In README.md around line 129, the profiles option description contains a double
period ("listed.."); remove the extra period so the sentence reads with a single
period (e.g., "...will be listed. _(**node** by default)_."), ensuring
punctuation spacing remains correct.

Comment on lines +106 to +113
'Npkill will try to detect this folders and show "⚠️"',
'alongside the result and mark it as "sensitive".',
'',
'',
pc.bold(pc.green('Pro tip')),
'Use the Info panel (→) to see more information',
'about why a folder is flagged.',
],

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Grammar fix: “these folders” + tighten wording

Minor copy tweak for clarity.

-      'Npkill will try to detect this folders and show "⚠️"',
+      'Npkill will try to detect these folders and show "⚠️"',
-      'alongside the result and mark it as "sensitive".',
+      'alongside the result and mark it as "sensitive".',
📝 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
'Npkill will try to detect this folders and show "⚠️"',
'alongside the result and mark it as "sensitive".',
'',
'',
pc.bold(pc.green('Pro tip')),
'Use the Info panel (→) to see more information',
'about why a folder is flagged.',
],
'Npkill will try to detect these folders and show "⚠️"',
'alongside the result and mark it as "sensitive".',
'',
'',
pc.bold(pc.green('Pro tip')),
'Use the Info panel (→) to see more information',
'about why a folder is flagged.',
],
🤖 Prompt for AI Agents
In src/cli/ui/components/help/help.constants.ts around lines 106 to 113, the
copy mistakenly uses "this folders" and is slightly wordy; change the phrasing
to "these folders" and tighten wording for clarity (e.g., combine the two
sentences into one concise line like 'Npkill will try to detect these folders,
show "⚠️" alongside the result, and mark it as "sensitive".' and remove the
extra blank lines), keeping the Pro tip and Info panel lines intact.

Comment on lines +228 to +232
/** Get real width, removing ANSI color codes. */
private getStringWidth(str: string): number {
// eslint-disable-next-line no-control-regex
return str.replace(/\u001b\[[0-9;]*m/g, '').length;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Biome lint error: control character in regex; also doesn’t handle fullwidth chars

Address the linter and improve width accuracy.

Option A (minimal change, fixes Biome):

-    // eslint-disable-next-line no-control-regex
-    return str.replace(/\u001b\[[0-9;]*m/g, '').length;
+    // Remove ANSI without embedding control chars in a literal
+    return str.replace(new RegExp('\\x1B\\[[0-9;]*m', 'g'), '').length;

Option B (recommended): use string-width + strip-ansi for correct display width.

+import stripAnsi from 'strip-ansi';
+import stringWidth from 'string-width';
@@
-    return str.replace(new RegExp('\\x1B\\[[0-9;]*m', 'g'), '').length;
+    return stringWidth(stripAnsi(str));

Follow-up: add deps and update package.json.

📝 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
/** Get real width, removing ANSI color codes. */
private getStringWidth(str: string): number {
// eslint-disable-next-line no-control-regex
return str.replace(/\u001b\[[0-9;]*m/g, '').length;
}
/** Get real width, removing ANSI color codes. */
private getStringWidth(str: string): number {
// Remove ANSI without embedding control chars in a literal
return str.replace(new RegExp('\\x1B\\[[0-9;]*m', 'g'), '').length;
}
🤖 Prompt for AI Agents
In src/cli/ui/components/help/help.ui.ts around lines 228-232, the current
regex-based getStringWidth both triggers the Biome lint error for control
characters and miscomputes widths for fullwidth characters; replace this with
the recommended approach: add dependencies strip-ansi and string-width to
package.json, import stripAnsi and stringWidth at the top of the file, then
implement getStringWidth to first call stripAnsi(str) and return
stringWidth(...) (remove the eslint-disable comment and the control-char regex),
and update package.json (and lockfile) to include the new deps.

Comment on lines +300 to 302
const targetFolderColored: string = pc[DEFAULT_CONFIG.warningColor](
this.config.targets.join(', '),
);

Copy link
Copy Markdown

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 that picocolors supports 'brightYellow' color name

The code uses pc[DEFAULT_CONFIG.warningColor] where warningColor is set to 'brightYellow' in src/constants/main.constants.ts (line 15). The old colors library had brightYellow, but picocolors typically only has yellow (which is already the bright variant). This dynamic property access will fail at runtime if pc.brightYellow doesn't exist.

Check lines 338, and the same pattern appears elsewhere in the file.

Please verify the picocolors API:


🌐 Web query:

Does picocolors library support brightYellow color function?

💡 Result:

No. Picocolors does not provide a brightYellow function — the bright variant is named yellowBright (e.g., pc.yellowBright). [1][2]

Sources:
[1] picocolors README / npm.
[2] picocolors changelog (v1.1.0 added bright variants).


🏁 Script executed:

#!/bin/bash
# Check the DEFAULT_CONFIG.warningColor value in constants
echo "=== Checking src/constants/main.constants.ts ===" 
if [ -f "src/constants/main.constants.ts" ]; then
  grep -n "warningColor" src/constants/main.constants.ts | head -20
else
  echo "File not found at src/constants/main.constants.ts"
  # Try to find it
  find . -name "*main.constants.ts" -type f 2>/dev/null | head -5
fi

echo ""
echo "=== Checking src/cli/ui/components/results.ui.ts for color usage ===" 
if [ -f "src/cli/ui/components/results.ui.ts" ]; then
  sed -n '295,310p' src/cli/ui/components/results.ui.ts
  echo ""
  echo "--- Line 338 area ---"
  sed -n '330,350p' src/cli/ui/components/results.ui.ts
else
  echo "File not found at src/cli/ui/components/results.ui.ts"
  find . -name "results.ui.ts" -type f 2>/dev/null
fi

Length of output: 1240


Fix warningColor constant: change 'brightYellow' to 'yellowBright'

The issue is confirmed. The picocolors library uses yellowBright (not brightYellow). Picocolors does not provide a brightYellow function — the bright variant is named yellowBright.

The code will fail at runtime because pc['brightYellow'] is undefined:

  • src/constants/main.constants.ts:15 — Change warningColor: 'brightYellow' to warningColor: 'yellowBright'

This single change fixes both usages in results.ui.ts (lines 300 and 338) since they use dynamic property access that will then resolve to the correct pc.yellowBright() function.

🤖 Prompt for AI Agents
In src/constants/main.constants.ts (around line 15) and referenced in
src/cli/ui/components/results.ui.ts (lines 300 and 338), the configured
warningColor is set to 'brightYellow', which picocolors does not export; change
the constant value from 'brightYellow' to 'yellowBright' so dynamic access
pc[DEFAULT_CONFIG.warningColor] resolves to pc.yellowBright and the runtime
error is fixed.

Comment on lines +280 to +282
(
profilesServiceMock.getTargetsFromProfiles as jest.Mock
).mockReturnValue(['node_modules']);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Remove redundant mock setup.

This mock setup duplicates the identical configuration already performed in the global beforeEach (lines 165-167). The redundancy can be removed for cleaner test code.

Apply this diff:

     describe('--delete-all', () => {
       beforeEach(() => {
         jest.clearAllMocks();
-        (
-          profilesServiceMock.getTargetsFromProfiles as jest.Mock
-        ).mockReturnValue(['node_modules']);
       });

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In tests/cli/cli.controller.test.ts around lines 280 to 282, there's a redundant
mock setup calling (profilesServiceMock.getTargetsFromProfiles as
jest.Mock).mockReturnValue(['node_modules']) that duplicates the identical
configuration already set in the global beforeEach (lines 165-167); remove these
three lines so the test relies on the shared beforeEach mock and keep the rest
of the test unchanged.

Comment on lines +57 to +66
it('should return empty string when no profiles exist', () => {
const originalProfiles = [...DEFAULT_PROFILES];
DEFAULT_PROFILES.length = 0;

const result = profilesService.getAvailableProfilesToPrint();

expect(result).toBe('');

DEFAULT_PROFILES.push(...originalProfiles);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Avoid mutating exported DEFAULT_PROFILES in tests

Mutating shared constants risks cross-test pollution. Prefer injecting a service with an empty profile set or mocking DEFAULT_PROFILES via module mocking.


🏁 Script executed:

#!/bin/bash
# Locate other tests touching DEFAULT_PROFILES to assess flakiness risk
rg -n "DEFAULT_PROFILES" tests -C2

Length of output: 2513



🏁 Script executed:

#!/bin/bash
# Check ProfilesService implementation to understand DEFAULT_PROFILES usage
cat src/cli/services/profiles.service.ts 2>/dev/null || find . -name "profiles.service.ts" -type f | head -1 | xargs cat

Length of output: 1333


🏁 Script executed:

#!/bin/bash
# Check if there's a way the service could accept profiles as dependency
rg -n "getAvailableProfilesToPrint" src -B5 -A10

Length of output: 2403


🏁 Script executed:

#!/bin/bash
# Check test setup/teardown structure to see if hooks exist
rg -n "beforeEach|afterEach|before|after" tests/cli/services/profiles.service.test.ts -B1 -A1

Length of output: 72


🏁 Script executed:

#!/bin/bash
# Verify if Jest is configured to allow mocking this import
find . -name "jest.config.*" -o -name "package.json" | head -5 | xargs grep -l "jest" 2>/dev/null | head -1

Length of output: 16


Move DEFAULT_PROFILES cleanup to afterEach hook and refactor service for testability

The mutation at line 59 lacks try/finally protection. If an error occurs before line 65 restoration, other tests (lines 18, 217, 281) reading DEFAULT_PROFILES will fail. Additionally, ProfilesService directly imports DEFAULT_PROFILES with no dependency injection, making test isolation fragile.

Immediate fix: Add afterEach(() => { DEFAULT_PROFILES.length = 0; DEFAULT_PROFILES.push(...originalProfiles); }) to guarantee cleanup. Longer-term: Refactor ProfilesService to accept profiles as a constructor parameter or use jest.mock() to intercept the import in tests, enabling reliable test data injection without state mutation.

🤖 Prompt for AI Agents
In tests/cli/services/profiles.service.test.ts around lines 57 to 66, the test
mutates DEFAULT_PROFILES without guaranteed cleanup which can leave global state
corrupted if the test throws; add an afterEach hook that restores
DEFAULT_PROFILES (capture originalProfiles in the test or at the top of the
describe and in afterEach set DEFAULT_PROFILES.length = 0;
DEFAULT_PROFILES.push(...originalProfiles)) to ensure restoration always runs;
additionally, for better testability refactor ProfilesService to accept profiles
via constructor parameter or use jest.mock to mock the DEFAULT_PROFILES import
so tests inject isolated data instead of mutating a shared module-level array.

@manascb1344
manascb1344 merged commit 2f16825 into main Oct 23, 2025
2 checks passed

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

12 issues found across 38 files

Prompt for AI agents (all 12 issues)

Understand the root cause of the following 12 issues and fix them.


<file name="README.md">

<violation number="1" location="README.md:129">
This sentence ends with a double period; please reduce it to a single period for correct punctuation.</violation>
</file>

<file name="tests/cli/services/profiles.service.test.ts">

<violation number="1" location="tests/cli/services/profiles.service.test.ts:59">
This test clears DEFAULT_PROFILES without wrapping the restoration in a finally block, so a failed assertion will leave the shared profile list empty for subsequent tests. Please guard the mutation with try/finally (or equivalent) to ensure cleanup always happens.</violation>
</file>

<file name="src/cli/ui/components/result-details.ui.ts">

<violation number="1" location="src/cli/ui/components/result-details.ui.ts:128">
Using `size ? …` treats `size = 0` as missing, so empty folders display `&#39;...&#39;` (and gray styling) instead of their real size. Please check for `null`/`undefined` explicitly so zero-byte folders still show the formatted size.</violation>
</file>

<file name="src/cli/ui/components/results.ui.ts">

<violation number="1" location="src/cli/ui/components/results.ui.ts:300">
picocolors does not provide a &#39;brightYellow&#39; function, so pc[DEFAULT_CONFIG.warningColor](...) resolves to undefined and calling it will crash the CLI whenever this code runs.</violation>

<violation number="2" location="src/cli/ui/components/results.ui.ts:338">
Selecting sensitive folders invokes pc[DEFAULT_CONFIG.warningColor], but picocolors has no &quot;brightYellow&quot; helper, so the CLI crashes with a TypeError.</violation>
</file>

<file name="src/constants/result-descriptions.constants.ts">

<violation number="1" location="src/constants/result-descriptions.constants.ts:174">
This key must be lowercase to stay reachable after folderName.toLowerCase(); as written, descriptions for TestResults folders never appear.</violation>

<violation number="2" location="src/constants/result-descriptions.constants.ts:213">
This key should be lowercase to align with the toLowerCase lookup so Debug build folders show their description.</violation>

<violation number="3" location="src/constants/result-descriptions.constants.ts:215">
Lowercase this key so Release build folders have a matching description after the toLowerCase lookup.</violation>

<violation number="4" location="src/constants/result-descriptions.constants.ts:235">
Lowercase this key so users with DerivedDataCache directories see the info panel; the current casing prevents any match.</violation>

<violation number="5" location="src/constants/result-descriptions.constants.ts:237">
Lowercase this key so the Saved folder description is reachable after folderName.toLowerCase().</violation>

<violation number="6" location="src/constants/result-descriptions.constants.ts:239">
Change this key to lowercase so Binaries folders surface their help text after the toLowerCase lookup.</violation>
</file>

<file name="src/cli/ui/components/help/help-command.ui.ts">

<violation number="1" location="src/cli/ui/components/help/help-command.ui.ts:19">
render() is required to draw the help UI, but this implementation always throws, so any BaseUi.setPosition/setVisible call on HelpCommandUi will crash instead of showing the help panel.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

Comment thread README.md

| ARGUMENT | DESCRIPTION |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| -p, --profiles | Allows you to select the [profile](./docs/profiles.md) (set of targets) to use. If no option is specified, the available ones will be listed.. _(**node** by default)_. |

@cubic-dev-ai cubic-dev-ai Bot Oct 23, 2025 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This sentence ends with a double period; please reduce it to a single period for correct punctuation.

Prompt for AI agents
Address the following comment on README.md at line 129:

<comment>This sentence ends with a double period; please reduce it to a single period for correct punctuation.</comment>

<file context>
@@ -126,6 +126,7 @@ After pressing &lt;kbd&gt;V&lt;/kbd&gt; to enter range selection mode:
 
 | ARGUMENT                         | DESCRIPTION                                                                                                                                                                         |
 | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| -p, --profiles                   | Allows you to select the [profile](./docs/profiles.md) (set of targets) to use. If no option is specified, the available ones will be listed.. _(**node** by default)_.             |
 | -c, --bg-color                   | Change row highlight color. _(Available: **blue**, cyan, magenta, white, red and yellow)_                                                                                           |
 | -d, --directory                  | Set the directory from which to begin searching. By default, starting-point is .                                                                                                    |
</file context>
Suggested change
| -p, --profiles | Allows you to select the [profile](./docs/profiles.md) (set of targets) to use. If no option is specified, the available ones will be listed.. _(**node** by default)_. |
| -p, --profiles | Allows you to select the [profile](./docs/profiles.md) (set of targets) to use. If no option is specified, the available ones will be listed. _(**node** by default)_. |
Fix with Cubic


it('should return empty string when no profiles exist', () => {
const originalProfiles = [...DEFAULT_PROFILES];
DEFAULT_PROFILES.length = 0;

@cubic-dev-ai cubic-dev-ai Bot Oct 23, 2025 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This test clears DEFAULT_PROFILES without wrapping the restoration in a finally block, so a failed assertion will leave the shared profile list empty for subsequent tests. Please guard the mutation with try/finally (or equivalent) to ensure cleanup always happens.

Prompt for AI agents
Address the following comment on tests/cli/services/profiles.service.test.ts at line 59:

<comment>This test clears DEFAULT_PROFILES without wrapping the restoration in a finally block, so a failed assertion will leave the shared profile list empty for subsequent tests. Please guard the mutation with try/finally (or equivalent) to ensure cleanup always happens.</comment>

<file context>
@@ -0,0 +1,301 @@
+
+    it(&#39;should return empty string when no profiles exist&#39;, () =&gt; {
+      const originalProfiles = [...DEFAULT_PROFILES];
+      DEFAULT_PROFILES.length = 0;
+
+      const result = profilesService.getAvailableProfilesToPrint();
</file context>
Fix with Cubic

drawLabel('Size:', formattedSize.text, colors.yellow);
drawLabel(
'Size:',
size ? formattedSize.text : '...',

@cubic-dev-ai cubic-dev-ai Bot Oct 23, 2025 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Using size ? … treats size = 0 as missing, so empty folders display '...' (and gray styling) instead of their real size. Please check for null/undefined explicitly so zero-byte folders still show the formatted size.

Prompt for AI agents
Address the following comment on src/cli/ui/components/result-details.ui.ts at line 128:

<comment>Using `size ? …` treats `size = 0` as missing, so empty folders display `&#39;...&#39;` (and gray styling) instead of their real size. Please check for `null`/`undefined` explicitly so zero-byte folders still show the formatted size.</comment>

<file context>
@@ -123,33 +123,39 @@ export class ResultDetailsUi extends BaseUi implements InteractiveUi {
-    drawLabel(&#39;Size:&#39;, formattedSize.text, colors.yellow);
+    drawLabel(
+      &#39;Size:&#39;,
+      size ? formattedSize.text : &#39;...&#39;,
+      size ? pc.yellow : pc.gray,
+    );
</file context>
Fix with Cubic


private noResults(): void {
const targetFolderColored: string = colors[DEFAULT_CONFIG.warningColor](
const targetFolderColored: string = pc[DEFAULT_CONFIG.warningColor](

@cubic-dev-ai cubic-dev-ai Bot Oct 23, 2025 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

picocolors does not provide a 'brightYellow' function, so pcDEFAULT_CONFIG.warningColor resolves to undefined and calling it will crash the CLI whenever this code runs.

Prompt for AI agents
Address the following comment on src/cli/ui/components/results.ui.ts at line 300:

<comment>picocolors does not provide a &#39;brightYellow&#39; function, so pc[DEFAULT_CONFIG.warningColor](...) resolves to undefined and calling it will crash the CLI whenever this code runs.</comment>

<file context>
@@ -297,7 +297,7 @@ export class ResultsUi extends HeavyUi implements InteractiveUi {
 
   private noResults(): void {
-    const targetFolderColored: string = colors[DEFAULT_CONFIG.warningColor](
+    const targetFolderColored: string = pc[DEFAULT_CONFIG.warningColor](
       this.config.targets.join(&#39;, &#39;),
     );
</file context>
Fix with Cubic

if (folder.riskAnalysis?.isSensitive) {
path =
colors[isFolderSelected ? 'blue' : DEFAULT_CONFIG.warningColor](path);
path = pc[isFolderSelected ? 'blue' : DEFAULT_CONFIG.warningColor](path);

@cubic-dev-ai cubic-dev-ai Bot Oct 23, 2025 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Selecting sensitive folders invokes pc[DEFAULT_CONFIG.warningColor], but picocolors has no "brightYellow" helper, so the CLI crashes with a TypeError.

Prompt for AI agents
Address the following comment on src/cli/ui/components/results.ui.ts at line 338:

<comment>Selecting sensitive folders invokes pc[DEFAULT_CONFIG.warningColor], but picocolors has no &quot;brightYellow&quot; helper, so the CLI crashes with a TypeError.</comment>

<file context>
@@ -335,10 +335,9 @@ export class ResultsUi extends HeavyUi implements InteractiveUi {
     if (folder.riskAnalysis?.isSensitive) {
-      path =
-        colors[isFolderSelected ? &#39;blue&#39; : DEFAULT_CONFIG.warningColor](path);
+      path = pc[isFolderSelected ? &#39;blue&#39; : DEFAULT_CONFIG.warningColor](path);
     } else if (!isRowSelected &amp;&amp; isFolderSelected) {
-      path = colors.blue(path);
</file context>
Fix with Cubic

'Unreal Engine derived data cache. Stores cooked/processed assets to speed up builds. Deleting forces re-cooking of assets. WARNING: Can be many GB. Safe to delete but rebuild will be slow.',
Saved:
'Unreal Engine saved files (logs, autosaves, cooked content, screenshots). Safe to delete but you may lose local editor settings, autosaves, and cooked assets. WARNING: May contain unsaved work!',
Binaries:

@cubic-dev-ai cubic-dev-ai Bot Oct 23, 2025 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Change this key to lowercase so Binaries folders surface their help text after the toLowerCase lookup.

Prompt for AI agents
Address the following comment on src/constants/result-descriptions.constants.ts at line 239:

<comment>Change this key to lowercase so Binaries folders surface their help text after the toLowerCase lookup.</comment>

<file context>
@@ -0,0 +1,300 @@
+    &#39;Unreal Engine derived data cache. Stores cooked/processed assets to speed up builds. Deleting forces re-cooking of assets. WARNING: Can be many GB. Safe to delete but rebuild will be slow.&#39;,
+  Saved:
+    &#39;Unreal Engine saved files (logs, autosaves, cooked content, screenshots). Safe to delete but you may lose local editor settings, autosaves, and cooked assets. WARNING: May contain unsaved work!&#39;,
+  Binaries:
+    &#39;Unreal Engine compiled binaries. Contains game/editor executables and DLLs. Regenerated by the build system. Safe to delete but requires full recompilation.&#39;,
+  &#39;.import&#39;: &#39;Godot imported assets cache. Re-imports on next run.&#39;,
</file context>
Fix with Cubic

"Unreal intermediate files (proper case). Delete to force a clean rebuild. WARNING: Generic name; verify it's in an Unreal project.",
DerivedDataCache:
'Unreal Engine derived data cache. Stores cooked/processed assets to speed up builds. Deleting forces re-cooking of assets. WARNING: Can be many GB. Safe to delete but rebuild will be slow.',
Saved:

@cubic-dev-ai cubic-dev-ai Bot Oct 23, 2025 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Lowercase this key so the Saved folder description is reachable after folderName.toLowerCase().

Prompt for AI agents
Address the following comment on src/constants/result-descriptions.constants.ts at line 237:

<comment>Lowercase this key so the Saved folder description is reachable after folderName.toLowerCase().</comment>

<file context>
@@ -0,0 +1,300 @@
+    &quot;Unreal intermediate files (proper case). Delete to force a clean rebuild. WARNING: Generic name; verify it&#39;s in an Unreal project.&quot;,
+  DerivedDataCache:
+    &#39;Unreal Engine derived data cache. Stores cooked/processed assets to speed up builds. Deleting forces re-cooking of assets. WARNING: Can be many GB. Safe to delete but rebuild will be slow.&#39;,
+  Saved:
+    &#39;Unreal Engine saved files (logs, autosaves, cooked content, screenshots). Safe to delete but you may lose local editor settings, autosaves, and cooked assets. WARNING: May contain unsaved work!&#39;,
+  Binaries:
</file context>
Fix with Cubic

"Unreal temp build files. Safe to delete but expect long rebuilds. WARNING: Generic name; verify it's in an Unreal project.",
Intermediate:
"Unreal intermediate files (proper case). Delete to force a clean rebuild. WARNING: Generic name; verify it's in an Unreal project.",
DerivedDataCache:

@cubic-dev-ai cubic-dev-ai Bot Oct 23, 2025 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Lowercase this key so users with DerivedDataCache directories see the info panel; the current casing prevents any match.

Prompt for AI agents
Address the following comment on src/constants/result-descriptions.constants.ts at line 235:

<comment>Lowercase this key so users with DerivedDataCache directories see the info panel; the current casing prevents any match.</comment>

<file context>
@@ -0,0 +1,300 @@
+    &quot;Unreal temp build files. Safe to delete but expect long rebuilds. WARNING: Generic name; verify it&#39;s in an Unreal project.&quot;,
+  Intermediate:
+    &quot;Unreal intermediate files (proper case). Delete to force a clean rebuild. WARNING: Generic name; verify it&#39;s in an Unreal project.&quot;,
+  DerivedDataCache:
+    &#39;Unreal Engine derived data cache. Stores cooked/processed assets to speed up builds. Deleting forces re-cooking of assets. WARNING: Can be many GB. Safe to delete but rebuild will be slow.&#39;,
+  Saved:
</file context>
Fix with Cubic

obj: 'Intermediate object files (.NET, C++, Unity). Deleting forces a full recompile next time. Safe to delete.',
'.vs':
'Visual Studio local workspace data. Safe to delete; VS will rehydrate it.',
TestResults: 'Visual Studio/.NET test result output. Toss it after runs.',

@cubic-dev-ai cubic-dev-ai Bot Oct 23, 2025 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This key must be lowercase to stay reachable after folderName.toLowerCase(); as written, descriptions for TestResults folders never appear.

Prompt for AI agents
Address the following comment on src/constants/result-descriptions.constants.ts at line 174:

<comment>This key must be lowercase to stay reachable after folderName.toLowerCase(); as written, descriptions for TestResults folders never appear.</comment>

<file context>
@@ -0,0 +1,300 @@
+  obj: &#39;Intermediate object files (.NET, C++, Unity). Deleting forces a full recompile next time. Safe to delete.&#39;,
+  &#39;.vs&#39;:
+    &#39;Visual Studio local workspace data. Safe to delete; VS will rehydrate it.&#39;,
+  TestResults: &#39;Visual Studio/.NET test result output. Toss it after runs.&#39;,
+  artifacts:
+    &#39;Generic build artifacts folder used by many .NET repos. Generated: safe to purge and rebuild.&#39;,
</file context>
Suggested change
TestResults: 'Visual Studio/.NET test result output. Toss it after runs.',
testresults: 'Visual Studio/.NET test result output. Toss it after runs.',
Fix with Cubic

}

render(): void {
throw new Error('Method not implemented.');

@cubic-dev-ai cubic-dev-ai Bot Oct 23, 2025 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

render() is required to draw the help UI, but this implementation always throws, so any BaseUi.setPosition/setVisible call on HelpCommandUi will crash instead of showing the help panel.

Prompt for AI agents
Address the following comment on src/cli/ui/components/help/help-command.ui.ts at line 19:

<comment>render() is required to draw the help UI, but this implementation always throws, so any BaseUi.setPosition/setVisible call on HelpCommandUi will crash instead of showing the help panel.</comment>

<file context>
@@ -0,0 +1,94 @@
+  }
+
+  render(): void {
+    throw new Error(&#39;Method not implemented.&#39;);
+  }
+
</file context>
Fix with Cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants