Initial commit of Descrybe v2 without local scratch artifacts.

Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
2026-08-09 22:47:43 +02:00
commit 8580c996c3
1285 changed files with 325780 additions and 0 deletions
+716
View File
@@ -0,0 +1,716 @@
import type { IntentDefinition, IntentId } from "./types.ts";
import { ADD_FEED_SELECTOR, MAP_FIELDS_SELECTOR } from "./spotlight.ts";
/**
* Phrase → intent registry. Matching is deterministic keyword/phrase scoring.
* Keep phrases lowercase; matcher normalizes input the same way.
*/
export const INTENT_REGISTRY: IntentDefinition[] = [
{
id: "help_overview",
label: "Getting started",
phrases: [
"help",
"what can you do",
"how does this work",
"getting started",
"get started",
"overview",
"show me around",
"i am new",
"i'm new"
],
keywords: ["help", "start", "overview", "guide", "tour"],
description: "Overview of setup: fields, feeds, mapping, stores, processing, API keys.",
requiresConfirm: false,
canExecute: false,
route: "/dashboard",
selector: '[data-assistant-target="dashboard-welcome"],[data-tour="dashboard-welcome"]',
guideSteps: [
{ title: "Enable standard fields", detail: "Catalog → Standard Fields" },
{ title: "Add a feed", detail: "Feeds → Add Feed (URL or CSV upload)" },
{ title: "Map columns", detail: "Open Map on the feed, then Auto-map" },
{ title: "Connect a store (optional)", detail: "Stores → Shopify or WooCommerce" },
{ title: "Process products", detail: "Products or Sync + Process sample on the feed" },
{ title: "API keys (developers)", detail: "Account → Settings → API Keys" }
]
},
{
id: "identity_system",
label: "About this assistant",
phrases: [
"are you a bot",
"are you an ai",
"are you ai",
"are you chatgpt",
"are you an llm",
"are you a llm",
"are you a chatbot",
"are you human",
"is this chatgpt",
"is this an llm",
"what are you",
"who are you"
],
keywords: ["bot", "chatgpt", "llm", "chatbot"],
description: "Explain that this is the System assistant (built-in workflows).",
requiresConfirm: false,
canExecute: false,
route: "/dashboard",
guideSteps: [
{ title: "Navigate the app", detail: "I open the right page and highlight controls" },
{ title: "Run supported actions", detail: "After you confirm, I can call safe APIs" },
{ title: "Guide setup", detail: "Feeds, mapping, stores, attributes, processing, and more" }
]
},
{
id: "add_feed_url",
label: "Add feed from URL",
phrases: [
"add feed url",
"add a feed",
"import feed from url",
"create feed url",
"http feed",
"xml url",
"csv url",
"add product feed"
],
keywords: ["feed", "url", "http", "https", "xml", "csv", "import"],
description: "Create an input feed from an HTTP(S) XML or CSV URL.",
requiresConfirm: true,
canExecute: true,
route: "/feeds",
selector: ADD_FEED_SELECTOR,
guideSteps: [
{ title: "Open Feeds", detail: "Sidebar → Feeds" },
{ title: "Click Add Feed", detail: "Choose URL source" },
{ title: "Paste the feed URL", detail: "Pick XML or CSV type" },
{ title: "Create", detail: "Then map fields before syncing" }
]
},
{
id: "upload_feed",
label: "Upload feed file",
phrases: [
"upload feed",
"upload csv",
"upload xml",
"import csv file",
"add feed file",
"file upload feed"
],
keywords: ["upload", "file", "csv", "xml"],
description: "Create a feed by uploading a CSV (or XML) file.",
requiresConfirm: true,
canExecute: true,
route: "/feeds",
selector: ADD_FEED_SELECTOR,
guideSteps: [
{ title: "Open Feeds", detail: "Sidebar → Feeds" },
{ title: "Click Add Feed", detail: "Choose file upload" },
{ title: "Select your CSV", detail: "Name the feed and create" },
{ title: "Map fields", detail: "Auto-map, review, Save Mappings" }
]
},
{
id: "map_fields",
label: "Map feed fields",
phrases: [
"map fields",
"mapping",
"suggest mappings",
"auto map",
"auto-map",
"match columns",
"map my feed"
],
keywords: ["map", "mapping", "auto-map", "suggest", "columns"],
description: "Open feed mapping and use Auto-map / suggest mappings.",
requiresConfirm: true,
canExecute: false,
route: "/feeds",
// Map only — do not fall back to feeds-add (that spotlights Add Feed as if it were Map).
selector: MAP_FIELDS_SELECTOR,
guideSteps: [
{ title: "Open Feeds", detail: "Find the feed row" },
{ title: "Click Map", detail: "Opens the mapping screen" },
{ title: "Extract schema if needed", detail: "Then click Auto-map" },
{ title: "Review fuzzy matches", detail: "Confirm, then Save Mappings" }
]
},
{
id: "sync_feed",
label: "Sync a feed",
phrases: [
"sync feed",
"sync now",
"run sync",
"import products from feed",
"pull feed"
],
keywords: ["sync", "import", "pull"],
description: "Trigger a feed sync after mappings are saved.",
requiresConfirm: true,
canExecute: true,
route: "/feeds",
selector: '[data-assistant-target="feed-sync-now"],[data-tour="feed-sync-now"]',
guideSteps: [
{ title: "Confirm mappings are saved", detail: "Map → Save Mappings first" },
{ title: "On Feeds, click Sync now", detail: "Or use Sync + Process sample on Map" },
{ title: "Watch job status", detail: "Errors appear on the feed row" }
]
},
{
id: "open_standard_fields",
label: "Standard fields",
phrases: [
"standard fields",
"enable fields",
"product fields",
"enable recommended",
"catalog fields"
],
keywords: ["standard", "fields", "enable", "recommended"],
description: "Open Standard Fields and enable recommended columns.",
requiresConfirm: false,
canExecute: false,
route: "/standard-fields",
selector:
'[data-assistant-target="enable-recommended"],[data-tour="enable-recommended"]',
guideSteps: [
{ title: "Open Standard Fields", detail: "Catalog → Standard Fields" },
{ title: "Click Enable recommended", detail: "Or toggle individual fields" },
{ title: "Save if prompted", detail: "Mappings use enabled fields only" }
]
},
{
id: "connect_shopify",
label: "Connect Shopify",
phrases: [
"connect shopify",
"shopify",
"link shopify",
"shopify store",
"setup shopify"
],
keywords: ["shopify"],
description: "Open Shopify connector and enter shop domain + Admin API token.",
requiresConfirm: false,
canExecute: false,
route: "/stores/shopify",
selector:
'[data-assistant-target="store-connect-shopify"],[data-tour="store-connect-shopify"],[data-tour="store-card-shopify"]',
guideSteps: [
{ title: "Open Stores", detail: "Or go straight to Shopify" },
{ title: "Enter *.myshopify.com domain", detail: "Custom domains are not used for Admin API" },
{
title: "Paste Dev Dashboard Client ID + secret",
detail: "Or a legacy shpat_ token; then Save and Test Connection"
}
]
},
{
id: "connect_woocommerce",
label: "Connect WooCommerce",
phrases: [
"connect woocommerce",
"woocommerce",
"woo commerce",
"connect woo",
"link woo"
],
keywords: ["woocommerce", "woo"],
description: "Open WooCommerce connector entry point.",
requiresConfirm: false,
canExecute: false,
route: "/woocommerce",
selector:
'[data-assistant-target="store-connect-woocommerce"],[data-tour="store-connect-woocommerce"],[data-tour="store-card-woocommerce"]',
guideSteps: [
{ title: "Open Stores or WooCommerce", detail: "Pick WooCommerce card" },
{ title: "Enter store URL + API keys", detail: "Consumer key and secret" },
{ title: "Save and Test Connection", detail: "Fix reconnect banners if shown" }
]
},
{
id: "start_processing",
label: "Start processing",
phrases: [
"start processing",
"process products",
"run processing",
"generate descriptions",
"process catalog",
"process all products",
"process category"
],
keywords: ["process", "processing", "generate"],
description:
"Start a processing job for unprocessed products (all or a category), or open Products to select items.",
requiresConfirm: true,
canExecute: true,
route: "/products?type=raw&status=unprocessed",
selector:
'[data-assistant-target="start-processing"],[data-tour="start-processing"]',
guideSteps: [
{ title: "Ensure a feed is mapped and synced", detail: "Products need source data" },
{ title: "Open Products (unprocessed)", detail: "Select items on the page" },
{ title: "Choose processing types", detail: "Category, attributes, title, description" },
{ title: "Confirm and start", detail: "Watch credits and job status" }
]
},
{
id: "open_feeds",
label: "Open Feeds",
phrases: ["open feeds", "go to feeds", "show feeds", "feeds page"],
keywords: ["feeds"],
description: "Navigate to the Feeds list.",
requiresConfirm: false,
canExecute: false,
route: "/feeds",
selector: '[data-assistant-target="nav-feeds"],[data-tour="nav-feeds"],[data-tour="feeds-add"]',
guideSteps: [{ title: "You're on Feeds", detail: "Add a feed or open Map on an existing one" }]
},
{
id: "open_dashboard",
label: "Open Dashboard",
phrases: ["open dashboard", "go to dashboard", "show dashboard", "home page", "dashboard"],
keywords: ["dashboard", "home"],
description: "Navigate to the Dashboard overview.",
requiresConfirm: false,
canExecute: false,
route: "/dashboard",
selector: '[data-assistant-target="nav-dashboard"],[data-tour="nav-dashboard"]',
guideSteps: [{ title: "You're on Dashboard", detail: "Overview of catalog health and quick links" }]
},
{
id: "open_products",
label: "Open Products",
phrases: ["open products", "go to products", "show products", "products page", "product list"],
keywords: ["products", "catalog"],
description: "Navigate to the Products list.",
requiresConfirm: false,
canExecute: false,
route: "/products?status=completed&type=processed&page=1&sortBy=updatedAt&sortOrder=desc",
selector: '[data-assistant-target="nav-products"],[data-tour="nav-products"]',
guideSteps: [{ title: "You're on Products", detail: "Filter processed vs unprocessed as needed" }]
},
{
id: "open_categories",
label: "Open Categories",
phrases: ["open categories", "go to categories", "show categories", "categories page"],
keywords: ["categories"],
description: "Navigate to Categories.",
requiresConfirm: false,
canExecute: false,
route: "/categories",
selector: '[data-assistant-target="nav-categories"],[data-tour="nav-categories"]',
guideSteps: [{ title: "You're on Categories", detail: "Edit formulas and attribute assignments" }]
},
{
id: "open_export_feeds",
label: "Open Export Feeds",
phrases: ["open export feeds", "go to export feeds", "show export feeds", "export feeds"],
keywords: ["export"],
description: "Navigate to Export Feeds.",
requiresConfirm: false,
canExecute: false,
route: "/export-feeds",
selector: '[data-assistant-target="nav-export-feeds"],[data-tour="nav-export-feeds"]',
guideSteps: [{ title: "You're on Export Feeds", detail: "Configure outbound catalog feeds" }]
},
{
id: "open_stores",
label: "Open Stores",
phrases: ["open stores", "go to stores", "store hub", "stores page"],
keywords: ["stores"],
description: "Navigate to the Stores hub.",
requiresConfirm: false,
canExecute: false,
route: "/stores",
selector:
'[data-assistant-target="nav-stores"],[data-tour="nav-stores"],[data-assistant-target="store-hub"],[data-tour="store-hub"]',
guideSteps: [
{ title: "Pick Shopify, WooCommerce, or file upload", detail: "Connect before syncing channel data" }
]
},
{
id: "open_processing",
label: "Open Processing",
phrases: ["open processing", "go to processing", "show processing", "background tasks", "processing page"],
keywords: ["processing", "jobs", "tasks"],
description: "Navigate to Processing / job monitor.",
requiresConfirm: false,
canExecute: false,
route: "/processing",
selector: '[data-assistant-target="nav-processing"],[data-tour="nav-processing"]',
guideSteps: [{ title: "You're on Processing", detail: "Watch job status and retries" }]
},
{
id: "open_campaigns",
label: "Open Campaigns",
phrases: ["open campaigns", "go to campaigns", "show campaigns", "campaigns page"],
keywords: ["campaigns"],
description: "Navigate to Campaigns.",
requiresConfirm: false,
canExecute: false,
route: "/campaigns",
selector: '[data-assistant-target="nav-campaigns"],[data-tour="nav-campaigns"]',
guideSteps: [{ title: "You're on Campaigns", detail: "Create and manage marketing campaigns" }]
},
{
id: "open_content_calendar",
label: "Open Content calendar",
phrases: [
"open content calendar",
"go to content calendar",
"show content calendar",
"content calendar",
"marketing calendar"
],
keywords: ["calendar", "content"],
description: "Navigate to the Content calendar.",
requiresConfirm: false,
canExecute: false,
route: "/marketing/calendar",
selector: '[data-assistant-target="nav-content-calendar"],[data-tour="nav-content-calendar"]',
guideSteps: [{ title: "You're on Content calendar", detail: "Plan marketing content" }]
},
{
id: "open_seo",
label: "Open SEO",
phrases: ["open seo", "go to seo", "show seo", "seo page"],
keywords: ["seo"],
description: "Navigate to SEO tools.",
requiresConfirm: false,
canExecute: false,
route: "/seo",
selector: '[data-assistant-target="nav-seo"],[data-tour="nav-seo"]',
guideSteps: [{ title: "You're on SEO", detail: "Review SEO settings and suggestions" }]
},
{
id: "open_brand",
label: "Open Brand",
phrases: ["open brand", "go to brand", "show brand", "brand kit", "brand page"],
keywords: ["brand"],
description: "Navigate to Brand kit.",
requiresConfirm: false,
canExecute: false,
route: "/brand",
selector: '[data-assistant-target="nav-brand"],[data-tour="nav-brand"]',
guideSteps: [{ title: "You're on Brand", detail: "Logo, voice, and guidelines" }]
},
{
id: "open_reviews",
label: "Open Reviews",
phrases: ["open reviews", "go to reviews", "show reviews", "product reviews"],
keywords: ["reviews"],
description: "Navigate to Reviews (WooCommerce tab).",
requiresConfirm: false,
canExecute: false,
route: "/woocommerce?tab=reviews",
selector: '[data-assistant-target="nav-reviews"],[data-tour="nav-reviews"]',
guideSteps: [{ title: "You're on Reviews", detail: "Manage product reviews" }]
},
{
id: "open_ai_integrations",
label: "Open AI integrations",
phrases: [
"open ai integrations",
"go to ai integrations",
"ai integrations",
"ai settings",
"ai providers"
],
keywords: ["integrations", "byok", "providers"],
description: "Navigate to AI integrations.",
requiresConfirm: false,
canExecute: false,
route: "/integrations/ai",
selector: '[data-assistant-target="nav-ai"],[data-tour="nav-ai"]',
guideSteps: [{ title: "You're on AI integrations", detail: "Configure providers and keys" }]
},
{
id: "open_email_integrations",
label: "Open Email sending",
phrases: ["open email sending", "go to email", "email integrations", "email sending"],
keywords: ["email", "smtp"],
description: "Navigate to Email sending integrations.",
requiresConfirm: false,
canExecute: false,
route: "/integrations/email",
selector: '[data-assistant-target="nav-email"],[data-tour="nav-email"]',
guideSteps: [{ title: "You're on Email sending", detail: "Configure outbound email" }]
},
{
id: "open_billing",
label: "Open Billing",
phrases: ["open billing", "go to billing", "usage and billing", "show billing", "credits"],
keywords: ["billing", "usage", "credits"],
description: "Navigate to Usage & Billing.",
requiresConfirm: false,
canExecute: false,
route: "/billing",
selector: '[data-assistant-target="nav-billing"],[data-tour="nav-billing"]',
guideSteps: [{ title: "You're on Usage & Billing", detail: "Credits, plan, and invoices" }]
},
{
id: "open_settings",
label: "Open Settings",
phrases: ["open settings", "go to settings", "show settings", "company settings"],
keywords: ["settings"],
description: "Navigate to Settings.",
requiresConfirm: false,
canExecute: false,
route: "/settings",
selector: '[data-assistant-target="nav-settings"],[data-tour="nav-settings"]',
guideSteps: [{ title: "You're on Settings", detail: "Profile, company, team, and API keys" }]
},
{
id: "open_admin",
label: "Open Platform admin",
phrases: [
"open platform admin",
"go to admin",
"show admin",
"platform admin",
"admin panel"
],
keywords: ["admin", "platform"],
description: "Navigate to Platform admin (staff only).",
requiresConfirm: false,
canExecute: false,
route: "/admin",
selector: '[data-assistant-target="nav-admin"],[data-tour="nav-admin"]',
guideSteps: [{ title: "You're on Platform admin", detail: "Users, billing, support, and gates" }]
},
{
id: "open_api_keys",
label: "API keys",
phrases: [
"api keys",
"api key",
"open api keys",
"show api keys",
"developer keys",
"settings api keys"
],
keywords: ["api", "keys", "developer"],
description: "Open Settings → API Keys and highlight create controls.",
requiresConfirm: false,
canExecute: false,
route: "/settings?tab=api-keys",
selector:
'[data-assistant-target="api-keys-create"],[data-tour="api-keys-create"]',
guideSteps: [
{ title: "Open Settings → API Keys", detail: "Company admin required to create keys" },
{ title: "Click Create API Key", detail: "Name the key, then create" },
{ title: "Copy the secret once", detail: "It is shown only at creation — store it safely" }
]
},
{
id: "create_api_key",
label: "Create API key",
phrases: [
"create api key",
"generate api key",
"new api key",
"make an api key",
"create a key"
],
keywords: ["create", "generate", "api", "key"],
description: "Create an API key (confirm required). Secret is shown once, then use curl examples.",
requiresConfirm: true,
canExecute: true,
route: "/settings?tab=api-keys",
selector:
'[data-assistant-target="api-keys-create"],[data-tour="api-keys-create"]',
guideSteps: [
{ title: "Open Settings → API Keys", detail: "Company admin required" },
{ title: "Create API Key", detail: "Enter a name and create" },
{ title: "Copy the secret now", detail: "It cannot be retrieved later" }
]
},
{
id: "api_examples",
label: "API examples",
phrases: [
"api examples",
"curl examples",
"how to use api key",
"http examples",
"example api request",
"developer help",
"how do i call the api",
"sample curl"
],
keywords: ["curl", "example", "http", "openapi", "developer"],
description: "Show example HTTP/curl calls for attributes and processing (placeholder key).",
requiresConfirm: false,
canExecute: false,
route: "/docs",
selector: '[data-assistant-target="nav-settings"],[data-tour="nav-settings"]',
guideSteps: [
{ title: "Create an API key", detail: "Settings → API Keys" },
{ title: "Send X-API-Key", detail: "Header on /api/v1/* requests" },
{ title: "Open API docs", detail: "Docs page for the full OpenAPI surface" }
]
},
{
id: "open_attributes",
label: "Open Attributes",
phrases: [
"open attributes",
"go to attributes",
"attributes page",
"show attributes",
"attributes"
],
keywords: ["attributes"],
description: "Navigate to the Attributes page.",
requiresConfirm: false,
canExecute: false,
route: "/attributes",
selector:
'[data-assistant-target="attributes-add"],[data-tour="attributes-add"],[data-assistant-target="nav-attributes"],[data-tour="nav-attributes"]',
guideSteps: [
{ title: "Open Attributes", detail: "Sidebar → Attributes" },
{ title: "Add or search", detail: "Create fields and assign to categories" }
]
},
{
id: "list_attributes",
label: "List attributes",
phrases: [
"list attributes",
"show my attributes",
"how many attributes",
"get attributes",
"attribute count"
],
keywords: ["list", "attributes", "count"],
description: "Fetch attributes via API and summarize count + a short sample.",
requiresConfirm: true,
canExecute: true,
route: "/attributes",
selector:
'[data-assistant-target="attributes-add"],[data-tour="attributes-add"]',
guideSteps: [
{ title: "Open Attributes", detail: "Browse or search the table" },
{ title: "Or ask me to list", detail: "I can summarize count and sample names" }
]
},
{
id: "create_attribute",
label: "Create attribute",
phrases: [
"create attribute",
"add attribute",
"new attribute",
"define attribute"
],
keywords: ["create", "add", "attribute"],
description: "Create an attribute (key, name, type) after confirmation.",
requiresConfirm: true,
canExecute: true,
route: "/attributes",
selector:
'[data-assistant-target="attributes-add"],[data-tour="attributes-add"]',
guideSteps: [
{ title: "Open Attributes", detail: "Click Add Attribute" },
{ title: "Enter key, name, type", detail: "Optional unit and example" },
{ title: "Create", detail: "Then assign to categories if needed" }
]
},
{
id: "open_support",
label: "Open Support",
phrases: [
"open support",
"support center",
"help desk",
"go to support",
"support tickets",
"support"
],
keywords: ["support", "ticket", "helpdesk"],
description: "Navigate to the Support center.",
requiresConfirm: false,
canExecute: false,
route: "/support",
selector:
'[data-assistant-target="nav-support"],[data-tour="nav-support"],[data-assistant-target="support-new"],[data-tour="support-new"]',
guideSteps: [
{ title: "Open Support", detail: "Sidebar → Support" },
{ title: "New ticket", detail: "Describe the issue without secrets or passwords" }
]
},
{
id: "create_support_ticket",
label: "Create support ticket",
phrases: [
"create support ticket",
"open a support ticket",
"new support ticket",
"file a ticket",
"contact support",
"submit a ticket"
],
keywords: ["ticket", "support", "contact"],
description: "Create a support ticket (confirm + subject/body). No secrets in the message.",
requiresConfirm: true,
canExecute: true,
route: "/support/new",
selector:
'[data-assistant-target="support-create"],[data-tour="support-create"]',
guideSteps: [
{ title: "Open New ticket", detail: "Support → New ticket" },
{ title: "Subject and details", detail: "Omit passwords, API secrets, and personal data" },
{ title: "Submit", detail: "Track replies in Support" }
]
},
{
id: "suggest_pricing",
label: "Pricing suggestion",
phrases: [
"which plan",
"suggest plan",
"pricing suggestion",
"what plan do i need",
"upgrade plan",
"recommend a plan",
"pricing help",
"too many products"
],
keywords: ["plan", "pricing", "upgrade", "billing"],
description: "Suggest a plan tier from product count using existing public plans data.",
requiresConfirm: true,
canExecute: true,
route: "/billing",
selector:
'[data-assistant-target="nav-billing"],[data-tour="nav-billing"]',
guideSteps: [
{ title: "Check product count", detail: "Usage & Billing or Products" },
{ title: "Compare plans", detail: "Billing → Plans / Pricing" },
{ title: "Upgrade when ready", detail: "Checkout or contact sales for Enterprise" }
]
}
];
export function intentById(id: IntentId): IntentDefinition | undefined {
return INTENT_REGISTRY.find((i) => i.id === id);
}
export const QUICK_START_REPLIES = [
"Getting started",
"Add a feed URL",
"Upload a CSV",
"Map fields",
"Connect Shopify",
"API keys",
"Attributes",
"Start processing",
"Pricing suggestion",
"Support"
] as const;