tricorder aims to empower users developing programs with Haskell and LLM coding agents. It does so by providing operations to surface the right information required at a given stage: documentation, build status, diagnostics, etc.
Like similar tools (ghcid, ghciwatch), it builds the code continuously on every change, presents diagnostics, and runs the tests afterwards. However, tricorder offers other advantages:
- Designed for humans - A
tricorder uiinteractive TUI mode that presents stats in real time for developers. - Designed for agents - A
SKILLis provided to inform agentic usage via thetricorderCLI. - Background builds - Building in the background using a daemon allows different clients to query the build state simultaneously without triggering multiple rebuilds. For instance, we ship the
tricorder uiTUI and thetricorder statusCLI command that communicate witha single daemon via a socket. - Sane defaults - Running
tricorder startshould Just Work™ for most cabal-based Haskell projects.- Daemon restarts automatically when cabal files change
- If customization is needed it can be provided at different levels via a
.tricorder.yamlor CLI args.- Optional config includes which cabal packages to watch, which exact command to use to enter a GHCi session, customizable key bindings, etc.
- Multi-package projects - In a
cabal.projectworkspace,tricorderdiscovers every package's components automatically, building and running tests across all of them — no manual target configuration needed. - Project context - Tools like
tricorder source Some.Modulewill attempt to find and provide the source code for a given dependency from disk, which allows exploring library APIs more easily. - Machine-readable output - Using
tricorder status --jsonwe can get build information in a format appropriate for programmatic usage.
tricorder is published on Hackage. With a GHC and cabal toolchain available, install the executable from source:
cabal update
cabal install tricorderThis builds and installs the tricorder binary into cabal's install directory (typically ~/.local/bin, or ~/.cabal/bin on older setups); make sure it is on your PATH.
tricorder runs on both Linux and macOS.
Tip
Configure the binary cache to avoid building GHC from scratch:
nixConfig = {
extra-substituters = [
"https://cache.iog.io"
"https://atelier.cachix.org"
];
extra-trusted-public-keys = [
"hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ="
"atelier.cachix.org-1:rEyd/Z4TiXZbBVuU/lDnKZ/7WtnFTwJ17OKHGcahVUo="
];
};nix run --accept-flake-config github:atelier-hub/tricorder -- ui--accept-flake-config tells Nix to use the binary caches declared in this flake. Without it, Nix will build the entire Haskell toolchain from source.
To make tricorder available in a project's dev shell without installing it system-wide:
inputs.tricorder.url = "github:atelier-hub/tricorder";
devShells.default = pkgs.mkShell {
packages = [ inputs.tricorder.packages.${system}.tricorder ];
};Add the flake input and apply the overlay:
inputs.tricorder.url = "github:atelier-hub/tricorder";
nixpkgs.overlays = [ inputs.tricorder.overlays.default ];imports = [ inputs.tricorder.homeManagerModules.default ];
programs.tricorder.enable = true;imports = [ inputs.tricorder.nixosModules.default ];
programs.tricorder.enable = true;Tricorder ships a Claude Code plugin that gives agents real-time GHCi build status via a skill.
Add the atelier marketplace to your Claude Code settings.json (either project-level .claude/settings.json or user-level ~/.claude/settings.json):
{
"extraKnownMarketplaces": {
"atelier": {
"source": {
"source": "github",
"repo": "atelier-hub/tricorder"
}
}
},
"enabledPlugins": {
"tricorder@atelier": true
}
}The skill uses tricorder status and tricorder status --wait. Add them to your permissions.allow list to avoid being prompted on every invocation:
{
"permissions": {
"allow": [
"Bash(tricorder status)",
"Bash(tricorder status --wait)",
"Skill(tricorder:tricorder)"
]
}
}Once enabled, Claude Code will automatically check GHCi build status and diagnostics when working on Haskell code in projects running the tricorder daemon.
You can specify custom key bindings for tricorder ui's TUI in your
.tricorder.yaml file.
The format is as follows:
keybindings:
<event>: <keybind>[, <keybind>, <keybind>, ...]keybindings is an object whose keys are event names and whose values are
strings of key bindings, each key binding in the string separated by a comma.
The following event names are recognized:
toggle_daemon_info_view: Toggle displaying daemon info.quit: Exit the TUI.exit_view: Exit the current view or go back.scroll_up: Scroll up in the diagnostic list.scroll_down: Scroll down in the diagnostic list.toggle_help: Toggle displaying the available key bindings. This includes your custom key bindings.cycle_test_view: Cycle through test results views.
Key binds are specified in the format <modifiers>-<key>, where <modifiers>
is an optional --separated list of modifier keys, and <key> is any
non-modifier key on your keyboard.
Alternatively, the key bind can be unbound, which removes default key
bindings for the given event.
The following modifiers are recognized:
s,shiftm,metaa,altc,ctrl,control
The following non-modifier keys are recognized:
f1,f2, ...escbackspaceenterleftrightupdownupleftuprightdownleftdownrightcenterbacktabprintscreenpauseinserthomepgupdelendpgdownbeginmenuspacetab- All letter, symbol and number keys.
keybindings:
quit: c-q
scroll_up: k, up
scroll_down: j, down
toggle_daemon_info_view: unboundnix develop
tricorder uiThis repository also contains Atelier, a set of Haskell libraries providing foundational infrastructure for effect-based applications (to be extracted into their own repository).