Skip to content

0.13.0

Choose a tag to compare

@aqkprogrammer aqkprogrammer released this 06 Oct 15:52
· 172 commits to 3787edc2f84b3609158b8e26f37133952d99d608 since this release

The CLI and the MCP server now work after the install as well as during it,
and coding agents are told which component is right, not only which exist.

  • Security. The CLI no longer trusts its registry with the filesystem or
    its licence key: paths are confined, keys go only to the registry they were
    issued for, and registry dependencies must be npm packages.
  • The component genome. Every registry item carries its props, whether it
    needs a client boundary, whether it animates, and its quality checks; 188
    carry guidance on when to use them and what they are confused with.
  • dowel doctor, diff, audit and plan, and the MCP server's
    audit_code. plan --model asks Claude, with your own credentials.
  • Private registries with per-registry keys, and governance metadata
    (owner, since, deprecated).
  • In the repository: real-browser accessibility over every story, visual
    regression, a fresh-app install of every item in CI, and AgentBench, a
    harness for measuring whether agent support helps.

Added

  • AgentBench (packages/agentbench, private): a harness that runs the same
    prompt in two copies of a project — with Dowel's agent files and MCP server,
    and without — and scores both diffs with tsc, dowel audit, invented and
    uninstalled imports, recall of expected components, and the jsx-a11y rules.
    Ten tasks, a Claude Code adapter, and noop/reference adapters that cost
    nothing. No run has been published; /agentbench on the site documents the
    method and shows published runs only.
  • Private registries can require a key. A registry that answers 401 gets
    one retry with the key stored for it, and no other; a public registry never
    receives a key it did not ask for. Keys are stored per registry, so a Pro
    licence and a company key coexist. login --registry <url> verifies against
    the registry's index when it has no licence endpoint; logout --registry
    removes one key; whoami lists them. The MCP server reads DOWEL_TOKEN and
    DOWEL_TOKEN_REGISTRY for the same.
  • Governance metadata: an item can declare owner, since, and
    deprecated (version, reason, replacement). Deprecated items still install;
    add and update name the replacement, list and doctor mark them, the
    MCP server and agent docs warn off them, and the planners skip them. Custom
    registries can also declare guidance and composesWith, and the build
    rejects any of these naming an item that does not exist. Upstream guidance
    that names an item the extending registry cannot serve, such as a Pro block,
    is dropped from the inherited copy.
  • dowel plan "<screen>" chooses the blocks and components for a screen you
    describe. --model asks Claude to choose, with your own Anthropic
    credentials and the optional peer @anthropic-ai/sdk; whatever it names
    that the registry does not have is dropped and reported. Without --model
    it uses the built-in planner, which needs nothing.
  • MCP audit_code checks code an agent wrote against the same rules as
    dowel audit. get_component now says when to use a component, what it is
    confused with, whether it needs a client boundary, and every prop its type
    declares; search_components matches on what a component is for.
  • The agent files list each component's guidance under it, and the planners
    score it above a description match.
  • create-dowel-app writes the agent files when it scaffolds.
  • dowel doctor checks a project's setup and prints a checklist: the
    project shape, the import alias against tsconfig.json, the tokens in the
    stylesheet, installed files present, npm packages and component dependencies
    installed, a licence for any Pro item, updates available, and stale agent
    docs. It is a checklist, not a score, and it writes nothing.
  • dowel diff [names…] shows how installed files differ from the
    registry's current ones, as a unified diff.
  • dowel audit [paths…] finds Tailwind palette colours, literal colours in
    classes and inline styles, arbitrary sizes off the scale, physical direction
    utilities, and native elements where the Dowel component is installed. It
    skips the files Dowel wrote. --fix rewrites the physical utilities, the
    only findings with one exact fix, after asking. --json is for CI.
  • The component genome. Every registry item now carries capabilities
    (whether it needs a client boundary, whether it animates), props read from
    its type, and the quality checks from /quality. Items may also declare
    guidance (when to use it, when not, what it is confused with) and
    composesWith. All optional: older registries parse, and older CLIs ignore
    the new fields.
  • The registry now publishes the JSON Schemas its $schema fields pointed at:
    r/schema/registry-item.json and r/schema/registry-index.json.
  • The MCP server has contract tests for every tool, and a README.

Continuous integration

  • Every Storybook story is checked by axe in a real browser, light and dark,
    with the color-contrast and target-size rules the jsdom tests cannot
    run (packages/browser-tests, ADR 18). It found 140 violations across 82
    stories, recorded as 83 entries in known-violations.json, each with a
    reason — 70 of them "to fix". The suite fails on anything new and on any
    entry that no longer occurs, so the list can only shrink. The largest group
    is status text on its own 10% tint (4.1–4.5:1), a pair the palette audit
    never checked.
  • Visual regression for 42 curated stories — forms, open overlays, data,
    feedback, AI and five blocks — in light and dark, LTR and RTL, compared
    pixel-for-pixel inside the pinned Playwright container (188 images). It
    found the calendar's month navigation anchored to the wrong ancestor.
  • Storybook has a Direction toolbar global that sets dir and wraps the
    story in DirectionProvider, so RTL previews mirror the primitives too.
  • Coverage thresholds are enforced in CI (measured: 97.3% statements,
    93.4% branches, against floors of 85% and 80%).
  • Every free item is installed into a fresh app on every pull request
    (scripts/smoke/install-all.mjs): scaffold, init, add all of them,
    tsc --noEmit, next build — the release check that used to be manual.

Security

  • Registry file paths are confined to their directory. A path such as
    ui/../../.bashrc used to be written outside the project. The registry
    schema now refuses absolute paths, .., . and empty segments,
    backslashes, colons and NUL, and the CLI checks again where the path meets
    the disk.
  • remove only deletes what the CLI could have written. It used to delete
    any path components.json listed. It now refuses, deleting nothing, when an
    entry names a file outside the directories components are installed into.
    Alias directories outside the project, as in a monorepo, still work.
  • The licence key goes only to the registry it was issued for, over HTTPS.
    The registry an install reads comes from components.json, so a cloned
    repository could name its own server, mark an item as licensed, and collect
    the key. login now records which registry it verified the key against, and
    the CLI refuses to send the key anywhere else. Keys stored before this change
    belong to the default registry. DOWEL_TOKEN belongs to the default registry
    unless the new DOWEL_TOKEN_REGISTRY names another.
  • Registry dependencies must be npm package names, optionally with a
    version range. A git+https: URL, a tarball or a local path is refused
    instead of being handed to the package manager.
  • Item names are validated wherever they arrive from, including the
    command line, before they become a URL or a file path.

Fixed

  • remove theme --force deleted the project's whole stylesheet, because
    init records it under theme. The stylesheet is now never deleted.
  • update failed with ENOENT restoring a file whose directory had been
    deleted.
  • Registry and licence requests time out after 30 seconds instead of waiting
    indefinitely.
  • The MCP server's install_command said a Pro item was "not found"; it now
    resolves it from the index and says it needs a licence. Unknown names are
    all reported together, with suggestions, and a name like ../package is
    refused rather than read from outside the registry.
  • audit:rtl skipped a physical utility whenever a class such as bg-muted
    sat within a dozen characters before it. No component had such a bug hiding;
    the check is now exact.
  • The CLI and scaffolder state Node 20.12 as their floor, which their prompts
    library requires, and CI runs the built binaries on Node 20 and 22.