-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add paths output and conf-backed config #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Review Details
Scope: This PR replaces subcommands (init, config-path, sync) with flags (--init, --paths) while adding conf library integration for config storage and improving path handling.
What looks good:
- Clean CLI simplification from subcommands to flags
- Good flag validation with clear error messages
- Improved
resolveInsidepath traversal checks following cross-platform best practices - Updated
normalizePathregex properly handles~uservs~/pathdistinction - Tests cover flag validation edge cases well
- Documentation is consistent with implementation
Summary: Found 1 medium issue with the --paths flag showing default rulesSource even when config fails to parse for non-ENOENT reasons. The overall refactoring is solid and improves the CLI UX.
Review by Claude (opus)
path.relative is case-insensitive on Windows, ensuring the default config detection works correctly regardless of path casing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 15 out of 16 changed files in this pull request and generated 5 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Separates access errors (EACCES, not a file) from parse errors (invalid JSON, schema validation) so users get appropriate hints.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Review Details
What looks good:
- Clean transition from subcommands to flags simplifies the CLI surface
- Good flag validation with clear error messages
- The
resolvePathsfunction nicely handles error cases while still showing useful path info - Path validation improvements using
path.relativeare correct for Windows case-insensitivity - The
~userpath handling fix is a good improvement for safety
Architectural notes:
- The
conflibrary integration is straightforward; the store is created per-load which is fine for a CLI tool - The removal of the three separate command registration files reduces complexity
Summary: No critical or high issues found. One medium observation about error handling behavior. The implementation is solid and the documentation is consistent with the code.
Review by Claude (opus)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Review Details
Reviewed: README.md, src/cli/main.ts, src/config/{constants.ts,loader.ts}, src/utils/{paths.ts,errors.ts}.
Ran: corepack enable && pnpm install --frozen-lockfile && pnpm test (all passing).
Key notes:
- CLI now uses flags ("--init", "--paths") instead of subcommands; docs appear updated accordingly.
- Path handling improvements reduce risk of accidental traversal/tilde mis-expansion.
Summary: Found 2 🟡 medium issues (both are small UX/correctness around "--paths"/default config detection) and 2 ℹ️ info notes.
Review by Copilot (gpt-5.2)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Review Details
- Internal docs:
main()JSDoc still mentions "subcommands" even though the CLI is now flag-based. - Error UX:
ConfigParseErrorsuggestssync-rules --helpfor "schema", but the CLI help text appears to be flags + examples only; consider pointing to README or the generated sample config instead.
Summary: Found 1 medium issue. Overall the config loading error taxonomy and Windows-safe default config detection look solid.
Review by Copilot (gpt-5.2)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Review Details
- Observed the CLI refactor to flags-only flow; help text and README updates align with the new options.
- Config loading now routes through Conf; the overall flow stays thin and readable.
Summary: Found 1 medium issue. See inline comment about --paths masking missing custom configs.
Review by Codex (gpt-5.2-codex)
Avoid writing system-specific paths to the sample config file. Use "/path/to/rules" as a clear placeholder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Review Details
This PR refactors the CLI to use flags instead of subcommands, which simplifies the interface but is a breaking change (correctly documented). It also switches to conf for config loading and improves path security.
Architectural Observations:
- CLI Refactor: Moving from
initcommand to--initflag makes the tool more single-purpose, which fits its role well. - Config Loading: The switch to
conffor reading the configuration file is interesting. Whileconfis typically used for managing application persistence (acting as a key-value store in a standard location), using it here to read a specific file path works but adds a heavy dependency for what could befs.readFile+JSON.parse. However, it doesn't cause any issues. - Security: The updates to
resolveInsidesignificantly harden directory traversal prevention.
Summary: Found 0 high, 1 low, and 1 info issue. The changes are solid and tests pass. The CLI refactor is clean, and path resolution is more robust.
Review by Gemini (gemini-3-pro-preview)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Review Details
This PR refactors the CLI from subcommand-based (init, sync, config-path) to flag-based (--init, --paths) architecture. The implementation is clean and the flag validation logic at lines 102-110 of src/cli/main.ts properly prevents conflicting flag combinations.
Notable improvements:
- Good use of
conflibrary for configuration storage - Proper error class hierarchy with
ConfigAccessErrorfor permission issues - The
resolveInsidefunction improvement usingpath.relativefor Windows case-insensitive path comparison - The
~userexpansion fix innormalizePathis correctly handled
The test coverage has been updated appropriately for the new CLI surface.
Summary: Found 1 medium issue regarding error message clarity for --verbose flag. The implementation is solid overall.
Review by Claude (opus)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 15 out of 16 changed files in this pull request and generated 2 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Review Details
Architectural Observations:
-
Good consolidation: The move from subcommands to a flag-based CLI surface (
--init,--paths,--force) simplifies the user experience and reduces code by removing three separate command registration files. -
Conf library integration: Using
conffor config storage provides a well-tested abstraction for configuration persistence. ThecreateConfigStorewrapper inconstants.tsmaintains a clean interface. -
Improved path validation: The updated
resolveInsidefunction inpaths.tsnow correctly handles Windows case-insensitivity by usingpath.relative()instead of string comparison, and properly checks for path traversal with the separator-aware..${path.sep}check. -
Better tilde handling: The regex update
^~(?=$|[\\/])correctly distinguishes between home directory expansion (~or~/foo) and Unix-style user home references (~user). -
Clear error taxonomy: The new
ConfigAccessErrorclass provides a distinct error type for permission/access issues, separating them from parse errors.
Summary: Clean refactor from subcommand architecture to flag-based CLI. Found 1 medium issue with potential unintended behavior when config path has no extension. The code follows good patterns for error handling and path normalization.
Review by Claude (opus)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Review Details
The refactor to a flag-based CLI structure simplifies the command interface. The path handling improvements in src/utils/paths.ts are particularly noteworthy for fixing edge cases in path resolution and expansion.
Summary: Found 1 low issue regarding dependency usage. The logic changes are sound and well-tested.
Review by Gemini (gemini-3-pro-preview)
| throw new Error(`Refusing to write outside ${base}: ${relativePath}`); | ||
| } | ||
| if (relative_ === ".." || relative_.startsWith(`..${path.sep}`)) { | ||
| throw new Error(`Refusing to write outside ${base}: ${relativePath}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ℹ️ Info: This is a great improvement. The previous check startsWith("..") incorrectly blocked valid sibling filenames starting with .. (e.g. ..foo). The new logic strictly targets directory traversal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Review Details
I reviewed the changes to the CLI flags, config loading logic, and path security.
Architectural Observation: conf for Config Loading
The introduction of the conf library to load a specific user-provided configuration file (--config) is risky. conf is primarily designed for managing application-owned settings (persisted in system directories), not for loading arbitrary static config files. It brings opinionated behaviors—most critically, the default handling of invalid JSON—that are dangerous in this context.
While the CLI refactoring and path security improvements are solid, the potential for data loss with the new config loader needs immediate attention.
Summary: Found 1 critical issue regarding potential user data loss and 1 info note on security improvements.
Review by Gemini (gemini-3-pro-preview)
| if (path.isAbsolute(relative_)) { | ||
| throw new Error(`Refusing to write outside ${base}: ${relativePath}`); | ||
| } | ||
| if (relative_ === ".." || relative_.startsWith(`..${path.sep}`)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ℹ️ Info: This updated check for parent directory escape (..) is much more robust than the previous implementation. Good fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Review Details
\n\n- Consolidated CLI flags and config loading looks coherent with README updates.\n- CLI help output not verified here due to sandbox permission errors when running `node src/cli/main.ts --help`.\n\nThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Review Details
\n\nNo architecture concerns found. CLI flag-based interface is consistent with docs; --paths and --init validation is clear. Error types and path normalization look solid.\n\nThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Review Details
- CLI UX: moved from subcommands (init/config-path/sync) to flags (--init/--paths), with explicit flag validation and consistent errors.
- Config loading now uses the "conf" store: the constructor reads the file during initialization (via #initializeStore calling .store), and
.storereads from disk and will create the config directory on ENOENT; the pre-stat guard in loadConfig prevents that side-effect for missing configs. - Docs: README usage examples and option list appear consistent with the new CLI surface.
Summary: Found 0 critical/high/medium issues (3 info notes). The changes look correct and tests pass locally.
Review by Copilot (gpt-5.2)
| export function normalizePath(input: string): string { | ||
| const expanded = input.startsWith("~") | ||
| ? input.replace(/^~/u, homedir()) | ||
| ? input.replace(/^~(?=$|[\\/])/u, homedir()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ℹ️ Info: Good hardening of normalizePath() — restricting ~ expansion to only bare ~/~/... avoids accidentally rewriting ~someone/... into the current user’s home. Also nice tightening in resolveInside() with the .. + path.sep check to avoid false positives like ..foo.
| try { | ||
| const configContent = await readFile(normalizedPath, "utf8"); | ||
| return parseConfig(configContent); | ||
| const configStat = await stat(normalizedPath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ℹ️ Info: The upfront stat() check is a good fit with conf: its constructor reads the file on init (#initializeStore calling .store), and the .store getter creates the directory on ENOENT (see get store() in conf source: https://raw.githubusercontent.com/sindresorhus/conf/main/source/index.ts). This keeps loadConfig() from creating config dirs when the file is missing.
| const wantsSyncFlags = | ||
| (options.dryRun ?? false) || (options.porcelain ?? false); | ||
|
|
||
| if (options.force && !wantsInit) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ℹ️ Info: The explicit flag guardrails here (e.g., --force only with --init, and mutually exclusive --init/--paths) should prevent ambiguous CLI states and makes error handling predictable for callers/scripts.
|
🎉 This PR is included in version 5.8.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Summary
Testing