reconcile 0.3.0

A reconciliation storage service to sync a key-value map over multiple instances
FROM debian:stable-slim

ENV DEBIAN_FRONTEND=noninteractive \
    RUSTUP_HOME=/usr/local/rustup \
    CARGO_HOME=/usr/local/cargo \
    PATH=/usr/local/cargo/bin:$PATH

RUN apt-get update && apt-get install -y --no-install-recommends \
      build-essential pkg-config libssl-dev \
      curl ca-certificates git sudo nodejs npm \
      shellcheck \
    && rm -rf /var/lib/apt/lists/*

RUN groupadd -g 1000 dev \
 && useradd -m -u 1000 -g dev -s /usr/bin/bash dev \
 && echo "dev ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --no-modify-path --default-toolchain stable \
 && rustup component add clippy \
 && rustup component add rustfmt

RUN curl -L \
     https://github.com/rust-lang/rust-analyzer/releases/latest/download/rust-analyzer-linux \
   -o /usr/local/bin/rust-analyzer \
  && chmod +x /usr/local/bin/rust-analyzer

RUN npm install -g dockerfile-language-server-nodejs markdownlint-cli bash-language-server

RUN cargo install taplo-cli --locked --features lsp

# AGENTS.md §3's last gate line, `cargo deny check`. Every other line on that list is plain `cargo`,
# which is why this is the only one that needs installing. Unpinned to match CI, which resolves its
# own version inside `EmbarkStudios/cargo-deny-action@v2` rather than at a fixed one.
RUN cargo install cargo-deny --locked

# AGENTS.md §3's test lines run under nextest (process-per-test isolation, native flaky-test
# detection). Unpinned to match CI's `taiki-e/install-action@cargo-nextest`.
RUN cargo install cargo-nextest --locked

# Structural search/rewrite for Rust (`ast-grep run -p '$X.unwrap()'`), a syntax-aware complement
# to `rg` for edits a regex would silently under- or over-match (generics, async, macro calls).
# Not part of any gate — a workflow tool, like rust-analyzer above.
RUN cargo install ast-grep --locked

RUN curl -L \
     https://github.com/artempyanykh/marksman/releases/latest/download/marksman-linux \
     -o /usr/local/bin/marksman \
  && chmod +x /usr/local/bin/marksman

# These dirs were populated as root by the RUN steps above; the container runs as 'dev' below.
RUN chown -R dev:dev /usr/local/cargo /usr/local/rustup

WORKDIR /workspace

# Ensure that any interactive shell picks up Cargo/Rustup binaries
RUN echo 'export PATH="/usr/local/cargo/bin:$PATH"' >> /home/dev/.bashrc \
 && echo 'export PATH="/usr/local/cargo/bin:$PATH"' >> /home/dev/.profile

USER dev

ENTRYPOINT ["bash"]