## 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>
## 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>
Stop resetting history navigation on input so editing recalled entries doesn't wipe the bottom draft. Allow ArrowDown navigation while in history and persist the session draft only for fresh prompts.
Extract prompt draft/history, attachments, picker, and keydown logic into co-located hooks. Introduce PromptInputApi for quote/expand/setText and migrate SessionView off DOM poking; remove legacy registerQuoteHandler.
Converts hardcoded UI copy to i18n keys across the app, adds global translation for non-component modules, and splits the English catalog into feature modules with duplicate-key detection.
- Remove isMobileWidth signal and updateMobileWidth resize listener
- Use same placeholder text for all devices/platforms
- "Type your message, @file, @agent, or paste images and text..."
Simplifies implementation per dev feedback - one approach for all
- Remove 3-state logic (normal/50%/80%) - now only normal/expanded
- Remove double-click detection and tooltips for simplicity
- Remove platform-specific behavior (same UX for Electron and web)
- Optimize button layout: reduce from 36px to 28px to fit 3 buttons
- Position expand button above history buttons in vertical stack
- Keep 15-line expanded height (360px, capped to available space)
Per upstream dev feedback to keep it simple with one approach
- Add platform detection (Electron vs Web) for expand behavior
- Electron: 3-state (normal → 50% → 80%) with double-click
- Web/Mobile: 2-state (normal → expanded) with instant single tap
- Implement fixed 15-line height for web/mobile (360px, capped)
- Add orientation-aware height calculation (landscape vs portrait)
- Remove tooltip on web/mobile, keep for Electron desktop
- Add responsive placeholder text to prevent overlap on mobile
- Desktop: "Type your message, @file, @agent, or paste images and text..."
- Mobile (≤640px): "Type message, @file, @agent..."
- Delete dev-docs/expand-chat-input.md per upstream feedback
Addresses PR feedback to simplify from 3-state to 2-state for web/mobile
while maintaining rich desktop experience in Electron app.
- Add expand button with Maximize2/Minimize2 icons
- Implement 3-state height management (normal/50%/80%)
- Smart double-click detection with 300ms delay
- Height calculation based on session-view - 200px message space
- Custom CSS tooltip with dark gradient background and backdrop blur
- Send button anchored at bottom via margin-top: auto
- Smooth CSS transitions throughout
- Double-click at 80% now reduces to 50% (not normal)
- Removed all debug console.log statements