Commit Graph
100 Commits
Author SHA1 Message Date
Dayuan Jiang 73f282e568 feat: add Claude Code plugin package (#541)
Add separate plugin package for Claude Code plugin directory submission.

Structure:
- .claude-plugin/plugin.json - plugin metadata
- .mcp.json - MCP server configuration
- README.md - documentation with use case examples
2026-01-09 11:37:46 +09:00
Dayuan Jiang 085d656a3c chore: bump version to 0.4.10 (#540) 2026-01-09 10:41:35 +09:00
Dayuan Jiang d22474b541 feat: add proxy settings to Settings dialog (Desktop only) (#537)
* feat: add proxy settings to Settings dialog (Desktop only)

Fixes #535 - Desktop app now respects HTTP/HTTPS proxy configuration.

- Add proxy-manager.ts to handle proxy config storage (JSON file in userData)
- Load proxy settings on app startup before Next.js server starts
- Add IPC handlers for get-proxy and set-proxy
- Add proxy settings UI in Settings dialog (Electron only)
- Add translations for en/zh/ja

* fix: improve proxy settings reliability and simplify UI

- Fix server restart race condition (wait for process exit before starting new server)
- Add URL validation (must include http:// or https:// prefix)
- Enable Node.js built-in proxy support (NODE_USE_ENV_PROXY=1)
- Remove "Proxy Exceptions" field (unnecessary for this app)
- Add debug logging for proxy env vars

* refactor: remove duplicate ProxyConfig interface, import from electron.d.ts
2026-01-09 09:26:19 +09:00
Dayuan Jiang 083c2a4142 fix: specify artifact-configuration-slug for SignPath (#533) 2026-01-08 12:52:24 +09:00
Dayuan Jiang c4b1ec8d28 feat: add SignPath code signing for Windows builds (#531)
- Split workflow into mac/linux and windows jobs
- Add dist:win:build script with --publish never
- Integrate SignPath signing for Windows executables
- Sign both NSIS installer and portable EXE files
2026-01-08 10:51:12 +09:00
Dayuan Jiang 6ad4a9b303 chore(mcp-server): fix author and repository to DayuanJiang (#529) 2026-01-07 12:30:14 +09:00
Dayuan Jiang 79491e2143 chore: remove usage limits from about pages (#520) 2026-01-06 10:46:13 +09:00
Dayuan Jiang 625d8f2afe fix: use OpenAI provider for Doubao multimodal models (#519)
DeepSeek provider was not properly formatting image content for Doubao's
API. Now uses OpenAI provider for Doubao models (multimodal support),
while keeping DeepSeek provider for DeepSeek/Kimi models on the platform.
2026-01-05 23:09:09 +09:00
Dayuan Jiang 0026639ee8 fix: add NEXT_PUBLIC_BASE_PATH build arg for subdirectory deployment (#518)
Dockerfile was missing the ARG declaration to receive NEXT_PUBLIC_BASE_PATH
from docker-compose build args, causing subdirectory deployment to fail.

Fixes #478
2026-01-05 21:40:15 +09:00
Dayuan Jiangandgithub-actions[bot] c7a85d398f test: add Vitest and Playwright testing infrastructure (#512)
* test: add Vitest and Playwright testing infrastructure

- Add Vitest for unit tests (39 tests)
  - cached-responses.test.ts
  - ai-providers.test.ts
  - chat-helpers.test.ts
  - utils.test.ts
- Add Playwright for E2E tests (3 smoke tests)
  - Homepage load
  - Japanese locale
  - Settings dialog
- Add CI workflow (.github/workflows/test.yml)
- Add vitest.config.mts and playwright.config.ts
- Update .gitignore for test artifacts

* test: add more E2E tests for UI components

- Chat panel tests (interactive elements, iframe)
- Settings tests (dark mode, language, draw.io theme)
- Save dialog tests (buttons exist)
- History dialog tests
- Model config tests
- Keyboard interaction tests
- Upload area tests

Total: 15 E2E tests, all passing

* test: fix E2E test issues from review

Fixes based on Gemini and Codex review:
- Remove brittle nth(1) selector in keyboard tests
- Remove waitForTimeout(500) race condition
- Remove if(isVisible) silent skip patterns
- Add proper assertions instead of no-op checks
- Remove expect(count >= 0) that always passes
- Remove unused hasProviderUI variable

All 14 E2E tests and 39 unit tests pass.

* style: auto-format with Biome

* fix: resolve lint errors for CI

* test(e2e): add diagram generation tests with mocked AI responses

- Add tests for generate, edit, and append diagram operations
- Use SSE mocked responses matching AI SDK UI message stream format
- Generate mxCell XML directly in tests for deterministic assertions
- Tests verify tool card rendering and 'Complete' badge state

* test: add comprehensive E2E tests for all major features

- Error handling tests (API errors, rate limits, network timeout, truncated XML)
- Multi-turn conversation tests (sequential requests, history preservation)
- File upload tests (upload button, file preview, sending with message)
- Theme switching tests (dark mode toggle, persistence, system preference)
- Language switching tests (EN/JA/ZH, persistence, locale URLs)
- Iframe interaction tests (draw.io loading, toolbar, diagram rendering)
- Copy/paste tests (chat input, XML input, special characters)
- History restore tests (new chat, persistence, browser navigation)

* refactor: extract shared test helpers and improve error assertions

- Create tests/e2e/lib/helpers.ts with shared SSE mock functions
- Add proper error UI assertions to error-handling.spec.ts
- Remove waitForTimeout calls in favor of real assertions
- Update 6 test files to use shared helpers

* docs: add testing section to CONTRIBUTING.md

* fix: improve test infrastructure based on PR review

- Fix double build in CI: remove redundant build from playwright webServer
- Export chat helpers from shared module for proper unit testing
- Replace waitForTimeout with explicit waits in E2E tests
- Add data-testid attributes to settings and new chat buttons
- Add list reporter for CI to show failures in logs
- Add Playwright browser caching to speed up CI
- Add vitest coverage configuration
- Fix conditional test assertions to use test.skip() instead of silent pass
- Remove unused variables flagged by linter

* fix: improve E2E test assertions and remove silent skips

- Replace silent test.skip() with explicit conditional skips
- Add actual persistence assertion after page reload
- Use data-testid selector for new chat button test

* refactor: add shared fixtures and test.step() patterns

- Add tests/e2e/lib/fixtures.ts with shared test helpers
- Add tests/e2e/fixtures/diagrams.ts with XML test data
- Add expectBeforeAndAfterReload() helper for persistence tests
- Add test.step() for better test reporting in complex tests
- Consolidate mock helpers into fixtures module
- Reduce code duplication across 17 test files

* fix: make persistence tests more reliable

- Remove expectBeforeAndAfterReload from mocked API tests
- Add explicit test.step() for before/after reload checks
- Add retry config for flaky clipboard tests
- Add sleep after reload for language persistence test

* test: remove flaky XML paste test

* docs: run both unit and e2e tests before PR

* chore: add type check and unit test git hooks

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-05 01:37:32 +09:00
Dayuan Jiang 3ce047f794 chore: revert version to 0.4.9 (#509) 2026-01-04 15:32:42 +09:00
Dayuan Jiang 2c2d35940b chore: bump version to 0.4.10 (#508) 2026-01-04 15:29:17 +09:00
Dayuan Jiang 02366cabfb fix: remove draw.io native save button to prevent duplicate save dialogs (#507) 2026-01-04 15:22:46 +09:00
Dayuan Jiang 3e0c3bcb36 chore: bump version to 0.4.9 (#505) 2026-01-04 14:45:09 +09:00
Dayuan Jiang 2637da3215 fix: restore draw.io native save button functionality (#503)
PR #442 accidentally changed showSaveDialog from using the diagram
context to local state, breaking draw.io's native save button (Ctrl+S)
that was fixed in PR #296.

This restores the original behavior by using the context's showSaveDialog
so both draw.io native save and the download button open the same dialog.
2026-01-04 12:49:57 +09:00
Dayuan Jiang 24325c178f refactor: extract ToolCallCard and ChatLobby components (#502)
* refactor: extract ToolCallCard and ChatLobby components

- Extract ToolCallCard.tsx (279 lines) for tool call UI rendering
- Extract ChatLobby.tsx (272 lines) for empty state with session history
- Reduce chat-message-display.tsx from 1760 to 1307 lines (-26%)

* fix: address PR review feedback

- Remove redundant key prop in ToolCallCard
- Make onDeleteSession optional and conditionally render delete button
- Extract shared types (DiagramOperation, ToolPartLike) to types.ts
2026-01-04 12:04:06 +09:00
Dayuan Jiang 814f448cb0 fix: disable new chat button during streaming (#501) 2026-01-04 11:28:24 +09:00
Dayuan Jiang 4dc774d03f feat: add chat session history with IndexedDB persistence (#500)
* feat(session): add chat session history with IndexedDB storage

- Add session-storage.ts with IndexedDB wrapper using idb library
- Add use-session-manager.ts hook for session state management
- Add session-history-dropdown.tsx for session selection UI
- Integrate session system into chat-panel.tsx
- Auto-generate session titles from first user message
- Auto-save sessions on message completion
- Support session switching, deletion, and creation
- Migrate existing localStorage data to IndexedDB
- Add i18n translations for session history UI

* feat(session): improve history dropdown and persist diagram history

- Add time-based grouping (Today, Yesterday, This Week, Earlier)
- Add thumbnail previews using Next.js Image component
- Add staggered entrance animations with fade-in effects
- Improve active session indicator with left border accent
- Fix scrolling by using native overflow instead of ScrollArea
- Persist diagram version history to IndexedDB sessions
- Remove redundant diagram XML from localStorage
- Add i18n strings for time group labels (en, ja, zh)

* fix(session): prevent data loss on theme change and tab close

- Add isDrawioReady effect to restore diagram after DrawIO remount
- Add visibilitychange handler to save session when page becomes hidden
- Fix missing currentSessionId in saveCurrentSession dependency array
- Remove unused sanitizeMessages import from use-session-manager

* fix(session): fix diagram save and migration data loss bugs

- Add diagramHistory to save effect dependency array so diagram-only
  edits trigger saves (previously only message changes did)
- Destructure stable sessionManager values to prevent unnecessary
  effect re-runs on every render
- Add try-catch wrapper around debounced async save operation
- Make saveSession() return boolean to indicate success/failure
- Verify IndexedDB write succeeded before deleting localStorage data
  during migration (prevents data loss if write silently fails)
- Keep localStorage data for retry if migration fails instead of
  marking as complete anyway

* refactor(session): extract helpers to reduce code duplication

- Add syncUIWithSession helper to consolidate 4 duplicate UI sync blocks
- Add buildSessionData helper to consolidate 4 duplicate save logic blocks
- Remove unused saveTimeoutRef and its cleanup effect
- Net reduction of ~80 lines of duplicate code

* style(ui): improve history dropdown and delete dialog styling

- Change destructive color from coral to muted rose for refined look
- Make session history panel taller (400px fixed height)
- Fix popover alignment to prevent truncation
- Style delete button with soft red outline instead of solid fill
- Make delete dialog more compact (max-w-sm)

* fix(session): reset refs on new chat and show recent sessions

- Fix cached example diagrams not displaying after creating new session
- Reset previousXML, lastProcessedXmlRef and processedToolCalls when
  messages become empty (new chat or session switch)
- Add recent chats section in empty chat state with collapsible examples
- Pass sessions and onSelectSession to ChatMessageDisplay
- Add loadedMessageIdsRef to skip animations on session restore
- Add debug console.log for diagram processing flow

* feat(session): add search bar and improve history UI

- Remove session history dropdown, use main panel instead
- Add search bar to filter history chats by title
- Show minutes (Xm ago) instead of "Just now" for recent sessions
- Scroll to top when switching to new/empty chat
- Remove title truncation limit for better searchability
- Remove debug console.log statements

* refactor: remove redundant code and fix nested button hydration error

- Remove unused 'sessions' from deleteSession dependency array
- Remove unused 'switchedTo' variable and simplify return type
- Remove unused 'restoredMessageIdsRef' (always empty)
- Fix nested button hydration error by using div with role=button
- Simplify handleDeleteSession callback

* fix(session): fix migration bug, improve metadata perf, truncate titles

- Fix migration retry loop when localStorage has empty array
- Use cursor-based iteration for getAllSessionMetadata
- Truncate session titles to 100 chars with ellipsis

* refactor: remove dead code and extract diagram length constant

- Remove unused exports: getAllSessions, createNewSession, updateSessionTitle
- Remove write-only CURRENT_SESSION_KEY and all localStorage calls
- Remove dead messagesEndRef and unused scroll effect
- Extract magic number 300 to MIN_REAL_DIAGRAM_LENGTH constant
- Add isRealDiagram() helper function for semantic clarity
2026-01-04 10:25:19 +09:00
Dayuan Jiang bc22b7c315 fix(docker): fix invalid YAML syntax in docker-compose.yml (#498)
Empty environment mapping caused validation error:
'services.next-ai-draw-io.environment must be a mapping'
2026-01-03 14:20:43 +09:00
Dayuan Jiang 6fbc7b340f fix: move toast notifications to bottom-left (#489) 2026-01-01 22:08:05 +09:00
Dayuan Jiang 3c8f420c3c docs: add Cline MCP configuration instructions (#488) 2026-01-01 21:47:46 +09:00
Dayuan Jiang f240c494ac fix: use npm install instead of npm ci in electron workflow (#487) 2026-01-01 17:42:39 +09:00
Dayuan Jiang a22d7025a3 fix: sync package-lock.json (#486) 2026-01-01 17:32:25 +09:00
Dayuan Jiang 2159db5586 chore: bump version to 0.4.8 (#485) 2026-01-01 17:23:42 +09:00
Dayuan Jiang ada06260db fix: faster message restore and skip panel animation on refresh (#483)
* fix: faster message restore and skip panel animation on refresh

- Use useLayoutEffect for localStorage restore (runs before paint)
- Track visibility changes to only animate panel when toggling, not on page load
- Use cn() utility for cleaner conditional className

* fix: reset animation state after completion for re-animation support

* revert: remove unnecessary animation reset timer
2026-01-01 16:25:39 +09:00
Dayuan Jiang 02527526ba fix: prevent flash of example panel and animations on page refresh (#482)
- Add isRestored state to track when localStorage restoration completes
- Show example panel only after confirming no saved messages exist
- Skip message animations for restored messages
- Default tool calls and reasoning blocks to collapsed for restored messages
2026-01-01 15:42:48 +09:00
Dayuan Jiangandgithub-actions[bot] 77a2f6f6fa fix: hide Draw.io loading flash with placeholder (#481)
* fix: hide Draw.io loading flash with placeholder

* style: auto-format with Biome

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-01 15:20:00 +09:00
Dayuan Jiang 037f32973a fix: resolve biome lint errors blocking CI (#480)
- Update biome schema version from 2.3.8 to 2.3.10
- Add radix parameter to parseInt in mcp-server
- Remove unnecessary React fragment in model-config-dialog
- Fix unused variable errors (err -> _err)
- Auto-format code with biome
2026-01-01 14:45:46 +09:00
Dayuan Jiang 7bdc1fe612 fix(mcp-server): add graceful shutdown to prevent zombie processes (#477)
* fix(mcp-server): add graceful shutdown to prevent zombie processes

Add lifecycle handlers to properly exit the MCP server when the parent
application closes:

- Listen for stdin close/end events (primary method for all platforms)
- Handle SIGINT/SIGTERM signals
- Handle stdout broken pipe errors
- Export shutdown() function from http-server to clean up resources

* chore(mcp-server): bump version to 0.1.11
2025-12-31 18:38:20 +09:00
Dayuan Jiang 03ac9a79de fix: detect models that don't support image input and return clear error (#474)
Some models (Kimi K2, DeepSeek, Qwen text models) don't support image/vision
input. The AI SDK silently drops unsupported image parts, causing confusing
responses where the model acts as if no image was uploaded.

Added supportsImageInput() function to detect unsupported models by name,
and return a 400 error with clear guidance when users try to upload images
to these models.

Closes #469
2025-12-31 12:20:09 +09:00
Dayuan Jiang 69f9df1792 fix: improve image not supported error detection for DeepSeek (#468) 2025-12-31 00:12:19 +09:00
Dayuan Jiang aaa2938dac docs: reorganize documentation into i18n folder structure (#466)
* docs: reorganize docs into en/cn/ja folders

- Move documentation files into language-specific folders (en, cn, ja)
- Add Chinese and Japanese translations for all docs
- Extract Docker section from README to separate doc file
- Update README to link to new doc locations

* docs: fix links to new docs folder structure

* docs: update README and provider docs

* docs: fix broken import statements in cloudflare deploy guides

* docs: sync CN/JA READMEs with EN structure and fix all paths
2025-12-31 00:04:32 +09:00
Dayuan Jiang 1d19127855 chore: remove About link from header and language switcher from about pages (#464)
- Remove About link and sponsor notice icon from chat panel header
- Remove language switcher (English | 中文 | 日本語) from all about pages
- Fix About link in settings dialog to use current language
- Remove unused sponsorTooltip translation key from all dictionaries
2025-12-30 23:45:31 +09:00
Dayuan Jiang 2d62496f9f fix(edit_diagram): implement cascade delete for children and edges (#451)
* fix(edit_diagram): implement cascade delete for children and edges

- Add automatic cascade deletion when deleting a cell
- Recursively delete all child cells (parent attribute references)
- Delete all edges referencing deleted cells (source/target)
- Skip silently if cell already deleted (handles AI redundant ops)
- Update prompts to inform AI about cascade behavior

Fixes #450

* fix: add root cell protection and sync MCP server cascade delete

- Add protection for root cells '0' and '1' to prevent full diagram wipe
- Sync MCP server with main app's cascade delete logic
- Both lib/utils.ts and packages/mcp-server now have identical delete behavior

* chore(mcp): bump version to 0.1.9

* fix(cascade-delete): recursively collect edge children (labels)

- Change from cellsToDelete.add(edgeId) to collectDescendants(edgeId)
- Fixes orphaned edge labels causing draw.io to crash/clear canvas
- Edge labels (parent=edgeId) are now deleted with their parent edge
2025-12-30 00:03:30 +09:00
Dayuan Jiang c2aa7f49be fix(mcp): rename display_diagram to create_new_diagram (#449)
Rename tool to be less ambiguous and help AI models correctly
provide the required xml parameter on subsequent calls.

Closes #445
2025-12-29 15:15:13 +09:00
Dayuan Jiang 30b30550d9 chore: clean up root folder by relocating config files (#448)
* chore: clean up root folder by moving config files

- Move renovate.json to .github/renovate.json
- Move electron-builder.yml to electron/electron-builder.yml
- Move electron.d.ts to electron/electron.d.ts
- Delete proxy.ts (unused dead code)
- Update package.json dist scripts with --config flag
- Use tsconfig.json files array for electron.d.ts (bypasses exclude)

Reduces git-tracked root files from 23 to 19.

* chore: regenerate package-lock.json to fix CI

* fix: regenerate package-lock.json with cross-platform deps
2025-12-29 14:30:25 +09:00
Dayuan Jiang 27f26d8b26 feat: improve quota toast with ByteDance Doubao sponsorship info and model config button (#447)
- Add 'Use Your API Key' button to open model config dialog
- Add ByteDance Doubao sponsorship message with registration link
- Update quota limit messages to be warmer and friendlier
- Add dev panel button to test quota toast
- Update i18n translations for EN, ZH, JA
2025-12-29 12:12:22 +09:00
Dayuan Jiangandgithub-actions[bot] 6d1e12bb39 feat: add doubao provider and ByteDance sponsorship (#329)
* feat: add doubao provider and ByteDance sponsorship

- Add doubao provider using DeepSeek SDK with Volcengine base URL
- Add ByteDance Doubao sponsorship acknowledgment to about pages
- Update all README files (EN/CN/JA) with K2-thinking model info
- Update ai-providers.md with doubao configuration
- Keep both gateway and doubao providers after merge

* style: auto-format with Biome

* feat: add doubao and sglang to provider config panel

* fix: add doubao and sglang to validate-model API and logo maps

* docs: update ByteDance sponsorship note in all README versions

* docs: add Doubao logo to sponsorship note

* fix: use raw GitHub URL for Doubao logo in READMEs

* fix: separate link and image in sponsorship note

* fix: use PNG instead of SVG for Doubao logo

* fix: use current branch for PNG URL (will update to main after merge)

* docs: reorganize Deployment section and update image URLs to main

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-29 11:30:58 +09:00
Dayuan Jiang 6d84dade56 chore: add enhancement issue template (#434) 2025-12-27 18:16:38 +09:00
Dayuan Jiang 43f3fbb5ee Merge pull request #432 from DayuanJiang/renovate/aws-actions-configure-aws-credentials-5.x
chore(deps): update aws-actions/configure-aws-credentials action to v5
2025-12-27 14:52:41 +09:00
Dayuan Jiang 1915c817c3 Merge pull request #431 from DayuanJiang/renovate/actions-setup-node-6.x
chore(deps): update actions/setup-node action to v6
2025-12-27 14:52:18 +09:00
Dayuan Jiang eeab1ba75d Merge pull request #425 from vansh-nagar/fix/theme-based-logo
fix: switch logo file based on dark mode
2025-12-27 14:48:55 +09:00
Dayuan Jiang 9fa1dd075b Merge pull request #430 from DayuanJiang/renovate/actions-checkout-6.x
chore(deps): update actions/checkout action to v6
2025-12-27 14:17:03 +09:00
Dayuan Jiang 743b317387 Merge pull request #429 from DayuanJiang/renovate/minor-and-patch-dependencies
fix(deps): update minor and patch dependencies
2025-12-27 14:16:37 +09:00
Dayuan Jiang 9c1117e8b0 Merge pull request #427 from DayuanJiang/renovate/core-framework-packages
chore(deps): update core framework packages
2025-12-27 13:33:41 +09:00
Dayuan Jiang 39bf3d6a49 Merge pull request #428 from DayuanJiang/renovate/radix-ui-packages
chore(deps): update radix ui packages
2025-12-27 13:33:32 +09:00
Dayuan Jiang 18ab1bffa0 feat: migrate DynamoDB quota to composite key schema (#426)
- Change from single key (PK only) to composite key (PK + SK)
- PK = user ID, SK = date for per-day history tracking
- Remove two-step daily reset logic (SK handles day separation)
- Rename dailyReqCount/dailyTokenCount to reqCount/tokenCount
- Remove TTL (data never expires per user request)
- Simplify checkAndIncrementRequest to single atomic update
- Fix recordTokenUsage to handle new items explicitly

New table: next-ai-drawio-quota-v2
2025-12-27 10:24:43 +09:00
Dayuan Jiang 067d309927 fix: handle fork PRs in auto-format workflow (#419)
- Use head.sha instead of head_ref for checkout (works for forks)
- For fork PRs: fail with helpful message if formatting needed
- For same-repo PRs: auto-commit and push as before
2025-12-26 12:15:31 +09:00
Dayuan Jiangandgithub-actions[bot] d1d0de3dea chore: bump version to 0.4.7 (#416)
* chore: bump version to 0.4.7

* style: auto-format with Biome

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-25 22:30:48 +09:00
Dayuan Jiang 8c736cee0d fix: persist settings in Electron by using fixed port (#415)
- Use fixed port 61337 in production instead of random ports (10000-65535)
- localStorage is origin-specific, so random ports caused settings loss
- Add locale save/restore since language is URL-based
- Fixes #399
2025-12-25 22:20:59 +09:00
Dayuan Jiang c5a04c9e50 feat: move delete provider button to header area (#412) 2025-12-25 19:52:07 +09:00
Dayuan Jiang 44c453403f fix: reset test button to idle state when switching providers (#411)
- Button now shows 'Test' by default instead of persisting 'Verified' state
- Verified status is still shown via green badge in provider header
- Updated OpenAI suggested models list with latest GPT-5.x series
2025-12-25 19:39:15 +09:00
Dayuan Jiang 9727aa5b39 chore: add CI workflow and Renovate configuration (#406) 2025-12-25 15:36:40 +09:00
Dayuan Jiang 51858dbf5d Add deprecation notice to Electron settings panel (#403)
- Add warning banner to settings window HTML
- Add CSS styling for deprecation notice (light/dark mode)
- Direct users to use AI Model Configuration button in chat panel
2025-12-25 13:56:07 +09:00
Dayuan Jiang 3047d19238 fix: rename edit_diagram type field to operation for better model compatibility (#402)
Fixes #374 - Models were confused by the `type` field name and sent
`operation` instead. This change:

- Renames DiagramOperation.type to DiagramOperation.operation across
  all files (MCP server, web app, hooks, components, system prompts)
- Adds JSON examples in tool descriptions to show correct format
- Updates all test data to use the new field name

Affected files:
- lib/utils.ts
- app/api/chat/route.ts
- hooks/use-diagram-tool-handlers.ts
- components/chat-message-display.tsx
- lib/system-prompts.ts
- packages/mcp-server/src/diagram-operations.ts
- packages/mcp-server/src/index.ts
- scripts/test-diagram-operations.mjs

MCP server version bumped to 0.1.6
2025-12-25 13:19:04 +09:00
Dayuan Jiang ed069afdea fix: use full IP for userId to prevent quota collision (#400)
* fix: use full IP for userId to prevent quota collision

- Remove .slice(0, 8) from base64 encoded IP
- Each IP now has unique userId (no /16 collision)
- Affects: quota tracking, Langfuse tracing

* refactor: extract getUserIdFromRequest to shared utility

- Create lib/user-id.ts with shared function
- Fix misleading 'privacy' comment (base64 is not privacy)
- Remove duplicate code from chat and log-feedback routes
2025-12-25 12:20:46 +09:00
Dayuan Jiang 447bb30745 refactor: extract diagram tool handlers to dedicated hook (#389)
- Create useDiagramToolHandlers hook for display_diagram, edit_diagram, append_diagram
- Remove ~300 lines from chat-panel.tsx
- Remove unused stopRef
- Gate debug console.log statements with DEBUG constant
2025-12-24 12:28:59 +09:00
Dayuan Jiang 63398d9f34 fix: filter Langfuse traces to only export chat and AI SDK spans (#392)
Switch from blocklist to whitelist approach - only export spans named
'chat' or starting with 'ai.' to filter out Next.js infrastructure noise
(HEAD, fetch, POST requests).
2025-12-24 10:47:34 +09:00
Dayuan Jiang 82f4deb23a fix: quota daily reset bug and add timezone support (#390)
- Fixed bug where daily quota counts weren't resetting on new day
  (if_not_exists only works for missing attributes, not day changes)
- Changed to two-phase approach: reset if new day, then increment
- Added QUOTA_TIMEZONE env var for local midnight reset (e.g., Asia/Tokyo)
- Added timezone validation with UTC fallback
2025-12-24 10:34:54 +09:00
Dayuan Jiang 1fab261cd0 refactor: extract dev XML streaming simulator to separate component (#388)
- Move DEV_XML_PRESETS constants to new file
- Create DevXmlSimulator component with all simulator logic
- Add preset dropdown with 5 test cases including HTML escape test
- Set default interval to 1ms and chunk size to 10 chars
- Simplify chat-panel.tsx by removing ~130 lines of inline code
2025-12-24 09:52:50 +09:00
Dayuan Jiang 7a4a04c263 fix: remove unused partialXmlRef prop from ChatMessageDisplay (#387) 2025-12-24 09:37:32 +09:00
Dayuan Jiang 0d2e7a7ad6 fix: escape HTML in XML attribute values to prevent parse errors (#386)
- Add HTML escaping (<, >) in convertToLegalXml for attribute values
- Update isMxCellXmlComplete to handle any LLM provider's wrapper tags
- Add wrapper tag stripping in wrapWithMxFile for DeepSeek/Anthropic tags
- Update autoFixXml to escape both < and > in attribute values

Fixes 'Malformed XML detected in final output' error when AI generates
diagrams with HTML content in value attributes like <b>Title</b>.
2025-12-24 09:31:54 +09:00
Dayuan Jiang 3218ccc909 feat: add dev XML streaming simulator for UI debugging (#385) 2025-12-24 09:29:29 +09:00
Dayuan Jiang d3be96de79 refactor: redesign config panels with refined minimal aesthetic (#384)
- Add CSS design system tokens (surfaces, borders, animations) to globals.css
- Update dialog.tsx with rounded-2xl, shadow-dialog, refined close button
- Enhance input.tsx with rounded-xl and refined focus states
- Refactor settings-dialog with SettingItem pattern and consistent control sizing
- Refactor model-config-dialog with ConfigSection/ConfigCard helpers
- Replace emerald-* classes with success design tokens
- Remove unused ValidationButton component and scrollState
2025-12-23 21:52:04 +09:00
Dayuan Jiang b2dfd5b890 fix: display correct quota values in limit toast (#383)
- Parse JSON error response from server to get actual used/limit values
- Previously showed 0/0 due to race condition (config fetch vs error)
- AI SDK puts full response body in error.message for non-OK responses
- Updated all quota toasts (request, token, TPM) to use server values
2025-12-23 21:08:21 +09:00
Dayuan Jiang 72d647de7a fix: use Chat Completions API for OpenAI-compatible proxies (#382)
Third-party OpenAI-compatible proxies typically don't support the
/responses endpoint. Use .chat() for custom baseURLs while keeping
Responses API for official OpenAI to preserve reasoning model support.

Fixes #377
2025-12-23 20:29:48 +09:00
Dayuan Jiang c6b0e5ac62 fix: use totalUsage with all token types for accurate quota tracking (#381)
The onFinish callback's 'usage' only contains the final step's tokens,
which underreports usage for multi-step tool calls (like diagram generation).
Changed to 'totalUsage' which provides cumulative counts across all steps.

Include all 4 token types for accurate counting:
1. inputTokens - non-cached input tokens
2. outputTokens - generated output tokens
3. cachedInputTokens - tokens read from prompt cache
4. inputTokenDetails.cacheWriteTokens - tokens written to cache

Tested locally:
- Request 1 (cache write): 334 + 62 + 0 + 6671 = 7,067 tokens
- Request 2 (cache read): 334 + 184 + 6551 + 120 = 7,189 tokens
- DynamoDB total: 14,256 ✓
2025-12-23 20:19:28 +09:00
Dayuan Jiang 7de192e1fa fix: enable progressive diagram rendering during streaming (#380)
- Add extractCompleteMxCells() to extract only complete mxCell elements from partial XML
- Remove useEffect cleanup that was killing debounce timeouts on every re-render
- Wrap XML in <root> tags for proper DOMParser validation

Previously, diagrams only rendered after ALL XML finished streaming because:
1. useEffect cleanup cleared the 150ms debounce timeout on every message change
2. DOMParser rejected partial XML like '<mxCell id="2" value="...' (incomplete)

Now each complete mxCell renders progressively as it finishes streaming.
2025-12-23 18:54:03 +09:00
Dayuan Jiang 97ae9395cd feat: add server-side quota tracking with DynamoDB (#379)
- Add dynamo-quota-manager.ts for atomic quota checks using ConditionExpression
- Enforce daily request limit, daily token limit, and TPM limit
- Return 429 with quota details (type, used, limit) when exceeded
- Quota is opt-in: only enabled when DYNAMODB_QUOTA_TABLE env var is set
- Remove client-side quota enforcement (server is now source of truth)
- Simplify use-quota-manager.tsx to only display toasts
- Add @aws-sdk/client-dynamodb dependency
2025-12-23 18:36:27 +09:00
Dayuan Jiang 5ec05eb100 refactor: simplify Langfuse integration with AI SDK 6 (#375)
- Remove manual token attribute setting (AI SDK 6 telemetry auto-reports)
- Use totalTokens directly instead of inputTokens + outputTokens calculation
- Fix sessionId bug in log-save/log-feedback (prevents wrong trace attachment)
- Hash IP addresses for privacy instead of storing raw IPs
- Fix isLangfuseEnabled() to check both keys for consistency
2025-12-23 16:26:45 +09:00
Dayuan Jiang 9aec7eda79 fix: add continuation retry limit for truncated diagrams (#372)
Previously, continuation mode (for truncated XML) had unlimited client-side
retries, relying only on server stepCountIs(5) limit. This could cause
excessive API calls (495 observed) when XML truncation kept occurring.

Added MAX_CONTINUATION_RETRY_COUNT=2 to limit continuation attempts:
- After 2 failed continuation attempts, shows error toast and stops
- Resets on successful completion or user-initiated message
- Also resets when quota limits are hit
2025-12-23 14:17:06 +09:00
Dayuan Jiang a0fbc0ad33 fix: use last user message for Langfuse trace input (#371)
In multi-step tool flows, messages array contains assistant messages
from previous steps. Using messages[messages.length - 1] would record
the assistant's response as trace input instead of the user's question.
2025-12-23 13:43:28 +09:00
Dayuan Jiang 0385c45a10 fix: OpenAI reasoning/thinking blocks not showing (#370)
- Use Responses API instead of Chat Completions API for OpenAI
  (.chat() -> default call) to support reasoning events
- Add o4 to reasoning model detection
- Change default reasoningSummary from 'detailed' to 'auto'
  (not all models support 'detailed')
- Update types to match AI SDK: 'auto' | 'detailed'
2025-12-23 13:38:50 +09:00
Dayuan Jiang 5262b7bfb2 chore: upgrade AI SDK to v6.0.1 (#369)
- Upgrade ai package from ^5.0.89 to ^6.0.1
- Upgrade @ai-sdk/* provider packages to latest v3/v4
- Update convertToModelMessages call to async (new API)
- Fix usage.cachedInputTokens to usage.inputTokenDetails?.cacheReadTokens
2025-12-23 13:31:42 +09:00
Dayuan Jiang 8cb7494d16 feat(i18n): add translations for model configuration UI (#368)
- Add ~40 new translation keys for model-config-dialog and model-selector
- Support English, Chinese, and Japanese translations
- Replace all hardcoded strings with dictionary lookups
2025-12-23 11:42:27 +09:00
Dayuan Jiang 98625dd72a docs: update about page model info to Haiku 4.5 (#367) 2025-12-23 10:22:31 +09:00
Dayuan Jiang b5734aa5e1 chore: hide notice icon from header (#366) 2025-12-23 10:08:14 +09:00
Dayuan Jiang 87cdc53665 fix: improve Langfuse span filter to exclude all Next.js infrastructure traces (#365)
* debug: add log to verify instrumentation initialization

* fix: improve Langfuse span filter to exclude all Next.js infrastructure traces
2025-12-23 09:47:23 +09:00
Dayuan Jiangandgithub-actions[bot] b4fc259de8 chore: bump version to 0.4.6 (#364)
* chore: bump version to 0.4.6

* style: auto-format with Biome

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-23 09:09:39 +09:00
Dayuan Jiang 28f9a81e7b chore: add build-time arg for showing About and Notice (#360) 2025-12-23 01:06:42 +09:00
Dayuan Jiang 0f67884ead fix: include instrumentation.ts in standalone build for Langfuse (#359)
Add outputFileTracingIncludes to next.config.ts to ensure instrumentation.ts
is included in standalone builds (required for App Runner deployment)
2025-12-23 01:03:11 +09:00
Dayuan Jiang 3521495ead chore: conditionally show about and notice based on env var (#358) 2025-12-23 00:32:22 +09:00
Dayuan Jiang 6446454cd7 fix: add SSRF protection to validate-model endpoint (#357)
Block private IPs, localhost, cloud metadata endpoints (169.254.169.254),
and internal hostnames in custom baseUrl parameter to prevent server-side
request forgery attacks.
2025-12-23 00:26:01 +09:00
Dayuan Jiang 85cb441e26 feat: multi-provider model configuration with UI/UX improvements (#355)
* feat: add multi-provider model configuration

- Add model config dialog for managing multiple AI providers
- Support for OpenAI, Anthropic, Google, Azure, Bedrock, OpenRouter, DeepSeek, SiliconFlow, Ollama, and AI Gateway
- Add model selector dropdown in chat panel header
- Add API key validation endpoint
- Add custom model ID input with keyboard navigation
- Fix hover highlight in Command component
- Add suggested models for each provider including latest Claude 4.5 series
- Store configuration locally in browser

* feat: improve model config UI and move selector to chat input

- Move model selector from header to chat input (left of send button)
- Add per-model validation status (queued, running, valid, invalid)
- Filter model selector to only show verified models
- Add editable model IDs in config dialog
- Add custom model input field alongside suggested models dropdown
- Fix hover states on provider buttons and select triggers
- Update OpenAI suggested models with GPT-5 series
- Add alert-dialog component for delete confirmation

* refactor: revert shadcn component changes, apply hover fix at usage site

* feat: add AWS credentials support for Bedrock provider

- Add AWS Access Key ID, Secret Access Key, Region fields for Bedrock
- Show different credential fields based on provider type
- Update validation API to handle Bedrock with AWS credentials
- Add region selector with common AWS regions

* fix: reset Test button after validation completes

* fix: reset validation button to Test after success

* fix: complete bedrock support and UI/UX improvements

- Add bedrock to ALLOWED_CLIENT_PROVIDERS for client credentials
- Pass AWS credentials through full chain (headers → API → provider)
- Replace non-existent GPT-5 models with real ones (o1, o3-mini)
- Add accessibility: aria-labels, focus-visible rings, inline errors
- Add more AWS regions (Ohio, London, Paris, Mumbai, Seoul, São Paulo)
- Fix setTimeout cleanup with useRef on component unmount
- Fix TypeScript type consistency in getSelectedAIConfig fallback

* chore: remove unused code

- Remove unused setAccessCodeRequired state in chat-panel.tsx
- Remove unused getSelectedModel export in model-config.ts

* fix: UI/UX improvements for model configuration dialog

- Add gradient header styling with icon badge
- Change Configuration section icon from Key to Settings2
- Add duplicate model detection with warning banner and inline removal
- Filter out already-added models from suggestions dropdown
- Add type-to-confirm for deleting providers with 3+ models
- Enhance delete confirmation dialog with warning icon
- Improve model selector discoverability (show model name + chevron)
- Add truncation for long model names with title tooltip
- Remove AI provider settings from Settings dialog (now in Model Config)
- Extract ValidationButton into reusable component

* fix: prevent duplicate model IDs within same provider

- Block adding model if ID already exists in provider
- Block editing model ID to match existing model in provider

* fix: improve duplicate model ID notifications

- Add toast notification when trying to add duplicate model
- Allow free typing when editing model ID, validate on blur
- Show warning toast instead of blocking input

* fix: improve duplicate model validation UX in config dialog

- Add inline error display for duplicate model IDs
- Show red border on input when error exists
- Validate on blur with shake animation for edit errors
- Prevent saving empty model names
- Clear errors when user starts typing
- Simplify error styling (small red text, no heavy chips)
2025-12-22 22:36:36 +09:00
Dayuan Jiang b088a0653e chore: update app icons with new diagram hierarchy design (#350) 2025-12-22 13:24:08 +09:00
Dayuan Jiang b25b944600 fix(ci): simplify electron release - let electron-builder publish directly (#349) 2025-12-22 11:36:38 +09:00
Dayuan Jiang 4f07a5fafc fix: add write permissions to electron build jobs (#347) 2025-12-22 11:08:03 +09:00
Dayuan Jiangandgithub-actions[bot] fc5eca877a chore: bump version to 0.4.5 (#346)
* chore: bump version to 0.4.5 and add desktop app to README

* style: auto-format with Biome

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-22 10:39:28 +09:00
Dayuan Jiang e03b65328d chore(mcp): bump version to 0.1.5 (#343) 2025-12-21 19:44:01 +09:00
Dayuan Jiang 14c1aa8e1c fix(mcp): sync browser state before get_diagram to prevent data loss (#342)
* fix(mcp): sync browser state before get_diagram to prevent data loss

- Add syncRequested flag to SessionState for browser sync coordination
- Add requestSync() and waitForSync() functions to http-server
- Browser polls for syncRequested flag and immediately pushes current state
- get_diagram now syncs fresh state from browser before returning
- edit_diagram requires get_diagram to be called within 30s to prevent stale edits
- Updated edit_diagram description to enforce workflow

* fix(mcp): make lastGetDiagramTime session-scoped and handle missing session in requestSync

- Move lastGetDiagramTime into currentSession object to prevent cross-session issues
- requestSync now returns boolean indicating if request was made
- Only wait for sync if session exists (avoids false-positive from undefined state)
2025-12-21 19:38:35 +09:00
Dayuan Jiang 9e651a51e6 Merge pull request #341 from DayuanJiang/feat/mcp-history
feat(mcp): add diagram version history with SVG previews
2025-12-21 18:08:14 +09:00
Dayuan Jiangandgithub-actions[bot] 74b9e38114 chore: bump version to 0.4.4 (#338)
* chore: bump version to 0.4.4

* style: auto-format with Biome

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-21 01:01:59 +09:00
Dayuan Jiang 68ea4958b8 feat: display app version in Settings dialog (#337) 2025-12-21 00:55:54 +09:00
Dayuan Jiangandgithub-actions[bot] 938faff6b2 feat(mcp): add XML validation and auto-fix to MCP server (#336)
* feat(mcp): add XML validation and auto-fix to MCP server

- Add xml-validation.ts with validateAndFixXml function
- Integrate validation into display_diagram tool (fails if unfixable)
- Integrate validation into edit_diagram tool (auto-fix each operation)
- Fix bug: typo fixes now run before foreign tag removal
- Fix bug: use before/after comparison instead of regex .test()

* style: auto-format with Biome

* chore(mcp): bump version to 0.1.3

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-21 00:32:51 +09:00
Dayuan Jiangandgithub-actions[bot] f087b54ee4 feat: add get_shape_library tool for AI icon discovery (#335)
* feat: add get_shape_library tool for AI icon discovery

- Add server-side tool that returns shape library documentation
- AI can fetch icon/shape names on-demand before generating diagrams
- Includes path traversal protection and input sanitization
- Library index embedded in tool description for discoverability
- Supports 33 libraries: AWS, Azure, GCP, Kubernetes, Cisco, etc.

* fix: improve get_shape_library error handling and imports

- Move fs/path imports to top of file (avoid dynamic imports per call)
- Distinguish file-not-found vs other errors in catch block
- Include invalid input in validation error message
- Log unexpected errors for debugging

* docs: add get_shape_library to system prompt tool list

- Add Tool4 (get_shape_library) to available tools section
- Add usage guidance in 'Choose the right tool' section
- Update AWS icons note to reference get_shape_library for icon discovery

* fix: display get_shape_library tool output in chat UI

* fix: correct state check for get_shape_library output display

* fix: make get_shape_library output respect fold state

* style: auto-format with Biome

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-20 23:19:49 +09:00
Dayuan Jiang 6bb33eeda2 chore: add auto-format workflow and fix formatting (#319)
- Add GitHub Action to auto-format PRs with Biome
- Fix formatting in app/manifest.ts and scripts/test-diagram-operations.mjs
2025-12-18 23:03:08 +09:00
Dayuan Jiang f65ef548b2 fix: make draw.io built-in save button work with mouse tracking (#296)
- Add showSaveDialog state to DiagramContext for shared state
- Add mouse tracking to only respond to save events when mouse is over draw.io panel
- Prevents save dialog from opening when clicking Send in chat panel
- Add DialogDescription to SaveDialog for accessibility
2025-12-17 20:24:53 +09:00
Dayuan Jiang 741a00db89 Revert "fix: make draw.io built-in save button work (#293)" (#294)
This reverts commit bcc6684ecb.
2025-12-17 19:46:52 +09:00
Dayuan Jiang bcc6684ecb fix: make draw.io built-in save button work (#293)
- Lift showSaveDialog state to DiagramContext for sharing between components
- Add onSave handler to DrawIoEmbed that opens the save dialog
- Add guard (isSavingRef) with 1s delay to prevent repeated save events from draw.io
- Add deprecation notice to custom download button tooltip

Closes #93, Closes #290
2025-12-17 19:14:15 +09:00
Dayuan Jiang a9415d24e7 Revise preview feature stability note
Updated the preview feature note for stability.
2025-12-17 14:52:39 +09:00