Fold the view command module (viewFile, the error type, the read
adapter) into index.ts so the command functions sit beside the guarded
CLI, and generalise formatViewError into formatError matching over a
CliError union that new fallible commands extend.
Align the test files with ADR 0009's tiers by name:
- index_test.ts now holds the in-process integration tests of the
command functions (formerly view_test.ts)
- end_to_end_test.ts holds the black-box subprocess e2e (formerly
index_test.ts)
Guard the CLI entry's program.parse() behind import.meta.main so the
command module can be imported without running the CLI, then rebuild the
deleted suite across the three tiers ADR 0009 defines:
- unit: parse (core) and render (bin), asserted on return values
- integration: the view command function, asserted on its Result
- e2e: the kitchen binary as a subprocess (exit codes, streams, ANSI
suppression, errors, --help)
Drop the stale test-support.ts coverage ignore and refresh the task's
implementation notes to describe the tiered suite.
Split the view command out of the entry point and make its failure a
value rather than an exception. index.ts is now scaffolding plus
dispatch; view.ts owns the behaviour, returning Result<string, ViewError>
(a plain-data tagged union) via neverthrow, with try/catch confined to a
readFile adapter. The entry point matches the Result at the boundary.
Because viewFile is a pure in-process function it is now unit-tested
directly (and counted by coverage), while the subprocess tests stay as
the end-to-end check. ADR 0008 records the errors-as-values convention.
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.
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.