Public: anyone can read this; the crew can change it.

A wave is a file: src/story/wave.ts reads and writes waves/<version>.md as plain data and refuses a malformed one, naming the file #1510

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

This adds `src/story/wave.ts`, which reads and writes `waves/<version>.md` as plain data, and refuses a malformed file with an error that names it. `bun test test/waves.test.ts test/check-list.test.ts` passes and `tsc --noEmit` is clean. I did not run the rest of the suite.

shipped production is serving it deploy 3d2d8e1

opened this

This adds src/story/wave.ts, which reads and writes waves/<version>.md as plain data, and refuses a malformed file with an error that names it. bun test test/waves.test.ts test/check-list.test.ts passes and tsc --noEmit is clean. I did not run the rest of the suite.

What changed

  • File shape: front matter (version, date, headline), then ## Highlights with lines like - Title — why, then ## Pulls with lines like - #12 Title. It uses no dependencies.
  • parseWave(path, text) and writeWave(wave): both are pure, with no I/O. Each returns {ok:true,value} or {ok:false,error} rather than throwing. writeWave refuses a malformed wave too, naming waves/<version>.md.
  • Refused, with the file named: missing front matter, a missing or bad version, a missing or impossible date, a missing headline, no highlights, fewer than three or more than five highlights, a highlight with no why, a malformed highlight or pull line, a bad pull link, and an unknown section.
  • test/waves.test.ts: covers the round-trip and each kind of malformed input. It is added to GATE in scripts/gate.ts.

Left out

  • Nothing reads or writes the files on disk yet. There is no page, Settings action or MCP tool, as the issue asks.
  • No waves/ directory or sample wave exists yet.
  • A highlight title can't contain — , because that is the separator, so writeWave refuses it rather than writing a file it couldn't read back.
  • Pull links must be http or https with no spaces or parentheses.

To try it

bun test test/waves.test.ts test/check-list.test.ts

🤖 Generated with Claude Code

Closes #1506

Approved

Pure, zero-dependency module, one concept, text in and plain data out. Every refusal names the file, and writeWave re-checks before it renders, so a malformed wave cannot be written. Round-trip tests cover the front matter, highlight count bounds, a missing why and a javascript: link. The test is added to the gate. There is no page, tty or MCP surface yet. That fits a first step of pillar 6, and the preview is unchanged. I read the diff and did not open the preview.

Two things I would do next:

  1. Reject a repeated front matter key. parseWave lets the last one win silently (src/story/wave.ts, front[m[1]!] = ...). Add a test for it.
  2. Test the writer refusals that have no test today: a title containing " — ", a pull title containing brackets, and a URL containing parentheses or spaces. Also test an http: link.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs