Conversation
* Add VHS integration tests with Require assertions - Add Require assertions to all tapes for screen verification - Add command-mode.tape for command completion testing - Add CI workflow for VHS integration tests - Add test:vhs task to Taskfile - Remove redundant test-diff.tape, separate light theme to theme-light.tape * Fix PR review feedback - Add missing Require assertion after :ec2/ navigation - Add LocalStack cleanup step to CI workflow * Address PR review feedback - Update docs/tapes/README.md with new tapes and test:vhs task - Add timeout-minutes: 5 to demo setup step
* feat: support custom config file path (#106) - Add -c/--config flag for custom config path - Add CLAWS_CONFIG env var support - Precedence: CLI flag > env var > default - Validate file exists before loading - Autosave writes to specified path * fix: expand tilde in custom config path SetConfigPath now expands ~/path to full home directory path, allowing `claws -c ~/.my-config.yaml` to work as expected. * fix: improve error handling in SetConfigPath - expandTilde now returns error on UserHomeDir failure - use apperrors.Wrap instead of fmt.Errorf * fix: trim whitespace from CLAWS_CONFIG env var
Pull Request Review: v0.12.7This PR adds custom config file path support and VHS integration tests. Overall, the implementation is well-structured with excellent test coverage. Below is my detailed feedback: ✅ StrengthsCode Quality
Documentation
Testing Strategy
🔍 Issues & Recommendations1. Security: File Validation in SetConfigPath (Medium Priority)Location: internal/config/file.go:51-62 Issue: The function only checks if the file exists using os.Stat(), but does not validate it is actually a file (not a directory) or check read permissions explicitly. // Current implementation
if _, err := os.Stat(expanded); err != nil {
return apperrors.Wrap(err, "config file", "path", expanded)
}Recommendation: Add validation for file type and readability: func SetConfigPath(path string) error {
expanded, err := expandTilde(path)
if err != nil {
return apperrors.Wrap(err, "config file", "path", path)
}
// Validate path points to a regular file
info, err := os.Stat(expanded)
if err != nil {
return apperrors.Wrap(err, "config file", "path", expanded)
}
if info.IsDir() {
return apperrors.Wrap(fmt.Errorf("path is a directory, not a file"), "config file", "path", expanded)
}
configPathMu.Lock()
customConfigPath = expanded
configPathMu.Unlock()
return nil
}2. Bug: Tilde Expansion Edge Case (Low Priority)Location: internal/config/file.go:38-47 Issue: expandTilde only handles " Recommendation: Handle the standalone "~" case: func expandTilde(path string) (string, error) {
if path == "~" {
return os.UserHomeDir()
}
if strings.HasPrefix(path, "~/") {
home, err := os.UserHomeDir()
if err != nil {
return "", fmt.Errorf("expand ~: %w", err)
}
return filepath.Join(home, path[2:]), nil
}
return path, nil
}3. Performance: Integration Test Timeout (Low Priority)Location: .github/workflows/integration-test.yml:34-45 Issue: LocalStack health check has 30-second timeout with 1-second polling. If LocalStack is slow to start, this could cause flaky test failures. Recommendation: Increase timeout to 60 seconds for more reliability and add attempt counter in output. 4. Code Quality: Global State Reset (Low Priority)Location: internal/config/file_test.go:691-815 Issue: Tests manually reset global state with defer blocks. If tests panic, cleanup might not run, affecting subsequent tests. Recommendation: Use t.Cleanup() for more reliable cleanup: func resetCustomConfigPath(t *testing.T) {
t.Helper()
t.Cleanup(func() {
configPathMu.Lock()
customConfigPath = ""
configPathMu.Unlock()
})
}5. Feature Gap: Directory Error Handling (Enhancement)Issue: No test case for when a directory path is passed instead of a file. This should fail gracefully with a clear error message. Recommendation: Add test case: func TestSetConfigPath_Directory(t *testing.T) {
tmpDir := t.TempDir()
err := SetConfigPath(tmpDir)
if err == nil {
t.Error("SetConfigPath should fail when given a directory")
}
}6. VHS Integration Tests: Require Statements (Good Practice)Positive Note: Excellent use of 7. Documentation: Missing CLAWS_CONFIG Example in Docker/CI (Minor)Location: docs/configuration.md Recommendation: Add practical CI/CD example: # Example: Using custom config in GitHub Actions
- name: Run claws with custom config
env:
CLAWS_CONFIG: ${{ github.workspace }}/configs/ci-config.yaml
run: claws -p production🔒 Security Review✅ No critical security issues found
Minor Recommendation:
⚡ Performance Review✅ No performance concerns
🧪 Test CoverageExcellent coverage (estimated 95%+ for new code):
📝 Best Practices Observed
🎯 Recommendations SummaryMust Fix (None)No blocking issues found. Should Fix (Recommended)
Nice to Have
✅ ApprovalThis is a high-quality PR with:
The identified issues are minor improvements rather than blockers. Approved for merge with optional follow-up improvements. Great work on this feature! The VHS integration testing approach is particularly clever. 🎉 Generated by Claude Code Review |
Changes
-c, --configCLI flagCLAWS_CONFIGenv var