From 96fe1b86dd814c1691bacc9d54ceaca11c9aab5a Mon Sep 17 00:00:00 2001 From: VooDisss Date: Fri, 20 Feb 2026 12:33:52 +0200 Subject: [PATCH 1/3] fix(ui): prevent timeline auto-scroll when removing badges --- packages/ui/src/components/message-timeline.tsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/ui/src/components/message-timeline.tsx b/packages/ui/src/components/message-timeline.tsx index c0e1d9d7..fc4ef7f3 100644 --- a/packages/ui/src/components/message-timeline.tsx +++ b/packages/ui/src/components/message-timeline.tsx @@ -1,4 +1,4 @@ -import { For, Show, createEffect, createMemo, createSignal, onCleanup, type Component } from "solid-js" +import { For, Show, createEffect, createMemo, createSignal, onCleanup, on, untrack, type Component } from "solid-js" import MessagePreview from "./message-preview" import { messageStoreBus } from "../stores/message-v2/bus" import type { ClientPart } from "../types/message" @@ -350,11 +350,9 @@ const MessageTimeline: Component = (props) => { clearCloseTimer() }) - createEffect(() => { - const activeId = props.activeMessageId - + createEffect(on(() => props.activeMessageId, (activeId) => { if (!activeId) return - const targetSegment = props.segments.find((segment) => segment.messageId === activeId) + const targetSegment = untrack(() => props.segments).find((segment) => segment.messageId === activeId) if (!targetSegment) return const element = buttonRefs.get(targetSegment.id) if (!element) return @@ -366,7 +364,7 @@ const MessageTimeline: Component = (props) => { window.clearTimeout(timer) } }) - }) + })) createEffect(() => { const element = tooltipElement() From d36e568ed00b31083ba709712c157c07feb8c2db Mon Sep 17 00:00:00 2001 From: VooDisss Date: Mon, 23 Feb 2026 02:30:44 +0200 Subject: [PATCH 2/3] fix: Use legacy diff algorithm for better large file performance - Set diffAlgorithm to 'legacy' for Monaco DiffEditor - Add maxComputationTime of 10s to avoid UI freeze on huge files This addresses the issue where sessions with large JSON files (50k-100k+ lines) would cause the UI to freeze. The 'legacy' algorithm is faster than 'advanced' for large files, similar to VSCode's workaround for the same issue. See: https://github.com/microsoft/vscode/issues/184037 --- .../ui/src/components/file-viewer/monaco-diff-viewer.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/ui/src/components/file-viewer/monaco-diff-viewer.tsx b/packages/ui/src/components/file-viewer/monaco-diff-viewer.tsx index c6694f80..ace89d5f 100644 --- a/packages/ui/src/components/file-viewer/monaco-diff-viewer.tsx +++ b/packages/ui/src/components/file-viewer/monaco-diff-viewer.tsx @@ -61,6 +61,11 @@ export function MonacoDiffViewer(props: MonacoDiffViewerProps) { // Keep enough gutter space so unified diffs don't overlap `+`/`-` markers. lineNumbersMinChars: 4, lineDecorationsWidth: 12, + // Use legacy diff algorithm for better performance with large files + // See: https://github.com/microsoft/vscode/issues/184037 + diffAlgorithm: "legacy", + // Limit computation time to avoid freezing on large files + maxComputationTime: 10000, }) setReady(true) From 90baefbb7e09d24c4f45cb2e3ff99c836f250af6 Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Mon, 23 Feb 2026 08:54:57 +0000 Subject: [PATCH 3/3] fix(ci): rezip Electron macOS zips with ditto Add a codesign verify step on extracted artifacts to catch signature/resource mismatches before upload. --- .github/workflows/build-and-upload.yml | 72 ++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/.github/workflows/build-and-upload.yml b/.github/workflows/build-and-upload.yml index 8ddc9daa..17e8d705 100644 --- a/.github/workflows/build-and-upload.yml +++ b/.github/workflows/build-and-upload.yml @@ -72,6 +72,78 @@ jobs: - name: Build macOS binaries (Electron) run: npm run build:mac --workspace @neuralnomads/codenomad-electron-app + - name: Repackage Electron macOS zips (ditto) + shell: bash + run: | + set -euo pipefail + + # Prefer the workflow-provided version; fall back to package.json. + VERSION_TO_USE="${VERSION:-}" + if [ -z "$VERSION_TO_USE" ]; then + VERSION_TO_USE=$(node -p "require('./packages/electron-app/package.json').version") + fi + + release_root="packages/electron-app/release" + shopt -s nullglob globstar + + apps=("$release_root"/**/CodeNomad.app) + if [ "${#apps[@]}" -eq 0 ]; then + echo "No CodeNomad.app found under $release_root" >&2 + exit 1 + fi + + for app in "${apps[@]}"; do + bundle_dir=$(basename "$(dirname "$app")") + arch="x64" + if [[ "$bundle_dir" == *"arm64"* ]]; then + arch="arm64" + fi + + out_zip="$release_root/CodeNomad-${VERSION_TO_USE}-mac-${arch}.zip" + rm -f "$out_zip" + echo "ditto -ck: $app -> $out_zip" + ditto -ck --sequesterRsrc --keepParent "$app" "$out_zip" + done + + - name: Validate Electron macOS codesign (unzipped) + shell: bash + run: | + set -euo pipefail + shopt -s nullglob + + tmp_dir=$(mktemp -d) + trap 'rm -rf "$tmp_dir"' EXIT + + zips=(packages/electron-app/release/CodeNomad-*-mac-*.zip) + if [ "${#zips[@]}" -eq 0 ]; then + echo "No Electron macOS zip artifacts found to validate" >&2 + exit 1 + fi + + for zip in "${zips[@]}"; do + echo "Validating codesign for: $zip" + extract_dir="$tmp_dir/$(basename "$zip" .zip)" + mkdir -p "$extract_dir" + + # Use ditto for extraction as well to preserve bundle metadata. + ditto -x -k "$zip" "$extract_dir" + + app_path="" + for candidate in "$extract_dir"/*.app "$extract_dir"/*/*.app; do + if [ -d "$candidate" ]; then + app_path="$candidate" + break + fi + done + + if [ -z "$app_path" ]; then + echo "No .app found after extracting $zip" >&2 + exit 1 + fi + + codesign --verify --deep --strict --verbose=2 "$app_path" + done + - name: Upload release assets if: ${{ inputs.upload && inputs.tag != '' }} run: |