mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-10-13 04:59:51 +08:00
## Problem
Two audits of the repository (a workflow of finder, dedup and per-file verifier agents, run on 2026-10-11 against 1f4141e and again against 07f3e3c after a first round of refactoring) found dead code and features that were more machinery than the app needs: an Electron configuration-preset system with its own settings window, three copies of the about page, a hand-written `.env` parser, an "extended" system prompt nobody selected, two data migrations for formats from 2025-12 and 2026-01, a server-side example cache, type-to-confirm provider deletion, 81 unused dictionary keys, wrapper components around single call sites, and a long tail of unused exports, props, options and tests.
## Change
Every item below was either approved one by one or covered by "fix all of the others".
- **Electron:** the configuration-preset system is gone (settings window, preload, IPC, menu entry, dev watcher); `config-manager.ts` keeps only `userLocale`; `.env` files are parsed with `dotenv`. Entitlements file and a duplicate CI workflow removed; `test.yml` gets a type check and concurrency.
- **Server:** no extended prompt, no example cache, no `ENABLE_HISTORY_XML_REPLACE`, no message metadata or `hasConfig`; the connection test is one shared helper; EdgeOne loses its mock branch and model aliases; `DEBUG_LLM_PAYLOAD` logs message structure instead of payloads; Langfuse scoring helper; `apiKeyEnv` arrays kept and documented in `env.example` and the provider docs.
- **Pages:** one about page per language from a single component (old `/cn` and `/ja` URLs redirect with 308); layout uses `hasLocale`; the GitHub icon is a local component instead of `react-icons`; Cloudflare deploys without an R2 cache by default.
- **Chat and canvas:** the legacy `diagramHistory` conversion, the localStorage chat migration and the templates storage are gone; `chat-engine` reads the diagram through the context's refs; the diagram context has one tagged export path (`requestTaggedExport` / `fetchDiagramXml`); the screenshot check uses fetch + JSON and `generateText` with `Output.object`; `load-diagram` accepts `<svg:svg>` and strips the XML prolog.
- **Settings UI:** `model-selector` inlines its Dialog, Command and Tooltip; `ai-elements/model-selector`, `button-with-tooltip`, `error-toast` removed; no type-to-confirm, no footer, no `bedrockApiKey`; `use-model-config` loses the old-format migration; one reasoning component; the shimmer is CSS (no `motion`, no `@radix-ui/react-use-controllable-state`); 81 dictionary keys removed in all four languages.
- **MCP server:** `registerTool` / `ok` / `fail` replace per-tool try/catch; `syncFromBrowser`, `commitDocument`, `describePages`; the hand-written XML syntax check, unused result fields, `pickPageSelector`, `expandStyles` and the `host` attribute handling are gone; tests get a shared `setup.ts` and drive the server through the SDK client.
- **Prompt:** the web app's style rules come from the MCP drawing guide (`styleRules`), byte-identical to before.
- **Tests:** shared e2e helpers (`openApp`, `sse`, `toolCallEvents`, `chunkedReplies`); placeholder specs dropped; `settings-review-fixes` split by topic; unit tests use `vi.stubEnv`.
- **Dependencies removed:** `@xmldom/xmldom`, `remark-gfm`, `@anthropic-ai/tokenizer`, `@testing-library/user-event`, `concurrently`, `wait-on`, `eslint`, `eslint-config-next`, `@vitest/coverage-v8`, `shx`, `motion`, `@radix-ui/react-use-controllable-state`, `react-icons`.
Source lines: 74,983 before, 67,418 after (excluding lockfiles).
The last commit merges #984 (the canvas shell). Where the shell, the classic page or their tests depend on a wire format or signature this branch had changed, main's version wins (export fields of the poll response, `addHistory` signature); where main only extended code this branch restructured, main's change is carried into the new structure (`start_session`, `get_selection`, `prepareNewDiagram`, the diagram context's `requestExport`).
## Testing
- `tsc --noEmit` for the web app, `packages/mcp-server`, its shell and `electron`: clean
- `biome ci`: 0 errors (37 pre-existing warnings)
- Root `vitest run`: 719 passed; `packages/mcp-server` `vitest run`: 372 passed
- `next build`: clean
- Playwright, whole web suite on the dev server (4 workers): 280 tests, 279 passed; `language.spec.ts` "a stale offer to switch without saving does nothing once a message is being sent" failed under parallel load and passed alone, as it does on main
140 lines
5.8 KiB
JSON
140 lines
5.8 KiB
JSON
{
|
|
"name": "next-ai-draw-io",
|
|
"version": "0.5.0",
|
|
"license": "Apache-2.0",
|
|
"private": true,
|
|
"main": "dist-electron/main/index.js",
|
|
"scripts": {
|
|
"predev": "node scripts/fetch-drawio.mjs",
|
|
"dev": "next dev --turbopack --port 6002",
|
|
"prebuild": "node scripts/fetch-drawio.mjs",
|
|
"build": "next build",
|
|
"start": "next start --port 6001",
|
|
"lint": "biome lint .",
|
|
"format": "biome check --write .",
|
|
"check": "biome ci",
|
|
"prepare": "husky",
|
|
"preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview",
|
|
"deploy": "opennextjs-cloudflare build && opennextjs-cloudflare deploy",
|
|
"upload": "opennextjs-cloudflare build && opennextjs-cloudflare upload",
|
|
"electron:dev": "node scripts/electron-dev.mjs",
|
|
"electron:build": "npm run build && npm run electron:compile",
|
|
"electron:compile": "npx esbuild electron/main/index.ts electron/preload/index.ts --bundle --platform=node --outdir=dist-electron --external:electron --sourcemap",
|
|
"electron:start": "npx cross-env NODE_ENV=development npx electron .",
|
|
"electron:prepare": "node scripts/prepare-electron-build.mjs",
|
|
"dist": "npm run electron:build && npm run electron:prepare && npx electron-builder --config electron/electron-builder.yml",
|
|
"dist:mac": "npm run electron:build && npm run electron:prepare && npx electron-builder --config electron/electron-builder.yml --mac",
|
|
"dist:win": "npm run electron:build && npm run electron:prepare && npx electron-builder --config electron/electron-builder.yml --win",
|
|
"dist:win:build": "npm run electron:build && npm run electron:prepare && npx electron-builder --config electron/electron-builder.yml --win --publish never",
|
|
"dist:linux": "npm run electron:build && npm run electron:prepare && npx electron-builder --config electron/electron-builder.yml --linux",
|
|
"dist:all": "npm run electron:build && npm run electron:prepare && npx electron-builder --config electron/electron-builder.yml --mac --win --linux",
|
|
"test": "vitest",
|
|
"test:e2e": "playwright test"
|
|
},
|
|
"dependencies": {
|
|
"@ai-sdk/amazon-bedrock": "^4.0.191",
|
|
"@ai-sdk/anthropic": "^3.0.127",
|
|
"@ai-sdk/azure": "^3.0.133",
|
|
"@ai-sdk/deepseek": "^2.0.71",
|
|
"@ai-sdk/google": "^3.0.130",
|
|
"@ai-sdk/google-vertex": "^4.0.210",
|
|
"@ai-sdk/openai": "^3.0.124",
|
|
"@ai-sdk/openai-compatible": "^2.0.81",
|
|
"@ai-sdk/react": "^3.0.303",
|
|
"@aihubmix/ai-sdk-provider": "^2.2.1",
|
|
"@aws-sdk/client-dynamodb": "^3.957.0",
|
|
"@aws-sdk/credential-providers": "^3.943.0",
|
|
"@extractus/article-extractor": "^8.0.18",
|
|
"@formatjs/intl-localematcher": "^0.9.0",
|
|
"@langfuse/client": "^4.4.9",
|
|
"@langfuse/otel": "^4.4.4",
|
|
"@langfuse/tracing": "^4.4.9",
|
|
"@next/third-parties": "^16.0.6",
|
|
"@openrouter/ai-sdk-provider": "^2.10.0",
|
|
"@opentelemetry/api": "^1.9.0",
|
|
"@opentelemetry/exporter-trace-otlp-http": "^0.222.0",
|
|
"@opentelemetry/sdk-trace-node": "^2.2.0",
|
|
"@radix-ui/react-alert-dialog": "^1.1.15",
|
|
"@radix-ui/react-collapsible": "^1.1.12",
|
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
"@radix-ui/react-label": "^2.1.8",
|
|
"@radix-ui/react-popover": "^1.1.15",
|
|
"@radix-ui/react-scroll-area": "^1.2.3",
|
|
"@radix-ui/react-select": "^2.2.6",
|
|
"@radix-ui/react-slot": "^1.2.4",
|
|
"@radix-ui/react-switch": "^1.2.6",
|
|
"@radix-ui/react-tooltip": "^1.1.8",
|
|
"ai": "^6.0.300",
|
|
"class-variance-authority": "^0.7.1",
|
|
"clsx": "^2.1.1",
|
|
"cmdk": "^1.1.1",
|
|
"idb": "^8.0.3",
|
|
"jsonrepair": "^3.13.1",
|
|
"lucide-react": "^0.577.0",
|
|
"nanoid": "^5.0.0",
|
|
"negotiator": "^1.0.0",
|
|
"next": "^16.0.7",
|
|
"ollama-ai-provider-v2": "^3.6.0",
|
|
"pako": "^2.1.0",
|
|
"prism-react-renderer": "^2.4.1",
|
|
"react": "^19.1.2",
|
|
"react-dom": "^19.1.2",
|
|
"react-markdown": "^10.1.0",
|
|
"saxes": "^6.0.0",
|
|
"server-only": "^0.0.1",
|
|
"sonner": "^2.0.7",
|
|
"tailwind-merge": "^3.0.2",
|
|
"tailwindcss-animate": "^1.0.7",
|
|
"turndown": "^7.2.0",
|
|
"unpdf": "^1.4.0",
|
|
"zod": "^4.1.12",
|
|
"zustand": "^5.0.15"
|
|
},
|
|
"optionalDependencies": {
|
|
"@tailwindcss/oxide-linux-x64-gnu": "^4.1.18",
|
|
"lightningcss": "^1.30.2",
|
|
"lightningcss-linux-x64-gnu": "^1.30.2"
|
|
},
|
|
"lint-staged": {
|
|
"*.{js,ts,jsx,tsx,json,css}": [
|
|
"biome check --write --no-errors-on-unmatched",
|
|
"biome check --no-errors-on-unmatched"
|
|
]
|
|
},
|
|
"devDependencies": {
|
|
"@biomejs/biome": "2.5.15",
|
|
"@opennextjs/cloudflare": "^1.17.1",
|
|
"@playwright/test": "^1.57.0",
|
|
"@tailwindcss/postcss": "^4",
|
|
"@tailwindcss/typography": "^0.5.19",
|
|
"@testing-library/dom": "^10.4.1",
|
|
"@testing-library/react": "^16.3.1",
|
|
"@types/negotiator": "^0.6.4",
|
|
"@types/node": "^24.0.0",
|
|
"@types/pako": "^2.0.3",
|
|
"@types/react": "^19",
|
|
"@types/react-dom": "^19",
|
|
"@types/turndown": "^5.0.6",
|
|
"@vitejs/plugin-react": "^5.1.2",
|
|
"cross-env": "^10.1.0",
|
|
"dotenv": "^16.6.1",
|
|
"electron": "^41.10.6",
|
|
"electron-builder": "^26.0.12",
|
|
"esbuild": "^0.28.0",
|
|
"husky": "^9.1.7",
|
|
"jsdom": "^27.4.0",
|
|
"lint-staged": "^16.2.7",
|
|
"postcss": "^8.5.6",
|
|
"tailwindcss": "^4",
|
|
"typescript": "^5",
|
|
"vite-tsconfig-paths": "^6.0.3",
|
|
"vitest": "^4.0.16",
|
|
"wrangler": "^4.60.0"
|
|
},
|
|
"overrides": {
|
|
"@openrouter/ai-sdk-provider": {
|
|
"ai": "^6.0.1"
|
|
}
|
|
}
|
|
}
|