Files
ETTerms/CLAUDE.md
T

24 KiB
Raw Permalink Blame History

CLAUDE.md — ETTerms

給 Claude 的專案記憶與指令入口。詳細架構見 ARCHITECTURE.md

專案簡介

ETTerms 是一個 C# .NET 8 WinForms 的原生 Windows 終端機工作台,主打 SSHSerial Port 兩種連線,並沿用 / 擴充 MyTeraTerm 的 TTL 腳本引擎做自動化。UI 參考 KKTermActivity Rail + 分頁工作區 + Saved Connections sidebar)。單機、無雲、無登入系統。

開發策略:GUI 先行 — 先把視窗外殼 + 分頁 + 連線清單做出來,再逐步補 Serial → SSH → VT100 → 腳本引擎 → Settings/About → PDU/Shell/SFTP。

進度: Phase 15 、Phase 6 TTL 引擎 + Group 同步,SSH 待驗收)、Phase 7 Settings/About)、Phase 8 PDU + Shell/ConPTY + SFTP + Settings 擴充)、Phase 9 Serial MCP serverGUI 持有 COM portMCP 經本機 named pipe 橋接AI 收發的資料即時以 [AI] 標色顯示在 GUI)、Phase 10 v0.6.0)內建 AI Assistant(見下)。打包待指示。

v0.7.2 高 DPI125%/150%)全面修正 —— 字型以點數指定會隨 DPI 放大、寫死像素不會,導致 user 機器(筆電常見 125%/150%)上 SessionPage 的 Log/Script/Stop 被截字、150% 時工具列 AI Chat 被裁、Quick Connect 對話框疊字。根因MainFormAutoScaleMode.Dpi 只在 Form 初始化當下對「已存在」的控制項縮放一次,本專案 UI 幾乎全是執行期才 new 的(SessionPage 開分頁才建),完全吃不到(實測 125% 下 sidebar 250px 原封不動)。作法(1) Theme.csDpi() 擴充(px × DeviceDpi/96,同 ActivityRail.ItemSize 的既有做法),全 app ~70 處裸像素尺寸(sidebar/工具列/tab 列/Settings 輸入框/表格/Ctrl+F 搜尋列/DarkScrollBar 寬)全部包上;(2) 會換字的按鈕(⏺ Log↔Logging、⏺ Log All↔Logging All)改 TextRenderer.MeasureText 量最長字串取寬(SessionPage.BarButtonWidth)/AutoSize(3) 多行說明 Label 改 AutoSize = true 不再固定框;(4) 絕對座標對話框(Dialogs/)在 DarkDialog 基底加 ApplyDpiScale()(建構子最後 Control.Scale(DeviceDpi/96f) 一次縮放全樹);(5) MainFormAutoScaleMode.None + ClientSize/MinimumSize 手動 Dpi()(明確自己管,避免未來 .NET 行為改變造成雙重縮放)。⚠️ 新增 UI 的鐵則:任何寫死像素尺寸都要 this.Dpi(n)100% 看起來正常不代表對(Dpi() 在 96 DPI 是恆等)。已知限制:執行中改系統縮放需重啟。通用規範已沉淀到 create-architecture skill 的「WinApp DPI Scaling Pattern」。

v0.7.1 新增 TTL 指令 sendlnretry '文字' '確認關鍵字' [最多送出次數]TTLInterpreter.SendLnRetry + WaitConfirm)——送出後等確認關鍵字,沒等到就重送;次數省略 = 無限重送,命中 result=1、用完次數 result=0繼續執行(不中止腳本)。動機:裝置開機、console 剛被 shell 接手的瞬間會丟棄輸入(tty 重開 / termios flush),sendln 送出的整行無聲消失(裝置不回顯、不執行),後面的 wait 就永遠卡住;這是機率性的,pause 只能調機率、無法根治(實測 45 輪 power-cycle 中 3 輪中招,且中招時間點與成功時完全重疊)。為何需要新指令而非用 wait 重試:單字串 wait 逾時是 throw 中止腳本(刻意設計,見下方「注意事項」),TeraTerm 的 waitif result = 0 then goto retry 重送寫法在 ETTerms 寫不出來。語意:每次送出前清空 _recv(確保比對到的是這次送出的回應);命中只消費到第一次出現處,後續輸出留給接下來的 wait;刻意不套 SettleAndConsume 的 settle(關鍵字出現本身就證明裝置收到了);每次等待逾時 timeout/mtimeout 有設就用設定值、沒設預設 3 秒(此處 0=無限等於永不重送,故不沿用 wait 的 0=無限)。⚠️ 確認關鍵字要挑「命令真的有跑」的輸出,不要挑指令回顯——tty echo 由核心產生,不保證命令被 shell 讀走。文件:docs/ttl-script-reference.md

v0.7.0 AI Chat 改用 WebView2 渲染(真氣泡 + Markdown + thinking 動畫泡)。訊息區從 RichTextBox 換成 WebView2user 右泡 / AI 左泡、AI 回覆走 Markdig markdown→HTML(程式碼區塊/表格/清單)、送出後顯示會動的 thinking「…」泡(AgentHost.Status "thinking"showThinking(),收到 AssistantTexthideThinking() 再加 AI 泡)。HTML 模板全內嵌於 Ai/ChatHtml.csNavigateToString,無外部依賴),C# 經 ExecuteScriptAsync 呼叫 JS 函式;WebView2 async 初始化,就緒前的呼叫先入 _pending 佇列、NavigationCompleted 後 flush。使用者資料夾 %LocalAppData%\ETTerms\WebView2(避開 Program Files 唯讀)。底部控制列(輸入框/模型下拉/Send)仍 WinForms。新增 NuGet Microsoft.Web.WebView2 + Markdig;依賴 WebView2 RuntimeWin11 內建,缺時 hint 顯示錯誤)。⚠️ publish 要確認 WebView2 nativeruntimes/win-x64/native/WebView2Loader.dll)有進產物工具呼叫上限可設定AppSettings.AiMaxToolRounds,Settings → AI Assistant,AgentHost 建構子傳入):0 = 無上限(自動化長跑;每輪燒 token,聊天視窗 Send 鈕在執行中變 Stop,經 CancellationToken 中止),預設 30。

v0.6.0 內建 AI AssistantPhase 10 — 不經 Claude / KiroGUI 內建 AI 聊天分頁,自然語言驅動 serial + PDU。AI 是 Workspace 的一種 pane(工具列 ✨ AI Chat 開啟,WorkspaceView.Session 抽象化為可容納 SessionPageAiChatViewContent),可用 Layout 與 serial 分頁並排同時用(像 Claude/Kiro);AI 分頁無 Group/Log/Script。UI 走乾淨逐字稿風user 靠右 accent、AI 靠左、工具灰字、thinking 收進 Send 按鈕不洗版;與終端機美學一致,非氣泡——真氣泡+Markdown 的 WebView2 版列 v0.7.0)。模型下拉(右下角)打端點 /v1/models 列可選模型、即時切換並記住;Settings 只留 Base URL / API Key / 系統提示詞,不再設 modelconfigured 只看 Base URL)。BYO endpointSettings → AI Assistant 填 Base URL / Model / API Key(任意 OpenAI 相容 gateway:本機 Ollama、LiteLLM、公司 gateway、OpenAI…),預設全空白=功能停用🚫 發佈版不含任何私人端點API key 存 Windows Credential ManagerETTerms/AiApiKey)、Base URL/Model 存 settings.json,程式碼範例一律 localhost/假 IP。架構(in-process,不經 MCPAi/OpenAiChatClient(極簡 OpenAI 相容 /chat/completionsHttpClient 非串流)+ Ai/AgentHost(手寫 agent looptool_calls→執行→role=tool 餵回→迴圈上限 8 輪)+ Ai/AiToolsserial list/attach/write/read 經 SerialBridge——與 MCP 同一路徑、AI 的 TX 照樣 [AI] 標色顯示在終端機;PDU connect/status/set_port/power_cycle 經 ETTerms.PduCore)。安全:破壞性 PDU 動作(關插座 / power-cycle)一律 AiTools.ConfirmAsync → GUI MessageBox(預設 No)確認,AI 不能自己斷電;每筆工具呼叫寫 AppLogger([AI tool] …)。刻意不引入 Microsoft.Extensions.AI(手寫 client+loop,依賴最小、對任意 gateway 相容性自己掌控)。既有 SerialMcp/PduMcpSettings → AI MCP不受影響,繼續服務外部 AI CLI;兩者是「內建 agentin-processvs 外部 AIMCP 跨行程)」的分工。新增 src/ETTerms/Ai/3 檔)+ App/AiChatView.csActivityRailAi viewSettingsView 加 AI Assistant 分頁,AppSettingsAiBaseUrl/AiModel/AiSystemPrompt

v0.5.0 搜尋 / 關鍵字警示 / TTL 大擴充。(1) Ctrl+F scrollback 搜尋TerminalView 內建搜尋列(Enter 往上找、Shift+Enter 往下、F3/Esc),全部命中黃底、目前命中橘底;命中以「絕對行號 = ScreenBuffer.DroppedLines + abs」錨定,環形緩衝丟舊行不漂移。(2) 關鍵字高亮 + 分頁警示AppSettings.KeywordRulesKeywordRule{Text,Enabled} + 全域開關),Settings 新 Highlight 分頁可增刪/勾選;TerminalView 每次重繪只掃可見行標紅底(不分大小寫),Feed 路徑用獨立 Decoder+去 ANSI 偵測觸發 KeywordAlert(每關鍵字 2s 冷卻)→ SessionPageWorkspaceView非 active 分頁的圓點標紅、切過去自動清除。(3) TTL 對齊 TeraTerm — 新 TtlExpression 運算式解析器(括號/邏輯/比較/十六進位 0x/$,失敗退回 legacy 規則相容舊腳本);新增控制流 goto/call(行內執行,迴圈內可用)/return/for-next/do-loop/until-enduntil/break/continue/end/exit/include/mpause、等待 waitln/waitregex/recvln/wait 多字串(TeraTerm 語意:逾時 result=0 繼續)/mtimeout、字串 strlen/strcompare/strconcat/strcopy/strinsert/strremove/strmatch/strscan/strreplace/strtrim/strsplit/strjoin/tolower/toupper/str2int/int2str/code2str/str2code/sprintf(→inputstr)/expandenv、檔案 fileopen/filereadln(result=1 是 EOF)/filewrite(ln)/fileclose/filecreate/filedelete/filesearch/basename/dirname/makepath/foldercreate/folderdelete/foldersearch/getdir/setdir、雜項 beep/getdate/gettime(strftime 子集)/getenv/setenv/random/exec/getver/getttdir/uptime/ifdefined/clipb2var/var2clipb/inputbox/yesnobox/crc32/checksum8/16/32/dispstr、serial 專用 sendbreak/setbaud/setdtr/setrts/sendfileSerialChannel 新增對應方法);單行 if <expr> <statement> 支援;Preprocess 引號內 ; 不再被當註解;系統變數 inputstr/matchstr/groupmatchstr1-9_vars 改大小寫不敏感;單字串 wait 保留 ETTerms settle+逾時中止語意(勿改),多字串才是 TeraTerm 語意。SessionPagerunner.Outputtrace[wait]/>>/錯誤)以灰色 echo 進終端機,可由 Settings → Terminal 的 ShowScriptTrace 開關關閉dispstr 走獨立的 Display 事件一律顯示。灰色訊息只進畫面 buffer——不進 ⏺ Log 側錄、不進 AI bridge、不送裝置(機台原始 log 乾淨)。指令表+範例:docs/ttl-script-reference.md(前段 ETTerms 獨有、後段與 TeraTerm 共有)。

v0.4.0 效能 / 穩定性總整理(來自全 codebase 審視)。(1) 終端機繪製熱路徑去配置TerminalView 快取 4 種 Font 變體(Bold/Underline 組合)與單一可變色 SolidBrush,run 合併時每 cell 顏色只解析一次,Dispose 收掉 GDI 資源;(2) scrollback 改環形緩衝ScreenBufferList+RemoveRange(0,…)(滿了每行 O(n) 搬移)改 O(1) ring buffer(3) UTF-8 跨 chunk 亂碼修正(3 處)TTLInterpreter.OnDataSerialBridgeServer rx 轉發、SessionLogger.Write 改用 stateful Decoder(比照 AnsiParser 原本的正確做法);(4) PDU SNMP 批次查詢 — 新共用專案 src/ETTerms.PduCore/ 取代 GUI 與 PduMcp 兩份複製的 PduControllerlog 走建構子委派),新增 GetAllPortsStatus() 一個 SNMP GET 帶 12 個 varbind12 port 輪詢從 36 個 UDP 來回縮成 3 個(StatusView 與 pdu_status 都改用);(5) ShellChannel 資源修正DeleteProcThreadAttributeList+FreeHGlobal 釋放 attribute list、CloseHandle(pi.hProcess)shell 自行 exit 時顯示灰色 [ETTerms] shell process exited 提示;(6) SSH 斷線可見 — 訂 ErrorOccurred/ShellStream.Closed 顯示提示,Write 例外不再炸 UI thread(7) 終端機行為 — 新輸出只在已貼底時跟隨(看歷史不被拉回底部)、alt screen 滾輪轉方向鍵(vim/htop 可滾)、回應 DSR ESC[6n/ESC[5n 與 DA ESC[cTUI 查游標位置不再卡住);(8) TTL_recv 上限 1MB、wait 輪詢長度沒變不重掃;(9) 去重複ScriptRunner 兩個 Run 合併、TtlScript 共用選檔/group 指令檢查(SessionPage/WorkspaceView 三份流程收斂)、ConnectionStore 讀取改 InvariantCulture+RoundtripKind。註:group waitall 一個成員失敗其他成員停在 barrier 是刻意行為(使用者要求整組停下),勿「修」。

v0.3.2 (1) 新增左側 Status rail view — 位於 Terminal 與 Settings 之間(圖示 ,新增 ActivityRail.RailView.Status 列舉與 Items),獨立 App/StatusView.cs,沿用 SettingsView 的自繪 tab strip + panel 切換風格(避免 TabControl 白邊);MainForm_statusView 欄位、佈局與 rail 切換可見性。目前只有 PDU 分頁,未來會再加分頁(MakeTab(...) 即可擴充)。(2) PDU 搬到 Status 並改自動輪詢 — PDU 從 SettingsView 移到 StatusView移除手動 Refresh 按鈕,連線成功後以 System.Threading.Timerperiod 3000ms)在背景執行緒讀 SNMP、再 BeginInvoke 回 UI 更新表格(不卡 UI);Interlocked 旗標防止前一輪未讀完就重入;斷線 / 控制項 Dispose 時自動停掉 timer 與 PduController;表格下方顯示「last update HH:mm:ss」。SettingsView 移除 BuildPduTab/RefreshPduGridETTerms.Scripting.Pdu import,現只剩 Terminal / AI MCP 兩分頁。(2b) PDU 分頁加手動開關鈕 — 狀態表格新增 Control 欄(DataGridViewButtonColumn),每個 Port 一顆鈕,文字隨狀態切換(ON→「Turn OFF」、OFF→「Turn ON」、未知→「—」);點擊在背景執行緒呼叫 PduController.SetPortOn/SetPortOff(不卡 UI),等 ~400ms 後回讀刷新整表,失敗跳 MessageBox;未連線點擊會提示先 Connect,斷線時清空表格避免顯示過時狀態。(3) 修 ShellChannel 啟動目錄 fallback — 本機 Shell 的 StartupDirectory 若已不存在(外接碟拔除 / 資料夾被刪)會 CreateProcess failed: 267 (ERROR_DIRECTORY);改為「為空 Directory.Exists 為 false」即 fallback 到使用者家目錄(Environment.SpecialFolder.UserProfile,隨登入者變動,例如 C:\Users\et_wen),與 Windows PowerShell 行為一致。

v0.3.1 終端機體驗修正(皆在 src/ETTerms/Terminal/)。(1) 深色垂直捲軸 — 新增自繪 DarkScrollBar(細長、無箭頭、圓角滑塊,配合 KKTerm 深色主題),TerminalView 右側 Dock=Right 掛上,ContentWidth 扣掉捲軸寬避免文字被蓋,UpdateScrollBar()Feed / 滾輪 / resize 時同步滑塊範圍與位置,滾輪與拖曳互通。(2) 多行貼上修正AnsiParser 新增 BracketedPasteDEC mode 2004);TerminalView.Paste() 在對方啟用 bracketed pastePSReadLine / Kiro CLI 等)時以 ESC[200~ … ESC[201~ 包夾整段,視為「單次貼上」而非逐行 Enter 立即送出;未啟用時退回原本逐字送出。(3) 右鍵複製清反白 — 右鍵複製後清掉 _hasSel 並重繪,讓使用者知道已複製。

v0.3.0 新增 ETTerms.PduMcpstdio MCP server):讓 AI agent 直接控制 SNMP PDU 插座。與 serial 不同,PDU 走 SNMP(UDP) 非獨佔,故 PduMcp 直接打 SNMP、不經 GUI 橋接(內含精簡版 PduControllerOID 邏輯複製自 GUI 版,log 走 stderr),GUI 不開著也能用。工具:pdu_connect / pdu_list / pdu_set_port / pdu_get_port / pdu_status / pdu_power_cycle / pdu_disconnect,回傳統一 {ok, result/error} JSON;連線狀態以行程內單例 PduRegistryIP→controller)保存。McpRegistrar 改為多 serverSettings → AI MCP 一鍵同時註冊 etterms-serialetterms-pduETTerms.csproj 的 publish target 更名 PublishMcpServersGUI publish 會把兩個 MCP 各自帶到 \ETTerms.SerialMcp\\ETTerms.PduMcp\ 子資料夾。

v0.2.1 新增 GUI Settings → AI MCP 分頁(McpRegistrar):對 Claude Code~/.claude.json)與 Kiro~/.kiro/settings/mcp.json一鍵 Setup / Remove 註冊 etterms-serial MCP serverread-modify-write 保留檔內其他設定、原子寫回;卡片附 CLI 驗證指令。ETTerms.csproj 加 publish targetAfterTargets=Publish),GUI publish 會自動把 MCP server 帶到子資料夾,與 McpRegistrar.ResolveServerExe() 解析路徑對齊。

v0.2.0 Phase 9 完成 — ETTerms.SerialMcpstdio MCP server+ GUI SerialBridgeServernamed pipe \\.\pipe\etterms-serial)上線,提供 serial_list / serial_attach / serial_write / serial_read / serial_detach 五個工具,AI 的 TX 在 GUI 以 [AI] 標色即時 echo;視窗 / 工作列 / About 改用 Choco 圖示,標題列顯示版本號。見 docs/serial-mcp-guide.md

v0.1.2 新增 sprintf2TeraTerm 相容 C printf 格式化);wait 改為命中關鍵字後須等裝置安靜(SettleMs 預設 300ms)才接受並取「最後一次」出現,排除輸出中途的指令回顯(避免腳本搶跑)。

技術棧

  • UI C# .NET 8 WinFormsnet8.0-windows, UseWindowsForms, Nullable=enable
  • SSH SSH.NETRenci.SshNet)— Shell + SFTP
  • Serial System.IO.Ports
  • Local Shell Windows ConPTYCreatePseudoConsole)— PowerShell / Bash / Cmd
  • 終端機渲染: 自繪 VT100 / ANSI 控制項(owner-drawn
  • 腳本: TTLInterpreter(從 For_AI/MyTeraTerm 移植,改驅動 ISessionChannel
  • 連線儲存: SQLiteMicrosoft.Data.Sqlite
  • 密碼儲存: Windows Credential Manager(不落地明碼)
  • PDU SnmpSharpNetiPoMan II/III via SNMP
  • 內建 AI Assistantv0.6.0): 手寫 OpenAI 相容 clientHttpClient+ agent loopin-process 直呼 serial/PDU 工具;BYO endpointProvider 預設空白,發佈版不含端點)。src/ETTerms/Ai/
  • AI / MCP(選用): 兩個 stdio MCP server(官方 C# SDK ModelContextProtocol)。ETTerms.SerialMcp不自己開 COM port,經本機 named pipe 接上 GUI 持有的 serial sessionAI 的 TX/RX 同步顯示在 GUI。ETTerms.PduMcpv0.3.0):直接打 SNMP 控制 PDU 插座,非獨佔故不需 GUI 在跑。皆暴露給 Kiro CLI / Claude CLI
  • 設定持久化: JSON → %LocalAppData%\ETTerms\settings.json

常用指令

# 建置 / 執行
dotnet build
dotnet run --project src\ETTerms\ETTerms.csproj

# 加套件
dotnet add src\ETTerms package SSH.NET

# 打包(見「Publish / 打包慣例」)—— 兩種版本都產出,輸出到 src\ETTerms\Publish\
# GUI publish 會「自動」把 ETTerms.SerialMcp 與 ETTerms.PduMcp 一併發到各自的子資料夾
# ETTerms.csproj 的 PublishMcpServers targetAfterTargets=Publish),且 MCP 跟隨 GUI 的 self-contained 設定。
$ver = ([regex]::Match((Get-Content src\ETTerms\ETTerms.csproj -Raw), '<Version>([^<]+)</Version>')).Groups[1].Value

# A. 框架相依版(需目標機已裝 .NET 8 Desktop Runtime)→ ETTerms_v{Version}\
$root = "src\ETTerms\Publish\ETTerms_v$ver"
dotnet publish src\ETTerms\ETTerms.csproj -c Release -r win-x64 --self-contained false -o $root
Rename-Item (Join-Path $root "ETTerms.exe") "ETTerms v$ver.exe"

# B. Portable 免安裝版(runtime 內含,免裝、免管理員)→ ETTerms_v{Version}_portable\
$proot = "src\ETTerms\Publish\ETTerms_v${ver}_portable"
dotnet publish src\ETTerms\ETTerms.csproj -c Release -r win-x64 --self-contained true -o $proot
Rename-Item (Join-Path $proot "ETTerms.exe") "ETTerms v$ver.exe"

# 註冊 Serial MCP server(給 AI agent 操作 serial
# 推薦:GUI Settings → AI MCP 分頁,對 Claude Code / Kiro 按 Setup 一鍵註冊(McpRegistrar)。
# 或手動 CLI
kiro-cli mcp add --name serial --command dotnet --args "run --project src\ETTerms.SerialMcp\ETTerms.SerialMcp.csproj"

開發慣例

  • 命名: PascalCase 類別 / 方法,_camelCase 私有欄位;檔名 = 類別名。
  • Publish / 打包: 輸出到 src\ETTerms\Publish\;主 exe 改名為 ETTerms v{Version}.exeETTerms.SerialMcpETTerms.PduMcp 一併發到其下 ETTerms.SerialMcp\ETTerms.PduMcp\ 子資料夾(且跟隨 GUI 的 self-contained 設定)。兩種版本都產出:框架相依 ETTerms_v{Version}\--self-contained false,需裝 .NET 8 Desktop Runtime)+ portable 免安裝 ETTerms_v{Version}_portable\--self-contained trueruntime 內含)。不要開 trimmingWinForms 反射)。詳見 ARCHITECTURE.md
  • 分層: UIApp/)只認 ISessionChannel 抽象,不直接相依 SSH.NET / SerialPort。
  • 執行緒: channel I/O 在背景;所有 UI 更新一律 Control.Invoke 回 UI thread。
  • commit 走 Conventional Commitsfeat: / fix: / refactor: …)。
  • 參考專案不改: For_AI/KKTerm-mainFor_AI/MyTeraTerm 只讀對照,不在 repo 內修改。

注意事項 / 禁止事項

  • 🚫 密碼絕不寫進 SQLite / 程式碼 / log,一律走 Windows Credential Manager。
  • 🚫 內建 AIPhase 10)採 BYO endpointProviderBase URL / API Key / Model預設空白=功能停用;開發者私人的 LLM 端點 / API key 絕不寫進程式碼、預設值、文件範例、publish 產物——只存在開發者本機的 settings.json / Credential Manager。文件與 UI 範例一律用 http://localhost:11434/v1 或占位符。發佈前驗收:publish 資料夾 grep 不到任何私人 IP / 網域 / key。
  • 🚫 不嵌 TeraTerm、不依賴 com0com —— ETTerms 走全原生(這是與舊版 MyTeraTerm 的關鍵差異)。
  • 🚫 不要把 For_AI/ 內容 commit 進 git。
  • ⚠️ Serial COM port 同時只能被一個 session 開啟,開啟前檢查可用性。
  • ⚠️ COM port 由 GUI 唯一持有Serial MCP serverETTerms.SerialMcp不自己開 port,而是經本機 named pipe 接上 GUI 已開啟的 serial session 來收發。AI 操作前該 port 必須已在 GUI 開啟(pipe 找不到對應 session 就回錯誤)。
  • ⚠️ VT 相容性以常見情境(VT100 / 常見 ANSI)為主,冷門 escape 後補,不阻塞 GUI 進度。
  • ⚠️ 本專案無伺服端祕密 / 無 DB 密碼 / 無 EC2 / 無 VM,因此不套用 AWS / VirtualBox 部署流程。
  • ⚠️ Group 同步指令(waitall / sendlnall / sendlngroup只能在 Run Group 模式使用;▶ Script▶ Run All 須拒絕含這些指令的腳本。
  • ⚠️ Group waitall 的 barrier 行為:一個成員失敗/停止,其他成員會停在 barrier 等 —— 這是刻意設計(整組一起停下來),不是 bug,勿改成 RemoveParticipant。
  • ⚠️ SshChannel.Resize 用反射挖 SSH.NET 私有 _channel 呼叫 SendWindowChangeRequest(該 API 未公開)。升級 SSH.NET 版本時必須驗證 resize 仍有效(連上後拉視窗大小看遠端 TUI 是否跟著變)。

資料夾用途

  • src/ETTerms/ — 主應用程式(WinForms 視窗外殼 + 連線 / 終端機 / 腳本引擎)。內含 Ai/v0.6.0 內建 AI AssistantOpenAiChatClient + AgentHost + AiTools)與 App/AiChatView.cs
  • src/ETTerms.SerialMcp/ stdio MCP server(給 AI agent 收發 serial)。獨立行程,但不直接開 COM port:經本機 named pipe 連到 GUI 的 SerialBridgeServer,由 GUI 代為讀寫實體 portnet8.0 console + ModelContextProtocol SDK。
  • src/ETTerms.PduMcp/ stdio MCP server(給 AI agent 控制 SNMP PDUv0.3.0)。獨立行程,直接打 SNMP,不經 GUI、GUI 不開著也能用;net8.0 console + ModelContextProtocolPDU 邏輯用 ETTerms.PduCore
  • src/ETTerms.PduCore/ PDU SNMP 控制共用庫(v0.4.0)。GUI 與 PduMcp 共用的唯一 PduController(先前兩份複製已移除);診斷 log 走建構子注入委派(GUI→AppLogger、MCP→stderr);含批次查詢 GetAllPortsStatus()
  • For_AI/ — AI 協作素材與參考專案KKTerm-main UI 參考、MyTeraTerm Script 參考)。整個資料夾 gitignored,僅供開發對照。
  • 本專案secret/ 資料夾:沒有伺服端祕密 / DB 密碼 / compile-time secret,連線密碼一律走 Windows Credential Manager。