Ctrl K
ComunidadGuías…

CLAUDE.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# CLAUDE.md

Guidance for AI coding agents working on Writers Guild. Everything in "The CI
gate" below is enforced by GitHub Actions on every PR to `main`.

Writers Guild is a self-hosted, AI-powered short story writing app: an Express
server (plain JavaScript, ESM) with SQLite storage, plus a Vue 3 + Vite client.

## Layout

- `server/` — Express routes (`src/routes/`), services (`src/services/`,
  including the LLM provider adapters in `services/providers/`), SQLite storage
- `vue_client/` — Vue 3 SPA (components, views, composables)
- `shared/` — code imported by both server and client
- `data/` — runtime user data; never read or write it from tests or tooling
- Tests are Vitest, colocated in `__tests__/` directories next to the code

## The CI gate — run before every PR

| Command                | What it is                                  |
| ---------------------- | ------------------------------------------- |
| `npm run lint`         | **oxlint** — errors fail CI, warnings don't |
| `npm run format:check` | **oxfmt**                                   |
| `npm test`             | **Vitest**, server + client suites          |

All three must pass before opening a PR. `npm run format` writes formatting
fixes; `npm run lint:fix` applies safe lint fixes.

## Code style

- **Formatter is `oxfmt`, NOT Prettier; linter is `oxlint`, NOT ESLint.** Do
  not run or configure Prettier/ESLint — they fight the house style (single
  quotes, 100-col width, trailing commas).
- Tooling conventions mirror
  [amiantos/lurker](https://github.com/amiantos/lurker): keep `.oxfmtrc.json`
  and `.oxlintrc.json` minimal, stating only non-default choices.
- **Unused vars/params:** prefix with `_` to satisfy the lint rule. For Express
  error middleware that means `(err, req, res, _next)` — keep the 4-arg arity,
  Express uses it to detect error handlers.
- Match the surrounding code's naming, comment density, and idiom.

## Users

- Each row of `OWNED_TABLES` (`server/src/services/database.js`) belongs to a user. **Every query
  on one must keep to the current user**: `AND ${MINE}` (`user_id = current_user_id()`), or
  `mineThrough()` for a table that hangs off one, and inserts set `user_id` to
  `current_user_id()`. See `server/src/services/user-context.js`.
- `current_user_id()` reads the user from AsyncLocalStorage, set per request by
  `middleware/authenticate.js`, and throws outside one. Work outside a request runs inside
  `runAsUser()`. Tests fall back to the admin (`src/__tests__/setup.js`); isolation tests turn
  that off with `setFallbackUserId(null)`.

## Testing

- `npm run test:server` / `npm run test:client` run one side on its own.
- Tests create their own temporary directories; never point them at `data/`.