Skip to content

feat: simplify development - #239

Open
anneke wants to merge 9 commits into
mainfrom
feat/simplify-development
Open

anneke wants to merge 9 commits into
mainfrom
feat/simplify-development

Conversation

@anneke

@anneke anneke commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

Add scripts to add and update components, which can be run manually instead of using AI for simple tasks.

Type of change

  • Fix
  • New feature / variant
  • Breaking change
  • Docs / repo tooling (no package code changed)
  • Chore / refactor

Checklist

  • pnpm build, pnpm lint, and pnpm format pass
  • Storybook story added/updated to cover the change (variants, sizes, states)
  • Visual snapshots updated (pnpm test:visual:update after pnpm build-storybook) if appearance changed
  • Changeset added (pnpm changeset) — required for any change to @surfnet/curve-react or @surfnet/curve-angular; N/A for docs/CI-only changes
  • React and Angular kept in parity, if applicable (contract updated in @surfnet/curve-contracts)

@anneke anneke changed the title Feat/simplify development feat: simplify development Oct 19, 2026
@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

♿ Accessibility audit — WCAG 2.2 AA

✅ No violations across 427 stories / 13664 theme·mode combinations in @surfnet/curve-angular, @surfnet/curve-react.

Automated axe covers ~30–50% of WCAG 2.2 AA. Keyboard, screen-reader and reflow checks still need a manual pass. Full per-story JSON is in the run’s a11y-reports artifact.

@anneke
anneke force-pushed the feat/simplify-development branch from 5b14248 to 296b2ff Compare October 20, 2026 09:40

@WDeenikSURF WDeenikSURF left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I applaud this, more consistent output from AI and much easier to build without AI.

Must admit I did not find the time to read through all skills changes. Scanned the rest and tried out the new & import scripts. Cannot really test the update script as there are no upstream snapshots yet.

Comment thread scripts/lib/scaffold.ts Outdated
let name = input;
if (mode === 'new') {
if (!input.startsWith(HOME_GROWN_PREFIX)) {
if (spartanPrimitives(repoRoot)[input]) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we only checking for name collisions with Spartan primitives, not shadcn ones?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I've changed this to check both

Comment thread scripts/lib/templates.ts Outdated

export function contract(name: string, description: string, axes: Axes): string {
const id = `${camel(name)}Contract`;
const entries = Object.entries(axes);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit; axesEntries is more clear

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed it!

Comment thread scripts/lib/vendor.ts
Comment on lines +119 to +122
export function spartanBlocker(name: string, root: string): string | undefined {
const primitive = spartanPrimitives(root)[name];
if (!primitive) return `The installed @spartan-ng/cli has no "${name}" primitive.`;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will the opposite never be the case (a primitive that exists on Spartan but not on shadcn)?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could! Updated this, too

Comment thread scripts/lib/vendor.ts
Comment on lines +172 to +178
/**
* The CLIs "helpfully" bump dependencies and re-write shared files. Snapshot
* package.json and the tracked source files first, then undo anything that
* wasn't there before: version bumps of existing deps, unwanted new deps, and
* edits to tracked files under src/.
*/
function startGuard(root: string, framework: Framework) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the shadcn CLI you can view a component which gives you the file contents & a list of dependencies, in which case we could write & install those ourselves to prevent this somewhat hacky approach of us having to revert changes made by the CLI.

Sadly I can't find something similar for Spartan.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated this for shadcn

Comment on lines +1 to +5
{
"react-story": ["command"],
"angular-story": ["command"],
"story-title-parity": ["dropdown-menu", "input-group"]
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to know why these are in the allowlist.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a "reason" key/value to clarify!

: {};
const allowed = (v: Violation) => allowlist[v.rule]?.includes(v.subject) ?? false;

const errors = violations.filter((v) => !allowed(v));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally you'd only allow subject-rule combinations. Now if there are new violations in an allowed subject you'd never see them because all violations are allowed for that subject.

Comment thread package.json Outdated
Comment on lines +13 to +15
"new:component": "jiti scripts/new-component.ts",
"import:component": "jiti scripts/import-component.ts",
"update:component": "jiti scripts/update-component.ts",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at different script variants (like the test: scripts), I'd expect these scripts to be called component:new, component:import and component:update.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed them, good point!

Turns rules that only lived in AGENTS.md and the skills into a check:
barrels, package exports, stories and contracts per component, no
leftover Tailwind in React or Angular component code, no TODOs in
contracts, and matching React/Angular story titles. Known exceptions
are listed in scripts/conventions.allowlist.json.
Scaffolds a component in contracts plus React and/or Angular: vendors it
with the shadcn or Spartan CLI, writes the barrel, package exports, CSS
and story stubs, and saves a pristine upstream copy in .upstream/.

Also undoes CLI side effects: dependency bumps, the bogus `cn` package
and import from the shadcn registry, tw-animate-css, duplicate copies of
components Curve already vendors, and edits to other tracked files.
Refuses up front when the component exists or Spartan needs a newer
@spartan-ng/brain than the repo has.
Lead with pnpm new:component / update:component / check:conventions and
keep the manual playbooks as the reference and fallback. Also remove the
duplicated refresh paragraphs in AGENTS.md, correct the React style
(base-vega), note that autodocs is set project-wide in preview.ts, and
document the Spartan CLI/brain version split.
…stom

Home-grown components (curve-<name>, like curve-data-table) have no
upstream CLI to vendor from. With --custom the generator skips the CLIs
and the .upstream/ snapshot and writes a small working component instead:
each contract axis becomes a typed prop that sets a data-* attribute, with
a CSS rule stub per value and Playground + per-axis stories named the same
in both frameworks.

The curve- prefix is required with --custom (and rejected without it), so
home-grown names never collide with upstream components. update:component
now says there is no upstream to merge for curve-* components.
move the manual steps into a separate fallback file that agents read only when the script can’t be used. Fail if there’s no —description for a new component so if an agent is used, the script doesn’t stall

Signed-off-by: Anneke Sinnema <[email protected]>
@anneke
anneke force-pushed the feat/simplify-development branch from 296b2ff to 578315c Compare October 21, 2026 15:51
Signed-off-by: Anneke Sinnema <[email protected]>
Signed-off-by: Anneke Sinnema <[email protected]>
component:import and component:new now check shadcn as well as Spartan, and say which upstream has a component. React vendoring asks 'shadcn add --dry-run' what it would write and writes only the component, so there are no CLI side effects to undo.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants