Commit Graph
100 Commits
Author SHA1 Message Date
Dayuan Jiang 8bc9871829 ci: pin Biome to 2.4.13 in auto-format workflow (#869)
CI used npx @biomejs/biome@latest, which drifted to 2.5.0 and failed
the format job (deprecated config fields + stricter parsing of existing
files like public/resnet50.svg) on unrelated PRs. Pin to the version
already in package.json so CI matches local and pre-commit runs.
2026-06-15 00:44:55 +09:00
Dayuan Jiang 449e4c4e26 feat: add file-based admin settings panel at /admin (#866)
* feat: add file-based admin settings panel at /admin

Settings saved in the panel are written to data/settings.json and
overlaid onto process.env, taking precedence over environment
variables and applying immediately without restart. Enable by setting
ADMIN_PASSWORD; on serverless platforms without persistent disk the
panel degrades to read-only.

* polish: admin panel UI improvements

- Provider logos in credential rows (shared ProviderLogo component,
  extracted from model-config-dialog)
- Scroll-spy active state in the sidebar nav
- Green success state in the save bar that clears after a few seconds
- Wider content column (max-w-6xl) for less wasted space on desktop

* polish: admin panel section toggles and reorder

- Move Quota & Rate Limits to the end of the settings page
- Add enable switches to Observability and Quota sections; default off
  with fields grayed out, auto-on when any field is already configured

* polish: make section enable switch more visible

Wrap the switch in a labeled pill ('Enabled'/'Disabled') with border
and background so the off state is clearly visible.

* refactor: derive admin registry from PROVIDER_INFO, simplify page state

- Provider options, labels, and base-URL placeholders now come from
  PROVIDER_INFO instead of hand-copied lists (fixes SiliconFlow .com/.cn
  placeholder drift; panel names now match the model-config dialog)
- Replace free-text subgroup strings + SUBGROUP_PROVIDERS reverse map
  with a typed provider field on SettingDef
- Precompute SETTINGS_BY_GROUP and PROVIDER_SUBGROUPS at module level
- Merge justSaved into saveMessage, drop unused mainRef, hoist
  fetchSettings out of the component, dedupe savedText logic
- Serialize from SETTINGS_REGISTRY directly; json validators in a map
  instead of a hardcoded key check
- Make allowPrivateUrls a function so ALLOW_PRIVATE_URLS edits in the
  admin panel apply without restart

* feat: graphical model management in admin panel

Replace the provider credential fields and raw AI_MODELS_CONFIG JSON
textarea with a Models section mirroring the in-app model settings UI:
provider instance list with logos, credential fields per provider type,
model add/remove with suggestions, per-model connectivity test, and a
default-provider star.

On save the server derives everything the runtime needs into
settings.json: credential env vars (with _2 suffixes for multiple
instances of one provider), AI_MODELS_CONFIG, and AI_PROVIDER/AI_MODEL
for the default. Secrets round-trip as masked markers and are never
sent back to the browser. The general settings registry now only
covers non-provider settings (generation, access, features,
observability, quota).

* fix: allow testing unsaved providers in admin panel

The test button previously looked up credentials by providerId in the
saved settings, so testing a newly added (unsaved) provider failed with
'Unknown provider or model'. The test endpoint now accepts the client's
current provider state; newly typed secrets are used as-is and masked
markers are resolved against the stored values, so testing works both
before and after saving.

* fix: merge env AI_MODELS_CONFIG with admin panel providers

Previously, saving in the admin panel wrote a complete AI_MODELS_CONFIG
into settings.json, which (by overlay precedence) replaced any config
from .env or ai-models.json — admins lost their env-configured models.

The panel no longer writes AI_MODELS_CONFIG. Instead its providers are
merged with the env baseline at read time in loadRawServerModelsConfig,
and panel credentials go to ADMIN_-prefixed env vars wired up via
apiKeyEnv/baseUrlEnv so they never shadow standard vars. Env-based
providers now appear read-only in the panel, name clashes are rejected,
and a panel default overrides the env default. data/ is now gitignored.

* fix: block global-credential providers already managed via env

Bedrock, Vertex AI, and Ollama credentials live in fixed env vars with
no apiKeyEnv redirection, so a panel instance of one of these would
silently override the credentials that env-configured models rely on.
The API now rejects saving such a provider when the env config already
uses that type, and the Add Provider dropdown disables it with a
'managed via env' note.

* fix: address admin panel review findings

- Security: test-model no longer resolves a stored secret when the
  request's baseUrl/provider differs from the stored entry, closing a
  path where a tampered baseUrl could exfiltrate a saved key
- Save failures are now visible: the save bar shows the error in red
  (was masked by the persistent 'Unsaved changes' text), and per-field
  validation errors from the settings API are surfaced under each field
- The Observability/Quota enable switch is now real: toggling off stages
  deletion of the group's saved values, and the toggle no longer snaps
  back to Enabled after saving
- Env provider's default star is hidden when a panel provider is the
  active default (no more double star)
- Clearing a credential field reverts to the stored value instead of
  silently deleting it; an explicit X button removes a stored secret
- Form inputs are disabled during an in-flight save

* refactor(admin): split 1549-line admin page into focused modules

Extract admin-shared.ts (types + fetch helper), setting-field.tsx
(registry-driven fields), and models-section.tsx (provider/model
manager) from page.tsx. Pure mechanical move, no behavior change.

* feat(admin): share credential fields with user dialog and localize panel

Extract ProviderCredentialsFields (display name + per-provider
credential inputs) used by both the user ModelConfigDialog and the
admin Models panel; secret input passed via renderSecret (plaintext
vs masked), test button via footer slot. Add full i18n for the admin
panel across en/zh/ja/zh-Hant, reusing modelConfig.* for shared parts.

* fix(admin): address Copilot review findings

- Reflect built-in defaults for boolean settings (ALLOW_PRIVATE_URLS
  defaults on) and allow clearing a saved boolean back to default,
  so the SSRF toggle matches actual runtime behavior.
- Harden JSON loading: filter settings values to strings only, and
  schema-validate stored ADMIN_PROVIDERS entries, dropping malformed
  ones instead of letting them reach runtime code.
- Set beforeunload returnValue so the unsaved-changes prompt shows in
  all browsers; reject non-finite numbers in settings validation.
- Fix README/CN/JA docs that claimed the panel auto-generates
  AI_MODELS_CONFIG (providers are merged at read time, not written).
- Add unit tests for corrupted-file value filtering and provider
  schema validation.

* docs: move admin panel details to dedicated docs/{en,cn,ja}/admin-panel.md

The READMEs now carry a short blurb + link, matching the existing
per-topic docs (docker.md, ai-providers.md, ...). Removes the ~22-line
inline section and the duplicated data/settings.json mentions.

* fix(admin): address follow-up Copilot findings on the prior fixes

- loadAdminProviders now validates against a stored-shape schema where
  secrets are plain strings, so a hand-edited ADMIN_PROVIDERS holding an
  {isSet} marker is dropped instead of later crashing maskSecret().
- loadSettings guards against array values (typeof [] === 'object'),
  which would otherwise overlay numeric keys onto process.env.
- Admin SecretInput uses the bare id so the shared component's
  <Label htmlFor> stays associated (only one ProviderDetail mounts).
- Add tests: marker-secret rejection, array-values guard, bedrock
  multi-secret round-trip.
2026-06-15 00:40:35 +09:00
Dayuan Jiang 54ff8d982c chore: refresh SUGGESTED_MODELS for all providers (#863)
Updates the SUGGESTED_MODELS quick-add list in lib/types/model-config.ts
against each provider's official model docs as of 2026-06-09.

- openai: GPT-5.5 / 5.4 frontier; drop deprecated 5.0-5.2 family
- anthropic: add Opus 4.8/4.7/4.6, Sonnet 4.6, Haiku 4.5 (new dateless
  pinned IDs); fix wrong date suffixes on Opus/Sonnet 4.5
- google / vertexai: adopt Gemini 3 family; drop Gemini 2.0 (shut down)
  and 1.5
- azure: GPT-5.x line + o3 / o4-mini; drop gpt-4-turbo / gpt-35-turbo
- bedrock: Opus 4.8/4.7/4.6, Sonnet 4.6, Haiku 4.5, Nova Premier /
  Nova 2 Lite, Llama 4 Maverick / Scout, Mistral Large 3, Pixtral
- openrouter: refreshed against live /api/v1/models
- deepseek: V4 Pro / Flash
- siliconflow / modelscope: DeepSeek V4, Qwen 3.x, drop bogus
  qwen3.5-plus
- gateway: verified against live Vercel AI Gateway endpoint
- doubao: Seed 2.0 / 1.8 / 1.6 in official dash-form IDs
- minimax: + M2.5
- novita: M3, GLM-5.1, Kimi-K2.6, DeepSeek V4
2026-06-09 21:11:02 +09:00
Dayuan Jiang 77e7766f9a fix(deps): bump @ai-sdk/amazon-bedrock to 4.0.113 to fix tool streaming under Zod v4 (#860)
The installed 4.0.64 declared `input: z.unknown()` on BedrockToolUseSchema,
which Zod v4 treats as non-optional. With the
`fine-grained-tool-streaming-2025-05-14` beta enabled in lib/ai-providers.ts,
Bedrock's contentBlockStart event arrives without an `input` field, causing
type validation to fail with "expected nonoptional, received undefined".

4.0.101 fixed this upstream by marking input optional on the streaming
tool-use schema. The semver range `^4.0.1` already permitted this; only the
lockfile needed refreshing.

Closes #859
2026-06-06 00:15:45 +09:00
Dayuan Jiang 7b6eb39fa5 fix(parse-url): block SSRF via private/internal URLs (#845)
/api/parse-url accepted any URL the user submitted, fetched it via
@extractus/article-extractor, and returned the body as Markdown. With
ALLOW_PRIVATE_URLS unset (the default after #600) the SSRF guard
short-circuited entirely, so an unauthenticated POST could probe
container ports, read AWS IMDS / GCP metadata, and reach same-VPC
internal services.

- parse-url now always rejects private URLs regardless of
  ALLOW_PRIVATE_URLS. The flag's only legitimate use case is local
  LLM provider baseUrl overrides (validate-model, chat); article
  extraction has no business fetching internal hosts. Local LLM
  setups (Ollama, LM Studio, etc.) are unaffected.
- Strip a trailing dot from the hostname before equality checks so
  the FQDN form "localhost." (which still resolves to 127.0.0.1) is
  caught by the existing string match.

Known follow-ups (not addressed here):
- DNS rebinding: hostnames are matched as strings; a public domain
  resolving to 127.0.0.1 (e.g. localtest.me) is not caught.
- HTTP redirects: @extractus/article-extractor uses cross-fetch with
  default redirect: "follow" and exposes no hook, so a public URL
  302-ing to an internal host still leaks.
2026-05-21 23:54:23 +09:00
Dayuan Jiang 1115b2d2cd chore: bump version to 0.4.16 (#843) 2026-05-21 09:28:55 +09:00
Dayuan Jiang 2f2d75961d chore: remove dead code from previous #815 fix attempts (#841)
PR #840 fixed issue #815 in the Electron main process via
will-prevent-unload + preventDefault. The renderer-side workarounds
introduced by previous fix attempts (#642, #648) are no longer needed
and never had effect for their stated purpose.

Removed:
- configuration={ confirmExit: false } in DrawIoEmbed
  confirmExit is not a recognized draw.io config key (zero matches in
  jgraph/drawio source). This was always dead code.

- modified=0 / keepmodified=0 URL parameters
  Per drawio source (app.min.js:14898), these only suppress the
  post-save modified-flag clearing — they do not prevent edits from
  setting editor.modified=true. They were ineffective for blocking
  beforeunload prompts and actually prevented draw.io from clearing
  its modified flag after save.

- canPersist / canPersistChecked state and isIndexedDBUsable() probe
  Their only purpose was gating the dead config above. Removing them
  also removes a startup delay before the iframe renders.

- handleDrawioAutoSave wrapper
  After PR #780 stripped its body, it was a pure passthrough useCallback.
  Now passes handleDiagramAutoSave directly to onAutoSave.

- withDB / isClosingError / resetDBPromise / onversionchange / onclose
  / terminated handlers in lib/session-storage.ts and lib/template-storage.ts
  PR #648 added these to recover from 'IDBDatabase: connection is closing'
  errors that PR #642's first land caused via db.close() on the shared
  singleton. That bug was already fixed in c5de1a1 (re-land of #642),
  three minutes before PR #648 commits started. The retry handlers
  defend against multi-tab / version-change scenarios that cannot occur
  in this single-instance Electron app (requestSingleInstanceLock).
  template-storage.ts copied the same pattern when introduced by #773.

Verified:
- npx tsc --noEmit passes
- Manual test in dev mode: session save/load works, template create works,
  diagram-only persistence works.
2026-05-21 08:37:14 +09:00
Dayuan Jiang 5406778dd6 fix(electron): override draw.io iframe beforeunload to allow window close (fixes #815) (#840)
The draw.io iframe registers a window.onbeforeunload handler that returns
a non-empty string whenever its internal editor.modified flag is true.
After the user edits text in a shape, that flag is set and never cleared.

Per Electron BrowserWindow docs, returning a non-void value from any
beforeunload handler in the page tree silently cancels the window close
without showing a dialog. This is what caused the X button (and Cmd+Q)
to do nothing for users who had typed in a shape.

Calling event.preventDefault() in will-prevent-unload tells Electron to
ignore the iframe's beforeunload return value and proceed with the close.
The host app already persists diagrams via autosave + visibilitychange,
so the prompt was unnecessary.

Verified by reproducing the bug, applying the fix, and re-testing.
2026-05-20 23:33:05 +09:00
Dayuan Jiang f965f3fa2e chore: align biome schema version with CLI latest (#832)
Bumps biome.json $schema from 2.4.4 to 2.4.14 so the repo schema
matches the version the 'Auto Format' workflow installs via
@biomejs/biome@latest. Also applies the one auto-fix the newer
version produces (export ordering in electron/electron.d.ts).

Fixes the spurious 'This PR has formatting issues' CI failure that
was blocking fork PRs unrelated to formatting.
2026-05-07 22:43:37 +09:00
Dayuan Jiang d4454beb9a chore: bump version to 0.4.15 (#810) 2026-04-14 23:57:40 +09:00
Dayuan Jiang c77af86011 fix: improve create_new_diagram tool description to prevent misuse and bump to v0.2.0 (#803) 2026-04-10 17:18:24 +09:00
Dayuan Jiang 0cd1260172 fix: show all enabled panels on chat lobby instead of only templates (#802) 2026-04-10 14:33:56 +09:00
Dayuan Jiang ccd9c1f48e fix: reduce CPU usage during large XML streaming (#801)
* fix: reduce CPU usage during large XML streaming

Skip Prism syntax highlighting while tool call is streaming — use plain
<pre> during streaming and only run Prism once at completion. Also throttle
scrollIntoView to once per 150ms to avoid layout thrashing.

Profiled with Playwright + CDP: for 200-cell diagrams the longest
browser task dropped from 6.7s to ~450ms and total long-task time
fell from ~10.9s to ~1.1s.

* fix: add trailing edge to scroll throttle

Ensures the chat scrolls to the bottom after streaming ends, even if
the last messages update arrives during the 150ms throttle window.
2026-04-10 11:12:50 +09:00
Dayuan Jiang b9fdf9538c chore: remove MCP preview labels (#790)
MCP server is no longer in preview. Remove "(Preview)" headings from
READMEs, the purple PREVIEW badge from the UI, and the preview i18n keys.
2026-04-06 10:17:38 +09:00
Dayuan Jiang 1f31692701 chore: always bundle latest draw.io version in Electron builds (#792)
Remove pinned v29.3.5 tag so the build always clones the latest draw.io.
This adds the Animated GIF export and other new features to the Electron app.

Closes #770
2026-04-06 10:14:50 +09:00
Dayuan Jiang 31819f413c fix: add 10MB body size limit to MCP HTTP endpoints (#791)
All three POST handlers (/api/state, /api/restore, /api/history-svg)
now use a shared readBody() helper that enforces a 10MB limit and
returns 413 if exceeded, preventing memory exhaustion from oversized
requests.

Bumps @next-ai-drawio/mcp-server to 0.1.19.
2026-04-06 09:14:20 +09:00
Dayuan Jiang 41c410c2ba fix: bind MCP server HTTP to 127.0.0.1 only (#787)
The embedded HTTP sidecar was using server.listen(port) without a host
argument, which defaults to 0.0.0.0 (all interfaces). This exposed the
server to the local network. Now explicitly binds to 127.0.0.1.

Also excludes release/ from tsconfig to fix pre-existing TS errors.

Bumps @next-ai-drawio/mcp-server to 0.1.18.
2026-04-06 09:04:38 +09:00
Dayuan Jiang f593901fee fix: zoom reset on drag and IndexedDB version conflict (#776)
- Fix zoom resetting when dragging items (#775): removed useEffect that
  called load() on every autosave-triggered chartXML change, which reset
  the viewport. Moved diagram restore logic to onDrawioLoad where it
  only fires on remount.

- Fix IndexedDB VersionError: template-storage.ts shared the same DB
  name as session-storage.ts but at version 2, causing session storage
  to fail with "requested version (1) < existing version (2)". Give
  templates their own DB ("next-ai-drawio-templates").
2026-04-03 16:44:42 +09:00
Dayuan Jiang 29538782fc docs: add AI tools guidelines to CONTRIBUTING.md (#771) 2026-04-01 22:05:46 +09:00
Dayuan Jiang 0690f05399 chore: bump version to 0.4.14 (#764) 2026-03-30 21:36:51 +09:00
Dayuan Jiang f9c30d95b2 Merge pull request #709 from DayuanJiang/fix/electron-startup-port-issues
fix: resolve Electron startup failures on Windows and Linux
2026-03-30 20:00:45 +09:00
Dayuan Jiang 95e3e97b8b Merge pull request #758 from Alex-wuhu/novita-integration
feat: add Novita AI as LLM provider
2026-03-30 19:44:23 +09:00
Dayuan Jiang 16801f69b4 Merge pull request #743 from Biki-dev/some-ui-fixes
Fix: Keep settings dialog within the viewport and change the scrollbar property from hidden to thin
2026-03-30 19:29:06 +09:00
Dayuan Jiang 4f41cd1f01 Merge pull request #648 from DayuanJiang/fix/idb-closing-retry
fix: recover IDB closing + restore diagram-only sessions
2026-03-30 19:27:58 +09:00
Dayuan Jiang 67b0d77fa1 fix(mcp-server): restrict CORS to same-origin only (#757)
Replace wildcard `Access-Control-Allow-Origin: *` with same-origin check,
preventing external websites from accessing MCP server APIs via cross-origin requests.
2026-03-24 11:50:03 +09:00
Dayuan JiangandClaude Opus 4.6 9bf0c7f23f chore: remove security audit step from CI (#744)
The npm audit check was failing due to vulnerabilities in transitive
dependencies (e.g. wrangler), blocking unrelated PRs.

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-03-21 00:46:04 +09:00
Dayuan Jiang fd84aa70db chore: update volcengine referral URL and sponsor info (#736)
- Replace newyear-referral URL with new Coding Plan referral URL across all files
- Update model name from K2-thinking to glm-4.7
- Add volcengine invite poster to Chinese README and about page
2026-03-16 20:48:39 +09:00
Dayuan Jiang 8b0beb68c0 fix(electron): use explicit file sets for electron-builder 26.8 compatibility (#732)
Use explicit from/to/filter file sets instead of top-level globs to
avoid a regression in electron-builder 26.8.x where dist-electron
files were not being included in the asar archive.
2026-03-07 22:35:54 +09:00
Dayuan Jiang 7a6a933cf6 fix(electron): explicitly include package.json in asar for electron-builder 26.8 (#731)
electron-builder 26.8.x no longer auto-includes package.json when a
custom files array is specified, causing the main entry file to not be
found in the asar archive.
2026-03-07 21:37:56 +09:00
Dayuan Jiang 05bda50b2a chore: bump version to 0.4.13 (#730) 2026-03-07 19:14:16 +09:00
Dayuan Jiang e7453e86a6 feat: add custom system message setting for AI personalization (#728)
* feat: add custom system message setting for AI personalization

Allow users to enter custom instructions via a textarea in Settings
that get appended to the AI's system prompt. Includes server-side
validation (type check + 5000 char limit), localStorage persistence,
and i18n support for all 4 locales.

* fix: add accessibility htmlFor/id pairing on custom system message textarea
2026-03-07 19:07:54 +09:00
Dayuan Jiang ffac74b0ff docs: add guidelines for discussing significant changes and handling Copilot reviews (#714) 2026-02-28 00:41:34 +09:00
Dayuan Jiang 41dc0b2b42 feat: add Material Design Icons shape library (#688)
* feat: add Material Design Icons shape library (#685)

Add Google Material Design Icons as a new shape library using Google's
CDN. Includes top 300 most popular icons by usage, and updates system
prompts to guide the AI to call get_shape_library before using any icon
library.

* fix: align get_shape_library guidance for non-cloud icon libraries
2026-02-07 13:57:00 +09:00
Dayuan Jiang 3041dafe2f feat: add PNG/SVG export to MCP server (#687)
* feat: add PNG/SVG export support to MCP server export_diagram tool

Previously export_diagram only supported .drawio XML files. This adds
PNG and SVG export by leveraging the existing browser sync mechanism:
the MCP tool sets an exportFormat flag on the session state, the browser
detects it via polling and triggers an iframe export, then POSTs the
result back as exportData which the tool reads and writes to disk.

* fix: address PR review feedback for export feature

- Validate exportData is a string in POST /api/state
- Update lastUpdated in setExportFormat to prevent session expiry
- Gate export postMessage on isReady to avoid lost messages
- Remove unused fmt variable
- Fix double extension when path has a different supported extension

* fix: resolve high severity npm audit vulnerabilities

Run npm audit fix to update @aws-sdk and @smithy transitive dependencies
that had high severity advisories, which was failing the CI security audit step.

* fix: address second round of PR review feedback

- Add 8s timeout for pendingMcpExport to prevent permanent blocking
- Move export trigger after version update in poll() to export latest diagram
- Return 404 when session not found for exportData POST
- Sync browser state before .drawio export to avoid stale XML
- Handle URL-encoded SVG data URIs in addition to base64

* fix: address third round of PR review feedback

- Sync browser state before PNG/SVG export (not just drawio)
- Add 10MB body size limit on POST /api/state
- Validate export response format matches request to prevent race conditions

* refactor: remove over-engineered defensive code from export feature

Strip unnecessary validation/guards added from Copilot review that
don't make sense for a localhost-only MCP server: body size limit,
type validation, 404 for missing session, lastUpdated refresh,
URL-encoded SVG handling. Also deduplicate requestSync call.

* refactor: keep original drawio export path unchanged

Don't restructure the existing drawio logic - just add png/svg
as a separate branch after it.

* refactor: remove redundant helper functions, inline state access

Remove setExportFormat/getExportData/clearExportData wrappers that
were each called once. Access state fields directly via getState().

* chore: bump mcp-server version to 0.1.16
2026-02-07 12:55:09 +09:00
Dayuan Jiang cd33e131ef feat: add API key load balancing for providers (#676)
Support multiple API keys per provider with random selection for load
balancing. When AI_MODELS_CONFIG has multiple apiKeyEnv values for
a provider, requests will randomly select one available key.

- Update schema to accept apiKeyEnv as string or string array
- Add random key selection in resolveApiKey()
- Update validation to check at least one key exists
- Add tests for array format support
2026-02-02 15:54:35 +09:00
Dayuan Jiang 4624ad40a1 fix: enable image support for Kimi K2.5 model (#670)
* fix: enable image support for Kimi K2.5 model

Kimi K2.5 supports image input but was incorrectly blocked by the
supportsImageInput check that excluded all Kimi models without
"vision" in the name. Updated the condition to only exclude the
older K2 model while allowing K2.5.

* fix: improve Kimi K2.5 image support logic and add tests

- Only block kimi-k2 specifically, not all Kimi models
- Add unit test for kimi-k2.5 image support
2026-02-02 00:14:27 +09:00
Dayuan Jiang b84b156c8c chore: update Volcengine referral link to new year campaign (#666)
Update the Volcengine referral URL from console.volcengine.com to the
new year referral campaign URL across all documentation and code files.
2026-01-30 14:05:16 +09:00
Dayuan Jiang c6eab07622 Merge pull request #660 from broBinChen/feat/add-stop-generation-button
feat: add stop button to cancel AI generation
2026-01-30 11:22:53 +09:00
Dayuan Jiang b2b9614404 Merge pull request #657 from shibamudi/fix/path-handling-with-basepath
Fix: path handling with basepath
2026-01-30 00:42:25 +09:00
Dayuan Jiang 31fffcc52d Merge pull request #664 from DayuanJiang/fix/ollama-client-base-url
Supports client-provided base URL for Ollama
2026-01-29 21:57:05 +09:00
Dayuan Jiang 0a03ac9f45 Merge pull request #663 from DayuanJiang/fix/ollama-allowed-client-provider
Adds Ollama to allowed client providers list
2026-01-29 21:57:00 +09:00
Dayuan Jiang 6dad6ab147 Merge pull request #662 from DayuanJiang/fix/ollama-ssrf-exception
Adds Ollama to SSRF protection exception list
2026-01-29 21:56:54 +09:00
Dayuan Jiang cb0c0fbcda Revert "fix(electron): prevent beforeunload prompt by using autosave (#642)" (#646)
This reverts commit e7c29fb410.

The PR introduced an IndexedDB error: 'Failed to execute transaction on IDBDatabase: The database connection is closing.'
2026-01-27 09:20:42 +09:00
Dayuan Jiang e7c29fb410 fix(electron): prevent beforeunload prompt by using autosave (#642)
* fix(electron): prevent beforeunload prompt by using autosave

- Enable draw.io autosave and handle autosave events to update chartXML
- Clear modified state after autosave to avoid beforeunload prompts
- Disable confirmExit in draw.io configuration
- Set modified=false and keepmodified=false URL parameters
- Fix session save condition to also save when only diagram exists

* fix: persist diagram-only saves and ref typing

* fix: harden persistence checks and export timeout
2026-01-26 22:04:41 +09:00
Dayuan Jiang 7656b64018 chore: switch to release signing policy for Windows builds (#639) 2026-01-24 20:47:44 +09:00
Dayuan Jiang c3f88e54fe chore: bump version to 0.4.12 (#638) 2026-01-24 19:25:47 +09:00
Dayuan Jiang a55ef7adf9 feat(electron): bundle draw.io for offline support (#629)
* feat(electron): bundle draw.io for offline support

- Download draw.io static files during CI build (v29.3.5)
- Detect Electron and use local draw.io files instead of CDN
- Add offline=1 parameter to disable external service calls
- Skip /drawio path from i18n middleware redirect
- Add public/drawio/ to .gitignore (downloaded during build)

This allows the Electron app to work completely offline.

* chore: bump version to 0.4.12-beta.3 for offline test

* fix(electron): ad-hoc sign macOS app for bundled draw.io compatibility

* chore: bump version to 0.4.12-beta.4 for ad-hoc sign test

* fix(electron): disable electron-builder signing to use custom ad-hoc signing

* chore: bump version to 0.4.12-beta.5
2026-01-24 12:47:51 +09:00
Dayuan Jiang 984eaae04d feat(mcp): update UI with project logo and modern dialog styles (#636)
* feat(mcp): update UI with project logo and modern dialog styles

- Replace Next.js logo with project favicon-white.svg
- Modernize modal dialogs with backdrop blur, animations, and DM Sans font
- Update button styles to match header design
- Change title to "Next AI Draw.io"
- Rename "Save" to "Download" for clarity
- Bump version to 0.1.15

* chore: remove dead code (unused download helpers and pendingManualSave)
2026-01-24 12:43:39 +09:00
Dayuan Jiang 0ed06360aa fix(mcp): auto-redirect to active session when no sessionId provided (#634)
Fixes #633 - browser showing infinite loading spinner when accessing
the MCP server URL without the session parameter.

When users access http://localhost:6002 directly (without ?mcp=xxx),
the page now auto-redirects to the most recent active session instead
of showing "No session" with an infinite loading spinner.
2026-01-24 11:03:58 +09:00
Dayuan Jiang dc37ce7fb1 fix: upgrade wrangler to ^4.60.0 to address CVE-2026-0933 (#628)
Upgrade wrangler from 4.58.0 to ^4.60.0 to fix the command injection
vulnerability (CWE-78) in the --commit-hash parameter of wrangler pages
deploy command.

Fixes #627
2026-01-23 08:38:07 +09:00
Dayuan Jiangandgithub-actions[bot] b386dc45e6 fix(quota): bypass quota for users with Bedrock credentials (#621)
* fix(quota): bypass quota for users with Bedrock credentials

The hasOwnApiKey check only looked for x-ai-api-key header, but Bedrock
users provide AWS credentials via x-aws-access-key-id instead. This
caused Bedrock users with their own credentials to still be subject to
quota limits.

* fix(quota): also bypass quota for Vertex AI users

* style: auto-format with Biome

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-20 20:27:31 +09:00
Dayuan Jiang 89a0e6d475 fix(electron): properly dereference symlinks by copying actual content (#610)
cpSync with dereference:true does NOT convert symlinks to files.
This implements a custom copyDereferenced function that:
- Detects symlinks using lstatSync
- Follows them using statSync
- Copies actual file/directory content instead of symlink

Fixes macOS arm64 codesign failure with electron-builder 26.4.0
which now does ad-hoc signing and runs codesign --verify.
2026-01-18 19:57:38 +09:00
Dayuan Jiangandgithub-actions[bot] 56df2678bf fix(electron): dereference symlinks when copying to prevent codesign failures (#609)
* fix(electron): dereference symlinks when copying to prevent codesign failures

* style: auto-format with Biome

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-18 19:24:51 +09:00
Dayuan Jiang c9e0841583 chore: bump version to 0.4.11 (#607) 2026-01-18 17:03:54 +09:00
Dayuan Jiang 552a2b2ab4 Merge pull request #586 from Biki-dev/fix-inputFocus
Set focus to input area after clicking Start Fresh Chat
2026-01-18 10:43:07 +09:00
Dayuan Jiang 629ba16e7c Merge pull request #596 from Biki-dev/feat-i18n-electron
[Enhancement] Add i18n support for Electron menu
2026-01-18 10:25:10 +09:00
Dayuan Jiang 4ace31d412 fix: allow private URLs by default for reverse proxy setups (#600)
* fix: allow private URLs by default for reverse proxy setups

Fixes #588 - Users with reverse proxy setups (e.g., Antigravity tools)
were getting "Invalid base URL" errors due to SSRF protection blocking
private/internal URLs.

Changes:
- Add ALLOW_PRIVATE_URLS env var (defaults to true)
- Set to "false" to enable strict SSRF protection if needed

* refactor: extract isPrivateUrl to shared utility
2026-01-17 23:14:53 +09:00
Dayuan Jiang 5007c7bbe4 fix(mcp): allow edit_diagram immediately after create_new_diagram (#595)
After create_new_diagram, edit_diagram would fail with "You must call
get_diagram first" because lastGetDiagramTime was never set (remained 0
from session init). This fix sets lastGetDiagramTime after creating a
diagram, allowing immediate edits.

Fixes #534, Fixes #589
2026-01-16 21:45:46 +09:00
Dayuan Jiang b128c57e94 Merge pull request #574 from ElshadHu/feat/gcp-vertex-ai
Feat/gcp vertex ai
2026-01-15 23:11:27 +09:00
Dayuan Jiang 6bd26c8bbd Merge pull request #578 from DayuanJiang/fix/user-apikey-baseurl-isolation
fix: prevent user API keys from using server's baseURL
2026-01-13 22:26:12 +09:00
Dayuan Jiang 0d79487b6c Merge pull request #573 from danqzq/enhance/remove-close-protection
enhance: remove close protection
2026-01-11 18:09:58 +09:00
Dayuan Jiang 651238529a Merge pull request #570 from DayuanJiang/chore/add-opencode-to-gitignore
chore: add opencode.json to gitignore
2026-01-11 11:05:45 +09:00
Dayuan Jiang 5eb797b191 chore: reduce Renovate noise - monthly schedule, group major updates (#569) 2026-01-10 23:31:01 +09:00
Dayuan Jiang 518b72a0be Merge pull request #562 from DayuanJiang/renovate/core-framework-packages
chore(deps): update core framework packages
2026-01-10 19:28:50 +09:00
Dayuan Jiang 5e503551e6 Merge pull request #563 from DayuanJiang/renovate/major-github-artifact-actions
chore(deps): update actions/upload-artifact action to v6
2026-01-10 19:28:34 +09:00
Dayuan Jiang 7bdb43cd20 Merge pull request #558 from DayuanJiang/renovate/actions-checkout-6.x
chore(deps): update actions/checkout action to v6
2026-01-10 14:42:33 +09:00
Dayuan Jiang 3d816442f6 Merge pull request #559 from DayuanJiang/renovate/actions-setup-node-6.x
chore(deps): update actions/setup-node action to v6
2026-01-10 14:42:26 +09:00
Dayuan Jiang f59a2f2b01 Merge pull request #556 from DayuanJiang/renovate/minor-and-patch-dependencies
fix(deps): update minor and patch dependencies
2026-01-10 14:40:03 +09:00
Dayuan Jiang 17b765bfd9 Merge pull request #552 from DayuanJiang/renovate/core-framework-packages
fix(deps): update core framework packages
2026-01-10 14:39:59 +09:00
Dayuan Jiang 945dffc949 Merge pull request #441 from DayuanJiang/renovate/zod-4.x
fix(deps): update dependency zod to v4
2026-01-10 14:36:20 +09:00
Dayuan Jiang 0b41084c24 Merge pull request #553 from DayuanJiang/renovate/electron-packages
chore(deps): update dependency electron-builder to v26.4.0
2026-01-10 14:36:09 +09:00
Dayuan Jiang 860eabd593 Merge pull request #557 from DayuanJiang/renovate/actions-cache-5.x
chore(deps): update actions/cache action to v5
2026-01-10 14:36:02 +09:00
Dayuan Jiang 4a0973a373 chore: remove dead code and consolidate duplicate types (#555)
- Delete unused files: lib/ai-config.ts, components/ui/card.tsx, lib/token-counter.ts
- Remove js-tiktoken dependency (only used by deleted token-counter.ts)
- Consolidate ProviderName type: add "ollama" to model-config.ts, import in ai-providers.ts
- Consolidate DiagramOperation type: keep in chat/types.ts, import in utils.ts and hook
2026-01-10 14:06:17 +09:00
Dayuan Jiang 9430618660 docs: fix FAQ formatting and update model recommendations (#546)
- Add missing "Problem" statement to FAQ #4 for consistency
- Update vision model recommendations to latest versions (GPT-5.2, Claude 4.5 Sonnet, Gemini 3 Pro)
2026-01-09 13:43:26 +09:00
Dayuan Jiang d71fe70cbe docs: add FAQ documentation for common issues (#544)
- Add FAQ.md in English, Chinese, and Japanese
- Link FAQ from each language README
- Cover: PDF export, offline deployment, self-hosted models, image upload
2026-01-09 13:30:07 +09:00
Dayuan Jiang 22f4c2e270 fix: update SiliconFlow default endpoint to .cn (#543)
SiliconFlow is transitioning from .com to .cn domain. The .cn endpoint
uses Global Traffic Manager (GTM) for better global access, while .com
is being phased out.
2026-01-09 13:21:34 +09:00
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