From 89b1476303482cbda03899598d9964a039bfd876 Mon Sep 17 00:00:00 2001
From: Brent Rager
Date: Tue, 25 Aug 2026 22:09:25 -0400
Subject: [PATCH] =?UTF-8?q?Drop=20the=20ui=20module=20and=20shared/=20?=
=?UTF-8?q?=E2=80=94=20nothing=20imported=20them?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This crate carried a byte-identical copy of SmooAI/ui's design system and
described itself as that crate's successor. The migration was never
finished, and an org-wide search found NOTHING importing
`smooai_client_shared::ui` — the real design-system consumers (smooblue,
observability-studio) depend on SmooAI/ui directly, and this crate's one
consumer, the `th` CLI, builds `features = ["auth"]` and never touched it.
Two copies of the same files is a drift surface, and it had already
drifted: this crate spent weeks serving a monogram missing its inner 'S'
and a styles.css that had lost the whole `.input` family, with nothing red.
Deleting the copy removes the failure mode instead of detecting it.
Removed: rust/src/ui/, shared/, rust/build.rs (it existed only to generate
the tokens module), the serde_json build-dependency, the ../shared/**
include entries, and the `ui` feature. `auth` is now the only feature and
stays opt-in — it is what the one consumer asks for, and its tree (tokio,
reqwest, axum) is heavy enough to be explicit about.
Docs rewritten: lib.rs and README described a design-system crate. They now
describe an auth library and point at SmooAI/ui for the design system.
SmooAI/ui#10 removes the now-pointless shared-drift gate and lands first, so
neither repo has a red window.
Verified: cargo fmt --check, clippy (default + all-features, --all-targets
-D warnings), cargo test --all-features (28 passed), check-module-tree.
Co-Authored-By: Claude Fable 5
Claude-Session: https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC
---
.github/workflows/rust.yml | 11 +-
README.md | 105 ++-------
rust/Cargo.toml | 33 +--
rust/build.rs | 17 --
rust/src/lib.rs | 61 ++----
rust/src/ui/mod.rs | 79 -------
shared/monogram.svg | 3 -
shared/styles.css | 425 -------------------------------------
shared/tokens.json | 140 ------------
shared/tokens_codegen.rs | 234 --------------------
shared/tokens_css_check.rs | 140 ------------
11 files changed, 54 insertions(+), 1194 deletions(-)
delete mode 100644 rust/build.rs
delete mode 100644 rust/src/ui/mod.rs
delete mode 100644 shared/monogram.svg
delete mode 100644 shared/styles.css
delete mode 100644 shared/tokens.json
delete mode 100644 shared/tokens_codegen.rs
delete mode 100644 shared/tokens_css_check.rs
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index 55a4a63..5b77bcb 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -31,15 +31,18 @@ jobs:
# `--all-targets` so tests and examples are linted too; `-p`-scoped or
# target-less clippy silently skips test code.
- - name: Clippy (default features — the no_std `ui` build)
+ # Default features are now empty (`auth` is opt-in), so this lints the
+ # bare crate; the all-features run below is the one that covers auth.
+ - name: Clippy (default features)
run: cargo clippy --all-targets -- -D warnings
- name: Clippy (all features)
run: cargo clippy --all-targets --all-features -- -D warnings
- # Run BOTH feature sets: the `ui` tests are the only ones in the default
- # build, and the `auth` tests only exist behind the feature — running one
- # configuration would report a green suite that never touched half the crate.
+ # Run BOTH feature sets. Every test lives behind `auth`, so the default
+ # run reports "0 passed; ok" — which is exactly why the all-features run
+ # below has to exist: a single default-only run would be a green suite
+ # that executed nothing.
- name: Test (default features)
run: cargo test
diff --git a/README.md b/README.md
index 374f6ca..def3286 100644
--- a/README.md
+++ b/README.md
@@ -12,49 +12,27 @@
-
+
---
-> **Every Smoo AI Rust client needs the same three things — so they live in one crate.** Design tokens + the smoo monogram (`ui`), the full Supabase auth story — browser OAuth with PKCE, email+password, session refresh, M2M `client_credentials` — with a shared 0600 on-disk credential store (`auth`), One Rust crate, feature-gated so the bare `ui` build stays `no_std` with zero dependencies. Consumed in production by the [`th` CLI](https://github.com/SmooAI/smooth). **Rust-only today; not yet on crates.io** — npm / NuGet / PyPI siblings are planned, not built.
+> **One Supabase auth story, shared by every Smoo AI Rust client.** Browser OAuth with PKCE and a localhost callback, email+password for headless environments, refresh-token rotation, the M2M `client_credentials` grant — and one `0600` on-disk credential store holding user and machine sessions side by side. Consumed in production by the [`th` CLI](https://github.com/SmooAI/smooth). **Rust-only today; not yet on crates.io** — a git dependency is the install path.
## What is this?
-A Smoo AI Rust client (smooblue, observability-studio, `th`, `smoo admin`, …) typically needs the same three things:
-
-1. **Design tokens + monogram** — so the UI looks like Smoo AI.
-2. **Auth** — Supabase user OAuth (browser login), email+password, session refresh, AND M2M `client_credentials` grant (service accounts), with one shared on-disk `CredentialsStore`.
-3. **LLM access** — exchanging a user session JWT for an org-scoped `llm.smoo.ai` bearer. *(Not built — there is deliberately no feature flag for it yet; see [Honest status](#honest-status).)*
-
-Each of these has been re-implemented in every consumer at least once. This crate makes them one dependency. It absorbs the standalone [`SmooAI/ui`](https://github.com/SmooAI/ui) crate: `ui` is one module alongside `auth` — same constants, same paths. This repo's `shared/` is the **source of truth** for the design system; SmooAI/ui carries a copy, and a CI gate there fails if the two ever diverge.
-
-```mermaid
-%%{init: {'theme':'base','themeVariables':{
- 'background':'#020618','primaryColor':'#0b1426','primaryTextColor':'#e6edf6','primaryBorderColor':'#2b3a52',
- 'lineColor':'#7c8aa0','secondaryColor':'#0b1426','tertiaryColor':'#0b1426','fontFamily':'ui-sans-serif, system-ui, sans-serif',
- 'clusterBkg':'#0b1426','clusterBorder':'#22304a'}}}%%
-flowchart LR
- subgraph CRATE["smooai-client-shared"]
- UI["ui (default) STYLES · MONOGRAM_SVG · tokens::* zero deps · no_std"]
- AUTH["auth (feature) oauth · password · refresh · m2m CredentialsStore (0600)"]
- end
- AUTH -->|"PKCE localhost callback"| SB[("Supabase /auth/v1")]
- AUTH -->|"client_credentials"| TOK[("auth.smoo.ai/token")]
- TH["th CLI (git dep, features=[auth])"] --> AUTH
- APPS["smooblue · desktop apps"] -.->|"can consume"| UI
-
- classDef warm fill:#f49f0a,stroke:#ff6b6c,color:#1a0f00;
- classDef teal fill:#00a6a6,stroke:#00c2c2,color:#011;
- class AUTH warm
- class UI,TH teal
-```
+The auth plumbing every Smoo AI Rust client needs identically, in one crate instead of re-implemented per app:
----
+1. **Sign a human in** — browser OAuth (PKCE + localhost callback), or email+password where no browser exists.
+2. **Keep them signed in** — refresh-token grant with Supabase's rotation handled, plus a renew-ahead window.
+3. **Sign a machine in** — the RFC 6749 `client_credentials` grant against `auth.smoo.ai/token`.
+4. **Put the credentials somewhere sane** — a `0600` store holding user and M2M sessions together.
+
+> **This crate used to carry the design system too**, and called itself [`SmooAI/ui`](https://github.com/SmooAI/ui)'s successor. That migration was never finished: nothing ever imported `smooai_client_shared::ui`, while the real design-system consumers (smooblue, observability-studio) depended on `SmooAI/ui` directly. Two copies of the same files is a drift surface, and it had already drifted — this crate spent weeks serving a monogram missing its inner 'S'. The copy is gone. **`SmooAI/ui` owns the design system**; this crate is auth.
## Feature tour
@@ -65,7 +43,6 @@ flowchart LR
| ♻️ | [**Session refresh**](#-session-refresh) | `refresh_token` grant with rotation handling + a renew-ahead window |
| 🤖 | [**M2M `client_credentials`**](#-m2m-client_credentials) | RFC 6749 service-account grant against `auth.smoo.ai/token` |
| 💾 | [**`CredentialsStore`**](#-the-credentials-store) | One 0600 on-disk store for user + M2M sessions, side by side |
-| 🎨 | [**Design tokens**](#-design-tokens-ui) | The `smooai-ui` surface, verbatim, as the `ui` module |
All snippets below are the actual API, verified against `rust/src/`.
@@ -134,18 +111,6 @@ if let Some(creds) = store.load()? {
}
```
-### 🎨 Design tokens (`ui`)
-
-The full `smooai-ui` surface, lifted verbatim — canonical OKLCH stylesheet, monogram, and token constants for non-DOM code paths. Zero dependencies, `no_std` when built with only the default `ui` feature:
-
-```rust
-use smooai_client_shared::ui::{STYLES, MONOGRAM_SVG, tokens};
-
-let accent = tokens::SMOOAI_GREEN; // "oklch(0.657 0.112 194.8)"
-```
-
----
-
## Quickstart
**`smooai-client-shared` is not published to crates.io.** Consume it as a git dependency — this is exactly how the [`th` CLI](https://github.com/SmooAI/smooth) consumes it in production (rev-pinned, `features = ["auth"]`):
@@ -159,78 +124,36 @@ smooai-client-shared = { git = "https://github.com/SmooAI/client-shared.git", fe
| Feature | Adds | Pulls | Status |
| --- | --- | --- | --- |
-| `ui` (default) | `STYLES`, `MONOGRAM_SVG`, `tokens::*` | nothing — `no_std` | ✅ working |
| `auth` | Supabase OAuth + password + refresh, M2M, `CredentialsStore` | `tokio`, `reqwest`, `axum`, `serde`, … | ✅ working, 28 unit tests |
-An `llm` feature (JWT → `llm.smoo.ai` org-session exchange, pearl th-f7b20f) is **planned and deliberately absent**. It previously existed as a flag over a six-line doc-comment module: `--features llm` compiled and produced nothing, which is worse than an honest gap. It returns when there is code behind it.
-
-Run the tests yourself — 34 unit tests across `ui` + `auth` (OAuth callback/PKCE, token rotation, store round-trips, permission bits, token/CSS drift):
-
-```bash
-cd rust && cargo test --all-features
-```
-
-CI (`.github/workflows/rust.yml`) runs `cargo fmt --check`, `clippy --all-targets -D warnings` and the test suite in **both** feature configurations — the default `no_std` `ui` build and `--all-features` — plus a module-tree check that fails if any `.rs` file is unreachable from a `mod` declaration.
-
----
+`auth` is not a default. It is the crate's only surface and its one consumer always asks for it, but the tree it pulls in is heavy enough to be explicit about.
## Honest status
| Surface | Status |
| --- | --- |
-| **Rust `ui`** | ✅ Working — the `tokens` constants are **generated** from `shared/tokens.json` at build time, and cross-checked against `shared/styles.css` in both directions (every token matches its custom property; every colour the CSS declares has a token) |
| **Rust `auth`** | ✅ Working — OAuth PKCE localhost-callback (387 LOC), password grant, refresh with rotation, M2M, 0600 `CredentialsStore`; 28 unit tests; consumed by the `th` CLI in production |
| **Rust `llm`** | ❌ Not built — no module, no feature flag. Pearl th-f7b20f tracks it |
| **crates.io** | ❌ Not published — git dependency is the only install path |
-| **npm / NuGet / PyPI** | 📦 Planned, no code — the `src/`, `dotnet/`, `python/` directories in the layout below don't exist yet |
+| **npm / NuGet / PyPI** | 📦 Planned, no code — there is no `src/`, `dotnet/` or `python/` directory |
## Layout
```
client-shared/
-├── shared/ # cross-language source of truth
-│ ├── styles.css # OKLCH tokens + base component CSS
-│ ├── monogram.svg # smoo monogram
-│ ├── tokens.json # THE token source — the Rust `tokens` module is generated from it
-│ ├── tokens_codegen.rs # generator, run from rust/build.rs
-│ └── tokens_css_check.rs # asserts tokens.json <-> styles.css agree, both ways
└── rust/ # smooai-client-shared (git dependency; crates.io planned)
├── Cargo.toml
└── src/
├── lib.rs
- ├── ui/ # lifted verbatim from smooai-ui
└── auth/ # oauth · password · refresh · m2m · storage (feature = "auth")
```
npm (`src/`), NuGet (`dotnet/`), and PyPI (`python/`) packages are roadmap, not directories.
-## Migrating from `smooai-ui`
-
-Both crates are git dependencies (neither is on crates.io — there is no published shim). Migration is a source-level swap:
-
-```toml
-# before
-smooai-ui = { git = "https://github.com/SmooAI/ui.git", branch = "main" }
-
-# after — default features include "ui", same zero-dep no_std tree
-smooai-client-shared = { git = "https://github.com/SmooAI/client-shared.git" }
-```
-
-```rust
-// before
-use smooai_ui::{STYLES, MONOGRAM_SVG, tokens};
-
-// after — every const and sub-module at the same relative path under ui::
-use smooai_client_shared::ui::{STYLES, MONOGRAM_SVG, tokens};
-```
-
-The `ui` module is API-compatible with `smooai-ui`: same constants, same paths, and the bare default build inherits the same dependency tree (none).
-
## Related repos
-- [`SmooAI/ui`](https://github.com/SmooAI/ui) — the original design-system-only crate; [smooblue](https://github.com/SmooAI/smooblue) still consumes it directly. This repo carries the same `ui` surface for clients that also need `auth`.
-- [`SmooAI/smooth`](https://github.com/SmooAI/smooth) — the `th` CLI; consumes `client-shared` (`features = ["auth"]`) for login + credential storage.
-- `smooblue`, `observability-studio` — Dioxus desktop apps.
+- [`SmooAI/ui`](https://github.com/SmooAI/ui) — **the design system**: tokens, base CSS, the smoo monogram. Consumed directly by [smooblue](https://github.com/SmooAI/smooblue) and observability-studio. This crate used to carry a copy; it no longer does.
+- [`SmooAI/smooth`](https://github.com/SmooAI/smooth) — the `th` CLI; consumes this crate (`features = ["auth"]`) for login + credential storage.
## 🧩 Part of Smoo AI
diff --git a/rust/Cargo.toml b/rust/Cargo.toml
index 7de4482..87cb906 100644
--- a/rust/Cargo.toml
+++ b/rust/Cargo.toml
@@ -10,40 +10,27 @@ keywords = ["smooai", "design-system", "auth", "client"]
categories = ["gui", "authentication", "config"]
readme = "README.md"
authors = ["SmooAI "]
-# Cargo can't pull files from outside the package root by default; we
-# explicitly enumerate the cross-language `shared/` assets we want
-# included so `cargo package` produces a self-contained tarball.
include = [
"Cargo.toml",
"README.md",
- "build.rs",
"src/**/*.rs",
- "../shared/styles.css",
- "../shared/monogram.svg",
- "../shared/tokens.json",
- "../shared/tokens_codegen.rs",
- "../shared/tokens_css_check.rs",
"../LICENSE",
]
[features]
-# Default to the lightweight `ui` module so existing smooai-ui
-# consumers (smooblue, observability-studio) get the same dependency
-# tree they had before — no tokio, no reqwest, still no_std-friendly.
-# Opt into `auth` only when needed.
-default = ["ui"]
-ui = []
+# `auth` is the crate's only surface and its one consumer (the `th` CLI)
+# always asks for it — but it stays opt-in rather than default so the heavy
+# tree (tokio, reqwest, axum) is never pulled in by accident.
+#
+# There was a `ui` feature here carrying the design system. Nothing ever
+# imported `client_shared::ui`; SmooAI/ui owns that and is what smooblue and
+# observability-studio actually depend on. Keeping a second copy behind a
+# feature flag only created a drift surface, which had already silently
+# shipped a broken monogram.
auth = ["dep:tokio", "dep:reqwest", "dep:serde", "dep:serde_json", "dep:url", "dep:axum", "dep:anyhow", "dep:chrono", "dep:dirs-next", "dep:webbrowser", "dep:rand", "dep:base64", "dep:sha2"]
-[build-dependencies]
-# Build-script only: parses shared/tokens.json to generate the `tokens`
-# module. Build dependencies are host-side and never reach consumers, so the
-# bare `ui` build stays zero-dependency and `no_std`.
-serde_json = "1"
-
[dependencies]
-# Heavy deps gated behind the `auth` feature so the bare `ui`
-# build stays no_std-compatible and zero-dep.
+# All gated behind the `auth` feature.
tokio = { version = "1", features = ["macros", "rt-multi-thread", "fs", "net", "sync", "time"], optional = true }
reqwest = { version = "0.12", features = ["json"], optional = true }
serde = { version = "1", features = ["derive"], optional = true }
diff --git a/rust/build.rs b/rust/build.rs
deleted file mode 100644
index a44518c..0000000
--- a/rust/build.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//! Generate the `tokens` module from `shared/tokens.json`.
-//!
-//! The generator itself lives in `shared/tokens_codegen.rs` so SmooAI/ui and
-//! SmooAI/client-shared generate identically from the identical input — the
-//! `shared/**` drift gate keeps those files byte-for-byte equal. This build
-//! script is only the shim that feeds it.
-
-include!("../shared/tokens_codegen.rs");
-
-fn main() {
- println!("cargo:rerun-if-changed=../shared/tokens.json");
- println!("cargo:rerun-if-changed=../shared/tokens_codegen.rs");
-
- let json = std::fs::read_to_string("../shared/tokens.json").expect("read shared/tokens.json");
- let out = std::path::Path::new(&std::env::var("OUT_DIR").expect("OUT_DIR")).join("tokens.rs");
- std::fs::write(out, generate_tokens_rs(&json)).expect("write tokens.rs");
-}
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 473713f..8158f27 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -1,56 +1,41 @@
//! # smooai-client-shared
//!
-//! Cross-runtime shared library for SmooAI Rust clients — the home for
-//! design system primitives, auth flows, and LLM session plumbing that
-//! every SmooAI Rust app needs identically. Consumed by `smooblue`
-//! (Dioxus desktop), `observability-studio` (Dioxus viewer), `th` and
-//! `smoo admin` (the Smooth CLI), and any future Rust client.
-//!
-//! Replaces the standalone `smooai-ui` crate (which only carried the
-//! `ui` slice) by adding an `auth` module behind a feature flag. The bare `default-features = ["ui"]` build stays
-//! `no_std`-compatible with zero runtime dependencies — same shape as
-//! the old `smooai-ui` so existing consumers don't inherit any new
-//! tree.
+//! Auth primitives shared across SmooAI's Rust clients — Supabase user
+//! OAuth (localhost-callback flow with PKCE), the M2M
+//! `client_credentials` grant, refresh-token rotation, and an on-disk
+//! `CredentialsStore`. Consumed by `th` and `smoo admin` (the Smooth
+//! CLI).
//!
//! ## Feature flags
//!
-//! - `ui` (default) — design tokens, base CSS, monogram. Zero deps,
-//! `no_std`.
-//! - `auth` — Supabase user OAuth (localhost-callback flow), M2M
-//! `client_credentials` grant, refresh-token rotation, on-disk
-//! `CredentialsStore`. Pulls in `tokio`, `reqwest`, `serde`, `axum`.
+//! - `auth` — everything above. Pulls in `tokio`, `reqwest`, `serde`,
+//! `axum`. Not a default: the dependency tree is heavy enough that it
+//! should be asked for explicitly.
+//!
+//! ## What happened to the `ui` module
+//!
+//! This crate used to carry a copy of the design system (tokens, base
+//! CSS, monogram) and describe itself as `smooai-ui`'s successor. That
+//! migration was never finished, and an org-wide search found **nothing
+//! importing `smooai_client_shared::ui`** — every real consumer of the
+//! design system depends on [`SmooAI/ui`](https://github.com/SmooAI/ui)
+//! directly (smooblue, observability-studio), while this crate's only
+//! consumer asks for `auth` and never touched it.
+//!
+//! Two copies of the same files is a drift surface, and it had already
+//! drifted: this crate spent weeks serving a monogram missing its inner
+//! 'S' because a fix in SmooAI/ui never crossed. The copy is gone;
+//! `SmooAI/ui` owns the design system.
//!
//! An `llm` feature (JWT → `llm.smoo.ai` org-scoped session exchange)
//! is planned under pearl th-f7b20f. It is deliberately **absent**
//! rather than stubbed: a feature flag that compiles to an empty
//! module advertises a capability that does not exist. It comes back
//! when there is something behind it.
-//!
-//! ## Migrating from `smooai-ui`
-//!
-//! Replace
-//!
-//! ```toml
-//! smooai-ui = "0.1"
-//! ```
-//!
-//! with
-//!
-//! ```toml
-//! smooai-client-shared = "0.1"
-//! ```
-//!
-//! and swap `smooai_ui::` → `smooai_client_shared::ui::` in your
-//! imports. Everything in the `ui` module is re-exported at the same
-//! path it lived at under `smooai_ui::` (e.g. `STYLES`,
-//! `MONOGRAM_SVG`, `tokens::*`).
#![cfg_attr(not(feature = "auth"), no_std)]
#![doc(html_root_url = "https://docs.rs/smooai-client-shared/0.1.0")]
#![warn(missing_docs)]
-#[cfg(feature = "ui")]
-pub mod ui;
-
#[cfg(feature = "auth")]
pub mod auth;
diff --git a/rust/src/ui/mod.rs b/rust/src/ui/mod.rs
deleted file mode 100644
index a86cfde..0000000
--- a/rust/src/ui/mod.rs
+++ /dev/null
@@ -1,79 +0,0 @@
-//! # ui — SmooAI design system primitives
-//!
-//! Lifted verbatim from the standalone `smooai-ui` crate so existing
-//! consumers can migrate by changing `smooai_ui::*` → `smooai_client_shared::ui::*`.
-//! Pure `pub const &'static str` constants — zero deps, `no_std`-friendly.
-
-/// Canonical brand stylesheet, sourced from the cross-language
-/// `shared/styles.css`. Embed in your app's root component so every
-/// consumer sees the same tokens + base component classes.
-pub const STYLES: &str = include_str!("../../../shared/styles.css");
-
-/// The smoo monogram, as an SVG string with `fill="currentColor"` so
-/// the surrounding CSS controls the color. Pair with the
-/// `.brand-badge` class (defined in [`STYLES`]) for the gradient pill
-/// backdrop.
-pub const MONOGRAM_SVG: &str = include_str!("../../../shared/monogram.svg");
-
-/// Brand + semantic token *values*, for code paths that need a colour,
-/// radius, spacing step, or font stack outside of CSS (custom-painted egui
-/// widgets, native menu chrome, chart libraries, etc.).
-///
-/// **Generated** at build time from
-/// [`shared/tokens.json`](https://github.com/SmooAI/client-shared/blob/main/shared/tokens.json)
-/// by `shared/tokens_codegen.rs` — nobody hand-writes these, so a token cannot
-/// exist in the design system and be missing here. `shared/tokens_css_check.rs`
-/// then asserts each one equals the resolved value of its custom property in
-/// [`STYLES`], and that every colour the CSS declares has a token.
-pub mod tokens {
- include!(concat!(env!("OUT_DIR"), "/tokens.rs"));
-
- /// The default corner radius, as used by cards and buttons. Retained as an
- /// alias of [`RADIUS_MD_PX`] so consumers pinned to the pre-codegen name
- /// keep compiling.
- pub const RADIUS_PX: u16 = RADIUS_MD_PX;
-}
-
-#[cfg(test)]
-mod tests {
- extern crate std;
- use super::*;
-
- #[test]
- fn styles_is_nonempty() {
- assert!(STYLES.len() > 100);
- assert!(STYLES.contains("--color-smooai-green"));
- }
-
- #[test]
- fn monogram_is_real_svg() {
- assert!(MONOGRAM_SVG.starts_with("