{"id":48897711,"url":"https://github.com/zenml-io/kitaru-ui","last_synced_at":"2026-04-16T12:01:18.016Z","repository":{"id":345769683,"uuid":"1173587981","full_name":"zenml-io/kitaru-ui","owner":"zenml-io","description":"UI interface for Kitaru - durable execution for AI agents, built on ZenML","archived":false,"fork":false,"pushed_at":"2026-04-14T14:59:58.000Z","size":866,"stargazers_count":2,"open_issues_count":19,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-14T16:32:10.481Z","etag":null,"topics":["agent-framework","ai-agents","checkpoints","durable-execution","llm","mcp","mlops","observability","pydantic","pydantic-ai","react","replay","typescript","workflow-orchestration"],"latest_commit_sha":null,"homepage":"https://kitaru.ai/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zenml-io.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-05T14:32:53.000Z","updated_at":"2026-04-12T19:35:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/zenml-io/kitaru-ui","commit_stats":null,"previous_names":["zenml-io/kitaru-ui"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/zenml-io/kitaru-ui","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zenml-io%2Fkitaru-ui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zenml-io%2Fkitaru-ui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zenml-io%2Fkitaru-ui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zenml-io%2Fkitaru-ui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zenml-io","download_url":"https://codeload.github.com/zenml-io/kitaru-ui/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zenml-io%2Fkitaru-ui/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31884929,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-16T11:36:10.202Z","status":"ssl_error","status_checked_at":"2026-04-16T11:36:09.652Z","response_time":69,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-framework","ai-agents","checkpoints","durable-execution","llm","mcp","mlops","observability","pydantic","pydantic-ai","react","replay","typescript","workflow-orchestration"],"created_at":"2026-04-16T12:01:17.130Z","updated_at":"2026-04-16T12:01:17.994Z","avatar_url":"https://github.com/zenml-io.png","language":"TypeScript","readme":"# Kitaru UI\n\nKitaru UI is the web dashboard for [Kitaru](https://kitaru.ai) — a durable agent infrastructure framework for Python that enables reliable agent execution with built-in crash recovery, human-in-the-loop approval, and cost tracking. It is a single-page application built with React 19 and Vite.\n\n## Current Scope\n\nThe app currently supports:\n\n- **Server activation** — first-run setup flow when the ZenML server has not yet been activated\n- **Login / session management** — cookie-based authentication with the ZenML backend\n- **Private area shell** — authenticated layout with a placeholder home page\n\n## Tech Stack\n\n| Layer           | Tool                                                                             |\n| --------------- | -------------------------------------------------------------------------------- |\n| Framework       | Vite 7 + React 19 (SPA)                                                          |\n| Routing         | [@tanstack/react-router](https://tanstack.com/router) (file-based, code-split)   |\n| Server state    | [@tanstack/react-query](https://tanstack.com/query)                              |\n| Forms           | React Hook Form + Zod                                                            |\n| Styling         | Tailwind CSS v4 (via `@tailwindcss/vite`)                                        |\n| UI primitives   | [Base UI](https://base-ui.com/) + [class-variance-authority](https://cva.style/) |\n| Icons           | [lucide-react](https://lucide.dev/)                                              |\n| Notifications   | [Sonner](https://sonner.emilkowal.dev/)                                          |\n| Theming         | next-themes                                                                      |\n| Type generation | openapi-typescript (from ZenML server OpenAPI spec)                              |\n| Testing         | Vitest                                                                           |\n| Compiler        | React Compiler (via Babel plugin)                                                |\n\n## Local Development\n\n### Prerequisites\n\n- Node.js (LTS)\n- [pnpm](https://pnpm.io/)\n- A running ZenML server (default: `http://localhost:8237`)\n\n### Setup\n\n```bash\n# Install dependencies\npnpm install\n\n# Copy environment config\ncp .env.example .env\n\n# Start dev server (default: http://localhost:5173)\npnpm dev\n```\n\nBy default, the app sends requests to relative paths (for example `/api/v1/current-user`). In local development, the Vite dev server proxies `/api` requests to `VITE_BACKEND_URL`, so the frontend and backend appear on the same origin.\n\n### Environment Variables\n\n| Variable            | Default                 | Description                                                                                                                                      |\n| ------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `VITE_BACKEND_URL`  | `http://localhost:8237` | ZenML server URL used by the Vite dev proxy                                                                                                      |\n| `VITE_API_BASE_URL` | _(unset)_               | Optional API origin override (build-time). If set (for example `https://backend.test.com`), requests are sent to `\u003corigin\u003e/api/v1/...` directly. |\n\n### Scripts\n\n```bash\npnpm dev              # Start development server\npnpm build            # Type-check and build for production\npnpm preview          # Preview the production build locally\npnpm lint             # Run ESLint\npnpm format           # Format code with Prettier\npnpm test:unit        # Run unit tests (Vitest)\npnpm generate:types   # Generate OpenAPI types: pnpm generate:types -- \u003cbase-url\u003e\n```\n\n### Pre-commit Hooks\n\nThe repo uses [Lefthook](https://github.com/evilmartians/lefthook) for pre-commit hooks that auto-fix ESLint issues and format staged files with Prettier.\n\n## Architecture\n\n### Project Structure\n\nThe frontend architecture is module-based under `src/modules/`.\n\n```\nsrc/\n  modules/\n    root/             Root Module bootstrap and app-global resources\n    \u003cmodule\u003e/\n      domain/          Types and actual API/request functions\n      business-logic/  TanStack Query definitions and module logic\n      feature/         Stateful containers and entrypoints\n      util/            Module-scoped utilities\n      ui/              Stateless presentational components\n  routes/              File-based TanStack Router route definitions\n  shared/\n    api/domain/        Transport layer (apiClient, paths, errors)\n    api/utils/         URL builders, error helpers\n    router/utils/      Router-specific shared helpers\n    ui/                Reusable UI primitives (Base UI-based)\n    utils/             Shared utilities (styles, page titles)\n  assets/              Icons, images (importable as React components via SVGR)\n```\n\n### Module Layers\n\n- `domain/` contains module-owned types and the actual request functions that talk to the backend.\n- `business-logic/` contains TanStack Query definitions and other module-specific logic.\n- `feature/` contains stateful containers, orchestration, and module entrypoints.\n- `util/` contains small module-scoped helpers.\n- `ui/` contains stateless, dumb UI components.\n\n### Generated Files\n\nThese files are auto-generated and should not be hand-edited:\n\n- `src/routeTree.gen.ts` — generated by TanStack Router plugin from `src/routes/`\n- `src/shared/api/types.ts` — generated by `pnpm generate:types` from the ZenML OpenAPI spec\n\nBoth are excluded from ESLint.\n\n### App Boot Sequence\n\n1. `src/main.tsx` creates the router with the generated route tree and injects a shared `queryClient`\n2. Root route (`__root.tsx`) fetches server info — if the server is inactive, redirects to `/activate-server`\n3. Private route (`_private.tsx`) ensures the current user is loaded before rendering children\n4. If any query returns a 401, a global `QueryCache` error handler redirects to `/login`\n\n### Data Fetching\n\n- **Request functions** live in `domain/` and handle transport and response parsing.\n- **Query keys and query collections** live in `business-logic/` and are built with `queryOptions(...)` or `infiniteQueryOptions(...)`.\n- **Read APIs** should prefer grouped exports such as `deviceQueryKeys` and `deviceQueries` instead of standalone exported fetcher-query helpers.\n- **Route loaders** call `context.queryClient.ensureQueryData(...)` to preload data\n- **Mutations** are exposed from `business-logic/` as `mutationOptions(...)` factories, while their underlying request functions stay in `domain/`\n- **Components** call `useMutation(...)` directly with mutation options\n- Global 401 handling lives in the `QueryCache` error callback (`query-client.ts`)\n\n### Authentication\n\n- `apiClient` sends all requests with `credentials: \"include\"` (cookie auth)\n- By default requests are relative (`/api/v1/...`); optionally set `VITE_API_BASE_URL` to target a full backend origin\n- Vite proxies `/api` to `VITE_BACKEND_URL` in development\n- Login uses `application/x-www-form-urlencoded` content type (exception to the default JSON headers)\n\n## CI\n\nGitHub Actions (`.github/workflows/build-validation.yml`) runs on push to `main` and on all PRs:\n\n1. `pnpm install --frozen-lockfile`\n2. `pnpm lint`\n3. `pnpm build`\n4. `pnpm test:unit`\n\n## Contributing\n\nSee [AGENTS.md](./AGENTS.md) for the full coding conventions, naming rules, data fetching patterns, and architectural guidance used by coding agents and contributors.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzenml-io%2Fkitaru-ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzenml-io%2Fkitaru-ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzenml-io%2Fkitaru-ui/lists"}