Communitygithub.com

broomva/skills

在命令列上逛 Tiendas D1(哥倫比亞,d1.com.co)— 搜尋目錄、查詢最近門市、以門市實際庫存為購物籃報價、並索取運送報價。D1 使用 VTEX IO(帳戶 `d1tiendas`),因此此工具透過其公開商店 API 運作,完全不需要管理員金鑰。目錄和購物車完全匿名運作,而一次性電子郵件驗證碼則可解鎖訂單歷史。處理兩種會使天真的 D1 自動化出錯的陷阱:庫存是區域化的(未指定區域的查詢會回傳全國目錄,實際上無法購買)以及價格以兩種不同單位呈現(搜尋回傳整數披索,結帳回傳百分之一披索,相差 100 倍)。可以建立購物籃並報價;但刻意無法付款,而是將結帳 URL 交給人類處理。在以下情況使用:使用者想查詢 D1 產品或價格、確認 D1 是否運送到某處、建立或計算 D1 購物籃花費、比較 D1 商品、或查閱他們的 D1 訂單。不適用於其他哥倫比亞零售商(Éxito、Jumbo、Ara、Alkosto),也**不**適用於...

skills 是什麼?

broomva/skills 是一個命令列工具,能夠與哥倫比亞最大折扣連鎖超市 Tiendas D1 的公開商店 API 進行互動。它透過 VTEX IO 平台(帳戶 `d1tiendas`)運作,無需任何管理員金鑰或爬蟲,使目錄搜尋、購物車建立和價格查詢完全匿名。此工具處理了兩個常使自動化失效的關鍵細節:庫存是區域化的(必須先設定送貨地點,才能看到準確的價格和庫存)以及價格單位在搜尋(整數披索)和結帳(百分之一披索)之間有所不同,它會自動將所有內容標準化為百分之一披索。它支援搜尋產品、查詢分類、取得替代建議、建立購物籃、估算運費和產生訂單歷史記錄,但它刻意不處理付款行為,而是將結帳 URL 交給人類使用者。此工具使用 TypeScript 和 Bun 執行,並提供結構化的 `--json` 輸出以及合約化的退出碼(0 表示成功、1 表示暫時錯誤、2 表示使用錯誤、3 表示有效但結果為空),使其非常適合整合到 AI 代理人和開發工作流程中。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/broomva/skills/tree/HEAD/skills/commerce/d1-cli

在你喜歡的 AI 中提問

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

說明文件

d1-cli — 在命令列上使用 Tiendas D1

D1 是哥倫比亞最大的硬折扣連鎖超市。其商店前後端運行在 VTEX IO 上(帳戶 d1tiendas),這意味著該網站自身的公開 API 就是整合介面——無需爬蟲,也無需管理員憑證。

執行

cd skills/commerce/d1-cli

# 1. 首先設定您的送貨點——其他所有步驟都依賴於它
bun run src/cli.ts region --lat 4.6486 --lng=-74.0628

# 2. 然後搜尋:價格和庫存現在是您指定門市的,而非全國的
bun run src/cli.ts search leche entera --count 5
bun run src/cli.ts search --facets category-1/lacteos-y-huevos --sort price:asc

# 3. 在不動到購物車的情況下為購物籃報價
bun run src/cli.ts quote 262:2 892:1

# 3b. 或者讓預算決定內容——使用條件而非 SKU
bun run src/cli.ts basket --budget 30000 arroz leche aceite huevos

# 4. 或者建立一個真實的購物車,然後交給人類付款
bun run src/cli.ts cart add 262 --qty 2
bun run src/cli.ts cart deliver-to
bun run src/cli.ts cart checkout      # 輸出一個 URL;不進行付款

在任何指令後加上 --json 可獲得代理人可讀的輸出。退出碼是一種合約,且此列表是唯一的副本:

代碼意義是否重試?
0執行成功—
1D1 拒絕或無法連線——無法送達的點、無庫存或未知 SKU、服務中斷是,可能會有幫助
2指令呼叫方式錯誤永遠沒有幫助
3執行成功且答案是「無」(substitute、basket)永遠沒有幫助

無法區分這些的代理人要不是永遠重試一個拼寫錯誤,就是在暫時性的服務中斷時放棄。3 的存在是因為一個空的分類並非錯誤。

請注意,cart add 設定該商品行數為 --qty,而不是增加。這是 D1 自身的語義,並已透過實際測試驗證。

導致天真的 D1 自動化出錯的兩件事

庫存是區域化的。 在未指定區域的情況下查詢目錄時,D1 會從全國目錄中回答,針對虛擬賣家 1 回報舒適的 10,000 件庫存。將同一個 SKU 放入針對真實地址的結帳模擬中,它會回傳 withoutStock,因為實際負責運送的那家門市沒有庫存。請務必先使用 d1 region;當 CLI 顯示的是全國價格時,它會以純文字的形式發出警告。

解析區域也是 API 中最難猜測的部分:座標必須以 geoCoordinates={lon};{lat} 的格式傳入——以分號分隔,經度在前。VTEX 自己的 JSON 主體中使用的是逗號,但此處使用逗號會被以 CHK0119(「地址必須包含郵遞區號或地理座標」)拒絕——這則訊息看起來像是參數缺失,而非格式錯誤。test/region.test.ts 固定了此行為,以防止後續清理時意外更改。

價格以兩種單位呈現。 對於 SKU 262(Latti 全脂牛奶 900 毫升,貨架價格為 COP 3,500):

API欄位值單位
intelligent-searchPrice3500整數披索
catalog_systemPrice3500.0整數披索
checkout orderFormsellingPrice350000百分之一披索

兩者都沒有標示其單位。catalog.ts 在邊界處將所有內容標準化為百分之一披索,因此其餘程式碼只有一種單位,並且一個測試斷言從搜尋獲得的價格與從結帳獲得的價格呈現方式相同。

它不會做什麼

d1 會建立購物籃並報價。它不會進行付款。d1 cart checkout 會輸出一個 URL,供人類審查總金額並完成付款。

該邊界在同一個列表(src/endpoints.ts)的兩個地方進行檢查:在執行時期,D1Client.request 會在請求離開程序之前,拒絕任何解析後的 URL 不是 D1 自身來源加上 18 個已核准路徑之一的請求;靜態檢查方面,test/safety.test.ts 會在 src/ 下任何地方的任何 /api/ 符合未獲核准時失敗。新增端點(付款或其他)在將其列入白名單之前會一直失敗,因此這個決定是經過考量的,而非預設允許的。

執行時期的檢查是關鍵的,並且是在審查後發現靜態掃描不足時加入的:--facets '../../../..' 可以從搜尋端點解析到訂單結算,而所有原始碼的關鍵字仍然是核准的。

準確地說,因為這個檔案的早期版本過於自信:沒有什麼可以阻止具有寫入權限的提交者編輯白名單。儲存庫內的測試無法做到這一點。

它儲存的唯一憑證是商店前端的會話 Token——與已登入瀏覽器持有的相同,範圍限定於其擁有者的訂單和購物車——以模式 0600 寫入 ~/.config/d1-cli/session.json。任何地方都不會讀取 VTEX 管理員的 appKey/appToken。登入是透過一次性電子郵件驗證碼;刻意未實作密碼驗證。

結帳閘門——始終在此結束

每個購物籃都以 d1 cart checkout 結束,並根據其退出碼採取行動。 這不是形式上的要求:它是唯一一個會根據 D1 此時此刻的狀態重新檢查整個購物車的指令,而購物車會因為其他指令無法發現的原因而過時。

0  每項商品均可送達——URL 可以安全交給使用者
1  至少有一項商品無法送達;URL 會被輸出,但購物車已損壞
2  指令呼叫方式錯誤

此檢查的存在是因為在真實的購物籃中,每種情況都發生過:

  • 某項商品隔夜售罄。 PAN ARTESANAL INTEGRAL 在加入後幾個小時就變成 no tiene inventario。購物車仍然可以顯示,仍然有總金額——但總金額默默地少了 6.490 披索,因為已售罄的商品行已從總金額中移除。
  • 地址變更導致所有商品無法送達。 九項商品回傳 cannotBeDelivered,而每項商品仍然有有效的 SLA,並且購物車仍然顯示一個可支付的總金額。
  • 運費被低估了 12 倍,原因是按商品行分配的費用看起來像總金額。

在這三種情況下,購物車看起來是正常的。在會話中稍早取得的報價,並不能作為當前購物車的證據,所以永遠不要交出你在最後一次修改之前取得的結帳 URL——請重新執行這個閘門檢查。

當它回傳 1 時,--json 會提供 undeliverable[] 列出問題商品,以及 readyToCheckout: false。請移除或替換那些商品行,然後再次執行。

替換 D1 無法提供的商品

d1 substitute 192 --limit 5        # 從相同分類中對有庫存的商品進行排名

退出碼 0 表示有東西可以推薦;退出碼 3 表示沒有——這是與 d1 basket 並列,唯二使用退出碼 3 的指令。

使用 3 而不是 1,其區別是關鍵所在:在 CLI 的其他地方,1 表示 「D1 拒絕連線,或無法連線」,並允許重試。一個空的分類永遠不會因為重試而變得非空,因此使用重試-1 策略的代理人會永遠循環。退出碼 0 伴隨著空列表是另一個錯誤答案——它會被視為成功並被執行。

每個候選商品都會說明改變了什麼:品牌、包裝尺寸、每公斤或每公升價格、包裝價格,以及任何新增或移除的 Ley 2120 警告。這是輸出內容,不是分數。相同的 900 毫升和相同標籤下,每公升便宜 -12% 是一個不同的方案,而附帶 Exceso en Azúcares 警告的又是另一個方案,只有差異才能區分它們。

僅供推薦,請勿直接採用。 substitute 永遠不會寫入——它會輸出 d1 cart add 命令供人類核准。這並非為了謹慎而謹慎:顧客兩次都明確表示偏好移除某項商品,而不是接受錯誤的替代品,而且兩次都是對的。請呈現候選商品及其利弊;讓使用者決定,並願意取消該商品。

有三件事值得關注:

  • 「此商品在您的門市仍有庫存。」 庫存是依門市而異的,因此其他門市缺貨的商品,此門市可能還有。在替換任何商品之前請先檢查。如果沒有提供 --lat/--lng,它會這樣說,而不是猜測——因為沒有門市可以做出基於門市的庫存聲明。
  • 「擴展到 3 個層級中的第 2 級」——葉子分類中沒有庫存,因此建議來自更廣泛的通道,相應地也比較寬鬆。
  • 「僅比較了 N 個項目」——該分類大於一個頁面。請提高 --count。這在空結果時也會顯示,因為*「此處無庫存」*的斷言建立在部分掃描的基礎上,更需要說明其限制。

在需求模糊時尋找商品

對於「我們需要米」而不是「購買 SKU 1092」這類需求,有兩個維度很重要,但都不是預設值:

按單位價格排序,而非包裝價格。 --sort per-unit 使用哥倫比亞法律要求 D1 公佈的 PUM 資料。這兩種排序方式確實存在分歧:ARROZ ESTÁNDAR 500 GRS 是最便宜的包裝,售價 $1.550,每公斤成本為 $3.100,而同一結果中最佳性價比是每公斤 $2.775——裝在一個 $5.550 的袋子裡,這個袋子根本不會出現在包裝價格排名前五中。按包裝價格排序會得到一個較差的答案,但看起來卻很合理。

由於 D1 的搜尋無法對此進行排序,--sort per-unit 會對您所獲取的頁面進行排序,而非整個結果集。請提高 --count(最多 50 個)以擴大範圍。輸出會說明這一點,而不是暗示一個它無法支持的極致結果,並且會指出有多少結果沒有公佈尺寸,因此無法進行比較。

多件包的標示尺寸是整個包裝的尺寸,而非單件——請勿「修正」它。 對所有 1,600 種產品的普查發現,在名稱可匹配的多件包中,D1 有足夠資訊可以決定的 46 個產品中,有 44 個標示的是包裝總量。從產品名稱中解析出 N UN 並進行乘法運算,將會破壞那 44 個,只為了修正 2 個。名稱中的數量並非 PUM 含義的證據。

因此,resolvePackSize 會讀取描述而非名稱。在所有 1,548 個帶有 PUM 的產品中,它只針對描述中同時說明了單件尺寸和數量的 10 個產品採取行動:三個被修正(SKU 718、510、1008),七個被確認為已正確標示包裝尺寸,而其餘所有產品則保持不變。

閱讀警告標籤。 產品帶有哥倫比亞的正面包裝警告(Exceso en Azúcares、Exceso en sodio、Exceso en grasas saturadas、Exceso en grasas trans、Contiene Edulcorantes)在 --json 輸出的 warnings[] 中。覆蓋率是部分的——大約按分類介於 70-90%——因此缺失表示「未申報」,絕不表示「安全」。

然後在分頁之前,使用 d1 facets <query>(分類、品牌、子分類及計數)進行縮小:搜尋上限為 50 頁,因此一個廣泛的查詢更適合透過面向來縮小,而不是逐頁瀏覽。

指令

指令功能
region --lat --lng解析並記住送貨點
search <query>尋找產品(--facets --sort --count --page --available)
suggest <partial> · trending自動完成 · 哥倫比亞正在搜尋的內容
categories · facets [query]部門樹狀圖 · 查詢的篩選條件
substitute <sku>該買什麼替代品,以及改變了什麼(--limit --count)
quote <sku>[:qty]...為購物籃報價,不修改購物車
cart [show|add|set|clear|deliver-to|checkout]建立購物籃
login --email / --from-cookie · whoami · logout帳戶管理
orders · order <id>訂單歷史(詳細資訊會根據允許清單進行編輯;使用 --raw 可選擇加入)
stores near查詢附近的 D1 門市——僅限位置,D1 不提供到店取貨服務

測試

bun test        # 貨幣單位、分號陷阱、報價中的數量、
                # 未知 SKU 的空值、購物車標準化、訂單編輯、以及
                # 界定付款範圍的端點允許清單
bun run lint && bun run typecheck

退出碼是一種合約,而非裝飾——上方 執行 下的表格是其唯一的副本。

請參閱 README.md 了解完整的端點對應表、運送層級行為以及公開 API 不會提供的內容。

Individual skills in this repo

This repo contains 7 individual skills — each has its own dedicated page.

broomva/skills

Local TTS, voice cloning, voice design, and video dubbing via the OmniVoice Studio MCP server (open-source ElevenLabs alternative; nothing leaves the machine, runs on MPS/CUDA/CPU). Use when: (1) generating speech from text in any of 646 languages, (2) cloning a voice from a 3-second reference clip, (3) designing a voice by gender/age/accent/pitch/style, (4) dubbing a video into another language, (5) listing voice profiles or personality presets, (6) producing narration where privacy, cost, or absent API keys matter, (7) non-English narration where Edge TTS/kokoro fall short, (8) batch audio for blog posts or content pipelines. Triggers: 'omnivoice', 'voice clone', 'clone this voice', 'tts', 'narrate', 'generate speech', 'voice synthesis', 'dub video', 'voice design', 'local tts', 'multilingual voice', 'narrate this post', 'elevenlabs alternative'.

broomva/skills

>- Speak an explanation out loud while working in any project — tiered text-to-speech with a pluggable backend (ElevenLabs by default and quota-guarded, macOS `say` via `--fast` for free instant local speech, local OmniVoice as an unlimited private tier). Markdown-aware, so code fences, URLs and deep paths collapse to short spoken placeholders instead of being dictated character by character, while snake_case identifiers survive intact so the listener can still search for them. Every utterance is saved to disk for later replay. Also carries a **talk mode** toggle: turn it on and the agent speaks a full readback of every turn, for as long as that session lasts — the whole response, not a summary of it, with `brief` and `marker` levels for when you want less. Talk mode is off by default and scoped to the single session that enabled it, so parallel agents in other worktrees stay silent. Use when the user asks to hear something rather than read it — an explanation of a change, a walkthrough of what just happen...

broomva/skills

Stateful, local-first household toxics inventory + swap engine. Identify the items in a home that carry endocrine disruptors and persistent chemicals (BPA/BPS, phthalates, PFAS/PTFE, parabens, flame retardants, VOCs, microplastics), score each by *real* exposure (severity x presence x how it's used x condition), and track the swap to a safer alternative from "flagged" -> "sourced" -> "swapped". Ships a grounded, cited knowledge graph of ~20 hazards, ~40 item-classes, and ~40 alternatives. Hands sourcing off to the `procurer` skill. The skill's state is the source of truth — the agent is the app.

broomva/skills

Tekton — the shared architecture-intent substrate for co-designing systems with the agent. One typed graph across six tiers (system / journey / data / infra / decisions / qualities); views are queries, not separate diagrams. The canonical artifact is a diff-friendly YAML model both human and agent read and write; it renders to Mermaid (agent-legible, GitHub-native) and a self-contained tabbed HTML viewer (human-visual). Cross-tier traceability (`tekton query <from> <to>`) answers "which infra does this user-journey step touch?" as a path query. USE WHEN: designing or thinking deeply about architecture, a system, a data model, user journeys/flows, or a technical plan WITH the agent; when a Category-C HTML doc isn't enough because you need to see AND edit AND traverse the design across tiers; "let's design X", "architect this", "model the system", "draw the flow", "how does this fit together", "diagram this", "/tekton". NOT FOR: a one-off throwaway diagram (use Mermaid inline); prose-only ADRs (write the ADR...

broomva/skills

Generate a polished Remotion video and X thread showcasing the full agent skills inventory. Use when creating social media content about skills, rendering category-based skill visualizations, or producing animated showcases of agent capabilities. Triggers on "skills video", "showcase skills", "skills thread", "render skills", "social content for skills", or requests to visualize the skills inventory.

broomva/skills

OpenCaptions extension for Content Engine — adds intent-driven CWI (Caption With Intent) captions to the post-production pipeline. Hooks into the grade → caption → final stage. Generates captions that understand video intent (pitch, volume, emotion, emphasis) and style themselves accordingly with variable font weight, size, and color. Uses the OpenCaptions CLI or MCP server. Triggers on: 'add captions', 'opencaptions', 'CWI captions', 'intent captions'.

broomva/skills

Produce polished product launch videos using the Liquid Glass aesthetic — dark void backgrounds, 3D perspective floating UI panels, particle effects, spring animations, and cinematic pacing. Built on Remotion with Imagen 4.0 for frames and Veo 3.1 for B-roll. Use when: (1) creating a product demo or launch video, (2) showcasing a UI/app/tool with cinematic polish, (3) building a social-ready video from screenshots and renders, (4) applying the liquid glass floating panel style, (5) composing Remotion videos with 3D transforms and spring animations. Triggers on: 'launch video', 'product video', 'liquid glass video', 'demo video', 'showcase video', 'remotion video', 'floating panel', 'glass aesthetic'.

相關技能