@mallardbay/cursor-rules 1.0.18 → 1.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -69,6 +69,12 @@ These principles apply to all code changes and should guide every implementation
|
|
|
69
69
|
### Testing and Linting
|
|
70
70
|
- **Lint and test files related to your changes** before completing work
|
|
71
71
|
- Run linters on modified files and fix issues
|
|
72
|
+
- Use `yarn lint:quiet` for quick iterations
|
|
73
|
+
- Use `yarn lint:quiet:slow` for deeper checks but slower when wrapping up
|
|
74
|
+
- **Never disable eslint rules** to make lint errors go away—fix the underlying issues instead
|
|
75
|
+
- Do not add `eslint-disable` comments unless there's a legitimate, documented reason
|
|
76
|
+
- Do not modify eslint config files to disable rules that are flagging real problems
|
|
77
|
+
- If a rule seems incorrect, investigate why it exists and fix the code properly
|
|
72
78
|
- Run tests for affected modules, not the entire test suite unnecessarily
|
|
73
79
|
- For large changes: **use test sharding**—split tests across multiple runs
|
|
74
80
|
- **Do not run all tests in parallel** when dealing with many changes
|
|
@@ -113,6 +119,8 @@ These principles apply to all code changes and should guide every implementation
|
|
|
113
119
|
1. Make **small, incremental changes**
|
|
114
120
|
2. **Test as you go**—verify each change works before moving on
|
|
115
121
|
3. **Lint frequently**—don't accumulate lint errors
|
|
122
|
+
- Use `yarn lint:quiet` for quick iterations
|
|
123
|
+
- Use `yarn lint:quiet:slow` for deeper checks when wrapping up
|
|
116
124
|
4. **Follow existing patterns**—don't reinvent the wheel
|
|
117
125
|
5. **Use semantic names**—code should be self-documenting
|
|
118
126
|
6. **Keep functions focused**—one responsibility per function
|
|
@@ -122,6 +130,8 @@ These principles apply to all code changes and should guide every implementation
|
|
|
122
130
|
1. **Clean up failed attempts**—remove experimental code
|
|
123
131
|
2. **Remove unused code**—imports, variables, functions
|
|
124
132
|
3. **Run linters** on modified files
|
|
133
|
+
- Use `yarn lint:quiet` for quick iterations
|
|
134
|
+
- Use `yarn lint:quiet:slow` for deeper checks when wrapping up
|
|
125
135
|
4. **Run relevant tests**—not the entire suite unless necessary
|
|
126
136
|
5. **Verify the change works** end-to-end
|
|
127
137
|
6. **Check for side effects**—ensure changes don't break unrelated code
|
|
@@ -143,6 +153,7 @@ These principles apply to all code changes and should guide every implementation
|
|
|
143
153
|
- ❌ Functions that do multiple unrelated things
|
|
144
154
|
- ❌ Leaving commented-out code or debugging statements
|
|
145
155
|
- ❌ Skipping tests or linting "to save time"
|
|
156
|
+
- ❌ Disabling eslint rules instead of fixing the underlying issues
|
|
146
157
|
- ❌ Running entire test suite for small changes
|
|
147
158
|
- ❌ Leaving experimental code after failed attempts
|
|
148
159
|
- ❌ Premature optimization without profiling
|
|
@@ -41,7 +41,10 @@ Avoid e2e tests for UI. Favor unit tests.
|
|
|
41
41
|
- Write clear, descriptive test names
|
|
42
42
|
- Test one concept per test case
|
|
43
43
|
- Avoid test interdependence
|
|
44
|
-
-
|
|
44
|
+
- **Every test must have assertions**—tests without assertions are pointless and provide no value
|
|
45
|
+
- Use meaningful assertions that verify expected behavior
|
|
46
|
+
- Assertions validate that the code works correctly—without them, tests don't catch bugs
|
|
47
|
+
- If a test doesn't need assertions, it probably doesn't need to exist
|
|
45
48
|
- Avoid tests that will make the overall run slower
|
|
46
49
|
|
|
47
50
|
### Component Testing
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ This project provides a structured way to manage AI agent rules and skills for d
|
|
|
8
8
|
|
|
9
9
|
- **Cursor IDE**: `.cursor/rules/*.mdc` files and `.cursor/skills/*/SKILL.md` files
|
|
10
10
|
- **Claude Code**: A combined `CLAUDE.md` file and `.claude/skills/*/SKILL.md` files
|
|
11
|
-
- **Codex**: `.codex/skills/*/SKILL.md` files
|
|
11
|
+
- **Codex**: A combined `AGENTS.md` file and `.codex/skills/*/SKILL.md` files
|
|
12
12
|
- **Cross-platform Skills**: Skills are automatically copied to all three platform directories for maximum compatibility
|
|
13
13
|
|
|
14
14
|
It supports three main environment types:
|
|
@@ -108,10 +108,11 @@ your-project/
|
|
|
108
108
|
│ │ └── SKILL.md
|
|
109
109
|
│ └── address-pr-feedback/
|
|
110
110
|
│ └── SKILL.md
|
|
111
|
-
|
|
111
|
+
├── CLAUDE.md # Claude Code configuration (combined rules)
|
|
112
|
+
└── AGENTS.md # Codex IDE configuration (combined rules)
|
|
112
113
|
```
|
|
113
114
|
|
|
114
|
-
|
|
115
|
+
Both `CLAUDE.md` and `AGENTS.md` combine all applicable rules into single files, with YAML frontmatter stripped for compatibility. Each file includes header comments explaining its purpose and which tool uses it.
|
|
115
116
|
|
|
116
117
|
Skills are automatically discovered by Cursor, Claude Code, and Codex, and can be invoked with `/skill-name` in chat. The setup script copies skills to all three platform directories for cross-platform compatibility.
|
|
117
118
|
|
package/bin/setup-cursor.sh
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# setup-cursor.sh — frontend & frontend-lib layering with shared base
|
|
3
|
-
# Also generates CLAUDE.md for Claude Code
|
|
3
|
+
# Also generates CLAUDE.md for Claude Code and AGENTS.md for Codex
|
|
4
4
|
|
|
5
5
|
set -e
|
|
6
6
|
|
|
@@ -43,25 +43,18 @@ SRC_DIR="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
|
|
43
43
|
|
|
44
44
|
# When run via npx, if .cursor doesn't exist at SRC_DIR, find the actual package location
|
|
45
45
|
if [ ! -d "$SRC_DIR/.cursor/shared/skills" ]; then
|
|
46
|
-
# Try multiple possible locations for the package
|
|
46
|
+
# Try multiple possible locations for the package (using individual checks instead of array for sh compatibility)
|
|
47
47
|
# When SRC_DIR is node_modules, package is at SRC_DIR/@mallardbay/cursor-rules
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"$SRC_DIR/node_modules/@mallardbay/cursor-rules"
|
|
52
|
-
|
|
53
|
-
"$(dirname "$
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
SRC_DIR="$location"
|
|
59
|
-
break
|
|
60
|
-
fi
|
|
61
|
-
done
|
|
62
|
-
|
|
63
|
-
# If still not found, search for package.json with our name
|
|
64
|
-
if [ ! -d "$SRC_DIR/.cursor/shared/skills" ]; then
|
|
48
|
+
if [ -d "$SRC_DIR/@mallardbay/cursor-rules/.cursor/shared/skills" ]; then
|
|
49
|
+
SRC_DIR="$SRC_DIR/@mallardbay/cursor-rules"
|
|
50
|
+
elif [ -d "$SRC_DIR/node_modules/@mallardbay/cursor-rules/.cursor/shared/skills" ]; then
|
|
51
|
+
SRC_DIR="$SRC_DIR/node_modules/@mallardbay/cursor-rules"
|
|
52
|
+
elif [ -d "$(dirname "$SRC_DIR")/@mallardbay/cursor-rules/.cursor/shared/skills" ]; then
|
|
53
|
+
SRC_DIR="$(dirname "$SRC_DIR")/@mallardbay/cursor-rules"
|
|
54
|
+
elif [ -d "$(dirname "$(dirname "$SRC_DIR")")/@mallardbay/cursor-rules/.cursor/shared/skills" ]; then
|
|
55
|
+
SRC_DIR="$(dirname "$(dirname "$SRC_DIR")")/@mallardbay/cursor-rules"
|
|
56
|
+
else
|
|
57
|
+
# If still not found, search for package.json with our name
|
|
65
58
|
PACKAGE_ROOT=$(find "$(dirname "$SRC_DIR")" -maxdepth 5 -type f -name "package.json" -exec grep -l '"name":\s*"@mallardbay/cursor-rules"' {} \; 2>/dev/null | head -1 | xargs dirname 2>/dev/null)
|
|
66
59
|
if [ -n "$PACKAGE_ROOT" ] && [ -d "$PACKAGE_ROOT/.cursor/shared/skills" ]; then
|
|
67
60
|
SRC_DIR="$PACKAGE_ROOT"
|
|
@@ -69,9 +62,6 @@ if [ ! -d "$SRC_DIR/.cursor/shared/skills" ]; then
|
|
|
69
62
|
fi
|
|
70
63
|
fi
|
|
71
64
|
|
|
72
|
-
echo "DEBUG: Final SRC_DIR=$SRC_DIR"
|
|
73
|
-
echo "DEBUG: Checking if .cursor/shared/skills exists: $([ -d "$SRC_DIR/.cursor/shared/skills" ] && echo "YES" || echo "NO")"
|
|
74
|
-
|
|
75
65
|
SHARED_DIR="$SRC_DIR/.cursor/shared/rules"
|
|
76
66
|
FRONTEND_DIR="$SRC_DIR/.cursor/frontend/rules"
|
|
77
67
|
FRONTEND_LIB_DIR="$SRC_DIR/.cursor/frontend-lib/rules"
|
|
@@ -84,9 +74,33 @@ mkdir -p "$PROJECT_DIR/.cursor/skills"
|
|
|
84
74
|
mkdir -p "$PROJECT_DIR/.claude/skills"
|
|
85
75
|
mkdir -p "$PROJECT_DIR/.codex/skills"
|
|
86
76
|
|
|
87
|
-
# Temporary
|
|
77
|
+
# Temporary files to collect content for both CLAUDE.md and AGENTS.md
|
|
88
78
|
CLAUDE_MD_TEMP=$(mktemp)
|
|
89
|
-
|
|
79
|
+
AGENTS_MD_TEMP=$(mktemp)
|
|
80
|
+
trap 'rm -f "$CLAUDE_MD_TEMP" "$AGENTS_MD_TEMP"' EXIT
|
|
81
|
+
|
|
82
|
+
# Add header comments explaining what each file is
|
|
83
|
+
add_file_header() {
|
|
84
|
+
local file="$1"
|
|
85
|
+
local tool_name="$2"
|
|
86
|
+
local description="$3"
|
|
87
|
+
|
|
88
|
+
cat > "$file" <<EOF
|
|
89
|
+
<!--
|
|
90
|
+
This file provides custom instructions and project context for $tool_name.
|
|
91
|
+
|
|
92
|
+
$description
|
|
93
|
+
|
|
94
|
+
This file is automatically generated by @mallardbay/cursor-rules. It combines
|
|
95
|
+
all applicable rules from .cursor/rules/ into a single configuration file.
|
|
96
|
+
|
|
97
|
+
For more information:
|
|
98
|
+
- $tool_name: See official documentation
|
|
99
|
+
- This package: https://github.com/mallardbay/cursor-rules
|
|
100
|
+
-->
|
|
101
|
+
|
|
102
|
+
EOF
|
|
103
|
+
}
|
|
90
104
|
|
|
91
105
|
copy_rules() {
|
|
92
106
|
local DIR="$1"
|
|
@@ -98,7 +112,6 @@ copy_rules() {
|
|
|
98
112
|
|
|
99
113
|
copy_skills() {
|
|
100
114
|
local DIR="$1"
|
|
101
|
-
echo "DEBUG: Checking skills directory: $DIR"
|
|
102
115
|
if [ -d "$DIR" ]; then
|
|
103
116
|
echo "Copying skills from: $DIR"
|
|
104
117
|
# Ensure target directories exist
|
|
@@ -137,13 +150,11 @@ copy_skills() {
|
|
|
137
150
|
fi
|
|
138
151
|
else
|
|
139
152
|
echo "Warning: Skills directory not found: $DIR"
|
|
140
|
-
echo "DEBUG: SRC_DIR=$SRC_DIR"
|
|
141
|
-
echo "DEBUG: SHARED_SKILLS_DIR=$SHARED_SKILLS_DIR"
|
|
142
153
|
fi
|
|
143
154
|
}
|
|
144
155
|
|
|
145
|
-
# Append rules to CLAUDE.md (strips YAML frontmatter)
|
|
146
|
-
|
|
156
|
+
# Append rules to both CLAUDE.md and AGENTS.md (strips YAML frontmatter)
|
|
157
|
+
append_to_md_files() {
|
|
147
158
|
local DIR="$1"
|
|
148
159
|
if [ -d "$DIR" ]; then
|
|
149
160
|
for file in "$DIR"/*.mdc; do
|
|
@@ -152,7 +163,10 @@ append_to_claude_md() {
|
|
|
152
163
|
echo "" >> "$CLAUDE_MD_TEMP"
|
|
153
164
|
echo "---" >> "$CLAUDE_MD_TEMP"
|
|
154
165
|
echo "" >> "$CLAUDE_MD_TEMP"
|
|
155
|
-
|
|
166
|
+
echo "" >> "$AGENTS_MD_TEMP"
|
|
167
|
+
echo "---" >> "$AGENTS_MD_TEMP"
|
|
168
|
+
echo "" >> "$AGENTS_MD_TEMP"
|
|
169
|
+
# Strip YAML frontmatter (content between --- markers) and append to both
|
|
156
170
|
awk '
|
|
157
171
|
BEGIN { in_frontmatter=0; found_end=0 }
|
|
158
172
|
/^---$/ && !found_end {
|
|
@@ -161,34 +175,45 @@ append_to_claude_md() {
|
|
|
161
175
|
}
|
|
162
176
|
!in_frontmatter || found_end { print }
|
|
163
177
|
' "$file" >> "$CLAUDE_MD_TEMP"
|
|
178
|
+
# Also append to AGENTS.md (same content)
|
|
179
|
+
awk '
|
|
180
|
+
BEGIN { in_frontmatter=0; found_end=0 }
|
|
181
|
+
/^---$/ && !found_end {
|
|
182
|
+
if (in_frontmatter) { found_end=1; next }
|
|
183
|
+
else { in_frontmatter=1; next }
|
|
184
|
+
}
|
|
185
|
+
!in_frontmatter || found_end { print }
|
|
186
|
+
' "$file" >> "$AGENTS_MD_TEMP"
|
|
164
187
|
done
|
|
165
188
|
fi
|
|
166
189
|
}
|
|
167
190
|
|
|
191
|
+
# Initialize both files with headers
|
|
192
|
+
add_file_header "$CLAUDE_MD_TEMP" "Claude Code" "Claude Code automatically reads CLAUDE.md files from your project root to understand project conventions, coding standards, and development workflows."
|
|
193
|
+
add_file_header "$AGENTS_MD_TEMP" "Codex IDE" "Codex IDE reads AGENTS.md files to provide project-specific context and instructions. Codex discovers AGENTS.md files starting from the project root and walking down to your current directory."
|
|
194
|
+
|
|
168
195
|
# Always include shared rules
|
|
169
196
|
copy_rules "$SHARED_DIR"
|
|
170
|
-
|
|
197
|
+
append_to_md_files "$SHARED_DIR"
|
|
171
198
|
|
|
172
199
|
# Always include shared skills
|
|
173
|
-
echo "DEBUG: SRC_DIR=$SRC_DIR"
|
|
174
|
-
echo "DEBUG: SHARED_SKILLS_DIR=$SHARED_SKILLS_DIR"
|
|
175
200
|
copy_skills "$SHARED_SKILLS_DIR"
|
|
176
201
|
|
|
177
202
|
# Inheritance handling
|
|
178
203
|
case "$ENV_TYPE" in
|
|
179
204
|
frontend)
|
|
180
205
|
copy_rules "$FRONTEND_DIR"
|
|
181
|
-
|
|
206
|
+
append_to_md_files "$FRONTEND_DIR"
|
|
182
207
|
;;
|
|
183
208
|
backend)
|
|
184
209
|
copy_rules "$BACKEND_DIR"
|
|
185
|
-
|
|
210
|
+
append_to_md_files "$BACKEND_DIR"
|
|
186
211
|
;;
|
|
187
212
|
frontend-lib)
|
|
188
213
|
copy_rules "$FRONTEND_DIR"
|
|
189
214
|
copy_rules "$FRONTEND_LIB_DIR"
|
|
190
|
-
|
|
191
|
-
|
|
215
|
+
append_to_md_files "$FRONTEND_DIR"
|
|
216
|
+
append_to_md_files "$FRONTEND_LIB_DIR"
|
|
192
217
|
;;
|
|
193
218
|
*)
|
|
194
219
|
echo "Unknown environment type: $ENV_TYPE"
|
|
@@ -196,10 +221,12 @@ case "$ENV_TYPE" in
|
|
|
196
221
|
;;
|
|
197
222
|
esac
|
|
198
223
|
|
|
199
|
-
# Generate CLAUDE.md
|
|
224
|
+
# Generate both CLAUDE.md and AGENTS.md
|
|
200
225
|
mv "$CLAUDE_MD_TEMP" "$PROJECT_DIR/CLAUDE.md"
|
|
226
|
+
mv "$AGENTS_MD_TEMP" "$PROJECT_DIR/AGENTS.md"
|
|
201
227
|
trap - EXIT
|
|
202
228
|
echo "CLAUDE.md generated for Claude Code"
|
|
229
|
+
echo "AGENTS.md generated for Codex IDE"
|
|
203
230
|
|
|
204
231
|
if [ -d "$PROJECT_DIR/.cursor/skills" ] && [ "$(ls -A "$PROJECT_DIR/.cursor/skills" 2>/dev/null)" ]; then
|
|
205
232
|
echo "Skills installed in:"
|