Communitygithub.com

vvedantb/eva

從實際運行的應用程式中,擷取一張乾淨的高畫質螢幕截圖(Eva 新功能),並撰寫一篇搭配的貼文。當使用者想要展示、公告或發布某個功能時使用。

eva 是什麼?

此技能為 Eva 應用程式提供了一個完整的「功能截圖 + 推文」發布流程。它使用 Playwright 以 2 倍的裝置像素比(deviceScaleFactor 2)在 1280 像素的版型上,擷取 2560×1440 的高畫質 PNG 截圖,確保在 Retina 螢幕上依然清晰。接著,它會自動為截圖套上 Eva 品牌漸層邊框與標誌,生成 3200×1800 的最終版本,使其看起來像是正式的產品公告,而非一般的 Bug 報告截圖。最後,它會呼叫 `eva-tweet` 技能來撰寫推文。此技能適用於 Claude Code 等 AI 代理工具,並提供 shell 腳本與 Node.js 模組兩種操作方式。其工作流程包含七個步驟:確認功能、啟動開發伺服器、執行截圖(包含一個名為 `recipe` 的腳本機制來處理互動式 UI 狀態)、審查截圖品質、加上邊框、撰寫推文,最後移交成果。技能中包含了多項強制性的預設規則,例如隱藏開發者疊加層、自動折疊側邊欄、絕不提交表單或觸發真實操作,以及透過修改開發資料來美化畫面而非繞道重拍。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/vvedantb/eva/tree/HEAD/.claude/skills/eva-feature-screenshot

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Eva 功能截圖

一個已發布功能的截圖 + 一篇推文。沒有 Remotion、沒有音樂、沒有剪輯、沒有嵌入在圖片中的字幕——產品 UI 本身就是資產。

兩個檔案會存放在儲存庫根目錄的 screenshots/ 資料夾(已加入 .gitignore):

檔案說明
<YYYY-MM-DD>-<slug>.png原始 2560×1440 截圖 — 請保留,這是無需重拍的來源
<YYYY-MM-DD>-<slug>-framed.png請發布這個 — 3200×1800,帶有品牌邊框

加上邊框的版本會將原始截圖放置在 Eva 的品牌漸層背景上,帶有圓角,並在上方加上 Eva 圖示和「Eva」字標。這就是為什麼這張截圖看起來像產品公告,而不是 Bug 報告截圖。

不可妥協的預設值

  1. 1280 版型,以 2560×1440 (16:9) 的高畫質擷取。 腳本會以 deviceScaleFactor 2 驅動真實的 Chrome 瀏覽器,並使用 scale:"device" 進行擷取,因此應用程式會以其原生 1280 寬度(可讀的元素大小)進行佈局,但 PNG 的畫素密度是兩倍——在 Retina 時間軸上非常清晰。16:9 是 X(Twitter)在時間軸中顯示且不裁切的格式。加上邊框的輸出是 3200×1800——同樣是 16:9,因此邊框在時間軸中不會造成任何額外開銷。agent-browser 無法做到這點:它的 screenshot 以 CSS 畫素擷取並忽略 DPR,因此永遠只會輸出 1280×720。請使用高畫質腳本。

  2. 絕不使用整頁截圖。 一個密集應用程式的整頁截圖會變成一個長條,在時間軸中會縮小成縮圖大小。一個視口,一個概念。

  3. 在拍攝前隱藏開發者疊加層。 react-scan 和 agentation 都會在頁面中渲染。scripts/hd-shot.mjs 會處理這件事——請使用腳本,而不是自己手動串接。

  4. 與應用程式的實際主題匹配。 無論使用者正在執行什麼(set media dark 表示深色模式)。不要為了截圖而重新設計應用程式的樣式。

  5. 該功能必須是視覺主題。 繁忙頁面角落的一個 200px 面板是失敗的。請導航到該功能佔據主導地位的視圖,或開啟包含它的表層(模態框、工作表、詳細資訊面板),使其在時間軸大小下可以被辨識。

    側邊欄會自動收起。 shot.sh(以及一般的 hd-shot.mjs --path 截圖)會在擷取前收起導航欄——它佔用了 1280px 框架中約 250px 的空間,而且其中的任何內容永遠不會是功能本身。只有在側邊欄本身就是功能時,才傳遞 --no-collapse。在使用 --recipe 時,請自行呼叫 ctx.collapseSidebar(page)(Recipe 掌控自己的準備工作)。

    如果該表層提供了隱藏次要清單列(評論清單、設定導航)的方法,也適用同樣的規則。請檢查原始 PNG:如果有一欄不相關的導航項目倖存下來,請重拍。

  6. 加上邊框,但不要加註解。 永遠執行步驟 6——漸層 + 字標是品牌風格。除非要求,否則不要加入箭頭、紅色圓圈、說明文字或假的瀏覽器 chrome。

  7. 絕不提交。僅輸入。 填寫輸入框、開啟選取器、準備好狀態——然後拍攝。不要在編輯器中按 Enter、不要按傳送箭頭、建立、儲存、執行或開始,也絕對不要啟動真實的會話或代理程式執行,即使是為了得到更好的畫面也不行。提交會改變使用者真實的工作區並消耗真實的計算資源;準備好的狀態才是你要拍攝的內容。Enter 只有在提交到欄位本身且不觸發其他任何動作時才允許使用(從開啟的選取器中接受一個 @ 提及)——如果你無法確定它只會做這些事,請改用點擊選取器中的該列。

  8. 如果資料難看,修正資料——不要繞道重拍。 預設值 7 阻止你驅動應用程式產生狀態;它並不阻止你寫入狀態。真實的開發資料通常是截圖失敗的原因:錯誤牆(「無法停止沙盒」×8)、Untitled session 列、部分遷移的回合、功能需要三個項目卻只有一個的儲存庫。在截圖周圍編輯應用程式自己的開發資料,比尋找一個剛好看起來不錯的會話更好,也比重新設計應用程式樣式更好(預設值 4 仍然適用——修改資料,永遠不要修改 CSS)。

    直接寫入開發部署:使用 npx convex run 執行的暫時性 internal/screenshotStaging.ts 突變,或使用 Convex 儀表板。為會話提供真實可讀的標題,刪除畫面上的錯誤/系統訊息,為功能需要的第二和第三列植入資料。

    規則:

    • 僅限開發部署。 在寫入前確認目標(npx convex env get CONVEX_URL,或讀取 .env.local),永遠不要將暫存突變指向生產環境。
    • 優先採用加法與可逆操作。 修改標題或插入示範列,優於刪除真實的歷史記錄。如果必須刪除,請先檢視這些列並說明你移除了什麼。
    • 合理,而非虛構特定細節。 標題和提示看起來像真實的工作。永遠不要編造推文後會當作事實重複的指標、客戶名稱或數字。
    • 截圖完成後刪除暫存突變——與任何遷移作業相同的清理規則。
    • 在交接時告訴使用者你更改了什麼。
  9. 保密性。 使用使用者自己的儲存庫 vvedantb/eva。絕對不要使用客戶端儲存庫(evalucom/carepulse、eprocurement),也不要使用列出這些儲存庫的「Codebases」首頁。檢查畫面上的文件/任務/會話清單中是否有以客戶命名的項目——如果清單不乾淨,請準備一個乾淨的示範列。絕對不要對畫面上的姓名或電子郵件提出個人資料的疑慮——「設定」→「實驗性功能」中有一個模糊 PII 的開關,可以模糊所有 [data-pii] 元素,因此這已在產品中處理。請標記洩漏環境變數名稱或專案 ID 的錯誤面板。

工作流程

  1. 確認已發布的內容。 如果使用者沒有指定是哪個功能,問一個問題就好——一個問題,不是一份問卷。git log --oneline -15、git diff --stat 或 internal/changelog/(最新的月份檔案)通常可以指出名稱。 你需要功能和顯示該功能的 URL。

  2. 啟動應用程式。 只需啟動開發伺服器——高畫質腳本會自行啟動自己的 Chrome 瀏覽器,並以代理使用者身份登入(/?agent=true),使用全新的上下文且 deviceScaleFactor 為 2。你不需要驅動 agent-browser 來進行拍攝。

    pnpm dev   # 從儲存庫根目錄 → localhost:5173
    
  3. 拍攝截圖。 對於一般的 URL 截圖,shot.sh 會導航、收起側邊欄、隱藏疊加層,並以 2560×1440 擷取:

    bash .claude/skills/eva-feature-screenshot/scripts/shot.sh /vvedantb/eva/web/sessions sessions
    

    接受 URL 路徑 + 別名(slug)(+ 可選的等待毫秒數 + 可選的 --no-collapse)。

    對於需要準備動作的截圖(開啟選單、輸入提示,然後擷取),請編寫一個 Recipe——一個匯出 export async function stage(page, ctx) 的 .mjs 檔案——並將其傳遞給 hd-shot.mjs。Recipe 負責導航、側邊欄收起和準備動作;ctx 提供了 { BASE, hideOverlays, collapseSidebar, settle }。使用 page.getByRole(...)(Playwright)定位器。若要找到確切的可存取名稱,請先以互動方式驅動 agent-browser 並使用 snapshot -i / read_page。

    // recipe.mjs — 準備好開啟模式選取器並輸入提示
    export async function stage(page, ctx) {
      await page.goto(`${ctx.BASE}/vvedantb/eva/web/sessions`, {
        waitUntil: "networkidle",
      });
      await ctx.settle(3000);
      await ctx.collapseSidebar(page);
      await page.getByRole("textbox", { name: /Ask Eva/ }).click();
      await page.keyboard.type("Redesign the sessions sidebar…");
      await page.getByRole("button", { name: "Edit", exact: true }).click();
      await ctx.settle(600);
    }
    
    node .claude/skills/eva-feature-screenshot/scripts/hd-shot.mjs --slug session-modes --recipe /abs/path/recipe.mjs
    

    準備乾淨、可讀的輸入——一個整潔的示範標題勝過一個真實但凌亂的。絕不提交(預設值 7)。

  4. 讀取 PNG 並進行判斷。 這一步會抓出不好的截圖:

    • 功能是明顯的主體,還是淹沒在 Chrome 元素中?
    • 有任何疊加層/工具列倖存嗎?畫面上還有骨架、旋轉圖示或 — 的預留位置嗎?(增加等待毫秒數並重拍。)
    • 所有四個邊緣:被剪裁的標籤、渲染不完全的按鈕、被切掉的欄位?
    • 有任何機密資訊違反預設值 9 嗎?
    • 空狀態:一個空白看板用來證明「看板任務」是張糟糕的截圖。請填入資料或選擇其他視圖。

    當畫面因為資料而失敗時——錯誤牆、Untitled session、功能需要三個項目卻只有一列——請準備開發資料(預設值 8),而不是尋找一個運氣更好的畫面。

  5. 加上邊框。

    bash .claude/skills/eva-feature-screenshot/scripts/frame.sh <slug> "Eva"
    

    寫入 screenshots/<today>-<slug>-framed.png(3200×1800)。它會透過自己的 Chrome(deviceScaleFactor 為 2)渲染 templates/frame.html——這是一個與截圖程式分開的瀏覽器,因此之後無需還原任何東西。也請讀取加上邊框後的 PNG——檢查漸層是否在角落沖淡了 UI,以及字標是否沒有被剪裁。第三個參數可以為來自其他路徑的原始 PNG 加上邊框。templates/frame.html 是此技能品牌顏色所在的唯一位置。

  6. 撰寫推文。 呼叫 eva-tweet 技能——鉤子、可選的定位片段、→ 功能列表、可選的結尾。截圖承擔了證明的責任,因此推文應敘述現在存在什麼,而不是描述圖片。絕對不要提及圖片本身。

  7. 交接。 加上邊框的檔案路徑作為 Markdown 連結、推文放在程式碼區塊中,以及畫面上任何使用者應在發布前確認的內容。

快速參考

需求命令
拍攝 URL(高畫質)bash .claude/skills/eva-feature-screenshot/scripts/shot.sh <path> <slug> [settle-ms]
在畫面中保留側邊欄bash .claude/skills/eva-feature-screenshot/scripts/shot.sh <path> <slug> <settle-ms> --no-collapse
有準備動作的截圖(選單/輸入)node .claude/skills/eva-feature-screenshot/scripts/hd-shot.mjs --slug <slug> --recipe <abs.mjs>
加上邊框(發布這個)bash .claude/skills/eva-feature-screenshot/scripts/frame.sh <slug> [title] [raw-png]
尋找可存取名稱以互動方式驅動 agent-browser,然後使用 agent-browser snapshot -i
除錯空白/損壞的頁面agent-browser console · agent-browser errors

注意事項

  • 高畫質功能存在於 Playwright,而非 agent-browser。 agent-browser 的 screenshot 以 CSS 畫素擷取並忽略 devicePixelRatio,因此最高只能達到 1280×720。hd-shot.mjs / hd-frame.mjs 使用全域 agent-browser 安裝內建的 playwright-core;如果它位於其他地方,請設定 PW_CORE。兩者都會啟動 channel:"chrome",因此系統必須安裝 Chrome。
  • 腳本會自行登入,使用 /?agent=true(一個布林值;/?agent 會拋出一個 zod SearchParamError),在全新的瀏覽器上下文中。拍攝截圖不需要 agent-browser 會話。
  • 開發者疊加層是三個節點,都掛在 <html> 上,而非 <body>。 僅隱藏 #react-scan-root 是不夠的:react-scan 在一個沒有 id 或 class 的純 html > canvas 上繪製其元件輪廓和標籤,而這個正是會毀掉截圖的元兇。hd-shot.mjs 使用內聯的 display:none !important 來殺死所有三個節點(#react-scan-root、html > canvas、[data-agentation-root]),因為樣式表會輸給它們的內聯樣式。
  • 有準備動作的截圖使用的是全新的瀏覽器,不是你探索時用的那個。 使用 agent-browser 來尋找選擇器,但 Recipe 會在 Playwright 自己的上下文中重新導航並從頭開始準備——請將每個步驟都放在 Recipe 中。優先使用 page.getByRole(...) 而非 CSS;像 @e1 這樣的參考在這裡不存在。
  • 兩張或更多的圖片會分散重點。 X 會以全寬渲染一張圖片;第二張會讓兩張都減半。只有在真正的對比(之前/之後)時才拍攝多於一張。
  • 不要重複使用 video/public/captures/——那些是 Remotion 資產,為不同的工作加上邊框。

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

相關技能