This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Requirements: Java 25 (Gradle 9.4.0), git, graphviz (dot)
make build # compile and assemble
make run # start web UI on port 7070 (via Gradle, picks up source changes)
make run-jar # run pre-built fat JAR (faster startup)
make dev # watch src/, rebuild + restart on change (requires entr)
make test # run the full test suite
make check # tests + all static checks
make clean # delete build outputRun a single test class via Gradle:
./gradlew test --tests "attractor.engine.EngineTest"Override JAVA_HOME if Java 25 is not at the default Homebrew path:
make build JAVA_HOME=/usr/lib/jvm/java-25-openjdkThe server JAR is build/libs/attractor-server-devel.jar; the CLI JAR is build/libs/attractor-cli-devel.jar. Use make release to produce versioned JARs from a git tag.
Docker:
make docker-build-base # builds attractor-base:local from docker/Dockerfile.base
make docker-build # builds attractor:local (builds base first if absent)
make docker-run # runs attractor:local, auto-loads .env if presentAttractor is a Kotlin/JVM pipeline runner for DOT-graph-defined AI workflows. It has two main entry points:
src/main/kotlin/attractor/Main.kt— server entry point, startsWebMonitorServersrc/main/kotlin/attractor/cli/Main.kt— CLI entry point, thin REST API client
- DOT parsing (
dot/Lexer.kt,dot/Parser.kt) — converts.dottext intoDotGraph/DotNode/DotEdgemodel objects - Transforms (
transform/) — applied in order before execution:VariableExpansionTransform(expands$goaletc.),StylesheetApplicationTransform(applies visual styles fromstyle/Stylesheet.kt) - Validation (
lint/Validator.kt,lint/BuiltInRules.kt) — lints the transformed graph before running - Engine (
engine/Engine.kt) — walks the graph node-by-node; usesEdgeSelectorfor conditional routing andRetryPolicyfor back-off; emitsProjectEvents viaProjectEventBus - Handlers (
handlers/) — each node type maps to a handler viaHandlerRegistry. Shape-to-type mapping:Mdiamond→start,Msquare→exitbox→codergen(LLM prompt node)diamond→conditionalgatehexagon→wait.human(human review gate)component→parallelfan-out,tripleoctagon→parallel.fan_inparallelogram→tool,house→stack.manager_loop
- LLM adapters (
llm/adapters/) — two execution modes: Direct API (AnthropicAdapter,OpenAIAdapter,GeminiAdapter,CustomApiAdapter) and CLI subprocess (AnthropicCliAdapter,OpenAICliAdapter,GeminiCliAdapter,CopilotCliAdapter)
web/WebMonitorServer.kt— HTTP server (JDKcom.sun.net.httpserver), serves dashboard SPA and SSE event streams at/eventsand/events/{id}web/RestApiRouter.kt— versioned REST API at/api/v1/(37 endpoints)web/ProjectRegistry.kt— in-memory registry of active pipeline runsweb/ProjectRunner.kt— runs theEnginefor a single pipeline in a background threadweb/DotGenerator.kt— LLM-powered DOT generation from natural language prompts
db/RunStore.kt— interface for pipeline state persistencedb/SqliteRunStore.kt— default SQLite backend (attractor.db)db/JdbcRunStore.kt— shared JDBC impl for MySQL/PostgreSQLdb/RunStoreFactory.kt— selects backend fromATTRACTOR_DB_*env varsdb/DatabaseConfig.kt— parses connection strings (supports both full JDBC URLs and simplifiedpostgres:///mysql://URLs)
state/Context.kt— per-node execution context (inputs, outputs, node info)state/Outcome.kt—success/failure/cancelledetc.state/Checkpoint.kt— serializable snapshot for persist & resumestate/ArtifactStore.kt— stores node output artifacts to the filesystem
- The
build.gradle.ktscompiles to JVM target 22; Java 25 is required to run (Gradle 9.4.0). - Tests use JUnit 5 + Kotest assertions + H2 in-memory database for DB tests.
- The
ATTRACTOR_DEBUGenv var enables debug logging and stack traces. bin/attractoris a shell wrapper that auto-locates the latest CLI JAR.
Whenever a change affects user-facing behavior, configuration, environment variables, file paths, commands, or architecture, update the documentation as part of the same change:
-
Docs site (
docs/site/content/) — the authoritative user-facing reference at https://attractor.coreydaley.dev. Update the relevant page(s) to reflect the change. If no suitable page exists, create one. -
Root
README.md— keep in sync with any changes to top-level commands, environment variables, or project structure that are summarized there. -
Subdirectory
README.mdfiles — each subdirectory that warrants one should contain only minimal usage information relevant to that directory (what it is, how to use it). All detail belongs in the docs site. Every subdirectory README must include a link to the relevant section of the docs at https://attractor.coreydaley.dev.
-
Keep subdirectory READMEs short — a brief description, the essential commands, and a pointer to the docs site.
-
Do not duplicate content that already lives in the docs site.
-
Use this pattern for the docs link:
Full documentation: https://attractor.coreydaley.dev/<section>/