200 lines
7.2 KiB
Markdown
200 lines
7.2 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
qctl is a multi-module Maven CLI tool for the QRun platform. It provides commands for project scaffolding (`qqq`), package management (`qbit`), deployment (`qrun`), and AI-assisted planning (`qstudio`).
|
|
|
|
## Build Commands
|
|
|
|
```bash
|
|
# Full build with tests
|
|
mvn clean verify
|
|
|
|
# Fast compile (skip tests)
|
|
mvn compile -DskipTests
|
|
|
|
# Checkstyle only
|
|
mvn checkstyle:check
|
|
|
|
# Spotless check/apply
|
|
mvn spotless:check
|
|
mvn spotless:apply
|
|
|
|
# Native build (requires GraalVM 21 and -Pnative profile)
|
|
JAVA_HOME=/Library/Java/JavaVirtualMachines/graalvm-21.jdk/Contents/Home mvn clean package -DskipTests -Pnative
|
|
|
|
# Output: qctl-cli/target/qctl
|
|
|
|
# Test version flag
|
|
./qctl-cli/target/qctl --version
|
|
```
|
|
|
|
## Module Structure
|
|
|
|
```
|
|
qctl/
|
|
├── qctl-shared # DTOs, ExitCodes, SPI interfaces, utilities
|
|
├── qctl-core # Config, HTTP client, auth, cache, logging, Main entrypoint
|
|
├── qctl-qqq # Template scaffolding (init, list) with Velocity
|
|
├── qctl-qbit # Package management commands, lockfile handling
|
|
├── qctl-qrun # OCI packaging and deployment commands
|
|
├── qctl-qstudio # AI planning commands (offline V1)
|
|
├── qctl-cli # Aggregator for native image build (has native profile)
|
|
├── qctl-integration-tests # E2E and integration tests with fixture templates
|
|
├── docs/ # Architecture and design documentation
|
|
├── packaging/ # Distribution manifests (Homebrew, Scoop, AUR, Docker)
|
|
└── codestyle/ # Checkstyle config and license headers
|
|
```
|
|
|
|
## Architecture
|
|
|
|
**Plugin System**: Commands discovered via `ServiceLoader<CommandPlugin>`. Each module implements `CommandPlugin` and registers via `META-INF/services`.
|
|
|
|
**CLI Framework**: Picocli with annotation-based commands. Main entrypoint in `qctl-core/Main.java`.
|
|
|
|
**Template System**: Templates fetched from [QRun-IO/templates-hub](https://github.com/QRun-IO/templates-hub). Apache Velocity for rendering with StringTool helpers (`$str.kebab()`, `$str.pascal()`, `$str.replace()`). Supports computed variables and transforms. Path variables use `__VARNAME__` or `$VARNAME` syntax.
|
|
|
|
**Interactive Commands**: All console I/O goes through `ConsoleUI` class (`qctl-qqq/template/ConsoleUI.java`). This separates UI from logic.
|
|
|
|
**Version Info**: `VersionProvider` reads from `version.properties` (Maven-filtered). Shows version, build timestamp, and git commit hash. Uses `${revision}` property for CI-friendly versioning.
|
|
|
|
**Native Image**: GraalVM 21 with reflection config. Native build is in a Maven profile (`-Pnative`) in `qctl-cli/pom.xml`.
|
|
|
|
## Code Style
|
|
|
|
- **3-space indentation** (Checkstyle enforced)
|
|
- **Braces on new line** (`LeftCurly: nl`)
|
|
- **Javadoc required** on all methods (flowerbox style)
|
|
- **No star imports**
|
|
- **Import order**: javax, java, third-party, static (alphabetical)
|
|
|
|
Flowerbox Javadoc:
|
|
```java
|
|
/***************************************************************************
|
|
* Brief description.
|
|
*
|
|
* @param foo description
|
|
* @return description
|
|
* @since 0.1.0
|
|
***************************************************************************/
|
|
```
|
|
|
|
## Key Patterns
|
|
|
|
**Exit Codes** (`qctl-shared/ExitCodes.java`):
|
|
- 0=success, 1=generic, 2=usage, 3=network, 4=auth, 5=not found, 6=validation, 7=integrity, 8=conflict, 9=cancelled
|
|
|
|
**Config Paths**:
|
|
- macOS: `~/Library/Application Support/qctl/qctl.yaml`
|
|
- Linux: `$XDG_CONFIG_HOME/qctl/qctl.yaml`
|
|
- Windows: `%APPDATA%\qctl\qctl.yaml`
|
|
|
|
## CI/CD Pipeline
|
|
|
|
Workflow: `.github/workflows/build.yml`
|
|
|
|
**Trigger**: Push to `main`/`develop`, tags `v*`, PRs
|
|
|
|
**Jobs**:
|
|
1. `test` - Run `mvn clean verify`
|
|
2. `build-native` - Build native images for 5 platforms (only on push, not PRs)
|
|
3. `release` - Create GitHub release with artifacts (only on tags)
|
|
4. `docker` - Build/push multi-arch Docker image to GHCR
|
|
5. `update-homebrew` - Push to `QRun-IO/homebrew-qctl` tap
|
|
6. `update-scoop` - Create PR for Scoop manifest update
|
|
7. `update-aur` - Create PR for AUR PKGBUILD update
|
|
|
|
**Build Matrix**:
|
|
| Platform | Runner | Artifact |
|
|
|----------|--------|----------|
|
|
| Linux x64 | ubuntu-latest | qctl-linux-amd64 |
|
|
| Linux ARM64 | ubuntu-24.04-arm | qctl-linux-arm64 |
|
|
| macOS Intel | macos-15 | qctl-macos-amd64 |
|
|
| macOS ARM | macos-14 | qctl-macos-arm64 |
|
|
| Windows x64 | windows-latest | qctl-windows-amd64.exe |
|
|
|
|
**Required Secrets**:
|
|
- `HOMEBREW_TAP_TOKEN` - PAT with repo scope for homebrew tap
|
|
|
|
**Release Process**:
|
|
```bash
|
|
git tag -a v0.0.3 -m "Release v0.0.3"
|
|
git push origin v0.0.3
|
|
```
|
|
|
|
## Distribution
|
|
|
|
| Channel | Location | Update Method |
|
|
|---------|----------|---------------|
|
|
| Homebrew | `QRun-IO/homebrew-qctl` | Direct push |
|
|
| Scoop | `packaging/scoop/qctl.json` | PR to develop |
|
|
| AUR | `packaging/aur/PKGBUILD` | PR to develop |
|
|
| Docker | `ghcr.io/qrun-io/qctl` | Direct push |
|
|
| GitHub | Releases | Auto-created |
|
|
|
|
**Install**:
|
|
```bash
|
|
# Homebrew
|
|
brew tap QRun-IO/qctl && brew install qctl
|
|
|
|
# Docker
|
|
docker run ghcr.io/qrun-io/qctl --help
|
|
```
|
|
|
|
## Native Image Notes
|
|
|
|
- Native profile is in `qctl-cli/pom.xml` (activated with `-Pnative`)
|
|
- Velocity requires runtime initialization for template parsing
|
|
- Jackson records need reflection config in `META-INF/native-image/reflect-config.json`
|
|
- Resources config in `META-INF/native-image/resource-config.json`
|
|
|
|
## Testing
|
|
|
|
**Frameworks**: JUnit 5 + AssertJ + Mockito
|
|
|
|
**Run Tests**:
|
|
```bash
|
|
mvn test # Unit tests only
|
|
mvn verify # Unit + integration tests
|
|
mvn test -pl qctl-integration-tests # E2E tests only
|
|
```
|
|
|
|
**Test Modules**:
|
|
- Unit tests in each module's `src/test/java/`
|
|
- Integration tests in `qctl-integration-tests/`
|
|
|
|
**E2E Test Infrastructure** (`qctl-integration-tests/`):
|
|
- `CommandTestHarness` - In-process command execution with stdout/stderr capture
|
|
- `TestTemplateRegistry` - Fixture-based template registry for offline testing
|
|
- `TestableConsoleUI` - Simulated user input for interactive prompts
|
|
- `ExitCodeAssertions` - Fluent assertions for exit codes
|
|
|
|
**Test Fixtures** (`src/test/resources/fixtures/templates/`):
|
|
| Fixture | Purpose |
|
|
|---------|---------|
|
|
| `test-minimal` | Basic template with no prompts |
|
|
| `test-with-prompts` | Template with interactive prompts |
|
|
| `test-full-substitution` | Tests variable replacement in content |
|
|
| `test-computed-vars` | Tests computed variables (packagePath) |
|
|
| `test-transforms` | Tests delete transforms |
|
|
| `test-variable-typo` | Tests "Did you mean?" suggestions |
|
|
|
|
**Path Variable Syntax**:
|
|
- Use `__VARNAME__` in directory names (converted to `$VARNAME` at runtime)
|
|
- Avoids shell/Maven interpretation of `$` characters
|
|
- Example: `template/src/main/java/__packagePath__/App.java`
|
|
|
|
## Session Continuity
|
|
|
|
To continue from last session, see `docs/internal/session-state.md` for current progress and next steps.
|
|
|
|
## Knowledge base
|
|
|
|
Reviewed dossier for this repo (commit `c7cf55a99e51`, branch `develop`, 2026-07-04):
|
|
`R:/Git.Local/KofTwentyTwo/second-brain/knowledge/qqq/repos/qctl.md`
|
|
|
|
QQQ platform hub (cross-repo map, v4.0 impact tracking, licensing follow-ups):
|
|
`R:/Git.Local/KofTwentyTwo/second-brain/knowledge/qqq/qqq-hub.md`
|