chore(release): v1.8.1#266
Merged
Merged
Conversation
Introduces image validation and resizing for MCP tool outputs with per-provider limits, plus a shared tool output sanitizer to normalize results across legacy and mcp-use services. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Introduce 'background' visual status for tool calls running as async tasks, with a new Activity icon and shared deriveToolCallVisualStatus helper. - Strip ANSI escape sequences in sanitizeBinaryOutput so shell tool output renders cleanly. - Rebuild web preview tabs from running tasks when push events are missed. - Add unit tests for shell sanitization and tool-call status derivation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Restores the gate removed in the WIP commit so the BreathingLogo only appears next to the running todo item, not duplicated below the list. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
feat(local): optional API key for private local/OpenAI-compatible endpoints
Simplify the sidebar file browser header by removing the show/hide hidden files toggle, manual refresh and inline add-files icon. Hidden files are always shown, and a single "Add files" button next to the root label opens a modal with a drop zone plus native file picker via webUtils.getPathForFile. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Introduce CanonicalToolResultV1 as the single storage format for MCP tool outputs. Image payloads are persisted on disk under userData/tool-result-assets/images keyed by SHA-256, with the DB only holding lightweight image-ref entries. Historical replay rebuilds the model payload via tool.toModelOutput, keeping base64 out of the sanitized message pipeline and compaction summaries. Assets are reference-counted and cleaned up on session delete, message update, and deleteMessagesAfter. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… 7 code quality fixes
Issue 1 — toolMessageSanitizer: strip uiResources/images from legacy branch;
fall back to '[Widget rendered]' when no recognized fields remain.
Issue 2 — chatService.mapMessageRow: normalize tool_calls in memory only,
remove rewriteNormalizedToolCalls (no UPDATE on reads).
Issue 3 — aiService: guard logContextDiagnostics behind isEnabled('ai-sdk','debug');
downgrade from info→debug; extract to contextDiagnostics.ts to avoid heavy
import chain in tests.
Issue 4 — toolResultAssetStore: JSDoc on isAssetReferenced explaining LIKE scan safety.
Issue 5 — docs/HANDOFF: strip 29 absolute /Users/saulgomezjimenez/... paths.
Issue 6 — move getImageDimensions to imageResizer.ts; remove sharp import from
toolResultAssetStore.
Issue 7 — miniChatWindow: extract mapPartsToPersistedToolCalls helper; fix shape
bug where AI SDK parts were saved as-is instead of mapped to PersistedToolCall.
Option A — historicalToolReplayTools: HISTORICAL_IMAGE_BUDGET=2; pre-scan counts
image-bearing results, oldest beyond budget are degraded to text via
supportsVision:false, keeping O(1) images per turn instead of O(turns).
Option B — canonicalToolResultService: MAX_TOOL_TEXT_CHARS=30_000; truncate at
materialize time (not storage), covering all text paths in canonical and legacy
outputs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sidebar fetched a global top-50 via db.sessions.list and then filtered
by project_id on the client, so projects whose chats fell outside that
window appeared with only a subset. Replace that path with a scope-aware
fetch: when selectedProject is set, load via projects.getSessions (no
LIMIT), matching ProjectPage 1:1.
- chatStore: add refreshProjectSessions(projectId); make global list
limit explicit ({ limit: 100, offset: 0 }); remove initializeChatStore
- App: effect reacts to selectedProject?.id and calls the correct
refresh, replacing the mount-time initializeChatStore call
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
`resolveModelTarget` already covers qualified and legacy raw refs in standalone, platform pure, and platform hybrid modes. The manual catch that re-scanned `preferencesService.providers` duplicated that logic and silently masked real errors (corrupted refs, deleted providers). Keep a single `try + warn + return undefined` so the only caller still receives `undefined` on failure, and drop the dynamic preferencesService import from the hot path. Refs: #231 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Move the unified `SelectableModelsResult` out of `useModelSelection` local state into a new `catalogStore`, shared across all consumers: - `catalogStore.ensureLoaded(params)` caches by (appMode, useOtherProviders, platformModels fingerprint), dedupes concurrent loads via `_inflight`, and only commits results when the cache key still matches at resolution time. - `catalogStore.invalidate(reason)` clears the cache and auto-reloads with the last known params so subscribers refresh without needing to re-pass them. - `useModelSelection` now subscribes to the store and derives `availableModels` / `groupedModelsByProvider` with `useMemo`; local `useState` + load effect removed. `handleModelChange` invalidates after `modelService.setActiveProvider` instead of setting two local arrays. - `modelStore` invalidates on every provider mutation (initialize, setActiveProvider, updateProvider, syncProviderModels, toggle/set model selections, add/remove user model). - `platformStore` invalidates after `ensureModelsLoaded` completes, on logout, on `setStandaloneMode`, on session-invalidated `refreshStatus`, and on unauthenticated/standalone init. Fast navigation between chat and settings, or between sessions, no longer recomputes the catalog; the loading flicker and race between overlapping loads go away. Refs: #231 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
`path-browserify` is POSIX-only, so Windows paths with backslashes were breaking `findNearestLoadedAncestor`, `pruneEntriesSubtree`, and the drop/mention handlers in `PromptInputEditor`. Introduce a shared `toPosixPath` helper and apply it before any `path.*` call; the original path strings are preserved for keys and UI to avoid leaking POSIX-style separators back into Windows state. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Ensures Cowork mode always has a POSIX shell and Python available. On
the first Cowork-mode stream of the process, ensureCoworkPrerequisites
runs once and provisions:
- Windows: Git Bash on PATH → Levante-managed PortableGit 2.47.0.2
downloaded from git-for-windows and extracted to
~/levante/runtimes/gitbash/<version>/.
- All platforms: Python 3.13 via python-build-standalone (needed by
skill-creator and Python-based MCP servers).
Progress is broadcast to renderer via the new
levante/cowork/prerequisites-status IPC channel and surfaced as toasts
by the new CoworkPrerequisitesStatus component. Provisioning failure
is non-fatal — the bash tool falls back to the existing
auto-detection in getShellConfig.
The resolved shell path is passed down through
getCodingTools → BashTool → executeCommand/BackgroundTaskManager via a
new shellOverride option, avoiding re-detection on every command.
Also widens analytics runtime typing to the new RuntimeType union
(node|python|gitbash) and pins MCPDeepLinkModal's local type to
node|python since gitbash is not user-selectable there.
Adds unit tests for getShellConfig override behavior and
ensureCoworkPrerequisites fallback order.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Revamps the CWD selector in the create/edit project modal:
- Replaces the "use custom folder" toggle with a two-option radio
group: "New folder" (auto-generated under ~/levante/projects) vs
"Existing folder" (user-selected path).
- Adds a drop zone in "Existing folder" mode that accepts a folder
dragged from the OS file browser. The resolved path is obtained
via webUtils.getPathForFile (exposed as window.levante.fs.getPath\
ForFile) because File.path is deprecated in Electron 32+.
- Validates the dropped item is actually a directory through a new
levante/cowork/validate-directory IPC handler before accepting it.
- Surfaces localized errors when the drop target is not a folder or
the path cannot be read, and disables Save until a path is chosen
in existing-folder mode.
- Adds en/es strings for the new UI (cwd_mode_new,
cwd_mode_existing, cwd_drop_zone, cwd_drop_zone_hint,
cwd_drop_error_*, cwd_clear).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ect-dnd feat: auto-provision Cowork prerequisites + drag-and-drop project folder
fix/refactor: sidebar scope, file browser, model catalog cache
feat(mcp): canonicalize tool results and offload images to disk
Emit the 'ensuring-python' progress event only when the Levante-managed Python runtime is missing and needs to be provisioned. Previously the event fired on every Cowork entry (first per process), causing a brief toast flash on each app restart even though Python was already cached. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… CJS build The overrides "minimatch: >=9.0.7" and "brace-expansion: >=5.0.5" forced an incompatible combination: @electron/asar's nested minimatch@3 (CJS) cannot require() brace-expansion@5.x (ESM-only), which broke `electron-forge make` with `TypeError: expand is not a function` on every platform. - minimatch → 10.0.1 (last version before the 10.0.2 breaking bump to brace-expansion@^4, which became ESM-only) - brace-expansion → ^2.0.2 (CJS + ReDoS CVE fix) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…lled-python fix(cowork): skip ensuring-python toast when already installed
Promote 1.8.1-beta.3 to stable. Includes cowork prerequisites auto-provisioning, MCP canonical tool results with image offloading, project drag-and-drop, and several fixes across file-browser, sidebar and AI provider handling. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment on lines
+9
to
+17
| import { | ||
| DEFAULT_NODE_VERSION, | ||
| DEFAULT_PYTHON_VERSION, | ||
| LEVANTE_DIR_NAME, | ||
| RUNTIME_DIR_NAME, | ||
| NODE_DIST_BASE_URL, | ||
| PORTABLE_GIT_ARCHIVE_X64, | ||
| PORTABLE_GIT_URL_X64, | ||
| } from './constants'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Promotes
v1.8.1-beta.3to the stablev1.8.1release. Bumpspackage.jsonfrom1.8.1-beta.3→1.8.1.This consolidates 24 commits merged to
developsincev1.8.0, validated via the beta channel (v1.8.1-beta.1→beta.3). The macOS notarization issue that blockedbeta.1andbeta.2was resolved beforebeta.3and the full asset matrix (4 macOS, 4 Linux, 3 Windows) is now publishing cleanly.What's included
✨ Features
ProjectModalcwdin a chat now updates the parent project🐛 Fixes
deps: pinminimatch@10.0.1andbrace-expansion@^2.0.2to unbreak the CJS buildfile-browser: normalize Windows paths beforepath-browserifyai: drop redundant fallback ingetProviderTypesidebar: list all project chats when entering project scopemcp: PR feat(mcp): canonicalize tool results and offload images to disk #256 review fixes — image budget, text truncation, and 7 code quality items🔧 Refactor
models: move selectable-models catalog to Zustand cacheRelease pipeline
After merge, run
/releasefrommainto cutv1.8.1(stable workflowRelease Build & Publish).Test plan
release/1.8.1v1.8.1-beta.3(already validated by beta channel users)main, run/releaseand confirm all 11 platform assets publish🤖 Generated with Claude Code