spaps
Version:
Sweet Potato Authentication & Payment Service CLI - Docker Compose orchestrator for local Python/FastAPI SPAPS server with built-in admin middleware
518 lines (457 loc) • 16.1 kB
JavaScript
/**
* Design System Registry (DSR) surface for the generated browser starters.
*
* The scaffolded React starter renders the SPAPS "Authentication reference"
* page. Its visual layer is registry-owned: tokens come from the pinned DSR
* theme payload, and the page composes shadcn semantic tokens only. Nothing
* here invents a local palette, radius scale, or shadow system.
*
* Adoption is recorded in the generated `design-system.registry.json`, and the
* repo-level decision lives in `docs/DSR-DECISION.md`.
*/
const DSR_THEME = {
item: 'vectorsight-theme',
version: '0.1.0',
channel: 'pilot',
family: 'vectorsight',
title: 'VectorSight',
registryUrl: 'https://registry.buildooor.com/r',
payloadUrl: 'https://registry.buildooor.com/r/vectorsight-theme.json',
installCommand: 'npx shadcn@latest add @design-system/vectorsight-theme',
sourceRepo: 'https://github.com/build000r/design-system-registry',
sourcePayload: 'registry/vectorsight/themes/vectorsight-theme.json',
// Every entry below carries the DSR cross-family `ds-*` token contract, so
// switching the active item is a one-line change in the theme adapter.
switchableItems: ['vectorsight-theme', 'nocturne-theme', 'molten-pop-theme'],
};
const DSR_DEPENDENCIES = {
'class-variance-authority': '^0.7.1',
clsx: '^2.1.1',
'tailwind-merge': '^3.3.1',
};
const DSR_DEV_DEPENDENCIES = {
'@tailwindcss/vite': '^4.1.14',
tailwindcss: '^4.1.14',
};
function provenanceHeader(commentOpen, commentLine, commentClose) {
const lines = [
'Design System Registry - ' + DSR_THEME.item + '@' + DSR_THEME.version + ' (channel: ' + DSR_THEME.channel + ')',
'Upstream: ' + DSR_THEME.sourceRepo,
'Payload: ' + DSR_THEME.payloadUrl,
'Refresh: ' + DSR_THEME.installCommand,
'',
'Registry-owned visual decisions. Pinned in design-system.registry.json.',
'Re-pull the item instead of hand-editing these values.',
];
return commentOpen + '\n' + lines.map((line) => (line ? commentLine + ' ' + line : commentLine)).join('\n') + '\n' + commentClose + '\n';
}
/**
* Tailwind v4 entry stylesheet carrying the pinned DSR theme payload.
*
* `:root` and `.dark` are identical on purpose: VectorSight is a void-only
* system (pure black ground in both schemes) per its upstream payload.
*/
function reactStylesSource() {
return provenanceHeader('/*', ' *', ' */') + `
@import "tailwindcss";
@custom-variant dark (&:is(.dark *));
:root,
.dark {
--radius: 3px;
--background: #000000;
--foreground: #00ff41;
--card: #0a0a0a;
--card-foreground: #00ff41;
--popover: #0a0a0a;
--popover-foreground: #00ff41;
--primary: #c8ff00;
--primary-foreground: #000000;
--secondary: #00ff41;
--secondary-foreground: #000000;
--muted: #0a0a0a;
--muted-foreground: rgba(0, 255, 65, 0.6);
--accent: #c8ff00;
--accent-foreground: #000000;
--destructive: #ff3333;
--destructive-foreground: #000000;
--border: rgba(0, 255, 65, 0.3);
--input: rgba(0, 255, 65, 0.3);
--ring: #c8ff00;
/* DSR cross-family token contract */
--ds-radius-sm: 2px;
--ds-radius-md: 3px;
--ds-radius-lg: 4px;
--ds-radius-card: 3px;
--ds-radius-full: 9999px;
--ds-font-display: var(--vs-font-display);
--ds-font-body: var(--vs-font-mono);
--ds-shadow-card: 0 0 8px rgba(0, 255, 65, 0.15);
--ds-shadow-elevated: 0 0 16px rgba(0, 255, 65, 0.2);
--ds-border-weight: 1px;
--ds-border-style: solid;
/* vectorsight family tokens */
--vs-font-mono: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
--vs-font-display: "Inter", "Helvetica Neue", ui-sans-serif, sans-serif;
--vs-mesh-green: #00ff41;
--vs-mesh-green-dim: rgba(0, 255, 65, 0.5);
--vs-mesh-green-faint: rgba(0, 255, 65, 0.15);
--vs-focal: #c8ff00;
--vs-focal-glow: rgba(200, 255, 0, 0.25);
--vs-scanline: rgba(0, 255, 65, 0.12);
--vs-text-bright: #ffffff;
--vs-incident-amber: #ffaa00;
--vs-incident-red: #ff3333;
}
@theme inline {
--font-sans: var(--ds-font-body);
--font-mono: var(--vs-font-mono);
--font-display: var(--ds-font-display);
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-signal: var(--vs-mesh-green);
--color-signal-faint: var(--vs-mesh-green-faint);
--color-caution: var(--vs-incident-amber);
--radius-sm: var(--ds-radius-sm);
--radius-md: var(--ds-radius-md);
--radius-lg: var(--ds-radius-lg);
--radius-xl: var(--ds-radius-lg);
--shadow-card: var(--ds-shadow-card);
--shadow-elevated: var(--ds-shadow-elevated);
}
@layer base {
* {
border-color: var(--color-border);
}
html {
color-scheme: dark;
}
body {
margin: 0;
min-height: 100svh;
background-color: var(--color-background);
color: var(--color-foreground);
font-family: var(--font-sans);
-webkit-font-smoothing: antialiased;
}
::selection {
background: var(--vs-focal);
color: var(--primary-foreground);
}
:focus-visible {
outline: 2px solid var(--color-ring);
outline-offset: 2px;
}
}
@layer components {
/* Scanline ground: the family's signature wireframe field. */
.vs-scanfield {
background-image: repeating-linear-gradient(
to bottom,
var(--vs-scanline) 0px,
var(--vs-scanline) 1px,
transparent 1px,
transparent 5px
);
}
/* Single-pixel mesh divider between console sections. */
.vs-rule {
height: var(--ds-border-weight);
background: linear-gradient(to right, var(--vs-mesh-green), transparent);
opacity: 0.5;
}
.vs-glow {
text-shadow: 0 0 10px var(--vs-focal-glow);
}
.vs-eyebrow {
font-size: 0.6875rem;
font-weight: 500;
letter-spacing: 0.22em;
text-transform: uppercase;
color: var(--vs-focal);
}
}
`;
}
function utilsSource() {
return `import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
`;
}
/**
* Theme adapter: the single switch point between approved registry items.
* Product components consume semantic tokens only and never read these names.
*/
function themeAdapterSource() {
const switchable = DSR_THEME.switchableItems.map((name) => " '" + name + "'").join(',\n');
return provenanceHeader('/*', ' *', ' */') + `
export const REGISTRY_ITEMS = [
${switchable},
] as const;
export type RegistryItem = (typeof REGISTRY_ITEMS)[number];
/** The item whose payload is currently vendored into src/app.css. */
export const ACTIVE_REGISTRY_ITEM: RegistryItem = '${DSR_THEME.item}';
export const ACTIVE_REGISTRY_VERSION = '${DSR_THEME.version}';
/**
* Swap the active item by re-pulling its payload and updating both
* ACTIVE_REGISTRY_ITEM above and activeItem in design-system.registry.json:
*
* npx shadcn@latest add @design-system/<item>
*/
export function registryInstallCommand(item: RegistryItem): string {
return 'npx shadcn@latest add @design-system/' + item;
}
`;
}
function componentsJsonSource() {
const config = {
$schema: 'https://ui.shadcn.com/schema.json',
style: 'new-york',
rsc: false,
tsx: true,
tailwind: {
config: '',
css: 'src/app.css',
baseColor: 'neutral',
cssVariables: true,
prefix: '',
},
aliases: {
components: '@/components',
ui: '@/components/ui',
lib: '@/lib',
utils: '@/lib/utils',
hooks: '@/hooks',
},
iconLibrary: 'lucide',
registries: {
'@design-system': DSR_THEME.registryUrl + '/{name}.json',
},
};
return JSON.stringify(config, null, 2) + '\n';
}
function designSystemManifestSource({ installedAt }) {
const manifest = {
$schema: 'https://design-system-registry.local/schemas/design-system.registry.schema.json',
manifestVersion: 1,
upstream: {
name: 'design-system-registry',
registryUrl: DSR_THEME.registryUrl,
sourceRepo: DSR_THEME.sourceRepo,
},
activeItem: {
name: DSR_THEME.item,
version: DSR_THEME.version,
payloadUrl: DSR_THEME.payloadUrl,
installCommand: DSR_THEME.installCommand,
installedAt,
provenance:
'Payload vendored into src/app.css by the spaps CLI scaffolder; values match ' +
DSR_THEME.sourcePayload +
' at meta.registry.version ' +
DSR_THEME.version +
'.',
},
adapter: {
family: 'web-shadcn-theme',
path: 'src/design-system/theme-adapter.ts',
tokenProjection: 'source',
switchableItems: DSR_THEME.switchableItems,
surfaces: [
{
route: '/',
role: 'authentication reference console',
proofMethod: 'visual-check',
},
],
notes:
'Generated by `spaps create --template react`. The page composes shadcn semantic tokens only; no local palette, radius scale, or shadow system.',
},
verification: {
command: 'npm run typecheck && npm run build',
visualChecks: ['authentication reference console at http://localhost:5173'],
},
driftPolicy: {
updateMode: 'manual',
forkAllowed: false,
},
};
return JSON.stringify(manifest, null, 2) + '\n';
}
/* ------------------------------------------------------------------ */
/* shadcn primitives (upstream shadcn/ui shapes, driven by DSR tokens) */
/* ------------------------------------------------------------------ */
function buttonSource() {
return `import * as React from 'react';
import { cva, type VariantProps } from 'class-variance-authority';
import { cn } from '@/lib/utils';
const buttonVariants = cva(
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-xs font-medium uppercase tracking-[0.12em] transition-[background,box-shadow,color] disabled:pointer-events-none disabled:opacity-40',
{
variants: {
variant: {
default:
'bg-primary text-primary-foreground shadow-[0_0_12px_var(--vs-focal-glow)] hover:brightness-110',
outline:
'border border-border bg-transparent text-foreground hover:bg-signal-faint hover:border-primary',
ghost: 'bg-transparent text-muted-foreground hover:text-foreground hover:bg-signal-faint',
destructive: 'bg-destructive text-destructive-foreground hover:brightness-110',
},
size: {
default: 'h-10 px-4',
sm: 'h-8 px-3 text-[0.6875rem]',
lg: 'h-11 px-6',
},
},
defaultVariants: { variant: 'outline', size: 'default' },
}
);
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {}
export function Button({ className, variant, size, ...props }: ButtonProps) {
return <button className={cn(buttonVariants({ variant, size }), className)} {...props} />;
}
export { buttonVariants };
`;
}
function cardSource() {
return `import * as React from 'react';
import { cn } from '@/lib/utils';
type DivProps = React.HTMLAttributes<HTMLDivElement>;
export function Card({ className, ...props }: DivProps) {
return (
<div
className={cn(
'flex flex-col gap-4 rounded-md border border-border bg-card p-5 text-card-foreground shadow-card',
className
)}
{...props}
/>
);
}
export function CardHeader({ className, ...props }: DivProps) {
return <div className={cn('flex flex-col gap-1', className)} {...props} />;
}
export function CardTitle({ className, ...props }: DivProps) {
return (
<h2
className={cn('text-sm font-medium uppercase tracking-[0.18em] text-foreground', className)}
{...props}
/>
);
}
export function CardDescription({ className, ...props }: DivProps) {
return <p className={cn('text-xs leading-relaxed text-muted-foreground', className)} {...props} />;
}
export function CardContent({ className, ...props }: DivProps) {
return <div className={cn('flex flex-col gap-3', className)} {...props} />;
}
export function CardFooter({ className, ...props }: DivProps) {
return <div className={cn('flex flex-wrap gap-2', className)} {...props} />;
}
`;
}
function fieldSource() {
return `import * as React from 'react';
import { cn } from '@/lib/utils';
export function FieldGroup({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
return <div className={cn('flex flex-col gap-3', className)} {...props} />;
}
export function Field({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
return <div className={cn('flex flex-col gap-1.5', className)} {...props} />;
}
export function FieldLabel({ className, ...props }: React.LabelHTMLAttributes<HTMLLabelElement>) {
return (
<label
className={cn(
'text-[0.6875rem] font-medium uppercase tracking-[0.18em] text-muted-foreground',
className
)}
{...props}
/>
);
}
export function FieldDescription({ className, ...props }: React.HTMLAttributes<HTMLParagraphElement>) {
return <p className={cn('text-xs leading-relaxed text-muted-foreground', className)} {...props} />;
}
`;
}
function inputSource() {
return `import * as React from 'react';
import { cn } from '@/lib/utils';
const control =
'w-full rounded-sm border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus-visible:border-ring disabled:opacity-40';
export function Input({ className, ...props }: React.InputHTMLAttributes<HTMLInputElement>) {
return <input className={cn(control, 'h-10', className)} {...props} />;
}
export function Textarea({ className, ...props }: React.TextareaHTMLAttributes<HTMLTextAreaElement>) {
return <textarea className={cn(control, 'min-h-20 resize-y font-mono text-xs', className)} {...props} />;
}
export function Select({ className, ...props }: React.SelectHTMLAttributes<HTMLSelectElement>) {
return <select className={cn(control, 'h-10', className)} {...props} />;
}
`;
}
function badgeSource() {
return `import * as React from 'react';
import { cva, type VariantProps } from 'class-variance-authority';
import { cn } from '@/lib/utils';
const badgeVariants = cva(
'inline-flex items-center gap-1.5 rounded-sm border px-2 py-0.5 text-[0.6875rem] uppercase tracking-[0.14em]',
{
variants: {
variant: {
default: 'border-border bg-signal-faint text-foreground',
muted: 'border-border/40 bg-transparent text-muted-foreground',
focal: 'border-primary bg-transparent text-primary',
danger: 'border-destructive bg-transparent text-destructive',
},
},
defaultVariants: { variant: 'default' },
}
);
export interface BadgeProps
extends React.HTMLAttributes<HTMLSpanElement>,
VariantProps<typeof badgeVariants> {}
export function Badge({ className, variant, ...props }: BadgeProps) {
return <span className={cn(badgeVariants({ variant }), className)} {...props} />;
}
`;
}
module.exports = {
DSR_THEME,
DSR_DEPENDENCIES,
DSR_DEV_DEPENDENCIES,
reactStylesSource,
utilsSource,
themeAdapterSource,
componentsJsonSource,
designSystemManifestSource,
uiPrimitiveSources: () => ({
'src/components/ui/badge.tsx': badgeSource(),
'src/components/ui/button.tsx': buttonSource(),
'src/components/ui/card.tsx': cardSource(),
'src/components/ui/field.tsx': fieldSource(),
'src/components/ui/input.tsx': inputSource(),
}),
};