feat(cli): add 'init' command for configuration setup#45
Conversation
- Add vectorlint init command to generate .vectorlint.ini and .env.vectorlint - Include --force flag to overwrite existing files - Print user-friendly next steps after generation - Add unit tests for init command
📝 WalkthroughWalkthroughAdds a new Changes
Sequence Diagram(s)mermaid Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
📜 Recent review detailsConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (1)src/**/*.ts📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧬 Code graph analysis (1)src/index.ts (2)
🔇 Additional comments (5)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/cli/init-command.ts (1)
56-56: Consider moving ENV_FILENAME to constants.ts for consistency.The constant
DEFAULT_CONFIG_FILENAMEis imported fromsrc/config/constants.ts, whileENV_FILENAMEis defined locally. For better maintainability and consistency, consider movingENV_FILENAMEto the constants file alongsideDEFAULT_CONFIG_FILENAME.🔎 Proposed refactor
In
src/config/constants.ts, add:export const ENV_FILENAME = '.env.vectorlint';Then update the import in this file:
-import { DEFAULT_CONFIG_FILENAME } from '../config/constants'; +import { DEFAULT_CONFIG_FILENAME, ENV_FILENAME } from '../config/constants';And remove the local constant definition:
-const ENV_FILENAME = '.env.vectorlint';
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
eslint.config.mjs(1 hunks)src/cli/init-command.ts(1 hunks)src/index.ts(2 hunks)tests/init-command.test.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
src/cli/init-command.ts (1)
src/config/constants.ts (1)
DEFAULT_CONFIG_FILENAME(5-5)
tests/init-command.test.ts (2)
src/config/constants.ts (1)
DEFAULT_CONFIG_FILENAME(5-5)src/cli/init-command.ts (1)
registerInitCommand(66-115)
src/index.ts (1)
src/cli/init-command.ts (1)
registerInitCommand(66-115)
🔇 Additional comments (11)
src/cli/init-command.ts (5)
6-16: LGTM! Well-structured configuration template.The template provides sensible defaults and clear structure. Leaving
RulesPathempty is appropriate since users need to specify their rules directory, and this is clearly communicated in the success message.
18-54: LGTM! Excellent environment template with good security practices.The template is comprehensive and well-documented. Having all sensitive configurations commented out by default prevents users from accidentally committing API keys. The multi-provider support with clear setup instructions will help users get started quickly.
76-93: LGTM! Excellent safety checks with clear user feedback.The logic correctly prevents accidental overwrites and provides helpful error messages. Collecting and displaying all existing files at once (rather than failing on the first one) improves the user experience.
95-103: LGTM! Robust error handling.The error handling properly catches write failures, safely handles unknown error types, and provides descriptive error messages. Specifying UTF-8 encoding explicitly is good practice.
105-114: LGTM! Clear and actionable success messages.The success output provides users with a clear roadmap for the next steps. Using template literals to reference actual filenames ensures the messages stay accurate if constants change.
eslint.config.mjs (1)
129-134: LGTM! Appropriate ESLint exemption for CLI command.Adding
src/cli/init-command.tsto the process-exit exemption list is correct since CLI commands need to exit with appropriate status codes. This follows the established pattern for other CLI command modules.src/index.ts (1)
8-8: LGTM! Clean integration of the init command.The import and registration follow the established pattern for CLI commands. Registering the init command first is sensible since it's a setup/bootstrap command that users would typically run before other commands.
Also applies to: 64-64
tests/init-command.test.ts (4)
15-24: LGTM! Excellent test isolation and cleanup.The setup/teardown properly isolates each test in a unique temporary directory and ensures thorough cleanup. Saving and restoring
process.cwd()prevents test pollution.
26-71: LGTM! Comprehensive file generation tests.The tests properly verify both file creation and content validity. Using dynamic imports ensures test isolation. The content assertions check for key configuration values without being overly brittle.
73-111: LGTM! Thorough safety check tests.The tests properly verify that existing files are not overwritten without the
--forceflag. UsingexitOverride()to test error cases and verifying that original content is preserved are both excellent testing practices.
113-136: LGTM! Force flag test properly verifies overwrite behavior.The test correctly verifies that existing files are overwritten when
--forceis provided. Pre-populating files with old content ensures the test actually validates overwrite behavior rather than just file creation.
…injection - Create global-config.ts module for managing user-level configuration - Add getGlobalConfigPath() to resolve global config location in user home directory - Implement ensureGlobalConfig() to create config file with template if missing - Implement loadGlobalConfig() to parse TOML and inject [env] variables into process.env - Add GLOBAL_CONFIG_SCHEMA validation for configuration structure - Include comprehensive template with examples for all supported LLM providers - Ensure CLI/shell environment variables take precedence over global config - Add graceful error handling to prevent crashes on config load failures - Enable users to store API keys and provider settings in a centralized location
- Add smol-toml dependency for TOML file parsing - Create comprehensive test suite for global config loader functionality - Add tests for environment variable injection from TOML configuration - Add tests to verify existing environment variables are not overwritten - Add tests for graceful handling of missing config files - Add tests for invalid TOML error handling - Update init command tests to mock global config module - Replace .env.vectorlint file generation with global config initialization - Simplify init command test by removing environment file assertions - Remove redundant file overwrite protection tests for env files
- Reorganize quick start steps to prioritize initialization command - Update configuration instructions to reflect global config at ~/.vectorlint/config.toml - Add reference to vectorlint init command for automatic file generation - Clarify precedence of project-scoped .env over global configuration - Simplify LLM provider setup instructions with TOML example - Update CONFIGURATION.md to document global and project-scoped configuration options - Improve documentation flow to guide users through initialization before rule creation
- Remove unused zod import from global-config.ts - Remove unused getGlobalConfigPath import from global-config.test.ts - Rename mockEnsureGlobalConfig to MOCK_ENSURE_GLOBAL_CONFIG for consistency with constant naming conventions - Update all references to use the new constant name in init-command.test.ts - Improve code clarity and reduce unnecessary dependencies
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
README.md (1)
53-66: Consider documenting the--forceflag for re-initialization scenarios.The PR objectives mention a
--forceflag to overwrite existing files. This might be helpful to document in the Quick Start section for users who need to regenerate or reset their configuration.Consider adding a brief note after line 59:
To regenerate configuration files and overwrite existing ones, use: ```bash vectorlint init --force</blockquote></details> </blockquote></details> <details> <summary>📜 Review details</summary> **Configuration used**: defaults **Review profile**: CHILL **Plan**: Pro <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 8d7403854e2b57e2772bf86ed0e2329b335f23d2 and d9c41b32a6cd6720eaed01135eb18ee74016b323. </details> <details> <summary>⛔ Files ignored due to path filters (1)</summary> * `package-lock.json` is excluded by `!**/package-lock.json` </details> <details> <summary>📒 Files selected for processing (10)</summary> * `CONFIGURATION.md` * `README.md` * `package.json` * `src/cli/init-command.ts` * `src/config/constants.ts` * `src/config/global-config.ts` * `src/index.ts` * `src/schemas/env-schemas.ts` * `tests/global-config.test.ts` * `tests/init-command.test.ts` </details> <details> <summary>🚧 Files skipped from review as they are similar to previous changes (1)</summary> * tests/init-command.test.ts </details> <details> <summary>🧰 Additional context used</summary> <details> <summary>📓 Path-based instructions (2)</summary> <details> <summary>src/**/*.ts</summary> **📄 CodeRabbit inference engine (AGENTS.md)** > `src/**/*.ts`: Use TypeScript ESM with explicit imports and narrow types > Use 2-space indentation; avoid trailing whitespace > Maintain strict TypeScript with no `any`; use `unknown` + schema validation for external data > Use custom error types with proper inheritance; catch blocks use `unknown` type Files: - `src/config/constants.ts` - `src/cli/init-command.ts` - `src/config/global-config.ts` - `src/schemas/env-schemas.ts` - `src/index.ts` </details> <details> <summary>tests/**/*.test.ts</summary> **📄 CodeRabbit inference engine (AGENTS.md)** > `tests/**/*.test.ts`: Write tests using Vitest framework with focus on config parsing, file discovery, schema/structured output, and locator > Use dependency injection in tests: mock providers; do not hit network in unit tests Files: - `tests/global-config.test.ts` </details> </details><details> <summary>🧠 Learnings (6)</summary> <details> <summary>📚 Learning: 2025-12-28T19:43:51.176Z</summary>Learnt from: CR
Repo: TRocket-Labs/vectorlint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T19:43:51.176Z
Learning: Applies to src/providers/**/*.ts : Depend onLLMProviderandSearchProviderinterfaces; keep providers thin (transport only)**Applied to files:** - `CONFIGURATION.md` </details> <details> <summary>📚 Learning: 2025-12-28T19:43:51.176Z</summary>Learnt from: CR
Repo: TRocket-Labs/vectorlint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T19:43:51.176Z
Learning: Never commit secrets;.envis gitignored and should be copied from.env.example**Applied to files:** - `src/cli/init-command.ts` </details> <details> <summary>📚 Learning: 2025-12-28T19:43:51.176Z</summary>Learnt from: CR
Repo: TRocket-Labs/vectorlint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T19:43:51.176Z
Learning: Applies to src/boundaries/env-parser.ts : All environment variables must be validated via Zod schemas insrc/boundaries/env-parser.ts**Applied to files:** - `src/schemas/env-schemas.ts` </details> <details> <summary>📚 Learning: 2025-12-28T19:43:51.176Z</summary>Learnt from: CR
Repo: TRocket-Labs/vectorlint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T19:43:51.176Z
Learning: Applies to src/boundaries/**/*.ts : Use Zod schemas for boundary validation of all external data (files, CLI, env, APIs) at system boundaries**Applied to files:** - `src/schemas/env-schemas.ts` </details> <details> <summary>📚 Learning: 2025-12-28T19:43:51.176Z</summary>Learnt from: CR
Repo: TRocket-Labs/vectorlint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T19:43:51.176Z
Learning: Applies to tests/**/*.test.ts : Write tests using Vitest framework with focus on config parsing, file discovery, schema/structured output, and locator**Applied to files:** - `tests/global-config.test.ts` </details> <details> <summary>📚 Learning: 2025-12-28T19:43:51.176Z</summary>Learnt from: CR
Repo: TRocket-Labs/vectorlint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T19:43:51.176Z
Learning: Applies to tests/**/*.test.ts : Use dependency injection in tests: mock providers; do not hit network in unit tests**Applied to files:** - `tests/global-config.test.ts` </details> </details><details> <summary>🧬 Code graph analysis (4)</summary> <details> <summary>src/cli/init-command.ts (2)</summary><blockquote> <details> <summary>src/config/constants.ts (1)</summary> * `DEFAULT_CONFIG_FILENAME` (6-6) </details> <details> <summary>src/config/global-config.ts (2)</summary> * `ensureGlobalConfig` (63-76) * `getGlobalConfigPath` (9-11) </details> </blockquote></details> <details> <summary>src/config/global-config.ts (3)</summary><blockquote> <details> <summary>src/config/constants.ts (2)</summary> * `GLOBAL_CONFIG_DIR` (7-7) * `GLOBAL_CONFIG_FILE` (8-8) </details> <details> <summary>src/schemas/env-schemas.ts (1)</summary> * `GLOBAL_CONFIG_SCHEMA` (47-49) </details> <details> <summary>src/errors/index.ts (1)</summary> * `handleUnknownError` (46-51) </details> </blockquote></details> <details> <summary>tests/global-config.test.ts (2)</summary><blockquote> <details> <summary>src/config/constants.ts (2)</summary> * `GLOBAL_CONFIG_DIR` (7-7) * `GLOBAL_CONFIG_FILE` (8-8) </details> <details> <summary>src/config/global-config.ts (1)</summary> * `loadGlobalConfig` (82-106) </details> </blockquote></details> <details> <summary>src/index.ts (2)</summary><blockquote> <details> <summary>src/config/global-config.ts (1)</summary> * `loadGlobalConfig` (82-106) </details> <details> <summary>src/cli/init-command.ts (1)</summary> * `registerInitCommand` (28-71) </details> </blockquote></details> </details> </details> <details> <summary>🔇 Additional comments (13)</summary><blockquote> <details> <summary>src/schemas/env-schemas.ts (1)</summary><blockquote> `47-49`: **LGTM!** The schema correctly validates the global configuration structure with appropriate type constraints. The optional `env` field and union type for values align well with TOML capabilities and the injection behavior in `loadGlobalConfig`. </blockquote></details> <details> <summary>CONFIGURATION.md (1)</summary><blockquote> `65-67`: **LGTM!** The documentation accurately reflects the configuration hierarchy and provides clear guidance on using the global config alongside project-level `.env` files. </blockquote></details> <details> <summary>src/config/constants.ts (1)</summary><blockquote> `7-8`: **LGTM!** The constants are well-named and provide a single source of truth for the global configuration file location. </blockquote></details> <details> <summary>src/index.ts (1)</summary><blockquote> `8-9`: **LGTM!** The environment loading refactor correctly implements the documented precedence hierarchy (Shell/CLI > Local .env > Global config). The integration of global config loading and init command registration is clean and preserves existing error handling patterns. Also applies to: 18-57, 60-60, 69-69 </blockquote></details> <details> <summary>tests/global-config.test.ts (1)</summary><blockquote> `26-86`: **LGTM!** The test suite provides comprehensive coverage of the global config loader, including success paths (loading and type conversion), preservation of existing environment variables, and graceful error handling for missing or invalid configs. The use of mocks properly isolates the tests from the filesystem. </blockquote></details> <details> <summary>src/cli/init-command.ts (2)</summary><blockquote> `8-17`: **LGTM!** The configuration template provides sensible defaults and clear placeholders for users to customize. --- `28-70`: **LGTM!** The init command implementation is clean and user-friendly. It properly validates existing files, provides clear error messages, creates both local and global configs, and offers helpful next-step guidance. The error handling is appropriate for a CLI command. </blockquote></details> <details> <summary>src/config/global-config.ts (4)</summary><blockquote> `9-11`: **LGTM!** The path resolution correctly uses the home directory and config constants. --- `13-57`: **LGTM!** The template provides comprehensive examples for all supported providers with helpful comments. The commented-out configuration approach allows users to uncomment only what they need. --- `63-76`: **LGTM!** The function properly ensures the directory and file exist with appropriate defaults, using recursive directory creation for reliability. --- `82-106`: **LGTM!** The loader implements correct environment variable injection with proper precedence (existing env vars are preserved). The graceful error handling ensures the application remains resilient even if the global config is malformed. </blockquote></details> <details> <summary>package.json (1)</summary><blockquote> `64-64`: **smol-toml version ^1.6.0 is valid, stable, and free from known vulnerabilities.** Version 1.6.0 is the current latest release on npm, actively maintained, and has no known security advisories. </blockquote></details> <details> <summary>README.md (1)</summary><blockquote> `67-77`: **Excellent documentation of global config and environment variable precedence.** The explanation of how to configure API keys in the global config is clear, and explicitly noting that local `.env` takes precedence is valuable context for users. </blockquote></details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
feat(cli): add 'init' command for configuration setup
Introduces a
vectorlint initcommand that automates the setup process by generating configuration files with verified templates.Changes
Usage