Closed
Conversation
## Summary - fix the sticky-bottom state where dragging the scrollbar to the bottom makes `PageUp` jump to the previous timeline block and then snap immediately back down - keep the change scoped to `virtual-follow-list.tsx`, where follow mode, scroll intent, and bottom pinning are coordinated ## Root Cause The list only disabled follow mode when it saw an explicit local "user intent" signal. After reaching the bottom through the native scrollbar, `PageUp` could move the viewport without tripping that path, so the next render notification re-enabled the bottom snap immediately. ## Validation - `npx tsc --noEmit --project packages/ui/tsconfig.json` - `npm run build --prefix packages/ui` - manual desktop test: `PageUp` works again from the bottom sticky state
Keep the textarea width independent from the prompt controls so wrapping matches the visible layout. Split secondary controls from the primary stop/send rail to preserve the original action column width and add a matching divider.
## Summary Fixes #303. This PR redesigns the Git Changes Monaco diff gutter so unified and split view both use a more intentional, space-efficient Monaco presentation while preserving Monaco's performance on large diffs. The final behavior includes: - `Compact` and `Normal` gutter modes for Git Changes - dynamic gutter sizing based on actual line-number digit counts - independent original/modified number-column sizing where needed - split-view fixes for both wasted left inset and line-number/sign overlap - persisted gutter-mode selection - localized user-facing labels for the control ## Visual comparison ### Unified view before <img width="465" height="353" alt="Unified view before" src="https://github.com/user-attachments/assets/0c061f25-f20a-4127-a85d-aee1161611c7" /> ### Unified view after <img width="634" height="240" alt="Unified view after" src="https://github.com/user-attachments/assets/f2dfd952-89ed-4fdd-83db-a05f19f023b2" /> ### Split view before <img width="596" height="335" alt="Split view before" src="https://github.com/user-attachments/assets/09bfbe41-9438-4801-b181-49a9d19d5bb8" /> ### Split view after <img width="640" height="338" alt="Split view after" src="https://github.com/user-attachments/assets/fc3618ef-474f-4217-bb21-5ffd53eb4e01" /> <!-- If you want to replace these screenshots later, keep the four sections above and swap the image URLs. --> ## What changed ### Unified view - added two Git Changes Monaco gutter presentations: - `Compact` - `Normal` - kept compact as the tighter single-column-feel unified gutter - kept normal as the wider Monaco-style unified gutter - made unified gutter sizing respond to actual line-number digit counts instead of fixed assumptions - made normal mode size the visible number columns independently when one side needs more width than the other ### Split view - added dynamic split gutter sizing derived from actual before/after line counts - made split original and modified number columns size independently - fixed the modified-pane overlap where larger line numbers could collide with the `+` lane - fixed the original-pane wasted left inset caused by Monaco reserving an empty original-side glyph-margin lane ### Persistence and UI - persisted the selected gutter mode in preferences so it survives reloads - moved the gutter-mode control out of the Git Changes toolbar and into Appearance settings - renamed the visible settings options to `Compact` and `Normal` ### i18n - removed hardcoded user-facing gutter toggle strings - added localized keys for the gutter control labels and titles used by the Git Changes surface ## Implementation notes - Monaco remains the active Git Changes renderer throughout - gutter sizing logic is centralized in `packages/ui/src/components/file-viewer/monaco-diff-viewer.tsx` - CSS is used only for narrow presentation adjustments such as the 4px left inset and the split original-pane glyph-margin correction - the persisted gutter-mode preference is the source of truth for the selected presentation ## Review focus - unified `Compact` mode should feel tight without clipping or overlap - unified `Normal` mode should remain wider and readable - 3-digit and 4-digit line numbers should not collide with the sign lane - split original pane should no longer show wasted left inset before the first visible number column - split modified pane should not leave conspicuous dead space or collide with the `+` lane as digit counts grow - selected gutter mode should persist after reload --------- Co-authored-by: Shantur Rathore <i@shantur.com>
## Summary - move delete-worktree failures out of transient toast-only UX and keep them inline in the delete modal - add parsed diagnostics for common failure modes, including a short summary, likely cause, and suggested next step - make the raw error easier to review and share with raw and sanitized copy actions Closes #301. ## BEFORE: <img width="1127" height="860" alt="image" src="https://github.com/user-attachments/assets/dd09ba1e-be8c-450c-a1dd-f1cde2a48802" /> ## AFTER: <img width="1384" height="835" alt="image" src="https://github.com/user-attachments/assets/6b0d1459-21fa-4264-9e54-45540f584538" /> ## Problem Before this change, delete-worktree failures were difficult to work with: 1. The failure message was effectively raw backend or git output. 2. Users had to infer the meaning of the error themselves. 3. The UI did not explain what likely went wrong or what to do next. 4. Sharing the error for debugging was awkward when it included machine-local absolute paths. 5. The confirmation modal was not being used as the primary diagnostic surface for a destructive action that frequently fails for understandable reasons. This was especially frustrating for common cases such as: - modified or untracked files in the worktree - a process still using the worktree directory - permission errors on Windows - missing worktree directories or stale worktree records ## What changed ### Modal failure UX - keep delete failures inline inside `packages/ui/src/components/worktree-selector.tsx` - clear modal-local error state when opening or closing the dialog - keep the success toast on successful deletion, but use the modal itself for failure presentation ### Human-readable diagnostics - parse JSON-shaped backend error payloads such as `{"error":"..."}` before classification - classify common delete failure patterns into: - `localChanges` - `inUse` - `notFound` - `permissionDenied` - `unknown` - render three user-facing lines above the raw error: - summary - likely cause - suggested next step ### Copy flows - add `Copy error` for the original failure text - add `Copy sanitized` to redact common absolute path and username patterns before copying ### Modal content and sizing - present the target worktree in a simpler two-line summary block - update the delete description text to plain English: `Deletes this branch worktree and its local folder.` - size the delete modal deliberately for desktop use while allowing vertical expansion to the viewport limit before scrolling ### i18n coverage - add the new delete diagnostic strings across all currently supported locales touched by this area: - `en` - `es` - `fr` - `he` - `ja` - `ru` - `zh-Hans` ## Why this approach - It keeps the backend contract unchanged and solves the UX problem where it occurs. - It preserves access to the raw failure text instead of hiding implementation detail entirely. - It gives users immediate guidance without forcing them to translate git errors into next actions. - It improves bug reporting without requiring a separate logging or export workflow. ## Not included - server-side preflight guards that block delete when the worktree is still assigned or in use - process-aware worktree locking detection - automatic retry or force-delete-and-retry flows Those are useful follow-ups, but this PR is intentionally scoped to failure presentation and debuggability. ## Files changed - `packages/ui/src/components/worktree-selector.tsx` - `packages/ui/src/lib/i18n/messages/en/instance.ts` - `packages/ui/src/lib/i18n/messages/es/instance.ts` - `packages/ui/src/lib/i18n/messages/fr/instance.ts` - `packages/ui/src/lib/i18n/messages/he/instance.ts` - `packages/ui/src/lib/i18n/messages/ja/instance.ts` - `packages/ui/src/lib/i18n/messages/ru/instance.ts` - `packages/ui/src/lib/i18n/messages/zh-Hans/instance.ts` ## Validation - `npm run typecheck --workspace @codenomad/ui` - `npm run build --workspace @codenomad/ui` - `npm run typecheck --workspace @neuralnomads/codenomad-electron-app` ## Notes for reviewers - The error classifier is intentionally heuristic and string-based. It is meant to improve the common cases without increasing backend coupling. - The sanitized copy flow is conservative and focused on path and username redaction, not full structured log scrubbing. --------- Co-authored-by: Shantur Rathore <i@shantur.com>
Fixes #326 ## Summary - source the user's bash or zsh rc before launching the bundled CLI from Tauri - use `-l -i -c` for zsh so shell-managed Node runtimes are available in launcher-started sessions - fixes the reproduced Linux launcher case where the app exits with `CLI exited early: exit status: 127` while terminal launches work ## Validation - reproduced the failure with the released Tauri `v0.14.0` Linux binary - verified the patched binary succeeds under the same launcher-like environment - ran `cargo build` on the dev-based PR branch
Fixes #294 ## Summary - detect missing desktop Node runtimes before spawning the bundled CLI - return a clear error message that tells users to install Node.js or set `NODE_BINARY` - handle both direct spawns and desktop-shell launches consistently ## Validation - `npm run bundle:server --workspace @codenomad/tauri-app && cargo build --manifest-path packages/tauri-app/src-tauri/Cargo.toml` - exercised the missing-runtime path in the Linux VM by launching with an invalid `NODE_BINARY`
Refs #330 ## Summary - add standard Linux hicolor icon sizes to the Tauri package outputs - enable the GTK app id on Linux and ship a matching reverse-DNS desktop entry alias for shell association - mark the alias desktop entry `NoDisplay=true` so it does not surface as a duplicate launcher in desktop menus - include the same alias desktop entry for AppImage so the fix is not limited to deb/rpm packages ## Validation - confirmed in the Linux VM that the desktop-integrated launch no longer shows the generic taskbar icon - verified the alias desktop entry is now hidden from app menus via `NoDisplay=true` - attempted a fresh `tauri build --bundles deb`; the build still hits the known optional `@tauri-apps/cli` native-binding issue in this workspace after prebuild, not a code/config error from this PR
Fixes #273 ## Summary - mark the session list header label as non-translatable - mark compact session status badges as non-translatable - prevent browser/page translation from duplicating already localized labels like the repeated idle badge shown in #273 ## Validation - `npm run build --workspace @codenomad/ui`
Follow-up from #334 ## Summary - align the Electron package `build.appId` with the runtime identifier already used in `app.setAppUserModelId(...)` - remove the mismatch between packaged desktop identity and runtime desktop identity - keep the change narrowly scoped to identifier consistency only ## Validation - verified the previous mismatch in `packages/electron-app/package.json` vs `packages/electron-app/electron/main/main.ts` - updated the packaging id to match the runtime id exactly
Fixes #324 ## Summary - declare root Rollup optional dependencies for the repo's current supported build matrix: macOS x64/arm64, Linux x64/arm64, and Windows x64 - pin those root platform packages to the same Rollup version already used by the repo - keep the existing workflow/manual-install fallback steps in place for now ## Validation - regenerated `package-lock.json` with `npm install --package-lock-only --ignore-scripts` - verified the root package entry now records the supported platform packages under `optionalDependencies` - kept the change scoped to the platforms currently represented in workflows and `packages/tauri-app/scripts/prebuild.js`
…#333) ## Summary - add a server-backed HTTPS proxy flow for Tauri remote windows so self-signed remote HTTPS works with the local CLI TLS assets and desktop auth/cookie handling - manage remote proxy sessions through `packages/server` with per-session bootstrap, local-only cleanup, and explicit session lifecycle handling - support the Tauri desktop flow across environments, including packaged Windows builds, `tauri dev`, and updated Linux/macOS handling for the new local HTTPS proxy path ## Testing - `npm run build --workspace @neuralnomads/codenomad` - `cargo check` - `npm run build --workspace @codenomad/tauri-app` - Windows smoke test for concurrent remote proxy bootstrap sessions - Windows manual validation of packaged Tauri remote connection flow ## Notes - Windows was validated end-to-end. - Linux and macOS code paths were updated for the new proxy flow, but runtime validation on those platforms is still pending. --------- Co-authored-by: Shantur Rathore <i@shantur.com>
Don't let remote server windows use local features like local file browser etc
## Summary - support Windows validation and launch of OpenCode binaries stored under WSL UNC paths like \\wsl.localhost\... - harden the existing manual directory browser so absolute, UNC, and WSL paths can be pasted and navigated reliably - harden WSL env/path propagation, UNC workspace handling, runtime shutdown, and add targeted tests Partially addresses #5. ## Testing - node --test --import tsx src/workspaces/__tests__/spawn.test.ts - npm run typecheck --workspace @neuralnomads/codenomad - npm run typecheck --workspace @codenomad/ui
## Summary - package `packages/server` as a standalone desktop executable so Electron and Tauri no longer depend on a system-installed Node runtime in production - align Electron and Tauri startup logic around launching the packaged server, resolving binaries from the user shell, and bundling the same server resources into both desktop apps - replace the workspace instance proxy path that used `@fastify/reply-from` with a direct streaming proxy so packaged standalone builds can talk to spawned `opencode` instances correctly ## Why Desktop production builds were still depending on a user-provided Node runtime to launch `packages/server`, which made packaging less self-contained and created different behavior across machines. While moving to a standalone server executable, we also found that Bun-compiled standalone builds could start `opencode` successfully but failed when proxying requests to those instances through `reply-from`. The goal of this change is to make desktop production startup self-contained, keep Electron and Tauri behavior aligned, and restore correct communication with local `opencode` instances in packaged builds. ## What Changed - added a standalone build path for `packages/server` and bundle `codenomad-server` into desktop resources - updated Electron production startup to resolve and launch the standalone server executable - updated Tauri production startup to resolve and launch the standalone server executable with matching cwd and shell behavior - added runtime path helpers so the packaged server can reliably find its bundled UI, auth templates, config template, and package metadata - improved bare binary resolution so commands like `opencode` can be resolved from the user's login shell environment - upgraded the server stack to newer Fastify-compatible packages needed for the standalone/runtime work - replaced the workspace instance proxy implementation with a direct streaming proxy for requests to spawned `opencode` instances - updated Electron and Tauri build/prebuild scripts to generate and package the standalone server, while also repairing missing platform-specific optional binaries during packaging ## Benefits - desktop production builds no longer require Node to be installed on the user's system - Electron and Tauri now use the same packaged server model in production, reducing platform drift - packaged desktop apps can successfully create workspaces, launch `opencode`, and proxy health/session traffic to those instances - the server bundle is more self-contained and resilient to different launch environments - desktop packaging is more predictable because the required server executable is built and bundled as part of the app build flow
Prevent idle system sleep on supported desktop runtimes without intentionally keeping the display awake. Narrow wake-lock activation to true active work states and drop the web screen-wake fallback where the platform cannot provide system-sleep-only behavior.
Add the wake-lock SCR, discussion summary, and task artifacts that captured investigation, specification, and implementation handoff for the system-sleep-only behavior change.
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.
No description provided.