Skip to content

Commit 7e6e426

Browse files
committed
Reorganize AI assistant configuration into .claude/ directory
- Slim down AGENTS.md to a concise project overview with pointers to detailed docs - Extract Java coding conventions to .claude/docs/java-coding-conventions.md - Extract build/test instructions to .claude/docs/building-and-testing.md - Add commit skill definition
1 parent 5beb2c3 commit 7e6e426

File tree

4 files changed

+325
-558
lines changed

4 files changed

+325
-558
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Building and Testing
2+
3+
## Build/Compile the Project
4+
5+
To compile the project without running tests:
6+
7+
```bash
8+
mvn clean compile
9+
```
10+
11+
## Run All Tests
12+
13+
To run all tests and verify the project:
14+
15+
```bash
16+
mvn clean verify
17+
```
18+
19+
This command will:
20+
21+
- Clean previous builds
22+
- Compile the code
23+
- Run all unit tests
24+
- Run integration tests (if configured)
25+
- Run code quality checks (like Spotless)
26+
27+
## Run Specific Tests
28+
29+
Because this is a multi-module project, use `-pl <module>` to target the module containing the test.
30+
Without it, Surefire fails on modules that don't contain the specified test class.
31+
32+
To run a specific test class:
33+
34+
```bash
35+
mvn test -pl modbus -Dtest=Crc16Test
36+
```
37+
38+
To run a specific test method:
39+
40+
```bash
41+
mvn test -pl modbus -Dtest=Crc16Test#crc16
42+
```
43+
44+
To run multiple test classes in the same module:
45+
46+
```bash
47+
mvn test -pl modbus -Dtest=Crc16Test,MbapHeaderTest
48+
```
49+
50+
To run tests matching a pattern in a specific module:
51+
52+
```bash
53+
mvn test -pl modbus -Dtest=*RequestTest
54+
```
55+
56+
Available modules: `modbus`, `modbus-tcp`, `modbus-serial`, `modbus-tests`.
57+
58+
## Other Common Maven Commands
59+
60+
**Run tests only (skip compilation if already compiled):**
61+
62+
```bash
63+
mvn test
64+
```
65+
66+
**Package the project (creates JAR file):**
67+
68+
```bash
69+
mvn clean package
70+
```
71+
72+
**Install to local Maven repository:**
73+
74+
```bash
75+
mvn clean install
76+
```
77+
78+
**Run only unit tests (skip integration tests):**
79+
80+
```bash
81+
mvn clean test
82+
```
83+
84+
## Code Formatting
85+
86+
This project uses Spotless with Google Java Format for code formatting.
87+
88+
The `spotless:check` goal is bound to the `verify` phase and will fail the build if code is not
89+
properly formatted.
90+
91+
If the build fails due to formatting issues, run:
92+
93+
```bash
94+
mvn spotless:apply
95+
```
96+
97+
This will automatically format all Java files according to Google Java Format standards.
98+
99+
## Dependency Source Code
100+
101+
To examine dependency source code, check the `external/src` directory at the project root. This
102+
directory contains unpacked source files from all dependencies, organized by package structure for
103+
easy browsing and searching.
104+
105+
**If the directory doesn't exist or content is missing:**
106+
107+
Run this command from the project root to download and unpack all dependency sources:
108+
109+
```bash
110+
mvn generate-resources -Pdownload-external-src
111+
```
112+
113+
This will create the `external/src` directory with sources from all dependencies in a single
114+
top-level location.
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Java Coding Conventions
2+
3+
## Variables and Types
4+
5+
Choose type declarations that make the code's intent immediately clear to readers. While `var` reduces verbosity, explicit types often communicate intent more effectively.
6+
7+
### Type Declarations
8+
9+
Use `var` for local variable declarations ONLY when the type is immediately obvious from the
10+
right-hand side. When in doubt, explicit types improve clarity and maintainability.
11+
12+
**Decision Checklist:**
13+
14+
- ✓ Can you tell the exact type in 1 second? → Use `var`
15+
- ✗ Would you need to check documentation or method signatures? → Use explicit type
16+
- ✗ Is the type generic, an interface, or complex? → Use explicit type
17+
- ✗ Is the variable used far from its declaration? → Use explicit type
18+
- ✗ Does the explicit type reveal important semantic information? → Use explicit type
19+
20+
**What counts as "obvious from the right-hand side":**
21+
22+
- Constructor calls with concrete types: `new ArrayList<String>()`, `new User(...)`
23+
- Literals: strings, numbers, booleans, `null`
24+
- Collection factory methods with only literals: `List.of(1, 2, 3)`, `Map.of("key", "value")`
25+
- Standard library methods with obvious return types: `isEmpty()`, `size()`, `toString()`
26+
- Builder patterns that return the same type: `User.builder().name("John").build()`
27+
28+
```java
29+
// Good: Type is clear from the right-hand side
30+
var list = new ArrayList<String>();
31+
var name = "John";
32+
var count = 42;
33+
var user = new User(id, name, email);
34+
var isEmpty = list.isEmpty();
35+
var items = List.of("a", "b", "c");
36+
37+
// Good: Explicit type when not obvious
38+
InputStream stream = getStream();
39+
Result<User> result = repository.getUser(id);
40+
Function<String, Integer> parser = Integer::parseInt;
41+
List<Item> items = Stream.of(item1, item2).collect(toList());
42+
43+
// Good: Explicit type for interface/abstract return types
44+
Map<String, Object> config = loadConfiguration();
45+
Callable<Data> task = () -> fetchData();
46+
47+
// Good: Explicit type for method chains
48+
ProcessedData result = data.transform().normalize();
49+
50+
// Good: Explicit type for factory methods
51+
User user = User.create(name);
52+
Order order = orderService.findById(id);
53+
54+
// Avoid: Unclear type from the right-hand side
55+
var data = process(); // What type is returned?
56+
var result = calculate(); // Not immediately obvious
57+
var callback = createHandler(); // What functional interface?
58+
```
59+
60+
**When in doubt, prefer explicit types.**
61+
62+
## Imports
63+
64+
Prefer importing classes and using their simple names over inline fully qualified class names.
65+
Fully qualified names add visual clutter and make code harder to read.
66+
67+
**Use imports and simple names:**
68+
69+
```java
70+
import com.inductiveautomation.ignition.gateway.redundancy.types.ProjectState;
71+
import com.inductiveautomation.ignition.gateway.redundancy.types.HistoryLevel;
72+
73+
// Good: Clean and readable
74+
return new RedundancyState(
75+
NodeRole.Backup,
76+
ProjectState.Unknown,
77+
HistoryLevel.Partial,
78+
activityLevel);
79+
```
80+
81+
**Avoid inline fully qualified names:**
82+
83+
```java
84+
// Avoid: Verbose and cluttered
85+
return new RedundancyState(
86+
NodeRole.Backup,
87+
com.inductiveautomation.ignition.gateway.redundancy.types.ProjectState.Unknown,
88+
com.inductiveautomation.ignition.gateway.redundancy.types.HistoryLevel.Partial,
89+
activityLevel);
90+
```
91+
92+
**Exception:** Use fully qualified names only when necessary to resolve ambiguity between classes
93+
with the same simple name:
94+
95+
```java
96+
import java.util.Date;
97+
98+
// Acceptable: Resolves ambiguity with java.util.Date
99+
java.sql.Date sqlDate = new java.sql.Date(timestamp);
100+
```
101+
102+
## Nullability
103+
104+
Packages should be annotated `@NullMarked` (JSpecify). Assume non-null by default; use `@Nullable`
105+
only for parameters, fields, or return types that genuinely accept or return null.
106+
107+
## Documentation
108+
109+
- Document public APIs with Javadoc
110+
111+
- Focus on why, not what (code should be self-documenting for "what")
112+
113+
- Keep documentation up to date with code changes
114+
115+
- Javadoc tag descriptions MUST begin with a lowercase letter and MUST end with a period
116+
117+
```java
118+
/**
119+
* Creates a new connection to the server.
120+
*
121+
* @param endpoint the server endpoint URL.
122+
* @param timeout the connection timeout in milliseconds.
123+
* @return the established connection.
124+
* @throws IOException if the connection fails.
125+
*/
126+
```
127+
128+
## Other
129+
130+
For any coding practices not explicitly covered by these conventions, defer to established Java best
131+
practices and community standards. This codebase uses Java 17.

.claude/skills/commit/SKILL.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
name: commit
3+
description: Create git commits with user approval
4+
allowed-tools: Bash(git add:*), Bash(git status:*), Bash(git diff:*), Bash(git commit:*), Bash(git log:*)
5+
---
6+
7+
You are tasked with creating git commits for the changes made during this session.
8+
9+
## Process
10+
11+
1. **Think about what changed:**
12+
- Review the conversation history and understand what was achieved
13+
- Run `git status` to see current changes
14+
- Run `git diff` to understand the modifications
15+
- Consider whether changes should be one commit or multiple logical commits
16+
17+
2. **Plan your commit(s):**
18+
- Identify which files belong together
19+
- Draft clear, descriptive commit messages
20+
- Use imperative mood in commit messages
21+
- Focus on why the changes were made, not just what
22+
23+
3. **Present your plan to the user:**
24+
- List the files you plan to add for each commit
25+
- Show the commit message(s) you'll use
26+
- Ask: "I plan to create [N] commit(s) with these changes. Shall I proceed?"
27+
28+
4. **Execute upon confirmation:**
29+
- Use `git add` with specific files (never use `-A` or `.`)
30+
- Create commits with your planned messages
31+
- Show the result with `git log --oneline -n [number]`
32+
33+
## Remember
34+
35+
- You have the full context of what was done in this session
36+
- Group related changes together
37+
- Keep commits focused and atomic when possible
38+
- The user trusts your judgment – they asked you to commit
39+
- Write commit messages as if the user wrote them

0 commit comments

Comments
 (0)