defmodule Lockstep.MixProject do use Mix.Project @version "0.1.0" @source_url "https://github.com/b-erdem/lockstep" def project do [ app: :lockstep, version: @version, elixir: "~> 1.15", start_permanent: Mix.env() == :prod, description: description(), package: package(), deps: deps(), docs: docs(), elixirc_paths: elixirc_paths(Mix.env()), name: "Lockstep", source_url: @source_url ] end def application do # `:inets` and `:ssl` are needed by `Lockstep.LLMExplainer` (the # optional Anthropic Claude integration). They live in OTP and # cost nothing extra to declare; if `LLMExplainer` is never used, # they just sit idle. [extra_applications: [:logger, :compiler, :syntax_tools, :inets, :ssl]] end defp deps do [ {:ex_doc, "~> 0.31", only: :dev, runtime: false}, {:cachex, "~> 4.1", only: :test}, {:telemetry, "~> 1.0", only: :test}, # ex_rated needs Ex2ms (match-spec macros) for delete_bucket/prune. # We don't call those, but the `import Ex2ms` inside other # functions still requires the module to be loaded at compile time. {:ex2ms, "~> 1.5", only: :test}, # groot needs HLClock for hybrid logical clock timestamps. {:hlclock, "~> 1.0", only: :test}, # delta_crdt: real version for clean repro of the # set_neighbours+failed-send crash (test/delta_crdt_real_test.exs). {:delta_crdt, "~> 0.6", only: :test}, # Lockstep.LLMExplainer (optional). If a host app already has # Jason in its deps, the explainer activates; otherwise it # silently skips. We also keep it for our own tests. {:jason, "~> 1.4", optional: true} ] end defp description do "Coyote-style controlled concurrency testing for the BEAM. " <> "PCT/POS scheduling, schedule shrinking, trace replay, " <> "Elixir + Erlang AST rewriters, and ETS / atomics / " <> "persistent_term sync points -- so message-passing AND " <> "shared-state races surface deterministically." end defp package do [ maintainers: ["Baris Erdem"], licenses: ["Apache-2.0"], links: %{ "GitHub" => @source_url, "Changelog" => @source_url <> "/blob/main/CHANGELOG.md" }, files: ~w(lib LICENSE mix.exs README.md CHANGELOG.md CONTRIBUTING.md AGENTS.md METHODOLOGY.md skill) ] end defp docs do [ main: "readme", extras: [ "README.md", "CHANGELOG.md", "CONTRIBUTING.md", "AGENTS.md", "METHODOLOGY.md", "skill/lockstep/SKILL.md": [filename: "skill", title: "Skill (Anthropic)"], "mcp_server/README.md": [filename: "mcp_server", title: "MCP Server"] ], source_ref: "v#{@version}", source_url: @source_url, groups_for_modules: [ "Runtime API": [ Lockstep ], "OTP wrappers": [ Lockstep.GenServer, Lockstep.GenStatem, Lockstep.Agent, Lockstep.Task, Lockstep.Task.Supervisor, Lockstep.Registry, Lockstep.Supervisor ], "NIF wrappers": [ Lockstep.ETS, Lockstep.Atomics, Lockstep.PersistentTerm ], "Test ergonomics": [ Lockstep.Test, Lockstep.Linter ], "Compile-time rewriters": [ Lockstep.Rewriter, Lockstep.ErlangRewriter, Lockstep.MixCompiler ], "Engine internals": [ Lockstep.Controller, Lockstep.Runner, Lockstep.Strategy ], Strategies: [ Lockstep.Strategy.Random, Lockstep.Strategy.PCT, Lockstep.Strategy.FairPCT, Lockstep.Strategy.POS, Lockstep.Strategy.Replay ], "Trace + replay + shrink": [ Lockstep.Trace, Lockstep.Replay, Lockstep.Shrink ], Errors: [ Lockstep.BugFound, Lockstep.ReplayDivergence ] ] ] end defp elixirc_paths(:test), do: ["lib", "test/support"] defp elixirc_paths(_), do: ["lib"] end