openpencil/apps/web/vite.config.ts
Kayshen-X a7d73ebb62 feat(ai): pencil-style agentic design tool-loop, multi-chat tabs, #27 panel restyle
Built-in design generation now runs as an agentic MCP tool-loop (reusing the
agent-rs BuiltInProvider), gated behind OPENPENCIL_DESIGN_AGENT_LOOP / the
Settings experimental toggle; the orchestrator stays the default.

- design-agent system prompt + in-process design toolset (parity-locked with
  the MCP surface) + flag-gated Intent::Design routing
- spawn_agents execution as sequential sub-loops + live creation-mode badges
  (per-agent glow + 'N/M designing...' header)
- new MCP tools: get_guidelines, ToolSearch, get_screenshot, get_editor_state,
  export_nodes, spawn_agents; style-guide local audit
- #27 AI panel restyle: rounded tool cards + green check-rings, gray user
  bubbles, model-pill bottom toolbar, header, empty-state pills, the
  PARALLEL AGENTS (agent_team_size) 1x-6x chip dropdown
- multi-chat tabs: ChatSessions model (Deref-to-active) + tab row UI
  (switch / close / + / Cmd+T) with each run bound to its tab

Large checkpoint commit spanning the working tree (Rust shell crates).
2026-07-02 21:21:06 +08:00

81 lines
2.4 KiB
TypeScript

import { defineConfig } from 'vitest/config';
import { devtools } from '@tanstack/devtools-vite';
import { tanstackStart } from '@tanstack/react-start/plugin/vite';
import viteReact from '@vitejs/plugin-react';
import viteTsConfigPaths from 'vite-tsconfig-paths';
import { fileURLToPath, URL } from 'node:url';
import tailwindcss from '@tailwindcss/vite';
import { nitro } from 'nitro/vite';
import { copyFileSync, mkdirSync, existsSync } from 'node:fs';
import { resolve } from 'node:path';
import { vitePluginSkills } from '../../packages/pen-ai-skills/vite-plugin-skills';
const isElectronBuild = process.env.BUILD_TARGET === 'electron';
// Copy CanvasKit WASM files to public directory for runtime loading
function copyCanvasKitWasm() {
const wasmDir = resolve('public/canvaskit');
if (!existsSync(wasmDir)) mkdirSync(wasmDir, { recursive: true });
const ckDir = resolve('../../node_modules/canvaskit-wasm/bin');
const files = ['canvaskit.wasm'];
for (const file of files) {
const src = resolve(ckDir, file);
const dest = resolve(wasmDir, file);
if (existsSync(src) && !existsSync(dest)) {
copyFileSync(src, dest);
}
}
}
copyCanvasKitWasm();
const config = defineConfig({
test: {
teardownTimeout: 1000,
include: [
'src/**/*.test.{ts,tsx}',
'server/**/*.test.ts',
'../../packages/*/src/**/*.test.{ts,tsx}',
'../desktop/git/__tests__/**/*.test.ts',
'../../scripts/**/__tests__/**/*.test.ts',
],
setupFiles: ['./src/__tests__/setup-react.ts'],
},
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
ssr: {
external: ['@zseven-w/agent-native'],
},
assetsInclude: ['**/*.wasm'],
plugins: [
vitePluginSkills(fileURLToPath(new URL('../../packages/pen-ai-skills', import.meta.url))),
...(process.env.NODE_ENV === 'production' ? [] : [devtools()]),
nitro({
rollupConfig: {
external: [
/^@sentry\//,
'canvas',
'jsdom',
'cssstyle',
'canvaskit-wasm',
'@zseven-w/agent-native',
],
},
serverDir: './server',
output: { dir: '../../out/web' },
...(isElectronBuild ? { preset: 'node-server' } : {}),
}),
// this is the plugin that enables path aliases
viteTsConfigPaths({
projects: ['./tsconfig.json'],
}),
tailwindcss(),
tanstackStart(),
viteReact(),
],
});
export default config;