## HTML Transform HTML Transform 是 prototype evidence 工具。現行 MVP 只做兩件事: - `doctor`:檢查執行 `scan` 需要的前置條件。 - `scan`:讀取 HTML prototype、prototype guide 與 backend API docs,產生瀏覽器證據、頁面級 UI Contract 與 implementation contract。 - `app-map.json`:推論每個 prototype 的頁面角色、layout 使用策略、API 對應、維護頁建議範本,並用 `prototype/*.md` 的人工 domain guide 輔助補上舊系統對照。 不提供 `plan`、`run`、`diff`、`verify`、`go`、`status`。這些舊骨架已移除,避免把尚未完成的自動化流程誤認成可用功能。 ## MVP 範圍 `scan` 會執行: ```text Stage 1 Capture Stage 3-lite Page Contract Stage 4-lite Contract Validation API Catalog Maintenance Contract ``` Stage 2 decomposition 不執行。現有 prototype 主要是後台系統頁面,重點是表單、查詢條件、表格、actions 與資訊架構;切 region screenshot 對 MVP 價值不高。 目前沒有 Codex slash command。也就是說,在 repo 根目錄輸入 `/scan` 不會自動執行本工具。 ## 指令 在 `packages/html-transform` 目錄內: ```bash node src/cli.js doctor node src/cli.js scan ``` 在 repo 根目錄: ```bash node packages/html-transform/src/cli.js doctor node packages/html-transform/src/cli.js scan ``` 若要在根目錄用簡短指令,建議由根目錄 `package.json` 包一層: ```json { "scripts": { "scan": "node packages/html-transform/src/cli.js doctor && node packages/html-transform/src/cli.js scan" } } ``` 之後即可執行: ```bash pnpm scan ``` ## 前置需求 需要 Node.js 20 以上。 ```bash node --version pnpm --version ``` 安裝相依套件: ```bash pnpm install ``` [playwright](https://playwright.dev/agent-cli/installation) 確認 `playwright-cli` 可用: ```bash pnpm --filter html-transform exec playwright-cli --version ``` 若環境還沒有 Chromium: ```bash HOME=/tmp \ XDG_CACHE_HOME=/tmp \ PLAYWRIGHT_DAEMON_SESSION_DIR=/tmp/ms-playwright/daemon \ pnpm --filter html-transform exec playwright-cli install-browser chromium ``` 若是在受限制環境中執行(例如 home directory 唯讀、sandbox 不允許寫入 `~/.cache`),建議同時指定: ```bash HOME=/tmp XDG_CACHE_HOME=/tmp PLAYWRIGHT_DAEMON_SESSION_DIR=/tmp/ms-playwright/daemon PLAYWRIGHT_BROWSERS_PATH=/tmp/ms-playwright ``` 這樣 Playwright 的 browser、cache 與 daemon session 都會寫到可寫目錄。 ## 設定檔 設定檔不是工具執行的絕對必要條件;沒有設定檔時,工具會使用內建預設並讀取: ```text packages/prototype/ ``` 本 repo 的 HTML prototype 位於根目錄 `./prototype`,不是 `./packages/prototype`。因此從 repo 根目錄執行 `node packages/html-transform/src/cli.js scan` 時,需要根目錄 `ht.config.mjs` 覆寫 `prototype` 路徑。 本 repo 根目錄目前使用最小設定: ```js export default { prototype: "./prototype", }; ``` `scan` 目前使用: - `prototype`:HTML prototype 與 `prototype/*.md` domain guide 來源。 - `backendDocs`:backend API markdown / OpenAPI JSON/YAML docs 來源,預設 `./apps/backend`。 本 repo 的 `backendDocs` 使用預設值即可。若其他專案的 backend docs 不在 `./apps/backend`,可明確指定: ```js export default { prototype: "./prototype", backendDocs: "./docs/backend", }; ``` 若要同時讀取多個 backend docs 來源,或混用 markdown 與 OpenAPI JSON/YAML,可使用陣列: ```js export default { prototype: "./prototype", backendDocs: ["./apps/backend", "./docs/openapi"], }; ``` 若只有 prototype、沒有 backend docs,可只指定 prototype: ```js export default { prototype: "./prototype", }; ``` 若 `backendDocs` 目錄不存在或沒有 markdown/OpenAPI 文件,`scan` 仍會完成,只是 `.ht/api-catalog.json` 會沒有 endpoints,頁面 spec 的 `apiContract.endpoints` 也會是空陣列。 `frontend`、`backend`、`output`、`plan` 等欄位不會被 `doctor` 或 `scan` 使用,不需要為本 MVP 加入設定檔。 ## 本 repo 實際執行 這個 monorepo 目前要能穩定跑 `scan`,至少需要處理三件事: 1. 根目錄 `ht.config.mjs` 將 prototype 指到 `./prototype` 2. Playwright Chromium 已安裝 3. 若根目錄 `.playwright/cli.config.json` 有指定 `channel`,需避免 `scan` 誤走系統 Chrome 目前本 repo 的最小設定是: ```js export default { prototype: "./prototype", }; ``` 若根目錄 `.playwright/cli.config.json` 類似: ```json { "browser": { "browserName": "chromium", "launchOptions": { "channel": "chromium" } } } ``` `scan` 可能會失敗,並出現類似: ```text Chromium distribution 'chrome' is not found at /opt/google/chrome/chrome ``` 原因是 `html-transform` 會在 `.ht/cache/playwright-cli` 底下呼叫 `playwright-cli`。在這種情況下,可在該工作目錄放一份最小覆寫設定: ```text .ht/cache/playwright-cli/.playwright/cli.config.json ``` 內容: ```json { "browser": { "browserName": "chromium" } } ``` 在這個 repo 內,實際可重現的流程如下。 1. 確認設定與 CLI: ```bash pnpm --filter html-transform exec playwright-cli --version HOME=/tmp \ XDG_CACHE_HOME=/tmp \ PLAYWRIGHT_DAEMON_SESSION_DIR=/tmp/ms-playwright/daemon \ PLAYWRIGHT_BROWSERS_PATH=/tmp/ms-playwright \ node packages/html-transform/src/cli.js doctor ``` 2. 安裝 Chromium: ```bash HOME=/tmp \ XDG_CACHE_HOME=/tmp \ PLAYWRIGHT_DAEMON_SESSION_DIR=/tmp/ms-playwright/daemon \ PLAYWRIGHT_BROWSERS_PATH=/tmp/ms-playwright \ pnpm --filter html-transform exec playwright-cli install-browser chromium ``` 3. 準備 Playwright CLI 的本地覆寫設定(只有在根目錄 `.playwright/cli.config.json` 含 `channel` 時需要): ```bash mkdir -p .ht/cache/playwright-cli/.playwright printf '%s\n' '{' ' "browser": {' ' "browserName": "chromium"' ' }' '}' > .ht/cache/playwright-cli/.playwright/cli.config.json ``` 4. 執行 scan: ```bash HOME=/tmp \ XDG_CACHE_HOME=/tmp \ PLAYWRIGHT_DAEMON_SESSION_DIR=/tmp/ms-playwright/daemon \ PLAYWRIGHT_BROWSERS_PATH=/tmp/ms-playwright \ node packages/html-transform/src/cli.js scan ``` 在受限制 sandbox 中,`scan` 可能因為 Vite 無法綁定本機 port、或 Chromium 啟動時的系統呼叫受限而失敗。這種情況下,需要在不受 sandbox 限制的 shell 執行上面的 `scan` 指令。 ## Doctor ```bash node packages/html-transform/src/cli.js doctor ``` 檢查項目: - `prototype` directory - package-local `vite` - `playwright-cli` - `pnpm` ## Scan ```bash node packages/html-transform/src/cli.js scan ``` 在本 repo 的受限制環境中,建議實際使用: ```bash HOME=/tmp \ XDG_CACHE_HOME=/tmp \ PLAYWRIGHT_DAEMON_SESSION_DIR=/tmp/ms-playwright/daemon \ PLAYWRIGHT_BROWSERS_PATH=/tmp/ms-playwright \ node packages/html-transform/src/cli.js scan ``` `scan` 會自動: - 用 Vite static server 提供 prototype。 - 用 `playwright-cli` 開啟每個 HTML。 - 等待 `networkidle`,再等待 500ms。 - 截取 desktop `1440 x 900` full-page screenshot。 - 產生 DOM summary。 - 產生 accessibility snapshot。 - 記錄 resource failure 與 console error/warning。 - 建立頁面級 `pageContract`。 - 驗證 contract 與 DOM evidence 是否明顯衝突。 - 讀取 `prototype/*.md` 的對照表與 checklist,擷取 prototype 檔、舊 JSP、舊 PB、對應 Vue view、功能描述與人工 checklist。 - 讀取 `prototype/*.md` 的 legacy flow code block,產出可對照每個 prototype 的 `flowRefs`,避免 prompt 需要硬編特定 domain 的 JSP 流程知識。 - 讀取 backend API markdown docs,建立 endpoint catalog、schema 摘要、欄位規則與錯誤格式。 - 依 prototype evidence、guide 與 API catalog 建立 `apiContract`。 - 依頁面 evidence 建立 `maintenanceContract`,推論頁面型態、操作能力、row action 啟用條件與 checklist 衍生的 business rules。 - 產出 `.ht/app-map.json`,供通用 prompt 判斷 auth、legacy shell、feature page、layout 策略、API 對應與舊系統對照。 ## 產物 每個 HTML 的 capture artifact: ```text .ht/cache/prototype/{page}/desktop-default.png .ht/cache/prototype/{page}/dom-summary.json .ht/cache/prototype/{page}/accessibility-tree.json .ht/cache/prototype/{page}/capture-metadata.json ``` 每個 HTML 的 contract artifact: ```text .ht/api-catalog.json .ht/app-map.json .ht/spec/{page}.spec.json .ht/spec/{page}.validation.json ``` `.ht/api-catalog.json` 是跨頁面的 backend API catalog,來源是 `backendDocs` 目錄下的 markdown 文件。它會包含: - `endpoints` - `schemas` - `fieldRules` - `errorContract` `.spec.json` 會包含: - `pageContract`:頁面文字、欄位、表格、actions、layout evidence 與 Vuetify checklist。 - `captureArtifacts`:screenshot、DOM summary、accessibility tree 與 capture metadata 的可追溯路徑。 - `browserEvidence`:瀏覽器 resource failure 與 console warning/error。 - `apiContract`:與該頁匹配的 API endpoints、用途分類、rejected candidates 與錯誤格式。 - `prototypeGuide`:該 prototype 對應的人工 guide、舊 JSP/PB、target view 與 checklist。 - `prototypeGuide.flowRefs`:從 guide 的 legacy flow code block 比對出的相關流程節點,包含 menu、task、nodeType、JSP、PB、動作與原始流程行。 - `maintenanceContract`:頁面型態、capabilities、data model、row actions、business rules 與 warnings。 - `bddContract`:以頁面 evidence 產生的 Gherkin 草稿、scenario evidence trace 與人工 review warnings。 - `regions`:目前仍保留,目的是相容既有資料形狀;不要把它視為 Stage 2 decomposition。 `.ht/app-map.json` 是跨頁面的應用結構推論。通用 prompt 應先讀它,再決定每個 prototype 是 `auth`、`legacy-shell-reference`、`feature-page` 或其他角色。MVP 固定策略是 template layout/style 優先,prototype 只提供內容與功能證據。 route 也會包含 implementation hints,例如: ```json { "prototype": "venue/applications-list.html", "kind": "feature-page", "pageKind": "maintenance", "primaryEntity": "ApplicationsList", "capabilities": ["back", "search", "edit", "delete", "print"], "apiCount": 8 } ``` 若 `prototype/*.md` 內有 markdown table 對照 prototype HTML,例如 `venue/query-room.html`,`scan` 會把匹配結果寫進 route: ```json { "prototype": "venue/query-room.html", "guide": { "source": "venue.md", "legacyJsp": "zte_pro/zte451_02.jsp + zte451_02_1.jsp", "legacyPb": "n_zte451.of_zte451_02 / of_zte451_02_1", "targetView": "RoomQueryView.vue", "description": null, "checklist": [] }, "evidence": { "prototypeGuide": "venue.md", "apiCount": 2 }, "guide": { "flowRefs": [ { "tasks": ["場地查詢"], "matchedKeys": ["zte451_02.jsp", "zte451_02_1.jsp"], "nodes": [ { "task": "場地查詢", "nodeType": "query", "jsp": ["zte451_02.jsp"], "pb": ["of_zte451_02"] } ] } ] } } ``` 這些 guide 欄位輔助 route、舊系統對照與 checklist 理解;HTML capture、DOM summary、UI contract 與 screenshot 仍是畫面內容的主要 evidence。API catalog 與 `apiContract` 則用來降低 endpoint、DTO 與欄位規則的猜測。 ## 使用方式是否改變 CLI 使用方式沒有改,仍然是: ```bash node packages/html-transform/src/cli.js doctor node packages/html-transform/src/cli.js scan ``` 有改變的是 `scan` 的輸入與輸出: - 新增可選輸入:`backendDocs`,預設 `./apps/backend`。 - 新增輸出:`.ht/api-catalog.json`。 - `.ht/spec/{page}.spec.json` 新增 `apiContract`、`prototypeGuide`、`maintenanceContract`。 - `.ht/app-map.json` route 新增 `pageKind`、`capabilities`、`primaryEntity`、`apiCount`。 因此既有 `doctor` / `scan` 指令不用改;但使用 `.ht` 產物的 prompt 或下游工具,應改讀新增欄位。 ## 產物中的路徑 `.spec.json` 內 `source`、`screenshot`、`domSummary`、`accessibilityTree`、`metadata` 等欄位使用絕對路徑,而非相對路徑。這是 scan pipeline 的自然結果:`config.prototypeDir`、`config.htDir` 都以 `path.resolve(cwd, ...)` 轉為絕對路徑,後續 `listFiles` 和 `path.join` 產出的路徑字串均繼承絕對形式,不做 `path.relative` 轉換。 因為 `.ht/` 目錄已由 `.gitignore` 排除,這些檔案不會進入版本控制,每個開發者在自己機器上跑 `scan` 會重新生成,路徑自然指向自己的專案目錄,因此不影響可攜性。 ## 驗證 修改本 package 後至少執行: ```bash pnpm --filter html-transform typecheck pnpm --filter html-transform test HOME=/tmp XDG_CACHE_HOME=/tmp PLAYWRIGHT_DAEMON_SESSION_DIR=/tmp/ms-playwright/daemon PLAYWRIGHT_BROWSERS_PATH=/tmp/ms-playwright node packages/html-transform/src/cli.js doctor HOME=/tmp XDG_CACHE_HOME=/tmp PLAYWRIGHT_DAEMON_SESSION_DIR=/tmp/ms-playwright/daemon PLAYWRIGHT_BROWSERS_PATH=/tmp/ms-playwright node packages/html-transform/src/cli.js scan ```