Communitygithub.com

d1-cli — Tiendas D1 (コマンドライン)

コロンビアのハードディスカウントスーパー「Tiendas D1」をコマンドラインから操作します。商品検索、最寄り店舗の特定、実際の在庫に基づく買い物かごの価格計算、配送見積もりを実行できます。

d1-cli — Tiendas D1 (コマンドライン) とは?

このスキルは、コロンビア最大のハードディスカウントスーパーマーケットチェーン「Tiendas D1」(VTEX IOアカウント `d1tiendas` 上で稼働)をコマンドラインから完全に操作するためのCLIツールです。公開ストアフロントAPIのみを使用し、スクレイピングや管理認証情報は不要で、カタログ検索やカート操作は完全に匿名で行えます。注文履歴の確認には、ワンタイムメールコードによるログインが必要です。このツールは、D1自動化でよくある2つの落とし穴(地域化されていない在庫と、価格単位の違い)を適切に処理します。商品検索、価格照会、買い物かごの作成(支払いはせず、人間にチェックアウトURLを渡す)が可能で、Claude Code、Cursor、CodexなどのAIエージェントが利用することを想定しています。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/broomva/skills/tree/HEAD/skills/commerce/d1-cli

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

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 でこの動作を固定しているため、後方互換性を壊す変更はできません。

価格は2つの単位で届きます。 SKU 262(Leche Entera Latti 900 ml、店頭価格 COP 3,500)の場合:

APIフィールド値単位
intelligent-searchPrice3500ペソ(整数)
catalog_systemPrice3500.0ペソ(整数)
checkout orderFormsellingPrice350000ペソの100分の1

どちらも単位をラベル付けしていません。catalog.ts は境界ですべてを100分の1単位に正規化し、残りのコードが一つの単位だけを持つようにします。また、検索から得られた価格がチェックアウトから得られた価格と同一にレンダリングされることをテストでアサートしています。

実行しないこと

d1 は買い物かごを構築し、価格を計算します。支払いは行いません。d1 cart checkout は、人間が合計金額を確認し、支払いを完了するためのURLを出力します。

この境界は、一つのリスト(src/endpoints.ts)から二箇所でチェックされます: 実行時、D1Client.request は、解決されたURLがD1自身のオリジンであり、18の承認済みパスのいずれかであることを確認し、そうでなければリクエストをプロセスから送信する前に拒否します。静的分析では、test/safety.test.ts は、src/ 以下のどこかに承認されていない /api/ リテラルがあれば失敗します。エンドポイント(支払いやその他)を追加するには、それがリストに登録される必要があり、決定がデフォルトではなく明示的に行われます。

実行時の部分は重要であり、静的分析だけでは不十分であることがレビューで判明した後に追加されました: --facets '../../../..' により、すべてのソースリテラルが承認されたまま、検索エンドポイントから注文決済エンドポイントにパスが解決されていました。

正確に言うと、このファイルの以前のバージョンでは過剰に主張していました。ここにあるものは、書き込みアクセス権を持つコミッターが許可リストを編集することを防ぐことはできません。リポジトリ内のテストでは不可能です。

保存される唯一の認証情報は、ストアフロントセッショントークンです。これは、サインインしたブラウザが保持するものと同じで、所有者自身の注文とカートにスコープされ、~/.config/d1-cli/session.json にモード 0600 で書き込まれます。VTEX管理の appKey/appToken はどこでも読み取られません。サインインはワンタイムメールコードによって行われます。パスワード認証は意図的に実装されていません。

チェックアウトゲート — 常にここで終了する

すべての買い物かごは d1 cart checkout で終了し、その終了コードに従って行動してください。 形式的なものではありません。これは、カート全体を現在のD1の状態と再チェックする唯一のコマンドであり、他の方法では表面化しない方法でカートが古くなることがあります。

0  すべてのラインが配送可能 — URLは安全に引き渡せる
1  少なくとも1つのラインが配送不可能 — URLは出力されるが、カートは壊れている
2  コマンドの呼び出し方に誤りがある

これは、実際の買い物かごで以下のそれぞれが発生したために存在します:

  • 一晩で品切れになったライン。 PAN ARTESANAL INTEGRAL は、カートに追加されてから数時間後に no tiene inventario になりました。カートはまだレンダリングされ、合計金額も表示されていましたが、その合計金額は、死んだラインが落ちたため、静かに6.490軽くなっていました。
  • 住所変更によりすべてのラインが機能しなくなった。 9つのアイテムが cannotBeDelivered を返したが、それぞれはまだ有効なSLAを持ち、カートはまだ支払い可能な合計金額を表示していました。
  • 配送料が12倍過小報告されていた。 ラインごとの割り当てが合計のように見えていた。

3つすべてにおいて、カートは 問題なく見えました。セッションの早い段階で取得した見積もりは、現在のカートに関する証拠にはなりません。最後の変更の前に取得したチェックアウトURLを決して引き渡さないでください — ゲートを再実行してください。

1が返された場合、--json は問題のあるラインを指定する undeliverable[] と、readyToCheckout: false を返します。それらのラインを削除または置き換えて、再度実行してください。

D1が供給できないラインの置き換え

d1 substitute 192 --limit 5        # 同じカテゴリから在庫のある製品をランク付けします

終了コード0は、提案できるものがあることを意味します。3は、提案できるものがないことを意味します — d1 basket と並んで 3 を使用する2つのコマンドのうちの1つです。

3であり1ではありません。その区別が重要です: 1 は、このCLIの他のすべての場所で 「D1が拒否した、または到達できなかった」 を意味し、再試行を促します。空のカテゴリは再試行しても空のままです。そのため、1のときに再試行するポリシーのエージェントは、永久にループします。空のリストで終了コード0は、もう一つの間違った答えです — 成功として読み取られ、実行されてしまいます。

各候補は、何が変わるのかを名前で示します: ブランド、パックサイズ、$/kg または $/L、パック価格、そして獲得または喪失したLey 2120警告。これは出力であり、スコアではありません。同じ900mlで同じラベルに対して1リットルあたり -12% は、Exceso en Azúcares が付いたものとは異なる提案であり、デルタだけがそれらを区別します。

提案は行いますが、実行はしません。 substitute は決して書き込みません — 承認のために人間が d1 cart add するものを出力します。これは単なる慎重さのためではありません。顧客は、間違った代替品よりもラインを 削除する ことを2度好み、そう明示的に述べ、そのたびに正しかったのです。候補とトレードオフを提示し、人間に決定を委ね、ラインを削除する用意をしてください。

読む価値のある3つのことを伝えます:

  • 「この商品はあなたの店舗でまだ在庫があります。」 在庫は店舗ごとなので、他の場所で失敗したラインでもここでは問題ないかもしれません。何かを置き換える前に確認してください。--lat/--lng がない場合は、推測する代わりにそのように伝えます — 店舗別の主張を行うための店舗が存在しないからです。
  • 「レベル2/3に拡大しました」 — リーフカテゴリに在庫がなかったため、提案はより広い売り場からのものであり、それに応じて緩くなります。
  • 「N個のみが比較されました」 — カテゴリは1ページよりも大きいです。--count を増やしてください。これは空の結果にも出力されます。なぜなら、「ここには在庫のあるものは何もない」 という主張は、部分的なスイープに対してなされた場合、注意書きがより必要だからです。

不明確なリクエストの場合の検索

「SKU 1092を買う」ではなく「米が必要」の場合、二つの軸が重要であり、どちらもデフォルトではありません:

パック価格ではなく、単価でランク付けします。 --sort per-unit は、コロンビアの法律でD1に公開が義務付けられているPUMデータを使用します。二つのランキングは実際に異なります: ARROZ ESTÁNDAR 500 GRS は最も安い パック で $1.550、$3.100/kg ですが、同じ結果で最もお買い得なのは $2.775/kg — $5.550の袋で、パック価格トップ5にはどこにも現れません。パック価格でランク付けすると、正しく見えるが悪い答えになります。

D1の検索はこれでソートできないため、--sort per-unit は、取得したページ を並べ替えます。結果セット全体ではありません。--count(最大50)を増やして範囲を広げてください。出力は、それがサポートできない最上級を暗示するのではなく、そのように伝え、サイズを公開していないため全く比較できない結果の数を示します。

マルチパックの宣言サイズはパック全体であり、1つのアイテムではありません — 「修正」しないでください。 全1,600製品の調査では、名前が一致するマルチパックの中で、D1が判断に十分な情報を提供している46製品のうち44製品がパック合計を宣言していました。製品名から N UN を解析して乗算すると、2つを修正するために44を壊してしまいます。名前に含まれる数は、PUMが何を意味するかについての証拠ではありません。

したがって、resolvePackSize は名前ではなく説明を読み取ります。PUMを持つ全1,548製品のうち、説明にアイテムあたりのサイズと数量の両方が記載されている10製品に対して動作します: 3つが修正され(SKU 718、510、1008)、7つが既にパックを宣言していることが確認され、その他すべては宣言されたままにされます。

警告ラベルを読んでください。 製品はコロンビアのパッケージ前面警告(Exceso en Azúcares、Exceso en sodio、Exceso en grasas saturadas、Exceso en grasas trans、Contiene Edulcorantes)を warnings[] として --json で伝えます。カバレッジは部分的です(カテゴリによって約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

終了コードは契約であり、飾りではありません — 上記 実行方法 の表が単一のコピーです。

完全なエンドポイントマップ、配送ティアの動作、公開APIで得られないものについては README.md を参照してください。

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'.

関連スキル