From 8a8cb031d6cd703aa9fa1d161e71606730b14ec7 Mon Sep 17 00:00:00 2001 From: 0thernet Date: Sat, 10 Oct 2026 21:17:25 -0400 Subject: [PATCH] release: v0.9.0 Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 27 +++++++++++++++++++++++++++ README.md | 8 ++++---- docs/publishing.md | 8 ++++---- package.json | 2 +- site/install.sh | 2 +- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7c915d9..3b2d9102 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,33 @@ All notable changes to dawg are recorded here. Versions follow [semantic version ## Unreleased +## 0.9.0 + +The patcher: modular instruments and effects built from nodes and cables, played by the song render, the loop and live keys, edited from a `/patch` view, typed `patch` commands, the agent and `song.ts`, with eight built-in patches and four macro knobs. Plus Ctrl-K breadcrumbs, short guide pages, real screens on dawg.sh and fixes for typed-ahead input. + +### Added + +- **Patches.** A patch is a small modular synth or effect stored in the score: nodes (oscillators, filters, envelopes, math, and dawg's engines and effects as `engine.*` and `fx.*` nodes) joined by cables, with up to four macros as its knobs. A track plays one as its instrument (`instrument: "patch"`) or runs effect patches in its chain (`fx.patch`, after distort, or after the chain with `at: "post"`), and `score.patches` holds a library tracks can reference. The validator suggests the nearest name for a bad node or port, infers per-voice or global rate, and breaks feedback loops deterministically as a one-block delay. Edits travel as node, cable and macro operations, so two panes wiring different cables both keep their change. +- **Patch engine.** Instrument patches render through a compiled block runner in the song render, the loop worker and live keys; effect patches run at the chain's patch stage. `engine.vocoder` wraps the vocoder's carrier. `patch convert` wraps a track's current instrument as a patch that renders bit-identical to the original. Editing one macro re-renders only that track's stem. +- **Fused patch runner.** The voice section compiles to one generated function per program with node kernels inlined and shared per-sample loops: about 27 ns per voice-sample before, about 13 ns now (16 voices x 12 nodes at 48 kHz, `bench/perf/patch-runner.ts`), bit-identical to the reference interpreter (`fuse.test.ts`). Absolute and fused/interpreted ratio gates in `bench/perf/gate.test.ts` hold it there. +- **`patch` commands.** `patch new|load|add|set|wire|unwire|macro|knob|rate|rm|convert|detach|save|show|nodes`, all with `--fx ` for effect patches. Each line is one undo step. Errors name the port and the nearest word and apply nothing; receipts report rate changes and cables the compiler drops. `patch show` prints the lines that rebuild a patch. The agent edits patches with the `patch_edit` tool (ops in order, one undo step, one bad op rejects the batch), and show-me types the same lines. `/help sound` has a `sound · patch` group, and Ctrl-K has Sound › patch and Effects › add effect patch. +- **Patch view.** `/patch [--fx ]` (Ctrl-K › Sound › patch › Edit patch) shows the focused track's nodes in signal order (`◆` per voice, `●` once), the selected node's ports and a cable matrix with pinned headers; `f` shows the whole matrix. `a` adds a node (each row auditions while the loop plays), `w` wires to a legal input, `x` removes, `m` maps a parameter to a knob and `g` switches a node between per voice and once; each key runs and echoes a typed `patch` command. Dropped cables are marked with their warning above the knobs. The first four macros are the four knobs. `dawg pane patch [track]` opens a pane on it, and a cable wired by a command, the agent or another pane moves the selection to its cell. It draws from 60x16 to 500x150, under NO_COLOR, mono and `TERM=dumb`. +- **Built-in patches.** Eight patches in `core/patches`, each with four named macros: `acid-bass`, `supersaw-pad`, `fm-bell`, `pluck-ks` and `wobble` instruments, and `sidechain-pump`, `wide-crush` and `formant-vox` effects. `patch load acid-bass` plays one; `patch show acid-bass` prints its recipe. +- **Patch library.** `patch save --user` writes a patch, with its knob settings, to `$XDG_DATA_HOME/dawg/patches` (`DAWG_PATCHES_DIR` overrides). `patch load github:/[@branch]/` loads a pack patch through the sample-pack manifest cache (https only, size-bounded, sha256-pinned). Every file is validated before it is used. +- **Patches in `song.ts` (SDK 1.35.0).** `patch(name, build)` and `fxPatch(name, build)` with node factories typed from the node specs, `macro()`, typed port setters, `.plus/.times/.range/.amount` and `.global()`; stable node and cable ids from a hash of the build; the plain form `patch({ role, name, nodes, cables, macros })` that dawg prints back, and `patch({ ref, macros })` for a library patch from `song({ patches })`. Strudel-style signals `sine cosine saw isaw tri square rand perlin irand pat()` with `range rangex slow fast segment add mul early late every` follow Strudel's formulas; `mods: { cutoff: sine.range(300, 2400).slow(4) }` drives a macro and `lanes:` any automation lane, baked into automation points. +- **Ctrl-K breadcrumbs.** Menu and drawer titles lead with the menu mark (`≡ Arrange › range`, `= Arrange > range` under `TERM=dumb`), the parents dim and the current step bold, folding middle steps to fit the box. +- **/help marks.** Group headings carry their mark: `›` command groups, `✦` agent, `→` topics, `⌃` key lists (the `?` panel too). The symbols carry the meaning under NO_COLOR and mono. +- **Short guide pages.** Guides split into pages that fit an 80x24 pane (at most 16 rows at 72 columns, sections never split): `n`/`p` turn pages and step to the next guide at the ends, and the title shows `guide · Arrange › TAPE · 1/2`. Each kind of line has one mark and one theme role (`✦` ask, `›` type it, `≡` menu, `⌃` keys, `→` next, `✓` tip, `!` careful), shared by the TUI and dawg.sh from `guides/marks.ts`. Every guide opens with one or two plain sentences, and the README has a new first screen. +- **Real screens.** `bun run screens` drives the real TUI in a PTY with a frozen clock and seeded randomness and writes `docs/screens/.json`; a test fails when a committed screen no longer matches the TUI. dawg.sh and its docs show these screens as selectable text. +- **dawg.sh.** The home page tells the product story with real screens (highway, play mode, TAPE, knobs and mix, patches, the Ctrl-K menu, show-me, panes, audio), guides show their screens, the README has a Patches section with the same screen, and a new [dawg vs Strudel](https://dawg.sh/vs/strudel) page compares the two. The site names the native audio sink, with ffplay, SoX and afplay as fallbacks. + +### Fixed + +- **Typed-ahead lines run in order.** Lines typed while an earlier one was still running ran newest first (`track drums`, `track bass` ended on drums). The prompt queue is now first in, first out, with Alt-Enter follow-ups behind it. +- **Undo and the next line.** A line queued behind Ctrl-Z ran against the revision before the undo and failed (`session changed`); queued lines now wait for an in-flight undo or redo. +- **TAPE keys typed ahead.** A TAPE key pressed while commands were still queued reduced from stale state, so `[ [ [` lost a press. It now waits its turn and reduces from what the lines before it left. +- **Package contents.** `guides/marks.ts`, which the CLI imports, is in the package `files`, and `test/package-files.test.ts` fails when a shipped file imports one that is not shipped. + ## 0.8.0 Panes and arrangement: several terminals over one session with per-pane undo, ranges you can loop, copy and move, four knobs on every sound page, a TAPE screen with loop recording, one audio output and input, and a UI that holds from 60x16 to very large terminals. diff --git a/README.md b/README.md index c51d6200..cfc88b5e 100644 --- a/README.md +++ b/README.md @@ -59,17 +59,17 @@ and its own undo, and they share one transport (`guide panes`). Install the release tarball from GitHub directly: ```sh -bun add -g https://github.com/hraness/dawg/releases/download/v0.8.0/hraness-dawg-0.8.0.tgz +bun add -g https://github.com/hraness/dawg/releases/download/v0.9.0/hraness-dawg-0.9.0.tgz dawg --help ``` Each [release](https://github.com/hraness/dawg/releases) is immutable and ships the tarball, a `SHA256SUMS` file and a build provenance attestation. To check a download before installing it: ```sh -gh release download v0.8.0 --repo hraness/dawg +gh release download v0.9.0 --repo hraness/dawg shasum -a 256 -c SHA256SUMS -gh attestation verify hraness-dawg-0.8.0.tgz --repo hraness/dawg -bun add -g "$PWD/hraness-dawg-0.8.0.tgz" +gh attestation verify hraness-dawg-0.9.0.tgz --repo hraness/dawg +bun add -g "$PWD/hraness-dawg-0.9.0.tgz" ``` dawg is also on npm as [`@hraness/dawg`](https://www.npmjs.com/package/@hraness/dawg): diff --git a/docs/publishing.md b/docs/publishing.md index 7f8a67e5..cab6aedb 100644 --- a/docs/publishing.md +++ b/docs/publishing.md @@ -141,15 +141,15 @@ authentication, from the exact Release tarball: ```sh npm login -gh release download v0.8.0 --repo hraness/dawg +gh release download v0.9.0 --repo hraness/dawg shasum -a 256 -c SHA256SUMS -gh attestation verify hraness-dawg-0.8.0.tgz --repo hraness/dawg -npm publish "$PWD/hraness-dawg-0.8.0.tgz" --access public +gh attestation verify hraness-dawg-0.9.0.tgz --repo hraness/dawg +npm publish "$PWD/hraness-dawg-0.9.0.tgz" --access public npm trust github @hraness/dawg --repo hraness/dawg --file release.yml --environment npm-release --allow-publish --yes npm trust list @hraness/dawg ``` -Then rerun the failed `npm` job of the `v0.8.0` release run. It finds the same +Then rerun the failed `npm` job of the `v0.9.0` release run. It finds the same integrity on npm and succeeds without publishing again. Every later version is published only by the workflow's OIDC identity. Do not add a long-lived npm token. diff --git a/package.json b/package.json index 81f3b740..d6d82edc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@hraness/dawg", - "version": "0.8.0", + "version": "0.9.0", "license": "MIT", "repository": { "type": "git", diff --git a/site/install.sh b/site/install.sh index 176e2333..f34050b1 100644 --- a/site/install.sh +++ b/site/install.sh @@ -12,7 +12,7 @@ # `bun add -g `. # # Settings (all optional): -# DAWG_VERSION=0.8.0 install this version instead of the latest +# DAWG_VERSION=0.9.0 install this version instead of the latest # DAWG_INSTALL_DIR= where verified tarballs are kept # DAWG_INSTALL_BASE_URL= download from /hraness-dawg-.tgz and # /SHA256SUMS instead of GitHub (testing;