Repository navigation
feat(aidd-ui): lay a platform-agnostic design system and carry a change through its impact - #1137
Draft
blafourcade wants to merge 71 commits into
Draft
blafourcade wants to merge 71 commits into
blafourcade wants to merge 71 commits into
Conversation
The engine gains a tokens command that writes aidd_docs/ui/tokens.css from tokens.json and each theme file, one custom property per token. T10 names a stylesheet that is missing or out of date, and a composite token without raw CSS; V8 names a render that does not load ../tokens.css. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mDvAh1xZvZGAKEVhJn
The engine gains an impact command that prints the tokens, elements, screens, journeys, renders and code files a change to tokens or elements reaches, from the graph the hook already uses. H8 names a validated or deprecated element edited since its committed version without a new one; it reads git through the command line and stays silent without git, a repository or a committed record. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mDvAh1xZvZGAKEVhJn
01-system lays a web design system from nothing or extracted from the code, then carries a token or component change from its impact report to its new versions, calling the engine's validate, tokens and impact commands. It ships the record templates and a render skeleton that loads the generated stylesheet, and stops saying a review is expected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mDvAh1xZvZGAKEVhJn
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mDvAh1xZvZGAKEVhJn
…e token file Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mDvAh1xZvZGAKEVhJn
…s of what it uses Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mDvAh1xZvZGAKEVhJn
…d read Astro files Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mDvAh1xZvZGAKEVhJn
…ADME Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mDvAh1xZvZGAKEVhJn
…and leave deprecated ones alone H8's token-value part reads the same token set as V7 through one helper, and applies to validated elements only. The change flow names a deprecated element and leaves it untouched, so keeping it deprecated no longer forces a false breaking row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
… what it redefines A var() computes where it is declared, so a theme set on a nested element left a semantic token at its base value when the theme redefined only its primitive. Each block now redeclares every base token depending on one it redefines, through an alias or raw CSS, transitively, in tree order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
Silence now covers only git not installed, no repository, no commit and a file not committed. Any other failure, such as a repository git refuses to read or the timeout, is one H8 problem on aidd_docs/ui naming it, and the other rules still run. git's messages are read under LC_ALL=C. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
…, and tidy small leftovers A deleted tokens.css is now T10's one problem instead of two. The guard keeping a package path out of the bare Astro link is gone: such a link stays an error under C1. The usage text has one definition. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
…een's version For a reached screen a review names, the change flow adds one pending verdict row per state at the new version. A test on the fixture walks the whole sequence, from the impact report to a design system that validates with no error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
…its a review found The skill finds the engine in a flat install and says a person validates a component by hand until the review page exists. An Astro component links by bare path, tokens.css stays committed, and the README and spec carry the remaining limits and the token set a render may use. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
…action criterion Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
… repository git diff falls back to comparing two paths when it cannot use a repository, so a repository refused for its owner kept H8 silent. diff-index needs a repository and says why it has none. A test runs the real git under a different owner. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
…p, and tighten three statements Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
…ersion guard Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
…olor attributes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
…the theme axis Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
An existing app's committed literals made the end-of-turn check impossible to pass, since the skill never edits code. A literal stays an error in a file changed or untracked since HEAD, or when git cannot answer. Blob ids decide, so a file only touched since still counts as unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
A monorepo's apps each hold their own token file, so the rule rejecting a list is reversed. Every listed file is left out of literals and coverage, must exist, and joins impact's code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
The @media order decides which value wins, so swapping two contexts changed desktop values while the check said VALID. T6 now names it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
A C4 error sat behind C3 warnings and the 20-line cap would cut it. Each keeps its relative order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
A redefinition printed "undefined" when the base token has no type, and R8 printed "a asset". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
States the expected errors, what extraction leaves in code, the token forms an existing app needs, the coverage a render owes and what a change must check by hand. The breakpoint list is now the order the media queries cascade in, so it no longer assumes mobile-first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
…nd new limits Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
Transversal rules keep only what holds for every step. The stylesheet, validation and History rules move to the references their step opens, implemented-version follows the record's version instead of a literal 1, and each write step states when it runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
A code link is path[#Export]@<version>, one or a list, at most one per platform, its platform that of the code root holding it. implemented-version leaves the format. Components and screens take an optional platforms. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
A platform is an optional modifier of the Resolver, its contexts named after the platforms of system.md and read like the theme ones. tokens.css writes each platform that changes a value as a [data-platform] block after the themes, with the same redeclaration of dependents. A token a theme and a platform both set, or a platform and a breakpoint, is named. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
Under a code root, documents, data, images, fonts and any file holding a NUL byte are neither covered nor scanned. Known stylesheets keep their reader; any other text file is read for colour literals inside its string literals. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
The 01-system skill no longer stops at web: it extracts any design system in the code, links each platform with its version and writes platform token contexts. The README gives the new forms and limits, the spec its built state. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
…ls read twice A Haiku run wrote the design system into the plugin's own repository, reading aidd_docs/ui/ from the skill's folder. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
From a Haiku run on a web and mobile project. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
…exception From a Codex run on a web and mobile project. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
…kill's judgement Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
…by the resolver order Remove the three T6 rules forbidding a token set by two modifiers. tokens.css resolves each pair of a theme and a platform, and each breakpoint over those selectors, by resolutionOrder and writes only what the cascade would not give. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
…path A token file outside every code root now extracts with its platform, as a code root does. A bare item stays valid with one platform or under a root. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
A deprecated element follows only a token it cites, directly or through what it uses. bump keeps a record's own line ends, and same-value drops the targets a reached token cites. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
…d type A Codex run added $type to every context entry by hand, reading the reference's example; Haiku kept extract's output. Both validate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
…d platform on html only A var() computes on the element that declares it, so a value citing a token another theme or platform redefines was inherited stale, and html[data-theme] lost to the later @media :root. tokens.css now holds the base in :root, then :root[data-theme], :root[data-platform] and the pair of both, then each breakpoint as one @media repeating them. A block holds what the Resolver gives its combination and the blocks before it do not. The dependent redeclaration and the nested-region machinery are gone, and V9 names data-theme or data-platform on any element but html. H8 and impact read the roots a stylesheet can be asked about, a theme at a breakpoint included. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
…ange in the task breaks Within one task an element is raised once. A later --breaking change to it now turns that History row to yes and appends the change text, instead of leaving it only in left. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🎯 What & why
Second PR of the aidd-ui rework. The
01-systemskill lays a design system on a blank or existing project, whatever its platforms. It extracts the norm from the code and carries a token or component change to its new versions.01-hellogoes away.🛠️ How it works
One norm, platform agnostic.
aidd_docs/ui/is the project's norm. An existing design system in the code is matter for extraction, then only an implementation the norm is checked against.system.mdties each code root to a platform:code-roots: [web=apps/web/src, mobile=apps/mobile/src].platforms, all of them when absent.codeis one link per platform with the version it implements:[apps/web/Button.tsx#Button@2, apps/mobile/Button.tsx#Button@1].implemented-versionis gone.Responsibilities.
hooks/aidd-ui.cjs: every rule and every deterministic write.hooks/ui-hook.cjs: an adapter only.The engine stays in
hooks/because the CLI ships only that folder at plugin level, and later skills call it too.Engine commands.
validate.tokenswritesaidd_docs/ui/tokens.css.extractreads the code's token files (CSS custom properties of:root,[data-theme]and@media, JS or TS literal objects) and writestokens.jsonand the theme, breakpoint and platform files. It keeps every CSS name, lists what it leaves, and writes the same bytes on every run.impactreports what a change reaches, plus the tokens holding the same value without aliasing it.bumpapplies the version rules to whatimpactreaches, once per task.Themes, breakpoints and platforms are DTCG Resolver modifiers, combined by
resolutionOrder.data-themeanddata-platformon<html>only, which V9 checks.var()computes against the final values.Version guard (H8). A validated element whose text, render or token values differ from
HEADmust raise its version.Colour literals (C4). They are found in any text file under a code root, except documents, data and images; a techno with no reader is read in its strings.
HEAD, a literal is a warning: existing debt.Skill in the lean format. Three phase actions,
prepare,write,conclude, a single sequence for setup and change. What the model needs lives in five references, as tables.Choices worth a veto:
<html>only.🧪 How to verify
node scripts/check-tests-leave-git-alone.js -- node --test 'scripts/__tests__/**/*.test.js': 1384 pass, 0 fail.Evidence:
tokens.json, theme and platform files are identicalVALID, about 30k tokens eachextractorbump. Only the synthetic web plus mobile project ran the final text.HEAD. Committing an unraised edit or a new literal hides it from a latervalidate.✅ I certify
🤖 Generated with Claude Code
https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD