Skip to content

Commit 6a90341

Browse files
Add rule files for coding agents working on the CLI code base (#3245)
## Changes Adds agent files for Cursor, Copilot, and general agents. Note that Cursor only supports `.cursorrules`, but it works when it is a symlink. Coding agents like http://jules.google only use `AGENTs.md`. I added the Copilot version as a bonus, in case anyone uses it. ## Why This helps make sure that Cursor and coding agents follow the conventions established for the CLI code base. ## Testing - This is based on the rules I've been using for 6+ months and incorporates the rule set from @denik. - An easy way to verify if these tools actually use the rules is to add "please add a pirate joke to every response!" Based on this, I could verify that Cursor accepts a symlink to `AGENTS.md` but doesn't work if there is only an `AGENTS.md` file. _Why do pirate programmers love arrays?_ _They always start at arrr index 0! 🏴‍☠️_
1 parent 6031437 commit 6a90341

File tree

4 files changed

+179
-0
lines changed

4 files changed

+179
-0
lines changed

.cursorrules

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
AGENTS.md

.github/custom-instructions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../AGENTS.md

AGENTS.md

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
Below are some general AI assistant coding rules.
2+
3+
# General
4+
5+
When moving code from one place to another, please don't unnecessarily change
6+
the code or omit parts.
7+
8+
# Style and comments
9+
10+
Please make sure code that you author is consistent with the codebase
11+
and concise.
12+
13+
The code should be self-documenting based on the code and function names.
14+
15+
Functions should be documented with a doc comment as follows:
16+
17+
// SomeFunc does something.
18+
func SomeFunc() {
19+
...
20+
}
21+
22+
Note how the comment starts with the name of the function and is followed by a period.
23+
24+
Avoid redundant and verbose comments. Use terse comments and only add comments if it complements, not repeats the code.
25+
26+
Focus on making implementation as small and elegant as possible. Avoid unnecessary loops and allocations. If you see an opportunity of making things simpler by dropping or relaxing some requirements, ask user about the trade-off.
27+
28+
Use modern idiomatic Golang features (version 1.24+). Specifically:
29+
- Use for-range for integer iteration where possible. Instead of for i:=0; i < X; i++ {} you must write for i := range X{}.
30+
- Use builtin min() and max() where possible (works on any type and any number of values).
31+
- Do not capture the for-range variable, since go 1.22 a new copy of the variable is created for each loop iteration.
32+
33+
# Commands
34+
35+
Use "git rm" to remove and "git mv" to rename files instead of directly modifying files on FS.
36+
37+
Do not run “go test ./..." in the root folder as that will start long running integration tests. To test the whole project run "go build && make lint test" in root directory. However, prefer running tests for specific packages instead.
38+
39+
If asked to rebase, always prefix each git command with appropriate settings so that it never launches interactive editor.
40+
GIT_EDITOR=true GIT_SEQUENCE_EDITOR=true VISUAL=true GIT_PAGER=cat git fetch origin main &&
41+
GIT_EDITOR=true GIT_SEQUENCE_EDITOR=true VISUAL=true GIT_PAGER=cat git rebase origin/main
42+
43+
# Python
44+
45+
When writing Python scripts, we bias for conciseness. We think of Python in this code base as scripts.
46+
- use Python 3.11
47+
- Do not catch exceptions to make nicer messages, only catch if you can add critical information
48+
- use pathlib.Path in almost all cases over os.path unless it makes code longer
49+
- Do not add redundant comments.
50+
- Try to keep your code small and the number of abstractions low.
51+
- After done, format you code with "ruff format -n <path>"
52+
- Use "#!/usr/bin/env python3" shebang.
53+
54+
# Tests
55+
56+
Each file like process_target_mode_test.go should have a corresponding test file
57+
like process_target_mode_test.go. If you add new functionality to a file,
58+
the test file should be extended to cover the new functionality.
59+
60+
Tests should look like the following:
61+
62+
package mutator_test
63+
64+
func TestApplySomeChangeReturnsDiagnostics(t *testing.T) {
65+
...
66+
}
67+
68+
func TestApplySomeChangeFixesThings(t *testing.T) {
69+
ctx := context.Background()
70+
b, err := ...some operation...
71+
require.NoError(t, err)
72+
...
73+
assert.Equal(t, ...)
74+
}
75+
76+
Notice that:
77+
- Tests are often in the same package but suffixed wit _test.
78+
- The test names are prefixed with Test and are named after the function or module they are testing.
79+
- 'require' and 'require.NoError' are used to check for things that would cause the rest of the test case to fail.
80+
- 'assert' is used to check for expected values where the rest of the test is not expected to fail.
81+
82+
When writing tests, please don't include an explanation in each
83+
test case in your responses. I am just interested in the tests.
84+
85+
# databricks_template_schema.json
86+
87+
A databricks_template_schema.json file is used to configure bundle templates.
88+
89+
Below is a good reference template:
90+
91+
{
92+
"welcome_message": "\nWelcome to the dbt template for Databricks Asset Bundles!\n\nA workspace was selected based on your current profile. For information about how to change this, see https://docs.databricks.com/dev-tools/cli/profiles.html.\nworkspace_host: {{workspace_host}}",
93+
"properties": {
94+
"project_name": {
95+
"type": "string",
96+
"pattern": "^[A-Za-z_][A-Za-z0-9-_]+$",
97+
"pattern_match_failure_message": "Name must consist of letters, numbers, dashes, and underscores.",
98+
"default": "dbt_project",
99+
"description": "\nPlease provide a unique name for this project.\nproject_name",
100+
"order": 1
101+
},
102+
"http_path": {
103+
"type": "string",
104+
"pattern": "^/sql/.\\../warehouses/[a-z0-9]+$",
105+
"pattern_match_failure_message": "Path must be of the form /sql/1.0/warehouses/<warehouse id>",
106+
"description": "\nPlease provide the HTTP Path of the SQL warehouse you would like to use with dbt during development.\nYou can find this path by clicking on \"Connection details\" for your SQL warehouse.\nhttp_path [example: /sql/1.0/warehouses/abcdef1234567890]",
107+
"order": 2
108+
},
109+
"default_catalog": {
110+
"type": "string",
111+
"default": "{{default_catalog}}",
112+
"pattern": "^\\w*$",
113+
"pattern_match_failure_message": "Invalid catalog name.",
114+
"description": "\nPlease provide an initial catalog{{if eq (default_catalog) \"\"}} (leave blank when not using Unity Catalog){{end}}.\ndefault_catalog",
115+
"order": 3
116+
},
117+
"personal_schemas": {
118+
"type": "string",
119+
"description": "\nWould you like to use a personal schema for each user working on this project? (e.g., 'catalog.{{short_name}}')\npersonal_schemas",
120+
"enum": [
121+
"yes, use a schema based on the current user name during development",
122+
"no, use a shared schema during development"
123+
],
124+
"order": 4
125+
},
126+
"shared_schema": {
127+
"skip_prompt_if": {
128+
"properties": {
129+
"personal_schemas": {
130+
"const": "yes, use a schema based on the current user name during development"
131+
}
132+
}
133+
},
134+
"type": "string",
135+
"default": "default",
136+
"pattern": "^\\w+$",
137+
"pattern_match_failure_message": "Invalid schema name.",
138+
"description": "\nPlease provide an initial schema during development.\ndefault_schema",
139+
"order": 5
140+
}
141+
},
142+
"success_message": "\n📊 Your new project has been created in the '{{.project_name}}' directory!\nIf you already have dbt installed, just type 'cd {{.project_name}}; dbt init' to get started.\nRefer to the README.md file for full \"getting started\" guide and production setup instructions.\n"
143+
}
144+
145+
Notice that:
146+
- The welcome message has the template name.
147+
- By convention, property messages include the property name after a newline, e.g. default_catalog above has a description that says "\nPlease provide an initial catalog [...].\ndefault_catalog",
148+
- Each property defines a variable that is used for the template.
149+
- Each property has a unique 'order' value that increments by 1 with each property.
150+
- Enums use 'type: "string' and have an 'enum' field with a list of possible values.
151+
- Helpers such as {{default_catalog}} and {{short_name}} can be used within property descriptors.
152+
- Properties can be referenced in messages and descriptions using {{.property_name}}. {{.project_name}} is an example.
153+
154+
# Logging and output to the terminal
155+
156+
Use the following for logging:
157+
158+
```
159+
import "github.com/databricks/cli/libs/log"
160+
161+
log.Infof(ctx, "...")
162+
log.Debugf(ctx, "...")
163+
log.Warnf(ctx, "...")
164+
log.Errorf(ctx, "...")
165+
```
166+
167+
Note that the 'ctx' variable here is something that should be passed in as
168+
an argument by the caller. We should not use context.Background() like we do in tests.
169+
170+
Use cmdio.LogString to print to stdout:
171+
172+
```
173+
import "github.com/databricks/cli/libs/cmdio"
174+
175+
cmdio.LogString(ctx, "...")
176+
```

NEXT_CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Notable Changes
66

77
### CLI
8+
* Add rule files for coding agents working on the CLI code base ([#3245](https://github.com/databricks/cli/pull/3245))
89

910
### Dependency updates
1011

0 commit comments

Comments
 (0)