# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
> **Branch note (`active-uix`):** the legacy layers `src/lib/`, `src/uix/terra/`,
> `src/uix/air/` and the old `src/routes/` test tree were removed during the
> UIX refactor. The new ecosystem lives in `src/arts/`, `src/libs/`, `src/svrs/`,
> and `src/uix/{active-uix,soma,sema,eidos,morfo}`. Demos are being re-authored
> under `web/routes/` from scratch.
## Build / Test Commands
```bash
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
npm run dev # Start dev server (routes resolve from web/routes)
npm run build # Production build (static via adapter-static)
npm run test # Run all tests once
npm run test:unit # Run tests in watch mode
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
npx vitest run src/uix/morfo/compile.test.ts # Run a single test file
npx vitest run -t "describe name" # Run tests matching a pattern
npm run check # Type check with svelte-check
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
npm run lint # Check formatting (Prettier)
npm run format # Auto-format
```
## Code Style
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
- Tabs for indentation, single quotes, no trailing commas, 100 char print width (Prettier).
- Comments in **English** . (Some legacy Spanish comments remain — don't add new ones.)
- Svelte 5 runes mode is enforced globally (`svelte.config.js` `dynamicCompileOptions` ).
- DOM event handlers: lowercase (`onclick`, `onfocus` ). User callbacks: camelCase (`onComplete`, `onInteractOutside` ).
- State: `$state()` without `#` . Derived: `readonly x = $derived.by(...)` .
## Path Aliases
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
Aliases are kept in sync between `svelte.config.js` and `vite.config.ts` . Source
of truth is `vite.config.ts` (single `aliases` const reused by both top-level
resolve and the server-test project).
| Alias | Target |
| --- | --- |
| `@` | `src/` |
| `$active-app` , `$adom` , `$auth` , `$bus` , `$cache` , `$connection` , `$format` , `$frontend` , `$http` , `$lang` , `$logger` , `$orca` , `$perm` , `$prefs` , `$session` , `$sium` , `$storage` , `$timer` | `src/arts/{name}` |
| `$libs` , `$locale` , `$reactive` | `src/libs` , `src/libs/locale` , `src/libs/reactive` |
| `$svrs` | `src/svrs/` |
| `$uix` , `$active-uix` , `$soma` | `src/uix` , `src/uix/active-uix` , `src/uix/soma` |
## Vitest Two-Project Structure
`vite.config.ts` defines two test projects:
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
- **client**: Browser tests via Playwright for `*.svelte.{test,spec}.{js,ts}` .
- **server**: Node environment for `*.{test,spec}.{js,ts}` (excludes svelte tests).
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
## Architecture
The UIX is layered around a declarative contract (morfo) that the other layers
consume. Each consumer reads the morfo via `compileMorfo(morfo)` , never by
walking the raw declaration.
```
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
arts/ → runtime artifacts: active-app, adom, perm, prefs, ...
libs/ → pure helpers (zero-dep): reactive, days, dom, locale, ...
svrs/ → server-authoritative engines
uix/morfo → declarative contract: parts, data-attrs, ARIA, keyboard,
events with semantic family/intent. Compiler at compile.ts
emits CompiledMorfo (cached by WeakMap).
uix/sema → semantic engine + channels (visual / sound / vibra).
The visual channel writes data-event* during a hold window.
State attrs (data-state, data-disabled, ...) are NEVER
touched by sema — they belong to the morfo runtime.
uix/soma → headless component layer. Each provider consumes morfo +
sema via `runtime.trigger(eventName)` which sequences:
prewrite → semantic.emit → handler → effect-driven state attrs.
uix/eidos → CSS layer that selects against the data-attrs the morfo
contract promises. lint.ts validates a CSS file against
compileMorfo(morfo).contracts.cssSelectors.
uix/active-uix → composition root. Two boot modes:
- createActiveUix(options) — standalone (owns services)
- attachActiveUix(activeApp) — attach to external app
```
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
### morfo (`src/uix/morfo/`)
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
Single source of truth for a component. A `Morfo` declares:
- `parts[]` — kebab + archetype + `data` + `aria` + optional `keyboard`
- `events[]` — name + `target` partRef + `semantic` + optional `prewrite` + `commits`
- `focus` — initial / trap / return / restore (for overlay components)
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
`compileMorfo(morfo)` returns a `CompiledMorfo` with pre-resolved `AttrPlan[]` ,
`KeyboardPlan[]` , `ActionPlan[]` , and `contracts.cssSelectors` (the closed set
of selectors eidos is allowed to use). Cached by morfo identity.
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
### eidos linter
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
`scripts/eidos-lint.ts <component>` and `scripts/eidos-lint-all.ts` classify every
`[data-*]` selector in eidos CSS as morfo-backed / eidos-only / invalid. Use
this to detect drift between the morfo contract and the eidos rules.
## Key Conventions
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
- **Never modify the morfo declaration files** without updating the eidos
selectors and provider sources that depend on them.
- **Read before acting.** When told to read a file, read it. Don't paraphrase.
- **Verify before reporting done.** Run `npm run check` and the relevant
vitest scope. UI claims need a browser check; if you can't run a browser, say so.
- **No backward-compat shims** when relocating code. Update consumers and delete
the old path; don't leave a re-export.
- **No re-export façades** between layers (e.g. soma must not re-export dias —
consume `$libs/days` directly).
- **Provider naming**: child providers reference the parent as `provider` , never
`root` . The exported component is `<Xxx.Provider>` . `createAttrs` still uses
the part kebab `'provider'` internally.
- **Data-attr naming**: `data-{component}` (provider) and `data-{component}-{kebab}`
(sub-parts). Never `data-soma-*` . The compiler emits these via
`compiled.parts.attrs` ; runtime queries match exactly.
- **CSS token naming (eidos recipes)**: bare-prefixed by component, never
by layer. Public tokens: `--{component}-…` (e.g. `--dialog-content-bg` ,
`--toggle-radius-md` ). Internal recipe tokens: `--_{component}-…` .
Never `--eidos-…` , `--air-…` , `--terra-…` , `--soma-…` . Migrating
`air-` baselines means stripping the `air-` prefix, not replacing it.
- **DOM helpers**: `$adom` is the single public surface for DOM-related
functionality at component / soma level. It re-exports all of
`$libs/dom` wholesale, plus the reactive `createActiveDom` runtime
and stateful primitives (`BodyScrollLock`, `DOMContext` , `RovingFocusGroup` ).
Components and soma NEVER import from `$libs/dom` directly —
consume `$adom` . Only `arts/adom/*` (the implementation), `arts/frontend`
(peer service fallback), and tests of `$libs/dom` may reach into it.
This includes responsive types (`ResponsiveProp< T > `, `Breakpoint` ,
`Breakpoints` ) — they travel with the runtime, so they live in `$adom` .
- **Iframe / popup correctness**: when you have a `uix.dom` , prefer
`uix.dom.getDocument(node?)` and `uix.dom.getWindow(node?)` over the
bare functions of the same name. The instance methods respect the
active-dom's `targetWindow` ; the bare functions fall back to the
global `document` / `window` , which is wrong in iframe / popup /
happy-dom-test contexts.
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
## Critical Rules
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
- **NEVER delete files without explicit instruction** ("delete", "remove",
"borra", "elimina"). If ambiguous, ASK first.
- **NEVER create fake translators / mocked services** in tests for components.
Use real instances composed via `createActiveUix` or `attachActiveUix` .
- **NEVER skip hooks (`--no-verify`) or bypass signing** unless explicitly asked.
If a hook fails, fix the root cause.
- **`$reactive` survives, `$lib` does not.** The `$reactive` alias points to the
current `src/libs/reactive` ; the singular `$lib` alias was removed in the
cleanup phase and any code that resurfaces it is a regression.
docs: prune obsolete audits + studies, refresh remaining references
Deleted 60 obsolete documents that no longer reflect the active-uix
state:
- 47 per-component audit logs (*-audit.md, audit_N.md, AUDIT.md)
- 5 global soma audits (AUDIT_1, codex_audit, soma-audit-04-20/21,
audit-prompt template)
- 5 closed studies (soma/study, morfo/study, morfo/DESIGN, morfo/
PROVIDER_STUDY_2026-04-23, uix/CONTINUITY_2026-04-24)
- 2 superseded refactor proposals (refactor_claude, refactor_code)
- 1 stale bug log (form/BUG-onchange-onblur-hang — repro path
src/routes/test/sium/kitchen-sink no longer exists)
Updated the remaining operational references to drop dead links and
reflect the post-cleanup architecture:
- src/uix/README.md — rewritten links section, dropped pointers to
terra/air/CONTINUITY/refactor docs, updated adom/dom paths
- src/uix/active_architecture.md — header now dated 2026-05-08, lists
the major shifts since 2026-04-26 (provider inheritance dropped,
eidos in production, doctrina parte IV, sound eager-init); pendings
section reflects the eidos migration roadmap; "see also" purged of
deleted files
- src/uix/morfo/README.md — file tree updated (removed DESIGN/study,
added compile/runtime/PERMUTATION_RUNNER); see-also pruned
- src/uix/sema/README.md — SoundChannel section now describes the
eager-init pattern (constructor-time, not lazy); pointer to
sema-implementation-guide added
- src/uix/soma/README.md — drops terra/air mentions, declares the
actual dependency direction (eidos -> soma, not the reverse)
- src/uix/soma/SOMA_ARCHITECTURE.md — §15 rewritten as "Estado actual
y deuda histórica" reflecting Provider-inheritance-drop; demo path
updated to web/routes/
- src/uix/soma/COMPONENT_GUIDE.md — A23 dates section now points to
$libs/days (no external/dates façade); demo paths swapped from
/test/soma/* to web/routes/
- src/uix/morfo/PERMUTATION_RUNNER.md — paths swapped to web/routes/
with a relocation note
- CLAUDE.md — Refactor Documents section replaced with Reference
Documents pointing to per-layer READMEs
npm run check holds at baseline (39 pre-existing errors, none new).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
## Reference Documents
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
docs: prune obsolete audits + studies, refresh remaining references
Deleted 60 obsolete documents that no longer reflect the active-uix
state:
- 47 per-component audit logs (*-audit.md, audit_N.md, AUDIT.md)
- 5 global soma audits (AUDIT_1, codex_audit, soma-audit-04-20/21,
audit-prompt template)
- 5 closed studies (soma/study, morfo/study, morfo/DESIGN, morfo/
PROVIDER_STUDY_2026-04-23, uix/CONTINUITY_2026-04-24)
- 2 superseded refactor proposals (refactor_claude, refactor_code)
- 1 stale bug log (form/BUG-onchange-onblur-hang — repro path
src/routes/test/sium/kitchen-sink no longer exists)
Updated the remaining operational references to drop dead links and
reflect the post-cleanup architecture:
- src/uix/README.md — rewritten links section, dropped pointers to
terra/air/CONTINUITY/refactor docs, updated adom/dom paths
- src/uix/active_architecture.md — header now dated 2026-05-08, lists
the major shifts since 2026-04-26 (provider inheritance dropped,
eidos in production, doctrina parte IV, sound eager-init); pendings
section reflects the eidos migration roadmap; "see also" purged of
deleted files
- src/uix/morfo/README.md — file tree updated (removed DESIGN/study,
added compile/runtime/PERMUTATION_RUNNER); see-also pruned
- src/uix/sema/README.md — SoundChannel section now describes the
eager-init pattern (constructor-time, not lazy); pointer to
sema-implementation-guide added
- src/uix/soma/README.md — drops terra/air mentions, declares the
actual dependency direction (eidos -> soma, not the reverse)
- src/uix/soma/SOMA_ARCHITECTURE.md — §15 rewritten as "Estado actual
y deuda histórica" reflecting Provider-inheritance-drop; demo path
updated to web/routes/
- src/uix/soma/COMPONENT_GUIDE.md — A23 dates section now points to
$libs/days (no external/dates façade); demo paths swapped from
/test/soma/* to web/routes/
- src/uix/morfo/PERMUTATION_RUNNER.md — paths swapped to web/routes/
with a relocation note
- CLAUDE.md — Refactor Documents section replaced with Reference
Documents pointing to per-layer READMEs
npm run check holds at baseline (39 pre-existing errors, none new).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
Architecture overview and motivations: [`src/uix/active_architecture.md` ](src/uix/active_architecture.md ).
Per-layer references:
- [`src/uix/morfo/README.md` ](src/uix/morfo/README.md )
- [`src/uix/sema/README.md` ](src/uix/sema/README.md )
- [`src/uix/soma/SOMA_ARCHITECTURE.md` ](src/uix/soma/SOMA_ARCHITECTURE.md ) +
[`src/uix/soma/COMPONENT_GUIDE.md` ](src/uix/soma/COMPONENT_GUIDE.md )
- [`src/uix/eidos/README.md` ](src/uix/eidos/README.md ) +
[`src/uix/eidos/components/README.md` ](src/uix/eidos/components/README.md )
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
docs + switch: align active docs to canon, migrate switch to eidos wrapper
Phase 4 (docs alignment with the canonical guide):
- active_architecture.md — Dialog example refactored to the new event
shape (target inside semantic, explicit verb + sequence). Verbs
table grouped by family with the post-canon vocabulary (select/
toggle moved to commit, edit removed from handle, new verbs added).
Section 10 (Estado actual) updated to 2026-05-08 with current
progress: doctrina cerrada, eidos en producción, SoundChannel
eager-init, switch migrated, etc. "Para profundizar" §14 points at
the canonical guide.
- morfo/README.md — Step 5.5 added covering the doctrinal event
shape with all fields (semantic.family, .verb, .target, .sequence,
.intent) and the two naming shapes ({verb}-{variant} and
{family}-{verb}).
- sema/README.md — verbs section restructured to Record-by-family
matching the runtime; documents the verbs that moved between
families per the canon. Naming shapes section updated with both
forms and validateEventName signature.
- CLAUDE.md — "Session hand-off" rewritten with the post-canon
state. Pointer at GUIA_IMPLEMENTACION_SEMAUIX.md as the canonical
source. Pending list refreshed: switch is the immediate next
component, persistence/a11ySemantic/polymorphism deferred until
real consumers appear.
Switch migration to the eidos wrapper pattern:
- morfo/components/switch.ts — adds events: [{ commit-toggle }] with
the doctrinal shape (verb=toggle, sequence=post, intent fromProp
binding to the 4 supported intents). New data-* (data-color with
the 6-token Toggle/Switch subset, data-readonly, data-invalid,
data-required) and corresponding aria-*. scope expanded to
['soma', 'sema'].
- soma/components/switch/types.ts — adds intent, color, readonly,
invalid, aria-labelledby props with full JSDoc. Subset constrained
per guide §3.1 (Toggle/Switch row).
- soma/components/switch/switch-provider.svelte.ts — runtime-direct,
Field integration via FieldProvider.get(), isDisabled/isReadonly/
isRequired/isInvalid OR-merge derivations, intent ↔ color
resolution (intent wins when evaluative), runtime.trigger(
'commit-toggle') in onclick.
- soma/components/switch/components/switch.svelte — wires the new
props through bindProps.
- eidos/components/switch/{switch.css, switch.svelte, types.ts,
index.ts, README.md} — full subdirectory pattern, mirroring
toggle. Recipe drops legacy success/warning/danger/info selectors;
declares the 6 doctrinal data-color values directly. Wrapper
auto-renders Switch.Thumb inside the track and exposes an optional
`thumb` snippet for in-thumb glyphs.
- eidos/components/switch.css (legacy flat) deleted; eidos/index.css
updated to import the subdirectory recipe.
- web/routes/switch/+page.svelte — interactive testbed with all soma
props as live controls + tabs (Live, Soma, Morfo, Sema, Eidos,
Notes). Mirrors toggle's structure.
npm run check holds at the 39-error baseline. Tests 217/217 green.
Pending:
- Migrate collapsible / dialog / drawer / popover / toast / avatar
to the eidos wrapper pattern.
- Persistence + holds-by-intent — defer until first signal.warn /
signal.alert consumer.
- a11ySemantic + polymorphic events — defer until concrete need.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
The canonical guide for sema vocabulary, morfo event shape, color
tokens, persistence and a11ySemantic lives in
[`src/docs/GUIA_IMPLEMENTACION_SEMAUIX.md` ](src/docs/GUIA_IMPLEMENTACION_SEMAUIX.md ).
That document is authoritative — when in doubt about families, intents,
verbs, color subsets per component, or holds, that's the source.
## Sema cascade selectors must use the typed builder
Cascade rules in `src/uix/sema/components/*.ts` MUST construct their
`selector` via `semaSelector(morfo, partKebab, matchers?)` from
`$uix/morfo` . **Never hand-write selector strings** that target morfo-
emitted attrs (`[data-{component}]`, `[data-{component}-{part}]` ,
`[data-event="..."]` ). The helper:
- Compile-error if `partKebab` doesn't exist on `morfo.parts` .
- Compile-error if `matchers.eventName` doesn't match `morfo.events` .
- Type-checks `eventFamily` /`eventIntent` against the canonical sema
unions.
- Output is the same CSS string the cascade rule needs — zero runtime
cost beyond concatenation.
Hand-written selectors in cascade rules are an architecture violation:
when morfo renames a part or event, the strings go stale silently. The
helper wires the cascade to the morfo's contract so renames break at
the type level.
```ts
// good
import { semaSelector } from '$uix/morfo'
import { dialogMorfo } from '$uix/morfo/components/dialog'
{
selector: semaSelector(dialogMorfo, 'content', { eventFamily: 'commit' }),
haptic: { kind: 'tap' }
}
// bad — string drifts silently if morfo renames
{
selector: '[data-dialog-content][data-event-family="commit"]',
haptic: { kind: 'tap' }
}
```
## Sema: intent policy per family
Per book canon there are **8 families** , encoded in `SEMA_FAMILY_POLICY` at
`src/uix/sema/types.ts` . Each family declares two independent axes:
```ts
{
contact: { intentRequirement: 'optional', intentGuidance: 'discouraged' },
commit: { intentRequirement: 'required', intentGuidance: 'expected' },
signal: { intentRequirement: 'required', intentGuidance: 'expected' },
handle: { intentRequirement: 'optional', intentGuidance: 'contextual' },
emerge: { intentRequirement: 'optional', intentGuidance: 'contextual' },
shift: { intentRequirement: 'optional', intentGuidance: 'contextual' },
sustain: { intentRequirement: 'optional', intentGuidance: 'contextual' },
delegate: { intentRequirement: 'optional', intentGuidance: 'contextual' }
}
```
- **`intentRequirement`** (`'required' | 'optional' | 'forbidden'`) — compile-time gate. `required` → `intent` REQUIRED in `MorfoEventSemantic` (discriminated union). `forbidden` is reserved for future use (no family uses it today).
- **`intentGuidance`** (`'expected' | 'contextual' | 'discouraged'`) — doctrinal hint, not type-enforced. Drives lint warnings and editor tooltips.
Type derivation: `SemaEvent` and `MorfoEventSemantic` discriminate over `intentRequirement` . Editing the const reshapes the discriminated union.
Runtime enforcement: `validateSemaEvent` throws when an `intentRequirement: 'required'` family declares an event without intent. Optional families pass silently.
**`delegate`** is the 8th family per book cap. 29 — reparto de iniciativa entre usuario y sistema. Structural; carries no intent of its own. Active channels empty (delegate composes with sustain / signal / commit for perceptual layering, doesn't own a base signature).
The earlier flat `intentPolicy: 'allowed' | 'expected' | 'optional'` mixed type-requirement with doctrinal guidance. The split was applied in commit `00f0b740` .
## Sema: open channel registry + flat CSS-style cascade
The perceptual layer is **NOT 4-channel-closed** . The framework ships 5
canonical channels (`motion`, `sound` , `color` , `presence` , `haptic` )
declared in `SemaChannelSignatures` . Apps add more via TypeScript
declaration merging.
**The semantic tokens are `data-event-*` **: the engine stamps `data-event` ,
`data-event-family` , `data-event-intent` , `data-event-phase` , `data-event-id`
on `signal.target` BEFORE the cascade resolves. Cascade rules use CSS
selectors that target those tokens directly — same surface that eidos CSS
already reads. Engine owns stamp/unstamp; VisualChannel only owns the hold.
Cascade rules are **flat** (no `overrides: { eventLabel: ... }` middle
layer): a single selector + per-channel deltas, like a CSS rule.
```ts
{
selector: '[data-dialog-content][data-event-intent="threat"]',
sound: { sampleUrl: '/sounds/dialog-fail.wav' },
haptic: { kind: 'error', pattern: [50, 80, 50, 80, 50] }
}
```
Resolution cascade (each layer overrides the previous):
```
1. SEMA_MAP.families[F].base — per-channel signatures
2. SEMA_MAP.intents[I].deltas — valenced families only;
numbers ADD (modificadores)
3. signal.overrides + signal.channels — per-event morfo overrides;
numbers REPLACE
4. engineOpts.overrides.runtime — path-based globals; REPLACE
5a. engineOpts.components[].cascade — per-component packs
(sema/components/{name}.ts)
5b. engineOpts.overrides.cascade — app-level rules; appended
AFTER packs so they win
on equal specificity
```
**Per-component packs live in `src/uix/sema/components/{name}.ts` ** —
symmetric to morfo / soma / eidos. Each exports a `Sema` with
`cascade` rules + optional `preloadSamples` (WAVs decoded at boot).
**Override semantics — numbers**:
- intent.deltas (capa 2): numbers ADD (modificadores compositivos).
- overrides (capas 4, 5, 6): numbers REPLACE (`color: red`, not "add red").
- Use `{ op: 'add' }` / `{ op: 'multiply' }` / `{ op: 'replace' }` for
explicit semantics either way.
**`intent.deltas` owns the perceptual signature of the intent** — the
sound primitives `pitch` , `gain` , `contour` (and the haptic `intensity`
when shaped per-intent) come from capa 2. **Cascade rules (capas 6a/6b)
MUST NOT override these primitives** — doing so flattens the perceptual
difference between `risk` / `threat` / `loss` (or `affirm` / `fulfill` ).
Cascade rules add character (`haptic.kind`, `haptic.pattern` ,
`sound.sampleUrl` , `motion.easing` , `presence.backdrop` ) — not the
intent's evaluative profile. If a per-component cascade rule needs to
*shift* a numeric primitive (e.g. close-* in emerge goes descending),
use `{ op: 'add', value: -150 }` so it composes on top of the intent
rather than erasing it.
`HapticChannel` (V1, real — Vibration API) is opt-in via
`new EngineSemantic({ haptic: true })` . Sound and haptic both default
off because they have audible / tactile side effects.
Canonical sources: `src/uix/sema/sema-map.ts` (SEMA_MAP value +
SemaChannelSignatures registry + Sema), `src/uix/sema/resolver.ts`
(cascade implementation + CSS specificity), `src/uix/sema/stamp.ts`
(stamp/unstamp), `src/uix/sema/components/*.ts` (per-component packs),
`src/uix/sema/README.md` .
## Eidos drift defense — types over lint
Selector drift between morfo's emitted attrs and the layers that style /
react to them (eidos CSS, sema cascade) is defended **at compile time
via typed builders**, not at lint time.
- **Sema cascade rules** (`sema/components/*.ts`) consume
`semaSelector(morfo, partKebab, matchers?)` from `$uix/morfo` . Renames
in morfo break the cascade at type-check time. See "Sema cascade
selectors must use the typed builder" above.
- **Eidos plain `.css` recipes** are still raw CSS today — there is no
CSS-side typed builder. For those, `scripts/eidos-lint.ts` remains as
an **opt-in safety net** that classifies each `[data-*]` selector as
`morfo-backed` / `eidos-only` / `invalid` . It is not the architectural
contract; the contract is the morfo declaration.
Rule: when a layer can consume the morfo via TypeScript (anything in
`.ts` / `.svelte` ), it MUST use the typed builder. Lint is for the
remaining surface (plain CSS recipes) until those gain a builder of
their own. Hand-written morfo-targeting selector strings in TypeScript
files are an architecture violation, not a lint warning.
## Session hand-off — 2026-05-27 (persistence + a11ySemantic + polymorphic)
Sprint cerrando los 3 ítems diferidos del hand-off 2026-05-08: persistence + holds-by-intent (libro §6), a11ySemantic per event (libro §9), polymorphic events (libro §5.3). Detalle completo en `src/docs/LIBRO_VARIACIONES_Y_EXTENSIONES.md` D.9 / D.10 / D.11.
**Persistence (libro §6.1)** — separa `hold` (duración perceptible mínima) de `persistence` (lifecycle real):
- Nuevo tipo `SignalPersistence = 'transient' | 'untilAction' | 'untilFix' | 'stateBound'` en `src/uix/sema/types.ts` , propagado a `SemanticSignal` , `MorfoEventSemantic` y `TriggerOptions` .
- Tabla canónica `SEMA_HOLDS_BY_INTENT` en `src/uix/sema/holds.ts` (referencia, NO auto-aplicada — default conservador `'transient'` ).
- `EngineSemantic.emit()` ahora devuelve `Promise<string>` (el id). Para `persistence !== 'transient'` mantiene la proyección viva pasado el hold; expone `engine.clear(id)` , `engine.clearTarget(target)` , `engine.hasActive(id)` .
- `SomaRuntime.trigger()` devuelve `TriggerResult { id?, persistence? }` . Expone `runtime.clearSignal(id)` , `runtime.clearTarget(target)` , `runtime.partRef(part)` (helper que devuelve el HTMLElement registrado de un part — útil para que providers limpien sin trackear ids).
- 6 morfos declaran `persistence` explícita: `announce.signal-alert` (untilAction), `dialog/drawer.close-after-fail` (transient explícito), `file-upload.signal-warn-reject` + `form.signal-warn-invalid` (untilFix), `password-field.signal-notify-caps-state` (stateBound).
- 3 providers cabledados con `clearTarget(provider)` : form (limpia al validar / reset), file-upload (limpia antes de cada nueva ronda de accept/reject + en remove / clear), password-field (limpia indicator al apagarse caps lock).
**a11ySemantic (libro §9.1)**:
- Nuevo `MorfoA11ySemantic` interface en `src/uix/morfo/types.ts` : `requiresPersistentTrace?` , `requiresLiveRegion?` , `requiresFocusMove?` , `keyboardEquivalent?` , `reducedMotionFallback?: 'state' | 'text' | 'focus' | 'none'` . Añadido como `a11ySemantic?` opcional en `MorfoEvent` . Pasa por compile a `ActionPlan.a11ySemantic` .
- Helper de reduced-motion en `src/arts/adom/reduced-motion.svelte.ts` (paralelo a `viewport.svelte.ts` ): `ReducedMotionTracker` reactivo del media query con SSR-safe fallback. Expuesto en `ActiveDom.prefersReducedMotion.matches` .
- `ActiveUix.announce(message, priority?, timeout?)` : live region compartida lazy-creada vía `dom.writeNode` . No depende de soma. Polite/assertive son regiones separadas, cleanup en `dispose()` .
- `Soma.runtime()` auto-wires `sources.announce = (m, p) => uix.announce(m, p)` . Tests usan fake `announce` .
- `SomaRuntime.trigger()` honra a11ySemantic después del emit: live region (con `opts.message` ), focus move, reduced-motion fallback (incluye forzar `channels: []` cuando fallback = 'state').
- 6 morfos anotados (los mismos consumidores).
**Polymorphic events (libro §5.3)** — ADITIVO sobre el shape concreto:
- Morfo declara `family` + `intent` + `verb` como default. Si añade `allowedFamilies: readonly SemaFamily[]` , los providers pueden override la family en `runtime.trigger(name, { semantic: { family, intent?, verb? } })` . El default family del morfo es IMPLÍCITAMENTE allowed.
- `isPolymorphicSemantic(semantic)` helper exportado de `$uix/morfo` .
- `SomaRuntimePolymorphicError` cuando override no está en allowedFamilies.
- Diseño aditivo (no variante separada con `defaultSemantic` ) elegido para mantener backwards-compat con 29 morfos existentes y demos que acceden `event.semantic.family` directamente.
**Tests**: 671/671 pasan en `src/uix/sema + morfo + soma + src/arts/adom/test` . 4 fallas pre-existentes en `src/uix/contracts.test.ts` (words component translation keys) — confirmadas en baseline antes de mis cambios via `git stash` .
**`npm run check`**: 1 error pre-existente en `src/uix/soma/components/command/command-provider.svelte.ts:384` (`Cannot find name 'attrs'`) que ya estaba en main.
**Pendientes deliberadamente fuera del sprint** (resueltos en la segunda mitad — ver hand-off 2026-05-27 #2 abajo):
- ~~Extender persistence a tags-input + textarea~~ — DONE
- ~~Caller messages para announce~~ — DONE (form / file-upload / password-field / dialog / drawer)
- ~~Demo polymorphic real~~ — DONE (Dialog refactorizado a polymorphic close)
## Session hand-off — 2026-05-27 #2 (messages + persistence ext + Dialog polymorphic)
Segunda mitad del sprint cerrando el backlog del hand-off anterior. 3 grupos de cambios.
**M — Caller messages para live region**:
Cada provider que dispara un evento con `a11ySemantic.requiresLiveRegion` ahora pasa `opts.message` con texto localizado. La live region (ya cabledada via `Soma.runtime() → sources.announce` ) finalmente anuncia algo:
- `form-provider` : `signal-warn-invalid` → "1 form error..." / "{N} form errors..." (count = `Object.keys(form.issues).length` ). Usa `FORM_LANGS.ERROR_SUMMARY_*` .
- `file-upload-provider` : `signal-warn-reject` → "1 file was rejected" / "{N} files were rejected". Nuevas entradas `FILE_UPLOAD_LANGS.REJECT_SUMMARY_SINGLE/MULTI` + langs catalog.
- `password-field-provider` : `signal-notify-caps-state` → "Caps Lock is on" (usa `PASSWORD_FIELD_LANGS.CAPS_WARNING` que ya existía).
- `dialog-provider.dismissWith(action, { message })` : signatura aceptando `message` opcional, forwarded al trigger.
- `drawer-provider.dismissWith(action, { message })` : igual que dialog.
**P — Persistence extendido a tags-input + textarea**:
Misma doctrina §6.2 — signal+risk = untilFix:
- `tags-input.signal-warn-reject` → persistence: `untilFix` + a11ySemantic + provider clear via `clearTarget(input)` . Nueva entrada `tags-input.reject-warning` en langs catalog. Provider gana método privado `emitWarnReject(target)` que centraliza clear + emit + message. Successful add también clearea (la adición VÁLIDA es el "fix" de un reject previo).
- `textarea.signal-warn-count-overflow` → persistence: `untilFix` + a11ySemantic + provider clear en transición OUT-of-overflow. Nueva entrada `textarea.overflow-warning` en langs catalog. Provider emite SOLO en transición INTO overflow (no en cada keystroke al cap) — el `untilFix` proyecta persistente, no necesita re-anuncio.
**POLY — Dialog refactor a polymorphic close**:
Caso real de uso del feature de eventos polymorphic (§5.3). 5 eventos `close-*` colapsados en 1 evento `close` :
- **Morfo** (`dialog.ts`): un evento `close` con `family: 'emerge', verb: 'close', allowedFamilies: ['emerge', 'commit', 'signal']` . SIN `prewrite` (el provider escribe `data-last-action` imperativamente).
- **Validador relajado**: el invariante "cada `values[]` debe ser prewritten por algún event" cayó al sentido único "cada prewrite con value debe estar en `values[]` ". Razón: con polymorphism los values pueden ser escritos imperativamente. El comentario en `schema.ts` explica.
- **Provider** (`dialog-provider.svelte.ts`): `DISMISS_CAUSES` mapa de acciones a `{ lastAction, semantic }` . `dismissWith(action, opts)` traduce a `dom.apply` + `runtime.trigger('close', { semantic, ... })` . `triggerClose` es privado ahora.
- **Cascade sema** (`sema/components/dialog.ts`): selectores `eventName: 'close-dismiss-outside'` → `eventName: 'close', state: { attr: 'data-last-action', value: 'dismissed-outside' }` . `eventNamePrefix: 'close-'` → `eventName: 'close', eventFamily: 'emerge'` .
- **Eidos CSS** (`dialog.css`): NO cambió — ya leía `data-last-action` para tintar, no nombres de evento.
- **API pública preservada**: consumidores externos no notan diferencia (`dismissWith` mantiene firma + comportamiento observable).
- **Drawer / Popover**: NO refactorizados. Mismo patrón aplicable; defer porque cada uno requiere reescribir su cascade + decisión separada de timing.
**Tests**:
- `npx vitest run src/uix/sema src/uix/morfo src/uix/soma src/arts/adom/test` : **679/679 pass** .
- `npm run check` : 1 error pre-existente (`command-provider.svelte.ts:384` — ya en baseline).
- 4 fallas pre-existentes en `src/uix/contracts.test.ts` (words translations) — no relacionadas.
**Pendientes a futuro** (cubierto en hand-off 2026-05-27 #3 abajo):
- ~~Refactor analógico de Drawer + Popover a polymorphic close~~ — DONE
- Otros `signal.warn-*` no incluidos: hay variantes con `verb: 'warn'` que podrían también beneficiarse de persistence untilFix (revisar caso por caso).
## Session hand-off — 2026-05-27 #3 (Drawer + Popover polymorphic close)
Tercera tanda del sprint — completa el rollout del patrón polymorphic close (book §5.3) a los dos componentes hermanos de Dialog. Mismo refactor aplicado de forma sistemática.
**Drawer**:
- Morfo: 5 close-* → 1 polymorphic `close` con `family: 'emerge', allowedFamilies: ['emerge', 'commit', 'signal']` , sin prewrite. Drag events (drag-start / drag-progress / drag-end / resize) intactos.
- Provider: `DISMISS_CAUSES` map + `dismissWith(action, opts?)` traduce a `dom.apply(data-last-action)` + `runtime.trigger('close', { semantic })` . `triggerClose` privado. 4 callsites internos migrados a `dismissWith` (Content escape, Content keydown escape, Overlay click-outside, Close button).
- Sema cascade (`sema/components/drawer.ts`): selector `eventNamePrefix: 'close-'` → `eventName: 'close', eventFamily: 'emerge'` .
- Test (`drawer-provider.svelte.test.ts`): `triggerClose('close-dismiss', ...)` → `dismissWith('dismiss')` ; expect name='close'.
**Popover**:
- Morfo: igual refactor. 5 close-* → 1 polymorphic `close` .
- Provider: igual patrón con DISMISS_CAUSES + dismissWith. Internal callsites (5 lugares: scheduleHoverClose, trigger toggle click, trigger toggle keydown, escape, outside) migrados a `dismissWith` . Close button: usa el prop `action` traducido a dismissWith.
- Sema cascade (`sema/components/popover.ts`): mismo patrón — `eventName: 'close'` + `state: { attr: 'data-last-action', value: 'dismissed-outside' }` para la regla de dismiss-outside passive.
- Test (`popover-provider.svelte.test.ts`): no había refs a close-* directos. Ningún cambio necesario.
**Test fixtures migrados antes del refactor**:
- `compile.test.ts` : prewrite test usaba `drawerMorfo` → ahora usa `colorPickerMorfo` .
- `runtime.svelte.test.ts` : prewrite test usaba `drawerMorfo` → ahora usa `colorPickerMorfo` .
**Resultado**:
- 3 componentes overlay (Dialog / Drawer / Popover) usan el patrón polymorphic close de forma consistente.
- 5 picker components (color-picker / date-picker / date-range-picker / time-picker / time-range-picker) mantienen el shape per-event. Son la canonical reference para `prewrite` declarativo + sirven como fixtures de tests.
- API pública intacta — `dismissWith` mantiene signatura en los tres overlays.
- Eidos CSS no tocó (ya leía `data-last-action` ).
**Tests**: 680/680 pass en `src/uix/sema + morfo + soma + src/arts/adom/test` . `npm run check` : 1 error pre-existente.
**Pendientes a futuro** (picker family cubierto en hand-off 2026-05-27 #4 ):
- ~~Picker family refactor~~ — DONE
- Otros `signal-warn-*` no cubiertos (textarea / tags-input ya hechos; revisar caso por caso si emergen más).
## Session hand-off — 2026-05-27 #4 (Picker family polymorphic close)
Cuarta tanda — completa el rollout polymorphic close al picker family (5 componentes). Más decoupling de tests.
**Refactor de los 5 pickers**:
- `color-picker` : 4 close-* → 1 polymorphic `close`
- `date-picker` : 4 close-* → 1 polymorphic `close`
- `date-range-picker` : 4 close-* (incl. `close-range-commit` ) → 1 polymorphic `close`
- `time-picker` : 4 close-* → 1 polymorphic `close`
- `time-range-picker` : 4 close-* → 1 polymorphic `close`
Cada morfo: `family: 'emerge', verb: 'close', target: v.partRef('calendar'|'clock'|'content'), persistence: 'transient', allowedFamilies: ['emerge', 'commit', 'signal']` .
**Hallazgo importante**: los picker providers NO disparan los close events. Solo togglean `opts.open = false` . Los eventos estaban declarados pero **inertes** — su único consumidor era el schema validator y los compiler tests. El refactor es alineación doctrinal, no de comportamiento.
**Sema cascade**: solo `color-picker` tiene un sema pack y no referenciaba close-* (solo handle-*). Cero updates necesarios en cascades.
**Test fixtures decoupling**:
- Nuevo `src/uix/morfo/test-fixtures.ts` con `prewriteFixtureMorfo` sintético.
- `compile.test.ts` : migrado de `colorPickerMorfo` → `prewriteFixtureMorfo` .
- `runtime.svelte.test.ts` : igual migración.
- Beneficio: los tests validan el contrato del compiler/runtime sin depender del catálogo de componentes. Futuros refactors del catálogo no rompen estos tests.
**Estado final del rollout polymorphic** (3 sprints combinados):
| Componente | Polymorphic morfo | Provider cabledado |
|---|---|---|
| Dialog | ✓ | ✓ (`dismissWith` → `runtime.trigger` ) |
| Drawer | ✓ | ✓ |
| Popover | ✓ | ✓ |
| color-picker | ✓ | ✗ (toggle opts.open) |
| date-picker | ✓ | ✗ |
| date-range-picker | ✓ | ✗ |
| time-picker | ✓ | ✗ |
| time-range-picker | ✓ | ✗ |
Único morfo con shape pre-polymorphic restante: el fixture sintético `prewriteFixtureMorfo` — vivo sólo para tests.
**Tests**: 680/680 pass. `npm run check` : 1 error pre-existente.
**Pendiente a futuro**:
- Cabledar `runtime.trigger('close', { semantic })` en los providers picker cuando justifique disparar el evento (telemetría, sound on commit picker, etc.).
feat(eidos): TSC v2.2 (parts + composition) + universal theming coverage
Token Scope Contract universal — no más excepciones arquitectónicas.
Los 3 componentes que vivían fuera de TSC v2.1 (select, avatar,
toggle-group) ahora están dentro del contrato via dos extensiones nuevas.
TSC v2.2 extensiones (lib/config-types.ts + render-css.ts + config.ts):
- `parts: readonly string[]` en RecipeTokenMultiDeclaration — emite
selectores comma-separados (`[data-{c}-x], [data-{c}-y]`) para
componentes con data-color cascadeado per-part. Consumer: select.
- `composition: { foreignRecipe: { targetSelector, tokens } }` sibling
key — overrides cross-recipe scoped a la cascade del host. Consumer:
toggle-group modifica `--toggle-palette-*` en sus items.
Migraciones:
- select: 3 private `_accent-{track,border,text}` con parts: ['trigger',
'content'] + 7 cascades color:X each. Removed orphan `_accent-solid`
(CSS no consumía).
- avatar: 6 tokens via composite scopes `['variant:X', 'color:Y']` con
matrix helper inline. Badge usa parts: ['badge']. Reemplaza 24 bloques
CSS × 2 partes.
- toggle-group: composition block con 8 palette tokens × 4 colors.
Reemplaza 4 bloques CSS per-color.
Bug toggle-group post-composition (encontrado y arreglado):
Tras la composition migration, el cascade del toggle-group seguía roto
porque los tokens derivados (`--toggle-solid-on-bg`, `--toggle-outline-fg`,
etc.) viven en scope `[data-toggle]`. El `[data-toggle-group-item]` es
sibling (no descendant), así que `var(--toggle-solid-on-bg)` resolvía
undefined. Fix: inlined derivation expressions directamente en
`[data-toggle-group-item]` y sus variant cascades (solid/outline/ghost),
referenciando palette tokens en su propio scope local.
Validador + emisor + contract:
- `validateRecipeComposition` valida el shape `{ targetSelector, tokens }`
y rechaza composition entries con scope='root'.
- `stripCompositionKey` + `emitComposition` separan el pipeline.
- `appendRecipeContractTokens` skip-list para `composition` (no aparece
como fake `--{c}-composition` knob).
- `tokenKeys`/`tokenEntries` helpers en recipe-css-contract.test.ts
filtran composition en todos los iteradores.
Documentación:
- THEMING.md §18 reescrito como "Cobertura universal de TSC". §7
extendido con subsecciones "Multi-part scope" y "Cross-recipe
composition" + ejemplos completos. TOC actualizado.
- eidos/README.md tabla de referencia ampliada con TSC v2.2 + §18.
- CLAUDE.md gana hand-off "2026-05-27 #5" (TSC v2.2 + cobertura universal).
- CONTINUE.md reescrito al estado actual de la sesión.
Working tree también incluye sprint Words en paralelo (multiple authors):
slash menu, find/replace regex, code language picker, table audit,
toolbar family menu, code highlight engine.
Tests: 786/786 pass en src/uix/{eidos,morfo,soma,sema}. `npm run check`:
6 errores pre-existentes (lib/_demo, soma/components/internal,
web/routes/active) no relacionados.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 months ago
## Session hand-off — 2026-05-27 #5 (TSC v2.2 + cobertura universal de theming)
Cierra la migración universal del Token Scope Contract. El usuario rechazó el framing "excepciones arquitectónicas" para los 3 componentes que vivían fuera de TSC v2.1 (`select`, `avatar` , `toggle-group` ) — la respuesta fue extender TSC con dos features nuevas (`parts` + `composition` ) y migrar los 3.
**Extensiones TSC v2.2** (`src/uix/eidos/lib/config-types.ts` + `lib/render-css.ts` + `lib/config.ts` ):
- **Multi-part scope** — `RecipeTokenMultiDeclaration.parts?: readonly string[]` . Cuando un token tiene `parts: ['x', 'y']` el generador emite selectores comma-separados (`[data-{c}-x][...], [data-{c}-y][...]`) en lugar del default `[data-{c}][...]` . Cubre el caso del select donde `data-color` vive en Trigger + Content (Content portaliza fuera del árbol del Trigger). Único consumer hoy.
- **Cross-recipe composition** — nuevo sibling field `composition?: { foreignComponent: { targetSelector, tokens } }` . Permite que un recipe declare overrides de tokens de OTRO recipe scoped a su propia cascade, con un selector de descendant para alcanzar la part foránea. Genera `{host-scope} {targetSelector} { --{foreign}-{tokenName}: ... }` . Validator rechaza root-scoped composition (un override no-scoped pertenece al foreign recipe). Único consumer hoy: `toggle-group` modifica `--toggle-palette-*` en sus items.
Validador (`config.ts`) extendido con `validateRecipeComposition` . Generator (`render-css.ts`) gana `stripCompositionKey` + `emitComposition` . Contract builder (`contract.ts`) skip-list de la reserved key `composition` para que no aparezca como `--{c}-composition` knob en el contrato público. Test helpers (`tokenKeys`/`tokenEntries` en `recipe-css-contract.test.ts` ) filtran `composition` en todos los iteradores.
**Migraciones de los 3 componentes restantes**:
- `select` : 4 → 3 private `_accent-*` con `parts: ['trigger', 'content']` . (`_accent-solid` no se migró porque la CSS nunca lo consumía — era orphan; se removió de la recipe.)
- `avatar` : 6 tokens (`_bg`/`_fg`/`_border` + `_badge-bg` /`_badge-fg`/`_badge-border`) con declarations[] generadas por un helper inline `matrix()` que recorre los 8 colores × 3 variants. `_badge-*` usa `parts: ['badge']` para retargetear a `[data-avatar-badge]` . Reemplaza ~150 declarations CSS por las mismas declarations, generadas desde TS.
- `toggle-group` : bloque `composition: { toggle: { targetSelector: '[data-toggle-group-item]', tokens: { 'palette-*': {...} } } }` con 8 palette tokens × 4 colors. Reemplaza los 4 bloques CSS per-color.
**Bug post-migración del toggle-group (toggle-group color cascade)** — encontrado y arreglado:
La composition correctamente override `--toggle-palette-*` en `[data-toggle-group-item]` , pero la cascade se rompía aguas abajo. Después de la migración TSC v2 original de toggle, los tokens DERIVADOS (`--toggle-solid-on-bg`, `--toggle-outline-fg` , etc.) viven en scope `[data-toggle]` . El `[data-toggle-group-item]` es SIBLING (no descendant) de `[data-toggle]` , así que `var(--toggle-solid-on-bg)` resolvía a undefined en el item.
Fix (en `toggle-group.css` ): **inlined las derivation expressions** que leen palette directamente en `[data-toggle-group-item]` y sus variant cascades. Las expresiones reflejan las de `recipes/base.ts > toggle.{solid,outline,ghost}-*` . Duplicación documentada en el header. Alternativa estructural (hacer el item carrier de `[data-toggle]` + propagar `data-color` morfo/soma) no se aplicó — change too big.
**Documentación**:
- `THEMING.md` §18 reescrito como "Cobertura universal de TSC" (sin excepciones). §7 extendido con subsecciones "Multi-part scope" y "Cross-recipe composition" con ejemplos completos. TOC actualizado.
- `eidos/README.md` tabla de referencia ampliada con entradas para TSC v2.2 + §18.
**Tests**: 786/786 pass en `src/uix/{eidos,morfo,soma,sema}` . `npm run check` : los mismos 6 errores pre-existentes en `lib/_demo` /`soma/components/internal`/`web/routes/active` (no relacionados).
**Pendiente a futuro**:
- Si emergen patrones similares al toggle-group (otros wrappers compositivos como button-group, nav-menu), la composition TSC v2.2 los cubre — no requiere más extensiones.
- Los `inlined derivation expressions` en `toggle-group.css` son la única duplicación entre recipes/base.ts y CSS. Si Toggle's derivations cambian, hay que actualizar ambos.
feat(eidos): variants canon — EIDOS_VARIANTS + per-component lint
Variants son canon del eidos, NO del theme. Decisión arquitectónica
firmemente sostenida: el vocabulario de variants (solid/outline/ghost/
soft/surface/line/pills) está fijo a nivel del framework — paralelo
a las 8 sema families del libro. Theme = retintar lo perceptualmente
fijo; cambia QUÉ color es `affirm`, no QUÉ significa `outline`.
Cambios:
- lib/types.ts: nueva constante `EIDOS_VARIANTS` con los 5 archetypes
canónicos (control / selection / chip / marker / tabs). Los 5 union
types se derivan via `[number]` indexed access — valor y tipo no
pueden desincronizarse. Nueva `EIDOS_VARIANT_VALUES` Set flat con
todos los valores canónicos + utilidades cross-component (`plain`,
`subtle`).
- recipe-css-contract.test.ts: nuevo test "variant CSS selectors per
component match the declared type union". Por cada componente:
extrae el union type de `components/{c}/types.ts` (soporta literal
unions + archetype aliases; cae a advisory mode en Extract<> y
conditional types); compara con `[data-{c}][data-variant='X']`
selectores en `{c}.css`; reporta typos y unauthorized extensions
bidireccionalmente.
- THEMING.md §19: nueva sección "Variants son canon del eidos, NO
del theme" con argumentación (portabilidad, type safety, archetypes
perceptuales paralelos a sema families), tabla de las 3 capas de
la cebolla, referencia a `EIDOS_VARIANTS`, comparación con Radix
Themes 3.x / Mantine 7 / Chakra v3 / Ark / shadcn. TOC actualizado.
- eidos/README.md: tabla de referencia ampliada con §19.
- CLAUDE.md: hand-off "2026-05-27 #6 (variants canon)".
- CONTINUE.md: nota de la decisión arquitectónica.
Variants component-specific permitidos (Banner inline/overlay/
persistent, Spinner bars/dots/ring, Button 'plain'): viven en cada
`components/{c}/types.ts` y el lint los valida contra la CSS del
componente.
Tests: 101/101 pass en `src/uix/eidos`. `npm run check`: los mismos 6
errores pre-existentes (lib/_demo, soma/components/internal, web/
routes/active) — no relacionados.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 months ago
## Session hand-off — 2026-05-27 #6 (variants canon — `EIDOS_VARIANTS` + lint)
Pregunta arquitectónica del usuario: "si activeUIX quiere ser referencia como framework, ¿qué es lo lógicamente coherente respecto a la extensibilidad de variants?". Respuesta firme: **variants son canon del eidos, NO del theme** — paralelo a las 8 sema families del libro.
**Cambios**:
- `src/uix/eidos/lib/types.ts` : nueva constante `EIDOS_VARIANTS` (5 archetypes: `control` /`selection`/`chip`/`marker`/`tabs`) como single source of truth. Los 5 union types se derivan via `[number]` indexed access — valor y tipo no pueden desincronizarse. Nueva constante `EIDOS_VARIANT_VALUES` (Set flat de todos los valores canónicos + utilidades cross-component como `'plain'` y `'subtle'` ).
- `src/uix/eidos/recipe-css-contract.test.ts` : nuevo test "variant CSS selectors per component match the declared type union". Por cada componente: extrae el union type de `components/{c}/types.ts` via regex (literal-union + archetype-alias patterns soportados, Extract< >/conditional types caen a advisory mode); compara con los `[data-{c}][data-variant='X']` selectores en `{c}.css` ; reporta typos y unauthorized extensions bidireccionalmente. 101/101 tests pasan.
- `src/uix/eidos/THEMING.md` §19: nueva sección "Variants son canon del eidos, NO del theme" con argumentación (portabilidad, type safety, archetypes perceptuales), tabla de las 3 capas de la cebolla (sema → variants → palette), referencia a `EIDOS_VARIANTS` , comparación con Radix Themes/Mantine/Chakra v3/Ark UI/shadcn. TOC actualizado.
- `src/uix/eidos/README.md` : tabla de referencia ampliada con §19.
**Doctrina sostenida**: Theme = retintar lo perceptualmente fijo. Cambia QUÉ color es `affirm` , no QUÉ significa `outline` . Si una app necesita un look brandeado, hace override de tokens en `EidosConfig.recipes` o crea un wrapper composicional — NO inventa un nuevo variant.
**Variants component-specific permitidos** (Banner `inline` /`overlay`/`persistent`, Spinner `bars` /`dots`/`ring`, Button `'plain'` ): viven en cada `components/{c}/types.ts` y el lint los valida contra la CSS del componente.
**Tests**: 101/101 pass en `src/uix/eidos` . `npm run check` : los mismos 6 errores pre-existentes (lib/_demo, soma/components/internal, web/routes/active).
## Session hand-off — 2026-05-09 (selector discipline + lint reframing)
- **Typed selector builder applied** in
`src/uix/sema/components/dialog.ts` . Every cascade rule now constructs
its selector via `semaSelector(dialogMorfo, 'content', matchers?)`
instead of hand-writing strings. The helper lives in
`src/uix/morfo/selectors.ts` and is exported from `$uix/morfo` .
- **Eidos-lint reframed** from "architectural drift mechanism" to
"opt-in safety net for plain CSS recipes". The architectural mechanism
is compile-time typing. The lint script + scripts continue to work
unchanged but are no longer the doctrinal source of safety.
- **Intent.deltas signature ownership documented** — cascade rules MUST
NOT override `pitch` / `gain` / `contour` on `sound` , because doing so
collapses the per-intent perceptual difference. Captured both inline
in the dialog cascade (NOTE comment on the intent block) and in the
"Override semantics — numbers" rule above.
- **Documentation updated**:
- `src/uix/morfo/README.md` — new "Typed selector builder —
`semaSelector` " section.
- `src/uix/eidos/README.md` — replaced "Linter" section with
"Defensa contra drift de selectores" framing the two-tier defense
(compile-time builder for TS/Svelte, opt-in lint for plain CSS).
- `src/uix/sema/README.md` — already documented the builder + the
cascade discipline + the SEMA_FAMILY_POLICY shape (from the prior
refactor).
**Verification at hand-off**: `npm run check` reports 0 errors, 2
pre-existing Svelte warnings unrelated to this work. `npm run test`
reports 1883/1883 tests green across 154 files (~22s).
docs + switch: align active docs to canon, migrate switch to eidos wrapper
Phase 4 (docs alignment with the canonical guide):
- active_architecture.md — Dialog example refactored to the new event
shape (target inside semantic, explicit verb + sequence). Verbs
table grouped by family with the post-canon vocabulary (select/
toggle moved to commit, edit removed from handle, new verbs added).
Section 10 (Estado actual) updated to 2026-05-08 with current
progress: doctrina cerrada, eidos en producción, SoundChannel
eager-init, switch migrated, etc. "Para profundizar" §14 points at
the canonical guide.
- morfo/README.md — Step 5.5 added covering the doctrinal event
shape with all fields (semantic.family, .verb, .target, .sequence,
.intent) and the two naming shapes ({verb}-{variant} and
{family}-{verb}).
- sema/README.md — verbs section restructured to Record-by-family
matching the runtime; documents the verbs that moved between
families per the canon. Naming shapes section updated with both
forms and validateEventName signature.
- CLAUDE.md — "Session hand-off" rewritten with the post-canon
state. Pointer at GUIA_IMPLEMENTACION_SEMAUIX.md as the canonical
source. Pending list refreshed: switch is the immediate next
component, persistence/a11ySemantic/polymorphism deferred until
real consumers appear.
Switch migration to the eidos wrapper pattern:
- morfo/components/switch.ts — adds events: [{ commit-toggle }] with
the doctrinal shape (verb=toggle, sequence=post, intent fromProp
binding to the 4 supported intents). New data-* (data-color with
the 6-token Toggle/Switch subset, data-readonly, data-invalid,
data-required) and corresponding aria-*. scope expanded to
['soma', 'sema'].
- soma/components/switch/types.ts — adds intent, color, readonly,
invalid, aria-labelledby props with full JSDoc. Subset constrained
per guide §3.1 (Toggle/Switch row).
- soma/components/switch/switch-provider.svelte.ts — runtime-direct,
Field integration via FieldProvider.get(), isDisabled/isReadonly/
isRequired/isInvalid OR-merge derivations, intent ↔ color
resolution (intent wins when evaluative), runtime.trigger(
'commit-toggle') in onclick.
- soma/components/switch/components/switch.svelte — wires the new
props through bindProps.
- eidos/components/switch/{switch.css, switch.svelte, types.ts,
index.ts, README.md} — full subdirectory pattern, mirroring
toggle. Recipe drops legacy success/warning/danger/info selectors;
declares the 6 doctrinal data-color values directly. Wrapper
auto-renders Switch.Thumb inside the track and exposes an optional
`thumb` snippet for in-thumb glyphs.
- eidos/components/switch.css (legacy flat) deleted; eidos/index.css
updated to import the subdirectory recipe.
- web/routes/switch/+page.svelte — interactive testbed with all soma
props as live controls + tabs (Live, Soma, Morfo, Sema, Eidos,
Notes). Mirrors toggle's structure.
npm run check holds at the 39-error baseline. Tests 217/217 green.
Pending:
- Migrate collapsible / dialog / drawer / popover / toast / avatar
to the eidos wrapper pattern.
- Persistence + holds-by-intent — defer until first signal.warn /
signal.alert consumer.
- a11ySemantic + polymorphic events — defer until concrete need.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
## Session hand-off — 2026-05-08 (post-canon alignment)
soma/morfo/active-uix: relocate runtime + rename SomaRuntime + sema opcional
Architectural correction. Morfo was importing Svelte runes, $adom, and
$uix/sema — all violations of "morfo is pure declarative DNA". The
runtime that interprets a CompiledMorfo lives where it executes: soma.
Move:
- src/uix/morfo/runtime.svelte.ts → src/uix/soma/runtime.svelte.ts
- src/uix/morfo/runtime.svelte.test.ts → src/uix/soma/runtime.svelte.test.ts
Rename (consistent with the move; "soma's runtime", per the doctrine
"morfo declares, soma executes"):
- class MorfoRuntime → SomaRuntime
- createMorfoRuntime() → createSomaRuntime()
- type MorfoRuntimeSources → SomaRuntimeSources
- error prefixes [morfo-runtime] → [soma-runtime]
Sema is now genuinely ornamental:
- ActiveUix.semantic returns EngineSemantic | undefined (no longer
throws when no engine is configured). Components in SSR / headless
tests / audio-disabled environments stay functional.
- SomaRuntime.trigger() skips the emit step AND the target-resolution
check when no engine is present — only requires a DOM target when
something will actually be emitted.
- Soma.semantic getter returns | undefined too (was non-optional).
Consumers updated:
- src/uix/active-uix/active-uix.svelte.ts — imports createSomaRuntime
from $soma; semantic getter returns | undefined
- src/uix/active-uix/types.ts — interface SomaRuntime, semantic | undefined
- 8 providers (toggle, switch, collapsible, dialog, drawer, popover,
toast, avatar) — type SomaRuntime, import path $soma
- src/uix/soma/index.ts — re-exports createSomaRuntime + types
- src/uix/morfo/index.ts — drops the runtime re-exports (morfo is pure)
- src/uix/sema/signal.ts — JSDoc reference updated
- src/uix/soma/core/soma.svelte.ts — semantic getter | undefined
Test added: SomaRuntime.trigger() succeeds without a semantic engine
(skips emit + target check, runs handler directly).
Docs aligned to the new shape:
- active_architecture.md — runtime locations, sema as ornamental
- soma/SOMA_ARCHITECTURE.md, soma/README.md — name + import paths
- morfo/README.md — file listing now flags morfo as PURE TS, points
at soma/runtime.svelte.ts for the interpreter
- sema/README.md — SomaRuntime references
- README.md — root architecture diagram
- CLAUDE.md — hand-off note
Tests 218/218 green. npm run check holds at the 39-error baseline.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
The codebase has been aligned to the canonical guide. Most recent
architectural move:
- **Runtime relocated + renamed** — what was `MorfoRuntime` in
`src/uix/morfo/runtime.svelte.ts` is now `SomaRuntime` in
`src/uix/soma/runtime.svelte.ts` . Reason: morfo must remain pure
declarative TypeScript (DNA); the runtime imports Svelte runes,
`$adom` , `$uix/sema` , and `$libs/reactive` — those are soma's
territory. Per the doctrine "morfo declares, soma executes" the
runtime now lives where it conceptually belongs. Active-uix's
`uix.runtime(morfo, sources)` factory stays unchanged; it imports
`createSomaRuntime` from `$soma` .
- **Sema is now genuinely ornamental** — `ActiveUix.semantic` returns
`EngineSemantic | undefined` (no longer throws). `SomaRuntime.trigger()`
skips the `emit` step and the target-resolution check when no engine
is present. Components stay functional in SSR / headless tests /
audio-disabled environments.
The earlier swept phases (still in effect):
docs + switch: align active docs to canon, migrate switch to eidos wrapper
Phase 4 (docs alignment with the canonical guide):
- active_architecture.md — Dialog example refactored to the new event
shape (target inside semantic, explicit verb + sequence). Verbs
table grouped by family with the post-canon vocabulary (select/
toggle moved to commit, edit removed from handle, new verbs added).
Section 10 (Estado actual) updated to 2026-05-08 with current
progress: doctrina cerrada, eidos en producción, SoundChannel
eager-init, switch migrated, etc. "Para profundizar" §14 points at
the canonical guide.
- morfo/README.md — Step 5.5 added covering the doctrinal event
shape with all fields (semantic.family, .verb, .target, .sequence,
.intent) and the two naming shapes ({verb}-{variant} and
{family}-{verb}).
- sema/README.md — verbs section restructured to Record-by-family
matching the runtime; documents the verbs that moved between
families per the canon. Naming shapes section updated with both
forms and validateEventName signature.
- CLAUDE.md — "Session hand-off" rewritten with the post-canon
state. Pointer at GUIA_IMPLEMENTACION_SEMAUIX.md as the canonical
source. Pending list refreshed: switch is the immediate next
component, persistence/a11ySemantic/polymorphism deferred until
real consumers appear.
Switch migration to the eidos wrapper pattern:
- morfo/components/switch.ts — adds events: [{ commit-toggle }] with
the doctrinal shape (verb=toggle, sequence=post, intent fromProp
binding to the 4 supported intents). New data-* (data-color with
the 6-token Toggle/Switch subset, data-readonly, data-invalid,
data-required) and corresponding aria-*. scope expanded to
['soma', 'sema'].
- soma/components/switch/types.ts — adds intent, color, readonly,
invalid, aria-labelledby props with full JSDoc. Subset constrained
per guide §3.1 (Toggle/Switch row).
- soma/components/switch/switch-provider.svelte.ts — runtime-direct,
Field integration via FieldProvider.get(), isDisabled/isReadonly/
isRequired/isInvalid OR-merge derivations, intent ↔ color
resolution (intent wins when evaluative), runtime.trigger(
'commit-toggle') in onclick.
- soma/components/switch/components/switch.svelte — wires the new
props through bindProps.
- eidos/components/switch/{switch.css, switch.svelte, types.ts,
index.ts, README.md} — full subdirectory pattern, mirroring
toggle. Recipe drops legacy success/warning/danger/info selectors;
declares the 6 doctrinal data-color values directly. Wrapper
auto-renders Switch.Thumb inside the track and exposes an optional
`thumb` snippet for in-thumb glyphs.
- eidos/components/switch.css (legacy flat) deleted; eidos/index.css
updated to import the subdirectory recipe.
- web/routes/switch/+page.svelte — interactive testbed with all soma
props as live controls + tabs (Live, Soma, Morfo, Sema, Eidos,
Notes). Mirrors toggle's structure.
npm run check holds at the 39-error baseline. Tests 217/217 green.
Pending:
- Migrate collapsible / dialog / drawer / popover / toast / avatar
to the eidos wrapper pattern.
- Persistence + holds-by-intent — defer until first signal.warn /
signal.alert consumer.
- a11ySemantic + polymorphic events — defer until concrete need.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
- **Sema verbs** (`src/uix/sema/verbs.ts`): restructured to
family-keyed `Record` . `select` /`toggle`/`acknowledge` moved to
`commit` ; `edit` removed from `handle` (now expressed as
`shift.enter-mode` ). New verbs added per the canon (tap, focus,
release, complete, restore, remind, route, step, syncing, etc.).
`validateEventName` recognises both `{verb}-{variant}` and
`{family}-{verb}` shapes.
- **Morfo event shape** (`src/uix/morfo/types.ts`): `target` moved
inside `semantic` ; added optional `verb` (advisory, validated against
`SEMA_VERBS[family]` ) and `sequence: 'pre' | 'coincident' | 'post'` .
All 22 events across toggle/toast/popover/drawer/dialog refactored
to the new shape.
- **Color tokens** (`src/uix/eidos/themes/base/{light,dark}.css`):
doctrinal 8 tokens — `primary, secondary, neutral, affirm, fulfill,
risk, threat, loss`. Renamed `success → fulfill` , `warning → risk` ,
`danger → threat` (same hex). New primitives for `secondary`
(slate-blue), `affirm` (teal-mint, low activation), `loss` (deep
violet-grave, posterior). `info` palette deleted entirely. Legacy
aliases in `_static.css` deleted (clean cut, no transition).
29 consumers (recipe CSS + tokens) migrated to doctrinal names.
Earlier in the session:
- **Toggle is the eidos pilot** (`src/uix/eidos/components/toggle/`):
recipe + Svelte wrapper + types + index + README. The pattern is
docs + switch: align active docs to canon, migrate switch to eidos wrapper
Phase 4 (docs alignment with the canonical guide):
- active_architecture.md — Dialog example refactored to the new event
shape (target inside semantic, explicit verb + sequence). Verbs
table grouped by family with the post-canon vocabulary (select/
toggle moved to commit, edit removed from handle, new verbs added).
Section 10 (Estado actual) updated to 2026-05-08 with current
progress: doctrina cerrada, eidos en producción, SoundChannel
eager-init, switch migrated, etc. "Para profundizar" §14 points at
the canonical guide.
- morfo/README.md — Step 5.5 added covering the doctrinal event
shape with all fields (semantic.family, .verb, .target, .sequence,
.intent) and the two naming shapes ({verb}-{variant} and
{family}-{verb}).
- sema/README.md — verbs section restructured to Record-by-family
matching the runtime; documents the verbs that moved between
families per the canon. Naming shapes section updated with both
forms and validateEventName signature.
- CLAUDE.md — "Session hand-off" rewritten with the post-canon
state. Pointer at GUIA_IMPLEMENTACION_SEMAUIX.md as the canonical
source. Pending list refreshed: switch is the immediate next
component, persistence/a11ySemantic/polymorphism deferred until
real consumers appear.
Switch migration to the eidos wrapper pattern:
- morfo/components/switch.ts — adds events: [{ commit-toggle }] with
the doctrinal shape (verb=toggle, sequence=post, intent fromProp
binding to the 4 supported intents). New data-* (data-color with
the 6-token Toggle/Switch subset, data-readonly, data-invalid,
data-required) and corresponding aria-*. scope expanded to
['soma', 'sema'].
- soma/components/switch/types.ts — adds intent, color, readonly,
invalid, aria-labelledby props with full JSDoc. Subset constrained
per guide §3.1 (Toggle/Switch row).
- soma/components/switch/switch-provider.svelte.ts — runtime-direct,
Field integration via FieldProvider.get(), isDisabled/isReadonly/
isRequired/isInvalid OR-merge derivations, intent ↔ color
resolution (intent wins when evaluative), runtime.trigger(
'commit-toggle') in onclick.
- soma/components/switch/components/switch.svelte — wires the new
props through bindProps.
- eidos/components/switch/{switch.css, switch.svelte, types.ts,
index.ts, README.md} — full subdirectory pattern, mirroring
toggle. Recipe drops legacy success/warning/danger/info selectors;
declares the 6 doctrinal data-color values directly. Wrapper
auto-renders Switch.Thumb inside the track and exposes an optional
`thumb` snippet for in-thumb glyphs.
- eidos/components/switch.css (legacy flat) deleted; eidos/index.css
updated to import the subdirectory recipe.
- web/routes/switch/+page.svelte — interactive testbed with all soma
props as live controls + tabs (Live, Soma, Morfo, Sema, Eidos,
Notes). Mirrors toggle's structure.
npm run check holds at the 39-error baseline. Tests 217/217 green.
Pending:
- Migrate collapsible / dialog / drawer / popover / toast / avatar
to the eidos wrapper pattern.
- Persistence + holds-by-intent — defer until first signal.warn /
signal.alert consumer.
- a11ySemantic + polymorphic events — defer until concrete need.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
documented in `src/uix/eidos/components/README.md` .
- **Eidos has a shared lib** at `src/uix/eidos/lib/types.ts` . First
type is `Size` (`'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'full'`).
Components narrow with `Extract<Size, 'sm' | 'md' | 'lg'>` per the
per-component-subset doctrine.
- **No `Eidos` prefix on types**. The path
`$uix/eidos/components/{x}` already conveys layer. Public types are
`ToggleProps` , `ToggleVariant` , `ToggleSize` .
- **API doctrine**: soma stays compound (`Toggle.Provider`); eidos
exports both `default` and `Provider` for single-part components so
`<Toggle>` works for the ergonomic case while `<Toggle.Provider>`
stays available.
- **SoundChannel eager-init landed** in `src/uix/sema/chans/sound.ts`
to fix the autoplay race: the AudioContext is created + resumed
synchronously on the first user gesture (capture-phase listener on
`document` ).
- **Demo page (`web/routes/toggle/+page.svelte`)** has the live
preview rendered ALWAYS above the tablist (so Sema-tab Play buttons
can fire on the real toggle) and the motion preview amplifies scale
× 8 visually only — doctrinal values stay in the `<dl>` .
collapsible: migrate to eidos wrapper pattern (third pilot)
Third component migrated to the eidos wrapper subdirectory pattern,
following the new "check air baseline first" discipline.
Air baseline recovered from commit 0a391408^:
- air/components/collapsible: 3 wrappers (Provider/Trigger/Content)
with `class` passthrough, `bind:open`, `onOpenChange`, manual
`air.interaction.play('expansion', enter|exit)` perceptual emit.
- No size, intent, color, or chevron slot.
Migration decisions (presented BEFORE coding per scope-approval rule):
- Two doctrinal events (`expand` + `collapse`, both emerge family,
sequence='pre', no intent — emerge is transitional). Replaces air's
manual `air.interaction.play` with `runtime.trigger('expand'|
'collapse')` which atravieses visual + sound + vibra channels.
- No intent/color/size — air didn't have them and disclosure is
non-evaluative per guide §3.1.
- Multi-part API: Provider + Trigger + Content (no flat default per
doctrine §10).
Files:
- src/uix/morfo/components/collapsible.ts: scope expanded to ['soma',
'sema'], events array added with two emerge events.
- src/uix/soma/components/collapsible/collapsible-provider.svelte.ts:
runtime.events handlers `expand`/`collapse` mutate state; toggle()
fires runtime.trigger(next ? 'expand' : 'collapse').
- src/uix/eidos/components/collapsible/{collapsible.css,
collapsible-provider.svelte, collapsible-trigger.svelte,
collapsible-content.svelte, types.ts, index.ts, README.md}.
- src/uix/eidos/components/collapsible.css (legacy flat) deleted.
- src/uix/eidos/index.css: import path updated to subdirectory.
- web/routes/collapsible/+page.svelte: full interactive testbed with
tabs (Live, Soma, Morfo, Sema, Eidos, Notes) mirroring switch's
structure. Sema tab shows per-channel signature cards for both
expand and collapse events.
Disciplina formalizada en CLAUDE.md hand-off + memory entry: "Check
air baseline first" before any future eidos migration. Switch shipped
without this check and lost ResponsiveProp<Size> (regression). Don't
repeat with collapsible/dialog/drawer/popover/toast/avatar.
npm run check holds at the 39-error baseline. Tests 218/218 green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
**Mandatory checklist before any eidos component migration**:
1. Recover the air baseline from git:
```
git ls-tree -r 0a391408^ --name-only | Select-String "air.*{name}"
git show 0a391408^:src/uix/air/components/{name}/types.ts
git show 0a391408^:src/uix/air/components/{name}/{name}.svelte
```
2. Inventory air's props, slots, effects, perceptual emits.
3. Build a comparison table: feature × (air had it | canon allows it |
eidos exposes it). Flag each gap as `regression` , `enhanced` ,
`dropped-by-canon` , or `nuevo` .
4. Present the table BEFORE coding. Get explicit per-gap decision.
5. Only then write the wrapper.
Switch was migrated WITHOUT this discipline and shipped a regression
(no `ResponsiveProp<Size>` for breakpoint-aware sizing). Don't repeat.
Next concrete steps:
collapsible: migrate to eidos wrapper pattern (third pilot)
Third component migrated to the eidos wrapper subdirectory pattern,
following the new "check air baseline first" discipline.
Air baseline recovered from commit 0a391408^:
- air/components/collapsible: 3 wrappers (Provider/Trigger/Content)
with `class` passthrough, `bind:open`, `onOpenChange`, manual
`air.interaction.play('expansion', enter|exit)` perceptual emit.
- No size, intent, color, or chevron slot.
Migration decisions (presented BEFORE coding per scope-approval rule):
- Two doctrinal events (`expand` + `collapse`, both emerge family,
sequence='pre', no intent — emerge is transitional). Replaces air's
manual `air.interaction.play` with `runtime.trigger('expand'|
'collapse')` which atravieses visual + sound + vibra channels.
- No intent/color/size — air didn't have them and disclosure is
non-evaluative per guide §3.1.
- Multi-part API: Provider + Trigger + Content (no flat default per
doctrine §10).
Files:
- src/uix/morfo/components/collapsible.ts: scope expanded to ['soma',
'sema'], events array added with two emerge events.
- src/uix/soma/components/collapsible/collapsible-provider.svelte.ts:
runtime.events handlers `expand`/`collapse` mutate state; toggle()
fires runtime.trigger(next ? 'expand' : 'collapse').
- src/uix/eidos/components/collapsible/{collapsible.css,
collapsible-provider.svelte, collapsible-trigger.svelte,
collapsible-content.svelte, types.ts, index.ts, README.md}.
- src/uix/eidos/components/collapsible.css (legacy flat) deleted.
- src/uix/eidos/index.css: import path updated to subdirectory.
- web/routes/collapsible/+page.svelte: full interactive testbed with
tabs (Live, Soma, Morfo, Sema, Eidos, Notes) mirroring switch's
structure. Sema tab shows per-channel signature cards for both
expand and collapse events.
Disciplina formalizada en CLAUDE.md hand-off + memory entry: "Check
air baseline first" before any future eidos migration. Switch shipped
without this check and lost ResponsiveProp<Size> (regression). Don't
repeat with collapsible/dialog/drawer/popover/toast/avatar.
npm run check holds at the 39-error baseline. Tests 218/218 green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
1. Migrate `collapsible → dialog → drawer → popover → toast → avatar`
to the eidos wrapper pattern. **For each: walk the air-baseline
checklist above first.** Toggle / switch are templates for the
subdirectory shape, but the per-component prop surface must come
from air's recovery, not from copying toggle's props.
docs + switch: align active docs to canon, migrate switch to eidos wrapper
Phase 4 (docs alignment with the canonical guide):
- active_architecture.md — Dialog example refactored to the new event
shape (target inside semantic, explicit verb + sequence). Verbs
table grouped by family with the post-canon vocabulary (select/
toggle moved to commit, edit removed from handle, new verbs added).
Section 10 (Estado actual) updated to 2026-05-08 with current
progress: doctrina cerrada, eidos en producción, SoundChannel
eager-init, switch migrated, etc. "Para profundizar" §14 points at
the canonical guide.
- morfo/README.md — Step 5.5 added covering the doctrinal event
shape with all fields (semantic.family, .verb, .target, .sequence,
.intent) and the two naming shapes ({verb}-{variant} and
{family}-{verb}).
- sema/README.md — verbs section restructured to Record-by-family
matching the runtime; documents the verbs that moved between
families per the canon. Naming shapes section updated with both
forms and validateEventName signature.
- CLAUDE.md — "Session hand-off" rewritten with the post-canon
state. Pointer at GUIA_IMPLEMENTACION_SEMAUIX.md as the canonical
source. Pending list refreshed: switch is the immediate next
component, persistence/a11ySemantic/polymorphism deferred until
real consumers appear.
Switch migration to the eidos wrapper pattern:
- morfo/components/switch.ts — adds events: [{ commit-toggle }] with
the doctrinal shape (verb=toggle, sequence=post, intent fromProp
binding to the 4 supported intents). New data-* (data-color with
the 6-token Toggle/Switch subset, data-readonly, data-invalid,
data-required) and corresponding aria-*. scope expanded to
['soma', 'sema'].
- soma/components/switch/types.ts — adds intent, color, readonly,
invalid, aria-labelledby props with full JSDoc. Subset constrained
per guide §3.1 (Toggle/Switch row).
- soma/components/switch/switch-provider.svelte.ts — runtime-direct,
Field integration via FieldProvider.get(), isDisabled/isReadonly/
isRequired/isInvalid OR-merge derivations, intent ↔ color
resolution (intent wins when evaluative), runtime.trigger(
'commit-toggle') in onclick.
- soma/components/switch/components/switch.svelte — wires the new
props through bindProps.
- eidos/components/switch/{switch.css, switch.svelte, types.ts,
index.ts, README.md} — full subdirectory pattern, mirroring
toggle. Recipe drops legacy success/warning/danger/info selectors;
declares the 6 doctrinal data-color values directly. Wrapper
auto-renders Switch.Thumb inside the track and exposes an optional
`thumb` snippet for in-thumb glyphs.
- eidos/components/switch.css (legacy flat) deleted; eidos/index.css
updated to import the subdirectory recipe.
- web/routes/switch/+page.svelte — interactive testbed with all soma
props as live controls + tabs (Live, Soma, Morfo, Sema, Eidos,
Notes). Mirrors toggle's structure.
npm run check holds at the 39-error baseline. Tests 217/217 green.
Pending:
- Migrate collapsible / dialog / drawer / popover / toast / avatar
to the eidos wrapper pattern.
- Persistence + holds-by-intent — defer until first signal.warn /
signal.alert consumer.
- a11ySemantic + polymorphic events — defer until concrete need.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
2. **Persistence + holds-by-intent** (guide §6) — defer until the
first concrete `signal.warn` / `signal.alert` consumer appears.
Today every signal is `transient` with a numeric hold. Need to add
`persistence: 'transient' | 'untilAction' | 'untilFix' | 'stateBound'`
to `SemanticSignal` + the holds-by-intent table per the canon.
3. **a11ySemantic per event** (guide §9) — defer until there's a
reduced-motion runtime helper + live-region helper to consume the
contract.
4. **Polymorphic events** (guide §5.3, `allowedFamilies` +
`defaultSemantic` ) — defer; no current component needs polymorphism.
5. The docs site's topbar prefs (sound mute toggle, theme switcher)
are wired up but the sound mute does NOT yet drive
`SoundChannel.masterGain` . Wiring belongs on layout.svelte's `$effect` .
Baseline `npm run check` shows 39 pre-existing errors in test files
docs + switch: align active docs to canon, migrate switch to eidos wrapper
Phase 4 (docs alignment with the canonical guide):
- active_architecture.md — Dialog example refactored to the new event
shape (target inside semantic, explicit verb + sequence). Verbs
table grouped by family with the post-canon vocabulary (select/
toggle moved to commit, edit removed from handle, new verbs added).
Section 10 (Estado actual) updated to 2026-05-08 with current
progress: doctrina cerrada, eidos en producción, SoundChannel
eager-init, switch migrated, etc. "Para profundizar" §14 points at
the canonical guide.
- morfo/README.md — Step 5.5 added covering the doctrinal event
shape with all fields (semantic.family, .verb, .target, .sequence,
.intent) and the two naming shapes ({verb}-{variant} and
{family}-{verb}).
- sema/README.md — verbs section restructured to Record-by-family
matching the runtime; documents the verbs that moved between
families per the canon. Naming shapes section updated with both
forms and validateEventName signature.
- CLAUDE.md — "Session hand-off" rewritten with the post-canon
state. Pointer at GUIA_IMPLEMENTACION_SEMAUIX.md as the canonical
source. Pending list refreshed: switch is the immediate next
component, persistence/a11ySemantic/polymorphism deferred until
real consumers appear.
Switch migration to the eidos wrapper pattern:
- morfo/components/switch.ts — adds events: [{ commit-toggle }] with
the doctrinal shape (verb=toggle, sequence=post, intent fromProp
binding to the 4 supported intents). New data-* (data-color with
the 6-token Toggle/Switch subset, data-readonly, data-invalid,
data-required) and corresponding aria-*. scope expanded to
['soma', 'sema'].
- soma/components/switch/types.ts — adds intent, color, readonly,
invalid, aria-labelledby props with full JSDoc. Subset constrained
per guide §3.1 (Toggle/Switch row).
- soma/components/switch/switch-provider.svelte.ts — runtime-direct,
Field integration via FieldProvider.get(), isDisabled/isReadonly/
isRequired/isInvalid OR-merge derivations, intent ↔ color
resolution (intent wins when evaluative), runtime.trigger(
'commit-toggle') in onclick.
- soma/components/switch/components/switch.svelte — wires the new
props through bindProps.
- eidos/components/switch/{switch.css, switch.svelte, types.ts,
index.ts, README.md} — full subdirectory pattern, mirroring
toggle. Recipe drops legacy success/warning/danger/info selectors;
declares the 6 doctrinal data-color values directly. Wrapper
auto-renders Switch.Thumb inside the track and exposes an optional
`thumb` snippet for in-thumb glyphs.
- eidos/components/switch.css (legacy flat) deleted; eidos/index.css
updated to import the subdirectory recipe.
- web/routes/switch/+page.svelte — interactive testbed with all soma
props as live controls + tabs (Live, Soma, Morfo, Sema, Eidos,
Notes). Mirrors toggle's structure.
npm run check holds at the 39-error baseline. Tests 217/217 green.
Pending:
- Migrate collapsible / dialog / drawer / popover / toast / avatar
to the eidos wrapper pattern.
- Persistence + holds-by-intent — defer until first signal.warn /
signal.alert consumer.
- a11ySemantic + polymorphic events — defer until concrete need.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
unrelated to this work. Tests are 217/217 green across uix.
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
## Session hand-off — 2026-05-26 (sema canon + soma emission + READMEs)
Sprint completing the alignment of the project with the book *Diseñando lo que ocurre* . Nine commits closed P1 #3 , P1 #4 and P1 #5 of the audit-codex:
```
504780ad expression field + sema coverage check
2d562f37 11 sema packs + doctrina samples (D.5/D.6/D.7)
826ca2bf D.8 channels scope doctrine
43b15372 picker-shell INTERNAL (P1 #5 closed)
66318c47 tree-view target → branch for emerge events
adf89a08 batch A — soma emission for 7 packs-shipped components
0784cae5 batch B — 8 components with sema scope, no pack
cbf76b66 batch C — drag-drop + virtual-list/grid
7afa7057 23 component READMEs with Sema events sections
```
**Architectural deltas from this sprint:**
- **`Morfo.expression`** new field (`'pack' | 'family-default' | 'delegated' | 'none'`) declares how each morfo with declared events materialises its perceptual signature. Schema-validated; lint enforces coverage. See `src/uix/morfo/types.ts` + `LIBRO_VARIACIONES_Y_EXTENSIONES.md` D.4.
- **`SemaFamily` is now 8** (added `delegate` per book cap. 29). `SEMA_FAMILY_POLICY` carries two axes (`intentRequirement` + `intentGuidance` ) — see updated section above.
- **`SEMA_VERBS`** extended with `signal.inform` , `commit.unselect` , contextual verbs (`apply`, `partial` , `block` , `move` , `upload` , `acknowledge` , `confirm` ).
- **38 sema packs** under `src/uix/sema/components/*.ts` compose 9 canonical tuning profiles (`form.commit.soft/subtle`, `form.toggle.silent` , `tooltip.silent` , `emerge.soft` , `emerge.exit/.soft` , `emerge.medium` , `emerge.dismiss.passive` , `tabs.select.soft` ). Apps override at `defineEngineSemantic({ overrides: { cascade: [...] } })` .
- **Soma emission cabled** in 18 components (toggle-group, menubar, navigation-menu, dropdown-menu, context-menu, tree-view, tree-grid, listbox, grid-list, table, feed, command, carousel, announce, clipboard, drag-drop, virtual-list, virtual-grid). Pattern: emit from the central state-mutator with `fallbackTarget` resolving the specific element so the cascade matches the right instance.
- **`handle-scroll*` intentionally NOT emitted** in virtual-list / virtual-grid — family.handle activates haptic only; emitting on every pixel of scroll would buzz the device nonstop. Apps that want scroll-feedback wire their own throttled emit. Documented in both READMEs.
- **picker-shell relocated** from `src/uix/morfo/components/` to `src/uix/morfo/internal/` — declares its INTERNAL status by file location. Apps never write `<PickerShell>` ; the five composite pickers (date / date-range / time / time-range / color) re-export the shell parts under their own namespace. README added at `src/uix/eidos/components/picker-shell/README.md` .
- **`LIBRO_VARIACIONES_Y_EXTENSIONES.md`** is the authoritative registry for project decisions vs the book canon. Sections D.4 (`expression` field), D.5 (toggles soft-tuned packs), D.6 (menus/trees packs), D.7 (samples doctrine — `SOUND_LIBRARY` = resources, `SOUND_TUNINGS` = canon, packs compose tunings never samples; `sampleOverlay` rejected permanently), D.8 (channels scope — `sound` + `haptic` are the only canonical runtime channels; ARIA structural lives in morfo, ARIA dynamic in soma, visual in eidos — never canonized as channels).
- **23 soma component READMEs** now include a `## Sema events` table with event / family / verb / target / intent / when + pack reference + doctrinal notes for the verb-rename corrections applied across the sprint.
**Verification at hand-off**: `npm run morfo:vocabulary` EXIT 0 (clean). `npx vitest run src/uix/sema src/uix/morfo` 195/195. `npx vitest run src/uix/soma` 419/419. Pre-existing words/* type errors unchanged (separate dev track).
**What's left from the audit-codex**: P2 (34 demos NEEDS-WORK) — explicitly out of scope (full refactor of demos + web routes pending separately).
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
---
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
# Behavioral Guidelines
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
These reduce common LLM coding mistakes. They bias toward caution over speed —
for trivial tasks, use judgment.
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
## 1. Think before coding
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
Don't assume. Don't hide confusion. Surface tradeoffs.
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
- State assumptions explicitly. If uncertain, ask.
- If multiple interpretations exist, present them — don't pick silently.
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
- If a simpler approach exists, say so. Push back when warranted.
- If something is unclear, stop. Name what's confusing. Ask.
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
## 2. Simplicity first
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
Minimum code that solves the problem. Nothing speculative.
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
- No features beyond what was asked.
- No abstractions for single-use code.
- No "flexibility" or "configurability" that wasn't requested.
- No error handling for impossible scenarios.
- If you write 200 lines and it could be 50, rewrite it.
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
## 3. Surgical changes
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
Touch only what you must. Clean up only your own mess.
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
- Don't "improve" adjacent code, comments, or formatting.
- Don't refactor things that aren't broken.
- Match existing style, even if you'd do it differently.
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
- If you notice unrelated dead code, mention it — don't delete it.
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
When your changes create orphans, remove the imports / variables / functions
your changes made unused. Don't remove pre-existing dead code unless asked.
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
## 4. Goal-driven execution
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
Define success criteria. Loop until verified.
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
- "Add validation" → "Write tests for invalid inputs, then make them pass."
- "Fix the bug" → "Write a test that reproduces it, then make it pass."
- "Refactor X" → "Ensure tests pass before and after."
soma: dias date library, Calendar + RangeCalendar, Command fixes, doc updates
**Date library reorganisation** (no new third-party dependency)
- New `src/lib/util/dias/` with `_vendor/` (Adobe Apache 2.0 vendored code,
ATTRIBUTION.md preserved) and a public facade split into `types`,
`values`, `calendars`, `queries`, `operations`, `parse`, `format`,
`index`. Consumers import only from `$lib/util/dias`.
- All date-related `Intl` consolidated in `dias/format.ts` —
`DateFormatter`, cache, `resolveDateOrder`, `resolveHourCycle`,
placeholders, defaults.
- `ext/dates` now a thin reactive wrapper delegating to `dias`.
- Aligned App-layer `HourCycle` to canonical numeric form `12 | 24`
(matches `Intl.DateTimeFormat`'s `hour12`). Removed string form
`'12h' | '24h'` from `ext/app/types`, `ext/dates`,
`ext/presentation/locale-defaults`, and their tests.
- Repointed every consumer: `soma/external/dates`,
`terra/external/dates`, eight `routes/test/*` pages.
- Legacy `src/lib/util/dates/` left untouched by request.
**Tier 3 components**
- `soma/components/calendar/` — 14 parts, single + multiple selection,
`MonthSelect`/`YearSelect`, ISO/simple week numbers,
`isDateHoliday` matcher, `data-weekend` flag, navigation live-
region, RTL flip, full ARIA, 27-item checklist verified.
- `soma/components/range-calendar/` — 14 parts, range selection with
live hover preview (novel vs ark/bits/radix/react-aria), `minDays`
/ `maxDays` / `allowSingleDay`, third-click deselects only the
clicked endpoint.
- Test pages at `/test/soma/calendar` and `/test/soma/range-calendar`
with seven demos each. Links added to the soma index under a new
"Dates" section.
- READMEs with anatomy, parts, props, ARIA, keyboard, data-attrs, and
a competitive comparison table.
**Command fixes**
- Resolved O(N^2) reactive cascade: introduced
`visibleSet: $derived<Set<string>>` on the root provider;
per-item `isVisible` is now an O(1) `has()` lookup instead of
calling back into the provider, which was re-running all items'
derivations on every `itemsVersion` bump.
- Added `dir` prop with fallback to `soma.presentation.getDir()`;
horizontal arrows flip in RTL via `getDirectionalKeys`; root
receives `dir` attribute.
**Doc updates (session outcomes)**
- `CLAUDE.md`: replaced obsolete `@/glob/lib` date references with
`$lib/util/dias`; added canonical date-layer section; reinforced
`Provider` export rule and `data-{component}[-{part}]` naming
(never `data-soma-*`); clarified translation convention.
- `src/uix/soma/COMPONENT_GUIDE.md`: new checklist items 26
(component README required) and 27 (grep for data-attr
consistency); new Common Mistakes 11 (`data-soma-*` prefix), 12
(wrong date module), 13 (string `HourCycle`).
- `src/uix/soma/SOMA_ARCHITECTURE.md`: clarified data-attr naming
(canonical emitter is `createAttrs`; validator checks enum
values only, not names); new section covering date types and
formatting through `$soma/external/dates` → `$lib/util/dias`;
documented numeric `HourCycle`.
**Infrastructure**
- `PrimitiveHeaderAttributes` and `PrimitiveSelectAttributes` added
to `$soma/types`.
- `getLastFirstDayOfWeek`, `getNextLastDayOfWeek` re-exported from
`$soma/external/dates`.
- `calendar.*` and `range-calendar.*` translation blocks added to
`$soma/core/langs.ts`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
cleanup phase D: rewrite CLAUDE.md to reflect new architecture
Drops references to terra/air/lib (deleted in phases A-B). New
architecture section: arts/libs/svrs at the runtime + helper layer;
uix/{morfo, sema, soma, eidos, active-uix} at the UI layer, with
morfo as the cross-layer contract (compileMorfo + cached
contracts.cssSelectors). Path-alias table updated to match
svelte.config.js / vite.config.ts after phase C. Build/test commands
point at the new test paths.
Critical-rules block: drop "NEVER modify terra source code" (terra is
gone) and the soma-audit references (legacy markdown). Keep "NEVER
delete files without explicit instruction" — this cleanup happened
under explicit user direction, the rule still holds.
Auto-memory in ~/.claude/projects/...: dropped feedback_terra_readonly,
feedback_air_wrapper_children, feedback_follow_terra_patterns,
feedback_architecture_fidelity, feedback_layout_kills_outlines (refs
deleted src/routes/layout.css), feedback_check_dias_before_porting
(consolidated into feedback_date_library), project_terra_air_dead,
project_session_state, project_activeapp_refactor. Added
project_active_uix_cleanup with the new state. Updated
feedback_date_library to point at \$libs/days.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
Strong success criteria let you loop independently. Weak criteria require
constant clarification.