chore: add Biome and document design decisions from grill session
- Add @biomejs/biome 2.5.3 with 2-space indent, double quotes, trailing commas - Add lint and format scripts to root package.json - Update CONTEXT.md: resolve Structured Output shape, add Document AST, Block, Inline Node terms - Add ADR 0002 (remark as internal Markdown parser) - Add ADR 0003 (core defines own AST types) - Add spec: core-parser (Parser implementation and Document AST) - Add spec: cli-view (kitchen view <file> command)
This commit is contained in:
39
.claude/adr/0002-remark-as-internal-markdown-parser.md
Normal file
39
.claude/adr/0002-remark-as-internal-markdown-parser.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# ADR 0002 — remark as Core's Internal Markdown Parser
|
||||
|
||||
**Status**: Accepted
|
||||
|
||||
## Context
|
||||
|
||||
`@kitchen-md/core` must parse CommonMark Markdown (plus Obsidian Flavored Markdown extensions) to build a Document AST.
|
||||
The spec requires that Annotations follow CommonMark's inline processing rules — they are parsed inside paragraphs and list items, and ignored inside code spans and code blocks.
|
||||
Correctly detecting those boundaries from scratch requires a complete CommonMark implementation.
|
||||
|
||||
Two approaches were considered:
|
||||
|
||||
**Option A — Use remark/unified**
|
||||
remark is a CommonMark-compliant Markdown parser that produces mdast (a typed Markdown AST).
|
||||
It has a plugin/transform architecture: OFM extensions (wikilinks, transclusion) are handled by existing community plugins (`remark-wiki-link`), and KitchenMD annotations are handled by a custom transform plugin that walks mdast text nodes and splits them into annotation nodes.
|
||||
TypeScript support is first-class.
|
||||
|
||||
**Option B — Build the Markdown parser from scratch**
|
||||
Write a custom CommonMark parser as part of `@kitchen-md/core`, with no external Markdown dependency.
|
||||
|
||||
## Decision
|
||||
|
||||
**Option A** — remark/unified as core's internal Markdown parser.
|
||||
|
||||
## Rationale
|
||||
|
||||
CommonMark is a large, precisely specified standard.
|
||||
Building a correct implementation from scratch is significant work with no unique value to the project — the interesting problems are annotation parsing and document rendering, not Markdown tokenisation.
|
||||
|
||||
The "built from scratch" statement in the project spec refers to not forking Cooklang's parser, not to avoiding all external dependencies.
|
||||
|
||||
remark's plugin architecture maps cleanly to core's needs: one plugin for OFM wikilinks, one plugin for KitchenMD annotations, both operating as transform passes over an existing mdast.
|
||||
|
||||
## Consequences
|
||||
|
||||
- remark and its plugin ecosystem are build-time dependencies of `@kitchen-md/core`.
|
||||
- remark must remain a private implementation detail — its types must not appear in core's public API (see ADR 0003).
|
||||
- OFM support requires `remark-wiki-link` (and the underlying `micromark-extension-wiki-link` / `mdast-util-wiki-link`).
|
||||
- KitchenMD annotation parsing is implemented as a custom remark transform plugin within core.
|
||||
39
.claude/adr/0003-core-defines-own-ast-types.md
Normal file
39
.claude/adr/0003-core-defines-own-ast-types.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# ADR 0003 — Core Defines Its Own AST Types
|
||||
|
||||
**Status**: Accepted
|
||||
|
||||
## Context
|
||||
|
||||
remark produces mdast — a well-typed Markdown AST with its own node type definitions.
|
||||
`@kitchen-md/core` builds its Document AST on top of remark's output.
|
||||
Two options exist for what core exposes in its public API:
|
||||
|
||||
**Option A — Expose mdast types directly**
|
||||
Core re-exports remark's node types, augmented with KitchenMD annotation nodes via TypeScript module augmentation.
|
||||
Consumers import `@kitchen-md/core` and receive mdast-typed nodes.
|
||||
|
||||
**Option B — Core defines its own AST types**
|
||||
Core defines its own `DocumentAST`, `Block`, and `InlineNode` types.
|
||||
remark is an internal implementation detail; its types never appear in the public API.
|
||||
Consumers import only from `@kitchen-md/core`.
|
||||
|
||||
## Decision
|
||||
|
||||
**Option B** — core defines its own AST types.
|
||||
|
||||
## Rationale
|
||||
|
||||
The public API is a long-lived contract with multiple future consumers: the `kitchen` CLI, and the future Obsidian plugin.
|
||||
Leaking mdast into that contract means any remark major version that changes mdast types breaks all consumers, even if core's own logic is unchanged.
|
||||
|
||||
mdast also exposes many node types that are irrelevant to KitchenMD consumers.
|
||||
Core's own types can be a clean, minimal vocabulary scoped to what consumers actually need.
|
||||
|
||||
The future Obsidian plugin should not need to know or care that remark is involved.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Core maintains its own type definitions for all public AST nodes (Document AST, Block types, Inline Node types).
|
||||
- An internal translation layer maps remark's mdast nodes to core's types before returning from the Parser.
|
||||
- Changing core's internal Markdown parser in the future does not require a public API change.
|
||||
- Consumers do not take a transitive dependency on remark.
|
||||
Reference in New Issue
Block a user