Skip to content

feat: migrate suitup to modular Node CLI#10

Open
ChangeHow wants to merge 8 commits intomainfrom
dev
Open

feat: migrate suitup to modular Node CLI#10
ChangeHow wants to merge 8 commits intomainfrom
dev

Conversation

@ChangeHow
Copy link
Owner

Summary

  • Replace legacy shell-script workflow with a modular Node.js CLI (setup, append, verify, clean) and step-based architecture.
  • Add shipped config templates under configs/ plus Vitest coverage for setup flows, config integrity, and shell syntax.
  • Update zsh setup behavior and docs, including startup optimizations, placeholder PATH config, and user-focused README/README.zh-CN split with architecture details in AGENTS.md.

@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request represents a significant architectural shift for the suitup project, transitioning from a collection of disparate shell scripts to a unified, modular Node.js command-line interface. This refactoring aims to improve the project's maintainability, extensibility, and overall user experience by providing a structured, interactive, and idempotent setup process. The changes streamline configuration management, enhance Zsh integration, and introduce robust testing, making the development environment setup more reliable and user-friendly.

Highlights

  • Modular Node.js CLI: Replaced the legacy shell-script workflow with a new modular Node.js CLI, introducing commands for setup, appending configurations, verifying installations, and cleaning up.
  • Enhanced Zsh Configuration: Updated Zsh setup behavior and documentation, including startup optimizations, a placeholder PATH configuration, and a layered configuration architecture under ~/.config/zsh/.
  • Comprehensive Documentation: Split the README.md into user-facing and contributor-facing documentation (AGENTS.md), providing detailed architecture and implementation notes for developers.
  • Config Templates and Testing: Added shipped config templates under configs/ for various Zsh components and introduced Vitest coverage for setup flows, config integrity, and shell syntax validation.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • .gitignore
    • Added Node.js specific ignore entries for node_modules/ and *.log.
  • AGENTS.md
    • Added a new document detailing project structure, Zsh architecture, templates, step behavior, testing notes, and documentation split for contributors.
  • README.md
    • Rewrote the entire README to reflect the new Node.js CLI, detailing features, usage, commands, installed components, file layout, testing, and requirements.
  • README.zh-CN.md
    • Added a new Chinese version of the README, mirroring the English one.
  • bootstrap.sh
    • Removed the legacy shell script, as its functionality is now integrated into the Node.js CLI.
  • clean.sh
    • Removed the legacy shell script, as its functionality is now integrated into the Node.js CLI.
  • configs/aliases
    • Added a new file containing shell aliases for utilities, Git, and search commands.
  • configs/config.vim
    • Added a new file with common Vim settings and shortcuts.
  • configs/core/env.zsh
    • Added a new file for general environment variables like ATUIN_CTRL_R_ENABLED and BAT_THEME.
  • configs/core/options.zsh
    • Added a new file for Zsh shell options and history settings, including AUTO_CD and history deduplication.
  • configs/core/paths.zsh
    • Added a new placeholder file for user-specific PATH configuration overrides.
  • configs/core/perf.zsh
    • Added a new file for Zsh startup timing and performance reporting.
  • configs/local/machine.zsh
    • Added a new placeholder file for machine-specific Zsh overrides.
  • configs/shared/prompt.zsh
    • Added a new file for prompt/theme loading, specifically for Powerlevel10k.
  • configs/shared/tools.zsh
    • Added a new file for external tool configuration and initialization, including FZF, Atuin, Zoxide, and FNM with caching mechanisms.
  • configs/zinit-plugins
    • Added a new file for Zinit plugin configuration, including zsh-autosuggestions, zsh-syntax-highlighting, and powerlevel10k.
  • configs/zshrc-omz.template
    • Added a new Zsh entry point template specifically for Oh My Zsh users.
  • configs/zshrc.template
    • Added a new Zsh entry point template for zinit users, orchestrating core and shared configurations.
  • package-lock.json
    • Updated dependencies and versions to support the new Node.js project structure and tools.
  • package.json
    • Added new Node.js project configuration, including scripts for start, setup, append, verify, clean, and test, along with new dependencies and dev dependencies like Vitest.
  • scripts/dev/vim-config.sh
    • Removed the legacy shell script, as its functionality is now integrated into the Node.js CLI.
  • scripts/dev/zsh-alias.sh
    • Removed the legacy shell script, as its functionality is now integrated into the Node.js CLI.
  • scripts/init/apps.sh
    • Removed the legacy shell script, as its functionality is now integrated into the Node.js CLI.
  • scripts/init/clean-dock.sh
    • Removed the legacy shell script, as its functionality is now integrated into the Node.js CLI.
  • scripts/init/command-line-tools.sh
    • Removed the legacy shell script, as its functionality is now integrated into the Node.js CLI.
  • scripts/init/front-end.sh
    • Removed the legacy shell script, as its functionality is now integrated into the Node.js CLI.
  • scripts/init/init-configs.sh
    • Removed the legacy shell script, as its functionality is now integrated into the Node.js CLI.
  • scripts/init/install-zsh-plugins.sh
    • Removed the legacy shell script, as its functionality is now integrated into the Node.js CLI.
  • scripts/init/ssh.sh
    • Removed the legacy shell script, as its functionality is now integrated into the Node.js CLI.
  • scripts/utils/log.sh
    • Removed the legacy shell script, as its functionality is now integrated into the Node.js CLI.
  • snippets/zvm-fzf.snippet.sh
    • Removed the snippet, as its functionality is now integrated into the new Node.js CLI.
  • src/append.js
    • Added a new module for the append CLI command, allowing users to add recommended configurations to an existing .zshrc.
  • src/clean.js
    • Added a new module for the clean CLI command, providing functionality to remove suitup-managed config files.
  • src/cli.js
    • Added the main entry point for the new modular Node.js CLI, dispatching commands like setup, append, verify, and clean.
  • src/constants.js
    • Added constants for file paths and markers used throughout the Node.js CLI.
  • src/setup.js
    • Added the main module for the interactive setup CLI command, orchestrating various installation steps.
  • src/steps/aliases.js
    • Added a module to handle the setup of shell aliases.
  • src/steps/apps.js
    • Added a module to handle the installation of GUI applications via Homebrew Cask.
  • src/steps/bootstrap.js
    • Added a module to handle the initial package manager and Zsh installation, supporting macOS and Linux.
  • src/steps/cli-tools.js
    • Added a module to handle the installation of command-line tools via Homebrew.
  • src/steps/dock.js
    • Added a module to handle macOS Dock cleanup and preference setting.
  • src/steps/frontend.js
    • Added a module to handle the installation of frontend development tools like FNM, Node.js, and pnpm.
  • src/steps/plugin-manager.js
    • Added a module to handle the installation of Zsh plugin managers, supporting both zinit and Oh My Zsh.
  • src/steps/ssh.js
    • Added a module to handle SSH key generation for GitHub.
  • src/steps/vim.js
    • Added a module to handle Vim configuration setup.
  • src/steps/zsh-config.js
    • Added a module to handle the creation of the Zsh configuration directory structure and .zshrc file generation from templates.
  • src/utils/fs.js
    • Added utility functions for file system operations, including directory creation, file writing, and safe reading.
  • src/utils/shell.js
    • Added utility functions for executing shell commands synchronously and asynchronously, and checking command existence.
  • src/verify.js
    • Added a new module for the verify CLI command, which checks installation integrity of configs and tools, and performs shell syntax validation.
  • tests/append.test.js
    • Added new Vitest tests for the append mode utilities, ensuring correct content appending and idempotency.
  • tests/apps.test.js
    • Added new Vitest tests for the apps installation step, verifying correct installation and skipping behavior.
  • tests/bootstrap.test.js
    • Added new Vitest tests for the bootstrap step, covering Homebrew and Zsh installation scenarios.
  • tests/cli-tools.test.js
    • Added new Vitest tests for the CLI tools installation step, verifying correct installation and skipping behavior.
  • tests/configs.test.js
    • Added new Vitest tests for static config templates, ensuring content integrity and absence of forbidden patterns.
  • tests/dock.test.js
    • Added new Vitest tests for the dock cleanup step, verifying user confirmation and command execution.
  • tests/frontend.test.js
    • Added new Vitest tests for the frontend tools installation step, covering FNM, Node.js, pnpm, and git-cz installation.
  • tests/helpers.js
    • Added new helper utilities for testing, including sandbox creation.
  • tests/plugin-manager.test.js
    • Added new Vitest tests for the plugin manager installation step, covering zinit and Oh My Zsh scenarios.
  • tests/setup.test.js
    • Added new Vitest tests for the overall setup process, simulating config structure creation and template usage.
  • tests/ssh.test.js
    • Added new Vitest tests for the SSH key setup step, verifying key generation and skipping behavior.
  • tests/verify.test.js
    • Added new Vitest tests for the verify mode, checking config presence and Zsh syntax validation.
  • tests/zsh-config-steps.test.js
    • Added new Vitest tests for the Zsh configuration steps, covering directory structure creation and .zshrc writing logic.
  • vitest.config.js
    • Added Vitest configuration file for running tests.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request represents a significant and impressive migration from a collection of shell scripts to a modern, modular Node.js CLI. The new architecture, built with @clack/prompts and vitest, greatly improves the user experience, maintainability, and testability of the project. The introduction of distinct commands (setup, append, verify, clean) and a layered Zsh configuration is a very well-thought-out design. My review includes a few minor suggestions for improving documentation clarity, robustness, and security.

Note: Security Review did not run due to the size of the PR.

Copy link

Copilot AI commented Mar 10, 2026

@ChangeHow I've opened a new pull request, #11, to work on those changes. Once the pull request is ready, I'll request review from you.

The `local/secrets.zsh` reference in `AGENTS.md` was ambiguous — it
omitted the full installed path, inconsistent with how the zshrc
templates source it and the layout described in `README.md`.

## Changes

- **`AGENTS.md`**: Updated `local/secrets.zsh` →
`~/.config/zsh/local/secrets.zsh` in the Local files section

<!-- START COPILOT CODING AGENT TIPS -->
---

✨ Let Copilot coding agent [set things up for
you](https://github.com/ChangeHow/suitup/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ChangeHow <23733347+ChangeHow@users.noreply.github.com>
Copy link

Copilot AI commented Mar 10, 2026

@ChangeHow I've opened a new pull request, #12, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link

Copilot AI commented Mar 10, 2026

@ChangeHow I've opened a new pull request, #13, to work on those changes. Once the pull request is ready, I'll request review from you.

@ChangeHow
Copy link
Owner Author

@copilot add a github action to current PR, it would run all the test cases in every PR and commit.

Copy link

Copilot AI commented Mar 10, 2026

@ChangeHow I've opened a new pull request, #14, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 3 commits March 10, 2026 23:17
- [x] Investigate CI failure logs
- [x] Fix: add `apt-get install zsh` step — tests use `zsh -n` for
syntax checking but zsh is not pre-installed on ubuntu-latest

<!-- START COPILOT CODING AGENT TIPS -->
---

✨ Let Copilot coding agent [set things up for
you](https://github.com/ChangeHow/suitup/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ChangeHow <23733347+ChangeHow@users.noreply.github.com>
Copy link

Copilot AI commented Mar 10, 2026

@ChangeHow I've opened a new pull request, #15, to work on those changes. Once the pull request is ready, I'll request review from you.

@ChangeHow
Copy link
Owner Author

/gemini review

@ChangeHow
Copy link
Owner Author

/gemini summary

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request successfully migrates the suitup tool from a collection of shell scripts to a modern, modular Node.js CLI, which is a significant improvement with clear separation of concerns into different commands (setup, append, verify, clean) and logical steps. While the new architecture, comprehensive Vitest test suite, and updated documentation are commendable, a critical command injection vulnerability was identified in the SSH key generation step. User-supplied input (email) is directly interpolated into a shell command string, which could allow for arbitrary code execution. This must be addressed by using environment variables or avoiding shell execution for this command. Additionally, please review the minor issues detailed in the specific comments.

Comment on lines +44 to +47
await runStream(
`ssh-keygen -t rsa -b 4096 -C "${email}" -f "${keyFile}" -N "$SSH_KEYGEN_PASSPHRASE"`,
{ env: { ...process.env, SSH_KEYGEN_PASSPHRASE: passphrase } }
);

Choose a reason for hiding this comment

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

security-high high

The email variable, obtained from user input via p.text, is directly interpolated into a shell command string without sanitization. This command is then executed using runStream, which calls spawn("bash", ["-c", cmd]). An attacker can provide an input containing shell metacharacters (e.g., ;, $(...), or backticks) to execute arbitrary commands with the privileges of the user running the script.

To remediate this, pass the email address via an environment variable, similar to how the passphrase is handled. This prevents the shell from interpreting the content of the email as part of the command structure.

Suggested change
await runStream(
`ssh-keygen -t rsa -b 4096 -C "${email}" -f "${keyFile}" -N "$SSH_KEYGEN_PASSPHRASE"`,
{ env: { ...process.env, SSH_KEYGEN_PASSPHRASE: passphrase } }
);
await runStream(
`ssh-keygen -t rsa -b 4096 -C "$SSH_KEYGEN_EMAIL" -f "${keyFile}" -N "$SSH_KEYGEN_PASSPHRASE"`,
{ env: { ...process.env, SSH_KEYGEN_EMAIL: email, SSH_KEYGEN_PASSPHRASE: passphrase } }
);

Copy link
Owner Author

Choose a reason for hiding this comment

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

@copilot valuable suggestion, solve it and add some test cases.

Comment on lines +96 to +98
export function projectRoot() {
return join(import.meta.dirname, "..", "..");
}

Choose a reason for hiding this comment

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

medium

The projectRoot function uses import.meta.dirname, which is not a standard property in Node.js ES modules and will be undefined at runtime, causing the function to fail if called. To correctly get the directory path, you should use dirname(fileURLToPath(import.meta.url)), as you've done in src/constants.js. Although this function appears to be unused currently, it's best to fix it to prevent future bugs.

You'll also need to add import { fileURLToPath } from "node:url"; at the top of the file.

Suggested change
export function projectRoot() {
return join(import.meta.dirname, "..", "..");
}
export function projectRoot() {
return join(dirname(fileURLToPath(import.meta.url)), "..", "..");
}

Copy link
Owner Author

Choose a reason for hiding this comment

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

@copilot add a node version checker before running script and make sure user running node withnative ESM support.

@gemini-code-assist
Copy link

Summary of Changes

This pull request represents a significant architectural overhaul of the suitup project, moving from a shell-script-based system to a modern, modular Node.js command-line interface. This transition aims to provide a more robust, maintainable, and user-friendly experience for setting up development environments. The changes introduce interactive setup flows, structured configuration management, and comprehensive testing, fundamentally improving the project's foundation and future extensibility.

Highlights

  • Modular Node.js CLI: The project was migrated from a collection of shell scripts to a modular Node.js CLI, introducing setup, append, verify, and clean commands for a structured and interactive experience.
  • Enhanced Zsh Configuration: A new layered Zsh configuration architecture was implemented under ~/.config/zsh/, featuring core, shared, and local configuration files, along with startup performance optimizations.
  • Comprehensive Documentation: Documentation was significantly improved with a split between user-facing (README.md, README.zh-CN.md) and contributor-focused (AGENTS.md) content, detailing architecture and implementation.
  • Extensive Test Coverage: New Vitest tests were added across various modules to ensure the integrity of setup flows, configuration files, and shell syntax, enhancing reliability.
  • Legacy Script Removal: All previous shell scripts (e.g., bootstrap.sh, clean.sh, and those under scripts/) were removed, streamlining the project and consolidating functionality within the new Node.js CLI.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • .gitignore
    • Updated to include Node.js specific ignore patterns for node_modules/ and *.log.
  • AGENTS.md
    • Added a new document detailing project structure, Zsh architecture, templates, step behavior, testing notes, and documentation split for contributors.
  • README.md
    • Rewritten to reflect the new Node.js CLI, detailing features, usage, commands, installed components, file layout, testing, and requirements.
  • README.zh-CN.md
    • Added a new Chinese version of the README, mirroring the English one.
  • bootstrap.sh
    • Removed as its functionality was integrated into the new Node.js CLI.
  • clean.sh
    • Removed as its functionality was integrated into the new Node.js CLI.
  • configs/aliases
    • Added shell aliases for common utilities, Git, and search commands.
  • configs/config.vim
    • Added basic Vim configuration settings and shortcuts.
  • configs/core/env.zsh
    • Added general environment variables for Zsh, including ATUIN_CTRL_R_ENABLED and BAT_THEME.
  • configs/core/options.zsh
    • Added Zsh shell options and history settings, such as AUTO_CD and history deduplication.
  • configs/core/paths.zsh
    • Added a placeholder file for user-specific PATH configuration overrides.
  • configs/core/perf.zsh
    • Added Zsh startup timing and performance reporting logic.
  • configs/local/machine.zsh
    • Added a placeholder file for machine-specific Zsh overrides.
  • configs/shared/prompt.zsh
    • Added configuration for prompt/theme loading, specifically for Powerlevel10k.
  • configs/shared/tools.zsh
    • Added configuration for external tool initialization, including FZF, Atuin, Zoxide, and FNM, with caching mechanisms.
  • configs/zinit-plugins
    • Added Zinit plugin definitions for zsh-autosuggestions, zsh-syntax-highlighting, and powerlevel10k.
  • configs/zshrc-omz.template
    • Added a Zsh entry point template specifically for Oh My Zsh users.
  • configs/zshrc.template
    • Added a Zsh entry point template for zinit users, orchestrating core and shared configurations.
  • package-lock.json
    • Updated to reflect new Node.js dependencies and versions.
  • package.json
    • Added Node.js project metadata, scripts for start, setup, append, verify, clean, and test, along with new dependencies and dev dependencies like Vitest.
  • scripts/dev/vim-config.sh
    • Removed as its functionality was integrated into the new Node.js CLI.
  • scripts/dev/zsh-alias.sh
    • Removed as its functionality was integrated into the new Node.js CLI.
  • scripts/init/apps.sh
    • Removed as its functionality was integrated into the new Node.js CLI.
  • scripts/init/clean-dock.sh
    • Removed as its functionality was integrated into the new Node.js CLI.
  • scripts/init/command-line-tools.sh
    • Removed as its functionality was integrated into the new Node.js CLI.
  • scripts/init/front-end.sh
    • Removed as its functionality was integrated into the new Node.js CLI.
  • scripts/init/init-configs.sh
    • Removed as its functionality was integrated into the new Node.js CLI.
  • scripts/init/install-zsh-plugins.sh
    • Removed as its functionality was integrated into the new Node.js CLI.
  • scripts/init/ssh.sh
    • Removed as its functionality was integrated into the new Node.js CLI.
  • scripts/utils/log.sh
    • Removed as its functionality was integrated into the new Node.js CLI.
  • snippets/zvm-fzf.snippet.sh
    • Removed as its functionality was integrated into the new Node.js CLI.
  • src/append.js
    • Added the implementation for the append CLI command, allowing users to add recommended configurations to an existing .zshrc.
  • src/clean.js
    • Added the implementation for the clean CLI command, providing functionality to remove suitup-managed config files.
  • src/cli.js
    • Added the main entry point for the new modular Node.js CLI, dispatching commands like setup, append, verify, and clean.
  • src/constants.js
    • Added constants for file paths and markers used throughout the Node.js CLI.
  • src/setup.js
    • Added the core logic for the interactive setup CLI command, orchestrating various installation steps.
  • src/steps/aliases.js
    • Added logic for setting up shell aliases.
  • src/steps/apps.js
    • Added logic for installing GUI applications via Homebrew Cask.
  • src/steps/bootstrap.js
    • Added logic for bootstrapping package managers and Zsh installation, supporting macOS and Linux.
  • src/steps/cli-tools.js
    • Added logic for installing command-line tools via Homebrew.
  • src/steps/dock.js
    • Added logic for cleaning up the macOS Dock and setting preferences.
  • src/steps/frontend.js
    • Added logic for installing frontend development tools like FNM, Node.js, and pnpm.
  • src/steps/plugin-manager.js
    • Added logic for installing Zsh plugin managers, supporting both zinit and Oh My Zsh.
  • src/steps/ssh.js
    • Added logic for generating SSH keys for GitHub.
  • src/steps/vim.js
    • Added logic for setting up Vim configuration.
  • src/steps/zsh-config.js
    • Added logic for creating the Zsh configuration directory structure and .zshrc file generation from templates.
  • src/utils/fs.js
    • Added utility functions for file system operations, including directory creation, file writing, and safe reading.
  • src/utils/shell.js
    • Added utility functions for executing shell commands synchronously and asynchronously, and checking command existence.
  • src/verify.js
    • Added the implementation for the verify CLI command, which checks installation integrity of configs and tools, and performs shell syntax validation.
  • tests/append.test.js
    • Added Vitest tests for the append mode utilities, ensuring correct content appending and idempotency.
  • tests/apps.test.js
    • Added Vitest tests for the apps installation step, verifying correct installation and skipping behavior.
  • tests/bootstrap.test.js
    • Added Vitest tests for the bootstrap step, covering Homebrew and Zsh installation scenarios.
  • tests/cli-tools.test.js
    • Added Vitest tests for the CLI tools installation step, verifying correct installation and skipping behavior.
  • tests/configs.test.js
    • Added Vitest tests for static config templates, ensuring content integrity and absence of forbidden patterns.
  • tests/dock.test.js
    • Added Vitest tests for the dock cleanup step, verifying user confirmation and command execution.
  • tests/frontend.test.js
    • Added Vitest tests for the frontend tools installation step, covering FNM, Node.js, pnpm, and git-cz installation.
  • tests/helpers.js
    • Added helper utilities for testing, including sandbox creation.
  • tests/plugin-manager.test.js
    • Added Vitest tests for the plugin manager installation step, covering zinit and Oh My Zsh scenarios.
  • tests/setup.test.js
    • Added Vitest tests for the overall setup process, simulating config structure creation and template usage.
  • tests/ssh.test.js
    • Added Vitest tests for the SSH key setup step, verifying key generation and skipping behavior.
  • tests/verify.test.js
    • Added Vitest tests for the verify mode, checking config presence and Zsh syntax validation.
  • tests/zsh-config-steps.test.js
    • Added Vitest tests for the Zsh configuration steps, covering directory structure creation and .zshrc writing logic.
  • vitest.config.js
    • Added Vitest configuration file for running tests.
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/test.yml
Activity

The `fzf-config` append block extracted FZF env vars from `tools.zsh` by
splitting on a comment string (`# Tool initialization`), silently
breaking if that comment ever changed. Additionally, the Powerlevel10k
theme was being loaded in the suitup stage instead of as the final step.

## Changes

- **`configs/shared/fzf.zsh`** — new standalone file holding only
`FZF_DEFAULT_COMMAND`, `FZF_CTRL_T_COMMAND`, and `FZF_CTRL_T_OPTS`
- **`configs/shared/tools.zsh`** — FZF vars removed; replaced with an
inline conditional source of `fzf.zsh` (avoids `source_if_exists`
dependency):
  ```zsh
[[ -f "${ZDOTDIR:-$HOME/.config/zsh}/shared/fzf.zsh" ]] && source
"${ZDOTDIR:-$HOME/.config/zsh}/shared/fzf.zsh"
  ```
- **`src/append.js`** — `fzf-config` block reads `fzf.zsh` directly via
`readFileSync` instead of parsing `tools.zsh`
- **`src/steps/zsh-config.js`** — `fzf.zsh` added to `sharedFiles` so
it's copied to `~/.config/zsh/shared/` during setup
- **`configs/zinit-plugins`** — removed `zinit light
romkatv/powerlevel10k` so p10k is no longer loaded in the suitup stage
(step 7)
- **`configs/shared/prompt.zsh`** — now loads the p10k theme as the very
last step (prompt stage, step 9), guarded with `(( ${+functions[zinit]}
))` so it is a no-op for OMZ setups where p10k is handled by OMZ itself
- **Tests** — 6 new cases in `append.test.js` assert `fzf.zsh` exists
standalone, contains only FZF vars (no cache helpers), and that the
appended block is idempotent; `configs.test.js` updated to assert p10k
is in `prompt.zsh` (not `zinit-plugins`) and `setup.test.js` asserts
`prompt.zsh` is sourced after `zinit-plugins` in the template loading
order

<!-- START COPILOT CODING AGENT TIPS -->
---

✨ Let Copilot coding agent [set things up for
you](https://github.com/ChangeHow/suitup/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ChangeHow <23733347+ChangeHow@users.noreply.github.com>
Copy link

Copilot AI commented Mar 11, 2026

@ChangeHow I've opened a new pull request, #16, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link

Copilot AI commented Mar 11, 2026

@ChangeHow I've opened a new pull request, #17, to work on those changes. Once the pull request is ready, I'll request review from you.

`cli.js` uses top-level `await` and native ESM, requiring Node ≥ 18.
There was no runtime guard against older versions, and `src/utils/fs.js`
had a silent bug (`import.meta.dirname` is non-standard and returns
`undefined`).

## Changes

- **`src/utils/node-version.js`** — new utility; checks
`process.version` against the Node 18 minimum and exits with a clear
upgrade message if not met
- **`src/cli.js`** — calls `checkNodeVersion()` before any setup logic
- **`package.json`** — adds `"engines": { "node": ">=18.0.0" }` for
tooling-level enforcement
- **`src/utils/fs.js`** — fixes `projectRoot()` to use
`dirname(fileURLToPath(import.meta.url))` instead of
`import.meta.dirname`

```js
// src/utils/node-version.js
export function checkNodeVersion() {
  const major = parseInt(process.version.replace(/^v/, "").split(".")[0], 10);
  if (major < 18) {
    console.error(
      `suitup requires Node.js 18 or later for native ESM support.\n` +
      `You are running Node.js ${process.version}.\n` +
      `Please upgrade: https://nodejs.org/en/download`
    );
    process.exit(1);
  }
}
```

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ChangeHow <23733347+ChangeHow@users.noreply.github.com>
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