(Community Market)架構(gòu)解析:安裝流程與卸載邊界如何工作)
deepseek-harness-desktop 插件市場(chǎng)Community Market架構(gòu)解析安裝流程與卸載邊界如何工作【免費(fèi)下載鏈接】deepseek-harness-desktop為 DeepSeek Harness (DSH) 插件生態(tài)打造的現(xiàn)代化桌面端解決方案。萬物皆「插件」桌面本身也是「插件」。項(xiàng)目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness-desktop本文基于 deepseek-harness-desktop 倉(cāng)庫(kù)內(nèi)的文檔與源碼拆解dsh-community-market包的插件市場(chǎng)架構(gòu)目錄來源如何歸一化、npmlatest如何成為安裝唯一信任錨、一次性確認(rèn)令牌如何約束寫操作以及故障恢復(fù)的唯一入口幫助不熟悉項(xiàng)目?jī)?nèi)部結(jié)構(gòu)的開發(fā)者理解其讀寫邊界并做二次開發(fā)。它要解決什么問題插件市場(chǎng)本質(zhì)上要回答三個(gè)問題插件從哪來、一次安裝憑什么被信任、卸載為什么不能直接執(zhí)行一條包名命令。從哪來目錄來源既可以是實(shí)現(xiàn)標(biāo)準(zhǔn) cursor 分頁契約的匿名 JSON 服務(wù)也可以是內(nèi)置經(jīng)審查的 provider 適配器DSH 1024Store、dshfind還可以由用戶自行添加 manifest URL。各來源的 wire format 完全不同界面層只能消費(fèi)一種歸一化形狀。憑什么信任安裝來源自己標(biāo)注的版本、徽章、驗(yàn)證標(biāo)記都不算數(shù)。真正決定能否進(jìn)入安裝預(yù)覽的是 npm 官方 registry 返回的latestmanifest 是否滿足一組最小條件。卸載為什么謹(jǐn)慎Installed 視圖列出的插件可能由本市場(chǎng)、其他市場(chǎng)或 DSH CLI 安裝。卸載前 Host 會(huì)兩次對(duì)照當(dāng)前 Profile 清單復(fù)核目標(biāo)而不是相信界面提交的字符串。職責(zé)與接口邊界只讀能力永遠(yuǎn)可用寫操作只有在對(duì)應(yīng)能力被注入時(shí)才存在——這是入口文件dsh-community-market/src/index.ts落地的分工契約。Market 擁有來源配置、來源適配器、歸一化發(fā)現(xiàn)normalized discovery、Client 界面、npmlatest預(yù)覽、圍繞 Profile 包操作的一次性確認(rèn)。它不擁有Profile 存儲(chǔ)、包執(zhí)行、恢復(fù) checkpoint、終端窗口docs/market-shell.md。依賴注入的形態(tài)如下依賴注入方式帶來的能力缺失時(shí)的降級(jí)行為webServer硬性注入inject [webServer]注冊(cè)全部/api/community-market/*路由包無法工作storageDomain軟注入按需動(dòng)態(tài)import來源選擇持久化狀態(tài)僅存活于會(huì)話重啟不保留僅寫 warn 日志desktopActions可選注入失敗對(duì)話框里打開 DSH Terminal按鈕按鈕不顯示pluginManagerprofileContext可選注入二者同時(shí)在場(chǎng)才創(chuàng)建MarketInstallService安裝 / 卸載 / 啟停編排安裝類路由返回 503Discover、Sources 照常瀏覽npm registry 請(qǐng)求走一個(gè)獨(dú)立受限 client其代理例外主機(jī)名是編譯期常量而非用戶輸入const npmRegistryHttp createRestrictedHttpClient({ // This is a compiled-in official registry hostname, never provider input. syntheticProxyHostnames: [registry.npmjs.org], })一次完整操作的時(shí)間線從瀏覽到卸載選定一條插件走完全流程數(shù)據(jù)形態(tài)依次經(jīng)歷provider 原始 JSON →CatalogSnapshot歸一化條目 → 安裝候選candidate→ 一次性令牌previewId→ manager 變更結(jié)果。瀏覽標(biāo)準(zhǔn) cursor 來源被 Host 掃描進(jìn)有界本地索引掃描結(jié)果緩存 5 分鐘DEFAULT_CATALOG_SCAN_CACHE_TTL_MSdsh-community-market/src/catalog/service.ts第 74 行搜索、多分類 OR 篩選、50 條/頁的 UI 分頁都在本地執(zhí)行用戶的搜索詞從不發(fā)給 provider。dshfindadapter 固定per_page100DSHFIND_PAGE_SIZE條目上限 20000MAX_DSHFIND_ITEMS數(shù)據(jù)集必須帶sha256:前綴的 64 位 hexdata_version任一校驗(yàn)失敗整批拒絕不發(fā)布部分索引dsh-community-market/src/adapters/dshfind.ts第 17-18、240-241 行。1024Storeprovider 的分頁 v2 API/api/v2/plugins直連每一次查詢頁大小上限 200 條BROWSE_PAGE_SIZE/MAX_PROVIDER_PAGE_SIZEInstallable 路由構(gòu)造limit: 200的查詢每批只物化一個(gè) provider 頁dsh-community-market/src/host/routes.ts第 941-946 行。預(yù)覽POST /api/community-market/operations/preview只接受這兩種精確形狀字段經(jīng)boundedIdentifier校驗(yàn)1–240 字符且不含\0{ action: install, sourceRecordId, itemId } { action: uninstall, packageName }Host 從本地候選表取回先前觀察到的條目observeCatalog在每次快照到達(dá)時(shí)登記請(qǐng)求https://registry.npmjs.org/package/latest核對(duì)包名一致、精確穩(wěn)定版本、dsh.bundle.patch安全相對(duì)路徑后簽發(fā)一個(gè) 32 字節(jié)隨機(jī) token 作為previewId。 5.執(zhí)行POST /api/community-market/operations/execute只接受{ previewId }。令牌一次性消費(fèi)Host 校驗(yàn) Profile 未變化再以精確nameversion目標(biāo)調(diào)用installBundle(target, { enabled: true, saveExact: true })并斷言 manager 回報(bào)的已安裝包與驗(yàn)證過的包名一致dsh-community-market/src/install/service.ts第 574-585 行。 6.卸載preview 階段調(diào)用removableBundle對(duì)照當(dāng)前l(fā)istBundles復(fù)核removable標(biāo)志執(zhí)行前再?gòu)?fù)核一次然后removeBundle——先取消選擇并卸載 bundle再由 pnpm 移除依賴。Renderer Host (market) pluginManager | GET catalog (cursor) | | |-------------------------| adapter - CatalogSnapshot | | POST preview {ids} | | |-------------------------| npm latest - verify - previewId | POST execute {previewId} | | |-------------------------| installBundle(nameversion) --| | |---------------- ChangeResult | |----- {packageName,version, application} |邊界與安全條件每一條為什么不能都對(duì)應(yīng)一個(gè)具體常量或校驗(yàn)函數(shù)而不是約定俗成。來源命令一律丟棄。1024Store 適配器只解析一種精確的惰性命令形狀dsh plugin --profile p add npm-package恰好 6 個(gè) token提取 npm 包名后立即丟棄命令本身注釋明確 The command itself is never retained or executeddsh-community-market/src/adapters/dsh-1024store.ts第 120-139 行dshfind 只接受kind npm且verification verified的單個(gè)結(jié)構(gòu)化目標(biāo)dshfind.ts第 142-167 行。來源不能聲明憑據(jù)或選擇權(quán)。標(biāo)準(zhǔn)來源 manifest URL 與目錄端點(diǎn)必須是無憑據(jù)的 HTTPS 443 端口readStandardSourceManifest顯式拒絕username、password、port、search、hashroutes.ts第 469-472 行provider 重定向最多 3 跳且逐跳校驗(yàn) origin 未漂移dsh-community-market/src/network/restricted-http.ts第 11、190-212 行。版本只認(rèn) npm 官方latest。stableExactVersion要求 semver 嚴(yán)格合法且無 prerelease 段manifest.name必須與候選包名完全相同來源列出的版本永不參與目標(biāo)構(gòu)造service.ts第 197-201、258 行。令牌短時(shí)且一次性。關(guān)鍵常量service.ts第 25-33 行const INSTALL_INTENT_TTL_MS 5 * 60 * 1000 // 意圖 5 分鐘過期 const CANDIDATE_TTL_MS 30 * 60 * 1000 const MAX_INTENTS 256 const ACTIVATION_GRACE_MS 5000consumeIntent消費(fèi)即刪除sameProfile在 preview 后 Profile 變化時(shí)拋conflict映射為 HTTP 409過期令牌映射 410見routes.ts第 90-96 行。入口僅限本機(jī)回環(huán)。marketAuthority要求源地址屬于127.0.0.0/8或::1、Host主機(jī)名恰好是127.0.0.1、端口與 webserver 一致、sec-fetch-site非cross-site寫操作額外要求Origin與 Host 完全同源routes.ts第 283-328 行。請(qǐng)求體上限 16 KiBMAX_BODY_BYTES。內(nèi)置 provider 的例外不擴(kuò)散。兩個(gè)內(nèi)置 HTTP client 各自持有獨(dú)立體積上限——1024Store 2 MiBMAX_DSH_1024STORE_BODY_BYTES、dshfind 16 MiBMAX_DSHFIND_BODY_BYTES——主機(jī)名是編譯進(jìn) adapter 的常量用戶添加的來源絕不繼承這些本地代理例外routes.ts第 53-74 行。產(chǎn)品自有包被禁裝。BLOCKED_PRODUCT_PACKAGESdsh-plugin-desktop、dsh-plugin-desktop-beta、dsh-desktop-next、dsh-community-market在任何安裝入口都會(huì)被marketManagedPackage拒絕service.ts第 34-39、207-209 行。失敗與恢復(fù)市場(chǎng)自身不做回滾降級(jí)路徑與拒絕路徑被明確劃分恢復(fù)的唯一顯式入口是恢復(fù)頁面。觸發(fā)條件系統(tǒng)行為用戶可見結(jié)果pluginManager未注入安裝/卸載/啟停路由返回 503瀏覽路由不受影響Discover、Sources 可用安裝按鈕不可用routes.ts第 907-910 行目錄請(qǐng)求超時(shí)catalog-timeoutHTTP 504失敗附著在所選來源上提供 Retry不回退其他來源routes.ts第 104-118 行響應(yīng)違反契約catalog-invalid-responseHTTP 502同上其他來源不可用catalog-unavailableHTTP 502同上preview 后 Profile 變化conflict409重復(fù)使用令牌返回intent-expired410需重新預(yù)覽manager 報(bào)告失敗或取消保留 manager 的有界 pnpm 輸出寫入 Desktop 日志絕不自動(dòng)重試失敗對(duì)話框展示同一份診斷與精確命令可手動(dòng)打開終端install-and-uninstall.md失敗行為表安裝結(jié)果與驗(yàn)證包不符拋錯(cuò)上報(bào)已裝依賴保留在 Installed 視圖供人工處理service.ts第 579-585 行條目仍可見啟用后行未即刻激活5 秒寬限期內(nèi)每 250 ms 輪詢行狀態(tài)全部 active 才判成功awaitActivationACTIVATION_GRACE_MS/ACTIVATION_POLL_MS寬限結(jié)束仍 pending 則維持失敗Renderer 在確認(rèn)后關(guān)閉Host 持有g(shù)enerationController.signal繼續(xù)執(zhí)行僅響應(yīng)可能丟失routes.ts第 1046-1048 行結(jié)果在下次讀取時(shí)可見恢復(fù)語義分兩層manager 負(fù)責(zé)還原它自己快照過的 Profile manifest 與 lockfile其余一切由 Desktop 的健康啟動(dòng) Profile checkpoint 覆蓋恢復(fù)永遠(yuǎn)是恢復(fù)頁面中的顯式動(dòng)作dsh-community-market/docs/market-shell.mdFailure boundary 一節(jié)。工程約束與延伸閱讀契約生成、類型檢查、單元測(cè)試、包構(gòu)建、export 驗(yàn)證、Loader smoke test 必須全部 headless-safe任何一步都不得啟動(dòng) Electron——這是市場(chǎng)能穩(wěn)定進(jìn)入 DSH Desktop 發(fā)布鏈的前提dsh-community-market/docs/market-shell.mdHeadless requirements 一節(jié)。dsh-community-market/tests/下的套件在同樣約束下運(yùn)行覆蓋點(diǎn)包括無默認(rèn)來源且不預(yù)選、顯式單來源選擇、來源失敗不回退、安裝候選 fail-closed、1024Store 命令丟棄、dshfind 數(shù)據(jù)集整批拒絕等驗(yàn)收行為如contracts.spec.ts、host-routes.spec.ts、market-install.spec.ts、dshfind-adapter.spec.ts。如需本地閱讀可用git clone https://gitcode.com/gh_mirrors/de/deepseek-harness-desktop獲取倉(cāng)庫(kù)。延伸閱讀均為倉(cāng)庫(kù)相對(duì)路徑dsh-community-market/docs/market-shell.md模塊歸屬、運(yùn)行時(shí)形態(tài)與故障邊界的權(quán)威摘要。dsh-community-market/docs/install-and-uninstall.md安裝/卸載分步流程與完整失敗行為表。dsh-community-market/docs/catalog-provider-contract.md公開 v1 provider 契約、Schema 權(quán)威與安全邊界。dsh-community-market/src/install/service.ts驗(yàn)證器、一次性令牌與 manager 編排的完整實(shí)現(xiàn)。dsh-community-market/src/host/routes.ts路由注冊(cè)、回環(huán)鑒權(quán)與錯(cuò)誤碼映射。【免費(fèi)下載鏈接】deepseek-harness-desktop為 DeepSeek Harness (DSH) 插件生態(tài)打造的現(xiàn)代化桌面端解決方案。萬物皆「插件」桌面本身也是「插件」。項(xiàng)目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness-desktop創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考