Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
744a9eb
refactor(configurator): de-obfuscate codec.ts internal names (SL-016)
claude Jul 2, 2026
c0505f9
fix(configurator): surface save failures instead of silently revertin…
claude Jul 2, 2026
eb88ede
test(configurator): start closing the interactive-layer coverage gap …
claude Jul 2, 2026
6004c90
refactor(scripts): dedupe generator parsing helpers into scripts/lib/…
claude Jul 2, 2026
12fa7fb
test: move selector-coverage check off Playwright onto node:test (SL-…
claude Jul 2, 2026
c839ae9
chore(configurator): remove unused motion dependency (SL-021)
claude Jul 2, 2026
902a161
docs(core): clean up core css comments (SL-001..005)
claude Jul 2, 2026
161f626
fix(configurator,scripts): address CodeRabbit review on PR 474
claude Jul 2, 2026
c6cdb3d
docs(core): replace hardcoded line-number citation in SL-001 comment
claude Jul 2, 2026
0b40267
chore: restore badges/badge-optimal.json accidentally deleted by prio…
claude Jul 2, 2026
5f1c4ae
docs(tests): docs and test hygiene remainder (SL-014, 028, 031, 032, …
claude Jul 2, 2026
c19b014
refactor(scripts): build script hardening (SL-006, 008, 009, 010, 011…
claude Jul 2, 2026
d476800
docs: fix two CLAUDE.md inaccuracies flagged by Qodo review on PR 476
claude Jul 2, 2026
62067e2
refactor(configurator): type codec.ts and its call sites, document sh…
claude Jul 2, 2026
2af608f
fix(configurator): stop advertising an ignored sanitize option on sha…
claude Jul 2, 2026
23c5327
refactor(configurator): shape-guard localStorage reads, migrate lucid…
claude Jul 2, 2026
04ab996
perf(configurator): rAF-coalesce preview iframe writes during rapid o…
claude Jul 2, 2026
0515efa
fix(configurator): remove redundant previewVersion bumps and skip spl…
claude Jul 2, 2026
04f2fc5
Merge pull request #475 from codeslash-dev/claude/audit-pr1-css-cleanup
jackgranatowski Jul 2, 2026
45a048d
Merge pull request #476 from codeslash-dev/claude/audit-pr2-docs-test…
jackgranatowski Jul 2, 2026
6310621
Merge pull request #477 from codeslash-dev/claude/audit-pr3-scripts-h…
jackgranatowski Jul 2, 2026
a5975d3
Merge pull request #478 from codeslash-dev/claude/audit-pr4-codec-types
jackgranatowski Jul 2, 2026
92f2a4c
Merge pull request #480 from codeslash-dev/claude/audit-pr6-preview-d…
jackgranatowski Jul 2, 2026
87f6114
Merge integration branch into PR5 (resolve conflicts with PR4/PR6)
claude Jul 2, 2026
b5e7e76
Merge pull request #479 from codeslash-dev/claude/audit-pr5-configura…
jackgranatowski Jul 2, 2026
5b14839
test(configurator): cover previewResolver.svelte.ts and StudioHeader'…
claude Jul 2, 2026
156e421
fix(configurator): clean up leaked test iframes and decouple canvas t…
claude Jul 2, 2026
2dcc34f
Merge pull request #481 from codeslash-dev/claude/audit-pr7-test-cove…
jackgranatowski Jul 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,21 @@ requires a rebuild+redeploy, not just a file edit.
| `npm run version-sync` | Sync all version references to root `package.json` |
| `npm run check:version` | Verify all version references match (CI gate — run before every commit that touches versions) |
| `npm run check:llm-guide` | Verify `docs/llm-guide.md` only references live tokens (CI gate) |
| `npm run check:macros` | Verify `.sf-*` macro classes match `docs/macros.md` (not currently wired into CI — run manually before committing macro changes) |
| `npm run check:registry` | Verify `token-registry.json` is in sync with source (CI gate) |
| `npm run audit:check` | Verify `docs/registry.json` matches source without writing (CI gate) |
| `npm run lint:css` | Lint all CSS source with stylelint (CI gate) |
| `npm run lint:css:fix` | Lint CSS source and auto-fix violations |
| `npm run docs` | Regenerate docs and sync configurator API index |
| `npm run docs:tokens` | Regenerate `docs/tokens.md` only |
| `npm run docs:index` | Regenerate `docs/token-index.md` + `.json` only |
| `npm run docs:api` | Regenerate `docs/api-index.md` + `.json` only |
| `npm run docs:classes` | Regenerate `docs/classes.md` only |
| `npm run gen:registry` | Regenerate `token-registry.json` (stable id assignments) |
| `npm run configurator:sync` | Push `docs/api-index.json` → `configurator/src/data/api-index.generated.json` |
| `npm run audit` | Audit CSS tokens for consistency |
| `npm run audit` | Audit CSS tokens for consistency, writing `docs/registry.json` |
| `npm run watch` | Rebuild CSS bundles on file change (dev watch mode) |
| `npm run test:unit` | Run the Node `--test` unit suite only, without the Playwright e2e build. Some tests read from `badges/` — run `npm run build` first on a clean checkout (CI instead downloads the `badges` artifact from the `build` job before this step) |
| `npm test` | Full suite: build → unit → Playwright e2e |

## Release process
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ and `badges/` must be rebuilt and committed.
## Tests & demo coverage

- Any new `.sf-*` or `.is-*` class in `core/*.css` must appear in `docs/demo.html`
(`tests/coverage.spec.js`).
(`tests/coverage.test.js`).
- Any new token must resolve in both themes (`tests/tokens.spec.js`); tokens whose
value is `inherit` go in that file's `EXPECTED_EMPTY` allowlist.
- Add a focused assertion when you fix a bug.
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ Use a pre-built bundle (see [Releases](https://github.com/codeslash-dev/SLASHED/
```

À la carte is also supported. When wiring up individual files, `core/layers.css`
must load **first**. `optional/legacy.css` is not bundled by default — add it
must load **first** — it declares the `@layer` order once, and that order (not
`<link>` order) controls the cascade, so the snippet below simply mirrors it
for readability. `optional/legacy.css` is not bundled by default — add it
explicitly if you need back-compat shims and load it **last**:

```html
Expand All @@ -44,10 +46,10 @@ explicitly if you need back-compat shims and load it **last**:
<link rel="stylesheet" href="core/tokens.macros.css">
<link rel="stylesheet" href="core/reset.css">
<link rel="stylesheet" href="core/base.css">
<link rel="stylesheet" href="core/themes.css">
<link rel="stylesheet" href="core/layout.css">
<link rel="stylesheet" href="core/macros.css">
<link rel="stylesheet" href="core/states.css">
<link rel="stylesheet" href="core/themes.css">
<link rel="stylesheet" href="core/motion.css">
<link rel="stylesheet" href="core/accessibility.css">
<link rel="stylesheet" href="core/print.css">
Expand Down
96 changes: 14 additions & 82 deletions configurator/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions configurator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@
"test:e2e": "playwright test"
},
"dependencies": {
"fflate": "^0.8.3",
"lucide-svelte": "^0.468.0",
"motion": "^12.23.24"
"@lucide/svelte": "^1.23.0",
"fflate": "^0.8.3"
},
"devDependencies": {
"@playwright/test": "^1.60.0",
Expand Down
16 changes: 8 additions & 8 deletions configurator/src/App.svelte
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
<script lang="ts">
import { onMount, untrack } from 'svelte';
import { SlidersHorizontal, Eye, RotateCcw } from 'lucide-svelte';
import type { PreviewTemplate, SlashedToken } from './types';
import { SlidersHorizontal, Eye, RotateCcw } from '@lucide/svelte';
import type { PreviewTemplate, SlashedToken, ApiIndex } from './types';
import StudioHeader from './components/shell/StudioHeader.svelte';
import SidebarNav from './components/shell/SidebarNav.svelte';
import StatusBar from './components/shell/StatusBar.svelte';
import PreviewPanel from './components/shell/PreviewPanel.svelte';
import DomainPanel from './components/DomainPanel.svelte';
import { fa } from './lib/codec';
import { generateCSS } from './lib/codec';
import { loadInitialOverrides, injectLivePreview, saveOverrides, hasWpBoot } from './lib/persistence';
import { domainOf } from './lib/domains';
import tokensRaw from './data/api-index.generated.json';
import CommandPalette from './components/CommandPalette.svelte';

const ALL_TOKENS = ((tokensRaw as any).tokens ?? tokensRaw) as SlashedToken[];
const ALL_TOKENS = ((tokensRaw as ApiIndex).tokens ?? tokensRaw) as SlashedToken[];

const DOMAIN_LABELS: Record<string, string> = {
home: "Home", colors: "Colors", typography: "Typography", spacing: "Spacing",
Expand Down Expand Up @@ -79,7 +79,7 @@

// Save state — hasPendingChanges is derived so undo/redo update it automatically.
let lastSavedOverrides = $state<Record<string, string>>(untrack(() => ({ ...overrides })));
let saveState = $state<'idle' | 'saving' | 'saved'>('idle');
let saveState = $state<'idle' | 'saving' | 'saved' | 'error'>('idle');
let hasPendingChanges = $derived(!shallowEq(overrides, lastSavedOverrides));
let saveStateTimer: ReturnType<typeof setTimeout> | null = null;

Expand All @@ -92,7 +92,7 @@
if (!shallowEq(prev, next)) {
past = [...past.slice(-49), prev];
future = [];
if (saveState === 'saved') saveState = 'idle';
if (saveState === 'saved' || saveState === 'error') saveState = 'idle';
}
overrides = next;
}
Expand All @@ -117,7 +117,7 @@
}
} catch (err) {
console.warn('slashed: save failed', err);
saveState = 'idle';
saveState = 'error';
}
}

Expand Down Expand Up @@ -219,7 +219,7 @@
}

function handleExport() {
const css = fa(overrides, { mode: "layer", banner: true });
const css = generateCSS(overrides, { mode: "layer", banner: true });
const blob = new Blob([css], { type: "text/css" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
Expand Down
2 changes: 1 addition & 1 deletion configurator/src/components/DomainPanel.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { SlidersHorizontal, List } from 'lucide-svelte';
import { SlidersHorizontal, List } from '@lucide/svelte';
import type { SlashedToken } from '../types';
import { DOMAIN_PATTERNS, domainOf } from '../lib/domains';
import HomePanel from './panels/HomePanel.svelte';
Expand Down
9 changes: 5 additions & 4 deletions configurator/src/components/panels/CheatsheetPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
<script lang="ts">
import classesData from '../../data/classes.generated.json';
import tokensData from '../../data/api-index.generated.json';
import { Copy, Check } from 'lucide-svelte';
import { Copy, Check } from '@lucide/svelte';
import type { SlashedClass } from '../../types';

const classes = classesData.classes;
const tokens = tokensData.tokens.filter((t: any) => t.tier === 'PUBLIC' || t.tier === 'PUBLIC-ADVANCED');
const tokens = tokensData.tokens.filter((t) => t.tier === 'PUBLIC' || t.tier === 'PUBLIC-ADVANCED');

let query = $state('');
let tab = $state<'classes' | 'tokens'>('classes');
Expand All @@ -17,7 +18,7 @@
let filteredClasses = $derived(() => {
const q = query.trim().toLowerCase();
if (!q) return classes;
return classes.filter((c: any) =>
return classes.filter((c: SlashedClass) =>
c.name.toLowerCase().includes(q) ||
c.selector?.toLowerCase().includes(q) ||
c.description?.toLowerCase().includes(q) ||
Expand All @@ -28,7 +29,7 @@
let filteredTokens = $derived(() => {
const q = query.trim().toLowerCase();
if (!q) return tokens;
return tokens.filter((t: any) =>
return tokens.filter((t) =>
t.name.toLowerCase().includes(q) ||
t.description?.toLowerCase().includes(q) ||
t.group?.toLowerCase().includes(q) ||
Expand Down
8 changes: 4 additions & 4 deletions configurator/src/components/panels/ExportPanel.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import { Check, Copy, Download, Link } from 'lucide-svelte';
import { fa, qa } from '../../lib/codec';
import { Check, Copy, Download, Link } from '@lucide/svelte';
import { generateCSS, buildShareUrl } from '../../lib/codec';

let { overrides }: {
overrides: Record<string, string>;
Expand All @@ -10,7 +10,7 @@
let copied = $state(false);
let copiedLink = $state(false);

let css = $derived(fa(overrides, { mode: outputMode, banner: true }));
let css = $derived(generateCSS(overrides, { mode: outputMode, banner: true }));
let count = $derived(Object.keys(overrides).length);

async function handleCopy() {
Expand All @@ -23,7 +23,7 @@

async function handleCopyLink() {
try {
const url = qa(overrides);
const url = buildShareUrl(overrides);
await navigator.clipboard.writeText(url);
copiedLink = true;
setTimeout(() => { copiedLink = false; }, 2000);
Expand Down
2 changes: 1 addition & 1 deletion configurator/src/components/panels/HomePanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import {
Sparkles, Palette, Type, Ruler, Layout, Square, Layers, Zap,
Puzzle, Blocks, SwatchBook, ShieldCheck, Package, BookOpen, Save,
} from 'lucide-svelte';
} from '@lucide/svelte';
import type { SavedSlot } from '../../types';
import { listSavedThemes, saveTheme } from '../../lib/savedThemes';

Expand Down
2 changes: 1 addition & 1 deletion configurator/src/components/panels/ThemesPanel.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { Save, Trash2, Check } from 'lucide-svelte';
import { Save, Trash2, Check } from '@lucide/svelte';
import type { SavedSlot } from '../../types';
import { listSavedThemes, saveTheme, deleteTheme } from '../../lib/savedThemes';

Expand Down
Loading