docs: add project docs, GitHub DX, fire-tools stamp
- CLAUDE.md with commands, structure, key constraints - .claude/rules/ coding standards + workflows - docs/architecture.md with design decisions - .github/ CI workflow, issue templates, PR template - LICENSE (MIT) - .fire-tools.json initialization stamp - README.md rewritten with features, quick start, stack table
This commit is contained in:
31
.claude/rules/coding-standards.md
Normal file
31
.claude/rules/coding-standards.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
description: Coding conventions — read when writing or reviewing any code file
|
||||||
|
---
|
||||||
|
|
||||||
|
# Coding Standards
|
||||||
|
|
||||||
|
## DO
|
||||||
|
- Use TypeScript strict mode (`"strict": true` in tsconfig)
|
||||||
|
- Use Zod only at user-input boundaries (settings form) — not for internal types
|
||||||
|
- Use named constants — never magic numbers or strings
|
||||||
|
- Keep components focused; co-locate sub-components in the same file if < 80 lines
|
||||||
|
- Use `type` imports for framer-motion's `Variants` type to avoid widening issues
|
||||||
|
- Cast TanStack Router `params` as `as never` for cross-route navigation
|
||||||
|
|
||||||
|
## NEVER
|
||||||
|
- Use `any` — use `unknown` and narrow explicitly
|
||||||
|
- Inline Honcho base URL — always read from `loadConfig()` in `src/lib/config.ts`
|
||||||
|
- Use Tailwind color classes for theme-sensitive values — use CSS `var(--*)` instead
|
||||||
|
- Use `React.FormEvent` (deprecated in TS6) — use `React.SyntheticEvent<HTMLFormElement>`
|
||||||
|
- Add `as const` to framer-motion variant objects — annotate with `const x: Variants = {}`
|
||||||
|
|
||||||
|
## Test Standards
|
||||||
|
- One assertion per test case
|
||||||
|
- Test behavior, not implementation
|
||||||
|
- Run targeted: `pnpm vitest run src/path/to/file.test.ts`
|
||||||
|
- Never mock internal modules — mock only external API boundaries (openapi-fetch client)
|
||||||
|
|
||||||
|
## API Query Patterns
|
||||||
|
- All data fetching via TanStack Query hooks in `src/api/queries.ts`
|
||||||
|
- POST body shapes are fixed per the openapi schema — do not guess field names
|
||||||
|
- Use `client.current` (getter) to always get fresh config at call time
|
||||||
50
.claude/rules/workflows.md
Normal file
50
.claude/rules/workflows.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
---
|
||||||
|
description: Recurring task patterns — read when fixing issues, adding features, or running tests
|
||||||
|
---
|
||||||
|
|
||||||
|
# Workflows
|
||||||
|
|
||||||
|
## Add a Feature
|
||||||
|
|
||||||
|
1. Read `docs/architecture.md` to understand where new code belongs
|
||||||
|
2. Write the test first (failing)
|
||||||
|
3. Implement minimum code to pass
|
||||||
|
4. `pnpm test` — full suite
|
||||||
|
5. `pnpm lint:fix` — Biome
|
||||||
|
6. Commit: `feat: <description>`
|
||||||
|
|
||||||
|
## Fix a Bug
|
||||||
|
|
||||||
|
1. Grep codebase for identifiers mentioned in the bug report
|
||||||
|
2. Read the 2–3 most relevant files
|
||||||
|
3. Write a failing test that reproduces the problem
|
||||||
|
4. Implement the minimal fix
|
||||||
|
5. `pnpm vitest run <path/to/test.ts>` — verify test passes
|
||||||
|
6. `pnpm lint:fix` — pass lint
|
||||||
|
7. Commit: `fix: <description>`
|
||||||
|
|
||||||
|
## Regenerate API Types
|
||||||
|
|
||||||
|
Run after updating `openapi.json`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm generate:api
|
||||||
|
# → overwrites src/api/schema.d.ts
|
||||||
|
# Do not edit schema.d.ts manually
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run Targeted Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm vitest run src/path/to/file.test.ts
|
||||||
|
pnpm vitest run --testNamePattern="<substring>"
|
||||||
|
pnpm vitest src/path/to/file.test.ts # watch mode
|
||||||
|
```
|
||||||
|
|
||||||
|
## Add a New Route
|
||||||
|
|
||||||
|
1. Create `src/routes/<flat-route-name>.tsx` using TanStack Router flat-route syntax
|
||||||
|
2. Export `const Route = createFileRoute("/<path>")({ component: Foo })`
|
||||||
|
3. Vite plugin auto-regenerates `src/routeTree.gen.ts` on save
|
||||||
|
4. Add nav link to `src/components/layout/Sidebar.tsx` if top-level
|
||||||
|
5. Cast all `navigate()` / `<Link>` params as `as never`
|
||||||
12
.fire-tools.json
Normal file
12
.fire-tools.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"fire_tools_version": "0.1.0",
|
||||||
|
"initialized_at": "2026-04-24T00:00:00Z",
|
||||||
|
"profile": "other",
|
||||||
|
"features": ["pnpm", "biome", "vitest", "zod"],
|
||||||
|
"deviations": [
|
||||||
|
"No SQL database (Honcho API handles persistence)",
|
||||||
|
"No turborepo (single package)",
|
||||||
|
"No commitlint/husky (small solo project)",
|
||||||
|
"No semantic-release (not publishing to npm)"
|
||||||
|
]
|
||||||
|
}
|
||||||
47
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
47
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
name: Bug report
|
||||||
|
description: Something isn't working as expected
|
||||||
|
labels: [bug]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: Thanks for taking the time to report a bug!
|
||||||
|
|
||||||
|
- type: input
|
||||||
|
id: honcho-version
|
||||||
|
attributes:
|
||||||
|
label: Honcho version / commit
|
||||||
|
description: What version of Honcho are you connecting to?
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: description
|
||||||
|
attributes:
|
||||||
|
label: What happened?
|
||||||
|
description: A clear description of the bug.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: expected
|
||||||
|
attributes:
|
||||||
|
label: What did you expect?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: steps
|
||||||
|
attributes:
|
||||||
|
label: Steps to reproduce
|
||||||
|
placeholder: |
|
||||||
|
1. Go to ...
|
||||||
|
2. Click ...
|
||||||
|
3. See error
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: context
|
||||||
|
attributes:
|
||||||
|
label: Additional context
|
||||||
|
description: Browser, OS, any relevant console errors.
|
||||||
24
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
24
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
name: Feature request
|
||||||
|
description: Suggest a new feature or improvement
|
||||||
|
labels: [enhancement]
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
id: problem
|
||||||
|
attributes:
|
||||||
|
label: What problem does this solve?
|
||||||
|
description: Describe the use case or pain point.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: proposal
|
||||||
|
attributes:
|
||||||
|
label: Proposed solution
|
||||||
|
description: What would you like to see?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: alternatives
|
||||||
|
attributes:
|
||||||
|
label: Alternatives considered
|
||||||
21
.github/pull_request_template.md
vendored
Normal file
21
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
## Summary
|
||||||
|
|
||||||
|
<!-- What does this PR change and why? -->
|
||||||
|
|
||||||
|
## Type
|
||||||
|
|
||||||
|
- [ ] Bug fix
|
||||||
|
- [ ] New feature
|
||||||
|
- [ ] Refactor
|
||||||
|
- [ ] Docs / chore
|
||||||
|
|
||||||
|
## Test plan
|
||||||
|
|
||||||
|
- [ ] `pnpm lint` passes
|
||||||
|
- [ ] `pnpm test` passes
|
||||||
|
- [ ] `pnpm build` succeeds
|
||||||
|
- [ ] Tested in browser (describe what you verified)
|
||||||
|
|
||||||
|
## Related issues
|
||||||
|
|
||||||
|
<!-- Closes #N -->
|
||||||
38
.github/workflows/ci.yml
vendored
Normal file
38
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check:
|
||||||
|
name: Lint, type-check & test
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: pnpm/action-setup@v4
|
||||||
|
with:
|
||||||
|
version: 9
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
cache: pnpm
|
||||||
|
|
||||||
|
- run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
- run: pnpm lint
|
||||||
|
name: Biome lint
|
||||||
|
|
||||||
|
- run: pnpm exec tsc --noEmit -p tsconfig.app.json
|
||||||
|
name: Type check
|
||||||
|
|
||||||
|
- run: pnpm test
|
||||||
|
name: Tests
|
||||||
|
|
||||||
|
- run: pnpm build
|
||||||
|
name: Production build
|
||||||
47
CLAUDE.md
Normal file
47
CLAUDE.md
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# honcho-ui
|
||||||
|
|
||||||
|
Frontend UI for self-hosted Honcho instances — browse memories, peers, sessions, conclusions, and chat with memory context.
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
| Command | Purpose |
|
||||||
|
|---------|---------|
|
||||||
|
| `pnpm dev` | Start Vite dev server (http://localhost:5173) |
|
||||||
|
| `pnpm build` | Production build to `dist/` |
|
||||||
|
| `pnpm lint` | Biome lint check |
|
||||||
|
| `pnpm lint:fix` | Biome lint + auto-fix |
|
||||||
|
| `pnpm format` | Biome format check |
|
||||||
|
| `pnpm test` | Run Vitest tests |
|
||||||
|
| `pnpm generate:api` | Regenerate `src/api/schema.d.ts` from `openapi.json` |
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
|
||||||
|
| Path | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `src/routes/` | TanStack Router file-based routes (flat-route syntax) |
|
||||||
|
| `src/components/` | Feature components grouped by domain |
|
||||||
|
| `src/api/` | openapi-fetch client + TanStack Query hooks |
|
||||||
|
| `src/lib/` | Config (localStorage) + theme utilities |
|
||||||
|
| `src/hooks/` | Custom React hooks |
|
||||||
|
| `.claude/rules/` | Coding conventions (auto-loaded) |
|
||||||
|
| `docs/` | Architecture and references |
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
|
||||||
|
Read `.claude/rules/coding-standards.md` when writing or reviewing any code file.
|
||||||
|
|
||||||
|
## Workflows
|
||||||
|
|
||||||
|
Read `.claude/rules/workflows.md` for recurring task patterns.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
Read `docs/architecture.md` for component overview, data flow, and design decisions.
|
||||||
|
|
||||||
|
## Key Constraints
|
||||||
|
|
||||||
|
- **No hardcoded URLs** — all connection config lives in `localStorage` under `honcho-ui:config`
|
||||||
|
- **TanStack Router flat-route params** — always cast `params` as `as never` at `navigate()` and `<Link>` callsites
|
||||||
|
- **`framer-motion` Variants typing** — import `type Variants` and annotate objects; never use `as const` on variant objects
|
||||||
|
- **Auth is optional** — token header only sent when non-empty; `checkConnection()` detects if auth is required
|
||||||
|
- **CSS variables only** — no Tailwind color utilities for theme-aware colors; use `var(--text-1)` etc.
|
||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 offendingcommit
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
140
README.md
140
README.md
@@ -1,73 +1,97 @@
|
|||||||
# React + TypeScript + Vite
|
# Honcho UI
|
||||||
|
|
||||||
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
A clean, fast frontend for browsing and chatting with a self-hosted [Honcho](https://github.com/plastic-labs/honcho) instance.
|
||||||
|
|
||||||
Currently, two official plugins are available:
|
> **Privacy-first**: all connection details (base URL, optional token) are stored locally in your browser — never sent anywhere except directly to your Honcho instance.
|
||||||
|
|
||||||
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs)
|
---
|
||||||
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/)
|
|
||||||
|
|
||||||
## React Compiler
|
## Features
|
||||||
|
|
||||||
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
|
- **Dashboard** — workspace count and queue status at a glance, auto-refreshes every 10 s
|
||||||
|
- **Workspaces** — paginated list with per-workspace navigation
|
||||||
|
- **Peers** — browse peers, view representations, context, and peer cards
|
||||||
|
- **Sessions** — paginated message history with summaries and context
|
||||||
|
- **Conclusions** — semantic search across conclusions with observer/subject display
|
||||||
|
- **Chat** — conversational interface that sends messages through Honcho's chat endpoint with memory context
|
||||||
|
- **Dark / light mode** — persisted per browser, instant toggle
|
||||||
|
- **Optional auth** — token field is optional; a connection health check auto-detects whether auth is required
|
||||||
|
|
||||||
## Expanding the ESLint configuration
|
## Quick Start
|
||||||
|
|
||||||
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
|
### Prerequisites
|
||||||
|
|
||||||
```js
|
- Node.js ≥ 20
|
||||||
export default defineConfig([
|
- pnpm ≥ 9
|
||||||
globalIgnores(['dist']),
|
- A running Honcho instance (local or remote)
|
||||||
{
|
|
||||||
files: ['**/*.{ts,tsx}'],
|
|
||||||
extends: [
|
|
||||||
// Other configs...
|
|
||||||
|
|
||||||
// Remove tseslint.configs.recommended and replace with this
|
### Install & run
|
||||||
tseslint.configs.recommendedTypeChecked,
|
|
||||||
// Alternatively, use this for stricter rules
|
|
||||||
tseslint.configs.strictTypeChecked,
|
|
||||||
// Optionally, add this for stylistic rules
|
|
||||||
tseslint.configs.stylisticTypeChecked,
|
|
||||||
|
|
||||||
// Other configs...
|
```bash
|
||||||
],
|
git clone https://github.com/offendingcommit/honcho-ui.git
|
||||||
languageOptions: {
|
cd honcho-ui
|
||||||
parserOptions: {
|
pnpm install
|
||||||
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
pnpm dev
|
||||||
tsconfigRootDir: import.meta.dirname,
|
|
||||||
},
|
|
||||||
// other options...
|
|
||||||
},
|
|
||||||
},
|
|
||||||
])
|
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
|
Open http://localhost:5173 — you'll be prompted to enter your Honcho URL.
|
||||||
|
|
||||||
```js
|
### Connect to your instance
|
||||||
// eslint.config.js
|
|
||||||
import reactX from 'eslint-plugin-react-x'
|
|
||||||
import reactDom from 'eslint-plugin-react-dom'
|
|
||||||
|
|
||||||
export default defineConfig([
|
1. Enter the base URL of your Honcho instance (e.g. `http://localhost:8000`)
|
||||||
globalIgnores(['dist']),
|
2. Optionally enter an API token if your instance requires auth
|
||||||
{
|
3. Click **Test connection** — the UI will tell you if auth is needed
|
||||||
files: ['**/*.{ts,tsx}'],
|
4. Click **Save** — you're in
|
||||||
extends: [
|
|
||||||
// Other configs...
|
### Build for production
|
||||||
// Enable lint rules for React
|
|
||||||
reactX.configs['recommended-typescript'],
|
```bash
|
||||||
// Enable lint rules for React DOM
|
pnpm build
|
||||||
reactDom.configs.recommended,
|
# Output in dist/ — serve with any static host
|
||||||
],
|
|
||||||
languageOptions: {
|
|
||||||
parserOptions: {
|
|
||||||
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
|
||||||
tsconfigRootDir: import.meta.dirname,
|
|
||||||
},
|
|
||||||
// other options...
|
|
||||||
},
|
|
||||||
},
|
|
||||||
])
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Stack
|
||||||
|
|
||||||
|
| Layer | Library |
|
||||||
|
|-------|---------|
|
||||||
|
| Framework | React 19 + Vite 8 |
|
||||||
|
| Routing | TanStack Router v1 (file-based) |
|
||||||
|
| Data fetching | TanStack Query v5 |
|
||||||
|
| API client | openapi-fetch (typed from `openapi.json`) |
|
||||||
|
| Styling | Tailwind CSS v4 + CSS custom properties |
|
||||||
|
| Animation | framer-motion |
|
||||||
|
| Icons | lucide-react |
|
||||||
|
| Lint / format | Biome |
|
||||||
|
| Tests | Vitest + Testing Library |
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm dev # dev server with HMR
|
||||||
|
pnpm lint:fix # Biome lint + format
|
||||||
|
pnpm test # run tests
|
||||||
|
pnpm generate:api # regenerate src/api/schema.d.ts from openapi.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## Regenerating API types
|
||||||
|
|
||||||
|
If your Honcho instance is updated, grab a fresh `openapi.json` and run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://your-honcho-url/openapi.json -o openapi.json
|
||||||
|
pnpm generate:api
|
||||||
|
```
|
||||||
|
|
||||||
|
## Privacy
|
||||||
|
|
||||||
|
- Base URL and token are stored in `localStorage` under `honcho-ui:config`
|
||||||
|
- Theme preference is stored in `localStorage` under `honcho-ui:theme`
|
||||||
|
- No telemetry, no analytics, no external requests beyond your configured Honcho instance
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Issues and PRs welcome. Open an issue first for significant changes.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT
|
||||||
|
|||||||
44
docs/architecture.md
Normal file
44
docs/architecture.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Architecture: honcho-ui
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Single-page application for browsing and interacting with a self-hosted [Honcho](https://github.com/plastic-labs/honcho) instance. Configurable at runtime — no URLs baked in.
|
||||||
|
|
||||||
|
Stack: React 19, Vite 8, TypeScript 6, TanStack Router v1, TanStack Query v5, Tailwind CSS v4, framer-motion, openapi-fetch.
|
||||||
|
|
||||||
|
## Key Components
|
||||||
|
|
||||||
|
| Component | Location | Responsibility |
|
||||||
|
|-----------|----------|---------------|
|
||||||
|
| API client | `src/api/client.ts` | openapi-fetch client, reads config from localStorage at call time |
|
||||||
|
| Query hooks | `src/api/queries.ts` | All TanStack Query hooks, typed via generated schema |
|
||||||
|
| Config | `src/lib/config.ts` | localStorage read/write, health check, Zod validation |
|
||||||
|
| Theme | `src/lib/theme.ts` | Dark/light theme via `data-theme` on `<html>` |
|
||||||
|
| Root route | `src/routes/__root.tsx` | Auth guard (redirect to /settings), Sidebar layout |
|
||||||
|
| Sidebar | `src/components/layout/Sidebar.tsx` | Nav with animated active indicator |
|
||||||
|
| Settings | `src/components/settings/SettingsForm.tsx` | Base URL + optional token, connection test |
|
||||||
|
|
||||||
|
## Data Flow
|
||||||
|
|
||||||
|
1. App boots → `__root.tsx` checks `localStorage` for config
|
||||||
|
2. No config → redirect to `/settings`
|
||||||
|
3. User saves URL (+ optional token) → `loadConfig()` returns it on every query
|
||||||
|
4. `client.current` getter recreates the openapi-fetch client on each call, always picking up latest config
|
||||||
|
5. TanStack Query caches responses; stale time 30s, retries 1x
|
||||||
|
|
||||||
|
## External Dependencies
|
||||||
|
|
||||||
|
- Honcho REST API — described by `openapi.json` (local copy, regenerate with `pnpm generate:api`)
|
||||||
|
- No external auth provider — token is optional, detected via health check
|
||||||
|
|
||||||
|
## Design Decisions
|
||||||
|
|
||||||
|
<!-- Format: **YYYY-MM-DD**: Decision — Rationale -->
|
||||||
|
|
||||||
|
**2026-04-24**: Use CSS custom properties instead of Tailwind color tokens — enables instant dark/light switch via `data-theme` attribute without JS class manipulation per element.
|
||||||
|
|
||||||
|
**2026-04-24**: `client.current` getter pattern instead of module-level singleton — config can change at runtime (user updates settings) without requiring page reload.
|
||||||
|
|
||||||
|
**2026-04-24**: TanStack Router flat-route syntax — required by v1 Vite plugin; `params` cast as `as never` at callsites to satisfy the union type constraint without widening the app's own types.
|
||||||
|
|
||||||
|
**2026-04-24**: Token is optional — self-hosted Honcho instances may not require auth; `checkConnection()` probes the API to detect whether a 401 is returned, then surfaces the result in the settings form.
|
||||||
Reference in New Issue
Block a user