diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 438e6d3..f54a346 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -480,13 +480,56 @@ cd F:\10_AI\ETTerms dotnet build dotnet run --project src\ETTerms\ETTerms.csproj -# 5. 打包(後期 Phase) -dotnet publish src\ETTerms\ETTerms.csproj -c Release -r win-x64 --self-contained false +# 5. 打包(見下方「Publish / 打包慣例」) +dotnet publish src\ETTerms\ETTerms.csproj -c Release -r win-x64 --self-contained false ` + -o src\ETTerms\Publish\ETTerms_v # 後續可用 Inno Setup / MSIX 做安裝程式 ``` --- +## Publish / 打包慣例 + +> 每次發 Release 都依此規則產出,方便辨識版本與一併攜帶 MCP server。 + +**輸出位置(固定):** `src\ETTerms\Publish\ETTerms_v{Version}\` +- `{Version}` 取自 `src\ETTerms\ETTerms.csproj` 的 ``(例:`0.2.0`)。 +- 資料夾命名:`ETTerms_v{Version}`(前綴 `v`,例:`ETTerms_v0.2.0`)。 +- `Publish/` 已 gitignore(`publish/`),**不入 git**。 + +**內容結構:** +``` +ETTerms_v0.2.0\ +├── ETTerms v0.2.0.exe # 主程式 apphost,改名為「ETTerms v{Version}.exe」 +├── ETTerms.dll + 各相依 dll # SSH.NET / SQLite / SnmpSharpNet / System.IO.Ports … +└── ETTerms.SerialMcp\ # Serial MCP server,獨立發佈到子資料夾(相依 dll 與 GUI 隔離) + ├── ETTerms.SerialMcp.exe + └── ETTerms.SerialMcp.dll + 相依 +``` + +**規則:** +1. **GUI 與 MCP 都發佈**:主程式發到 `ETTerms_v{Version}\`,`ETTerms.SerialMcp` 發到其下 **`ETTerms.SerialMcp\` 子資料夾**(兩者相依 dll 不互相覆蓋)。 +2. **主 exe 改名**:`dotnet publish` 產生的 `ETTerms.exe` 重新命名為 **`ETTerms v{Version}.exe`**。 + - 可安全改名:.NET apphost 內部記錄要載入的 `ETTerms.dll`,**不靠自身檔名**,改名後仍正常啟動。 +3. **框架相依**:`--self-contained false -r win-x64`(目標機需已裝 .NET 8 Desktop Runtime)。 + +**PowerShell 範例:** +```powershell +$ver = ([regex]::Match((Get-Content src\ETTerms\ETTerms.csproj -Raw), '([^<]+)')).Groups[1].Value +$root = "src\ETTerms\Publish\ETTerms_v$ver" +if (Test-Path $root) { Remove-Item $root -Recurse -Force } + +# 1) GUI +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" + +# 2) Serial MCP server → 子資料夾 +dotnet publish src\ETTerms.SerialMcp\ETTerms.SerialMcp.csproj -c Release -r win-x64 --self-contained false ` + -o (Join-Path $root "ETTerms.SerialMcp") +``` + +--- + ## Development Phases > 依使用者要求「**前面先把 GUI 做出來,後面再慢慢補功能**」排序: diff --git a/CLAUDE.md b/CLAUDE.md index 20f8ce8..8d7f434 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -38,8 +38,12 @@ dotnet run --project src\ETTerms\ETTerms.csproj # 加套件 dotnet add src\ETTerms package SSH.NET -# 打包 -dotnet publish src\ETTerms\ETTerms.csproj -c Release -r win-x64 --self-contained false +# 打包(見「Publish / 打包慣例」,輸出固定到 src\ETTerms\Publish\ETTerms_v{Version}\) +$ver = ([regex]::Match((Get-Content src\ETTerms\ETTerms.csproj -Raw), '([^<]+)')).Groups[1].Value +$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" +dotnet publish src\ETTerms.SerialMcp\ETTerms.SerialMcp.csproj -c Release -r win-x64 --self-contained false -o (Join-Path $root "ETTerms.SerialMcp") # 註冊 Serial MCP server(給 AI agent 操作 serial) kiro-cli mcp add --name serial --command dotnet --args "run --project src\ETTerms.SerialMcp\ETTerms.SerialMcp.csproj" @@ -48,6 +52,7 @@ kiro-cli mcp add --name serial --command dotnet --args "run --project src\ETTerm ## 開發慣例 - **命名:** PascalCase 類別 / 方法,`_camelCase` 私有欄位;檔名 = 類別名。 +- **Publish / 打包:** 固定輸出到 `src\ETTerms\Publish\ETTerms_v{Version}\`(`{Version}` 取自 csproj ``);主 exe 改名為 `ETTerms v{Version}.exe`;`ETTerms.SerialMcp` 一併發到其下 `ETTerms.SerialMcp\` 子資料夾。框架相依(`--self-contained false -r win-x64`)。詳見 [ARCHITECTURE.md](ARCHITECTURE.md#publish--打包慣例)。 - **分層:** UI(`App/`)只認 `ISessionChannel` 抽象,不直接相依 SSH.NET / SerialPort。 - **執行緒:** channel I/O 在背景;所有 UI 更新一律 `Control.Invoke` 回 UI thread。 - **commit:** 走 Conventional Commits(`feat:` / `fix:` / `refactor:` …)。 diff --git a/src/ETTerms/App/AboutView.cs b/src/ETTerms/App/AboutView.cs index 49c70e7..f46bd8b 100644 --- a/src/ETTerms/App/AboutView.cs +++ b/src/ETTerms/App/AboutView.cs @@ -177,6 +177,16 @@ public sealed class AboutView : UserControl private static readonly ChangelogEntry[] Changelog = [ + new("0.2.0", new DateOnly(2026, 6, 4), "Beta Version Release", + [ + "Phase 9: Serial MCP server — AI agents can send/receive serial while you watch live in the GUI.", + "GUI is the sole COM-port owner; the MCP server bridges over a local named pipe (never opens the port itself).", + "MCP tools: serial_list / serial_attach / serial_write / serial_read / serial_detach.", + "AI-sourced output is echoed into the terminal tagged [AI] so you see exactly what the AI sees.", + "New app icon for the window title bar, taskbar and executable; version now shown in the title bar.", + "About page now displays the app icon.", + "Beta Version: expect bugs and missing features. Feedback welcome!", + ]), new("0.1.0", new DateOnly(2026, 6, 3), "Initial Release", [ "Beta Version: expect bugs and missing features. Feedback welcome!", diff --git a/src/ETTerms/App/MainForm.cs b/src/ETTerms/App/MainForm.cs index f754f7d..ea13e27 100644 --- a/src/ETTerms/App/MainForm.cs +++ b/src/ETTerms/App/MainForm.cs @@ -39,7 +39,7 @@ public partial class MainForm : Form var v = Assembly.GetExecutingAssembly().GetName().Version; var versionStr = v != null ? $"{v.Major}.{v.Minor}.{v.Build}" : "0.1.0"; - Text = $"ETTerms Version v{versionStr}"; + Text = $"ETTerms v{versionStr}"; } private void BuildLayout()