en.json: 664 new keys, 65 removed. ar.json: current catalog (5438 keys). fr.json: 65 removed keys pruned, plus two entries whose English gained a {vendor} placeholder dropped until re-translated — they fall back to English meanwhile.
- v2 is archived; drop compile gate, Windows bundle/installer/smoke jobs
- remove headless-forge, publish, release-windows workflows
- locales gate unchanged
- locales/en.json: 1,850 UI strings, generated from source; translate by copying it to <tag>.json
- locales/README.md: how to add a language, what the checker refuses and why
- scripts/validate-locales.ts: the gate; rejects escape/control chars, bidi overrides, invisible chars, broken placeholders and plurals, oversize files
- .github/workflows/locales.yml: runs the gate on every PR, refuses edits to en.json, actions pinned by SHA
- CODEOWNERS: gate and en.json need maintainer review
- non-dismissible top banner: SoulForge has evolved into Empryo, links to docs/download
- Empryo-themed look (near-black + terminal green, mono) in both color schemes
- genome-scan sweep + breathing underglow animation, reduced-motion safe
- tree-sitter: skip files >1MB before parse (minified/generated content stalled the thread)
- tree-sitter: cancel parses over 5s via native progressCallback (a Promise.race timeout can't preempt the synchronous WASM parse proposed in #129)
- tree-sitter: guarantee tree.delete() on error paths in findImports/getFileOutline (WASM memory leak)
- tree-sitter: cap collectHashableNodes at 200 results; recursion depths kept at 40/10 to preserve clone-detection hash semantics
- regex: extractBraceScope now skips braces inside strings and comments (Rust lifetime-aware)
- regex: skip files >1MB in findSymbols/findImports/findExports
- ts-morph: skip files >1MB in getSourceFile, evicting any stale oversized entry
- router: per-op fallback timeouts (10s default, 30s for project-wide ops like findImplementation/getDiagnostics)
- router: BFS directory scans yield to the event loop every 20 dirs instead of cutting depth limits, keeping JVM project detection intact
Reported with proposed fixes by @Dojdik in discussion #129
Semantic summary generation aborted mid-run with "Callback timeout:
summaryGenerator" on slow models (Minimax M3, DeepSeek) at higher LLM
limits. Each batch summarizes 10 symbols via ctx.requestCallback, which
had a hardcoded 60s timeout — slow models exceed that on some batches,
rejecting the whole run. The outer RPC already allows 300s.
Pass 300_000ms to the summaryGenerator callback (matching the outer RPC
budget) and surface the optional timeoutMs param on the
WorkerHandlerContext.requestCallback interface.
Fixes#126
Co-Authored-By: SoulForge <[email protected]>
- Add llmgatewayReasoningEffort knob, overrides shared compat effort
- Expose cache TTL (5m/1h) and web search toggle in the tab
- Wire effort override through getCompatReasoningBody, falls through when off
Co-Authored-By: SoulForge <[email protected]>
Add a read-only Embedding row to the /memory Settings tab showing the resolved model and source, or offline (hashbag-v2) on fallback.
Expand memory docs to cover API key requirement, supported models, auto-resolution, and how to verify the embedder is active (#115).
Co-Authored-By: SoulForge <[email protected]>
Defer the /models background fetch storm one tick so OpenTUI paints the scrollbox before the io.worker HTTP burst.
Removes the native-render + worker-FFI contention that segfaults on Windows (#120).
Co-Authored-By: SoulForge <[email protected]>
ESC byte is required to match the CSI 48;rows;cols t in-band resize report. Same suppression pattern used in useMouse.ts and App.tsx for terminal protocol parsing.
Refs #91
Co-Authored-By: SoulForge <[email protected]>
Replace the poll-only resize fix with the mechanism modern TUIs use: DEC mode 2048 in-band resize notifications. The terminal reports size changes as a stdin escape sequence (CSI 48;rows;cols;hpix;wpix t), which travels the input stream and survives transports that drop SIGWINCH (Win32-OpenSSH -> WSL2, #91).
- enable ?2048h at startup, parse reports via renderer.addInputHandler
- disable ?2048l in restoreTerminal on exit
- keep the 1s TIOCGWINSZ watchdog as fallback for terminals without
mode 2048 (xterm, Alacritty, Windows Terminal)
- unsupported terminals ignore the enable sequence; strictly additive
Refs #91
Co-Authored-By: SoulForge <[email protected]>
Win32-OpenSSH (PowerShell ssh client) does not forward window-change to the remote PTY, so the renderer's SIGWINCH handler never fires and the TUI stays at its launch size (or corrupts on shrink). Add a 1s watchdog that reconciles process.stdout.columns/rows with the renderer via renderer.resize() — the documented hook for externally-driven resizes. No-op when sizes match; unref'd so it never holds the process open.
Fixes#91
Co-Authored-By: SoulForge <[email protected]>
- fall back to raw OSC-52 on stdout when renderer capability detection misses osc52 (SSH)
- route non-ASCII Windows copy through base64-in-argv PowerShell (clip.exe codepage mojibake)
- resolve PowerShell binary properly for pwsh-only installs
- WSL: text + image clipboard via Windows interop (clip.exe / powershell.exe GetImage)
- order Linux image backends by WAYLAND_DISPLAY to avoid 3s wrong-backend timeout
- fix AppleScript escaping order in macOS image read
Fixes#93
Co-Authored-By: SoulForge <[email protected]>
vmmap suspends the target task while walking its VM map, so the TTL cache from 8b459ca6 only made the freeze rarer (every 30s), not gone. /usr/bin/footprint reads task_info phys_footprint directly without stalling the target. Measured: vmmap caused 350-380ms stalls per sample; footprint caused zero.
Fixes#102
Co-Authored-By: SoulForge <[email protected]>
Cross-compile/release jobs were gated to pull_request only, so a dep bump pushed straight to main passed (lint+typecheck) then broke the release. Add a fast compile gate to the always-run check job.
- check job cross-compiles all 5 shipped targets (SKIP_SMOKE, ~5s each)
- a dep that breaks Bun static resolution now fails on main, not at release
- fix stale pinned @opentui/[email protected] in windows-bundle: derive version from installed @opentui/core
Co-Authored-By: SoulForge <[email protected]>
- Stamp x-session-id + x-session-affinity on every LLM request
- Per-tab routing id (TUI), resumed/opts/UUID (headless), workspace id (hearth)
- /clear rotates the routing id so the chat re-scores its provider
- Skips vercel-gateway (prebuilt instance) and bedrock (SigV4-signed headers)
Co-Authored-By: SoulForge <[email protected]>
- Add isClaude5Plus() to gate temperature/adaptive-thinking for Fable 5 / Mythos 5
- Detect proxy login success via credential file changes, not proxy health
- Bounce running proxy after login so it reloads fresh upstream creds
Co-Authored-By: SoulForge <[email protected]>
- copy-on-select keeps the highlight; only explicit copy (right-click/Ctrl+C) clears
- reset drip state when content shrinks (native markdown assumes monotonic growth)
- pass real streaming flag to <markdown> so trailing block finalizes at handoff
Co-Authored-By: SoulForge <[email protected]>
Replace per-family allow-list with a low-cardinality slug shape gate so new public models surface without regex upkeep; gate on first-slash segment to block path traversal. Relax worker MODEL_RE and FAMILIES to shape checks.
Co-Authored-By: SoulForge <[email protected]>
- enable useMouse so the renderer builds a selection model
- copy via right-click, mouse-up, Ctrl+C and Ctrl+Y (console keybind)
- gate copy-on-select off on Windows; add Ctrl+C console guard + input flush
- wire copy-on-select into the modal/dialog overlay layer
- centralize logic in useCopySelection hook
Co-Authored-By: SoulForge <[email protected]>
- post-scan semantic/cache task could reject and strand /repo-map on the "waiting for soul map..." stub
- wrap in try/catch; on failure reset semantic status to off when still showing the stub
Co-Authored-By: SoulForge <[email protected]>
- extractReasoningMiddleware scanned answer text for <think>/<thinking>, corrupting normal output containing those words near angle brackets
- gate middleware to non-native families only; Claude/OpenAI/Google/xAI/DeepSeek-R skip it (they stream reasoning natively)
Co-Authored-By: SoulForge <[email protected]>
- live view (FinalResponseLiveAutoView) now shows reasoning blocks like static view
- "Thinking…" placeholder when no visible body yet — no bare header husk
- thread showReasoning/reasoningExpanded from TabInstance
Co-Authored-By: SoulForge <[email protected]>
- wrap every resolved model with extractReasoningMiddleware
- splits <think> and <thinking> from text into native reasoning
- no-op for providers with a native reasoning channel
Co-Authored-By: SoulForge <[email protected]>
- yield via microtask budget, not setTimeout(0) — no event-loop starvation
- hoist + gate Hearth bridge streaming behind active binding
- show "Thinking…" placeholder when reasoning hidden and no visible body
Co-Authored-By: SoulForge <[email protected]>