Next Release: schema-0.31.0+cli-0.28.0 - #351
Draft
nathanacurtis wants to merge 13 commits into
Draft
Conversation
…#353) Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
* docs(adr): draft ADR 071 — separate library conventions from tooling settings Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(adr): revise ADR 071 — independent term lists, Figma-scoped conventions, artifact layout, plugin analysis Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(adr): ADR 071 — uniform match/exclude shape for name-based conventions Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(adr): ADR 071 — block-sequence YAML; rekey conventions without adding capability Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(adr): ADR 071 — expand states examples from a real catalog declaration Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(adr): ADR 071 — focus Decision 1 on the two-way split; move plugin evidence to Downstream Impact Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(adr): ADR 071 — explicit detect setting replaces block-presence on-switch Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(adr): ADR 071 — no switch; scope and backgroundImage classify as conventions Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(adr): ADR 071 — two root types, no container; avoids PropConfigurations collision Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(adr): ADR 071 — output/format swap, figma.naming, settings absorbs workspace members, ResolvedConventions justified Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(adr): ADR 071 — settings grouped by concern, paths co-located, pipeline artifact Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(adr): ADR 071 — work vs place; sources folds into data; transformers own no paths Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(adr): ADR 071 — assets block, analysis derived, targets deferred Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(adr): ADR 071 — Pipeline type, supporting type placement, schema ref strategy, author, PanelSettings Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(adr): ADR 071 — one schema file per artifact, workspace schema retired Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(adr): ADR 071 — retire workspace.schema.json for per-artifact schemas Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * feat(schema)!: split Config into Conventions, Settings and Pipeline (ADR-071) BREAKING CHANGE: Config, ResolvedConfig and DEFAULT_CONFIG are removed. Library facts move to Conventions.figma, run choices to Settings grouped by concern, and declared work to Pipeline. Metadata.config becomes Metadata.conventions + Metadata.settings, and workspace.schema.json is replaced by one schema per authored artifact. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(adr): ADR 071 — record the config/ folder-name rationale Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * adr(071): accept — Conventions, Settings and Pipeline replace Config Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(site): retarget schema pages to Conventions, Settings and Pipeline (ADR-071) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(adr): use neutral example identifiers Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Ported from the specsplugin-com repo, lost in the site migration. - Left-aligned doc layout with sidebar and table of contents hidden, rather than the centered splash template - Activate your license section split into individual and team subscriptions, drawing the subscription/license distinction - Seat management consolidated into Manage your subscription - Card grids replaced with plain link lists; links made site-relative Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(cli)!: load conventions, settings and pipeline (ADR-071) ConfigLoader reads a config/ directory of three artifacts and still loads a legacy specs.config.yaml, migrating it in memory with a one-time warning. init scaffolds all three files. Commands, bridge and analyzers read the two halves, with a fallback for specs whose metadata predates the split. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(site): regroup nav as Configuration with conventions, settings and pipeline Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(settings): retarget configuration pages to the three artifacts (ADR-071) Each option page names which file it lives in and why, with legacy paths kept as migration notes. Overview retitled Configuration; folders documents the per-concern directories; data-sources renames data to fetch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(cli,guides): retarget to the three-artifact configuration (ADR-071) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(cli): update stale strings in scan manifest and init output Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs: legacy config is refused, not migrated in place; add migrate command page Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * feat(cli): refuse pre-split config; add specs migrate config The loader detects a legacy file only to stop — before the fallback path, so a workspace is never generated from defaults it did not declare. Conversion moves to a registry-backed migrate command, keyed by subject and source version. init refuses in a legacy workspace rather than scaffolding defaults over a real configuration. Every refusal names a remedy that works: the discovered file, an explicit --source, or moving a user-level config into the workspace. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(schema): update types README for the split exports Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(schema): align README diagram border Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * feat(schema): add DEFAULT_CONVENTIONS; amend constitution for the split exports The constitution named DEFAULT_CONFIG as the only permitted runtime export, so ADR-071 violated it by shipping two. The rule now permits one defaults constant per configuration artifact, and conventions gain theirs — removing the literals the CLI had been hardcoding. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs: retarget repo docs to the three-artifact configuration (ADR-071) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * feat(schema,cli)!: default the split spec layout to on One folder per component holding one file per concern is what transform, analyze and render all read, so the layout was not really a per-consumer choice — yet splitComponents, splitConcerns and useSubfolders carried no schema default and both consumers picked false, the one shape nothing downstream can use. DEFAULT_SETTINGS now carries all three as true and ResolvedSettings requires them. The generate flags are renamed for what they do, since each can now only turn a split off: --combine-as-library, --combine-concerns and --no-subfolders replace --split-components, --split-concerns and --use-subfolders. An absent flag defers to the configured value rather than overriding it. specs migrate config writes all three out explicitly, including from a source that configured no output block, so migrating changes where configuration lives without changing what a workspace emits. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(cli,schema): record the configuration split in the changelogs The cli 0.28.0 section was empty, so the breaking change users hit first — specs.config.yaml no longer being read — went unrecorded while the release notes described only the layout default. Adds a Breaking section leading the release, writes up specs migrate as the Added feature it is, and covers config/ discovery, --config taking a directory, init refusing over a legacy workspace, the vocabulary renames, and the removal of user-level ~/.specs/config.yaml. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…2) (#357) Figma has no numeric variant, so a count axis is authored as a VARIANT whose options are the strings "1", "2", "3". Read back, that became an EnumProp — a string type over a numeric domain — and consumers typed the prop "1" | "2" | "3". NumberProp could carry the numeric type but left the range open; EnumProp could carry the closed set but fixed type: string. A numeric variant needs both at once, and neither type provided it. `enum?: number[]` closes that gap, so the option set survives alongside the numeric type — the render direction rebuilds the variant axis from it positionally, so losing it would make the round trip lossy. Additive and optional: a NumberProp without `enum` keeps its present meaning of an open numeric range. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ows (#362) (#364) `scan` collapsed every dev status other than READY_FOR_DEV to NONE, so a COMPLETED component was indistinguishable from an untouched one. The manifest parser then accepted only those two values and silently discarded any other row. Dev statuses are now carried through verbatim, an unrecognized status leaves the row parsed but unselected, and both scan and generate warn on a row they cannot read. Selection is unchanged: generate still builds only READY_FOR_DEV defaults. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
The ADRs drafted in PR #363 never had their index rows cherry-picked onto main, so the index topped out at 070 and the next author would have claimed 073 again. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs(adr): draft ADR-080 — null as a prop configuration value Widens PropConfigurationValue with a null arm so a configuration can state that a nullable prop is unset, instead of pairing a content value with a visibility boolean that is not a prop of the component being configured. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat(schema): null as a prop configuration value (ADR-080) A configuration can now state that a nullable prop is unset. null is a value, not an absence: an absent key inherits from the layer beneath, a null key overrides an inherited value with no value. Without it, a content prop paired with a visibility boolean could only be expressed as both at once — a bound value beside a false flag naming a prop that pairing had already removed from the component's props. InstanceExample.propConfigurations declares its own inline union so it can exclude PropBinding, so it is widened separately. It gains null and keeps that exclusion. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs(adr): accept ADR-080 All gates pass: tsc build, schema validation 7/7, type tests compile. Moves the index row from Draft to Accepted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Reserves the number for the slot-wrapper collapse ADR drafted on 083-slot-wrapper-collapse, so concurrent ADR authors do not collide. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs(adr): draft ADR-083 — collapsing a slot-only wrapper Extends ADR-058's primitive wrapper collapse to a root whose sole anatomy child is a slot, governed by the existing collapsePrimitiveWrapper setting. Context and prior analysis in #377. Claims 083 in the index (082 is taken by origin/082-component-description). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs(adr): drop the style eligibility test from ADR-083 Root and slot are both container nodes with the same style signature, so merging them discards nothing and no style needs testing. ADR-058 needs an eligibility list because it merges a container into a `text` or `glyph` leaf, where container styles have nowhere to go — that reason does not carry over. - Eligibility is structural only: a container root with exactly one anatomy child, of type slot, all-or-nothing across variants - The merge keeps the slot's value on any shared key; the slot is the box the children sit in, and the wrapper's layout is an artifact of holding one child - Expansion splits by what a style acts on: parent layout to both boxes, child layout to the slot, everything else to the root `padding` is called out as the one parent-layout key that is not a no-op on a single-child wrapper — applied to both boxes it insets twice. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs(adr): correct the padding note in ADR-083 Merge keeps the slot's value on a shared key; values are never summed. A root with padding 8 and a slot with padding 12 collapses to 12. The earlier note framed padding as an exception to the split rule. It is not: a slot carrying padding is an authoring mistake, since padding belongs to the box with the surface and the slot has none. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat(schema): collapse a slot-only wrapper (ADR-083) collapsePrimitiveWrapper now covers a root container whose only child is a container bound to the component's sole slot property. Eligibility is the binding, not the anatomy label, and it must hold in every variant. No member is added, removed or retyped — the setting's documented meaning widens and the behaviour belongs to the consuming packages, so this is a PATCH within the unreleased 0.31.0. - types/Settings.ts — Settings.spec and ResolvedSettings.spec doc comments state both shapes and why they are tested differently - schema/settings.schema.json — description widened to match - site docs — the settings page gains the slot shape, its eligibility and a collapsed example; the schema table row is updated - CHANGELOG — one Changed entry under 0.31.0 The collapsed element keeps the slot layer's $extensions['com.figma'], so the source layer stays traceable, matching what ADR-058 already does for a leaf. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs(adr): accept ADR-083 All three gates pass: tsc build, schema validation (7/7), and the type tests. Status flipped to ACCEPTED and the INDEX row moved from Draft to Accepted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Draft release PR — opened automatically by start-next-release so the in-flight release is visible. Versions, CHANGELOG, build, tests, and publish will be finalized by the release skill.