Commit Graph

37 Commits

Author SHA1 Message Date
2663dfb095 Add SVG cover art to SX Manifesto as s-expression
Soviet constructivist poster with paper texture filters, grid lines,
aged stain spots, and "(<x>)" symbol in red.

Add missing SVG filter primitive tags to both server (html.py) and
client (sx.js): feTurbulence, feColorMatrix, feBlend,
feComponentTransfer, feFuncR/G/B/A, feDisplacementMap, feComposite,
feFlood, feImage, feMorphology, feSpecularLighting, feDiffuseLighting,
fePointLight, feSpotLight, feDistantLight.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 13:34:58 +00:00
ccd9b969ea Add 40 more links to SX Manifesto, author: Markdown & Anglebrackets
Link HTML, CSS, JavaScript, framework, separation of concerns, markup,
weak typing, prototype chains, declarative, Turing-complete, DOM,
homoiconicity, validate forms, server-side execution, signals, hooks,
reconciler, tree-shaking, code-splitting, HMR, transpilation, scoping,
composition model, template literals, inline styles, node_modules,
structured data, dependency tree, breaking changes, developer experience,
angle bracket, and "designed in ten days". Remove original source link.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 13:27:43 +00:00
7325bb9ecf Fix ParseError in SX Manifesto: bare backslash + unclosed li
- Wrap \"this\" in sx string quotes so backslash escapes are inside a string
- Remove stray quote before closing paren on wire protocol li item

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 13:15:09 +00:00
6f3562707a Change language to paradigm where referring to SX in the manifesto
SX is a paradigm, not a language. Changed 7 instances where "language"
referred to SX itself: "one paradigm since 1958", "the paradigm is the
framework", "not a framework but a paradigm", "paradigms do not have
breaking changes", "the paradigm itself provides", "a paradigm that
does not require a migration guide", "distinct from the paradigm".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 13:00:02 +00:00
2609e782fc Change s-expressions to s-expressionism where it refers to the movement
In the SX Manifesto: "the spectre of s-expressionism", "S-expressionism
abolishes", "S-expressionism needs no ecosystem", "S-expressionism
resolves the CSS question", "The s-expressionist revolution".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 12:57:51 +00:00
28cbe60dc6 Add 78 links throughout the SX Manifesto essay
External links to Google, Meta, webpack, Vercel, Stack Overflow, React,
Vue, Angular, Svelte, SolidJS, Qwik, Astro, Next, Nuxt, Remix, Gatsby,
Rollup, Parcel, esbuild, Vite, Turbopack, TypeScript, Emacs, Clojure,
npm, Lisp, Scheme, Brendan Eich, Tailwind, Sass, Less, PostCSS, XML,
XSLT, JSON, YAML, TOML, JSX, SFCs, Lodash, Moment, Axios, left-pad,
is-odd, CSS-in-JS, virtual DOM, Vicar of Bray, CGI-bin, and Marx.

Internal links to /docs/components, /docs/evaluator, /docs/primitives,
/docs/css, /essays/on-demand-css, /protocols/wire-format.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 12:55:12 +00:00
0f82294dc1 Update /docs/css page with CSSX native style primitives docs
Document css primitive, style atoms, variants, defstyle, defkeyframes,
and on-demand delivery protocol.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 12:50:07 +00:00
28388540d5 Fix unquoted (code) element in SX manifesto essay
The (code :class "text-violet-700" ...) was embedded inside a string
child of (p), causing the SX parser to see text-violet-700 as a bare
symbol. Close the text string before the (code) element so it becomes
a proper child of the paragraph.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 12:09:41 +00:00
5fac47c132 Fix sx-manifesto EvalError: close string before italic span
The em span variable was embedded inside an unclosed sx string,
causing the " before "italic" to close the outer string and
leaving italic as an undefined bare symbol.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 11:57:28 +00:00
213421516e Add SSE, response headers, view transitions, and 5 new sx attributes
Implement missing SxEngine features:
- SSE (sx-sse, sx-sse-swap) with EventSource management and auto-cleanup
- Response headers: SX-Trigger, SX-Retarget, SX-Reswap, SX-Redirect,
  SX-Refresh, SX-Location, SX-Replace-Url, SX-Trigger-After-Swap/Settle
- View Transitions API: transition:true swap modifier + global config
- every:<time> trigger for polling (setInterval)
- sx-replace-url (replaceState instead of pushState)
- sx-disabled-elt (disable elements during request)
- sx-prompt (window.prompt, value sent as SX-Prompt header)
- sx-params (filter form parameters: *, none, not x,y, x,y)

Adds docs (ATTR_DETAILS, BEHAVIOR_ATTRS, headers, events), demo
components in reference.sx, API endpoints (prompt-echo, sse-time),
and 27 new unit tests for engine logic.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 11:55:21 +00:00
3bffc212cc Fix sx docs load_sx_dir path to point to sxc/ not sxc/pages/
The .sx component files (home.sx, docs.sx, etc.) live in sxc/, but
the path was pointing to sxc/pages/ after the move from sx_components.py.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 11:35:22 +00:00
5bb02b7dd5 Move 7 htmx-equivalent attrs from SX_UNIQUE_ATTRS to BEHAVIOR_ATTRS
These are sx implementations of htmx attributes (boost, preload,
preserve, indicator, validate, ignore, optimistic), not unique to sx.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 11:26:24 +00:00
16f0908ec9 Move SX docs rendering from sx_components.py to sxc/pages (phase 8)
Consolidate 86 component rendering functions into sxc/pages/__init__.py,
update 37 import sites in routes.py, remove app.py side-effect imports,
and delete sx/sxc/sx_components.py.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 11:24:26 +00:00
31a8b755d9 Implement 7 missing sx attributes: boost, preload, preserve, indicator, validate, ignore, optimistic
Add sx-preserve/sx-ignore (morph skip), sx-indicator (loading element),
sx-validate (form validation), sx-boost (progressive enhancement),
sx-preload (hover prefetch with 30s cache), and sx-optimistic (instant
UI preview with rollback). Move all from HTMX_MISSING_ATTRS to
SX_UNIQUE_ATTRS with full ATTR_DETAILS docs and reference.sx demos.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 11:18:31 +00:00
8578eb525e Change sx logo to (<x>)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 10:56:50 +00:00
96a4f56424 Fix extra closing paren in SX manifesto and TCO essays
Both essays had one excess `)` causing ParseError when navigating
via HTMX (oob_page_sx path).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 10:55:51 +00:00
da8d2e342f Continuations essay: add argument that they're easier to reason about than workarounds
Without call/cc you get callback pyramids, state machines, command
pattern undo stacks, Promise chains, and framework-specific hooks —
each a partial ad-hoc reinvention of continuations with its own edge
cases. The complexity doesn't disappear; it moves into user code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 10:42:08 +00:00
fd67f202c2 Add Continuations essay to SX docs
Covers server-side (suspendable rendering, streaming, error boundaries),
client-side (linear async flows, wizard forms, cooperative scheduling,
undo), and implementation path from the existing TCO trampoline. Updates
TCO essay's continuations section to link to the new essay instead of
dismissing the idea. Fixes "What sx is not" to acknowledge macros + TCO.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 10:41:22 +00:00
5069072715 Add TCO to evaluator, update SX docs messaging
Evaluator: add _Thunk + _trampoline for tail-call optimization in
lambdas, components, if/when/cond/case/let/begin. All callers in
html.py, resolver.py, handlers.py, pages.py, jinja_bridge.py, and
query_registry.py unwrap thunks at non-tail positions.

SX docs: update tagline to "s-expressions for the web", rewrite intro
to reflect that SX replaces most JavaScript need, fix "What sx is not"
to acknowledge macros and TCO exist.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 10:31:31 +00:00
a3318b4fd7 Fix syntax error: double-escaped apostrophes in essay strings
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 10:23:05 +00:00
8a945db37b Add "The SX Manifesto" essay to sx docs app
A satirical essay in the style of The Communist Manifesto, recasting
the historic struggle between bourgeoisie and proletariat as the war
between HTML, JS, and CSS — with frameworks as petty-bourgeois lackeys
and s-expressions as the revolutionary force that abolishes the
language distinction itself.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 10:11:59 +00:00
44503a7d9b Add Client Reactivity and SX Native essays to sx docs app
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 00:11:48 +00:00
e085fe43b4 Replace sx_call() with render_to_sx() across all services
Python no longer generates s-expression strings. All SX rendering now
goes through render_to_sx() which builds AST from native Python values
and evaluates via async_eval_to_sx() — no SX string literals in Python.

- Add render_to_sx()/render_to_html() infrastructure in shared/sx/helpers.py
- Add (abort status msg) IO primitive in shared/sx/primitives_io.py
- Convert all 9 services: ~650 sx_call() invocations replaced
- Convert shared helpers (root_header_sx, full_page_sx, etc.) to async
- Fix likes service import bug (likes.models → models)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 00:08:33 +00:00
0554f8a113 Refactor sx.js: extract string renderer, deduplicate helpers, remove dead code
Extract Node-only string renderer (renderToString, renderStr, etc.) to
sx-test.js. Add shared helpers (_processOOBSwaps, _postSwap, _processBindings,
_evalCond, _logParseError) replacing duplicated logic. Remove dead isTruthy
and _sxCssKnown class-list fallback. Compress section banners. sx.js goes
from 2652 to 2279 lines (-14%) with zero browser-side behavior change.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 23:00:58 +00:00
293f7713d6 Auto-mount defpages: eliminate Python route stubs across all 9 services
Defpages are now declared with absolute paths in .sx files and auto-mounted
directly on the Quart app, removing ~850 lines of blueprint mount_pages calls,
before_request hooks, and g.* wrapper boilerplate. A new page = one defpage
declaration, nothing else.

Infrastructure:
- async_eval awaits coroutine results from callable dispatch
- auto_mount_pages() mounts all registered defpages on the app
- g._defpage_ctx pattern passes helper data to layout context

Migrated: sx, account, orders, federation, cart, market, events, blog

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 19:03:15 +00:00
0c9dbd6657 Add attribute detail pages with live demos for SX reference
Per-attribute documentation pages at /reference/attributes/<slug> with:
- Live interactive demos (demo components in reference.sx)
- S-expression source code display
- Server handler code shown as s-expressions (defhandlers in handlers/reference.sx)
- Wire response display via OOB swaps on demo interaction
- Linked attribute names in the reference table

Covers all 20 implemented attributes (sx-get/post/put/delete/patch,
sx-trigger/target/swap/swap-oob/select/confirm/push-url/sync/encoding/
headers/include/vals/media/disable/on:*, sx-retry, data-sx, data-sx-env).

Also adds sx-on:* to BEHAVIOR_ATTRS, updates REFERENCE_NAV to link
/reference/attributes, and makes /reference/ an index page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 17:12:57 +00:00
c243d17eeb Migrate all apps to defpage declarative page routes
Replace Python GET page handlers with declarative defpage definitions in .sx
files across all 8 apps (sx docs, orders, account, market, cart, federation,
events, blog). Each app now has sxc/pages/ with setup functions, layout
registrations, page helpers, and .sx defpage declarations.

Core infrastructure: add g I/O primitive, PageDef support for auth/layout/
data/content/filter/aside/menu slots, post_author auth level, and custom
layout registration. Remove ~1400 lines of render_*_page/render_*_oob
boilerplate. Update all endpoint references in routes, sx_components, and
templates to defpage_* naming.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 14:52:34 +00:00
a8c0741f54 Add SX editor to post edit page, prevent sx_content clearing on save
- Add sx_content to _post_to_edit_dict so edit page receives existing content
- Add SX/Koenig editor tabs, sx-editor mount point, and SxEditor.mount init
- Only pass sx_content to writer_update when form field is present (prevents
  accidental clearing when editing via Koenig-only path)
- Add csrf_exempt to example API POST/DELETE/PUT demo endpoints
- Add defpage infrastructure (pages.py, layouts.py) and sx docs page definitions
- Add defhandler definitions for example API handlers (examples.sx)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 10:23:33 +00:00
4098c32878 Fix value-select: return raw option elements instead of component
The ~value-options component wrapped options in a fragment that didn't
render correctly inside a <select> innerHTML swap. Return plain
(option) elements directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 08:54:28 +00:00
5dd1161816 Move example CSS to basics.css, pretty-print wire response, update sx logo
- Move .sx-fade-in and .sx-loading-btn CSS from inline (style) tags to
  basics.css so they go through the on-demand CSS registry
- Pretty-print sx source in wire response display (not all on one line)
- Change sx logo from </> icon to (</>) text

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 08:45:54 +00:00
002cc49f2c Add 21 new interactive examples to sx docs site (27 total)
Loading: lazy loading, infinite scroll, progress bar
Forms: active search, inline validation, value select, reset on submit
Records: edit row, bulk update
Swap/DOM: swap positions, select filter, tabs
Display: animations, dialogs, keyboard shortcuts
HTTP: PUT/PATCH, JSON encoding, vals & headers
Resilience: loading states, request abort (sync replace), retry

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 02:26:10 +00:00
8024fa5b13 Live wire response + component display with OOB swaps on all examples
- All 6 examples show Component and Wire response as placeholders that
  fill with actual content when the demo is triggered (via OOB swaps)
- Wire response shows full wire content including component definitions
  (when not cached) and CSS style block
- Component display only includes defs the client doesn't already have,
  matching real sx_response() behaviour
- Add "Clear component cache" button to reset localStorage + in-memory
  component env so next interaction shows component download
- Rebuild tw.css with Tailwind v3.4.19 including sx content paths
- Optimize sx_response() CSS scanning to only scan sent comp_defs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 01:54:45 +00:00
ea18a402d6 Remove Prism language-* classes from code block components
highlight.py handles syntax coloring with Tailwind classes —
Prism classes were conflicting and are not needed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 01:14:11 +00:00
e4e43177a8 Fix code blocks + add violet bg classes to tw.css
- Pass :code keyword to ~doc-code and ~example-source components
  (highlighted content was positional but components use &key code)
- Rebuild tw.css (v3.4.19) with sx/sxc and sx/content in content paths
  so highlight.py classes (text-violet-600, text-rose-600, etc.) are included
- Add bg-violet-{100-500} classes for the sx app's violet menu bar
- Add highlight.py custom syntax highlighter (sx, python, bash)

IMPORTANT: tw.css must contain bg-violet-{100-500} rules for the sx
app's menu bar. Do not rebuild tw.css without ensuring violet classes
are included (via safelist or content paths).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 01:13:01 +00:00
13bcf755f6 Add OOB header swaps for sx docs navigation + enable OAuth + fragments
- OOB nav updates: AJAX navigation now swaps both menu bar levels
  (main nav highlighting + sub-nav with current page) using the same
  oob_header_sx/oob_page_sx pattern as blog/market/events
- Enable OAuth for sx and test apps (removed from _NO_OAUTH, added sx
  to ALLOWED_CLIENTS, added app_urls for sx/test/orders)
- Fetch real cross-service fragments (cart-mini, auth-menu, nav-tree)
  instead of hardcoding empty values
- Add :selected param to ~menu-row-sx for white text current-page label
- Fix duplicate element IDs: use menu-row-sx child_id/child mechanism
  instead of manual header_child_sx wrappers
- Fix home page copy: "Server-rendered DOM over the wire (no HTML)"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 23:22:01 +00:00
3d55145e5f Fix illegible code blocks: use light background to match Prism theme
The existing prism.css sets color:black on code elements. Dark
bg-stone-900 backgrounds made text invisible. Switched to bg-stone-50
with a border to work with the light Prism theme.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 21:38:20 +00:00
03196c3ad0 Add sx documentation app (sx.rose-ash.com)
New public-facing service documenting the s-expression rendering engine.
Modelled on four.htmx.org with violet theme, all content rendered via sx.

Sections: docs, reference, protocols, examples (live demos), essays
(including "sx sucks"). No database — purely static documentation.

Port 8012, Redis DB 10. CI and deploy.sh updated with app_dir() mapping
for sx_docs -> sx/ directory. Caddy reverse proxy entry added separately.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 21:25:52 +00:00