From wire
Build multi-turn shopping assistant chat interface
How this command is triggered — by the user, by Claude, or both
Slash command
/wire:ac_conversational_assistant-generate <release-folder>The summary Claude sees in its command listing — used to decide when to auto-load this command
# Build multi-turn shopping assistant chat interface ## User Input ## Path Configuration - **Projects**: `.wire` (project data and status files) When following the workflow specification below, resolve paths as follows: - `.wire/` in specs refers to the `.wire/` directory in the current repository - `TEMPLATES/` references refer to the templates section embedded at the end of this command ## Workflow Specification --- description: Implement multi-turn conversational shopping assistant with intent detection argument-hint: <project-folder> --- # Agentic Commerce — Conversational Assi...
$ARGUMENTS
.wire (project data and status files)When following the workflow specification below, resolve paths as follows:
.wire/ in specs refers to the .wire/ directory in the current repositoryTEMPLATES/ references refer to the templates section embedded at the end of this commandBuild a full-featured conversational shopping assistant that handles multi-turn chat, detects user intent, renders product cards inline, and integrates with the Zustand cart store. The assistant opens as a modal accessible from the hero, via Cmd+K, and from a mobile floating button.
/wire:ac_conversational_assistant-generate YYYYMMDD_project_name
storefront.review: approved in status.md.wire/<project_id>/status.mdstorefront.review == approvedsrc/lib/shopify.ts to understand product data shapesrc/stores/ to understand the Zustand cart store APIsupabase/functions/ to understand existing edge functionssrc/lib/analytics.ts to verify the trackEvent stub is presentCreate supabase/functions/shopping-assistant/index.ts.
Provide the following Claude Code prompt:
Create a Supabase edge function at supabase/functions/shopping-assistant/index.ts that:
1. Accepts a JSON body with { message: string, conversationId: string | null }
2. Maintains conversation state across turns:
- If conversationId is null, generate a new UUID and start a fresh conversation
- Pass the conversationId to the underlying API so it can recall earlier turns
3. Calls [LLM or Conversational API] to process the message:
- System prompt: "You are a helpful shopping assistant for [STORE_NAME].
When users describe what they want, search for matching products.
Ask one clarifying question at a time. Keep replies concise (under 100 words).
When you have enough context, recommend 3-6 products."
- Pass the user message and conversation history
- Request structured output with fields: reply, intent, suggestedProducts[]
4. Detects intent from the model response and maps it to one of:
PRODUCT_SEARCH | REFINEMENT | GENERAL | CHECKOUT
5. Fetches matching products from the Shopify Storefront API using
the product handles or IDs returned by the AI
6. Returns:
{
reply: string,
products: ShopifyProduct[],
conversationId: string,
intent: "PRODUCT_SEARCH" | "REFINEMENT" | "GENERAL" | "CHECKOUT"
}
7. Handles errors gracefully — if the AI call fails, return:
{ reply: "I'm having trouble right now. Try searching above.", products: [], ... }
Read src/lib/shopify.ts to understand the existing product data structure and
Storefront API helper functions. Use the same storefrontApiRequest helper.
Create src/components/ShoppingAssistant.tsx.
Provide the following Claude Code prompt:
Create a ShoppingAssistant React component at src/components/ShoppingAssistant.tsx that:
1. Renders as a centered modal (Dialog) over the page, full-height on mobile
2. Has a chat interface with:
- A scrollable message list showing user and assistant bubbles
- User bubbles right-aligned (primary colour background)
- Assistant bubbles left-aligned (muted background)
- A loading indicator ("Assistant is thinking...") while awaiting a response
- Auto-scroll to the latest message after each reply
3. Renders product cards inline within assistant messages when products[] is non-empty:
- Product image (80x80px), title, price
- "Add to Cart" button that calls the existing Zustand cart store addToCart()
- "Try On" button (only when virtual try-on feature is available)
- Cards should not break the text flow — render them below the reply text
4. Shows shortcut pills when the conversation is empty (no messages yet):
- 3-4 pills with catalog-relevant prompts (e.g. "Gift ideas", "Best sellers",
"Summer gear", "New arrivals")
- Clicking a pill populates the input and submits immediately
5. Adapts layout based on the intent returned by the API:
- PRODUCT_SEARCH: prominent product grid, minimal text
- REFINEMENT: compact product list, reply text above
- CHECKOUT: show cart summary with "Go to Cart" button
- GENERAL: text only, no product section
6. Has a message input area at the bottom with:
- Text input (placeholder: "What are you looking for?")
- Send button (disabled while loading)
- Enter key submits the message
7. Calls supabase.functions.invoke("shopping-assistant", { body: { message, conversationId } })
and maintains conversationId in component state across turns
8. Tracks analytics by calling trackEvent("chat_message", { intent, hasProducts })
from src/lib/analytics.ts after each reply
9. Exports a named export: ShoppingAssistant
Provide the following Claude Code prompt:
Add three entry points to open the ShoppingAssistant modal:
1. In the hero section of src/pages/Index.tsx (or wherever the hero component lives):
Add a "Chat with our AI Assistant" button with a chat bubble icon.
It should be prominent — a secondary CTA below the main hero button.
2. Global keyboard shortcut Cmd+K (Mac) / Ctrl+K (Windows):
In the root App.tsx (or a layout component), add a useEffect that listens for
the keydown event and opens the ShoppingAssistant modal when the shortcut fires.
Show a small pill hint "Press ⌘K" in the navbar on desktop.
3. Floating action button on mobile (md:hidden):
A fixed bottom-right circular button with a chat icon.
z-index should be below the cart drawer but above page content.
Use a shared isAssistantOpen / setIsAssistantOpen state (or context) to control
the modal from all three entry points.
.wire/<project_id>/status.mdconversational_assistant section:conversational_assistant:
generate: complete
validate: not_started
review: not_started
generated_date: YYYY-MM-DD
files:
- supabase/functions/shopping-assistant/index.ts
- src/components/ShoppingAssistant.tsx
## Conversational Assistant Generated
**Files created:**
- supabase/functions/shopping-assistant/index.ts
- src/components/ShoppingAssistant.tsx (modal + entry points)
### Next Steps
1. Add your AI provider credentials as Supabase secrets:
- Vertex AI: GOOGLE_APPLICATION_CREDENTIALS_JSON, GCP_PROJECT_ID
- OpenAI-compatible: OPENAI_API_KEY (or GEMINI_API_KEY)
2. Deploy the edge function:
```bash
supabase functions deploy shopping-assistant
/wire:ac_conversational_assistant-validate <project>
## Edge Cases
### Conversation State Lost
If the AI provider does not maintain server-side conversation history, implement
a client-side fallback: store the full message history in component state and
pass it as a `history` array in the request body. The edge function should
use this when a stateful conversationId is not available.
### LLM Returns No Products for a Product-Intent Query
If intent is `PRODUCT_SEARCH` or `REFINEMENT` but `products[]` is empty, the edge
function should fall back to calling the `semantic-search` edge function directly
using the user's message as the query. Merge results before returning.
### Modal Accessibility
Ensure the modal:
- Traps focus within when open
- Returns focus to the trigger button on close
- Has `aria-modal="true"` and a descriptive `aria-label`
- Can be dismissed with the Escape key
## Output
This command produces:
- `supabase/functions/shopping-assistant/index.ts`
- `src/components/ShoppingAssistant.tsx`
- Three entry points wired into the existing storefront
- Updated `.wire/<project_id>/status.md`
Execute the complete workflow as specified above.
## Execution Logging
After completing the workflow, append a log entry to the project's execution_log.md:
# Execution Log — Command and Skill Logging
## Purpose
After completing any generate, validate, or review workflow (or a project management command that changes state), append a single log entry to the project's execution log file. Skills also append an entry on activation, making the log a unified trace of all agent activity — both explicit commands and auto-activated skills.
## Log File Location
<DP_PROJECTS_PATH>/<project_folder>/execution_log.md
Where `<project_folder>` is the project directory passed as an argument (e.g., `20260222_acme_platform`).
## Format
If the file does not exist, create it with the header:
```markdown
# Execution Log
| Timestamp | Command | Result | Detail |
|-----------|---------|--------|--------|
Then append one row per execution:
| YYYY-MM-DD HH:MM | /wire:<command> | <result> | <detail> |
YYYY-MM-DD HH:MM format (24-hour, local time)/wire:* command invoked, or skill for a skill activation entrycomplete — generate command finished successfullypass — validate command passed all checksfail — validate command found failuresapproved — review command: stakeholder approvedchanges_requested — review command: stakeholder requested changescreated — /wire:new created a new projectarchived — /wire:archive archived a projectremoved — /wire:remove deleted a projectactivated — a skill was auto-activated (used with skill in the Command column)When a skill activates, it appends a row in the same format as commands, using skill in the Command column and the skill identifier in the Result column:
| YYYY-MM-DD HH:MM | skill | <skill-identifier> | activated | <brief trigger description> |
Skill identifiers:
| Skill | Identifier |
|---|---|
| Engagement Context | engagement-context |
| Research Persistence | research-persistence |
| dbt Development | dbt-development |
| LookML Content Authoring | lookml-authoring |
| dbt Analytics QA | dbt-analytics-qa |
| dbt Migration | dbt-migration |
| dbt Troubleshooting | dbt-troubleshooting |
| dbt Semantic Layer | dbt-semantic-layer |
| dbt Unit Testing | dbt-unit-testing |
| dbt DAG | dbt-dag |
| Dagster | dagster |
| Fivetran | fivetran |
| Project Review | project-review |
| Looker Dashboard Mockup | looker-dashboard-mockup |
This makes skill activations visible in the same log that captures command invocations, enabling full activity tracing across both explicit commands and automatic skill triggers.
|, replace with — to preserve table formatting# Execution Log
| Timestamp | Command | Result | Detail |
|-----------|---------|--------|--------|
| 2026-02-22 14:30 | skill | engagement-context | activated | Context loaded for new conversation |
| 2026-02-22 14:35 | /wire:new | created | Project created (type: full_platform, client: Acme Corp) |
| 2026-02-22 14:40 | /wire:requirements-generate | complete | Generated requirements specification (3 files) |
| 2026-02-22 15:12 | /wire:requirements-validate | pass | 14 checks passed, 0 failed |
| 2026-02-22 16:00 | /wire:requirements-review | approved | Reviewed by Jane Smith |
| 2026-02-23 09:15 | /wire:conceptual_model-generate | complete | Generated entity model with 8 entities |
| 2026-02-23 10:30 | /wire:conceptual_model-validate | fail | 2 issues: missing relationship, orphaned entity |
| 2026-02-23 11:00 | /wire:conceptual_model-generate | complete | Regenerated entity model (fixed 2 issues, 8 entities) |
| 2026-02-23 11:15 | /wire:conceptual_model-validate | pass | 12 checks passed, 0 failed |
| 2026-02-23 14:00 | /wire:conceptual_model-review | changes_requested | Reviewed by John Doe — add Customer entity |
| 2026-02-23 15:30 | /wire:conceptual_model-generate | complete | Regenerated entity model (9 entities, added Customer) |
| 2026-02-23 15:45 | /wire:conceptual_model-validate | pass | 14 checks passed, 0 failed |
| 2026-02-23 16:00 | /wire:conceptual_model-review | approved | Reviewed by John Doe |
npx claudepluginhub rittmananalytics/wire-plugin --plugin wire