-
-
Notifications
You must be signed in to change notification settings - Fork 210
chore: monorepo setup audit (build, tsconfig, types, docs) #572
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
239e721
chore(monorepo): tighten build/CI scope, defensive changeset ignores,…
AlemTuzlak 2ab32d9
chore(tsconfig): consolidate to root tsconfig.base.json and include t…
AlemTuzlak 77c947b
refactor(ai-gemini): merge GeminiThinking{,Advanced}Options into one …
AlemTuzlak 66737a5
refactor(ai-anthropic): drop modelOptions.system escape hatch
AlemTuzlak d618ed4
fix(ai): expose Logger via the adapter-internals subpath
AlemTuzlak 31bfa1c
test: fix type rot and unsafe casts surfaced by typecheck standardiza…
AlemTuzlak b5d1747
docs(contributing): add CONTRIBUTING.md, editorconfig, vscode recomme…
AlemTuzlak 2f77fb7
ci: apply automated fixes
autofix-ci[bot] 0561426
chore(changesets): use ts-* glob instead of listing each example expl…
AlemTuzlak 30e3317
docs: drop incorrect Node.js v24+ requirement from READMEs and CONTRI…
AlemTuzlak 8323a3c
fix: scope Node version constraint to ai-isolate-node (Node >= 22 for…
AlemTuzlak 05e65f1
chore: address CodeRabbit feedback on PR #572
AlemTuzlak c284260
fix(ai-anthropic): warn loudly when modelOptions keys are dropped
tombeckenham 1031edd
Merge main into chore/monorepo-setup-audit + fix structured-output test
AlemTuzlak File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| --- | ||
| '@tanstack/ai-anthropic': minor | ||
| --- | ||
|
|
||
| Drop `modelOptions.system` from the accepted Anthropic provider options. System prompts must now flow through the top-level `systemPrompts` option on `chat()`/`structuredOutput()`. | ||
|
|
||
| This was an undocumented escape hatch only reachable via casts, but it was the only way to attach `cache_control` to system blocks for prompt caching. Until `systemPrompts` is widened to carry per-prompt metadata (planned follow-up), callers who need Anthropic `cache_control` on system text should keep using `modelOptions.system` on the prior version, or supply a custom adapter override. | ||
|
|
||
| To make the removal loud instead of silent, the adapter now logs an `errors`-category log line via the provided `Logger` whenever unknown `modelOptions` keys are passed (including `system`). Callers casting around the public type will see the dropped keys named in the log, rather than the request going out without them. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| root = true | ||
|
|
||
| [*] | ||
| charset = utf-8 | ||
| end_of_line = lf | ||
| indent_style = space | ||
| indent_size = 2 | ||
| insert_final_newline = true | ||
| trim_trailing_whitespace = true | ||
|
|
||
| [*.md] | ||
| trim_trailing_whitespace = false | ||
|
|
||
| [Makefile] | ||
| indent_style = tab |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "recommendations": [ | ||
| "dbaeumer.vscode-eslint", | ||
| "esbenp.prettier-vscode", | ||
| "vitest.explorer", | ||
| "nrwl.angular-console", | ||
| "svelte.svelte-vscode", | ||
| "Vue.volar", | ||
| "EditorConfig.EditorConfig" | ||
| ] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,161 @@ | ||
| # Contributing to TanStack AI | ||
|
|
||
| Thanks for contributing! This guide covers everything you need to get from a fresh clone to a merged PR. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - **pnpm**: 10.17.0 or newer. Use the version pinned in `packageManager` (`pnpm@11.1.1`). | ||
| - Recommended: install via [Corepack](https://nodejs.org/api/corepack.html). Run `corepack enable` once and pnpm is managed automatically. | ||
| - **Git**. | ||
|
|
||
| ## Initial setup | ||
|
|
||
| ```bash | ||
| git clone https://github.com/TanStack/ai.git | ||
| cd ai | ||
| pnpm install | ||
| pnpm run build:all # build all public packages once so workspace deps resolve | ||
| ``` | ||
|
|
||
| `pnpm install` runs Playwright's chromium download (used by the E2E suite). If you don't need E2E, you can skip it via `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 pnpm install`. | ||
|
|
||
| ## Repository layout | ||
|
|
||
| ``` | ||
| packages/typescript/ # Public, published packages (@tanstack/ai, @tanstack/ai-openai, etc.) | ||
| testing/ # Internal test harnesses — NOT published | ||
| e2e/ # Playwright + aimock E2E suite (mandatory coverage for all changes) | ||
| panel/ # Stream processor visualisation panel | ||
| examples/ # Example apps (React, Solid, Vue, Svelte, PHP, Python, vanilla) | ||
| codemods/ # Internal codemods (not published) | ||
| docs/ # Documentation source | ||
| scripts/ # Repo-level scripts (doc generation, model sync, link verification) | ||
| ``` | ||
|
|
||
| - Direct children of `packages/typescript/` are public packages (published to npm). | ||
| - Everything under `examples/`, `testing/`, and `codemods/` is `"private": true` and excluded from build/publish. | ||
| - The build system is **Nx** with affected-target detection. | ||
| - The package manager is **pnpm** with workspace + catalog protocols. | ||
|
|
||
| For deeper architecture details (adapter system, isomorphic tools, framework integrations), see `CLAUDE.md` at the repo root. | ||
|
|
||
| ## Day-to-day commands | ||
|
|
||
| All commands are run from the repo root. Nx handles affected detection and caching. | ||
|
|
||
| | Goal | Command | | ||
| | ----------------------------- | ------------------- | | ||
| | Run unit tests (affected) | `pnpm test:lib` | | ||
| | Watch unit tests | `pnpm test:lib:dev` | | ||
| | Type-check (affected) | `pnpm test:types` | | ||
| | Lint (affected) | `pnpm test:eslint` | | ||
| | Verify build artifacts | `pnpm test:build` | | ||
| | Format the repo | `pnpm format` | | ||
| | Build (affected) | `pnpm build` | | ||
| | Build everything | `pnpm build:all` | | ||
| | Run the full CI suite locally | `pnpm test` | | ||
| | Run the affected-PR check | `pnpm test:pr` | | ||
| | E2E suite | `pnpm test:e2e` | | ||
| | E2E with Playwright UI | `pnpm test:e2e:ui` | | ||
|
|
||
| Working on a single package? `cd packages/typescript/<pkg>` and use its scripts directly (`pnpm test:lib`, `pnpm test:types`, etc.). | ||
|
|
||
| ## TypeScript configuration | ||
|
|
||
| There is a single `tsconfig.base.json` at the repo root with the shared `compilerOptions`. Every package extends it and overrides only what's unique to that package (e.g. `outDir`, JSX runtime, framework lib). | ||
|
|
||
| The standardised per-package shape is: | ||
|
|
||
| ```jsonc | ||
| { | ||
| "extends": "../../../tsconfig.base.json", | ||
| "compilerOptions": { | ||
| "outDir": "dist", | ||
| // + package-specific overrides only | ||
| }, | ||
| "include": ["src", "tests"], | ||
| "exclude": ["node_modules", "dist"], | ||
| } | ||
| ``` | ||
|
|
||
| Tests are included in typecheck. `vite.config.ts` / `vitest.config.ts` are not — they're tooling configs typechecked by the build tools themselves. | ||
|
|
||
| ## Adding a unit test | ||
|
|
||
| - Place tests under `packages/typescript/<pkg>/tests/` with the suffix `.test.ts` (or `.test.tsx` for JSX). | ||
| - Vitest's defaults discover anything matching `**/*.{test,spec}.?(c|m)[jt]s?(x)` — no per-package config is needed. | ||
| - Tests are typechecked by `tsc` and linted by ESLint. | ||
|
|
||
| ## Adding E2E test coverage (required) | ||
|
|
||
| **Every feature, bug fix, or behaviour change MUST have E2E coverage.** See `testing/e2e/README.md` for the full guide. Quick reference: | ||
|
|
||
| | Change type | What to add | | ||
| | -------------------------------------- | ------------------------------------------------------------------------ | | ||
| | New provider adapter | Add provider to `feature-support.ts` + `test-matrix.ts`. Tests auto-run. | | ||
| | New feature (e.g. new generation type) | Add to types, feature config, support matrix, fixture, spec file. | | ||
| | Chat / streaming bug fix | Test case in `chat.spec.ts` or `tools-test/`. | | ||
| | Tool system change | Scenario in `tools-test-scenarios.ts` + spec. | | ||
| | Middleware change | Test in `middleware.spec.ts`. | | ||
| | Client-side change (useChat etc.) | Test covering the observable behavior change. | | ||
|
|
||
| Run the suite locally with `pnpm test:e2e`. Record real LLM fixtures with `OPENAI_API_KEY=sk-... pnpm --filter @tanstack/ai-e2e record`. | ||
|
|
||
| ## Changesets | ||
|
|
||
| Any change that ships in a published package requires a changeset. Examples, internal test harnesses, codemods, and docs do not. | ||
|
|
||
| ```bash | ||
| pnpm changeset | ||
| ``` | ||
|
|
||
| Pick the affected packages and the bump type: | ||
|
|
||
| - **patch**: bug fix, internal refactor, perf, docs in package, no API change. | ||
| - **minor**: new public API, new opt-in behaviour, backwards-compatible enhancement. | ||
| - **major**: breaking change to a published API surface. Coordinate with maintainers first. | ||
|
|
||
| The defensive `ignore` list in `.changeset/config.json` blocks accidental publication from examples/testing/codemods even if `"private": true` is ever dropped. | ||
|
|
||
| ## Branches and commits | ||
|
|
||
| - Branch off `main`. Name the branch after the change (`fix/openai-streaming-eof`, `feat/anthropic-cache-control`). | ||
| - Conventional Commits aren't strictly enforced, but follow the prefixes you see in `git log`: `feat:`, `fix:`, `docs:`, `refactor:`, `chore:`, `ci:`. | ||
| - Keep commits logical. The repo prefers a few coherent commits over one giant squash. | ||
|
|
||
| ## Pull request flow | ||
|
|
||
| 1. Push your branch and open a PR against `main`. | ||
| 2. CI runs: `pnpm test:pr` (sherif workspace check, knip dead-code, docs link verification, ESLint, unit tests, typecheck, build artifacts, build) + the full E2E suite. | ||
| 3. Address review comments. | ||
| 4. A maintainer merges. Releases are cut via Changesets — your changeset entry lands in the next release. | ||
|
|
||
| The PR template lists the steps. The `Test plan` section is required — describe how a reviewer can verify your change. | ||
|
|
||
| ## Adding a new provider adapter | ||
|
|
||
| The pattern lives in `packages/typescript/ai-openai/`, `packages/typescript/ai-anthropic/`, `packages/typescript/ai-gemini/`, etc. New core adapters typically: | ||
|
|
||
| 1. Create `packages/typescript/ai-<provider>/` with `package.json`, `tsconfig.json`, `src/`, `tests/`, `README.md`. Copy structure from an existing adapter. | ||
| 2. Implement tree-shakeable adapter exports under `src/adapters/` (`text.ts`, `embed.ts`, `summarize.ts`, etc.). | ||
| 3. Add `model-meta.ts` so per-model type safety works. | ||
| 4. Wire the provider into `testing/e2e/feature-support.ts` and `testing/e2e/test-matrix.ts`. Existing provider-coverage tests pick it up automatically. | ||
| 5. Record fixtures (`OPENAI_API_KEY=... pnpm --filter @tanstack/ai-e2e record`) — or write deterministic ones by hand. **No real API keys at test time.** | ||
| 6. Add a `pnpm changeset` entry. | ||
|
|
||
| If you're building a community/third-party adapter that lives outside this repo, follow `docs/community-adapters/guide.md` instead. | ||
|
|
||
| ## Known gaps | ||
|
|
||
| - **Vue/Svelte SFCs are not currently linted.** Our linter doesn't yet support `.vue`/`.svelte` parsers in the toolchain we use; the script blocks inside those files rely on TypeScript and tests for safety. If you're touching a `.svelte` or `.vue` file, lean on `tsc` / `svelte-check` / `vue-tsc` and explicit tests. | ||
| - **Build configs (`vite.config.ts`, `vitest.config.ts`) are not in the `tsc` typecheck pass.** They're typechecked at build time by vite/vitest themselves. If you make changes there, run `pnpm build` or `pnpm test:lib` to surface issues. | ||
|
|
||
| ## Reporting issues / getting help | ||
|
|
||
| - Bugs: open a GitHub issue with a minimal repro (the bug report template in `.github/issue_template/bug_report.yml` walks you through it). | ||
| - Questions / discussions: [TanStack Discord](https://tlinz.com/discord). | ||
| - Security: follow the disclosure process in `SECURITY.md` (if applicable) or email the maintainers directly. | ||
|
|
||
| ## Code of Conduct | ||
|
|
||
| By participating you agree to abide by our [Code of Conduct](./CODE_OF_CONDUCT.md). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,6 +36,6 @@ | |
| "tailwindcss": "^4.1.18", | ||
| "tslib": "^2.8.1", | ||
| "typescript": "5.9.3", | ||
| "vite": "^7.2.7" | ||
| "vite": "^7.3.3" | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,6 +13,6 @@ | |
| "@tanstack/ai-client": "workspace:*" | ||
| }, | ||
| "devDependencies": { | ||
| "vite": "^7.2.7" | ||
| "vite": "^7.3.3" | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.