Forward any positional arguments to `bun test` as path filters, so
`bun run test:report packages/core` reports just core while a bare
`bun run test:report` still covers the whole repo. The report's header
records the scope.
Add scripts/test-report.ts (bun run test:report): it runs the full suite
with JUnit + lcov output, then renders a gitignored reports/test-report.md
— a summary, a describe-grouped inventory (pass/todo/fail), and a
coverage table. The report is written even when tests fail and the script
exits with the test run's own status, so CI can gate on it later. Adds
fast-xml-parser (dev) for robust JUnit parsing; lcov is parsed by hand.
Add a bunfig.toml enabling coverage with text + lcov reporters, a
test:coverage script, and gitignore the coverage/ output. Test files and
the test-support helper are excluded so the numbers reflect product code
only.
packages/core/src/index.ts is a pure re-export barrel with no behavior
of its own, so its behavior tests belonged next to the module they
exercise. Relocate the parser tests (and their roadmap todos) into a
co-located parse_test.ts importing parse from ./parse.ts, and drop
index_test.ts. A broken re-export is still caught by typecheck and by
the bin package importing parse through the public entrypoint.
Drop the Point/Position types and the source/position fields from
Diagnostic. Nothing constructs a diagnostic yet — diagnostics is always
empty until task 0007 emits the first invalid-frontmatter warning, which
adds the locator fields back additively alongside its own tests.
Pull a reduced end-to-end smoke forward into the slice so the view flow
is exercised over a real on-disk recipe, not just a temp file.
Add fixtures/prose.md — a recipe using only this slice's modelled
constructs (frontmatter, headings, plain paragraphs) so it renders
losslessly. integration_test now runs `kitchen view fixtures/prose.md`
as a subprocess and asserts the frontmatter, separator, headings,
paragraphs, and flat document order end-to-end. smoke_test covers
`kitchen --help` exiting 0 with the view command listed.
The full fixtures/basic.md smoke remains task 0007, which needs 0004's
richer nodes before that fixture renders losslessly.
Cut the first complete thread through both layers with the smallest set
of node types.
@kitchen-md/core gains a pure, total `parse` returning a
`DocumentAST` of `{ frontmatter, blocks, diagnostics }`, built from a
minimal remark pipeline (remark-parse + remark-frontmatter) with an
internal translation layer to core's own types. This slice models
frontmatter passthrough, HeadingBlock, ParagraphBlock, and TextNode;
remark's mdast does not surface in the public API.
@kitchen-md/bin gains the `view` subcommand (commander) that reads a
file, calls `parse`, and passes the AST to a pure `render` that returns
an ANSI-styled string via chalk (auto-suppressed off a TTY). Frontmatter
prints as raw YAML followed by a separator, headings styled distinctly
by level, paragraphs as prose. A missing argument prints usage and a
missing/unreadable file a human-readable error, both exiting 1.
Richer blocks/inline plus raw fallbacks are task 0004; malformed
frontmatter diagnostics and the basic.md smoke test are task 0007.
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.
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.
Replace the stale Bun-only project-scaffold spec with a Nix-aware
packaging spec, and record the flake-parts + bun2nix + pinned-Bun
decision as ADR 0007.
Bring core-parser.md in line with the resolved design in CONTEXT.md and
ADRs 0004/0005, and promote a new decision to normalise ingredient/cookware
units.
- Full sync of the core-parser spec: diagnostics/total-function channel,
container blocks (ListItemBlock, BlockquoteBlock), RawInline alongside
RawBlock via position-slicing, the unified WikilinkNode/TransclusionNode
shape as two typed nodes, and the minimal remark plugin set.
- New ADR 0006: normalise ingredient/cookware units via a known-alias table
with passthrough, case-insensitive, canonical-only; align Timer matching
to case-insensitive too.
- SPEC.md: units are normalised (new Units section, alias table); Timer table
marked case-insensitive.
- CONTEXT.md: add Unit Normalisation entry, resolve the open item.
- fixtures/basic.md: add a blockquote (callout) carrying an annotation and a
non-canonical unit so the integration test exercises containers and
normalisation.
- Expand the core test.todo checklists to cover the new behaviour (containers,
raw fallbacks, diagnostics, unit normalisation, wikilink/transclusion
variants); still pending, suite stays green.
Capture the design decisions reached while grilling the core-parser spec:
- Parser is a total function; invalid frontmatter YAML surfaces through a
new Document AST `diagnostics` channel instead of throwing (ADR 0004).
- Parse all of OFM losslessly via `RawBlock`/`RawInline` fallbacks with
position-sliced verbatim source and a minimal plugin set (ADR 0005).
- Grammar-driven (not last-space) quantity/unit split, fixing the
mixed-number collision, with trimming and multi-word unit rules.
- Container blocks nest `Block[]` so annotations surface inside
blockquotes and list items; unified wikilink/transclusion shape.
Update SPEC.md and CONTEXT.md accordingly; no parser code yet.
Expand fixtures/basic.md beyond prose-only annotations to exercise the
OFM features the parser must model: unordered and ordered lists,
emphasis and strong, a code span, a fenced code block (proving
annotations inside code are ignored), a thematic break, and a
transclusion. Also adds an empty-braces ingredient (@black pepper{}).
Add fixtures/combined.md, a Combined Recipe demonstrating Step
References in both sectioned (#Batter:1) and headingless (#2) forms,
which do not fit cleanly into a standalone recipe file.
Sets up the initial project structure: two packages (@kitchen-md/core
and @kitchen-md/bin), shared tsconfig, shared fixtures, per-package
test stubs (unit, integration, smoke), .gitignore, and project
CLAUDE.md with Conventional Commits convention.