diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6b82d8b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,19 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 +trim_trailing_whitespace = true +indent_style = tab +indent_size = 2 + +[*.{md,mdx}] +trim_trailing_whitespace = false + +[*.{yml,yaml,toml}] +indent_style = space +indent_size = 2 + +[*.json] +indent_style = tab diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fb7c6c7..c7121f7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: - uses: ./.github/actions/setup - - run: pnpm turbo lint typecheck test build --filter=@openconcho/web + - run: make ci-web cargo-check: name: Rust compile check @@ -36,7 +36,7 @@ jobs: - uses: ./.github/actions/setup - - run: pnpm turbo cargo-check --filter=@openconcho/desktop + - run: make ci-desktop release: name: Release diff --git a/.gitignore b/.gitignore index 698f67f..7abf907 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ dist-ssr # Editor directories and files .vscode/* !.vscode/extensions.json +!.vscode/settings.json .idea .DS_Store *.suo diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..a45fd52 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +24 diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..556613c --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + "recommendations": [ + "biomejs.biome", + "tauri-apps.tauri-vscode", + "rust-lang.rust-analyzer", + "bradlc.vscode-tailwindcss", + "editorconfig.editorconfig", + "ms-playwright.playwright" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..48489f8 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,26 @@ +{ + "editor.defaultFormatter": "biomejs.biome", + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.fixAll.biome": "explicit" + }, + "[rust]": { + "editor.defaultFormatter": "rust-lang.rust-analyzer" + }, + "typescript.tsdk": "node_modules/typescript/lib", + "typescript.enablePromptUseWorkspaceTsdk": true, + "search.exclude": { + "**/node_modules": true, + "**/dist": true, + "**/.turbo": true, + "**/playwright-report": true, + "**/test-results": true, + "**/src-tauri/target": true, + "**/pnpm-lock.yaml": true, + "packages/web/src/api/schema.d.ts": true, + "packages/web/src/routeTree.gen.ts": true + }, + "files.associations": { + ".releaserc.json": "jsonc" + } +} diff --git a/CLAUDE.md b/CLAUDE.md index f6c3d60..d647c4c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,28 +1,37 @@ # openconcho -Frontend UI for self-hosted Honcho instances — browse memories, peers, sessions, conclusions, and chat with memory context. +Frontend UI for self-hosted Honcho instances — browse memories, peers, sessions, conclusions, and chat with memory context. Ships as a web app (`@openconcho/web`) and a Tauri desktop wrapper (`@openconcho/desktop`). ## Commands +`make` is the canonical interface; it shells out to pnpm scripts which shell out to turborepo. CI calls the same targets — `make help` lists everything. + | 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` | +| `make bootstrap` | Install deps + Playwright Chromium (run once after clone) | +| `make dev-web` | Vite dev server on http://localhost:5173 | +| `make dev-desktop` (or `make dev`) | Tauri desktop app | +| `make build` | Turbo: build web + desktop | +| `make lint` | Biome check | +| `make typecheck` | tsc --noEmit | +| `make test` | Vitest (unit + integration), excludes `e2e/` | +| `make test-e2e` | Playwright e2e (uncached) | +| `make check` | lint + typecheck + test | +| `pnpm --filter @openconcho/web generate:api` | Regen `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 | +| `packages/web/` | Vite + React 19 + TanStack Router/Query SPA | +| `packages/web/src/routes/` | TanStack Router file-based routes (flat-route syntax) | +| `packages/web/src/components/` | Feature components grouped by domain | +| `packages/web/src/api/` | openapi-fetch client + TanStack Query hooks | +| `packages/web/src/lib/` | Config (localStorage) + theme utilities | +| `packages/web/src/hooks/` | Custom React hooks | +| `packages/web/src/test/` | Vitest unit/integration tests + setup | +| `packages/web/e2e/` | Playwright e2e specs | +| `packages/desktop/` | Tauri shell that bundles the built web app | | `.claude/rules/` | Coding conventions (auto-loaded) | | `docs/` | Architecture and references | @@ -45,3 +54,7 @@ Read `docs/architecture.md` for component overview, data flow, and design decisi - **`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. +- **Shared deps via pnpm catalog** — version-pinned in `pnpm-workspace.yaml`; reference as `"catalog:"` in package.json +- **Conventional commits enforced** — commitlint runs in husky `commit-msg`; body lines must be ≤100 chars +- **Releases via semantic-release** — `.releaserc.json`; commits land on `main`, no manual version bumps +- **GitHub account** — push under `offendingcommit` (`gh auth switch` if needed) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d149cf9..6464d81 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,26 +13,37 @@ Thanks for your interest in helping out. This is a small, focused project — pl ```bash git clone https://github.com/offendingcommit/openconcho.git cd openconcho -pnpm install -pnpm dev # web dev server at http://localhost:5173 +make bootstrap # installs deps + Playwright Chromium +make dev-web # web dev server at http://localhost:5173 ``` +Run `make help` to see every target. Make is the canonical interface — CI calls +the same targets, so anything that passes locally will pass in CI. + +Node 24 is what CI runs (`.nvmrc`); pnpm version is pinned via the +`packageManager` field — `corepack enable` and it just works. + +VS Code users: workspace recommends Biome, Tauri, rust-analyzer, Tailwind, +EditorConfig, and Playwright extensions on first open. + For desktop work: ```bash -pnpm --filter @openconcho/desktop dev +make dev-desktop # alias: make dev ``` +Tauri needs system dependencies (WebKit, etc.) — see the +[Tauri prerequisites guide](https://tauri.app/start/prerequisites/) for your OS. + ## Before opening a PR ```bash -pnpm lint # Biome lint -pnpm typecheck # tsc --noEmit -pnpm test # Vitest -pnpm build # full build +make check # lint + typecheck + unit/integration tests +make test-e2e # Playwright (requires `make bootstrap` first) +make build # full build ``` -All four must pass. CI will block the merge otherwise. +CI will block the merge otherwise. ## Coding standards @@ -49,7 +60,7 @@ The full standards live in [`.claude/rules/coding-standards.md`](.claude/rules/c `src/api/schema.d.ts` is generated. Don't edit it by hand — run: ```bash -pnpm generate:api +pnpm --filter @openconcho/web generate:api ``` …after updating `openapi.json`. diff --git a/Makefile b/Makefile index 5855d48..b04432f 100644 --- a/Makefile +++ b/Makefile @@ -1,22 +1,51 @@ -.PHONY: dev build test lint lint-fix typecheck install +# Single source of truth for repo commands. CI calls these targets too, +# so anything that works in `make` locally works in `make` on a runner. +# Targets delegate to pnpm scripts, which delegate to turborepo. -dev: - pnpm --filter @openconcho/desktop dev +.PHONY: bootstrap dev dev-web dev-desktop \ + build test test-e2e lint lint-fix typecheck check \ + ci-web ci-desktop install help -build: - pnpm turbo run build +help: + @grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS=":.*?## "}; {printf " \033[36m%-14s\033[0m %s\n", $$1, $$2}' -test: - pnpm turbo run test +bootstrap: ## Install deps + Playwright Chromium (run once after clone) + pnpm bootstrap -lint: - pnpm turbo run lint +dev: dev-desktop ## Alias for `dev-desktop` -lint-fix: - pnpm exec biome check --write packages/web/src/ +dev-web: ## Vite dev server at http://localhost:5173 + pnpm dev:web -typecheck: - pnpm turbo run typecheck +dev-desktop: ## Tauri desktop app + pnpm dev:desktop -install: +build: ## Turbo: build all packages + pnpm build + +test: ## Vitest (unit + integration) + pnpm test + +test-e2e: ## Playwright e2e (requires bootstrap) + pnpm test:e2e + +lint: ## Biome lint check + pnpm lint + +lint-fix: ## Biome lint + format auto-fix + pnpm lint:fix + +typecheck: ## tsc --noEmit across packages + pnpm typecheck + +check: ## lint + typecheck + test + pnpm check + +ci-web: ## CI: lint + typecheck + test + build for @openconcho/web + pnpm ci:web + +ci-desktop: ## CI: cargo-check for @openconcho/desktop + pnpm ci:desktop + +install: ## pnpm install (no playwright) pnpm install diff --git a/package.json b/package.json index 211e0c6..07b0451 100644 --- a/package.json +++ b/package.json @@ -3,13 +3,25 @@ "private": true, "version": "0.5.2", "packageManager": "pnpm@10.33.2", + "engines": { + "node": ">=22", + "pnpm": ">=10" + }, "scripts": { + "bootstrap": "pnpm install && pnpm exec playwright install --with-deps chromium", "dev": "pnpm --filter @openconcho/desktop dev", + "dev:web": "pnpm --filter @openconcho/web dev", + "dev:desktop": "pnpm --filter @openconcho/desktop dev", "build": "turbo run build", "lint": "turbo run lint", + "lint:fix": "biome check --write .", + "format": "biome format --write .", "test": "turbo run test", "test:e2e": "turbo run test:e2e", "typecheck": "turbo run typecheck", + "check": "turbo run lint typecheck test", + "ci:web": "turbo run lint typecheck test build --filter=@openconcho/web", + "ci:desktop": "turbo run cargo-check --filter=@openconcho/desktop", "prepare": "husky" }, "devDependencies": {