內嵌瀏覽器
VMark 可以在文件視窗內寄宿一個真正的網頁瀏覽器——網頁會成為與你的 Markdown 文件並列的一級分頁。它是貨真價實的原生 webview(macOS WKWebView),而不是外部的 Chrome 視窗,也不是內嵌框架(iframe)。
實驗性功能
內嵌瀏覽器是早期功能,在此版本中僅支援 macOS。Windows 與 Linux 的支援會於日後推出——在那些平台上,下方的設定完全不會出現。
工作區導軌
啟用實驗性的工作區導軌後,瀏覽器網頁是視窗全域的:它們在視窗中的每個工作區都能存取,永遠不會被綁定到單一工作區的分頁。
關閉功能
在 macOS 上,瀏覽器預設為開啟。新增瀏覽器分頁位於 檔案 選單 (Alt + Mod + Shift + B)與命令面板中——無需事先啟用任何東西。
若要關閉,請前往 設定 → 進階 → macOS,並關閉內嵌瀏覽器。這也會關閉所有 已開啟的瀏覽器分頁,並撤除下方所述的 AI 自動化介面。
切換開關正下方有兩項 AI 態勢設定,只有在功能開啟時才會出現。兩者出廠時都採保守 設定,且不會因為瀏覽器被啟用而改變:
| 設定 | 預設值 | 說明 |
|---|---|---|
| AI 工作階段 | 沙箱 | AI 驅動的網頁會取得獨立的工作階段,而非共用你已登入的工作階段 |
| 允許回送 | 關閉 | 拒絕 AI 導覽至 localhost/私有網路位址 |
網站權限不在設定中——它們位於瀏覽器側邊欄,在擁有它們的那個視窗裡。
使用方式
瀏覽器分頁會在編輯區開啟,與你的文件並列——側邊欄、分頁列、終端機和狀態列都維持原位。它的控制項位於網頁上方:在 macOS 上,這些控制項與視窗的標題列共用空間,因為 VMark 會自行繪製標題列。在由系統繪製標題列的平台(Windows、Linux)上,控制項則位於視窗內、網頁上方,就像其他所有桌面瀏覽器的排列方式一樣。
| 控制項 | 操作 |
|---|---|
| ‹ / › | 上一頁/下一頁。無處可去時會變灰 |
| ⟳ / ✕ | 重新載入,或停止進行中的載入 |
| 網址列 | 一個 omnibox(全能輸入列):輸入網址即可前往,輸入其他任何內容則會搜尋 |
| ☆ / ★ | 將此頁面加入書籤 |
網址列會自動追蹤頁面:如果網站重新導向,或連結把你帶到別處,網址列會更新以顯示你實際所在的位置。
側邊欄會跟隨分頁
當瀏覽器分頁處於使用中時,側邊欄會顯示瀏覽記錄與書籤。當你切換回文件時,它又會自動顯示檔案總管、大綱和檔案歷史。沒有需要同步的第二種模式,而且每一側都會記住你上次開啟的內容,所以瞄一眼瀏覽器分頁,並不會讓你失去原本使用的檔案樹。
瀏覽記錄是各視窗獨立的,而且只在本次工作階段中存在:它從不寫入磁碟。(仍然有一個清除按鈕——「結束時就消失」和「現在就能清掉」並不是同一回事。)重新載入不會新增重複項目,而會重新導向你的網站,記錄的是你原本想造訪的頁面,而非沿途的每一次跳轉。
書籤則會保留下來。它們以你加入書籤時的確切網址儲存——同一頁面、不同區段(#install 與 #usage)就是兩個書籤,而且 VMark 不會悄悄「整理」網址的查詢參數,因為被改寫過的網址可能無法帶你回到你當時看到的內容。
網頁四周的視窗會轉為中性色
VMark 的佈景主題刻意帶有色調——Paper 是暖灰色,Mint 和 Sepia 更是如此。這用來書寫很怡人,但拿來包住別人的網頁就不對了:帶色的邊框會改變你對其中每一種顏色的判讀,這正是沒有任何真正的瀏覽器會為自己的框架介面(chrome)上色的原因。
所以當瀏覽器分頁取得焦點時,四周的視窗會切換為樸素的中性色——淺色主題下是白色,深色主題下是深色——而在你回到文件的那一刻又會切換回來。你的佈景主題並未改變;改變的只有網頁四周的部分。
終端機也遵循相同的規則。 如果你在瀏覽器分頁旁開著終端機,它會採用相符的中性色,而非維持你佈景主題的顏色,如此一來視窗的兩半便會協調一致,而不會在中間留下明顯的接縫。深色主題會得到深色的終端機,而非白色——終端機中的顏色是針對其背景調校的,強制使用白色會讓深色主題的輸出難以閱讀。
如果頁面當機
如果頁面的網頁內容程序終止,分頁會顯示一個附有重新載入按鈕的**「此頁面已當機」**覆蓋層,而不是空白或凍結的畫面。對於暫時性的當機,VMark 會自動重新載入幾次;如果頁面在載入時持續當機,它會停下來等你手動重新載入,因此你永遠不會卡在重新載入的迴圈裡。
它是如何打造的(以及為何在設計上就注重隱私)
VMark 會自行建立平台的 webview,並將它作為視窗的原生子項目加入——它不會向應用程式框架索取現成的 webview。這對隱私很重要:由框架建立的 webview 會在每個頁面注入一個內部訊息橋接,等於把一條通往應用程式的通道交給任何網站。由於 VMark 擁有的是一個全新建構、沒有這種橋接的 webview,被瀏覽的頁面沒有任何通往 VMark 的通道。頁面完全是單向被驅動的(應用程式可以讀取並操作頁面;頁面無法反向觸及應用程式)。
工作階段(登入資訊、Cookie)會依設定檔保存在作業系統 webview 自己的資料儲存區中,因此每個網站你只需登入一次。VMark 本身不會儲存任何憑證。
用 AI 驅動瀏覽器
透過 MCP 連接的 AI 助理可以操作瀏覽器分頁:
- 讀取(Read)——取得頁面的結構化無障礙快照(每個可互動或結構性元素會以「角色 + 無障礙名稱」表示,外加一個像
e5這樣穩定的 ref 控制代碼)。 - 動作(Act)——點擊或輸入到某個目標,可以依照先前讀取取得的精確 ref,也可以依照 ARIA 的角色 + 無障礙名稱(例如,點擊名為「Learn more」的連結)。ref 只有在動作已獲授權時才會被採用;任何需要你核准的操作都改用「角色 + 名稱」,如此核准提示才能向你顯示一個可讀的元素。點擊會確認它確實命中目標:它會把目標捲動到可見範圍、要求目標確實有被繪製出來——摺疊區段內的重複按鈕會被略過,而不會被點擊——並對點擊位置進行命中測試,因此被覆蓋層蓋住的目標會被回報為「被…覆蓋」,而不是穿透點擊。AI 被告知的是實際發生了什麼,而不只是它嘗試過,因此它無法悄悄對錯誤的東西動手卻回報成功。
- 捲動(Scroll)——將某個元素(依 ref)帶入可見範圍,或依像素數量捲動。屬動作類(與點擊一樣需經核准)。
- 按鍵(Key)——向取得焦點的元素或某個 ref 送出一次按鍵(
Enter、Escape、Tab、方向鍵,並可搭配 Ctrl/Shift/Alt/Meta)——例如提交表單或關閉對話框。屬動作類。注意:按鍵和捲動都是合成的 DOM 事件,因此只信任真實硬體輸入的網站可能會忽略它們。 - 查詢(Query)——以 CSS 選擇器進行結構化 DOM 偵測,抓取無障礙快照無法指名的東西(表格、計算後的值、屬性)。屬讀取類。
- 擷取(Extract)——把頁面轉為閱讀模式的 Markdown(標題、作者署名、文章正文,去除樣板內容),供 AI 想要閱讀而非操作的頁面使用。網站外掛會針對各來源精修擷取結果——內建的維基百科外掛會依名稱剝除 wiki 的框架介面——並以通用的閱讀器作為後備。頁面只輸出位元組;擷取則在 VMark 內執行。屬讀取類。
- 樣式(Style)——透過設定行內樣式、切換類別,或注入一段
<style>區塊(作用於整個頁面,而非侷限於選擇器)來操作 CSS(關閉擋住畫面的覆蓋層、標示某個目標)。屬動作類,而且核准會綁定確切的樣式內容——在你允許之後,它無法被替換成其他 CSS。 - 執行 JS(Execute JS)——這是逃生出口:當結構化動作無法表達某件事時,用它執行一段指令碼。它會在隔離內容世界(DOM + CSS,絕不碰觸頁面自己的 JavaScript)中執行,採逐次核准(絕不記住——它沒有「在此網站上允許」的選項),而且其結果會被視為不受信任。核准提示會向你顯示確切的指令碼,而執行的正是那段指令碼——AI 無法誘使你核准一段指令碼卻改跑另一段。請優先使用查詢/樣式;只有在它們不敷使用時才動用此項。
- 工作階段儲存/載入(Session save / load)——以一個控制代碼(你核准的名稱)儲存分頁目前的工作階段,之後再還原它,讓流程一開始就已處於登入狀態——而 AI 從頭到尾都不會看到你的 Cookie 或權杖。這些值會存放在作業系統的 keychain(靜態加密)中,AI 只會收到控制代碼與一份數量摘要。儲存與載入都採逐次核准,而且針對某個控制代碼的核准無法挪用到另一個。還原只會套用到與儲存來源相同來源(origin)的頁面。這是以參照方式保管憑證:AI 只指名一個工作階段,祕密由 VMark 持有。
- 主控台(Console)——讀取頁面被擷取下來的
console.*輸出(log/warn/error…),外加未被攔截的錯誤與未處理的 promise rejection——這是頁面在自己的指令碼出錯時發出的訊號,單純的console記錄從不會顯示它——好讓 AI 能對它正在驅動的頁面進行除錯。此為唯讀,且輸出會被視為不受信任的頁面資料。這是為了保住「設計上就注重隱私」的保證而打造的:擷取會寫入頁面自己的 DOM,再由 VMark 從那裡讀取,因此不會有任何訊息通道被開回應用程式。
工作階段儲存/載入——範圍
一個已儲存的工作階段涵蓋 localStorage 與 Cookie,兩者都侷限於你儲存當下頁面所提交到的 來源。Cookie 是透過原生 Cookie 儲存區讀取並重播的,而且在兩個方向上都受網域範圍限制—— 儲存時絕不會複製你整個 Cookie 罐,還原時也絕不會在不相干的網站底下植入 Cookie。
- 開啟(Open)——建立一個由 AI 擁有的分頁並載入一個 HTTP(S) 網址。
- 導覽(Navigate)——導覽一個由 AI 擁有的分頁,並等待它的導覽票證。當載入的頁面看起來像一道關卡、而非所要求的內容時——登入牆、同意條款插頁、真人驗證挑戰(reCAPTCHA/Turnstile),或流量限制通知——結果會如實說明,並要求 AI 讓你介入,而不是試圖繞過。偵測以精準為先:提到「$429」的價格,或寫著「Cloudflare」的頁尾,都不會誤觸它。
- 等待(Wait)——等待某個特定的導覽票證,而不啟動另一次載入。
- 等待條件(Wait for)——輪詢直到某個條件成立(依 ref 或「角色 + 名稱」指定的元素、一段可見文字,或分頁的 URL 含有某個子字串——最後這一項可確認由點擊觸發的導覽已完成),或直到逾時,並回報是否符合。它讓多步驟流程變得可預期——先動作,再等待結果,然後讀取——而不是用猜的。
- 螢幕截圖(Screenshot)——取得頁面目前繪製狀態的一張 JPEG 圖片,讓 AI 能看到無障礙快照未指名的版面與渲染狀態。與讀取一樣,它不會變更頁面:在由 AI 擁有的分頁上一律允許,在人類分頁上則只有在你已附加時才允許。
- 執行工作流程(Run a workflow)——把一段簡短、已儲存的步驟序列(點擊/輸入/導覽/擷取,以一套小型文字語法撰寫並以
source傳入)當作一次非同步執行來重播:它會立即回傳一個 run id,然後由你輪詢其狀態,因為多步驟的執行會比單一請求存活得更久。其中的每一個步驟都會逐一經過核准,就跟手動下達的動作一模一樣——工作流程不是繞過核准提示的手段——而 AI 無法確定性執行的步驟(自由文字的「目標」、一次「確認」)則會暫停執行,交由它手動處理。重新執行會略過已經成功的步驟,因此在暫停後重新執行絕不會重複送出。每個分頁一次只能有一項執行、且有其上限,並且可以取消——取消永遠是被允許的,而你親自接管瀏覽器也會停止該次執行。 - 記錄工作流程(Record a workflow)——與其親手撰寫語法,你可以直接記錄一份:在你核准之下(每次都重新徵求——記錄從不是常駐權限),VMark 會擷取你在分頁上執行的點擊與欄位編輯,並交還可直接執行的工作流程文字。它在設計上即不含任何值:你所輸入的任何內容都不會被儲存——每個欄位都會變成一個具名的
{input},由你在重播時填入;密碼欄位會變成一個手動的confirm:步驟;而 URL 則會被削減到只剩 origin + path。它記錄的是你碰觸了哪些控制項,絕非你輸入了什麼。
AI 瀏覽器的態勢可在 設定 → 進階 → 內嵌瀏覽器 中設定:
- 沙箱(建議)使用一個共用、不持久保存的 AI webview 儲存區。它會與其他沙箱分頁共用 Cookie,但不會與人類分頁共用。
- 共享設定檔 使用人類的 webview 儲存區,並在每次 AI 導覽之前要求核准目標網站,除非該 來源已有相符的
navigate授權。
由 AI 建立的分頁是暫時性的,重新啟動後不會被還原。它們的網址、模式、標題、世代與載入狀態 會出現在 session.get_state 中;憑證則會從 MCP 回應中被遮蔽。
各項動作都需經核准:未經你授權的操作不會執行——AI 會被告知需要核准並等待。檔案上傳永遠不允許由 AI 進行(由 AI 選擇的檔案上傳會成為資料外洩的管道);這類操作嚴格維持由人類主導。
核准操作
當 AI 請求動作時,VMark 會彈出一則提示並暫停該頁面。它會明確告訴你三件事——網站、操作,以及元素(它的角色與無障礙名稱,例如 button "Publish"):
- 允許一次——只授權那一個動作、在那個元素上、在那個頁面上。它會立即被用掉,不會變成常設權限。
- 在此網站上允許——AI 可以在那個網站上執行那項操作而不再詢問。它不會擴及其他操作或其他網站。
- 拒絕——什麼都不會發生。按
Escape,或直接按Enter,同樣是拒絕:這則提示刻意偏向拒絕。
這則提示向你顯示的是操作的描述,而非頁面的畫面——這是刻意為之。網頁掌控自己的像素,因此惡意頁面可以把「Delete everything」的按鈕做成看起來像「Publish」。VMark 向你顯示的,正是安全防線所強制執行的內容,取自瀏覽器引擎,而非頁面對自身的宣稱。
權限也會在頁面導覽時失效。提示描述的是針對某個特定頁面的動作;如果頁面在你正在決定時改變了,該請求會被捨棄,而不會套用到取而代之載入的任何頁面。未用掉的「允許一次」也會以相同方式被丟棄。
這也包括頁面內部的導覽。大多數現代網站在不同檢視之間切換時,根本不會載入新頁面——網址改變、內容被改寫,但網站從未離開。這在此處很重要,因為網站與來源維持不變,而你核准過的 button "Publish" 可能已經不再是那個名稱底下的按鈕。因此 VMark 把頁內導覽完全視同其他導覽:授權會隨著它被授予時所針對的檢視一同失效,而不僅僅是隨頁面失效。
不過,真正承擔關鍵作用的是描述子本身。網站可以在任何時刻改寫自己的內容而完全不進行導覽,任何瀏覽器引擎都不會回報這件事。所以「允許一次」所授權的,恰恰是一項操作、作用於一個以角色與無障礙名稱識別的元素、在一個網站上——而且會立即被用掉。真正該三思的是「在此網站上允許」:它是針對那個網站上那項操作的常設權限,而你授予它的網站,就是你信任它會妥善行使該權限的網站。
檢視與撤銷權限
設定 → 進階 → 網站權限 會列出你已授權的每個網站,以及它可以做的事。撤銷 會立即收回權限——該網站上的下一個 AI 動作會再次詢問。
網站權限只保存在記憶體中:它們從不寫入磁碟,並在 VMark 結束時失效。讓 AI 跨越重新啟動仍保有在某網站上點擊的能力,是一個比表面上看起來更重的承諾,因此 VMark 不會默默地做出這個承諾。
當 AI 以人類建立的分頁為目標時,VMark 會先詢問是否要為該分頁附加 AI 存取權。這個附加會綁定到目前的導覽世代。允許一次 會在一次成功的讀取或動作之後被用掉;允許直到導覽 則會在下一次完整或頁內導覽、關閉、停用或重新啟動時到期。
AI 導覽預設會拒絕回送、私有區域網路、連結本機、中繼資料、格式錯誤,以及不支援協定的目標。DNS 重新綁定仍是屬於 WebKit 的限制;VMark 並不宣稱能消除它。
協同駕駛:從終端機看著 AI 操作瀏覽器
瀏覽器是一個面板,而不是一種模式。這讓一種特別的工作方式成為可能:在瀏覽器分頁旁開啟一個終端機(`Ctrl + ``),在裡面執行一個 AI 代理,然後看著頁面隨著它工作而回應。
終端機與瀏覽器並排而坐——瀏覽器會調整大小以騰出空間,而不是被覆蓋。所以在代理操作頁面的整段時間裡你都看得到頁面,而它採取的每一個動作仍然必須先經過你(見上方核准操作)。
這正是 VMark 中 AI 瀏覽器用法所設想的樣貌:代理提議、頁面可見、由你核准。它不是代理在一個你看不到的視窗裡工作。
取回控制權只需一個動作。 當一次 AI 工作流程執行正在驅動某個分頁時,它的框架介面會顯示一個**「AI 正在控制 — 點擊接管」**的指示標記。點擊它——或者你只是自己與頁面或其網址列互動——就會立即收回該分頁並停止該次執行。你永遠不必在代理的終端機裡找停止按鈕;碰一下瀏覽器就是停止按鈕。
當頁面載入失敗時
離線的網路、錯誤的主機名稱、被拒絕的憑證,或被拒絕的連線,都會在瀏覽器面板中產生一則說明出了什麼問題的訊息,並附上一個重試按鈕。較早的版本則會顯示空白面板,讓人無法將它與只是載入緩慢的頁面區分開來。
目前的限制
- 此版本僅支援 macOS。
- JavaScript 的
confirm()/prompt()對話框目前會被抑制(只有alert()會被呈現);彈出視窗(window.open)會被封鎖,而不是以新分頁開啟。 - 下載、列印,以及逐一請求的網路政策尚未實作。
這些功能正逐步補齊;上文所述的是目前可用的內容。