Compare commits

...

2 Commits

Author SHA1 Message Date
fdede89e0c feat: add flake app, dev shell, direnv, and checks
Layer the remaining flake outputs onto the build: a default app pointing at
the compiled binary, a dev shell exposing the pinned Bun, biome, and bun2nix,
a `use flake` .envrc for direnv, and a checks set aggregating the Bun test
tiers, a build-seam smoke check against the Nix-built binary, and biome lint
through the treefmt-nix flake-parts module.

The dev shell and the build share the one pinned nixpkgs-bun input so Bun
cannot drift between them. treefmt's biome reuses the repo's biome.json with
VCS disabled for the sandbox, and packages/core/src/index_test.ts is
reformatted by biome so the new lint gate is green.
2026-07-25 22:28:10 -04:00
8fd2e53c53 build: package the kitchen CLI as a Nix flake
Add a flake-parts flake whose default package Bun-compiles the kitchen
CLI into a self-contained native binary, built in the sandbox with
dependencies vendored by bun2nix.

Bun is pinned via a dedicated nixpkgs-bun input (Bun 1.3.13) that
bun2nix follows, so nixpkgs can track unstable without moving the
compile toolchain onto a release that emits empty binaries.

bun2nix is both a flake input and an npm devDependency, and a
postinstall hook keeps the checked-in bun.nix in sync with the lockfile.
2026-07-25 22:28:10 -04:00
11 changed files with 515 additions and 4 deletions

View File

@@ -0,0 +1,53 @@
---
spec: nix-flake-packaging
---
## What to build
The tracer bullet for packaging the repository as a Nix flake: a flake-parts flake whose default package Bun-compiles the `kitchen` CLI into a self-contained native binary, built reproducibly in the sandbox with vendored dependencies.
This is the whole risk seam — a Nix build is sandboxed with no network, while `bun install` fetches from npm, so the dependency closure must be vendored before anything compiles.
Bun dependencies are vendored via bun2nix (a flake input) reading the workspace lockfile into a checked-in generated expression, kept in sync with the lockfile by a postinstall hook so a dependency change needs no separate manual regeneration.
A single pinned Bun version is shared by the build derivation (and later the dev shell), avoiding point releases known to produce empty binaries under sandboxed native compilation.
Once this compiles, the remaining outputs (`nix run`, `nix develop`, checks) hang off the working flake in the next slice.
## Acceptance criteria
- [x] The flake is structured with flake-parts, with `x86_64-linux` in the systems list and nixpkgs tracking `nixpkgs-unstable`.
- [x] bun2nix is a flake input, and its generated vendoring expression is checked in and regenerated by a postinstall hook on lockfile changes.
- [x] A single Bun version is pinned in one place and consumed by the build derivation.
- [x] `nix build` produces a runnable `kitchen` binary reproducibly with no network access during the build.
- [x] The compiled binary embeds its dependencies and runs on a machine with no Node.js or Bun runtime present.
- [x] The default package is consumable as a flake input from another configuration.
## Implementation Notes
The tracer bullet builds and all six criteria were verified end-to-end against a real `nix build`, not just by inspection.
### The Bun pin
bun2nix compiles the binary with the `bun` from *its own* nixpkgs, baked into its setup hook at bun2nix build time.
So pinning Bun means controlling the nixpkgs that bun2nix follows, not overlaying `bun` in this flake's package set.
The pin is a dedicated `nixpkgs-bun` input fixed to one revision (Bun 1.3.13), with `bun2nix.inputs.nixpkgs.follows = "nixpkgs-bun"`.
That revision is the one bun2nix 2.1.2 itself locks, so the compile toolchain matches what bun2nix was tested against.
`nixpkgs` still tracks `nixpkgs-unstable` for everything else, and updating it cannot move Bun.
The dev shell in task 0002 consumes the same `nixpkgs-bun`, keeping "develop with the version that compiles" true from one place.
### Vendoring and the postinstall hook
bun2nix is both a flake input (native builder) and an npm devDependency, so the `postinstall: bun2nix -o bun.nix` hook regenerates the checked-in `bun.nix` on any `bun install` even outside the Nix dev shell.
The build passes `dontRunLifecycleScripts = true` so that same postinstall does not fire redundantly inside the sandbox.
### Verification performed
`nix build` produced a 101 MB native ELF that runs to exit 0 under `env -i` (empty environment, no Node or Bun, `ldd` shows only glibc), confirming the embedded-runtime and no-network claims — the compile derivation is a normal sandboxed derivation with networking disabled.
A throwaway consumer flake built the package through `inputs.kitchen.packages.x86_64-linux.default`, confirming criterion 6.
### Deviations from the plan
- The nix-community cachix `nixConfig` block that the bun2nix templates ship was dropped, because the spec lists "any binary cache or substituter setup" as out of scope.
Consequence: a first build with a cold store compiles bun2nix from source.
A developer who wants the prebuilt bun2nix can add the substituter to their own Nix configuration.
- `packages/bin/src/index.ts` is still the placeholder entry point.
The CLI's behaviour belongs to the core-parser and cli-view specs, so the compiled binary is a no-op that exits 0 — enough to prove the packaging seam.

View File

@@ -0,0 +1,52 @@
---
spec: nix-flake-packaging
blocked-by: 0001-flake-build
---
## What to build
The remaining flake outputs layered onto the working build: a runnable app, a development shell, direnv auto-loading, and a checks set that gates the project reproducibly.
The default app points at the compiled binary so the CLI runs without a prior install.
The default dev shell exposes the same pinned Bun as the build plus biome, and a `use flake` direnv configuration loads it automatically on entering the directory.
The checks set aggregates the Bun test tiers, a build-seam smoke check that invokes the built binary (for example `--help`) and asserts a zero exit, and biome lint run through the treefmt-nix flake-parts module sharing the existing biome configuration.
## Acceptance criteria
- [x] `nix run` executes the CLI without a prior install.
- [x] `nix develop` drops into a shell exposing the pinned Bun and biome at their expected versions.
- [x] The dev shell's Bun version is the same pin the build derivation uses.
- [x] A `use flake` `.envrc` auto-loads the dev shell for direnv users.
- [x] `nix flake check` runs the Bun test tiers, the build-seam smoke check against the Nix-built binary, and biome lint via treefmt-nix.
## Implementation Notes
All five criteria were verified end-to-end: `nix run` exits 0, `nix develop` exposes Bun 1.3.13, biome 2.5.4, and bun2nix, and `nix flake check` runs all three checks green.
### Outputs
The default app points at the compiled binary via its store path.
The dev shell carries the pinned Bun, biome, and bun2nix — bun2nix so the repo's `postinstall` regeneration of `bun.nix` works inside the shell.
`.envrc` is a one-line `use flake`, and `.direnv/` is gitignored.
### Bun pin sameness
The dev shell takes Bun from `inputs.nixpkgs-bun` directly, while the build takes it through bun2nix, whose nixpkgs `follows` the same `nixpkgs-bun`.
Both therefore resolve to the one pinned input, which is the single source of the Bun version.
The value is not threaded through a shared binding because bun2nix bakes its own `pkgs.bun` into its build hook, so the compile-side Bun cannot be passed in — the shared `nixpkgs-bun` input is the seam instead.
### Checks
`tests` runs `bun test` across the workspace through bun2nix's check phase.
`smoke` runs the Nix-built binary with `--help` and asserts a zero exit; while the CLI is still a placeholder this passes for any argument, and it will exercise real `--help` once the CLI lands.
Biome runs through the treefmt-nix flake-parts module, which auto-adds its own check.
### Biome via treefmt-nix
The treefmt biome program reads the repo's `biome.json` (via `importJSON`) so there is one configuration, but with `vcs.enabled` overridden off: the reproducible check has no git tree, and biome's `useIgnoreFile` lookup errors without one, while treefmt already selects the files.
Schema validation is skipped because nixpkgs' biome is newer than the schema treefmt-nix would validate against, and the config is the one biome itself runs with.
### Deviation
`packages/core/src/index_test.ts` was reformatted by biome (two `test.todo` lines exceeded the repo's `lineWidth`).
This is a pre-existing file, formatted only to make the new lint gate green — a necessary consequence of adding the gate, not a change of its behaviour.

1
.envrc Normal file
View File

@@ -0,0 +1 @@
use flake

7
.gitignore vendored
View File

@@ -3,6 +3,13 @@ node_modules/
# compiled CLI binary # compiled CLI binary
packages/bin/kitchen packages/bin/kitchen
# nix build result symlinks
result
result-*
# direnv / nix-direnv cache
.direnv/
# local environment overrides # local environment overrides
.env .env
.env.local .env.local

View File

@@ -7,6 +7,7 @@
"devDependencies": { "devDependencies": {
"@biomejs/biome": "^2.5.3", "@biomejs/biome": "^2.5.3",
"bun-types": "latest", "bun-types": "latest",
"bun2nix": "^2.1.2",
}, },
}, },
"packages/bin": { "packages/bin": {
@@ -51,6 +52,12 @@
"bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="], "bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="],
"bun2nix": ["bun2nix@2.1.2", "", { "dependencies": { "sade": "^1.8.1" }, "bin": { "bun2nix": "index.ts" } }, "sha512-0wx6Ar5ccrz4aSD5prbShwymjDEXFh7Bucxs+YrpAMa67TnVB95Hv8FV3oaQEbtOx6QGgIAyOmap6Y3WCRqetg=="],
"mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="],
"sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="],
"undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="], "undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="],
} }
} }

78
bun.nix Normal file
View File

@@ -0,0 +1,78 @@
# Autogenerated by `bun2nix`, editing manually is not recommended
#
# Set of Bun packages to install
#
# Consume this with `fetchBunDeps` (recommended)
# or `pkgs.callPackage` if you wish to handle
# it manually.
{
copyPathToStore,
fetchFromGitHub,
fetchgit,
fetchurl,
...
}:
{
"@biomejs/biome@2.5.3" = fetchurl {
url = "https://registry.npmjs.org/@biomejs/biome/-/biome-2.5.3.tgz";
hash = "sha512-MrJswFdei9EfDwwUy2tQrPDpK0AO+RmMFvBoaaJ6ayBc3sUbHdCE+XG5N8vp+5So41ZupZJQm0roHFFhMGVD7A==";
};
"@biomejs/cli-darwin-arm64@2.5.3" = fetchurl {
url = "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.3.tgz";
hash = "sha512-QhYP9muVQ0nUO5zztFuPbEwi4+94sJWVjaZds9aMi1l/KNZBiUjdiSUrGHsTaMGDXrYl+r4AS2sUKfgH3w+V3g==";
};
"@biomejs/cli-darwin-x64@2.5.3" = fetchurl {
url = "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.5.3.tgz";
hash = "sha512-NC1Ss13UaW7QZX+y8j44bF7AP0jSJdBl6iRhe0MAkvaSqZy+mWg3GaXsrb+eSoHoGDBtaXWEbMVV0iVN2cZ7cQ==";
};
"@biomejs/cli-linux-arm64-musl@2.5.3" = fetchurl {
url = "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.3.tgz";
hash = "sha512-fccix0w6xp6csCXgxeC0dU/3ecgRQal0y+cv2SP9ajNlhe7Yrk2Ug7UDe2j9AT9ZDYitkXpvUKgZjjuoYeP4Vg==";
};
"@biomejs/cli-linux-arm64@2.5.3" = fetchurl {
url = "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.5.3.tgz";
hash = "sha512-ksx1KWeyYW18ILL04msF/J4ZBtBDN33znYK8Z/aNv/vlBVxL9/g3mGP+omgHJKy4+KWbK87vcmmpmurfNjSgiA==";
};
"@biomejs/cli-linux-x64-musl@2.5.3" = fetchurl {
url = "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.3.tgz";
hash = "sha512-O/yU9YKRUiHhmcjF2f38PSjseVk3G4VLWYc0G2HWpzdBVREV6G8IGWIVEFf7MFPfWIzNUIvPsEjeAZQIOgnLcQ==";
};
"@biomejs/cli-linux-x64@2.5.3" = fetchurl {
url = "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.5.3.tgz";
hash = "sha512-yMkJtilsgvILDcVkh187aVLTb64xYsrxYajx5kym+r1ULkO5HUOfu9AYKLGQbOVLwJtT2utNw7hhFNg+17mUYA==";
};
"@biomejs/cli-win32-arm64@2.5.3" = fetchurl {
url = "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.5.3.tgz";
hash = "sha512-cX5z+GYwRcqEok0AH3KSfQGgqYd0Nomfp6Fbe1uiTtELE38hdH2k842wQ9wLNaF/JJ7r4rjJQ4VR+ce+fRmQbw==";
};
"@biomejs/cli-win32-x64@2.5.3" = fetchurl {
url = "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.5.3.tgz";
hash = "sha512-ExSaJWi4/u6+GXCszlSKpWSjKNbDseAYqqkCznsCsZ/4uidZ/BEqsCc5/3ctlq6dfIubdIIRSVLC/PG9xPl70Q==";
};
"@kitchen-md/bin" = copyPathToStore ./packages/bin;
"@kitchen-md/core" = copyPathToStore ./packages/core;
"@types/node@26.1.1" = fetchurl {
url = "https://registry.npmjs.org/@types/node/-/node-26.1.1.tgz";
hash = "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==";
};
"bun-types@1.3.14" = fetchurl {
url = "https://registry.npmjs.org/bun-types/-/bun-types-1.3.14.tgz";
hash = "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ==";
};
"bun2nix@2.1.2" = fetchurl {
url = "https://registry.npmjs.org/bun2nix/-/bun2nix-2.1.2.tgz";
hash = "sha512-0wx6Ar5ccrz4aSD5prbShwymjDEXFh7Bucxs+YrpAMa67TnVB95Hv8FV3oaQEbtOx6QGgIAyOmap6Y3WCRqetg==";
};
"mri@1.2.0" = fetchurl {
url = "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz";
hash = "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==";
};
"sade@1.8.1" = fetchurl {
url = "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz";
hash = "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==";
};
"undici-types@8.3.0" = fetchurl {
url = "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz";
hash = "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==";
};
}

184
flake.lock generated Normal file
View File

@@ -0,0 +1,184 @@
{
"nodes": {
"bun2nix": {
"inputs": {
"flake-parts": "flake-parts",
"nixpkgs": [
"nixpkgs-bun"
],
"systems": [
"systems"
],
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1784665499,
"narHash": "sha256-9BMxlTxCCDAeoNLtb1a/st7udtTIJep+wpUzquA29VU=",
"owner": "nix-community",
"repo": "bun2nix",
"rev": "0f2a1f0b6f42cebe3b149bf62d38754c5e0e9729",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "2.1.2",
"repo": "bun2nix",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"bun2nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1782949081,
"narHash": "sha256-vp6Y/Grm98ESt6ceOkWiHWyZRDV3J1RID4w+6NWK9yA=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1782949081,
"narHash": "sha256-vp6Y/Grm98ESt6ceOkWiHWyZRDV3J1RID4w+6NWK9yA=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1784872115,
"narHash": "sha256-THPEF2po0fsoH8gNtp+Ae0XFDJH3N/ol7xO3v6VMTJU=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "335f0738cb2fa9708f3f428e39d2eae975d1338d",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-bun": {
"locked": {
"lastModified": 1784497964,
"narHash": "sha256-vlHUuqAcbcH2RKmHbPiuQzbv1pnzzavXnI62RD0bqCU=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "241313f4e8e508cb9b13278c2b0fa25b9ca27163",
"type": "github"
},
"original": {
"owner": "nixos",
"repo": "nixpkgs",
"rev": "241313f4e8e508cb9b13278c2b0fa25b9ca27163",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1782614948,
"narHash": "sha256-ePjCwr1sNm9NYUqywL7QfK3JnlS015msC+eBu2zKlp8=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "db3f255737b94216eb71cce308e2912cf6bc2d7c",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"root": {
"inputs": {
"bun2nix": "bun2nix",
"flake-parts": "flake-parts_2",
"nixpkgs": "nixpkgs",
"nixpkgs-bun": "nixpkgs-bun",
"systems": "systems",
"treefmt-nix": "treefmt-nix_2"
}
},
"systems": {
"locked": {
"lastModified": 1680978846,
"narHash": "sha256-Gtqg8b/v49BFDpDetjclCYXm8mAnTrUzR0JnE2nv5aw=",
"owner": "nix-systems",
"repo": "x86_64-linux",
"rev": "2ecfcac5e15790ba6ce360ceccddb15ad16d08a8",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "x86_64-linux",
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"bun2nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1784369104,
"narHash": "sha256-47cxbcZODibHv3rELFQ9vZly0vUNkND/atn/U7HLeb0=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "df3c0640565d04a0261253cdd89fce78ec50168a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"treefmt-nix_2": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1784369104,
"narHash": "sha256-47cxbcZODibHv3rELFQ9vZly0vUNkND/atn/U7HLeb0=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "df3c0640565d04a0261253cdd89fce78ec50168a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

104
flake.nix Normal file
View File

@@ -0,0 +1,104 @@
{
description = "kitchen the KitchenMD CLI, packaged as a Nix flake";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
# The single pinned Bun, used to compile the binary and to develop against.
# It is held apart from `nixpkgs` so a `nixpkgs` update cannot pull in a Bun
# release that emits empty binaries under sandboxed native compilation.
nixpkgs-bun.url = "github:nixos/nixpkgs/241313f4e8e508cb9b13278c2b0fa25b9ca27163";
flake-parts.url = "github:hercules-ci/flake-parts";
systems.url = "github:nix-systems/x86_64-linux";
bun2nix = {
url = "github:nix-community/bun2nix?ref=2.1.2";
# Compile against the pinned Bun rather than `nixpkgs`'s.
inputs.nixpkgs.follows = "nixpkgs-bun";
inputs.systems.follows = "systems";
};
treefmt-nix = {
url = "github:numtide/treefmt-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
inputs:
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
systems = import inputs.systems;
imports = [ inputs.treefmt-nix.flakeModule ];
perSystem =
{ system, ... }:
let
pkgs = import inputs.nixpkgs {
inherit system;
overlays = [ inputs.bun2nix.overlays.default ];
};
# The Bun from the same pinned `nixpkgs-bun` the build compiles with.
bun = inputs.nixpkgs-bun.legacyPackages.${system}.bun;
kitchen = pkgs.callPackage ./package.nix { };
bunDeps = pkgs.bun2nix.fetchBunDeps { bunNix = ./bun.nix; };
in
{
# Share the overlaid package set with the imported modules.
_module.args.pkgs = pkgs;
packages.default = kitchen;
apps.default = {
type = "app";
program = "${kitchen}/bin/kitchen";
};
devShells.default = pkgs.mkShell {
packages = [
bun
pkgs.biome
pkgs.bun2nix
];
};
treefmt = {
projectRootFile = "flake.nix";
programs.biome = {
enable = true;
# Reuse the repo's biome configuration as the single source.
# The sandboxed check has no git tree, so biome's VCS-ignore
# lookup must be off.
settings = pkgs.lib.recursiveUpdate (pkgs.lib.importJSON ./biome.json) {
vcs.enabled = false;
};
# Skip re-validating the config; biome consumes it directly.
validate.enable = false;
};
};
checks = {
tests = pkgs.bun2nix.mkDerivation {
pname = "kitchen-tests";
inherit (kitchen) version;
src = ./.;
inherit bunDeps;
dontRunLifecycleScripts = true;
dontUseBunBuild = true;
doCheck = true;
installPhase = "touch $out";
};
smoke = pkgs.runCommand "kitchen-smoke" { } ''
${kitchen}/bin/kitchen --help
touch $out
'';
};
};
};
}

View File

@@ -9,10 +9,12 @@
"scripts": { "scripts": {
"test": "bun test", "test": "bun test",
"lint": "biome check .", "lint": "biome check .",
"format": "biome check --write ." "format": "biome check --write .",
"postinstall": "bun2nix -o bun.nix"
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "^2.5.3", "@biomejs/biome": "^2.5.3",
"bun-types": "latest" "bun-types": "latest",
"bun2nix": "^2.1.2"
} }
} }

19
package.nix Normal file
View File

@@ -0,0 +1,19 @@
# The `kitchen` CLI compiled to a self-contained native binary.
{ lib, bun2nix }:
bun2nix.mkDerivation {
pname = "kitchen";
version = (lib.importJSON ./packages/bin/package.json).version;
src = ./.;
module = "packages/bin/src/index.ts";
bunDeps = bun2nix.fetchBunDeps {
bunNix = ./bun.nix;
};
# No vendored dependency needs install-time lifecycle scripts, and running
# them would fire this repo's own `postinstall` (bun2nix) inside the sandbox,
# where it is redundant.
dontRunLifecycleScripts = true;
}

View File

@@ -36,8 +36,12 @@ describe("parser", () => {
}); });
describe("raw fallbacks", () => { describe("raw fallbacks", () => {
test.todo("preserves an unmodelled block (e.g. a GFM table) as a RawBlock with verbatim source"); test.todo(
test.todo("preserves an unmodelled inline (e.g. strikethrough) as a RawInline with verbatim source"); "preserves an unmodelled block (e.g. a GFM table) as a RawBlock with verbatim source",
);
test.todo(
"preserves an unmodelled inline (e.g. strikethrough) as a RawInline with verbatim source",
);
}); });
describe("ingredient annotations", () => { describe("ingredient annotations", () => {