Skip to content

Commit 94f93c3

Browse files
Add agentic coding infrastructure (#27)
## Summary - Adds the `AGENTS.md` + `.agent/` directory structure for multi-tool AI coding support - Creates symlinks for Claude Code (`CLAUDE.md`), Cursor (`.cursorrules`, `.cursor/rules/`), and a pointer for Copilot (`.github/copilot-instructions.md`) - Updates `.gitignore` to track `.agent`, `.claude` (excluding local sessions), and `.cursor` This is a copy of the approach adopted in the Go SDK: databricks/databricks-sdk-go#1520 ## How is this tested? N/A — documentation and configuration only, no code changes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Ubuntu <renaud.hartert@databricks.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 74d0a3a commit 94f93c3

16 files changed

Lines changed: 407 additions & 0 deletions

‎.agent/prompts/code-review.md‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Code Review
2+
3+
Review the given PR or code changes for the following concerns, in order of priority:
4+
5+
1. **Backward compatibility** — Does this change break any existing public API?
6+
Check for removed or renamed exported types, functions, or methods.
7+
2. **Correctness** — Are there logic errors, race conditions, or unhandled edge cases?
8+
3. **Error handling** — Are errors wrapped with caller context? Are sentinel errors
9+
used correctly? See `.agent/rules/error-handling.md`.
10+
4. **Test coverage** — Are new code paths tested? Do tests follow the conventions
11+
in `.agent/rules/testing.md`?
12+
5. **API design** — Does the change follow the principles in `.agent/rules/api-design.md`?
13+
Is the exported surface minimal?
14+
6. **Style** — Does the code follow `.agent/rules/style-guide.md`? Are names descriptive?
15+
Are doc comments present on exported symbols?
16+
17+
For each issue found, state the file and line, the concern category, and a
18+
concrete suggestion for how to fix it.

‎.agent/rules/api-design.md‎

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
---
2+
description: "API design principles for the Databricks SDK."
3+
globs: "**/*.go"
4+
alwaysApply: false
5+
---
6+
7+
# API Design
8+
9+
## Public API Surface
10+
11+
- Minimize exported API surface: if a type is only used through an interface, keep
12+
the concrete type unexported
13+
- **Return interfaces from constructors** when the concrete type is private and adds
14+
no methods beyond the interface — this prevents direct construction and keeps
15+
implementation details hidden
16+
- Prefer new types over modifying existing exported types (additive changes only)
17+
- Adding a required field to a public type is a breaking change — use nil checks
18+
and defaults to preserve existing behavior
19+
- Remove dead or unused code — don't leave unexported functions that nothing calls
20+
21+
## Interface Design
22+
23+
- **Keep interfaces small and focused**: avoid coupling unrelated concerns in one interface.
24+
If an interface does "too many things", split it
25+
- **Encapsulate domain knowledge**: requirements and validation should live in the component
26+
that owns the behavior, not in an external orchestrator. Every consumer should not have
27+
to re-implement the same mapping logic
28+
- Pass specific values, not entire config objects — functions should depend on the narrowest
29+
interface possible
30+
31+
## Constructors and Defaults
32+
33+
- Validate required fields in constructors — validate early, fail fast
34+
- Validation logic should live near its point of use, not in generic/shared layers
35+
- **Components should own their default values** — don't let callers hard-code defaults
36+
that belong to the component
37+
- **Zero values should be the default behavior**: use negative field names (`Disable` not
38+
`Enable`) so that the zero value corresponds to the intended default. A non-zero value
39+
always corresponds to a special case
40+
- When setting default values (timeouts, retries, cache durations), comment the rationale
41+
- **Use variadic options** (`...Option`) for backward-compatible extensibility
42+
43+
## Immutability and Concurrency
44+
45+
- **Treat config objects as immutable** after construction — do not mutate config fields
46+
after a type has been built from them
47+
- **Keep concurrency primitives internal**: locks, mutexes, and synchronization should be
48+
implementation details of the type, not exposed to or managed by callers
49+
- **Separate mechanism from policy**: e.g., separate *how* to iterate strategies from
50+
*which* strategies to try
51+
52+
## Code Structure
53+
54+
- Place helper functions near their callers, not at the top of the file
55+
- Use `switch/case` for type dispatching, not `if/else` chains
56+
- Split functions with multiple concerns (e.g., create temp file + atomic rename)
57+
so each has one clear responsibility. Use `defer` to enforce cleanup invariants
58+
- Extract shared logic into helpers at 3+ duplications, not before
59+
- **Consolidate redundant code paths**: when two functions produce the same result,
60+
have one delegate to the other rather than duplicating logic

‎.agent/rules/error-handling.md‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
description: "Error handling conventions for the Databricks SDK."
3+
globs: "**/*.go"
4+
alwaysApply: false
5+
---
6+
7+
# Error Handling
8+
9+
- Wrap errors with **caller's context**: `fmt.Errorf("resolving workspace host: %w", err)`.
10+
Describe what *you* were doing, not what the callee does
11+
- **Add context at the caller, not in utility functions** — the caller knows the
12+
operation's purpose; a utility function like `atomicWriteFile` should not prefix its
13+
errors when the caller can provide better context like `"storing token in local cache"`
14+
- Don't add redundant wrapping — if the underlying error already contains the path/resource,
15+
don't repeat it: `write /home/user/.databricks/.tmp: permission denied` is sufficient
16+
without a `"write temp file: "` prefix
17+
- Include the specific resource/URL that failed, not just the operation name
18+
- Define sentinel errors as package-level `var` using `errors.New()` — never `fmt.Errorf`.
19+
They must be comparable with `errors.Is()`
20+
- **Unexpected cases must error**: a `default` case in a `switch` should return an error
21+
(e.g., `fmt.Errorf("unknown host type: %v", h)`), not silently succeed. If silence is
22+
intentional, add a comment explaining why
23+
- **Error messages should be actionable**: include the specific field or value that is
24+
wrong so the user knows what to fix (e.g., `"azure_client_id is required"`)
25+
- Use `%q` (not `%s`) for strings in error/log messages — makes empty strings visible as `""`

‎.agent/rules/style-guide.md‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
description: "Go code style and naming conventions for the Databricks SDK."
3+
globs: "**/*.go"
4+
alwaysApply: false
5+
---
6+
7+
# Code Style
8+
9+
- Go 1.25+ idioms: range-over-int, `min`/`max` builtins
10+
- Format with `gofmt`
11+
- All exported functions and types need doc comments: `// FuncName does X.`
12+
- Interface doc comments should explain the **contract/lifecycle** — when methods are called,
13+
what callers expect, and when errors are appropriate — not just what they do
14+
- Return early on errors; avoid deeply nested if-else chains
15+
- Use `context.Context` as the first parameter for functions that do I/O
16+
17+
## Naming
18+
19+
- Acronyms are fully capitalized: `ID` not `Id`, `URL` not `Url`, `HTTP` not `Http`
20+
- No `Get` prefix on methods — not idiomatic in Go. Use `HostType()` not `GetHostType()`
21+
- Avoid abbreviations: `authTokenCommand` not `authTokenCmd`
22+
- Variable names describe content, not origin: `workspaceHost` not `resolvedHost`
23+
- Use specific names when multiple similar types exist: `httpClient` not `client`
24+
25+
## Go Idioms
26+
27+
- **Exhaustive switches**: prefer `switch` over `if-else` chains for type/enum dispatching.
28+
Always include a `default` case that returns an error for unknown values
29+
- **`sync.Once`** over manual double-checked locking with mutexes — it is safer and
30+
respects Go's memory model
31+
- **Scope variables tightly**: use `:=` inside `if` blocks when the variable is not needed
32+
outside: `if err := json.Unmarshal(raw, &f); err != nil {`
33+
- **Use stdlib functions** over manual equivalents: `math.Ceil`, `json.Marshal`,
34+
`slices.Sort`, `slices.Compact`, `sort.Strings`
35+
- **No forced line length**: Go does not mandate 80-char lines. Prefer keeping function
36+
signatures on one line, or use one argument per line for very long signatures
37+
- **Config structs over long parameter lists**: when a function takes many parameters,
38+
group them in a config struct
39+
([Google Go style](https://google.github.io/styleguide/go/best-practices#option-structure))
40+
- **Don't alias imports unnecessarily**: only alias when there is a genuine name collision
41+
- **Use `sync.Mutex` directly**, not through an interface — the zero value is valid and
42+
needs no initialization
43+
44+
## Code Organization
45+
46+
- **Keep related code close together**: place constructors near the types they return,
47+
move helper functions near their callers
48+
- **Declare variables close to where they're used**: don't declare at the top of a function
49+
if the variable is only needed 30 lines later
50+
- **Inline simple helpers** when they obscure intent — a one-line function called once
51+
adds indirection without value. Remove unnecessary intermediate variables that suggest
52+
the value might be mutated when it won't be
53+
- **Move branching out of callbacks**: if a visitor/callback is only needed conditionally,
54+
check the condition first, then register the callback — don't put the `if` inside
55+
56+
## Comments and Documentation
57+
58+
- **Full sentences**: comments start with a capital letter and end with a period.
59+
Ref: [Go Code Review Comments](https://go.dev/wiki/CodeReviewComments#comment-sentences)
60+
- **Explain why, not what**: the code is self-explanatory for *what* it does; comments
61+
should explain *why* a decision was made or why a non-obvious approach was chosen
62+
- **Use Go doc links**: reference types with bracket syntax: `// implements the [TokenCache] interface`
63+
- **Document public types thoroughly**: explain the purpose, which fields are optional,
64+
and what the zero value means
65+
- **Don't duplicate godoc**: if a method's doc comment says the same thing as the type's
66+
doc comment, remove the redundancy

‎.agent/rules/testing.md‎

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
description: "Testing standards and anti-patterns for the Databricks SDK."
3+
globs: "**/*_test.go"
4+
alwaysApply: false
5+
---
6+
7+
# Testing
8+
9+
Use Go's standard `testing` package with `google/go-cmp` for complex comparisons.
10+
Do NOT introduce `testify` — this SDK minimizes third-party dependencies.
11+
12+
Table-driven tests are preferred:
13+
14+
```go
15+
for _, tc := range testCases {
16+
t.Run(tc.name, func(t *testing.T) {
17+
// ...
18+
if diff := cmp.Diff(tc.want, got); diff != "" {
19+
t.Errorf("mismatch (-want +got):\n%s", diff)
20+
}
21+
})
22+
}
23+
```
24+
25+
- Unit tests: `*_test.go` alongside source files
26+
- Call `t.Helper()` at the start of test helper functions (correct line numbers in failures)
27+
- For configurable options, always test three cases: (1) explicit values, (2) nil/unset default, (3) empty value
28+
- Inject `time.Now` as `func() time.Time` for time-dependent logic — makes tests deterministic
29+
- Always check errors — never use `_` for error returns in tests
30+
- Assert on exact expected values, not partial matches (e.g., full header value, not just prefix)
31+
- Extract repeated test values to shared `const`/`var` to convey intent and avoid silent drift
32+
- Add explicit timeouts to channel/goroutine-based tests to prevent hanging
33+
- Use `defer close(ch)` for channel cleanup to handle error paths safely
34+
35+
## Naming and Style
36+
37+
- Use `want` for expected values and `got` for actual values — not `expected`/`actual`
38+
- Use **named struct fields** in test mock initialization: `&IDToken{Value: tok}` not `&IDToken{tok}`
39+
- Use existing test utilities rather than creating new one-off mock types
40+
41+
## Test Design Philosophy
42+
43+
- **Pragmatic about test value**: don't write tests that can't catch real regressions.
44+
If removing the tested code wouldn't be caught by the test, the test is not useful
45+
- **Prefer blackbox tests over whitebox tests**: verify observable behavior, not
46+
implementation details. When structural constraints make blackbox testing impossible,
47+
consider refactoring for testability — but not at the cost of breaking backward compatibility
48+
- **Test at the right abstraction level**: test behavior through the public interface of
49+
a component, not through its internals
50+
- **Mock at the right level**: mock the nearest interface boundary, not deep internals
51+
- **Prefer isolated tests by design**: use dependency injection and mocks rather than
52+
relying on environment cleanup utilities
53+
54+
## Anti-Patterns (never do these)
55+
56+
- Deleting or skipping flaky tests instead of fixing the root cause
57+
- Tests depending on execution order or shared mutable state
58+
- Non-descriptive test names (`TestFoo`, `TestBasic`) — follow the same pattern as Go
59+
`Example` functions: `TestFunctionName_description` (e.g., `TestHostType_missingScheme`,
60+
`TestConfig_HostType_missingScheme` for a method on a type)
61+
- `time.Now` in tests — use a mock clock
62+
- Exporting methods solely for test access — use `cmp.Diff` to compare structs,
63+
or write internal (`_test.go` in same package) tests instead
64+
- Unnecessary concurrency in tests — if goroutines/channels aren't clearly needed, don't use them
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
---
2+
name: write-pr-description
3+
description: >
4+
Write or improve a GitHub pull request description. Use when the user asks
5+
to "write a PR description", "improve the PR description", "update the PR
6+
body", or provides a PR URL and asks for a better description.
7+
Keywords: PR description, pull request summary, PR body, PR writeup.
8+
---
9+
10+
# Write PR Description
11+
12+
Generate a structured PR description that explains **why** the change exists,
13+
not just what files were touched.
14+
15+
## When to use
16+
17+
- The user provides a PR URL and asks to write or improve its description.
18+
- The user asks to draft a PR description for the current branch.
19+
- An agent needs to open a PR and wants a high-quality description.
20+
21+
## Workflow
22+
23+
### Phase 1: Gather context
24+
25+
Collect all the information needed to understand the change:
26+
27+
1. **Read the PR metadata** — title, current description, author, branch name.
28+
2. **Read the full diff** — understand every file changed, every function added
29+
or removed, every signature change. Do not skip files.
30+
3. **Read surrounding code when needed** — if the diff modifies an interface or
31+
a struct, read the full file to understand how the change fits into the
32+
existing architecture.
33+
4. **Check for linked issues or docs** — the PR or commit messages may
34+
reference issues, design docs, or RFCs that explain motivation.
35+
36+
### Phase 2: Analyze the change
37+
38+
Before writing, answer these questions internally:
39+
40+
- **What was the status quo before this PR?** What limitation, bug, or missing
41+
capability existed?
42+
- **Why is this change needed now?** What concrete problem does it solve? Who
43+
benefits?
44+
- **What are the key design decisions?** Why was this approach chosen over
45+
alternatives?
46+
- **What is the new API surface?** Any new public types, functions, or
47+
configuration options?
48+
- **What are the architectural changes?** How does the internal structure
49+
change? What moves where? What gets refactored?
50+
- **Are there behavioral changes?** If not, say so explicitly — this reassures
51+
reviewers.
52+
53+
### Phase 3: Write the description
54+
55+
Use the structure defined in `.github/PULL_REQUEST_TEMPLATE.md` as the
56+
template. The tone should be direct and technical. Write for a reviewer who is
57+
familiar with the codebase but has not seen this change before.
58+
59+
**Key principles:**
60+
61+
- **Lead with why, not what.** The diff already shows the what. The description
62+
should explain the reasoning that is not visible in the code.
63+
- **Be specific.** Instead of "improves extensibility", say "allows internal
64+
tools to compose their own auth chain from individual credential strategies".
65+
- **Name things.** Reference actual types, functions, files, and config fields.
66+
Use backticks for code references.
67+
- **State non-changes explicitly.** If the PR is a refactor with no behavioral
68+
change, say "No behavioral changes. Existing users are unaffected." This is
69+
valuable information for reviewers.
70+
- **Keep the summary to one or two sentences.** It should be scannable.
71+
- **Use the motivation section to tell a story.** What was the problem? Why
72+
couldn't it be solved before? What does this PR unlock?
73+
74+
### Phase 4: Update the PR
75+
76+
Use the GitHub MCP tools or `gh` CLI to update the PR body with the new
77+
description. Confirm with the user before pushing if unsure.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
description: Always load AGENTS.md context first
3+
alwaysApply: true
4+
globs:
5+
- "**/*"
6+
---
7+
8+
Always apply AGENTS.md context before taking actions.
9+
10+
1. If `/AGENTS.md` exists, read and follow it for every task in this workspace.
11+
2. Read scoped rules from `.agent/rules/` when working on relevant files.
12+
3. Keep these instructions active even for small or routine requests.

‎.cursor/rules/api-design.mdc‎

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

‎.cursor/rules/error-handling.mdc‎

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

‎.cursor/rules/style-guide.mdc‎

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

0 commit comments

Comments
 (0)