nix: add installable package

This commit is contained in:
Keisuke Hirata 2026-05-29 01:32:04 +09:00
parent 32be379f54
commit 9df9dc1863
No known key found for this signature in database
3 changed files with 186 additions and 2 deletions

74
docs/nix.md Normal file
View File

@ -0,0 +1,74 @@
# Nix package
INSOMNIA provides a flake package for installing the user-facing Pod CLI and TUI binaries without relying on a source checkout at runtime.
## Build
From the repository root:
```sh
nix build .#
```
The default package is implemented by `package.nix` and builds the Cargo workspace binaries `pod` and `tui`. The derivation uses the checked-in `Cargo.lock`, so Cargo dependencies are fetched by the normal Nix Rust packaging path instead of by network access during the build.
The package output contains:
- `bin/pod` — Pod CLI / runtime process.
- `bin/tui` — terminal UI.
- `share/insomnia/resources/` — bundled runtime resources, including `resources/prompts/`.
- `share/doc/insomnia/nix.md` — this document.
## Run
After `nix build`:
```sh
./result/bin/pod --help
./result/bin/tui
```
With flakes:
```sh
nix run .#tui
nix run .#pod -- --help
```
`nix run .#` defaults to the TUI.
## Configuration discovery
The Nix package does not put user configuration, sessions, sockets, or other mutable state in the Nix store. The installed binaries keep the same path semantics as non-Nix builds:
| Purpose | Override | `INSOMNIA_HOME` fallback | XDG / default fallback |
| --- | --- | --- | --- |
| User config (`manifest.toml`, prompt overrides, model/provider overrides) | `INSOMNIA_CONFIG_DIR` | `$INSOMNIA_HOME/config` | `$XDG_CONFIG_HOME/insomnia`, then `$HOME/.config/insomnia` |
| Persistent data (`sessions/`, Pod metadata) | `INSOMNIA_DATA_DIR` | `$INSOMNIA_HOME` | `$HOME/.insomnia` |
| Runtime state (sockets, lock files, live registry) | `INSOMNIA_RUNTIME_DIR` | `$INSOMNIA_HOME/run` | `$XDG_RUNTIME_DIR/insomnia`, then `$HOME/.insomnia/run` |
`INSOMNIA_USER_MANIFEST=<path>` can still be used to select an explicit user manifest for the Pod CLI cascade path. Project manifests are still discovered from `.insomnia/manifest.toml` under the current workspace unless a CLI mode documents otherwise.
## Validation
The package derivation has a credential-free install check that verifies:
- `pod --help` starts successfully.
- `tui` is installed and reaches argument parsing.
- bundled prompt resources and this Nix usage document are present in the output.
For full validation before handing changes to review, run:
```sh
nix build .#
nix flake check
cargo fmt --check
```
This packaging change does not require provider credentials. A Rust `cargo check` is only needed if Rust source or runtime path semantics are changed.
## Known limitations
- The package currently installs the TUI and Pod CLI only; development-only wrappers from `devshell.nix` are not part of the installable package.
- The TUI does not currently expose a conventional `--help` / `--version` CLI path, so the package smoke check uses an argument-parse failure path for the TUI rather than launching an interactive session.
- Bundled resources are installed under `share/insomnia/resources/` for packaging completeness and inspection. Built-in prompt/resource loading remains governed by the existing application code and user/project override rules.

View File

@ -1,5 +1,5 @@
{
description = "A very basic flake";
description = "INSOMNIA agent runtime";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
@ -16,9 +16,22 @@
system:
let
pkgs = nixpkgs.legacyPackages.${system};
insomnia = pkgs.callPackage ./package.nix { };
mkApp = name: description: {
type = "app";
program = "${insomnia}/bin/${name}";
meta.description = description;
};
in
{
packages.default = pkgs.callPackage ./package.nix { };
packages.default = insomnia;
packages.insomnia = insomnia;
apps.default = mkApp "tui" "Run the INSOMNIA terminal UI";
apps.tui = mkApp "tui" "Run the INSOMNIA terminal UI";
apps.pod = mkApp "pod" "Run the INSOMNIA Pod CLI";
checks.default = insomnia;
devShells.default = import ./devshell.nix { inherit pkgs; };
}

View File

@ -0,0 +1,97 @@
{
lib,
stdenv,
rustPlatform,
pkg-config,
openssl,
darwin,
}:
let
srcRoot = ./.;
srcRootString = toString srcRoot;
sourceFilter =
path: type:
let
pathString = toString path;
relPath = lib.removePrefix "${srcRootString}/" pathString;
baseName = baseNameOf pathString;
in
!(
baseName == ".git"
|| baseName == "target"
|| baseName == "result"
|| lib.hasPrefix ".insomnia" relPath
|| lib.hasPrefix "work-items" relPath
);
in
rustPlatform.buildRustPackage rec {
pname = "insomnia";
version = "0.1.0";
src = lib.cleanSourceWith {
src = srcRoot;
filter = sourceFilter;
};
cargoLock.lockFile = ./Cargo.lock;
strictDeps = true;
nativeBuildInputs = [ pkg-config ];
buildInputs = [
openssl
]
++ lib.optionals stdenv.hostPlatform.isDarwin (
with darwin.apple_sdk.frameworks;
[
CoreFoundation
Security
SystemConfiguration
]
);
cargoBuildFlags = [
"-p"
"pod"
"-p"
"tui"
];
# The package check is a credential-free install smoke check below. Running the
# workspace test suite is intentionally left to cargo-based CI because this
# derivation is scoped to packaging the user-facing binaries.
doCheck = false;
postInstall = ''
install -Dm644 docs/nix.md "$out/share/doc/insomnia/nix.md"
mkdir -p "$out/share/insomnia"
cp -R resources "$out/share/insomnia/resources"
'';
doInstallCheck = true;
installCheckPhase = ''
runHook preInstallCheck
"$out/bin/pod" --help >/dev/null
test -x "$out/bin/tui"
if "$out/bin/tui" --session not-a-uuid 2>tui.err; then
echo "tui unexpectedly accepted an invalid --session value" >&2
exit 1
fi
grep -q "invalid --session UUID" tui.err
test -d "$out/share/insomnia/resources/prompts"
test -f "$out/share/doc/insomnia/nix.md"
runHook postInstallCheck
'';
meta = {
description = "Agentic coding Pod runtime and terminal UI";
license = lib.licenses.mit;
mainProgram = "tui";
platforms = lib.platforms.unix;
};
}