From f4aa9dc34d753cf14c25667667a580960f178af3 Mon Sep 17 00:00:00 2001 From: Jon Langevin Date: Mon, 23 Feb 2026 04:57:14 -0500 Subject: [PATCH 1/2] docs: add comprehensive README.md Closes #1 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- README.md | 286 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 286 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..88fd829 --- /dev/null +++ b/README.md @@ -0,0 +1,286 @@ +# @gocodealone/workflow-ui + +A shared React component library providing UI utilities for workflow orchestration applications. Built with React 19, TypeScript, and Zustand. + +## Features + +- 🎨 **Theme System** — Catppuccin Mocha color palette with pre-styled components +- 🔐 **Authentication** — Configurable Zustand auth store with LoginPage component +- 🌐 **API Client** — Shared fetch wrapper with auth token injection +- 📡 **SSE Support** — Server-Sent Events connection utility +- ⚡ **TypeScript** — Full type safety with TypeScript 5.9 +- 📦 **Tree-shakeable** — Modular exports for optimal bundle size + +## Installation + +This package is published to GitHub Packages. Configure npm to use GitHub Packages for the `@gocodealone` scope: + +```bash +# Add to your .npmrc +@gocodealone:registry=https://npm.pkg.github.com +//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN +``` + +Then install: + +```bash +npm install @gocodealone/workflow-ui +``` + +## Quick Start + +### Theme + +Use the Catppuccin Mocha color palette and pre-styled base components: + +```tsx +import { colors, statusColors, baseStyles } from '@gocodealone/workflow-ui/theme'; + +function App() { + return ( +
+
+

Hello World

+ +
+
+ ); +} +``` + +### API Client + +Configure once at app startup, then use the typed HTTP methods: + +```tsx +import { configureApi, apiGet, apiPost } from '@gocodealone/workflow-ui/api'; + +// Configure at app root +configureApi({ + baseUrl: '/api/v1', + onResponseError: (status) => { + if (status === 401) { + // Handle unauthorized + } + }, +}); + +// Use anywhere +const data = await apiGet('/users'); +await apiPost('/users', { name: 'Alice' }); +``` + +### Authentication + +Create an auth store and use the LoginPage component: + +```tsx +import { createAuthStore, LoginPage } from '@gocodealone/workflow-ui/auth'; + +// Create store (once at module scope) +export const useAuthStore = createAuthStore({ + loginPath: '/auth/login', + mePath: '/auth/me', +}); + +// Use in your app +function App() { + const { isAuthenticated, login, error } = useAuthStore(); + + if (!isAuthenticated) { + return ( + + ); + } + + return
Authenticated!
; +} +``` + +### Server-Sent Events + +Connect to SSE endpoints with automatic auth token handling: + +```tsx +import { connectSSE } from '@gocodealone/workflow-ui/sse'; +import { useEffect } from 'react'; + +function EventListener() { + useEffect(() => { + const es = connectSSE({ + url: '/events', + onEvent: (event) => { + console.log('Received:', event.type, event.data); + }, + onError: (err) => console.error('SSE error:', err), + }); + + return () => es.close(); + }, []); + + return
Listening for events...
; +} +``` + +## API Reference + +### `/theme` + +#### `colors` +Catppuccin Mocha color palette with semantic naming: +- Base colors: `base`, `mantle`, `crust`, `surface0-2`, `overlay0-2` +- Text colors: `text`, `subtext0-1` +- Accent colors: `blue`, `green`, `yellow`, `red`, `mauve`, `pink`, etc. + +#### `statusColors` +Status-to-color mappings for common states: +```typescript +statusColors.active // green +statusColors.error // red +statusColors.pending // yellow +``` + +#### `baseStyles` +Pre-styled component objects: +- `baseStyles.container` — Full-height page container +- `baseStyles.card` — Card with border and padding +- `baseStyles.input` — Text input +- `baseStyles.button.primary` — Primary action button +- `baseStyles.button.secondary` — Secondary button +- `baseStyles.button.danger` — Destructive action button +- `baseStyles.table`, `baseStyles.th`, `baseStyles.td` — Table styles + +### `/api` + +#### `configureApi(config: ApiClientConfig)` +Configure the API client. Call once at app startup. + +**Config options:** +- `baseUrl?: string` — Base URL prefix (default: `/api`) +- `getToken?: () => string | null` — Token retrieval function +- `onResponseError?: (status: number, body: string) => void` — Error handler + +#### HTTP Methods +All methods return typed promises and inject auth tokens automatically: +- `apiGet(path: string): Promise` +- `apiPost(path: string, body?: unknown): Promise` +- `apiPut(path: string, body?: unknown): Promise` +- `apiPatch(path: string, body: unknown): Promise` +- `apiDelete(path: string): Promise` + +### `/auth` + +#### `createAuthStore(config?: AuthStoreConfig)` +Factory function to create a Zustand auth store. + +**Config options:** +- `loginPath?: string` — Login endpoint (default: `/auth/login`) +- `mePath?: string` — User profile endpoint (default: `/auth/me`) +- `tokenKey?: string` — localStorage key (default: `auth_token`) +- `parseLoginResponse?: (data: unknown) => { token: string; user?: BaseUser }` +- `buildLoginBody?: (username: string, password: string) => unknown` +- `onLogout?: (token: string | null) => void` + +**Store interface:** +```typescript +interface BaseAuthState { + token: string | null; + user: BaseUser | null; + isAuthenticated: boolean; + isLoading: boolean; + error: string | null; + login: (username: string, password: string) => Promise; + logout: () => void; + loadUser: () => Promise; + clearError: () => void; +} +``` + +#### `LoginPage` Component +Pre-styled login form using theme system. + +**Props:** +```typescript +interface LoginPageProps { + title: string; + subtitle?: string; + usernameLabel?: string; + usernameType?: string; + usernamePlaceholder?: string; + onLogin: (username: string, password: string) => Promise; + error?: string | null; + style?: CSSProperties; +} +``` + +### `/sse` + +#### `connectSSE(config: SSEConfig): EventSource` +Connect to a Server-Sent Events endpoint. Returns the EventSource instance. + +**Config:** +```typescript +interface SSEConfig { + url?: string; // Default: '/events' + withAuth?: boolean; // Default: true + tokenKey?: string; // Default: 'auth_token' + onEvent: (event: { type: string; data: unknown }) => void; + onError?: (event: Event) => void; +} +``` + +## Development + +### Setup + +```bash +npm install +``` + +### Build + +```bash +npm run build +``` + +Output: `dist/` with ESM, CJS, and type definitions. + +### Test + +```bash +npm test # Run once +npm run test:watch # Watch mode +``` + +### Lint + +```bash +npm run lint +``` + +### Local Development + +Link locally for testing in other projects: + +```bash +npm link +cd ../your-project +npm link @gocodealone/workflow-ui +``` + +## Peer Dependencies + +- `react`: ^18.0.0 || ^19.0.0 +- `react-dom`: ^18.0.0 || ^19.0.0 +- `zustand`: ^4.0.0 || ^5.0.0 + +## License + +MIT © GoCodeAlone From 3b5aa28a42523bf0c047d1339830915ec3ab7623 Mon Sep 17 00:00:00 2001 From: Jon Langevin Date: Mon, 23 Feb 2026 04:57:19 -0500 Subject: [PATCH 2/2] ci: add CI and publish GitHub Actions workflows Closes #2 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- .github/workflows/publish.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 615f9cf..a580ea2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/setup-node@v4 with: - node-version: '20' + node-version: '22' cache: 'npm' - run: npm ci diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f2f8e23..58d2a7f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/setup-node@v4 with: - node-version: '20' + node-version: '22' registry-url: 'https://npm.pkg.github.com' scope: '@gocodealone'