📦 deps(thirdparty): update snapshots

This commit is contained in:
ci[bot]
2026-06-14 16:02:32 +00:00
parent b4618ee9e9
commit 167b2b60dd
315 changed files with 47462 additions and 4210 deletions
@@ -0,0 +1,204 @@
# Language Adapter Schema
Every language adapter must follow this schema. Adapters are the single source of truth
for all language-specific behavior across the harness system.
## Design Principles
1. **Discover, don't assume**: Adapters define detection rules, not the core system
2. **One adapter, one language**: Each adapter is self-contained for one language ecosystem
3. **Graceful degradation**: Every field is optional — missing fields fall back to generic behavior
4. **Extensibility**: Adding a new language = adding one adapter file, zero core changes
## Schema Definition
```yaml
adapter:
# ─── Metadata ───────────────────────────────────────────────
language: string # Unique identifier: go, typescript, python, java, rust, etc.
display_name: string # Human-readable: "Go", "TypeScript", "Python", etc.
version: string # Adapter schema version (currently "1.0")
# ─── Detection ──────────────────────────────────────────────
# How to identify this language in a project.
# Detection runs in order; first match with highest confidence wins.
detection:
# Files whose existence signals this language (ANY match = candidate)
files: [string]
# Optional: require file content patterns for higher confidence
content_patterns:
- file: string # Glob pattern (e.g., "*.toml", "package.json")
pattern: string # Regex to match inside the file
# Overall confidence when detection.files match (0.0 - 1.0)
confidence: float
# ─── Commands ───────────────────────────────────────────────
# Standard development commands. null = not applicable for this language.
# These are defaults; project-level overrides in DEVELOPMENT.md or
# harness/config/validate.json always take priority.
commands:
build: string | null # Compile/transpile: "go build ./...", "npm run build"
test: string | null # Run tests: "go test ./...", "npm test"
lint: string | null # General linting: "golangci-lint run", "npm run lint"
lint_arch: string | null # Architectural linting: "make lint-arch", "npm run lint:arch"
format: string | null # Code formatting: "gofmt -w .", "prettier --write ."
start: string | null # Start the application: "go run main.go", "npm start"
dev: string | null # Development mode: "air", "npm run dev"
# ─── Package Manager ────────────────────────────────────────
# How to detect and use the package manager.
package_manager:
# Detection priority: first match wins
detection:
- lockfile: string # e.g., "pnpm-lock.yaml"
manager: string # e.g., "pnpm"
- lockfile: string
manager: string
default: string # Fallback if no lockfile: "npm", "pip", etc.
install_command: string # Template: "{manager} install"
# ─── Route Detection ────────────────────────────────────────
# How to find HTTP routes, CLI commands, and other entry points.
# Used by verify.py and generate_task_verification.py.
route_detection:
# Indicators that this project is a server (scan file contents)
server_indicators:
- pattern: string # Regex to find in source files
description: string # Human-readable explanation
frameworks: [string] # Associated frameworks: ["chi", "gin"]
# Indicators that this project is a CLI tool
cli_indicators:
- pattern: string
description: string
frameworks: [string]
# Indicators that this project is a frontend app
frontend_indicators:
- pattern: string
description: string
frameworks: [string]
# Route/command extraction patterns
patterns:
- type: route # "route" for HTTP, "command" for CLI
regex: string # Extraction regex with named groups
groups: [string] # Named groups: [method, path] or [command_name]
frameworks: [string] # Which frameworks this pattern matches
# ─── Import Analysis ────────────────────────────────────────
# How to analyze imports for dependency linting.
import_analysis:
# Command to list all packages/modules
list_packages: string | null # "go list ./...", null for languages without this
# Regex to extract imports from source files
import_pattern: string # e.g., '"([^"]+)"' for Go, 'from [\'"]([^\'"]+)' for TS
# File extensions to scan
source_extensions: [string] # [".go"], [".ts", ".tsx", ".js", ".jsx"]
# Module root detection
module_root_file: string # "go.mod", "package.json", "pyproject.toml"
# ─── Layer Conventions ──────────────────────────────────────
# Default layer hierarchy for architectural linting.
# These are starting-point defaults; the analyzer agent adjusts based on
# actual import graph analysis.
layer_conventions:
patterns:
- layer: int # 0 = foundational, higher = more application-specific
paths: [string] # Directory patterns: ["internal/types", "types", "domain"]
description: string # "Pure types, zero internal imports"
# ─── Dependency Detection ───────────────────────────────────
# How to detect external dependencies (databases, services, etc.)
# from the project's dependency manifest.
dependency_detection:
manifest_file: string # "go.mod", "package.json", "requirements.txt"
# Patterns to detect specific dependency types
databases:
- pattern: string # Regex on dependency name
type: string # "postgres", "mysql", "mongodb", "redis", "sqlite"
default_port: int
services:
- pattern: string
type: string # "kafka", "rabbitmq", "elasticsearch", etc.
default_port: int
# Environment variable detection in source code
env_var_patterns:
- pattern: string # e.g., 'os\.Getenv\("([^"]+)"\)' for Go
# ─── Linter Template ────────────────────────────────────────
# Reference to the linter implementation for this language.
linter:
# Pointer to the section in linter-templates.md
template_section: string # "go-linter", "typescript-linter", etc.
# File extension for the linter script
script_extension: string # ".go", ".ts", ".py"
# How to run the linter
run_command: string # "go run scripts/lint-deps.go", "npx ts-node scripts/lint-deps.ts"
# ─── Naming Conventions ─────────────────────────────────────
# File and directory naming rules for verify_action.py.
naming:
file_pattern: string # Regex: "^[a-z][a-z0-9_]*\\.go$"
test_pattern: string # Regex: "^[a-z][a-z0-9_]*_test\\.go$"
directory_style: string # "snake_case", "kebab-case", "camelCase"
# ─── CI Template ────────────────────────────────────────────
# CI configuration template for this language.
ci:
# GitHub Actions template (primary)
github_actions:
image: string # "golang:1.22", "node:20", "python:3.12"
setup_steps: [string] # Additional setup steps
cache_paths: [string] # Paths to cache: ["~/go/pkg/mod"], ["node_modules"]
# Other CI systems can be added here
```
## Resolution Priority
When the harness system needs language-specific behavior, it follows this resolution chain:
1. **Project-level override**`harness/config/validate.json`, `DEVELOPMENT.md` commands
2. **Adapter defaults** — The matching adapter's `commands` section
3. **Generic fallback**`generic.md` adapter (discovers from Makefile/README)
## Adding a New Language
To add support for a new language (e.g., Kotlin):
1. Create `references/adapters/kotlin.md` following this schema
2. Fill in detection rules, commands, route patterns
3. Optionally add a linter template section to `linter-templates.md`
4. No changes to core scripts needed — `detect_adapter.py` auto-discovers adapters
## Adapter File Format
Each adapter file uses YAML front matter followed by prose documentation:
```markdown
---
adapter:
language: kotlin
display_name: "Kotlin"
version: "1.0"
detection:
files: [build.gradle.kts, build.gradle]
confidence: 0.9
commands:
build: "./gradlew build"
test: "./gradlew test"
# ...
---
# Kotlin Adapter
## Framework-Specific Notes
### Ktor (server)
- Routes defined via `routing { get("/path") { ... } }`
- ...
### Spring Boot
- Routes via `@GetMapping`, `@PostMapping` annotations
- ...
```
@@ -0,0 +1,156 @@
---
adapter:
language: generic
display_name: "Generic (Auto-Discovery)"
version: "1.0"
detection:
files: [] # Always matches as fallback
confidence: 0.10
commands:
build: null # Discovered from Makefile / README
test: null # Discovered from Makefile / README
lint: null
lint_arch: null
format: null
start: null
dev: null
package_manager:
detection: []
default: null
install_command: null
route_detection:
server_indicators:
- pattern: 'listen|serve|http|server'
description: "Generic HTTP server indicator"
frameworks: []
cli_indicators:
- pattern: 'argv|args|argparse|getopt|flag'
description: "Generic CLI argument parsing"
frameworks: []
frontend_indicators:
- pattern: 'index\\.html|<!DOCTYPE html>'
description: "HTML file presence"
frameworks: []
patterns: []
import_analysis:
list_packages: null
import_pattern: null
source_extensions: []
module_root_file: null
layer_conventions:
patterns:
- layer: 0
paths: ["types", "models", "domain", "entities"]
description: "Core types (generic convention)"
- layer: 1
paths: ["utils", "lib", "common", "helpers", "shared"]
description: "Shared utilities (generic convention)"
- layer: 2
paths: ["services", "core", "business", "logic"]
description: "Business logic (generic convention)"
- layer: 3
paths: ["handlers", "controllers", "api", "routes", "endpoints"]
description: "API layer (generic convention)"
- layer: 4
paths: ["main", "cmd", "bin", "app", "src/index", "src/main"]
description: "Entry points (generic convention)"
dependency_detection:
manifest_file: null
databases: []
services: []
env_var_patterns: []
linter:
template_section: null
script_extension: null
run_command: null
naming:
file_pattern: null
test_pattern: null
directory_style: null
ci:
github_actions:
image: "ubuntu-latest"
setup_steps: []
cache_paths: []
---
# Generic Adapter (Auto-Discovery Fallback)
This adapter activates when no language-specific adapter matches. Instead of
assuming a specific language (previous behavior: defaulting to Go), it discovers
commands from project conventions.
## Discovery Strategy
### 1. Makefile Discovery
If a `Makefile` exists, parse targets:
```bash
# Extract make targets
grep -E '^[a-zA-Z_-]+:' Makefile | sed 's/:.*//'
```
Common target mappings:
| Target Pattern | Mapped Command |
|---------------|---------------|
| `build`, `compile` | `commands.build` |
| `test`, `check` | `commands.test` |
| `lint`, `lint-arch` | `commands.lint`, `commands.lint_arch` |
| `fmt`, `format` | `commands.format` |
| `run`, `start`, `serve` | `commands.start` |
| `dev`, `watch` | `commands.dev` |
### 2. README Discovery
If no Makefile, scan `README.md` for code blocks with common commands:
```bash
# Look for fenced code blocks with build/test commands
grep -A 2 '```' README.md
```
### 3. package.json Scripts Discovery (non-Node projects)
Some non-Node projects use `package.json` for script aliases:
```bash
# Check if package.json scripts exist
cat package.json | python3 -c "import sys,json; [print(k,v) for k,v in json.load(sys.stdin).get('scripts',{}).items()]"
```
### 4. docker-compose.yml Discovery
If `docker-compose.yml` exists, extract service definitions for environment setup.
## When Generic Adapter Activates
The generic adapter is the **last resort**. It activates only when:
1. No `go.mod`, `package.json`, `pyproject.toml`, `pom.xml`, `Cargo.toml` exists
2. Or when the user explicitly requests generic mode
## Behavior Differences from Language-Specific Adapters
| Aspect | Language Adapter | Generic Adapter |
|--------|-----------------|-----------------|
| Build command | Hardcoded default | Discovered from Makefile/README |
| Route detection | Framework-specific regex | Generic HTTP patterns only |
| Layer conventions | Language-idiomatic paths | Common directory names |
| Linter | Language-specific template | None (rely on existing tools) |
| CI template | Language-specific image | Ubuntu with custom steps |
## Extending to New Languages
If you find yourself repeatedly using the generic adapter for a specific language,
that's a signal to create a proper language adapter. See `adapter-schema.md` for
the schema to follow.
@@ -0,0 +1,212 @@
---
adapter:
language: go
display_name: "Go"
version: "1.0"
detection:
files: [go.mod, go.sum]
confidence: 0.95
commands:
build: "go build ./..."
test: "go test ./..."
lint: "golangci-lint run"
lint_arch: "make lint-arch"
format: "gofmt -w ."
start: null # Inferred from cmd/ structure or main.go
dev: null # Often uses "air" but not assumed
package_manager:
detection: [] # Go modules are built-in
default: "go"
install_command: "go mod download"
route_detection:
server_indicators:
- pattern: 'http\.ListenAndServe|http\.Server\{|\.Listen\('
description: "Standard library HTTP server"
frameworks: ["net/http"]
- pattern: 'gin\.Default|gin\.New'
description: "Gin web framework"
frameworks: ["gin"]
- pattern: 'chi\.NewRouter|chi\.NewMux'
description: "Chi router"
frameworks: ["chi"]
- pattern: 'echo\.New\(\)'
description: "Echo web framework"
frameworks: ["echo"]
- pattern: 'mux\.NewRouter'
description: "Gorilla Mux router"
frameworks: ["gorilla/mux"]
- pattern: 'fiber\.New\(\)'
description: "Fiber web framework"
frameworks: ["fiber"]
cli_indicators:
- pattern: 'github\.com/spf13/cobra'
description: "Cobra CLI framework"
frameworks: ["cobra"]
- pattern: 'github\.com/urfave/cli'
description: "urfave/cli framework"
frameworks: ["urfave/cli"]
- pattern: 'flag\.Parse\(\)|flag\.String\('
description: "Standard library flags"
frameworks: ["flag"]
frontend_indicators: [] # Go is not typically used for frontend
patterns:
# Chi router
- type: route
regex: 'r\.(Get|Post|Put|Delete|Patch|Head|Options)\s*\(\s*["\x27]([^"\x27]+)["\x27]'
groups: [method, path]
frameworks: ["chi"]
# Gin
- type: route
regex: '\.(GET|POST|PUT|DELETE|PATCH)\s*\(\s*["\x27]([^"\x27]+)["\x27]'
groups: [method, path]
frameworks: ["gin"]
# Echo
- type: route
regex: 'e\.(GET|POST|PUT|DELETE|PATCH)\s*\(\s*["\x27]([^"\x27]+)["\x27]'
groups: [method, path]
frameworks: ["echo"]
# Gorilla Mux
- type: route
regex: '\.HandleFunc\s*\(\s*["\x27]([^"\x27]+)["\x27].*\)\.(Methods)\s*\(\s*["\x27]([^"\x27]+)["\x27]\)'
groups: [path, _, method]
frameworks: ["gorilla/mux"]
# net/http
- type: route
regex: 'http\.HandleFunc\s*\(\s*["\x27]([^"\x27]+)["\x27]'
groups: [path]
frameworks: ["net/http"]
# Cobra CLI
- type: command
regex: '&cobra\.Command\s*\{\s*Use:\s*["\x27]([^"\x27\s]+)'
groups: [command_name]
frameworks: ["cobra"]
import_analysis:
list_packages: "go list -json ./..."
import_pattern: '"([^"]+)"'
source_extensions: [".go"]
module_root_file: "go.mod"
layer_conventions:
patterns:
- layer: 0
paths: ["internal/types", "types", "domain", "model", "entity"]
description: "Pure types, zero internal imports"
- layer: 1
paths: ["internal/utils", "utils", "pkg/utils", "lib"]
description: "Utilities, depend only on types"
- layer: 2
paths: ["internal/core", "core", "internal/service", "service"]
description: "Business logic, depend on types + utils"
- layer: 3
paths: ["internal/handler", "handler", "api", "internal/api"]
description: "HTTP/gRPC handlers, depend on core"
- layer: 4
paths: ["cmd"]
description: "Entry points, depend on everything"
dependency_detection:
manifest_file: "go.mod"
databases:
- pattern: "github.com/jackc/pgx|github.com/lib/pq"
type: "postgres"
default_port: 5432
- pattern: "github.com/go-sql-driver/mysql"
type: "mysql"
default_port: 3306
- pattern: "go.mongodb.org/mongo-driver"
type: "mongodb"
default_port: 27017
- pattern: "github.com/go-redis/redis|github.com/redis/go-redis"
type: "redis"
default_port: 6379
- pattern: "github.com/mattn/go-sqlite3|modernc.org/sqlite"
type: "sqlite"
default_port: 0
services:
- pattern: "github.com/segmentio/kafka-go|github.com/IBM/sarama"
type: "kafka"
default_port: 9092
- pattern: "github.com/rabbitmq/amqp091-go|github.com/streadway/amqp"
type: "rabbitmq"
default_port: 5672
- pattern: "github.com/nats-io/nats.go"
type: "nats"
default_port: 4222
- pattern: "github.com/elastic/go-elasticsearch"
type: "elasticsearch"
default_port: 9200
env_var_patterns:
- pattern: 'os\.Getenv\("([^"]+)"\)'
- pattern: 'os\.LookupEnv\("([^"]+)"\)'
- pattern: 'viper\.\w+\("([^"]+)"\)'
linter:
template_section: "go-linter"
script_extension: ".go"
run_command: "go run scripts/lint-deps.go"
naming:
file_pattern: "^[a-z][a-z0-9_]*\\.go$"
test_pattern: "^[a-z][a-z0-9_]*_test\\.go$"
directory_style: "snake_case"
ci:
github_actions:
image: "golang:1.22"
setup_steps:
- "uses: actions/setup-go@v5\n with:\n go-version: '1.22'"
cache_paths: ["~/go/pkg/mod", "~/.cache/go-build"]
---
# Go Adapter
## Server Start Command Inference
Priority order for detecting the server start command:
1. Existing `harness/config/environment.json` startup command, if present
2. `cmd/server/main.go` exists → `go run cmd/server/main.go`
3. `cmd/api/main.go` exists → `go run cmd/api/main.go`
4. `main.go` at root with `http` import → `go run main.go`
5. Fail with actionable error
## CLI Binary Inference
1. `cmd/cli/main.go` exists → `go build -o bin/cli cmd/cli/main.go`
2. `cmd/<name>/main.go` exists → `go build -o bin/<name> cmd/<name>/main.go`
3. `main.go` at root with `cobra`/`flag` import → `go build -o bin/app .`
## Testing Patterns
- Unit tests: `*_test.go` files alongside source
- Integration tests: `//go:build integration` build tag → `go test -tags=integration ./...`
- Table-driven tests are idiomatic
## Common Frameworks
| Framework | Detection Pattern | Route Style |
|-----------|------------------|-------------|
| chi | `github.com/go-chi/chi` | `r.Get("/path", handler)` |
| gin | `github.com/gin-gonic/gin` | `r.GET("/path", handler)` |
| echo | `github.com/labstack/echo` | `e.GET("/path", handler)` |
| fiber | `github.com/gofiber/fiber` | `app.Get("/path", handler)` |
| gorilla/mux | `github.com/gorilla/mux` | `r.HandleFunc("/path", handler).Methods("GET")` |
| net/http | stdlib | `http.HandleFunc("/path", handler)` |
## Structured Logging
Go projects should use structured loggers. Common patterns to detect:
- `go.uber.org/zap``zap.String()`, `zap.Int()`
- `log/slog` (stdlib) → `slog.Info()`, `slog.With()`
- `github.com/rs/zerolog``log.Info().Str().Msg()`
- `github.com/sirupsen/logrus``logrus.WithFields()`
Unstructured patterns to flag: `log.Printf`, `log.Println`, `log.Fatalf`, `fmt.Printf` (in non-CLI code)
@@ -0,0 +1,205 @@
---
adapter:
language: java
display_name: "Java / Kotlin"
version: "1.0"
detection:
files: [pom.xml, build.gradle, build.gradle.kts, settings.gradle, settings.gradle.kts]
content_patterns:
- file: "pom.xml"
pattern: "<groupId>"
- file: "build.gradle.kts"
pattern: "plugins|dependencies"
confidence: 0.90
commands:
build: null # Detected from build tool
test: null # Detected from build tool
lint: null # Often spotbugs, checkstyle, or ktlint
lint_arch: null
format: null
start: null
dev: null
package_manager:
detection:
- lockfile: "pom.xml"
manager: "maven"
- lockfile: "build.gradle"
manager: "gradle"
- lockfile: "build.gradle.kts"
manager: "gradle"
default: "maven"
install_command: null # Dependencies resolved during build
route_detection:
server_indicators:
- pattern: '@RestController|@Controller|@RequestMapping'
description: "Spring MVC/Boot controller"
frameworks: ["spring"]
- pattern: 'import io\.micronaut'
description: "Micronaut framework"
frameworks: ["micronaut"]
- pattern: 'import io\.quarkus'
description: "Quarkus framework"
frameworks: ["quarkus"]
- pattern: 'import io\.vertx'
description: "Vert.x framework"
frameworks: ["vertx"]
- pattern: 'import io\.ktor'
description: "Ktor framework (Kotlin)"
frameworks: ["ktor"]
- pattern: 'import io\.javalin'
description: "Javalin web framework"
frameworks: ["javalin"]
cli_indicators:
- pattern: 'import picocli|@CommandLine'
description: "picocli CLI framework"
frameworks: ["picocli"]
- pattern: 'public static void main\(String'
description: "Java main method (potential CLI)"
frameworks: ["stdlib"]
frontend_indicators: []
patterns:
# Spring MVC annotations
- type: route
regex: '@(GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping)\s*\(\s*(?:value\s*=\s*)?["\x27]([^"\x27]*)["\x27]'
groups: [method, path]
frameworks: ["spring"]
# Spring RequestMapping
- type: route
regex: '@RequestMapping\s*\(.*(?:value|path)\s*=\s*["\x27]([^"\x27]+)["\x27].*method\s*=\s*RequestMethod\.(\w+)'
groups: [path, method]
frameworks: ["spring"]
# Ktor (Kotlin)
- type: route
regex: '(get|post|put|delete|patch)\s*\(\s*["\x27]([^"\x27]+)["\x27]'
groups: [method, path]
frameworks: ["ktor"]
# Javalin
- type: route
regex: 'app\.(get|post|put|delete|patch)\s*\(\s*["\x27]([^"\x27]+)["\x27]'
groups: [method, path]
frameworks: ["javalin"]
import_analysis:
list_packages: null
import_pattern: "^import\\s+([\\w.]+)"
source_extensions: [".java", ".kt"]
module_root_file: "pom.xml"
layer_conventions:
patterns:
- layer: 0
paths: ["src/main/java/**/model", "src/main/java/**/entity", "src/main/java/**/dto"]
description: "Domain models, entities, DTOs"
- layer: 1
paths: ["src/main/java/**/util", "src/main/java/**/common", "src/main/java/**/config"]
description: "Utilities and configuration"
- layer: 2
paths: ["src/main/java/**/service", "src/main/java/**/repository", "src/main/java/**/dao"]
description: "Service and data access layer"
- layer: 3
paths: ["src/main/java/**/controller", "src/main/java/**/api", "src/main/java/**/resource"]
description: "REST controllers, API endpoints"
- layer: 4
paths: ["src/main/java/**/Application.java", "src/main/java/**/Main.java"]
description: "Application entry point"
dependency_detection:
manifest_file: "pom.xml"
databases:
- pattern: "postgresql|postgres"
type: "postgres"
default_port: 5432
- pattern: "mysql-connector"
type: "mysql"
default_port: 3306
- pattern: "mongodb-driver|mongo-java-driver"
type: "mongodb"
default_port: 27017
- pattern: "jedis|lettuce-core|spring-data-redis"
type: "redis"
default_port: 6379
- pattern: "h2|sqlite-jdbc"
type: "sqlite"
default_port: 0
services:
- pattern: "kafka-clients|spring-kafka"
type: "kafka"
default_port: 9092
- pattern: "amqp-client|spring-amqp|spring-rabbit"
type: "rabbitmq"
default_port: 5672
- pattern: "elasticsearch-rest-client|spring-data-elasticsearch"
type: "elasticsearch"
default_port: 9200
env_var_patterns:
- pattern: 'System\.getenv\(\s*["\x27]([^"\x27]+)["\x27]\)'
- pattern: '\\$\\{([A-Z_][A-Z0-9_]*)\\}'
linter:
template_section: "java-linter"
script_extension: ".java"
run_command: null # Typically integrated into build tool (spotbugs, checkstyle)
naming:
file_pattern: "^[A-Z][a-zA-Z0-9]*\\.java$"
test_pattern: "^[A-Z][a-zA-Z0-9]*Test\\.java$"
directory_style: "lowercase"
ci:
github_actions:
image: null # Uses setup-java action
setup_steps:
- "uses: actions/setup-java@v4\n with:\n distribution: 'temurin'\n java-version: '21'"
cache_paths: ["~/.m2/repository", "~/.gradle/caches"]
---
# Java / Kotlin Adapter
## Build Tool Detection
| File | Build Tool | Build Command | Test Command |
|------|-----------|---------------|--------------|
| `pom.xml` | Maven | `mvn package -DskipTests` | `mvn test` |
| `build.gradle` | Gradle (Groovy) | `./gradlew build -x test` | `./gradlew test` |
| `build.gradle.kts` | Gradle (Kotlin DSL) | `./gradlew build -x test` | `./gradlew test` |
If `mvnw` or `gradlew` wrapper exists, prefer the wrapper over system-installed tool.
## Server Start Command Inference
1. Existing `harness/config/environment.json` startup command, if present
2. Spring Boot → `./gradlew bootRun` or `mvn spring-boot:run`
3. Fat JAR exists → `java -jar target/*.jar` or `java -jar build/libs/*.jar`
4. Main class annotated with `@SpringBootApplication` → infer from pom.xml/build.gradle
## Framework-Specific Notes
### Spring Boot
- Routes via annotations: `@GetMapping("/path")`, `@PostMapping("/path")`
- Controller prefix: `@RequestMapping("/api/v1")` on class
- Auto-configuration: `application.properties` or `application.yml`
- Default port: 8080 (configurable via `server.port`)
- Actuator health: `/actuator/health`
### Micronaut
- Similar annotation style to Spring: `@Get("/path")`, `@Post("/path")`
- Compile-time DI (no reflection)
- Default port: 8080
### Ktor (Kotlin)
- DSL-based routing: `routing { get("/path") { ... } }`
- Configuration via `application.conf` (HOCON) or `application.yaml`
## Testing Patterns
- JUnit 5 is standard: `@Test`, `@ParameterizedTest`
- Kotlin: same JUnit 5 + kotest as alternative
- Integration tests often use `@SpringBootTest` + Testcontainers
- Test directory: `src/test/java/` or `src/test/kotlin/`
@@ -0,0 +1,225 @@
---
adapter:
language: python
display_name: "Python"
version: "1.0"
detection:
files: [pyproject.toml, setup.py, requirements.txt, Pipfile]
content_patterns:
- file: "pyproject.toml"
pattern: '\\[project\\]|\\[tool\\.poetry\\]'
confidence: 0.90
commands:
build: null # Python typically doesn't need a build step
test: "pytest"
lint: "ruff check ."
lint_arch: "python scripts/lint_deps.py src/"
format: "ruff format ."
start: null # Inferred from framework
dev: null
package_manager:
detection:
- lockfile: "poetry.lock"
manager: "poetry"
- lockfile: "uv.lock"
manager: "uv"
- lockfile: "Pipfile.lock"
manager: "pipenv"
- lockfile: "pdm.lock"
manager: "pdm"
default: "pip"
install_command: "{manager} install"
route_detection:
server_indicators:
- pattern: 'from fastapi|import fastapi|FastAPI\(\)'
description: "FastAPI ASGI framework"
frameworks: ["fastapi"]
- pattern: 'from flask|import flask|Flask\(__name__\)'
description: "Flask WSGI framework"
frameworks: ["flask"]
- pattern: 'from django|import django'
description: "Django web framework"
frameworks: ["django"]
- pattern: 'from aiohttp|import aiohttp\.web'
description: "aiohttp async web framework"
frameworks: ["aiohttp"]
- pattern: 'from starlette|import starlette'
description: "Starlette ASGI framework"
frameworks: ["starlette"]
- pattern: 'from litestar|import litestar'
description: "Litestar ASGI framework"
frameworks: ["litestar"]
cli_indicators:
- pattern: 'import click|from click'
description: "Click CLI framework"
frameworks: ["click"]
- pattern: 'import typer|from typer'
description: "Typer CLI framework"
frameworks: ["typer"]
- pattern: 'import argparse|from argparse'
description: "Standard library argparse"
frameworks: ["argparse"]
- pattern: 'import fire|from fire'
description: "Google Python Fire"
frameworks: ["fire"]
frontend_indicators: [] # Python is not typically used for frontend
patterns:
# FastAPI
- type: route
regex: '@(?:app|router)\.(get|post|put|delete|patch)\s*\(\s*["\x27]([^"\x27]+)["\x27]'
groups: [method, path]
frameworks: ["fastapi", "starlette", "litestar"]
# Flask
- type: route
regex: '@(?:app|bp|blueprint)\.(route)\s*\(\s*["\x27]([^"\x27]+)["\x27](?:.*methods\s*=\s*\[([^\]]+)\])?'
groups: [_, path, method]
frameworks: ["flask"]
# Django URLs
- type: route
regex: 'path\s*\(\s*["\x27]([^"\x27]+)["\x27]'
groups: [path]
frameworks: ["django"]
# Click
- type: command
regex: '@\w+\.command\s*\(\s*(?:name\s*=\s*)?["\x27]?([^"\x27\)]+)'
groups: [command_name]
frameworks: ["click"]
# Typer
- type: command
regex: '@app\.command\s*\(\s*(?:name\s*=\s*)?["\x27]?([^"\x27\)]*)'
groups: [command_name]
frameworks: ["typer"]
import_analysis:
list_packages: null
import_pattern: "^(?:from|import)\\s+([\\w.]+)"
source_extensions: [".py"]
module_root_file: "pyproject.toml"
layer_conventions:
patterns:
- layer: 0
paths: ["src/models", "src/schemas", "src/types", "models", "schemas"]
description: "Data models, Pydantic schemas, type definitions"
- layer: 1
paths: ["src/utils", "src/lib", "src/common", "utils", "lib"]
description: "Shared utilities"
- layer: 2
paths: ["src/services", "src/core", "src/domain", "services", "core"]
description: "Business logic, service layer"
- layer: 3
paths: ["src/api", "src/routes", "src/views", "src/handlers", "api", "routes"]
description: "API endpoints, request handlers"
- layer: 4
paths: ["src/main.py", "src/app.py", "src/cli.py", "main.py", "app.py"]
description: "Application entry points"
dependency_detection:
manifest_file: "pyproject.toml"
databases:
- pattern: "psycopg|asyncpg|sqlalchemy.*postgres|databases.*postgres"
type: "postgres"
default_port: 5432
- pattern: "pymysql|aiomysql|mysqlclient"
type: "mysql"
default_port: 3306
- pattern: "pymongo|motor"
type: "mongodb"
default_port: 27017
- pattern: "redis|aioredis"
type: "redis"
default_port: 6379
- pattern: "aiosqlite|sqlite3"
type: "sqlite"
default_port: 0
services:
- pattern: "confluent-kafka|aiokafka"
type: "kafka"
default_port: 9092
- pattern: "pika|aio-pika"
type: "rabbitmq"
default_port: 5672
- pattern: "elasticsearch|elastic-transport"
type: "elasticsearch"
default_port: 9200
env_var_patterns:
- pattern: 'os\.environ\.get\(\s*["\x27]([^"\x27]+)["\x27]'
- pattern: 'os\.environ\[["\x27]([^"\x27]+)["\x27]\]'
- pattern: 'os\.getenv\(\s*["\x27]([^"\x27]+)["\x27]'
linter:
template_section: "python-linter"
script_extension: ".py"
run_command: "python scripts/lint_deps.py src/"
naming:
file_pattern: "^[a-z][a-z0-9_]*\\.py$"
test_pattern: "^test_[a-z][a-z0-9_]*\\.py$"
directory_style: "snake_case"
ci:
github_actions:
image: "python:3.12"
setup_steps:
- "uses: actions/setup-python@v5\n with:\n python-version: '3.12'"
cache_paths: ["~/.cache/pip", ".venv"]
---
# Python Adapter
## Server Start Command Inference
1. Existing `harness/config/environment.json` startup command, if present
2. FastAPI detected → `python -m uvicorn {module}:app --port 8080`
- Module inferred from main app file location
3. Flask detected → `python -m flask run --port 8080`
4. Django detected → `python manage.py runserver 8080`
5. `main.py` exists → `python main.py`
## Virtual Environment Detection
The adapter checks for virtual environments in this order:
1. `.venv/` directory → `source .venv/bin/activate`
2. `venv/` directory → `source venv/bin/activate`
3. `poetry.lock``poetry shell` or prefix with `poetry run`
4. `uv.lock` → prefix with `uv run`
5. `Pipfile.lock` → prefix with `pipenv run`
## Framework-Specific Notes
### FastAPI
- Routes via decorators: `@app.get("/path")`, `@router.post("/path")`
- Dependency injection via `Depends()`
- Auto-generated OpenAPI docs at `/docs` and `/redoc`
- Start with uvicorn: `uvicorn app.main:app --reload`
### Flask
- Routes via decorators: `@app.route("/path", methods=["GET"])`
- Blueprints for modular routing
- Start with: `flask run` or `python -m flask run`
### Django
- URL configuration in `urls.py`: `path("api/", include("app.urls"))`
- Class-based views and function-based views
- Start with: `python manage.py runserver`
- Migrations: `python manage.py migrate`
### Click / Typer (CLI)
- Click: `@cli.command()` decorator pattern
- Typer: `@app.command()` decorator pattern, with auto-generated help
## Type Checking
Python projects may use type checkers:
- `mypy` — most common, configured in `pyproject.toml` or `mypy.ini`
- `pyright` — Microsoft's type checker, often via Pylance
- `pytype` — Google's type checker
Detection: check `pyproject.toml` `[tool.mypy]` or `mypy.ini` existence.
@@ -0,0 +1,220 @@
---
adapter:
language: rust
display_name: "Rust"
version: "1.0"
detection:
files: [Cargo.toml, Cargo.lock]
content_patterns:
- file: "Cargo.toml"
pattern: '\\[package\\]'
confidence: 0.95
commands:
build: "cargo build"
test: "cargo test"
lint: "cargo clippy -- -D warnings"
lint_arch: null # Rust module system enforces architecture naturally
format: "cargo fmt"
start: "cargo run"
dev: "cargo watch -x run"
package_manager:
detection: [] # Cargo is built-in
default: "cargo"
install_command: "cargo build"
route_detection:
server_indicators:
- pattern: 'use actix_web|actix_web::'
description: "Actix-web framework"
frameworks: ["actix-web"]
- pattern: 'use axum|axum::'
description: "Axum web framework"
frameworks: ["axum"]
- pattern: 'use rocket|#\[rocket::main\]'
description: "Rocket web framework"
frameworks: ["rocket"]
- pattern: 'use warp|warp::'
description: "Warp web framework"
frameworks: ["warp"]
- pattern: 'use hyper|hyper::'
description: "Hyper HTTP library"
frameworks: ["hyper"]
- pattern: 'use tide|tide::'
description: "Tide web framework"
frameworks: ["tide"]
cli_indicators:
- pattern: 'use clap|clap::'
description: "Clap CLI framework"
frameworks: ["clap"]
- pattern: 'use structopt|structopt::'
description: "StructOpt CLI (legacy clap)"
frameworks: ["structopt"]
- pattern: 'std::env::args'
description: "Standard library args parsing"
frameworks: ["stdlib"]
frontend_indicators:
- pattern: 'use leptos|leptos::'
description: "Leptos WASM framework"
frameworks: ["leptos"]
- pattern: 'use yew|yew::'
description: "Yew WASM framework"
frameworks: ["yew"]
- pattern: 'use dioxus|dioxus::'
description: "Dioxus UI framework"
frameworks: ["dioxus"]
patterns:
# Actix-web
- type: route
regex: '#\[(?:web::)?(get|post|put|delete|patch)\s*\(\s*"([^"]+)"'
groups: [method, path]
frameworks: ["actix-web"]
# Axum
- type: route
regex: '\.(get|post|put|delete|patch)\s*\(\s*"([^"]+)"'
groups: [method, path]
frameworks: ["axum"]
# Rocket
- type: route
regex: '#\[(get|post|put|delete|patch)\s*\(\s*"([^"]+)"'
groups: [method, path]
frameworks: ["rocket"]
# Clap derive
- type: command
regex: '#\[command\s*\(.*name\s*=\s*"([^"]+)"'
groups: [command_name]
frameworks: ["clap"]
# Clap builder
- type: command
regex: 'Command::new\s*\(\s*"([^"]+)"'
groups: [command_name]
frameworks: ["clap"]
import_analysis:
list_packages: "cargo metadata --format-version 1"
import_pattern: "use\\s+([\\w:]+)"
source_extensions: [".rs"]
module_root_file: "Cargo.toml"
layer_conventions:
patterns:
- layer: 0
paths: ["src/models", "src/types", "src/domain"]
description: "Domain types and models"
- layer: 1
paths: ["src/utils", "src/common", "src/lib.rs"]
description: "Shared utilities"
- layer: 2
paths: ["src/services", "src/core", "src/repository"]
description: "Business logic"
- layer: 3
paths: ["src/handlers", "src/routes", "src/api"]
description: "HTTP/API handlers"
- layer: 4
paths: ["src/main.rs", "src/bin"]
description: "Entry points"
dependency_detection:
manifest_file: "Cargo.toml"
databases:
- pattern: 'sqlx.*postgres|tokio-postgres|diesel.*postgres'
type: "postgres"
default_port: 5432
- pattern: 'sqlx.*mysql|diesel.*mysql'
type: "mysql"
default_port: 3306
- pattern: 'mongodb'
type: "mongodb"
default_port: 27017
- pattern: 'redis|deadpool-redis'
type: "redis"
default_port: 6379
- pattern: 'rusqlite|sqlx.*sqlite'
type: "sqlite"
default_port: 0
services:
- pattern: 'rdkafka|kafka'
type: "kafka"
default_port: 9092
- pattern: 'lapin|amqp'
type: "rabbitmq"
default_port: 5672
- pattern: 'elasticsearch'
type: "elasticsearch"
default_port: 9200
env_var_patterns:
- pattern: 'std::env::var\(\s*"([^"]+)"'
- pattern: 'env::var\(\s*"([^"]+)"'
- pattern: 'dotenv::var\(\s*"([^"]+)"'
linter:
template_section: "rust-linter"
script_extension: ".rs"
run_command: "cargo clippy"
naming:
file_pattern: "^[a-z][a-z0-9_]*\\.rs$"
test_pattern: "^[a-z][a-z0-9_]*\\.rs$" # Tests are inline in Rust
directory_style: "snake_case"
ci:
github_actions:
image: null
setup_steps:
- "uses: dtolnay/rust-toolchain@stable\n with:\n components: clippy, rustfmt"
cache_paths: ["~/.cargo/registry", "~/.cargo/git", "target"]
---
# Rust Adapter
## Architecture Note
Rust's module system (`mod`, `pub`, `pub(crate)`) naturally enforces encapsulation.
The `lint_arch` command is `null` because Rust's compiler already prevents many
dependency violations at compile time. However, a custom architectural linter can
still be valuable for enforcing higher-level layer boundaries.
## Server Start Command Inference
1. Existing `harness/config/environment.json` startup command, if present
2. `Cargo.toml` has `[[bin]]` section → `cargo run --bin <name>`
3. Default → `cargo run`
For release builds: `cargo build --release && ./target/release/<name>`
## Framework-Specific Notes
### Axum
- Router-based: `Router::new().route("/path", get(handler))`
- Extractors for request parsing: `Json<T>`, `Path<T>`, `Query<T>`
- State sharing via `Extension` or `State`
- Default: runs on `0.0.0.0:3000`
### Actix-web
- Attribute macros: `#[get("/path")]`, `#[post("/path")]`
- App factory pattern: `App::new().service(handler)`
- Default: `HttpServer::new(...).bind("127.0.0.1:8080")`
### Rocket
- Attribute macros: `#[get("/path")]`, `#[post("/path")]`
- Fairings for middleware
- Config via `Rocket.toml`
## Testing Patterns
- Unit tests: inline `#[cfg(test)] mod tests { ... }` in same file
- Integration tests: `tests/` directory at crate root
- `cargo test` runs both
- Useful flags: `cargo test -- --nocapture` (show println output)
## Workspace Support
If `[workspace]` in root `Cargo.toml`:
- Each member crate may have its own layer conventions
- Build: `cargo build --workspace`
- Test: `cargo test --workspace`
@@ -0,0 +1,245 @@
---
adapter:
language: typescript
display_name: "TypeScript / JavaScript"
version: "1.0"
detection:
files: [package.json, tsconfig.json]
content_patterns:
- file: "package.json"
pattern: '"(typescript|@types/node)"'
confidence: 0.90
commands:
build: "{pkg_manager} run build"
test: "{pkg_manager} test"
lint: "{pkg_manager} run lint"
lint_arch: "{pkg_manager} run lint:arch"
format: "{pkg_manager} run format"
start: "{pkg_manager} start"
dev: "{pkg_manager} run dev"
package_manager:
detection:
- lockfile: "pnpm-lock.yaml"
manager: "pnpm"
- lockfile: "yarn.lock"
manager: "yarn"
- lockfile: "bun.lockb"
manager: "bun"
- lockfile: "package-lock.json"
manager: "npm"
default: "npm"
install_command: "{manager} install"
route_detection:
server_indicators:
- pattern: 'require\(["\x27]express["\x27]\)|from ["\x27]express["\x27]'
description: "Express.js web framework"
frameworks: ["express"]
- pattern: 'require\(["\x27]fastify["\x27]\)|from ["\x27]fastify["\x27]'
description: "Fastify web framework"
frameworks: ["fastify"]
- pattern: 'from ["\x27]@nestjs/common["\x27]'
description: "NestJS framework"
frameworks: ["nestjs"]
- pattern: 'require\(["\x27]koa["\x27]\)|from ["\x27]koa["\x27]'
description: "Koa web framework"
frameworks: ["koa"]
- pattern: 'require\(["\x27]hono["\x27]\)|from ["\x27]hono["\x27]'
description: "Hono web framework"
frameworks: ["hono"]
- pattern: 'createServer|http\.Server'
description: "Node.js HTTP server"
frameworks: ["http"]
cli_indicators:
- pattern: 'require\(["\x27]commander["\x27]\)|from ["\x27]commander["\x27]'
description: "Commander.js CLI framework"
frameworks: ["commander"]
- pattern: 'require\(["\x27]yargs["\x27]\)|from ["\x27]yargs["\x27]'
description: "Yargs CLI framework"
frameworks: ["yargs"]
- pattern: 'require\(["\x27]@oclif/core["\x27]\)|from ["\x27]@oclif'
description: "Oclif CLI framework"
frameworks: ["oclif"]
- pattern: 'require\(["\x27]inquirer["\x27]\)|from ["\x27]inquirer["\x27]'
description: "Inquirer.js interactive CLI"
frameworks: ["inquirer"]
frontend_indicators:
- pattern: 'from ["\x27]react["\x27]|require\(["\x27]react["\x27]\)'
description: "React"
frameworks: ["react"]
- pattern: 'from ["\x27]vue["\x27]|createApp'
description: "Vue.js"
frameworks: ["vue"]
- pattern: 'from ["\x27]svelte["\x27]'
description: "Svelte"
frameworks: ["svelte"]
- pattern: 'from ["\x27]next["\x27]|from ["\x27]next/'
description: "Next.js"
frameworks: ["next"]
- pattern: 'defineNuxtConfig|from ["\x27]nuxt["\x27]'
description: "Nuxt"
frameworks: ["nuxt"]
patterns:
# Express / Koa style
- type: route
regex: '(app|router)\.(get|post|put|delete|patch|all)\s*\(\s*["\x27]([^"\x27]+)["\x27]'
groups: [_, method, path]
frameworks: ["express", "koa", "hono"]
# Fastify
- type: route
regex: '(fastify|server|app)\.(get|post|put|delete|patch)\s*\(\s*["\x27]([^"\x27]+)["\x27]'
groups: [_, method, path]
frameworks: ["fastify"]
# NestJS decorators
- type: route
regex: '@(Get|Post|Put|Delete|Patch)\s*\(\s*["\x27]([^"\x27]*)["\x27]?\s*\)'
groups: [method, path]
frameworks: ["nestjs"]
# Next.js app router (file-based)
- type: route
regex: 'export\s+(?:async\s+)?function\s+(GET|POST|PUT|DELETE|PATCH)'
groups: [method]
frameworks: ["next"]
# Commander CLI
- type: command
regex: '\.command\s*\(\s*["\x27]([^"\x27]+)["\x27]'
groups: [command_name]
frameworks: ["commander"]
# Yargs
- type: command
regex: '\.command\s*\(\s*["\x27]([^"\x27\s]+)'
groups: [command_name]
frameworks: ["yargs"]
import_analysis:
list_packages: null # TS doesn't have a native package lister
import_pattern: "from ['\"]([^'\"]+)['\"]|require\\(['\"]([^'\"]+)['\"]\\)"
source_extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]
module_root_file: "package.json"
layer_conventions:
patterns:
- layer: 0
paths: ["src/types", "src/models", "types", "shared/types"]
description: "Type definitions, interfaces, schemas"
- layer: 1
paths: ["src/utils", "src/lib", "src/helpers", "utils", "lib"]
description: "Utility functions, depend only on types"
- layer: 2
paths: ["src/services", "src/core", "services", "core"]
description: "Business logic layer"
- layer: 3
paths: ["src/controllers", "src/handlers", "src/routes", "src/api"]
description: "HTTP/API handlers"
- layer: 4
paths: ["src/app", "src/pages", "src/index.ts", "src/main.ts"]
description: "Application entry points"
dependency_detection:
manifest_file: "package.json"
databases:
- pattern: '"(pg|postgres|@prisma/client|typeorm|knex|drizzle-orm|sequelize)"'
type: "postgres"
default_port: 5432
- pattern: '"(mysql2|mysql)"'
type: "mysql"
default_port: 3306
- pattern: '"(mongodb|mongoose|mongosh)"'
type: "mongodb"
default_port: 27017
- pattern: '"(redis|ioredis|@redis/client)"'
type: "redis"
default_port: 6379
- pattern: '"(better-sqlite3|sql.js)"'
type: "sqlite"
default_port: 0
services:
- pattern: '"(kafkajs|@kafka-js/confluent-schema-registry)"'
type: "kafka"
default_port: 9092
- pattern: '"(amqplib|amqp-connection-manager)"'
type: "rabbitmq"
default_port: 5672
- pattern: '"(@elastic/elasticsearch)"'
type: "elasticsearch"
default_port: 9200
env_var_patterns:
- pattern: 'process\.env\.([A-Z_][A-Z0-9_]*)'
- pattern: 'process\.env\[[\x27"]([A-Z_][A-Z0-9_]*)[\x27"]\]'
linter:
template_section: "typescript-linter"
script_extension: ".ts"
run_command: "npx ts-node scripts/lint-deps.ts"
naming:
file_pattern: "^[a-zA-Z][a-zA-Z0-9.-]*\\.(ts|tsx|js|jsx|mjs|cjs)$"
test_pattern: "^[a-zA-Z][a-zA-Z0-9.-]*\\.(test|spec)\\.(ts|tsx|js|jsx)$"
directory_style: "kebab-case"
ci:
github_actions:
image: "node:20"
setup_steps:
- "uses: actions/setup-node@v4\n with:\n node-version: '20'"
cache_paths: ["node_modules", ".next/cache"]
---
# TypeScript / JavaScript Adapter
## Package Manager Detection
TypeScript projects have multiple package managers. Detection priority:
| Lock File | Manager | Run Command |
|-----------|---------|-------------|
| `pnpm-lock.yaml` | pnpm | `pnpm run <script>` |
| `yarn.lock` | yarn | `yarn <script>` |
| `bun.lockb` | bun | `bun run <script>` |
| `package-lock.json` | npm | `npm run <script>` |
All `{pkg_manager}` placeholders in commands are resolved at detection time.
## Server Start Command Inference
1. Existing `harness/config/environment.json` startup command, if present
2. `package.json``scripts.start` exists → `{pkg_manager} start`
3. `package.json``scripts.dev` exists → `{pkg_manager} run dev`
4. `dist/index.js` exists → `node dist/index.js`
5. `src/index.ts` exists → `npx ts-node src/index.ts`
## Port Detection
1. Existing `harness/config/environment.json` readiness port, if present
2. `package.json` scripts containing `PORT=(\d+)` → use that port
3. `.env` containing `PORT=(\d+)` → use that port
4. Default: 3000 (frontend), 8080 (server)
## Framework-Specific Notes
### Next.js / Nuxt
- File-based routing: routes are derived from `app/` or `pages/` directory structure
- API routes: `app/api/**/route.ts` (Next.js App Router)
- Use `next build && next start` for production verification
### NestJS
- Decorator-based routing: `@Get()`, `@Post()`, `@Controller('prefix')`
- Module system: scan `*.module.ts` for service registration
- Default port: 3000
### Express / Fastify
- Explicit routing: `app.get('/path', handler)`
- Middleware chain matters for verification order
## Monorepo Support
If `workspaces` in `package.json` or `pnpm-workspace.yaml` exists:
- Run detection per-workspace
- Each workspace may have its own adapter overlay
- Build order respects workspace dependency graph