Settle the AI chat pane on a clean, terminal-consistent layout instead of
faux bubbles in a RichTextBox:
- Messages: user right-aligned accent, AI left, tool activity quiet gray,
"thinking" folded into the Send button (no transcript spam).
- Bottom bar: input (fill) + bottom-right column (model dropdown over Send).
- Model dropdown lists the endpoint's /v1/models, switches on the fly, and
is remembered — Settings → AI Assistant now only holds Base URL / API Key
/ system prompt (configured = Base URL set). OpenAiChatClient.Model is
mutable + ListModelsAsync.
Real chat bubbles + Markdown via WebView2 are logged as a v0.7.0 option in
ARCHITECTURE Future Extensions rather than hacked onto RichTextBox.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Chat UI now Claude-style: user messages right-aligned with an accent
bubble (no "你:" prefix), AI replies left-aligned.
- Model dropdown at the bottom, populated from the endpoint's GET
/v1/models, lets you switch models without opening Settings; the choice
is remembered. OpenAiChatClient.Model is now mutable + ListModelsAsync.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Open it from the toolbar (✨ AI Chat) and lay it out next to a Serial
session with Layout (1×2, 2×2…) — chat on one side, watch the terminal
on the other, like Claude Code / Kiro. Previously it was a full-page
Activity Rail view that couldn't sit beside a live session.
WorkspaceView.Session is now abstracted to hold either a SessionPage or
an AiChatView via a Content property; group/log/script actions skip AI
panes. Removed the standalone Ai rail view; Settings → AI Assistant
(provider config) is unchanged.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add a GUI AI Assistant view (✨ rail) that drives serial + PDU in plain
language, without depending on Claude/Kiro. In-process function calling
(no MCP hop): Ai/OpenAiChatClient (minimal OpenAI-compatible client) +
Ai/AgentHost (hand-written agent loop) + Ai/AiTools (serial via the
existing SerialBridge with [AI] echo; PDU via ETTerms.PduCore).
BYO endpoint: Base URL / Model / API Key set in Settings → AI Assistant,
blank by default = disabled. No private endpoint ships in the app; API
key lives in Windows Credential Manager, never in settings.json or code.
Safety: destructive PDU actions (outlet off / power-cycle) require a GUI
confirmation; every tool call is written to AppLogger. Existing Serial/
PDU MCP servers (Settings → AI MCP) are unaffected and keep serving
external AI CLIs.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Settings -> Terminal gains a 'Show script trace in terminal' checkbox
(AppSettings.ShowScriptTrace, default on). When off, TTL trace lines
([wait] progress, sent-command echo, errors) are no longer drawn in
the terminal. dispstr moves to a dedicated Display event and always
shows, since it is the script explicitly printing something.
Trace was already display-only (never written to session logs, the AI
serial bridge, or the device) - docs now state this explicitly.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Terminal:
- cache font variants + single reusable brush in render hot path;
resolve cell colors once per cell; dispose GDI resources
- scrollback: List+RemoveRange -> O(1) ring buffer
- follow new output only when already at bottom (no more yank-to-bottom
while reading history)
- alt-screen mouse wheel -> arrow keys (vim/htop scroll)
- answer DSR (ESC[5n/6n) and DA (ESC[c) queries so TUIs no longer hang
- remove dead code in OnKeyPress
Encoding correctness (garbled CJK across chunk boundaries):
- stateful UTF-8 Decoder in TTLInterpreter.OnData, SerialBridgeServer
rx forwarding, and SessionLogger.Write
Sessions:
- ShellChannel: free proc-thread attribute list, close hProcess,
notify '[ETTerms] shell process exited' in the tab
- SshChannel: surface ErrorOccurred / ShellStream.Closed in the tab;
Write no longer throws into the UI thread on a dead connection
PDU:
- new shared ETTerms.PduCore project replaces the two drifted copies of
PduController (GUI + PduMcp); logging via injected delegates
- batched SNMP GET (GetAllPortsStatus): 12-port poll is 3 UDP
round-trips instead of 36 (StatusView polling + pdu_status tool)
Scripting:
- cap TTL receive buffer at 1MB; skip re-scan in wait when buffer
length unchanged
- merge ScriptRunner.RunAsync/RunGroupAsync; new TtlScript helper
dedups script picking + group-command checks (3 copies -> 1)
Misc:
- ConnectionStore: parse LastUsedUtc with InvariantCulture/RoundtripKind
- version 0.4.0; About changelog; CLAUDE.md notes (intentional group
barrier behavior, SSH.NET reflection resize caveat)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bump the version badge to 0.3.3 and add the v0.3.3 entry to Version History
in both README.md and README.zh-TW.md (terminal input fix). Add the v0.3.3
release note, and include the previously uncommitted v0.3.2 release note.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The terminal's DarkScrollBar derives from Control, which is selectable by
default. Once enough output accumulated to create scrollback, the scrollbar
became enabled and was the only selectable child of the TerminalView
(a ContainerControl). On window re-activation (minimize/restore, click away
and back) WinForms restored focus down the container chain onto the scrollbar,
which has no keyboard handling, so typing/Enter went nowhere until the session
was reopened. This affected both Serial and PowerShell tabs (shared TerminalView),
and only after output appeared — matching the reported symptom.
Make the scrollbar mouse-only: SetStyle(Selectable, false) + TabStop=false, so
it never takes keyboard focus and the TerminalView keeps focus itself, exactly
as it already did when idle (scrollbar disabled).
Bump version to 0.3.3 and add the About changelog entry.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- New left-rail Status view (StatusView.cs) hosting the PDU tab; PDU panel moved out of SettingsView and auto-polls all 12 outlets every 3s on a background thread (no manual Refresh).
- Each outlet row gets a Control button (DataGridViewButtonColumn) that toggles the port via SNMP off the UI thread, re-reads after ~400ms, and resets the grid on disconnect.
- fix(shell): ShellChannel falls back to the user home folder when StartupDirectory no longer exists (avoids CreateProcess 267).
- docs: update ARCHITECTURE / CLAUDE / README / README.zh-TW and About changelog; bump version to 0.3.2.
- Add owner-drawn DarkScrollBar (slim, dark, rounded thumb) to TerminalView; content width excludes the bar so text isn't covered; synced on feed/wheel/resize.
- Support bracketed paste (DEC mode 2004): wrap multi-line paste in ESC[200~..ESC[201~ when the app enables it (PSReadLine/Kiro CLI), so pasted lines aren't each submitted immediately.
- Clear text selection after right-click copy so the user knows it worked.
- Bump version to 0.3.1; rewrite v0.3.0 changelog in plain language and add v0.3.1 entry; update ARCHITECTURE.md / CLAUDE.md.
New ETTerms.PduMcp stdio MCP server lets AI agents (Kiro/Claude CLI)
control SNMP PDU outlets directly. Unlike serial, SNMP is non-exclusive
so it talks to the PDU directly without bridging through the GUI.
Tools: pdu_connect / pdu_list / pdu_set_port / pdu_get_port / pdu_status
/ pdu_power_cycle / pdu_disconnect.
- McpRegistrar now registers both etterms-serial and etterms-pdu in one click
- Settings -> AI MCP shows both server paths
- publish target (PublishMcpServers) bundles both MCP servers
- bump version to 0.3.0, update About changelog, ARCHITECTURE.md, CLAUDE.md
Switch to AutoScaleMode.Dpi (PerMonitorV2) so control sizes scale by the exact DPI ratio, matching point-font rendering and eliminating text/button clipping at 125%/150%. Make toolbar, settings, sidebar buttons and About labels AutoSize; align left tab bar with workspace toolbar (both 40px); About cards now auto-grow and the left column scrolls. ActivityRail cell size is DPI-aware. No version bump.
OnSizeChanged now ignores degenerate sizes (minimized / smaller than one cell), so ConPTY no longer receives a 1x1 size that collapsed full-screen TUIs like Kiro CLI. ScreenBuffer.Resize reflows both the live and saved alt-screen buffers instead of discarding the main-screen backup. TerminalInput.Map sends LF for Shift+Enter (CR for plain Enter) so the shell inserts a newline for multi-line input. Bump version to 0.2.2 and add About changelog entry.
PublishSerialMcp target now inherits the GUI's SelfContained setting, so a --self-contained true publish also produces a runtime-free ETTerms.SerialMcp. Document both publish variants in ARCHITECTURE.md / CLAUDE.md: framework-dependent ETTerms_v{Version}\ and portable ETTerms_v{Version}_portable\ (no .NET runtime install needed).
Add Settings -> AI MCP tab with McpRegistrar to one-click register/remove the Serial MCP server into Claude Code (~/.claude.json) and Kiro (~/.kiro/settings/mcp.json); read-modify-write preserves other servers, atomic write-back. Each card shows a CLI verify command.
Add PublishSerialMcp MSBuild target so a single GUI publish auto-bundles ETTerms.SerialMcp into the \ETTerms.SerialMcp\ subfolder, aligning with McpRegistrar.ResolveServerExe(). Bump version to 0.2.1. Update ARCHITECTURE/CLAUDE/README/README.zh-TW and About changelog.
- About: add v0.2.0 "Beta Version Release" changelog entry.
- MainForm: title bar now shows "ETTerms vX.Y.Z" (drop the word "Version").
- ARCHITECTURE.md + CLAUDE.md: document the publish convention --
output to src\ETTerms\Publish\ETTerms_v{Version}\, main exe renamed to
"ETTerms v{Version}.exe", ETTerms.SerialMcp published into a subfolder.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase 9 (AI integration) complete -- AI agents can send/receive serial
while the user watches live in the GUI, with the GUI as sole COM-port owner.
- ETTerms.SerialMcp: stdio MCP server (net8.0 + ModelContextProtocol SDK)
exposing serial_list / serial_attach / serial_write / serial_read
(waitFor + timeoutMs) / serial_detach; forwards over named pipe.
- GUI SerialBridgeServer (pipe etterms-serial) + SerialBridge endpoint;
SessionPage.WriteFromAi echoes MCP-sourced TX tagged [AI] (magenta).
- App icon: window title bar / taskbar / exe now use Choco_256x256.ico
(embedded via AppAssets); title bar shows ETTerms Version vX.Y.Z.
- About page: large Choco icon (Zoom, no crop).
- Docs: ARCHITECTURE.md + CLAUDE.md mark Phase 9 done; docs/serial-mcp-guide.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
GUI holds the COM port exclusively; ETTerms.SerialMcp becomes a thin client that bridges over a local named pipe (SerialBridgeServer). AI TX/RX flows through the GUI channel so it is visible live in the terminal view. Tools change from open/close to attach/detach.
After finding the keyword, wait requires the receive buffer to stay quiet for ~300ms (no new bytes) and consumes up to the LAST occurrence. This rejects matches on echoed command prompts (e.g. 'SVOS> help') mid-output, preventing the script from racing ahead. Applies to all wait-based loops without per-command markers.
- Add TeraTerm-compatible sprintf2 (C printf formatting into a string var)
- Fix SVOS power-cycle script racing ahead by gating prompt waits behind output-completion markers
- Bump version to 0.1.2; docs and README updates
- Add per-tab Log button: record session output to logs\[name]_yyyyMMdd_HHmmss.log
- Add Log All toolbar button to toggle logging on every open tab at once
- Add drag-to-reorder for top tabs (also rearranges grid layout cells)
- Polish Settings > Terminal: align all input boxes, soften folder browse button
Logs strip ANSI escapes and prefix each line with [yyyy-MM-dd HH:mm:ss.fff].
LogName per channel: Shell=ShellType, Serial=PortName, SSH=user@host.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>