You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Added docs/Venice_swagger_api.yaml and docs/venice_llm_info.md as the canonical API reference used for alignment work.
Changed
Refactored verify-dist to support both Windows and macOS file validations.
secureStore.ts strictly enforces macOS Keychain encryption exactly like Windows DPAPI.
Updated all supporting documentation to match the current app status and public release process.
CI workflow now uses npm ci --prefer-offline for slightly faster installs and reproducibility.
Windows release workflow now generates and uploads SHA-256 checksum sidecar files for .exe artifacts.
Updated metadata.json to describe Venice Forge instead of the previous empty/generated metadata.
readDesktopErrorBody (src/services/veniceClient.ts) and readResponseError (electron/services/veniceClient.ts) both now correctly parse Venice DetailedError (Zod format: { details: { _errors, fieldName: { _errors } } }) — previously fell through to "Unknown Venice API error" for all schema-validation failures.
Diagnostic dispatch deduplication: failed Venice requests now emit exactly one SET_DIAGNOSTICS entry with the resolved error message. Previously, each failure emitted two entries — an initial empty-error entry and a second entry with the error — causing duplicate rows in the Status log.
Web-mode diagnostics parity: non-2xx responses in the web transport now parse Venice DetailedError consistently and avoid catch-path duplicate diagnostics once an HTTP diagnostics entry has already been emitted.
Fixed
CI:.github/workflows/windows-release.yml referenced non-existent actions/checkout@v6 and actions/setup-node@v6. Downgraded to @v4 to match the latest published action versions and restore the release pipeline.
Test:src/services/desktopBridge.test.ts failed with ReferenceError: indexedDB is not defined because vi.stubGlobal("window", {}) stripped the fake-indexeddb instance from jsdom. The test now stubs window with { indexedDB: global.indexedDB } so the isConfigured() path can open the fake database.
BUG-003: Settings auto-save had no debounce — rapid changes could race and persist out-of-order state. Added a 500 ms debounce to the save effect.
BUG-004: IndexedDB init failure still marked dbReady=true, causing later writes to a broken database. Only sets dbReady/settingsHydrated on successful init.
BUG-005:SET_CHAT_DRAFT, SET_IMAGE_DRAFT, SET_BATCH_DRAFT reducers crashed on null/undefined patch. Added truthy guard before Object.assign.
BUG-006:dedupeKey threw unhandled TypeError on circular request bodies. Wrapped JSON.stringify in try/catch with "[circular]" fallback.
BUG-007: Import loops over stores sequentially with await inside for…of. Store writes are now parallelised via Promise.all.
BUG-008: Rate-limit reqCounts Map grew unbounded under multi-IP traffic. Added a 10,000-entry cap with FIFO eviction.
BUG-010: Raw console.error/console.warn calls left in production renderer and server paths (17 occurrences). Replaced with conditional shared logger (src/shared/logger.ts).
BUG-011:AbortSignal.any/AbortSignal.timeout may throw in older runtimes. Added createTimeoutSignal() helper with manual fallback.
BUG-013:veniceFetch deduplication map could leak promises on abrupt navigation. Added beforeunload listener that clears inFlight.
BUG-018:veniceFetchDesktop asserted method as "GET" | "POST" instead of narrowing. Method parameter now typed as "GET" | "POST".
BUG-019:veniceFetch<T = any> disabled TypeScript inference. Generic default changed from any to unknown.
BUG-022: Log rotation overwrote the single backup file. Implemented 3-file rotation ring (.1, .2, .3).
BUG-023:catch (err: any) used in 8+ production files — loose error typing masked safety. Replaced with catch (err) and runtime guards (err instanceof Error).
BUG-028:sleep ignored already-aborted signals, allowing stale timeouts to proceed. Now rejects immediately if signal.aborted before setting timeout.
BUG-029:modelService swallowed localStorage write failures silently. Empty catch now warns via shared logger.
BUG-030:byteLength used new Blob([value]).size — slow for large strings. Replaced with new TextEncoder().encode(value).length.
BUG-036:SettingsModuleProps used state: any, dispatch: any. Now typed with AppState and AppDispatch.
BUG-037:desktopUpdates callbacks typed as (info: unknown) / (progress: unknown). Now use UpdateInfo and ProgressInfo from electron-updater.
BUG-040:normalizeWebSearchSetting did not warn on invalid input. Now logs a warning when coercion happens.
BUG-042:isAllowedAppNavigation used path.normalize without symlink resolution. Added fs.realpathSync with try/catch for both target and root paths.
BUG-043:verify-dist-mac.cjs artifact name pattern did not match electron-builder default zip naming. Added zip.artifactName to electron-builder.config.cjs to align naming.
BUG-044:BatchDraft interface had wrong fields (prompts, model, systemPrompt instead of promptsText). Fixed type to match actual runtime state; removed inline cast in BatchModule.
BUG-045:cryptoService.keyPromise rejection was never cleared, causing permanent cache miss on any key-init failure. Added .catch handler to reset latch and allow retry.
BUG-046: IPC endpoint.search query string was forwarded without length cap, allowing pathological renderer inputs. Added 512-byte limit before building the return value.
BUG-047: Web-mode export URL.revokeObjectURL was called synchronously after a.click(), causing race where download failed before browser processed the blob. Deferred revocation by 1 second.
BUG-048: Circuit breaker circuitFailures counter never reset when circuitOpenUntil timeout expired. Half-open reset now clears both circuitFailures and circuitOpenUntil on recovery window re-entry.
BUG-049:setInterval for rate-limit map cleanup leaked on each createServerApp() call in tests. Stored interval ID and exposed cleanupIntervals() method on returned app object.
BUG-050:AppSettings.apiKey field declared in type but never written by SET_SETTINGS reducer, leading to misleading type surface. Removed unused field.
BUG-021:StorageService and cryptoService exposed any in public APIs (4 occurrences). Added EncryptedPayload and KeyRecord types; replaced any with proper generics in getOrCreateKey, encryptData<T>, decryptData<T>, and sort comparator.
BUG-020:appReducer and model helpers used any parameters and return types, causing 16+ ESLint warnings and masking type safety across the state layer. Replaced all any with narrow types: classifyModel(model: ModelInfo), flattenModels(payload: unknown), withFallbackModels(groups: Record<string, ModelInfo[]>), and explicit AppState interface. Broke the circular type dependency between appReducer.ts and types/app.ts by extracting AppState into a standalone interface. Added ChatHistoryItem type for stored chat records.
BUG-042 follow-up: Added electron/main.test.ts with 7 unit tests for symlink traversal blocking, path traversal, and containment checks. Extracted checkPathContained() into electron/utils/navigation.ts for testability without loading Electron APIs.
SEC-R001: Added 'unsafe-inline' to production script-src CSP to accommodate the inline theme bootstrap script in index.html.
SEC-R002: Added auditable logInfo entry when VENICE_FORGE_DEBUG_DEVTOOLS=true is detected in production.
THEME-R004: Added isValidTheme() validation in exportImport.ts to sanitize malformed custom themes to null on import. Fixed redactSecrets eagerly replacing tokens key inside theme objects. Added export/import round-trip tests for custom themes.
THEME-R006: Added prefers-contrast: more and prefers-contrast: less media query overrides in src/styles/accessibility.css.
REFACTOR-001: Extracted useThemeLifecycle, useNetworkStatus, and useSettingsPersistence hooks from App.tsx into src/hooks/. Reduced App.tsx from ~351 to ~290 lines.
REFACTOR-002: Unified all module and component props to use ModuleProps from src/types/app.ts. Eight files updated to use ModuleProps directly or extend it.
REFACTOR-003: Split src/index.css into src/styles/theme.css, src/styles/components.css, and src/styles/accessibility.css.
TEST-001: Added src/theme/applyTheme.test.ts with 10 tests for CSS variable assignment, theme mode attribute, and fallback resolution.
TEST-002: Added src/theme/contrast.test.ts with 10 tests for WCAG contrast ratios and isAAPass.
DOC-012:.env.example labeled VENICE_TIMEOUT_MS as "legacy fallback" but code still actively reads it. Updated comment to "Deprecated alias for VENICE_API_TIMEOUT_MS — still accepted as fallback".
BUG-004 (payload):enable_web_search was serialised as a boolean (true/false) instead of the required string enum ("auto" / "on" / "off"), causing HTTP 400 on every /chat/completions request. buildChatPayload now passes the string value directly (defaulting to "off").
BUG-005 (payload): Venice DetailedError responses (Zod validation failures) were not parsed — the error body contains a details object with _errors arrays and no top-level error field. Both the renderer and Electron main-process clients now extract the first _errors message or a field-level error when present.
BUG-006 (payload): Every failed Venice request produced two entries in the diagnostics log: one with error: "" from the initial HTTP dispatch, and a second with the actual message from the retry/catch path. The redundant dispatch has been removed; the initial entry now carries the fully resolved error.
BUG-007 (payload): Legacy persisted settings could still carry boolean webSearch values (true/false), which mapped to invalid API payloads and recurring 400 schema errors. Settings ingestion now coerces legacy values to on/off/auto, and chat payload construction enforces the same normalization.
BUG-008 (payload): Desktop /augment/text-parser uploads were unstable because veniceFetchDesktop serialized FormData but still sent the raw body over IPC. The request now correctly sends the serialized multipart payload, restoring reliable file-upload request construction.
Security
Explicitly disabled plaintext API-key fallback on macOS.
Documented web proxy forbidden-header stripping and proxy-root rejection.
Added Venice.ai TOS, privacy, and API documentation coverage for public releases.
[1.0.1] — 2026-05-20
Security
SEC-001: Added /augment/search, /augment/scrape, /augment/text-parser to the IPC and web-proxy endpoint allowlist. These endpoints were previously blocked, making the Research tab non-functional in both Electron and web modes.
SEC-002: Added safeHref() sanitization to search result anchor tags. Only http: and https: scheme URLs are allowed; javascript:, data:, and other schemes are replaced with # to prevent XSS.
SEC-003 (web proxy): Added security response headers — X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Referrer-Policy: no-referrer, and Content-Security-Policy — to all web-proxy responses.
Fixed
BUG-001:galleryFilename was called with a plain string instead of the item object in bulk gallery download, producing venice-undefined-undefined.png filenames for all downloads.
BUG-002: Import backup was constructed in memory but never written to disk before import records were applied, misleading the user with a "backup prepared" message.
BUG-003: Removed dead const endedAt = nowIso() variable captured before fetch() was called in veniceClient.ts.
Changed
upscaleGalleryImage now accepts a model parameter (default "upscale-model"); GalleryModule passes state.selectedImageModel so the currently selected model is used.
Express trust proxy is configurable through TRUST_PROXY; removed deprecated req.connection.remoteAddress fallback so rate limiting uses the correct client IP behind a configured reverse proxy.
Excluded vite.config.ts and test files from tsconfig.json; npm run typecheck now exits with zero errors.
Added
25 new tests across server.test.ts, src/utils/image.test.ts, src/utils/markdown.test.ts — total 41 tests (was 16). Coverage includes: augment endpoint validation, rate limiter enforcement, security header assertions, galleryFilename regression guard, normalizeImageData, extractImages, markdown XSS safety, and escapeHtml.