Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/slow-falcons-leave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/preact-ai-devtools': minor
---

Initial release
5 changes: 5 additions & 0 deletions docs/getting-started/devtools.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ Or the `@tanstack/solid-ai-devtools` package for SolidJS:
npm install -D @tanstack/solid-ai-devtools @tanstack/solid-devtools
```

Or the `@tanstack/preact-ai-devtools` package for Preact:
```bash
npm install -D @tanstack/preact-ai-devtools @tanstack/preact-devtools
```

## Usage

Import and include the Devtools component in your application:
Expand Down
1 change: 1 addition & 0 deletions packages/typescript/preact-ai-devtools/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# @tanstack/preact-ai-devtools
101 changes: 101 additions & 0 deletions packages/typescript/preact-ai-devtools/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<div align="center">
<img src="./media/header_ai.png" >
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add alt text to the header image.

The header image is missing alt text, which impacts accessibility for screen reader users.

♿ Proposed fix
-  <img src="./media/header_ai.png" >
+  <img src="./media/header_ai.png" alt="TanStack AI Header">
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<img src="./media/header_ai.png" >
<img src="./media/header_ai.png" alt="TanStack AI Header">
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

2-2: Images should have alternate text (alt text)

(MD045, no-alt-text)

🤖 Prompt for AI Agents
In @packages/typescript/preact-ai-devtools/README.md at line 2, The header image
tag lacks an alt attribute which hurts accessibility; update the <img
src="./media/header_ai.png" > element in README.md to include a meaningful alt
text (for example alt="AI DevTools header" or another concise description of the
image content) so screen readers can convey its purpose; ensure the tag becomes
<img src="./media/header_ai.png" alt="..."> and keep the alt text brief and
descriptive.

</div>

<br />

<div align="center">
<a href="https://npmjs.com/package/@tanstack/ai" target="\_parent">
<img alt="" src="https://img.shields.io/npm/dm/@tanstack/ai.svg" />
</a>
<a href="https://github.com/TanStack/ai" target="\_parent">
<img alt="" src="https://img.shields.io/github/stars/TanStack/ai.svg?style=social&label=Star" alt="GitHub stars" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Replace hard tabs with spaces.

Lines 12, 23-25 contain hard tabs instead of spaces, which should be corrected for consistency with the rest of the file.

🔧 Proposed fix
 <a href="https://github.com/TanStack/ai" target="\_parent">
-	  <img alt="" src="https://img.shields.io/github/stars/TanStack/ai.svg?style=social&label=Star" alt="GitHub stars" />
+  <img alt="" src="https://img.shields.io/github/stars/TanStack/ai.svg?style=social&label=Star" alt="GitHub stars" />
 </a>
-	<a href="#badge">
-		<img src="https://img.shields.io/github/v/release/tanstack/ai" alt="Release"/>
-	</a>
+<a href="#badge">
+  <img src="https://img.shields.io/github/v/release/tanstack/ai" alt="Release"/>
+</a>

Also applies to: 23-25

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

12-12: Hard tabs
Column: 1

(MD010, no-hard-tabs)

🤖 Prompt for AI Agents
In @packages/typescript/preact-ai-devtools/README.md at line 12, Replace the
hard tab characters on the affected lines (12 and 23–25) with spaces to match
the rest of the README's indentation style; edit the lines containing the image
badge and the subsequent lines to remove tabs and use the file's existing
space-based indentation (e.g., two spaces per indent level) so whitespace is
consistent throughout.

</a>
<a href="https://bundlephobia.com/result?p=@tanstack/ai@latest" target="\_parent">
<img alt="" src="https://badgen.net/bundlephobia/minzip/@tanstack/ai@latest" />
</a>
Comment on lines +8 to +16
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Package references are incorrect for preact-ai-devtools.

The badges reference @tanstack/ai instead of @tanstack/preact-ai-devtools. Users viewing this README on npm will see incorrect download stats and bundle size information for the devtools package.

📦 Proposed fix
-<a href="https://npmjs.com/package/@tanstack/ai" target="\_parent">
-  <img alt="" src="https://img.shields.io/npm/dm/@tanstack/ai.svg" />
+<a href="https://npmjs.com/package/@tanstack/preact-ai-devtools" target="\_parent">
+  <img alt="" src="https://img.shields.io/npm/dm/@tanstack/preact-ai-devtools.svg" />
 </a>
 <a href="https://github.com/TanStack/ai" target="\_parent">
 	  <img alt="" src="https://img.shields.io/github/stars/TanStack/ai.svg?style=social&label=Star" alt="GitHub stars" />
 </a>
-<a href="https://bundlephobia.com/result?p=@tanstack/ai@latest" target="\_parent">
-  <img alt="" src="https://badgen.net/bundlephobia/minzip/@tanstack/ai@latest" />
+<a href="https://bundlephobia.com/result?p=@tanstack/preact-ai-devtools@latest" target="\_parent">
+  <img alt="" src="https://badgen.net/bundlephobia/minzip/@tanstack/preact-ai-devtools@latest" />
 </a>
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

12-12: Hard tabs
Column: 1

(MD010, no-hard-tabs)

🤖 Prompt for AI Agents
In @packages/typescript/preact-ai-devtools/README.md around lines 8 - 16, The
README badges currently reference the wrong package (@tanstack/ai); update all
occurrences in the badge links and image sources to use
@tanstack/preact-ai-devtools instead so the npm, GitHub and bundlephobia badges
show correct stats for this package (replace the hrefs and the img src URLs that
include "@tanstack/ai" with "@tanstack/preact-ai-devtools" and ensure the
npm/bundlephobia URLs and badge labels reflect the preact-ai-devtools package).

</div>

<div align="center">
<a href="#badge">
<img alt="semantic-release" src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg">
</a>
<a href="#badge">
<img src="https://img.shields.io/github/v/release/tanstack/ai" alt="Release"/>
</a>
<a href="https://twitter.com/tan_stack">
<img src="https://img.shields.io/twitter/follow/tan_stack.svg?style=social" alt="Follow @TanStack"/>
</a>
</div>

<div align="center">

### [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/)
</div>

# TanStack Preact AI Devtools

Developer tools for TanStack AI in Preact applications.

## Installation

```bash
npm install @tanstack/preact-ai-devtools
# or
pnpm add @tanstack/preact-ai-devtools
# or
yarn add @tanstack/preact-ai-devtools
```

## Usage

### Using the Panel Component

Add the `AiDevtoolsPanel` component to your app:

```tsx
import { AiDevtoolsPanel } from '@tanstack/preact-ai-devtools'

function App() {
return (
<>
<YourApp />
<AiDevtoolsPanel />
</>
)
}
```

### Using the Plugin

You can also use the devtools as a plugin:

```tsx
import { aiDevtoolsPlugin } from '@tanstack/preact-ai-devtools'
import { useAIProvider } from '@tanstack/ai-preact'

function App() {
const ai = useAIProvider({
// your config
plugins: [aiDevtoolsPlugin()],
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems to be completely hallucinated


return <YourApp />
}
```

## Production Builds

For production builds, import from the production entry point to exclude devtools code:

```tsx
import { AiDevtoolsPanel } from '@tanstack/preact-ai-devtools/production'
```

The devtools will automatically be disabled in production environments when using the main entry point.

## Get Involved

- [Join the Discord](https://tlinz.com/discord)
- [Read the docs](https://tanstack.com/ai)
- [Report an issue](https://github.com/TanStack/ai/issues)
62 changes: 62 additions & 0 deletions packages/typescript/preact-ai-devtools/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"name": "@tanstack/preact-ai-devtools",
"version": "0.0.0",
"description": "Preact Devtools for TanStack AI.",
"author": "tannerlinsley",
"license": "MIT",
"homepage": "https://tanstack.com/ai",
"repository": {
"type": "git",
"url": "git+https://github.com/TanStack/ai.git",
"directory": "packages/typescript/ai"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
},
"scripts": {
"clean": "premove ./build ./dist",
"lint:fix": "eslint ./src --fix",
"test:eslint": "eslint ./src",
"test:lib": "vitest --passWithNoTests",
"test:lib:dev": "pnpm test:lib --watch",
"test:types": "tsc",
"test:build": "publint --strict",
"build": "vite build"
},
"type": "module",
"types": "./dist/esm/index.d.ts",
"module": "./dist/esm/index.js",
"exports": {
".": {
"import": {
"types": "./dist/esm/index.d.ts",
"default": "./dist/esm/index.js"
}
},
"./production": {
"import": {
"types": "./dist/esm/production.d.ts",
"default": "./dist/esm/production.js"
}
},
"./package.json": "./package.json"
},
"sideEffects": false,
"files": [
"dist",
"src"
],
"dependencies": {
"@tanstack/ai-devtools-core": "workspace:*",
"@tanstack/devtools-utils": "^0.2.0"
},
"devDependencies": {
"@vitest/coverage-v8": "4.0.14",
"vite": "^7.2.7",
"@preact/preset-vite": "^2.9.3"
},
"peerDependencies": {
"preact": "^10.0.0"
}
}
9 changes: 9 additions & 0 deletions packages/typescript/preact-ai-devtools/src/AiDevtools.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { createPreactPanel } from '@tanstack/devtools-utils/preact'
import { AiDevtoolsCore } from '@tanstack/ai-devtools-core'
import type { DevtoolsPanelProps } from '@tanstack/devtools-utils/preact'

const [AiDevtoolsPanel, AiDevtoolsPanelNoOp] = createPreactPanel(AiDevtoolsCore)

export interface AiDevtoolsPreactInit extends DevtoolsPanelProps {}

export { AiDevtoolsPanel, AiDevtoolsPanelNoOp }
14 changes: 14 additions & 0 deletions packages/typescript/preact-ai-devtools/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as Devtools from './AiDevtools'
import * as plugin from './plugin'

export const AiDevtoolsPanel =
process.env.NODE_ENV !== 'development'
? Devtools.AiDevtoolsPanelNoOp
: Devtools.AiDevtoolsPanel

export const aiDevtoolsPlugin =
process.env.NODE_ENV !== 'development'
? plugin.aiDevtoolsNoOpPlugin
: plugin.aiDevtoolsPlugin
Comment on lines +4 to +12
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, verify the file exists and check its contents
ls -la packages/typescript/preact-ai-devtools/src/
cat -n packages/typescript/preact-ai-devtools/src/index.ts

Repository: TanStack/ai

Length of output: 914


🏁 Script executed:

# Check the package.json for build configuration and exports
cat packages/typescript/preact-ai-devtools/package.json

Repository: TanStack/ai

Length of output: 1588


🏁 Script executed:

# Check if dist directory exists and what's in it
ls -la packages/typescript/preact-ai-devtools/dist/ 2>/dev/null || echo "dist/ does not exist yet"

Repository: TanStack/ai

Length of output: 79


🏁 Script executed:

# Look for the Nx/build configuration files
fd -e "tsconfig.json" -e "vite.config.ts" -e "vite.config.js" packages/typescript/preact-ai-devtools/ 2>/dev/null | head -20

Repository: TanStack/ai

Length of output: 37


🏁 Script executed:

# Check production.ts which appears to be an alternative export
cat -n packages/typescript/preact-ai-devtools/src/production.ts

Repository: TanStack/ai

Length of output: 239


🏁 Script executed:

# Check AiDevtools.tsx to see the NoOp implementation
cat -n packages/typescript/preact-ai-devtools/src/AiDevtools.tsx

Repository: TanStack/ai

Length of output: 519


🏁 Script executed:

# Check plugin.tsx to see the NoOp implementation
cat -n packages/typescript/preact-ai-devtools/src/plugin.tsx

Repository: TanStack/ai

Length of output: 467


🏁 Script executed:

# Look for Vite configuration
find packages/typescript/preact-ai-devtools -name "vite.config.*" -o -name "tsconfig.json" | xargs cat -n 2>/dev/null

Repository: TanStack/ai

Length of output: 1461


🏁 Script executed:

# Check if there's a shared Vite config at the workspace root
find . -maxdepth 3 -name "vite.config.*" | head -10

Repository: TanStack/ai

Length of output: 324


🏁 Script executed:

# Find the vite-config package to understand how NODE_ENV is handled
fd -e "vite-config" -type d | head -5

Repository: TanStack/ai

Length of output: 225


🏁 Script executed:

# Search for documentation or configuration about NODE_ENV handling
rg "NODE_ENV" packages/typescript/preact-ai-devtools/ -C 3

Repository: TanStack/ai

Length of output: 991


🏁 Script executed:

# Check if there's a shared vite config explanation
rg "define:" . --type ts --type js -C 2 | head -30

Repository: TanStack/ai

Length of output: 37


🏁 Script executed:

# Look at how other devtools packages handle this
find packages/typescript -name "*devtools*" -type d | head -10

Repository: TanStack/ai

Length of output: 201


🏁 Script executed:

# Check the ai-devtools-core to see if there's a similar pattern
cat packages/typescript/ai-devtools-core/src/index.ts 2>/dev/null | head -20

Repository: TanStack/ai

Length of output: 37


🏁 Script executed:

# Look at how tanstackViteConfig is configured - might be in a shared package
rg "tanstackViteConfig" . --type-list | head -5

Repository: TanStack/ai

Length of output: 444


🏁 Script executed:

# Check the vite-config package contents
find . -path "*/vite-config/*" -name "*.ts" | head -10

Repository: TanStack/ai

Length of output: 37


🏁 Script executed:

# Search for packages that contain vite-config
ls -la packages/ | grep -i vite

Repository: TanStack/ai

Length of output: 37


🏁 Script executed:

# Check if tanstackViteConfig is exported from a package
rg "export.*tanstackViteConfig" --type ts --type js

Repository: TanStack/ai

Length of output: 37


🏁 Script executed:

# Search for tanstackViteConfig definition or import
rg "tanstackViteConfig" --include="*.ts" --include="*.js"

Repository: TanStack/ai

Length of output: 496


🏁 Script executed:

# Check node_modules or look for the package
find . -name "@tanstack" -type d | grep vite

Repository: TanStack/ai

Length of output: 37


🏁 Script executed:

# Look at package.json files to find where tanstackViteConfig comes from
rg "@tanstack/vite-config" --include="package.json"

Repository: TanStack/ai

Length of output: 496


🏁 Script executed:

# Check the vite config more carefully - look at what tanstackViteConfig does
# It might be handling NODE_ENV automatically
cat -n packages/typescript/react-ai-devtools/vite.config.ts 2>/dev/null | head -50

Repository: TanStack/ai

Length of output: 1102


🏁 Script executed:

# Search for how other packages handle NODE_ENV
rg "NODE_ENV" packages/typescript/ -l | head -10

Repository: TanStack/ai

Length of output: 253


🏁 Script executed:

# Check the structure of another devtools package to compare
cat packages/typescript/react-ai-devtools/src/index.ts 2>/dev/null

Repository: TanStack/ai

Length of output: 478


🏁 Script executed:

# Look at the learnings to understand the recommended pattern
# Check if there are any adapter patterns mentioned
rg "adapter" packages/typescript/preact-ai-devtools/ -i

Repository: TanStack/ai

Length of output: 37


🏁 Script executed:

# Verify the package exports are correctly defined
cat packages/typescript/preact-ai-devtools/package.json | jq '.exports'

Repository: TanStack/ai

Length of output: 346


The environment-based export pattern is correct, but consider documenting the explicit ./production subpath export as the more reliable alternative for users prioritizing bundle size.

The conditional process.env.NODE_ENV checks are used consistently across all devtools packages (react-ai-devtools, solid-ai-devtools) and work correctly with Vite's configuration. However, the package already provides ./production.ts as an alternative entry point that directly exports production implementations without relying on NODE_ENV detection. This explicit export (@tanstack/preact-ai-devtools/production) is more reliable for users who want to guarantee their bundler eliminates development code, as it bypasses the NODE_ENV pattern entirely. Consider documenting this option in your package README or examples.

🤖 Prompt for AI Agents
In @packages/typescript/preact-ai-devtools/src/index.ts around lines 4-12, Add
documentation noting the explicit production subpath export as an alternative to
NODE_ENV checks: explain that instead of relying on the conditional exports
(AiDevtoolsPanel and aiDevtoolsPlugin) which use process.env.NODE_ENV, users can
import from the provided './production' subpath (e.g.,
@tanstack/preact-ai-devtools/production) to always get production
implementations and reduce bundle size; update README/examples to show both
import patterns and recommend the './production' path for bundler-safe builds.


export type { AiDevtoolsPreactInit } from './AiDevtools'
11 changes: 11 additions & 0 deletions packages/typescript/preact-ai-devtools/src/plugin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { createPreactPlugin } from '@tanstack/devtools-utils/preact'
import { AiDevtoolsPanel } from './AiDevtools'

const [aiDevtoolsPlugin, aiDevtoolsNoOpPlugin] = createPreactPlugin({
Component: AiDevtoolsPanel,
name: 'TanStack AI',
id: 'tanstack-ai',
defaultOpen: true,
})

export { aiDevtoolsPlugin, aiDevtoolsNoOpPlugin }
5 changes: 5 additions & 0 deletions packages/typescript/preact-ai-devtools/src/production.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export { AiDevtoolsPanel } from './AiDevtools'

export type { AiDevtoolsPreactInit } from './AiDevtools'

export { aiDevtoolsPlugin } from './plugin'
11 changes: 11 additions & 0 deletions packages/typescript/preact-ai-devtools/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"jsx": "preserve",
"jsxFactory": "h",
"jsxFragmentFactory": "Fragment",
"moduleResolution": "bundler",
"strictNullChecks": true
},
"include": ["eslint.config.js", "prettier.config.js", "src"]
}
36 changes: 36 additions & 0 deletions packages/typescript/preact-ai-devtools/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { defineConfig, mergeConfig } from 'vitest/config'
import { tanstackViteConfig } from '@tanstack/vite-config'
import packageJson from './package.json'

const config = defineConfig({
test: {
name: packageJson.name,
dir: './',
watch: false,
globals: true,
environment: 'node',
include: ['tests/**/*.test.ts'],
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html', 'lcov'],
exclude: [
'node_modules/',
'dist/',
'tests/',
'**/*.test.ts',
'**/*.config.ts',
'**/types.ts',
],
include: ['src/**/*.ts'],
},
},
})

export default mergeConfig(
config,
tanstackViteConfig({
entry: ['./src/index.ts', './src/production.ts'],
srcDir: './src',
cjs: false,
}),
)
7 changes: 7 additions & 0 deletions packages/typescript/preact-ai-devtools/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from 'vitest/config'

export default defineConfig({
test: {
watch: false,
},
})
Comment on lines +1 to +7
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Compare Vitest configurations in both files

echo "=== vite.config.ts ==="
cat packages/typescript/preact-ai-devtools/vite.config.ts

echo -e "\n=== vitest.config.ts ==="
cat packages/typescript/preact-ai-devtools/vitest.config.ts

echo -e "\n=== Check for other TanStack packages with similar pattern ==="
fd -t f "vitest.config.ts" packages/typescript/

Repository: TanStack/ai

Length of output: 1567


🏁 Script executed:

#!/bin/bash
# Sample vitest.config.ts files from other packages

echo "=== ai-devtools vitest.config.ts ==="
cat packages/typescript/ai-devtools/vitest.config.ts

echo -e "\n=== ai-openai vitest.config.ts ==="
cat packages/typescript/ai-openai/vitest.config.ts

echo -e "\n=== ai-react vitest.config.ts ==="
cat packages/typescript/ai-react/vitest.config.ts

echo -e "\n=== Check corresponding vite.config.ts for ai-openai ==="
cat packages/typescript/ai-openai/vite.config.ts | head -20

Repository: TanStack/ai

Length of output: 2174


Remove redundant vitest.config.ts that overrides test configuration.

When both vite.config.ts and vitest.config.ts exist, Vitest uses the .vitest.config.ts file with precedence. The current vitest.config.ts with only watch: false would override the comprehensive test configuration in vite.config.ts (globals, environment, include patterns, coverage settings), causing the test setup to break when running vitest commands.

This pattern differs from other TanStack packages (ai-devtools, ai-openai, ai-react, etc.) which consolidate full test configuration into vitest.config.ts. Either move the test configuration from vite.config.ts to vitest.config.ts to match the pattern across packages, or remove vitest.config.ts entirely if keeping configuration in vite.config.ts.

🤖 Prompt for AI Agents
In @packages/typescript/preact-ai-devtools/vitest.config.ts around lines 1-7,
The vitest.config.ts file currently exports a defineConfig with a test block
containing only watch: false which unintentionally overrides the full test setup
in vite.config.ts; either delete this vitest.config.ts entirely or replace its
contents by copying the full test configuration from vite.config.ts into
vitest.config.ts (preserving defineConfig and the test object) so that globals,
environment, include patterns and coverage settings are present and no longer
hidden by the minimal test: { watch: false } override.

Loading
Loading