- Add direction: ltr to .monaco-viewer so the Monaco editor renders
correctly when the document inherits dir="rtl" from Hebrew locale
- Replace physical margin-left with logical margin-inline-start on
the refresh button in FilesTab
- Remove manifest.json (unrelated to RTL work, flagged in PR #229)
- Remove docs/rtl-hebrew-deployment.md (no longer needed)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add direction: ltr to pre elements so code always displays LTR in RTL UI
- Fix selector secondary text: text-left → text-start, add w-full to
prevent RTL flex cross-axis drift
- Add dir="ltr" to model path span (opencode/model-id is always LTR)
- Restore padding-inline-start: 2.5rem in narrow-screen media query
where padding shorthand was overriding it
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- border-l-[3px] → border-s-[3px] on .message-error-block (both CSS files)
- ml-auto → ms-auto on .message-step-time
- text-left → text-start on buttons and list items across panels and tool-call styles
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Buttons were originally at right:0.25rem (physical), same side as the scrollbar
in LTR — a pre-existing overlap bug masked by overlay scrollbars on macOS.
Fix: move buttons to inset-inline-start so they are always opposite the scrollbar
in both LTR (buttons left, scrollbar right) and RTL (buttons right, scrollbar left).
Flip padding accordingly: inline-start gets 2.5rem, inline-end gets 0.75rem.
Also add direction:rtl override for RTL to fix dir="auto" defaulting to LTR
on an empty textarea.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Use direction:ltr on the textarea in RTL mode to keep scrollbar on the right
(start side). Nav buttons remain at inset-inline-end (left/end in RTL).
Swap padding so left gets 2.5rem (for buttons) and right 0.75rem (for scrollbar gap).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
In RTL, browser places textarea scrollbar on the left. Using inset-inline-end
put nav buttons also on the left, causing overlap. Keep physical right/padding-right
so buttons are always away from the scrollbar.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace physical pl-3/pr-10 with logical padding-inline-start/end
so the large padding (for nav buttons) is on the correct side in RTL.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Invert resize delta in RTL for drawer (useDrawerResize) and split panel (RightPanel)
- Add dir="ltr" to path/code value elements in instance-info panel
- Replace hardcoded English strings with i18n: Hide/Show files, No git changes yet,
Hide unchanged regions / Show full file, diff toolbar titles, + Create worktree
- Fix sessionList.status.idle: "בסרלה" → "מוכן" in session.ts
- Fix text-align: left → start in message-reasoning-toggle and tool-call-io-toggle
- Fix left: 0 → inset-inline-start: 0 in attachment-chip-preview
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Step-by-step guide covering npm global install (node only, not bun),
UI download and extraction, systemd user service setup, and update flow.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Translates all ~400 UI strings to Hebrew across 16 message modules.
Registers the 'he' locale in the i18n system and adds עברית to the
language picker. Built on top of the rtl-support branch so RTL layout
applies immediately when Hebrew is selected.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
## Summary
- defer locale and overlay loading work away from the first critical
render path
- seed locale state from the bootstrap preload so the first render can
use the preloaded language immediately
- keep bootstrap cache and locale fallback behavior consistent on
subsequent launches
## Testing
- npm run build --workspace @codenomad/ui
## Summary
- split the right panel, picker, and tool call secondary viewers into
smaller deferred chunks
- release hidden right-panel file buffers and stop tracking static
tool-call scrollers when they are not needed
- keep this branch focused on the remaining secondary viewer chunking
work now that the Monaco-specific chunking moved into PR 215
## Testing
- npm run build --workspace @codenomad/ui
## What and why
CodeNomad had no RTL (right-to-left) support, so users writing in Hebrew
or Arabic would see their messages displayed left-to-right — misaligned
text, broken reading flow, wrong punctuation placement.
This PR adds automatic direction detection to all elements that display
user or model text. The browser detects direction from the first strong
character in each text block: Hebrew/Arabic → RTL, Latin/code → LTR. No
configuration needed — it just works per message, per paragraph.
## Technical notes
The natural fix is `dir="auto"` on the containing elements. However,
Chromium does not propagate direction detection from a parent `<div>`
into its `<p>` children — so Hebrew inside `<p>` rendered via
`innerHTML` (as markdown is) was still detected as LTR. The fix is to
apply `unicode-bidi: plaintext` via CSS directly on the block-level
elements (`p`, `li`, headings, etc.), which has the same auto-detection
semantics but applies per element.
## Summary
- Add `dir="auto"` to all elements containing user-generated or
model-generated text (message content, prompt input, session names, tool
outputs) so the browser auto-detects text direction
- Add `unicode-bidi: plaintext` via CSS to markdown block elements (`p`,
`li`, headings, `blockquote`, `td`/`th`) to fix per-paragraph RTL
detection in Chromium (where `dir="auto"` on a parent div does not
recurse into block children)
- Convert physical CSS properties to logical equivalents in
`markdown.css`: `border-left` → `border-inline-start`, `padding-left` →
`padding-inline-start`, `text-align: left` → `text-align: start`,
`margin-left` → `margin-inline-start`
## Affected components
- `markdown.tsx` — main markdown renderer
- `message-part.tsx` — text part wrapper and plain-text fallback
- `message-item.tsx` — message body and error blocks
- `prompt-input.tsx` — user input textarea
- `session-list.tsx` — session titles in sidebar
- `session-rename-dialog.tsx` — session rename input
- `instance-welcome-view.tsx` — Resume Session dialog
- `tool-call/markdown-render.tsx` — tool output markdown fallback
- `tool-call/ansi-render.tsx` — ANSI output
- `tool-call/diagnostics-section.tsx` — diagnostic messages
## Test plan
- [ ] Send a Hebrew-only message → text right-aligned
- [ ] Send a mixed Hebrew + English message → correct per-paragraph
direction
- [ ] Message containing a code block → code stays LTR
- [ ] Type Hebrew in the prompt textarea → input flows right-to-left
- [ ] Hebrew session name in sidebar → right-aligned
- [ ] Hebrew session name in Resume Session dialog → right-aligned
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
## Summary
- restore the missing desktop View and Window menu controls
- use native reload and window actions where supported instead of
brittle webview-only behavior
- restore the working fullscreen keyboard shortcut while keeping the
zoom menu labels aligned with the intended desktop behavior
## Testing
- cargo check --manifest-path packages/tauri-app/src-tauri/Cargo.toml
## Summary
- lazy-load the markdown and diff render paths so they stop inflating
initial UI startup work
- move shared text rendering helpers out of the markdown path and keep
diff rendering on the deferred path
- defer the Monaco secondary viewers so the markdown and diff path no
longer keeps that work in the main bundle
## Follow-ups
- related fork follow-up: Pagecran/CodeNomad#1
- that follow-up is now independent on dev and only keeps the remaining
right panel, picker, and tool-call secondary chunking work
## Testing
- npm run typecheck --workspace @codenomad/ui
- npm run build --workspace @codenomad/ui
## What
Fix slash command execution so `[pasted #N]` placeholders are resolved
before calling `session.command`, matching normal prompt send behavior.
## Why
When pasting long text into a slash command (e.g. `/some-command [pasted
#1]`), the UI previously bypassed `resolvePastedPlaceholders(...)` for
known slash commands and sent the literal placeholder text as command
arguments.
## Changes
- Resolve pasted placeholders (and other prompt placeholders handled by
`resolvePastedPlaceholders`) in slash-command arguments before
`executeCustomCommand(...)`.
- Remove *consumed* pasted-text attachments (those referenced by
placeholders in the slash-command args) so they don’t linger for the
next prompt.
Fixes#234.
## Notes
- I attempted `npm run typecheck --workspace @codenomad/ui` locally but
the workspace dependencies aren’t installed in this bot environment, so
it fails with missing-module errors. CI should validate with a full
install.
--
Yours,
[CodeNomadBot](https://github.com/NeuralNomadsAI/CodeNomad)
Co-authored-by: Shantur Rathore <i@shantur.com>
## Summary
- restore the GitHub and Discord links on the folder picker in the Tauri
app
- open those links through the desktop opener bridge instead of relying
on browser-only navigation behavior
- include the capability/schema updates needed for the opener path
## Testing
- npm run typecheck --workspace @codenomad/ui
- cargo check --manifest-path packages/tauri-app/src-tauri/Cargo.toml
This PR prevents OS notification spam from spawned subagent sessions by
skipping OS-level notifications for any session that is a child thread
(`parentId !== null`).
What changed
- `packages/ui/src/stores/session-events.ts`
- Added `isChildSession(...)` +
`shouldSendOsNotificationForSession(...)`
- Applied the check to OS notifications emitted from:
- `handleSessionIdle(...)`
- `handlePermissionUpdated(...)`
- `handleQuestionAsked(...)`
- If a session is not yet hydrated in the client store, we
conservatively *do not* emit an OS notification (avoids early subagent
spam).
Why
- Subagent sessions are represented as child sessions in the UI thread
model; OS notifications were previously emitted for all sessions
indiscriminately.
Testing
- Not run here: `bun run typecheck` fails in this environment due to
missing installed deps/types (e.g. `solid-js`).
Closes#228
--
Yours,
[CodeNomadBot](https://github.com/NeuralNomadsAI/CodeNomad)
Co-authored-by: Shantur Rathore <i@shantur.com>
### Summary of Improvements
This PR replaces the custom `IntersectionObserver`-based virtualization
with the `virtua` library to significantly improve rendering performance
and UI responsiveness.
### 🚀 Performance Results
Verified using `session-performance.test.ts`:
- **Rendering**: 2000 messages rendered in **16.90ms**.
- **Huge Conversation**: 10,000 messages processed in **0.80ms**.
- **Session Switching**: Average switch time reduced to **0.58ms**
(virtually zero lag).
### 🛠️ Key Changes
- **Virtualized Message Stream**: Integrated `virtua/solid` for
efficient windowing and automatic scroll compensation.
- **Floating Scroll Controls**: Applied `position: absolute` and
`pointer-events: none` to the list controls to ensure
scroll-to-top/bottom buttons float correctly over the message area
without blocking interactions.
- **Package Synchronization**: Updated `virtua` and SDK dependencies,
with a fully synchronized `package-lock.json` for stable builds.
### 🎥 UI Verification
https://github.com/user-attachments/assets/24e483a3-8be6-4ac4-a431-d719f2015f4e
- **Smooth Scrolling**: Verified that rendering gaps are eliminated
during fast scrolls.
- **Position Retention**: Scroll positions are preserved when switching
between sessions.
> [!NOTE]
> Detailed performance gains and layout fixes are isolated to the
`virtua` implementation and core package updates, following the
requested cleanup.
---------
Co-authored-by: Shantur Rathore <i@shantur.com>
Restrict non-dev pull requests to an allowlisted set of actors and skip cross-platform PR builds unless that authorization check passes. Keep dev open for general contributions while guiding other PRs back to the dev branch.
Run the full cross-platform build matrix on pull request creation and updates so build regressions are caught before merge without publishing release artifacts.