-
Notifications
You must be signed in to change notification settings - Fork 27
fix: transform command references in file contents when --prefix applied #295
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
Previously --prefix only reorganized directory structure (commands/ → commands/ck/) but didn't transform content inside files. This caused slash commands to fail because files still referenced /plan:fast instead of /ck:plan:fast. Changes: - Add content-transformer.ts for command reference transformation - Integrate into prefix-applier.ts after directory restructuring - Transform patterns: /plan:, /fix:, /code:, /review:, /cook:, /brainstorm, etc. - Add comprehensive unit tests (20 test cases) Closes #294
Code Review - PR #295SummaryThis PR adds content transformation for command references when the ✅ Strengths1. Excellent Test Coverage
2. Robust Pattern MatchingThe regex patterns in
3. Smart File Filtering
4. Good Architecture
5. Helpful Logging
🔍 Observations & Suggestions1. Regex Performance with Large FilesLocation: The current implementation iterates through all patterns and uses for (const { regex, replacement } of patterns) {
regex.lastIndex = 0;
const matches = transformed.match(regex);
if (matches) {
changes += matches.length;
regex.lastIndex = 0;
transformed = transformed.replace(regex, replacement);
}
}Suggestion: Consider combining patterns into a single alternation regex for better performance on large files: // Build single combined regex
const combinedPattern = COMMAND_ROOTS.map(cmd =>
`(?<\![\\w:])(/)(:|(?=[\\s\\\`"'\\)\\]}>.,;:\!?]|$))
`).join('|');
const regex = new RegExp(combinedPattern, 'g');
transformed = transformed.replace(regex, (match, ...args) => {
changes++;
// Transform logic here
});This would reduce the number of string traversals from 2N (where N = number of commands) to 2. 2. Command List MaintenanceLocation: The const COMMAND_ROOTS = [
"plan", "fix", "code", "review", "cook",
"brainstorm", "integrate", "bootstrap", "worktree", "scout",
];Question: Is there a central source of truth for available commands in the codebase? If so, consider importing from there to avoid drift. Recommendation: Add a comment indicating this list should be kept in sync with the actual command directory structure or link to documentation. 3. Error Handling in Recursive ProcessingLocation: } catch (error) {
// Skip files that can't be read (binary, permissions, etc.)
logger.debug(`Skipped ${fullPath}: ${error instanceof Error ? error.message : "unknown"}`);
}Good: Gracefully handles errors. 4. Regex Escape Issue PotentialLocation: patterns.push({
regex: new RegExp(`(?<\![\\w:])(\\/)(:)`, "g"),
replacement: "ck:".replace("", `${cmd}:`),
});Concern: The command name `` is directly interpolated into the regex without escaping. While the current Recommendation: Add a regex escape function or document the assumption that command names contain only alphanumeric characters. 5. Test File LocationLocation: The test file is named Suggestion: Consider renaming to 6. Edge Case: Nested BackticksYour tests cover single backticks well, but consider testing nested or escaped backticks:
While your patterns should handle these correctly, explicit tests would provide confidence. 🔒 Security Considerations✅ Path Validation: Proper use of existing 🎯 Performance ConsiderationsCurrent Performance: Acceptable for typical use cases
Potential Optimization: If users have very large
✅ Code Quality Checklist
🚀 RecommendationsPriority: Low (Nice-to-haves)
Priority: Optional
📊 Overall AssessmentStatus: ✅ APPROVED This is a high-quality PR that:
The suggestions above are minor enhancements that don't block merging. The code is production-ready as-is. Great work! 🎉 🔗 Related
|
Added 6 missing ClaudeKit commands to COMMAND_ROOTS: - test, debug, preview, kanban, journal, watzup These commands are referenced in engineer repo but weren't being transformed when --prefix was applied. Added 6 new tests to verify transformations.
Code Review SummaryThis PR successfully addresses issue #294 by transforming command references in file contents when the ✅ Strengths1. Excellent Code Organization
2. Robust Regex Implementation
3. Comprehensive Test Coverage (20 test cases)
4. Security & Error Handling
5. Good UX
🔍 Minor Observations & Suggestions1. Regex Pattern Performance (Minor Optimization Opportunity)Location: The regex patterns are rebuilt on every call to // At module level
const COMMAND_PATTERNS = buildCommandPatterns();
export function transformCommandContent(content: string): { transformed: string; changes: number } {
// Use cached COMMAND_PATTERNS instead of rebuilding
const patterns = COMMAND_PATTERNS;
// ... rest of function
}Impact: Minor performance improvement when processing many files, but not critical given current usage. 2. Regex Replacement Logic (Potential Bug)Location: replacement: "$1ck:$2".replace("$2", `${cmd}:`),This seems unnecessarily complex. The string replace happens at definition time, not during regex replacement. Consider simplifying: replacement: `ck:${cmd}:`,Test: Verify this doesn't break functionality, as the current approach may be working coincidentally. 3. File Extension Detection (Edge Case)Location: const ext = filename.toLowerCase().slice(filename.lastIndexOf("."));Issue: Files without extensions (e.g., Fix: function shouldTransformFile(filename: string): boolean {
const lastDot = filename.lastIndexOf(".");
if (lastDot === -1 || lastDot === 0) return false; // No extension or hidden file
const ext = filename.toLowerCase().slice(lastDot);
return TRANSFORMABLE_EXTENSIONS.has(ext);
}4. Test Accuracy (Minor Inconsistency)Location: The test name says "does not transform word boundaries incorrectly" but then expects a transformation to occur: it("does not transform word boundaries incorrectly", () => {
const input = "The planning process uses /plan:fast";
expect(transformed).toBe("The planning process uses /ck:plan:fast");
expect(changes).toBe(1); // This DOES transform
});Suggestion: Rename to "transforms commands after word boundaries" for clarity. 5. Error Handling Verbosity (Enhancement)Location: Currently skips unreadable files silently (debug log only). Consider counting skipped files and reporting in the result: export interface ContentTransformResult {
filesTransformed: number;
totalReplacements: number;
filesSkipped: number; // New field
}🔒 Security Review✅ No security concerns identified
🎯 Best Practices Adherence✅ Follows CLAUDE.md conventions:
✅ Quality Gate Requirements:
🚀 Performance ConsiderationsCurrent Implementation: O(n * m) where n = number of files, m = file size
Assessment: ✅ Acceptable for ClaudeKit use case
Future optimization (if needed):
📊 Test Coverage Analysis✅ Excellent coverage (20 tests covering):
Missing test (optional addition):
🎨 Code QualityReadability: ⭐⭐⭐⭐⭐ Excellent
Maintainability: ⭐⭐⭐⭐⭐ Excellent
Testability: ⭐⭐⭐⭐⭐ Excellent
✅ RecommendationAPPROVE with minor suggestions for future improvements. This PR is production-ready and can be merged as-is. The observations above are optimizations and edge case handling that can be addressed in follow-up PRs if needed. The core functionality is solid, well-tested, and solves the stated problem effectively. Great work on the implementation! 🎉 |
|
🎉 This PR is included in version 3.23.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Summary
--prefixflag is used--prefixonly reorganized directory structure but didn't update file contents/plan:fast→/ck:plan:fast,/fix:types→/ck:fix:types, etc.Changes
src/services/transformers/commands-prefix/content-transformer.tstransformCommandContent()- transforms command references in contenttransformCommandReferences()- recursively processes directoryprefix-applier.ts- calls content transformer after directory restructuringTest Plan
Closes #294