Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/target
/result

/.tinyharness
/todo
/todo

32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,30 @@ Alternatively, install via Cargo:
cargo install --path .
```

### Installation (Nix)

A Nix flake is provided for reproducible builds and dev environments.

**Run once without installing:**

```bash
nix run github:PTFOPlayer/TinyHarness
```

**Build the package:**

```bash
cd TinyHarness
nix build
./result/bin/tinyharness
```

**Enter a development shell** (with Rust toolchain, rustfmt, and clippy pre-configured):

```bash
nix develop
```

### Usage

**Ollama** (default):
Expand Down Expand Up @@ -420,6 +444,14 @@ cargo fmt --all -- --check # Format check
cargo fmt --all # Auto-format
```

If you're using the Nix flake, prefer:

```bash
nix build # Build the package
nix flake check # Run all checks (build + fmt + clippy --deny warnings + test)
nix develop # Enter dev shell with cargo/rustfmt/clippy
```

### Verification Steps

After making changes, run:
Expand Down
13 changes: 12 additions & 1 deletion docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ TinyHarness is a Rust workspace with three crates and a focus on minimal depende

### Prerequisites

- Rust latest stable (edition 2024)
- Nix with flakes enabled or Rust latest stable (edition 2024)
- An LLM backend for testing (Ollama recommended, but not required for library tests)

### Getting the Code
Expand All @@ -18,6 +18,9 @@ cd TinyHarness

### First Build

>[!NOTE]
>If you have Nix, run `nix develop`

```bash
cargo build --workspace
cargo test --workspace
Expand Down Expand Up @@ -117,6 +120,14 @@ Before submitting a PR, run these in order:
3. `cargo test --workspace` — all tests pass
4. `cargo build` — clean debug build succeeds

If you have Nix installed, the same checks are available as a single command:

```bash
nix flake check
```

This runs `cargo fmt --all -- --check`, `cargo clippy --workspace -- -D warnings`, `cargo test --workspace` (release), and a release build — i.e. steps 1, 2, 3, and a release variant of step 4. See the [Nix installation section](../../README.md#installation-nix) in the README for setup.

---

## Code Conventions
Expand Down
98 changes: 98 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

94 changes: 94 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{
description = "TinyHarness - AI Coding Harness";

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Provides a set of utilities for making flakes more ergonomic – here eachDefaultSystem is used to avoid having to write explicit separate derivations for Linux x86, Linux ARM, MacOS Apple Silicon, etc.

crane = {
url = "github:ipetkov/crane";
};
Comment on lines +7 to +9

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Crane provides lots of utilities for building Rust projects with Nix: https://crane.dev/index.html

rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
Comment on lines +10 to +13

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rust-overlay lets you pin specific Rust toolchain dependencies

};

outputs = { self, nixpkgs, flake-utils, crane, rust-overlay, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ (import rust-overlay) ];
};

inherit (pkgs) lib;

rustToolchain = pkgs.rust-bin.stable.latest.default.override {
extensions = [ "rustfmt" "clippy" ];
};

craneLib = (crane.mkLib pkgs).overrideToolchain rustToolchain;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uses the defined (latest) toolchain for building the project, instead of the default


src = lib.cleanSourceWith {
filter = path: type:
(craneLib.filterCargoSources path type) ||
(lib.hasSuffix ".md" path);
src = lib.cleanSource ./.;
};
Comment on lines +32 to +37

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tells Nix which files to include when building the project. Anything not included by the filter is treated as absent at build time.

Crane provides a filter that includes all standard Cargo/Rust files. I'm combining with another filter that adds .md files, because that's what tiny-harness stores its prompts in.


commonArgs = {
inherit src;
strictDeps = true;
buildInputs = [

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

buildInputs are build time and runtime dependencies for the project. Usually, these are libraries that get linked to the binary.

pkgs.openssl

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reqwest expects there to be an openssl lib available to link to (unless you switch it to rustls instead)

] ++ lib.optionals pkgs.stdenv.isDarwin [
pkgs.apple-sdk

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

required for building on Macs

];
nativeBuildInputs = [
pkgs.pkg-config
Comment on lines +47 to +48

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nativeBuildInputs are build-time only deps. In this case, we need pkg-config to be able to find openssl at build time

];
};

cargoArtifacts = craneLib.buildDepsOnly commonArgs;

tinyharness = craneLib.buildPackage (commonArgs // {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This defines the actual build for the project

inherit cargoArtifacts;
doCheck = false;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This just means we don't run the checks by default when building, since those are handled by the flake checks

meta = {
mainProgram = "tinyharness";
};
});

tests = craneLib.cargoTest (commonArgs // {
inherit cargoArtifacts;
});

in {
packages = {
default = tinyharness;
tinyharness = tinyharness;
};
Comment on lines +67 to +70

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Packages are the actual output from an end user perspective. When you do nix flake run, the default package is what gets called; same if you install via Nix.


checks = {
inherit tinyharness;
inherit tests;
clippy = craneLib.cargoClippy (commonArgs // {
inherit cargoArtifacts;
cargoClippyExtraArgs = "-- --deny warnings";
});
fmt = craneLib.cargoFmt {
inherit src;
};
};

devShells.default = craneLib.devShell {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This defines all the development dependencies. You run nix develop, or use direnv to automate it when entering the directory, and you have everything you need to work on the project. No need to manually install a Rust toolchain, cargo, LSP, etc.

checks = self.checks.${system};
packages = with pkgs; [
cargo
clippy
rust-analyzer
rustfmt
];
};
});
}
Loading