@takeshape/purchase-order-chat 1.60.1 → 1.60.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/{purchase-order-chat-wrapper-Ctm9BV2k.js → purchase-order-chat-wrapper-D6twvEIU.js} +110 -89
- package/dist/purchase-order-chat-wrapper-D6twvEIU.js.map +1 -0
- package/dist/shadow.js +2 -2
- package/dist/tailwind.js +1 -1
- package/package.json +1 -1
- package/dist/purchase-order-chat-wrapper-Ctm9BV2k.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"purchase-order-chat-wrapper-D6twvEIU.js","sources":["../src/lib/utils.ts","../src/components/styles-target.tsx","../src/constants.ts","../src/lib/native-fetch.ts","../src/lib/bigcommerce/b2b/graphql.ts","../src/lib/bigcommerce/b2b/queries.ts","../src/lib/bigcommerce/storefront/graphql.ts","../src/lib/bigcommerce/storefront/queries.ts","../src/lib/bigcommerce/utils.ts","../src/lib/bigcommerce/storefront/pagination.ts","../src/lib/bigcommerce/storefront/client.ts","../src/stores/chat-display-store.ts","../src/components/chat-view/expanded-chat-view.tsx","../src/lib/convert-heic.ts","../src/lib/file-validation.ts","../src/hooks/use-file-drop.ts","../src/components/icons/cart-icon.tsx","../src/components/icons/check-icon.tsx","../src/components/icons/copy-icon.tsx","../src/components/icons/maximize-icon.tsx","../src/components/icons/minimize-icon.tsx","../src/components/icons/alert-circle-icon.tsx","../src/components/icons/spinner-icon.tsx","../src/components/chat-view/cartifact/cartifact-address.tsx","../src/lib/formatting.ts","../src/components/chat-view/cartifact/cartifact-footer.tsx","../src/components/icons/x-icon.tsx","../src/components/step-button.tsx","../src/components/quantity-selector.tsx","../src/components/chat-view/cartifact/cartifact-line-item.tsx","../src/components/chat-view/cartifact/panel-action-button.tsx","../src/components/chat-view/cartifact/cartifact-new-order.tsx","../src/components/icons/order-list-icon.tsx","../src/components/chat-view/cartifact/empty-cartifact.tsx","../src/stores/slices/ai-slice.ts","../src/stores/slices/batch-processor-slice.ts","../src/stores/slices/bc-session-slice.ts","../src/stores/slices/cartifact-slice.ts","../src/stores/slices/chat-slice.ts","../src/stores/slices/customer-slice.ts","../src/stores/slices/parser-slice.ts","../src/stores/slices/takeshape-config-slice.ts","../src/stores/slices/ui-slice.ts","../src/stores/purchase-order-store.ts","../src/components/chat-view/cartifact/line-item-warning.tsx","../src/components/chat-view/cartifact/cartifact.tsx","../src/components/chat-view/chat-panel/chat-error.tsx","../src/components/icons/send-icon.tsx","../src/components/chat-view/chat-panel/chat-input.tsx","../src/components/tools/tool-names.ts","../src/utils/group-renderable-parts.ts","../src/components/icons/file-icon.tsx","../src/components/icons/expand-chevron-icon.tsx","../src/components/tools/generic-tool-message.tsx","../src/components/tools/parse-tool-output.ts","../src/components/tools/search-products-by-sku-tool.tsx","../src/components/tools/search-products-tool.tsx","../src/contexts/bigcommerce-client-context.tsx","../src/hooks/use-product-variants.ts","../src/components/icons/placeholder-image-icon.tsx","../src/components/variant-picker.tsx","../src/components/product-card.tsx","../src/components/product-grid.tsx","../src/components/tools/show-products-tool.tsx","../src/components/tools/tool.tsx","../src/components/tools/collapsible-tool-calls.tsx","../src/schema.ts","../src/lib/sse.ts","../src/lib/takeshape-api.ts","../src/lib/tracing.ts","../src/components/feedback/feedback-dialog.tsx","../src/components/icons/feedback-icon.tsx","../src/components/chat-view/chat-panel/collapsible-agent-message.tsx","../src/components/chat-view/chat-panel/chat-message.tsx","../src/hooks/use-touch-device.ts","../src/components/icons/upload-document-icon.tsx","../src/components/icons/camera-icon.tsx","../src/components/uploader/camera-button.tsx","../src/components/chat-view/chat-panel/chat-panel-empty-state.tsx","../src/components/chat-view/chat-panel/typing-indicator.tsx","../src/components/chat-view/chat-panel/chat-panel.tsx","../src/stores/user-settings-store.ts","../src/components/chat-view/hooks/use-resizable-panel.ts","../src/components/chat-view/tab-bar.tsx","../src/components/chat-view/index.tsx","../src/components/existing-cart-prompt.tsx","../src/components/fatal-error.tsx","../src/hooks/use-processing-state.ts","../src/components/uploader/processing-steps.tsx","../src/components/uploader/upload-drop-zone.tsx","../src/components/uploader/initial-state.tsx","../src/components/uploader/cart-preview.tsx","../src/hooks/use-progressive-cart-items.ts","../src/hooks/use-progressive-tool-calls.ts","../src/utils/processing-helpers.ts","../src/components/uploader/processing-steps-vertical.tsx","../src/components/uploader/processing.tsx","../src/components/uploader/index.tsx","../src/utils/cart-sync-helpers.ts","../src/hooks/use-bigcommerce-cart.ts","../src/hooks/use-cart-handlers.ts","../src/lib/batch-processor-core.ts","../src/lib/batch-processor.ts","../src/hooks/use-batch-processor.ts","../src/hooks/use-chat-orchestration.ts","../src/lib/batching.ts","../src/lib/read-file.ts","../src/lib/spreadsheet.ts","../src/lib/validate-pdf.ts","../src/hooks/use-file-upload.ts","../src/hooks/use-takeshape-thread.ts","../src/hooks/use-document-parser.ts","../src/lib/bigcommerce/b2b/client.ts","../src/lib/tool-handlers/add-to-cart.ts","../src/lib/tool-handlers/clear-cart.ts","../src/lib/tool-handlers/get-cart.ts","../src/lib/tool-handlers/get-purchase-order-data.ts","../src/lib/tool-handlers/remove-from-cart.ts","../src/lib/tool-handlers/remove-item-warnings.ts","../src/lib/tool-handlers/set-item-warnings.ts","../src/lib/tool-handlers/set-po-metadata.ts","../src/lib/tool-handlers/update-cart.ts","../src/lib/tool-handlers/index.ts","../src/lib/chat-tool-execution.ts","../src/stores/session-validation.ts","../src/utils/ai-sdk-helpers.ts","../src/purchase-order-chat.tsx","../src/purchase-order-chat-wrapper.tsx"],"sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport function resolveProductPath(\n template: string,\n product: Record<string, unknown>\n): string {\n return template.replace(/:(\\w+)/g, (_, key) => {\n const value = product[key];\n return value != null ? String(value) : '';\n });\n}\n","import { useEffect, useState } from 'react';\n\nexport interface StylesTargetProps {\n onChange?: (\n stylesMap: Map<string, { css: string; attributes: Record<string, string> }>\n ) => void;\n}\n\n// Provided by @takeshape/vite/plugins/css-position\ndeclare const __VITE_CSS_POS_GLOBAL_VAR_NAME__: string;\ndeclare const __VITE_CSS_POS_EVENT_NAME__: string;\n\nconst globalVarName = __VITE_CSS_POS_GLOBAL_VAR_NAME__;\nconst eventName = __VITE_CSS_POS_EVENT_NAME__;\n\nconst getCurrent = () =>\n typeof window !== 'undefined' ? (window as any)[globalVarName] : undefined;\n\nexport const StylesTarget = (props: StylesTargetProps) => {\n const [stylesMap, setStylesMap] = useState<\n Map<string, { css: string; attributes: Record<string, string> }>\n >(() => getCurrent() || new Map());\n\n const [version, setVersion] = useState(0);\n\n useEffect(() => {\n const updateListener = (_e: Event | undefined) => {\n const newValues = getCurrent() || new Map();\n setStylesMap(newValues);\n setVersion((v) => v + 1);\n props.onChange?.(newValues);\n };\n window.addEventListener(eventName, updateListener);\n\n updateListener(undefined);\n\n return () => {\n window.removeEventListener(eventName, updateListener);\n };\n }, [props.onChange]);\n\n return Array.from(stylesMap?.keys() || []).map((key) => {\n const entry = stylesMap.get(key);\n if (!entry) return null;\n return (\n <style {...entry.attributes} key={`${key}-${version}`}>\n {entry.css}\n </style>\n );\n });\n};\n","export const DEFAULT_AGENT_NAME = 'bigcommercePurchaseOrderAgent';\n\nexport const DEFAULT_ORIGIN = 'https://api.takeshape.io';\n\nexport const B2B_GRAPHQL_URL = 'https://api-b2b.bigcommerce.com/graphql';\n\n// The well-known B2B Edition client ID used for Current Customer JWT requests\nexport const B2B_APP_CLIENT_ID = 'dl7c39mdpul6hyc489yk0vzxl6jesyx';\n\n// Synthetic message sent after client tool responses to trigger server processing\n// TODO: Remove after https://app.shortcut.com/takeshape/story/16151/support-sending-agent-tool-call-results-without-a-user-message\nexport const CLIENT_TOOL_RESPONSE_MESSAGE =\n '[client is providing tool response]';\n\nexport const PO_ADDRESS_ID = '__po_address__';\nexport const PO_BILLING_ADDRESS_ID = '__po_billing_address__';\nexport const CHECKOUT_ADDRESS_ID = '__checkout_address__';\n\n// Storage key for persistence\nexport const STORAGE_KEY = 'purchase-order-chat-session';\n\n// Persistence version for future migrations\nexport const STORAGE_VERSION = 3;\n","// Recover the browser's native fetch implementation via a throwaway iframe.\n// This is necessary because third-party scripts on the host page (e.g. sticky.io)\n// can replace window.fetch with a broken implementation that chokes on Request objects.\n// A freshly created iframe has its own JavaScript realm that no host-page script has touched.\n//\n// The iframe must remain in the DOM — removing it destroys its global scope,\n// which invalidates the bound fetch function.\n\nfunction getNativeFetch(): typeof fetch {\n if (typeof document !== 'undefined') {\n try {\n const iframe = document.createElement('iframe');\n iframe.style.display = 'none';\n document.head.appendChild(iframe);\n const iframeFetch = iframe.contentWindow?.fetch;\n if (iframeFetch) {\n return iframeFetch.bind(iframe.contentWindow);\n }\n // No fetch on contentWindow (jsdom) — clean up\n document.head.removeChild(iframe);\n } catch {\n // Fall through to global fetch\n }\n }\n // Node / SSR / jsdom — global fetch is fine\n return fetch;\n}\n\nconst _nativeFetch = getNativeFetch();\n\nexport const nativeFetch: typeof fetch = _nativeFetch;\n","import { initGraphQLTada } from 'gql.tada';\nimport type { introspection } from './graphql-env.gen.d.ts';\n\nexport const graphql = initGraphQLTada<{\n introspection: introspection;\n}>();\n\nexport type { FragmentOf, ResultOf, VariablesOf } from 'gql.tada';\nexport { readFragment } from 'gql.tada';\n","import { graphql } from './graphql.js';\n\nexport const UserAuthorizationFragment = graphql(`\n fragment UserAuthorizationFragment on UserAuthorization {\n result {\n token\n }\n }\n`);\n\nexport const AuthorizationMutation = graphql(\n `\n mutation Authorization($authData: UserAuthType!) {\n authorization(authData: $authData) {\n ...UserAuthorizationFragment\n }\n }\n`,\n [UserAuthorizationFragment]\n);\n\nexport const UserFragment = graphql(`\n fragment UserFragment on UserType {\n companyInfo {\n companyId\n }\n }\n`);\n\nexport const CurrentUserQuery = graphql(\n `\n query CurrentUser {\n currentUser {\n ...UserFragment\n }\n }\n`,\n [UserFragment]\n);\n\nexport const CompanyAddressFragment = graphql(`\n fragment CompanyAddressFragment on AddressType {\n id\n firstName\n lastName\n company\n addressLine1\n addressLine2\n city\n state\n zipCode\n country\n countryCode\n phoneNumber\n isDefaultShipping\n isDefaultBilling\n isShipping\n isBilling\n label\n }\n`);\n\nexport const CompanyAddressesQuery = graphql(\n `\n query CompanyAddressesQuery(\n $companyId: Int!\n $first: Int\n $offset: Int\n ) {\n addresses(\n companyId: $companyId\n first: $first\n offset: $offset\n ) {\n totalCount\n edges {\n node {\n ...CompanyAddressFragment\n }\n }\n }\n }\n`,\n [CompanyAddressFragment]\n);\n\nexport const CheckoutResultFragment = graphql(`\n fragment CheckoutResultFragment on CheckoutLoginResultType {\n redirectUrl\n }\n`);\n\nexport const CheckoutLoginMutation = graphql(\n `\n mutation CheckoutLoginMutation(\n $cartData: CheckoutLoginType!\n ) {\n checkoutLogin(cartData: $cartData) {\n result {\n redirectUrl\n }\n }\n }\n`\n);\n","import { initGraphQLTada } from 'gql.tada';\nimport type { introspection } from './graphql-env.gen.d.ts';\n\nexport const graphql = initGraphQLTada<{\n introspection: introspection;\n scalars: {\n DateTime: string;\n JSON: unknown;\n JSONObject: Record<string, unknown>;\n BigDecimal: number;\n };\n}>();\n\nexport type { FragmentOf, ResultOf, VariablesOf } from 'gql.tada';\nexport { readFragment } from 'gql.tada';\n","// BigCommerce GraphQL Storefront API Queries and Mutations\nimport { graphql } from './graphql.js';\n\nexport const CartFragment = graphql(`\n fragment CartFields on Cart {\n id\n entityId\n lineItems {\n physicalItems {\n entityId\n productEntityId\n variantEntityId\n quantity\n name\n sku\n originalPrice {\n value\n currencyCode\n }\n listPrice {\n value\n currencyCode\n }\n extendedListPrice {\n value\n currencyCode\n }\n extendedSalePrice {\n value\n currencyCode\n }\n imageUrl\n }\n digitalItems {\n entityId\n productEntityId\n variantEntityId\n quantity\n name\n sku\n originalPrice {\n value\n currencyCode\n }\n listPrice {\n value\n currencyCode\n }\n extendedListPrice {\n value\n currencyCode\n }\n extendedSalePrice {\n value\n currencyCode\n }\n imageUrl\n }\n }\n amount {\n value\n currencyCode\n }\n baseAmount {\n value\n currencyCode\n }\n discountedAmount {\n value\n currencyCode\n }\n createdAt {\n utc\n }\n updatedAt {\n utc\n }\n }\n`);\n\nexport const GetCartQuery = graphql(\n `\n query GetCart($cartEntityId: String) {\n site {\n cart(entityId: $cartEntityId) {\n ...CartFields\n }\n }\n }\n`,\n [CartFragment]\n);\n\nexport const CreateCartMutation = graphql(\n `\n mutation CreateCart($input: CreateCartInput!) {\n cart {\n createCart(input: $input) {\n cart {\n ...CartFields\n }\n }\n }\n }\n`,\n [CartFragment]\n);\n\nexport const AddCartLineItemsMutation = graphql(\n `\n mutation AddCartLineItems($input: AddCartLineItemsInput!) {\n cart {\n addCartLineItems(input: $input) {\n cart {\n ...CartFields\n }\n }\n }\n }\n`,\n [CartFragment]\n);\n\nexport const UpdateCartLineItemMutation = graphql(\n `\n mutation UpdateCartLineItem($input: UpdateCartLineItemInput!) {\n cart {\n updateCartLineItem(input: $input) {\n cart {\n ...CartFields\n }\n }\n }\n }\n`,\n [CartFragment]\n);\n\nexport const DeleteCartLineItemMutation = graphql(\n `\n mutation DeleteCartLineItem($input: DeleteCartLineItemInput!) {\n cart {\n deleteCartLineItem(input: $input) {\n cart {\n ...CartFields\n }\n }\n }\n }\n`,\n [CartFragment]\n);\n\nexport const DeleteCartMutation = graphql(`\n mutation DeleteCart($input: DeleteCartInput!) {\n cart {\n deleteCart(input: $input) {\n deletedCartEntityId\n }\n }\n }\n`);\n\nexport const CreateCartRedirectUrlsMutation = graphql(`\n mutation CreateCartRedirectUrls($input: CreateCartRedirectUrlsInput) {\n cart {\n createCartRedirectUrls(input: $input) {\n redirectUrls {\n redirectedCheckoutUrl\n }\n }\n }\n }\n`);\n\nexport const CreateCartMetafieldMutation = graphql(`\n mutation CreateCartMetafield($input: CreateCartMetafieldInput!) {\n cart {\n createCartMetafield(input: $input) {\n metafield {\n id\n entityId\n }\n }\n }\n }\n`);\n\n// Checkout Queries and Mutations\nexport const CheckoutFragment = graphql(`\n fragment CheckoutFields on Checkout {\n entityId\n subtotal {\n value\n currencyCode\n }\n taxTotal {\n value\n currencyCode\n }\n grandTotal {\n value\n currencyCode\n }\n shippingCostTotal {\n value\n currencyCode\n }\n handlingCostTotal {\n value\n currencyCode\n }\n billingAddress {\n firstName\n lastName\n address1\n address2\n city\n stateOrProvince\n stateOrProvinceCode\n countryCode\n postalCode\n phone\n email\n }\n shippingConsignments {\n entityId\n address {\n firstName\n lastName\n address1\n address2\n city\n stateOrProvince\n stateOrProvinceCode\n countryCode\n postalCode\n phone\n email\n }\n availableShippingOptions {\n entityId\n description\n type\n cost {\n value\n currencyCode\n }\n }\n selectedShippingOption {\n entityId\n description\n type\n cost {\n value\n currencyCode\n }\n }\n shippingCost {\n value\n currencyCode\n }\n lineItemIds\n }\n }\n`);\n\nexport const GetCheckoutQuery = graphql(\n `\n query GetCheckout($checkoutEntityId: String) {\n site {\n checkout(entityId: $checkoutEntityId) {\n ...CheckoutFields\n }\n }\n }\n`,\n [CheckoutFragment]\n);\n\nexport const AddCheckoutShippingConsignmentsMutation = graphql(\n `\n mutation AddCheckoutShippingConsignments($input: AddCheckoutShippingConsignmentsInput!) {\n checkout {\n addCheckoutShippingConsignments(input: $input) {\n checkout {\n ...CheckoutFields\n }\n }\n }\n }\n`,\n [CheckoutFragment]\n);\n\nexport const AddCheckoutBillingAddressMutation = graphql(\n `\n mutation AddCheckoutBillingAddressMutation($input: AddCheckoutBillingAddressInput!) {\n checkout {\n addCheckoutBillingAddress(input: $input) {\n checkout {\n ...CheckoutFields\n }\n }\n }\n }\n`,\n [CheckoutFragment]\n);\n\nexport const DeleteCheckoutConsignmentMutation = graphql(\n `\n mutation DeleteCheckoutConsignment($input: DeleteCheckoutConsignmentInput!) {\n checkout {\n deleteCheckoutConsignment(input: $input) {\n checkout {\n ...CheckoutFields\n }\n }\n }\n }\n`,\n [CheckoutFragment]\n);\n\nexport const UpdateCheckoutCustomerMessageMutation = graphql(\n `\n mutation UpdateCheckoutCustomerMessage($input: UpdateCheckoutCustomerMessageInput!) {\n checkout {\n updateCheckoutCustomerMessage(input: $input) {\n checkout {\n ...CheckoutFields\n }\n }\n }\n }\n`,\n [CheckoutFragment]\n);\n\n// Product Variant Details Query\nexport const GetProductVariantDetailsQuery = graphql(`\n query GetProductVariantDetails($entityIds: [Int!], $first: Int = 50) {\n site {\n products(entityIds: $entityIds) {\n edges {\n node {\n entityId\n productOptions(first: $first) {\n edges {\n node {\n entityId\n displayName\n isRequired\n isVariantOption\n ... on MultipleChoiceOption {\n displayStyle\n values(first: $first) {\n edges {\n node {\n entityId\n label\n isDefault\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n variants(first: $first) {\n edges {\n node {\n entityId\n sku\n isPurchasable\n defaultImage {\n urlTemplate\n }\n prices {\n price {\n value\n currencyCode\n }\n }\n inventory {\n aggregated {\n availableToSell\n warningLevel\n }\n }\n options(first: $first) {\n edges {\n node {\n entityId\n displayName\n values(first: 1) {\n edges {\n node {\n entityId\n label\n }\n }\n }\n }\n }\n }\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n }\n }\n }\n`);\n\n// Query for fetching products to display (includes names, prices, images)\nexport const GetProductsForDisplayQuery = graphql(`\n query GetProductsForDisplay($entityIds: [Int!], $first: Int = 50) {\n site {\n products(entityIds: $entityIds) {\n edges {\n node {\n entityId\n name\n sku\n path\n defaultImage {\n urlTemplate\n }\n variants(first: $first) {\n edges {\n node {\n entityId\n sku\n isPurchasable\n defaultImage {\n urlTemplate\n }\n prices {\n price {\n value\n currencyCode\n }\n }\n inventory {\n isInStock\n aggregated {\n availableToSell\n warningLevel\n }\n }\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n }\n }\n }\n`);\n\n// Pagination query for product variants (for display)\nexport const GetProductVariantsForDisplayPageQuery = graphql(`\n query GetProductVariantsForDisplayPage($entityId: Int!, $first: Int = 50, $after: String!) {\n site {\n product(entityId: $entityId) {\n variants(first: $first, after: $after) {\n edges {\n node {\n entityId\n sku\n isPurchasable\n defaultImage {\n urlTemplate\n }\n prices {\n price {\n value\n currencyCode\n }\n }\n inventory {\n isInStock\n aggregated {\n availableToSell\n warningLevel\n }\n }\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n }\n`);\n\nexport const CustomerAddressFragment = graphql(`\n fragment CustomerAddressFields on CustomerAddress {\n entityId\n firstName\n lastName\n address1\n address2\n city\n stateOrProvince\n postalCode\n countryCode\n country\n phone\n }\n`);\n\n// Customer Address Query\nexport const GetCustomerAddressesQuery = graphql(\n `\n query GetCustomerAddresses($first: Int = 50, $after: String) {\n customer {\n entityId\n firstName\n lastName\n email\n addresses(first: $first, after: $after) {\n edges {\n node {\n ...CustomerAddressFields\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n`,\n [CustomerAddressFragment]\n);\n\n// Follow-up pagination queries for fetching additional pages\n\nexport const GetProductVariantsPageQuery = graphql(`\n query GetProductVariantsPage($entityId: Int!, $first: Int = 50, $after: String!) {\n site {\n product(entityId: $entityId) {\n variants(first: $first, after: $after) {\n edges {\n node {\n entityId\n sku\n isPurchasable\n defaultImage {\n urlTemplate\n }\n prices {\n price {\n value\n currencyCode\n }\n }\n inventory {\n aggregated {\n availableToSell\n warningLevel\n }\n }\n options(first: 50) {\n edges {\n node {\n entityId\n displayName\n values(first: 1) {\n edges {\n node {\n entityId\n label\n }\n }\n }\n }\n }\n }\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n }\n`);\n\nexport const GetProductOptionsPageQuery = graphql(`\n query GetProductOptionsPage($entityId: Int!, $first: Int = 50, $after: String!) {\n site {\n product(entityId: $entityId) {\n productOptions(first: $first, after: $after) {\n edges {\n node {\n entityId\n displayName\n isRequired\n isVariantOption\n ... on MultipleChoiceOption {\n displayStyle\n values(first: 50) {\n edges {\n node {\n entityId\n label\n isDefault\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n }\n`);\n\nexport const GetProductPathsQuery = graphql(`\n query GetProductPaths($entityIds: [Int!]) {\n site {\n products(entityIds: $entityIds) {\n edges {\n node {\n entityId\n path\n }\n }\n }\n }\n }\n`);\n\nexport const GetProductOptionValuesPageQuery = graphql(`\n query GetProductOptionValuesPage($entityId: Int!, $optionEntityId: Int!, $first: Int = 50, $after: String!) {\n site {\n product(entityId: $entityId) {\n productOptions(entityIds: [$optionEntityId]) {\n edges {\n node {\n entityId\n displayName\n isRequired\n isVariantOption\n ... on MultipleChoiceOption {\n displayStyle\n values(first: $first, after: $after) {\n edges {\n node {\n entityId\n label\n isDefault\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n }\n }\n }\n }\n }\n`);\n\n// Store Settings Query (used to get storeHash for B2B Edition)\nexport const GetStoreSettingsQuery = graphql(`\n query GetStoreSettings {\n site {\n settings {\n storeHash\n }\n }\n }\n`);\n","import { PO_ADDRESS_ID, PO_BILLING_ADDRESS_ID } from '../../constants.js';\nimport type { Address } from '../../types.js';\nimport { type FragmentOf, readFragment } from './b2b/graphql.js';\nimport { CompanyAddressFragment } from './b2b/queries.js';\nimport { CustomerAddressFragment } from './storefront/queries.js';\nimport type { CustomerAddress } from './storefront/types.js';\n\n/**\n * Convert a B2B company address to the standard CustomerAddress format.\n * Uses negative numeric IDs to avoid collisions with storefront address IDs.\n */\nexport function convertCompanyAddressToCustomerAddress(\n companyAddress: FragmentOf<typeof CompanyAddressFragment>\n): CustomerAddress {\n const address = readFragment(CompanyAddressFragment, companyAddress);\n return {\n source: 'b2b',\n id: `${address.id}`,\n firstName: address.firstName,\n lastName: address.lastName,\n address1: address.addressLine1 ?? '',\n address2: address.addressLine2 || undefined,\n city: address.city,\n stateOrProvince: address.state || undefined,\n postalCode: address.zipCode || undefined,\n countryCode: address.countryCode ?? '',\n country: address.country || undefined,\n phone: address.phoneNumber || undefined,\n isShipping: address.isShipping === 1,\n isBilling: address.isBilling === 1,\n isDefaultShipping: address.isDefaultShipping === 1,\n isDefaultBilling: address.isDefaultBilling === 1,\n label: address.label || undefined\n };\n}\n\nexport function convertCustomerAddressToCustomerAddress(\n customerAddress: FragmentOf<typeof CustomerAddressFragment>,\n index = 0\n): CustomerAddress {\n const address = readFragment(CustomerAddressFragment, customerAddress);\n return {\n source: 'storefront',\n id: `${address.entityId}`,\n firstName: address.firstName,\n lastName: address.lastName,\n address1: address.address1 ?? '',\n address2: address.address2 || undefined,\n city: address.city,\n stateOrProvince: address.stateOrProvince || undefined,\n postalCode: address.postalCode || undefined,\n countryCode: address.countryCode ?? '',\n country: address.country || undefined,\n phone: address.phone || undefined,\n isShipping: true,\n // Unclear how to determine billing vs shipping from storefront address, so default to true for both\n isBilling: true,\n // Just make the first address the default\n isDefaultShipping: index === 0,\n isDefaultBilling: index === 0\n };\n}\n\nexport function convertPoAddressToCustomerAddress(\n addr: Address,\n options: {\n id: typeof PO_ADDRESS_ID | typeof PO_BILLING_ADDRESS_ID;\n }\n): CustomerAddress {\n return {\n source: 'po',\n id: options.id,\n firstName: addr.firstName ?? '',\n lastName: addr.lastName ?? '',\n address1: addr.address1,\n address2: addr.address2,\n city: addr.city ?? '',\n stateOrProvince: addr.stateOrProvince ?? '',\n countryCode: addr.countryCode ?? 'US',\n postalCode: addr.postalCode,\n phone: addr.phone,\n isShipping: options.id === PO_ADDRESS_ID,\n isBilling: options.id === PO_BILLING_ADDRESS_ID,\n isDefaultShipping: false,\n isDefaultBilling: false,\n label: 'PO Address'\n };\n}\n","import type { ResultOf, TadaDocumentNode } from 'gql.tada';\nimport type { Variables } from 'graphql-request';\nimport type { TadaRequestOptions } from '../types.js';\nimport type { PageInfo } from './types.js';\n\ninterface Connection<TNode> {\n edges: Array<{ node: TNode }> | null;\n pageInfo: PageInfo;\n}\n\nexport interface GraphQLRequestClient {\n request<R, V extends Variables | undefined = Variables>(\n options: TadaRequestOptions<R, V>\n ): Promise<ResultOf<TadaDocumentNode<R, V>>>;\n}\n\nexport const MAX_PAGES = 20; // Safety limit: 50 items/page * 20 = 1,000 items max\n\nexport async function fetchAllPages<R, V extends Variables | undefined, TNode>(\n client: GraphQLRequestClient,\n document: TadaRequestOptions<R, V>['document'],\n baseVariables: Record<string, unknown>,\n getConnection: (result: R) => Connection<TNode> | null\n): Promise<Array<{ node: TNode }>> {\n const allEdges: Array<{ node: TNode }> = [];\n let after: string | null | undefined;\n let pages = 0;\n\n while (pages < MAX_PAGES) {\n const variables =\n after !== undefined ? { ...baseVariables, after } : { ...baseVariables };\n\n const result = await client.request({\n document,\n variables: variables as V\n });\n\n const connection = getConnection(result);\n if (!connection) {\n break;\n }\n\n allEdges.push(...(connection.edges ?? []));\n pages++;\n\n if (!connection.pageInfo.hasNextPage || !connection.pageInfo.endCursor) {\n break;\n }\n\n after = connection.pageInfo.endCursor;\n }\n\n return allEdges;\n}\n","// BigCommerce GraphQL Storefront API Client\n\nimport type { FragmentOf, ResultOf, TadaDocumentNode } from 'gql.tada';\nimport { ClientError, GraphQLClient, type Variables } from 'graphql-request';\nimport { nativeFetch } from '../../native-fetch.js';\nimport type { TadaRequestOptions } from '../types.js';\nimport { convertCustomerAddressToCustomerAddress } from '../utils.js';\nimport { readFragment } from './graphql.js';\nimport { fetchAllPages } from './pagination.js';\nimport {\n AddCartLineItemsMutation,\n AddCheckoutBillingAddressMutation,\n AddCheckoutShippingConsignmentsMutation,\n CartFragment,\n CheckoutFragment,\n CreateCartMetafieldMutation,\n CreateCartMutation,\n CreateCartRedirectUrlsMutation,\n DeleteCartLineItemMutation,\n DeleteCartMutation,\n GetCartQuery,\n GetCheckoutQuery,\n GetCustomerAddressesQuery,\n GetProductOptionsPageQuery,\n GetProductOptionValuesPageQuery,\n GetProductPathsQuery,\n GetProductsForDisplayQuery,\n GetProductVariantDetailsQuery,\n GetProductVariantsForDisplayPageQuery,\n GetProductVariantsPageQuery,\n UpdateCartLineItemMutation,\n UpdateCheckoutCustomerMessageMutation\n} from './queries.js';\nimport type {\n BigCommerceConfig,\n CartBatchError,\n CartLineItemInput,\n CartRedirectUrls,\n CheckoutAddress,\n CheckoutConsignmentLineItem,\n CustomerAddress,\n CustomerInfo,\n GetCustomerAddressesResult,\n GetProductOptionValuesPageResult,\n ProductForDisplay,\n ProductVariantDetails\n} from './types.js';\n\ntype QueuedRequest<R, V extends Variables | undefined> = {\n options: TadaRequestOptions<R, V>;\n resolve: (value: R) => void;\n reject: (reason: any) => void;\n retry?: boolean;\n};\n\n/**\n * Maximum number of items to add to cart in a single operation\n * This is to avoid BigCommerce API 500 errors when adding too many items at once\n */\nconst CART_BATCH_SIZE = 20;\n\n/**\n * Unmask a CartFragment result and map to domain Cart type.\n * Handles null-vs-undefined differences between tada types and domain types.\n */\nfunction toCart(raw: FragmentOf<typeof CartFragment>) {\n return readFragment(CartFragment, raw);\n}\n\n/**\n * Unmask a CheckoutFragment result and map to domain Checkout type.\n */\nfunction toCheckout(raw: FragmentOf<typeof CheckoutFragment>) {\n return readFragment(CheckoutFragment, raw);\n}\n\n/**\n * Resolve a potentially relative URL to an absolute URL.\n * In browser context, prepends window.location.origin for relative paths.\n */\nfunction resolveEndpoint(endpoint: string): string {\n // Already absolute\n if (endpoint.startsWith('http://') || endpoint.startsWith('https://')) {\n return endpoint;\n }\n\n // Relative URL in browser context\n if (typeof window !== 'undefined' && window.location?.origin) {\n return `${window.location.origin}${endpoint.startsWith('/') ? '' : '/'}${endpoint}`;\n }\n\n // Fallback: return as-is (may fail, but provides clear error)\n return endpoint;\n}\n\nexport class BigCommerceClient {\n private endpoint: string;\n private storefrontToken: string | undefined;\n private graphQLClient: GraphQLClient;\n private isProcessing = false;\n // biome-ignore lint/suspicious/noExplicitAny: Necessary to allow for the tada type inference\n private requestQueue: QueuedRequest<any, any>[] = [];\n\n readonly channelId: number;\n\n constructor(config: BigCommerceConfig) {\n this.endpoint = resolveEndpoint(config.endpoint);\n this.storefrontToken = config.storefrontToken;\n this.channelId = config.channelId ?? 1;\n\n const headers: Record<string, string> = {\n 'content-type': 'application/json',\n accept: 'application/json'\n };\n\n if (this.storefrontToken) {\n headers.authorization = `Bearer ${this.storefrontToken}`;\n }\n\n this.graphQLClient = new GraphQLClient(this.endpoint, {\n fetch: nativeFetch,\n credentials: 'same-origin',\n headers\n });\n }\n\n /**\n * Execute a request with retry logic (up to 5 attempts with exponential backoff)\n */\n private async executeWithRetry<const R, V extends Variables | undefined>(\n options: TadaRequestOptions<R, V>,\n attempt = 1\n ): Promise<ResultOf<TadaDocumentNode<R, V>>> {\n const maxAttempts = 5;\n const delays = [1000, 2000, 4000, 8000, 16000]; // 1s, 2s, 4s, 8s, 16s\n\n try {\n const result = await this.graphQLClient.request(options);\n return result;\n } catch (error) {\n // GraphQL business errors (HTTP 200 with errors payload) are not retriable\n if (this.isGraphQLBusinessError(error)) {\n throw error;\n }\n\n if (attempt < maxAttempts) {\n const delay = delays[attempt - 1] ?? 16000;\n console.warn(\n `[BigCommerceClient] Request failed, retrying in ${delay / 1000}s (attempt ${attempt}/${maxAttempts})`,\n error\n );\n await new Promise((resolve) => setTimeout(resolve, delay));\n return this.executeWithRetry(options, attempt + 1);\n }\n console.error(\n `[BigCommerceClient] Request failed after ${maxAttempts} attempts:`,\n error\n );\n throw error;\n }\n }\n\n /**\n * Check if an error is a GraphQL business error (HTTP 200 with errors payload).\n * These are errors like \"out of stock\", \"invalid product\", etc. that won't succeed on retry.\n */\n private isGraphQLBusinessError(err: unknown): boolean {\n return err instanceof ClientError && err.response.status === 200;\n }\n\n /**\n * Extract a clean error message from a GraphQL error or generic error.\n */\n private extractErrorMessage(err: unknown): string {\n const gqlError = err as { response?: { errors?: { message: string }[] } };\n return (\n gqlError.response?.errors?.[0]?.message ??\n (err instanceof Error ? err.message : String(err))\n );\n }\n\n /**\n * Process the next request in the queue\n */\n private processNextInQueue(): void {\n if (this.requestQueue.length === 0) {\n this.isProcessing = false;\n return;\n }\n\n const next = this.requestQueue.shift();\n if (!next) return;\n\n const executeRequest =\n next.retry === false\n ? this.graphQLClient.request(next.options)\n : this.executeWithRetry(next.options);\n\n executeRequest\n .then((result) => {\n next.resolve(result);\n this.processNextInQueue();\n })\n .catch((error) => {\n next.reject(error);\n this.processNextInQueue();\n });\n }\n\n async request<const R, V extends Variables | undefined>(\n options: TadaRequestOptions<R, V>,\n { retry = true }: { retry?: boolean } = {}\n ) {\n // If already processing a request, queue this one\n if (this.isProcessing) {\n return new Promise<R>((resolve, reject) => {\n this.requestQueue.push({ options, resolve, reject, retry });\n });\n }\n\n // Execute immediately\n this.isProcessing = true;\n try {\n const result = retry\n ? await this.executeWithRetry(options)\n : await this.graphQLClient.request(options);\n this.processNextInQueue();\n return result;\n } catch (error) {\n this.processNextInQueue();\n throw error;\n }\n }\n\n /**\n * Get an existing cart by ID\n */\n async getCart(cartEntityId?: string) {\n const result = await this.request({\n document: GetCartQuery,\n variables: {\n cartEntityId\n }\n });\n\n const cart = result.site.cart;\n return cart ? toCart(cart) : null;\n }\n\n /**\n * Create a new cart with line items\n * Batches items if more than CART_BATCH_SIZE\n * Returns the cart and any errors that occurred during batch processing\n * Resilient to partial failures: if a batch fails, skips it and tries remaining items\n */\n async createCart(\n lineItems: CartLineItemInput[],\n previousErrors: CartBatchError[] = []\n ): Promise<{\n cart: ReturnType<typeof toCart> | null;\n errors: CartBatchError[];\n }> {\n if (lineItems.length === 0) {\n // If this is the initial call (no previous errors), throw error\n // Otherwise, we've exhausted all batches - return accumulated errors\n if (previousErrors.length === 0) {\n throw new Error('Cannot create cart with no line items');\n }\n return { cart: null, errors: previousErrors };\n }\n\n const errors = [...previousErrors];\n const firstBatch = lineItems.slice(0, CART_BATCH_SIZE);\n\n try {\n const cart = await this.createCartBatch(firstBatch);\n\n if (cart) {\n // Success! Add remaining items if any\n if (lineItems.length > CART_BATCH_SIZE) {\n const remainingItems = lineItems.slice(CART_BATCH_SIZE);\n const { cart: updatedCart, errors: batchErrors } =\n await this.addCartLineItems(cart.entityId, remainingItems);\n return {\n cart: updatedCart ?? cart,\n errors: [...errors, ...batchErrors]\n };\n }\n\n return { cart, errors };\n }\n\n // API returned success but cart is null - record error for this batch\n errors.push({ items: firstBatch, message: 'Failed to create cart' });\n } catch (err) {\n if (this.isGraphQLBusinessError(err)) {\n // If batch is already size 1, no need to isolate - error is already pinpointed\n if (firstBatch.length === 1) {\n errors.push({ items: firstBatch, message: this.extractErrorMessage(err) });\n } else {\n // Business error - isolate to find specific failing items\n const { cart: isolatedCart, errors: isolatedErrors } =\n await this.isolateCartCreation(firstBatch);\n\n if (isolatedCart) {\n // Isolation created a cart - add remaining items to it\n if (lineItems.length > CART_BATCH_SIZE) {\n const remainingItems = lineItems.slice(CART_BATCH_SIZE);\n const { cart: updatedCart, errors: batchErrors } =\n await this.addCartLineItems(isolatedCart.entityId, remainingItems);\n return {\n cart: updatedCart ?? isolatedCart,\n errors: [...errors, ...isolatedErrors, ...batchErrors]\n };\n }\n return { cart: isolatedCart, errors: [...errors, ...isolatedErrors] };\n }\n\n // Isolation couldn't create a cart (all items in batch failed)\n errors.push(...isolatedErrors);\n }\n } else {\n // Transport error after retries exhausted - record and continue\n errors.push({ items: firstBatch, message: this.extractErrorMessage(err) });\n }\n }\n\n // First batch failed - try remaining items\n const remainingItems = lineItems.slice(CART_BATCH_SIZE);\n return this.createCart(remainingItems, errors);\n }\n\n /**\n * Add a single batch of line items to a cart\n * Returns the updated cart or null if the operation failed\n */\n private async addBatchToCart(\n cartEntityId: string,\n batch: CartLineItemInput[],\n { retry = true }: { retry?: boolean } = {}\n ) {\n const result = await this.request(\n {\n document: AddCartLineItemsMutation,\n variables: {\n input: {\n cartEntityId,\n data: {\n lineItems: batch.map((item) => ({\n productEntityId: item.productEntityId,\n variantEntityId: item.variantEntityId,\n quantity: item.quantity\n }))\n }\n }\n }\n },\n { retry }\n );\n\n const rawCart = result.cart.addCartLineItems?.cart;\n return rawCart ? toCart(rawCart) : null;\n }\n\n /**\n * Try to add a batch to cart, isolating failures if needed.\n * If the batch fails and has multiple items, recursively isolates.\n * If the batch fails and has one item, records the error.\n */\n private async tryAddBatchWithIsolation(\n cartEntityId: string,\n batch: CartLineItemInput[]\n ): Promise<{\n cart: ReturnType<typeof toCart> | null;\n errors: CartBatchError[];\n }> {\n if (batch.length === 0) {\n return { cart: null, errors: [] };\n }\n\n try {\n const result = await this.addBatchToCart(cartEntityId, batch, {\n retry: false\n });\n return { cart: result, errors: [] };\n } catch (err) {\n const message = this.extractErrorMessage(err);\n if (batch.length === 1) {\n return { cart: null, errors: [{ items: batch, message }] };\n }\n return this.isolateFailingItems(cartEntityId, batch);\n }\n }\n\n /**\n * Binary search to isolate failing items within a batch.\n * Splits the batch in half, tries each half, and recursively isolates failures.\n * Returns successfully added items in cart and pinpoints individual failing items.\n */\n private async isolateFailingItems(\n cartEntityId: string,\n batch: CartLineItemInput[]\n ): Promise<{\n cart: ReturnType<typeof toCart> | null;\n errors: CartBatchError[];\n }> {\n const mid = Math.floor(batch.length / 2);\n const left = batch.slice(0, mid);\n const right = batch.slice(mid);\n\n const leftResult = await this.tryAddBatchWithIsolation(cartEntityId, left);\n const rightResult = await this.tryAddBatchWithIsolation(cartEntityId, right);\n\n return {\n cart: rightResult.cart ?? leftResult.cart,\n errors: [...leftResult.errors, ...rightResult.errors]\n };\n }\n\n /**\n * Create a cart with a batch of line items\n * Returns the created cart or null if the operation failed\n */\n private async createCartBatch(\n batch: CartLineItemInput[],\n { retry = true }: { retry?: boolean } = {}\n ) {\n const result = await this.request(\n {\n document: CreateCartMutation,\n variables: {\n input: {\n lineItems: batch.map((item) => ({\n productEntityId: item.productEntityId,\n variantEntityId: item.variantEntityId,\n quantity: item.quantity\n }))\n }\n }\n },\n { retry }\n );\n\n const rawCart = result.cart.createCart?.cart;\n return rawCart ? toCart(rawCart) : null;\n }\n\n /**\n * Try to create a cart with a batch, isolating failures if needed.\n * If the batch fails and has multiple items, recursively isolates.\n * If the batch fails and has one item, records the error.\n */\n private async tryCreateCartWithIsolation(\n batch: CartLineItemInput[]\n ): Promise<{\n cart: ReturnType<typeof toCart> | null;\n errors: CartBatchError[];\n }> {\n if (batch.length === 0) {\n return { cart: null, errors: [] };\n }\n\n try {\n const result = await this.createCartBatch(batch, { retry: false });\n return { cart: result, errors: [] };\n } catch (err) {\n const message = this.extractErrorMessage(err);\n if (batch.length === 1) {\n return { cart: null, errors: [{ items: batch, message }] };\n }\n return this.isolateCartCreation(batch);\n }\n }\n\n /**\n * Binary search to isolate failing items during cart creation.\n * Uses CreateCartMutation until a cart is created, then switches to addBatchToCart.\n * Returns the created cart (if any items succeeded) and pinpoints individual failing items.\n */\n private async isolateCartCreation(\n batch: CartLineItemInput[]\n ): Promise<{\n cart: ReturnType<typeof toCart> | null;\n errors: CartBatchError[];\n }> {\n const mid = Math.floor(batch.length / 2);\n const left = batch.slice(0, mid);\n const right = batch.slice(mid);\n\n // Try left half - create cart\n const leftResult = await this.tryCreateCartWithIsolation(left);\n let cart = leftResult.cart;\n const errors = [...leftResult.errors];\n\n // Try right half - add to cart if we have one, otherwise create\n if (cart) {\n const rightResult = await this.tryAddBatchWithIsolation(cart.entityId, right);\n if (rightResult.cart) cart = rightResult.cart;\n errors.push(...rightResult.errors);\n } else {\n const rightResult = await this.tryCreateCartWithIsolation(right);\n cart = rightResult.cart;\n errors.push(...rightResult.errors);\n }\n\n return { cart, errors };\n }\n\n /**\n * Add line items to an existing cart\n * Batches items if more than CART_BATCH_SIZE\n * Continues processing all batches even if some fail, returns partial results with errors\n */\n async addCartLineItems(\n cartEntityId: string,\n lineItems: CartLineItemInput[]\n ): Promise<{\n cart: ReturnType<typeof toCart> | null;\n errors: CartBatchError[];\n }> {\n let cart: ReturnType<typeof toCart> | null = null;\n const errors: CartBatchError[] = [];\n\n // Process items in batches - continue even if some fail\n for (let i = 0; i < lineItems.length; i += CART_BATCH_SIZE) {\n const batch = lineItems.slice(i, i + CART_BATCH_SIZE);\n try {\n const result = await this.addBatchToCart(cartEntityId, batch);\n if (result) cart = result;\n } catch (err) {\n if (this.isGraphQLBusinessError(err)) {\n // If batch is already size 1, no need to isolate - error is already pinpointed\n if (batch.length === 1) {\n errors.push({ items: batch, message: this.extractErrorMessage(err) });\n } else {\n // Business error (out of stock, invalid product, etc.) - isolate to find specific failing items\n const { cart: isolatedCart, errors: isolatedErrors } =\n await this.isolateFailingItems(cartEntityId, batch);\n if (isolatedCart) cart = isolatedCart;\n errors.push(...isolatedErrors);\n }\n } else {\n // Transport error after retries exhausted - record and continue\n errors.push({ items: batch, message: this.extractErrorMessage(err) });\n }\n }\n }\n\n return { cart, errors };\n }\n\n /**\n * Update the quantity of a cart line item\n */\n async updateCartLineItem(\n cartEntityId: string,\n lineItemEntityId: string,\n quantity: number,\n productEntityId: number,\n variantEntityId?: number\n ) {\n const result = await this.request({\n document: UpdateCartLineItemMutation,\n variables: {\n input: {\n cartEntityId,\n lineItemEntityId,\n data: {\n lineItem: {\n productEntityId,\n variantEntityId,\n quantity\n }\n }\n }\n }\n });\n\n const rawCart = result.cart.updateCartLineItem?.cart;\n return rawCart ? toCart(rawCart) : null;\n }\n\n /**\n * Remove a line item from the cart\n */\n async deleteCartLineItem(cartEntityId: string, lineItemEntityId: string) {\n const result = await this.request({\n document: DeleteCartLineItemMutation,\n variables: {\n input: {\n cartEntityId,\n lineItemEntityId\n }\n }\n });\n\n const rawCart = result.cart.deleteCartLineItem?.cart;\n return rawCart ? toCart(rawCart) : null;\n }\n\n /**\n * Delete an entire cart\n */\n async deleteCart(cartEntityId: string) {\n const result = await this.request({\n document: DeleteCartMutation,\n variables: {\n input: {\n cartEntityId\n }\n }\n });\n\n return result.cart.deleteCart?.deletedCartEntityId ?? null;\n }\n\n /**\n * Create a cart or add to existing cart\n * Convenience method that handles both cases\n * Returns { cart, errors } for consistent handling\n */\n async addToCart(\n lineItems: CartLineItemInput[],\n existingCartId?: string\n ): Promise<{\n cart: ReturnType<typeof toCart> | null;\n errors: CartBatchError[];\n }> {\n if (existingCartId) {\n return this.addCartLineItems(existingCartId, lineItems);\n }\n return this.createCart(lineItems);\n }\n\n /**\n * Create single-use redirect URLs for a cart\n * URLs should be generated just-in-time (within 30s of use)\n */\n async createCartRedirectUrls(\n cartEntityId: string\n ): Promise<CartRedirectUrls | null> {\n const result = await this.request({\n document: CreateCartRedirectUrlsMutation,\n variables: {\n input: {\n cartEntityId\n }\n }\n });\n\n return result.cart.createCartRedirectUrls?.redirectUrls ?? null;\n }\n\n /**\n * Create a metafield on a cart\n */\n async createCartMetafield(\n cartEntityId: string,\n key: string,\n value: string\n ): Promise<void> {\n await this.executeWithRetry({\n document: CreateCartMetafieldMutation,\n variables: {\n input: {\n cartEntityId,\n data: {\n key,\n value\n }\n }\n }\n });\n }\n\n /**\n * Get checkout by entity ID\n * Checkouts are automatically created when a cart is created\n */\n async getCheckout(checkoutEntityId?: string) {\n const result = await this.request({\n document: GetCheckoutQuery,\n variables: {\n checkoutEntityId\n }\n });\n\n const rawCheckout = result.site.checkout;\n return rawCheckout ? toCheckout(rawCheckout) : null;\n }\n\n /**\n * Add shipping consignments (addresses) to a checkout\n * This is required for tax calculation\n */\n async setCheckoutShippingAddress(\n checkoutEntityId: string,\n address: CheckoutAddress,\n lineItems: CheckoutConsignmentLineItem[]\n ) {\n // Add the new consignment with the provided address and line items\n const result = await this.request({\n document: AddCheckoutShippingConsignmentsMutation,\n variables: {\n input: {\n checkoutEntityId,\n data: {\n consignments: [\n {\n address,\n lineItems\n }\n ]\n }\n }\n }\n });\n\n const rawCheckout =\n result.checkout.addCheckoutShippingConsignments?.checkout;\n\n return rawCheckout ? toCheckout(rawCheckout) : null;\n }\n\n /**\n * Add shipping consignments (addresses) to a checkout\n * This is required for tax calculation\n */\n async setCheckoutBillingAddress(\n checkoutEntityId: string,\n address: CheckoutAddress\n ) {\n // Add the new consignment with the provided address and line items\n const result = await this.request({\n document: AddCheckoutBillingAddressMutation,\n variables: {\n input: {\n checkoutEntityId,\n data: {\n address\n }\n }\n }\n });\n\n const rawCheckout = result.checkout.addCheckoutBillingAddress?.checkout;\n\n return rawCheckout ? toCheckout(rawCheckout) : null;\n }\n\n /**\n * Get customer's saved addresses and customer info\n * Requires the customer to be logged in\n * Automatically paginates through all addresses\n */\n async getCustomerAddresses(): Promise<{\n customerInfo: CustomerInfo | null;\n addresses: CustomerAddress[];\n }> {\n const result = await this.request({\n document: GetCustomerAddressesQuery\n });\n\n if (!result.customer) {\n return {\n customerInfo: null,\n addresses: []\n };\n }\n\n const customerInfo: CustomerInfo = {\n entityId: result.customer.entityId,\n firstName: result.customer.firstName,\n lastName: result.customer.lastName,\n email: result.customer.email\n };\n\n const allAddressEdges = [...(result.customer.addresses.edges ?? [])];\n\n if (result.customer.addresses.pageInfo.hasNextPage) {\n const additionalEdges = await fetchAllPages(\n this,\n GetCustomerAddressesQuery,\n { after: result.customer.addresses.pageInfo.endCursor },\n (r: GetCustomerAddressesResult) => r.customer?.addresses ?? null\n );\n allAddressEdges.push(...additionalEdges);\n }\n\n const addresses = allAddressEdges.map((edge, index) =>\n convertCustomerAddressToCustomerAddress(edge.node, index)\n );\n\n return {\n customerInfo,\n addresses\n };\n }\n\n /**\n * Update checkout customer message (order notes)\n * This message will be included with the order\n */\n async updateCheckoutCustomerMessage(\n checkoutEntityId: string,\n options: { purchaseOrderNumber: string | null; threadId: string | null }\n ) {\n let message = '';\n\n if (options.purchaseOrderNumber) {\n message += `PO Number: ${options.purchaseOrderNumber}, `;\n }\n\n if (options.threadId) {\n if (message) {\n message += '\\n';\n }\n message += `Thread ID: ${options.threadId}`;\n }\n\n const result = await this.request({\n document: UpdateCheckoutCustomerMessageMutation,\n variables: {\n input: {\n checkoutEntityId,\n data: {\n message\n }\n }\n }\n });\n\n const rawCheckout = result.checkout.updateCheckoutCustomerMessage?.checkout;\n return rawCheckout ? toCheckout(rawCheckout) : null;\n }\n\n /**\n * Get product variant details for multiple products\n * Returns product options and all variants with their option values\n * Automatically paginates through all variants, options, and option values\n */\n async getProductVariantDetails(\n productEntityIds: number[]\n ): Promise<ProductVariantDetails[]> {\n const result = await this.request({\n document: GetProductVariantDetailsQuery,\n variables: {\n entityIds: productEntityIds\n }\n });\n\n const products: ProductVariantDetails[] = [];\n\n for (const edge of result.site.products.edges ?? []) {\n const product = edge.node;\n\n // Paginate variants\n const allVariantEdges = [...(product.variants.edges ?? [])];\n if (product.variants.pageInfo.hasNextPage) {\n const additionalVariants = await fetchAllPages(\n this,\n GetProductVariantsPageQuery,\n {\n entityId: product.entityId,\n after: product.variants.pageInfo.endCursor\n },\n (r) => r.site.product?.variants ?? null\n );\n allVariantEdges.push(...additionalVariants);\n }\n\n // Paginate productOptions\n const allOptionEdges = [...(product.productOptions.edges ?? [])];\n if (product.productOptions.pageInfo.hasNextPage) {\n const additionalOptions = await fetchAllPages(\n this,\n GetProductOptionsPageQuery,\n {\n entityId: product.entityId,\n after: product.productOptions.pageInfo.endCursor\n },\n (r) => r.site.product?.productOptions ?? null\n );\n allOptionEdges.push(...additionalOptions);\n }\n\n // Paginate option values for each MultipleChoiceOption\n // Accumulate into a separate map to avoid mutating API response objects\n // biome-ignore lint/suspicious/noExplicitAny: option node is a union; we narrow via __typename at runtime\n const paginatedValueEdges = new Map<number, any>();\n for (const optionEdge of allOptionEdges) {\n const node = optionEdge.node as Record<string, any>;\n if (\n node.values?.pageInfo.hasNextPage &&\n node.values.pageInfo.endCursor\n ) {\n const additionalValues = await fetchAllPages(\n this,\n GetProductOptionValuesPageQuery,\n {\n entityId: product.entityId,\n optionEntityId: node.entityId,\n after: node.values.pageInfo.endCursor\n },\n (r: GetProductOptionValuesPageResult) => {\n const edges = r.site.product?.productOptions.edges;\n const firstEdge = edges?.[0];\n if (!firstEdge) return null;\n const firstNode = firstEdge.node as Record<string, any>;\n return firstNode.values ?? null;\n }\n );\n paginatedValueEdges.set(node.entityId, {\n ...node.values,\n edges: [...(node.values.edges ?? []), ...additionalValues]\n });\n }\n }\n\n // Map to ProductVariantDetails (same mapping as before)\n products.push({\n entityId: product.entityId,\n productOptions: allOptionEdges\n .filter((optionEdge) => optionEdge.node.isVariantOption)\n .map((optionEdge) => {\n const node = optionEdge.node as Record<string, any>;\n const values =\n paginatedValueEdges.get(node.entityId) ?? node.values;\n return {\n entityId: node.entityId,\n displayName: node.displayName,\n isRequired: node.isRequired,\n isVariantOption: node.isVariantOption,\n displayStyle: node.displayStyle,\n values:\n values?.edges?.map(\n (valueEdge: {\n node: {\n entityId: number;\n label: string;\n isDefault: boolean;\n };\n }) => ({\n entityId: valueEdge.node.entityId,\n label: valueEdge.node.label,\n isDefault: valueEdge.node.isDefault\n })\n ) ?? []\n };\n }),\n variants: allVariantEdges.map((variantEdge) => ({\n entityId: variantEdge.node.entityId,\n sku: variantEdge.node.sku,\n isPurchasable: variantEdge.node.isPurchasable,\n defaultImage: variantEdge.node.defaultImage ?? undefined,\n prices: variantEdge.node\n .prices as ProductVariantDetails['variants'][number]['prices'],\n inventory: variantEdge.node\n .inventory as ProductVariantDetails['variants'][number]['inventory'],\n options: (variantEdge.node.options.edges ?? []).map((optionEdge) => ({\n entityId: optionEdge.node.entityId,\n displayName: optionEdge.node.displayName,\n values: (optionEdge.node.values.edges ?? []).map((valueEdge) => ({\n entityId: valueEdge.node.entityId,\n label: valueEdge.node.label\n }))\n }))\n }))\n });\n }\n\n return products;\n }\n\n /**\n * Get product paths for building product page URLs\n * Returns a map of productEntityId to path\n */\n async getProductPaths(\n productEntityIds: number[]\n ): Promise<Map<number, string>> {\n const result = await this.request({\n document: GetProductPathsQuery,\n variables: {\n entityIds: productEntityIds\n }\n });\n\n const paths = new Map<number, string>();\n for (const edge of result.site.products.edges ?? []) {\n if (edge.node.path) {\n paths.set(edge.node.entityId, edge.node.path);\n }\n }\n return paths;\n }\n\n /**\n * Get products for display (used by showProducts tool)\n * Returns product names, images, prices, and variant information\n */\n async getProductsForDisplay(\n productEntityIds: number[]\n ): Promise<ProductForDisplay[]> {\n const result = await this.request({\n document: GetProductsForDisplayQuery,\n variables: {\n entityIds: productEntityIds\n }\n });\n\n const products: ProductForDisplay[] = [];\n\n for (const edge of result.site.products.edges ?? []) {\n const product = edge.node;\n\n // Paginate variants if needed\n const allVariantEdges = [...(product.variants.edges ?? [])];\n if (product.variants.pageInfo.hasNextPage) {\n const additionalVariants = await fetchAllPages(\n this,\n GetProductVariantsForDisplayPageQuery,\n {\n entityId: product.entityId,\n after: product.variants.pageInfo.endCursor\n },\n (r) => r.site.product?.variants ?? null\n );\n allVariantEdges.push(...additionalVariants);\n }\n\n products.push({\n entityId: product.entityId,\n name: product.name,\n sku: product.sku,\n path: product.path,\n defaultImage: product.defaultImage ?? undefined,\n variants: allVariantEdges.map((variantEdge) => ({\n entityId: variantEdge.node.entityId,\n sku: variantEdge.node.sku,\n isPurchasable: variantEdge.node.isPurchasable,\n defaultImage: variantEdge.node.defaultImage ?? undefined,\n prices: variantEdge.node\n .prices as ProductForDisplay['variants'][number]['prices'],\n inventory: variantEdge.node\n .inventory as ProductForDisplay['variants'][number]['inventory']\n }))\n });\n }\n\n return products;\n }\n}\n\n/**\n * Construct the BigCommerce GraphQL Storefront API endpoint from a store hash.\n * Use this when you have a store hash (e.g., from Catalyst's BIGCOMMERCE_STORE_HASH).\n *\n * @example\n * const endpoint = createBigCommerceEndpoint('abc123');\n * // Returns: 'https://store-abc123.mybigcommerce.com/graphql'\n */\nexport function createBigCommerceEndpoint(storeHash: string): string {\n return `https://store-${storeHash}.mybigcommerce.com/graphql`;\n}\n\n/**\n * Create a BigCommerce client instance\n */\nexport function createBigCommerceClient(\n config: BigCommerceConfig\n): BigCommerceClient {\n return new BigCommerceClient(config);\n}\n","import { create } from 'zustand';\n\ninterface ChatDisplayState {\n isExpanded: boolean;\n setExpanded: (expanded: boolean) => void;\n toggleExpanded: () => void;\n reset: () => void;\n}\n\nexport const useChatDisplayStore = create<ChatDisplayState>((set) => ({\n isExpanded: false,\n setExpanded: (expanded) => set({ isExpanded: expanded }),\n toggleExpanded: () => set((state) => ({ isExpanded: !state.isExpanded })),\n reset: () => set({ isExpanded: false })\n}));\n","import { type ReactNode, useEffect, useLayoutEffect, useRef } from 'react';\nimport { useChatDisplayStore } from '../../stores/chat-display-store.js';\n\ninterface ExpandedChatViewProps {\n children: ReactNode;\n}\n\nexport function ExpandedChatView({ children }: ExpandedChatViewProps) {\n const isExpanded = useChatDisplayStore((state) => state.isExpanded);\n const setExpanded = useChatDisplayStore((state) => state.setExpanded);\n const overlayRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!isExpanded) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n setExpanded(false);\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [isExpanded, setExpanded]);\n\n // Prevent background scroll while expanded, restoring scroll position on close.\n useLayoutEffect(() => {\n if (!isExpanded) return;\n\n const scrollY = window.scrollY;\n const originalOverflow = document.body.style.overflow;\n const originalPosition = document.body.style.position;\n const originalTop = document.body.style.top;\n const originalWidth = document.body.style.width;\n\n document.body.style.overflow = 'hidden';\n document.body.style.position = 'fixed';\n document.body.style.top = `-${scrollY}px`;\n document.body.style.width = '100%';\n\n return () => {\n document.body.style.overflow = originalOverflow;\n document.body.style.position = originalPosition;\n document.body.style.top = originalTop;\n document.body.style.width = originalWidth;\n window.scrollTo(0, scrollY);\n };\n }, [isExpanded]);\n\n // Elevate the Shadow DOM host so the modal appears above the host page.\n // This is the JS equivalent of the :host:has() CSS rule in utilities.css,\n // which Firefox does not support.\n useLayoutEffect(() => {\n if (!isExpanded || !overlayRef.current) return;\n\n const root = overlayRef.current.getRootNode();\n if (!(root instanceof ShadowRoot)) return;\n\n const host = root.host as HTMLElement;\n const prev = {\n position: host.style.position,\n top: host.style.top,\n right: host.style.right,\n bottom: host.style.bottom,\n left: host.style.left,\n zIndex: host.style.zIndex,\n overflow: host.style.overflow\n };\n\n host.style.position = 'fixed';\n host.style.top = '0';\n host.style.right = '0';\n host.style.bottom = '0';\n host.style.left = '0';\n host.style.zIndex = '2147483647';\n host.style.overflow = 'hidden';\n\n return () => {\n host.style.position = prev.position;\n host.style.top = prev.top;\n host.style.right = prev.right;\n host.style.bottom = prev.bottom;\n host.style.left = prev.left;\n host.style.zIndex = prev.zIndex;\n host.style.overflow = prev.overflow;\n };\n }, [isExpanded]);\n\n if (!isExpanded) {\n return null;\n }\n\n return (\n <div\n ref={overlayRef}\n data-state=\"expanded\"\n data-testid=\"modal-overlay\"\n className=\"fixed inset-0 z-50 flex items-center justify-center\"\n >\n {/* Backdrop */}\n <div\n data-testid=\"modal-backdrop\"\n className=\"absolute inset-0 bg-black/50 animate-modal-backdrop-in\"\n />\n\n {/* Content */}\n <div className=\"relative w-[95vw] max-w-[1440px] h-[95vh] bg-surface rounded-lg shadow-2xl flex flex-col overflow-hidden animate-modal-content-in\">\n <div className=\"flex-1 min-h-0\">{children}</div>\n </div>\n </div>\n );\n}\n","/// <reference path=\"../types/libheif-js.d.ts\" />\n\nconst HEIC_MIME_TYPES = new Set(['image/heic', 'image/heif']);\nconst HEIC_EXTENSIONS = new Set(['.heic', '.heif']);\n\nfunction getExtension(filename: string): string {\n const dot = filename.lastIndexOf('.');\n return dot === -1 ? '' : filename.slice(dot).toLowerCase();\n}\n\nexport function isHeic(file: File): boolean {\n if (HEIC_MIME_TYPES.has(file.type)) {\n return true;\n }\n\n if (file.type !== '' && file.type !== 'application/octet-stream') {\n return false;\n }\n\n return HEIC_EXTENSIONS.has(getExtension(file.name));\n}\n\nfunction toJpegName(name: string): string {\n return name.replace(/\\.heic$/i, '.jpg').replace(/\\.heif$/i, '.jpg');\n}\n\n/** Try native browser HEIC decoding (Safari 17+, Chrome 120+). */\nasync function convertNative(\n file: File,\n quality: number\n): Promise<File | null> {\n try {\n const bitmap = await createImageBitmap(file);\n const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);\n const ctx = canvas.getContext('2d')!;\n ctx.drawImage(bitmap, 0, 0);\n bitmap.close();\n\n const blob = await canvas.convertToBlob({ type: 'image/jpeg', quality });\n return new File([blob], toJpegName(file.name), { type: 'image/jpeg' });\n } catch {\n return null;\n }\n}\n\n/** Fallback HEIC decoding via libheif WASM. */\nasync function convertWithLibheif(file: File, quality: number): Promise<File> {\n const { HeifDecoder } = await import('libheif-js/wasm-bundle');\n\n const buffer = await new Promise<Uint8Array>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(new Uint8Array(reader.result as ArrayBuffer));\n reader.onerror = () => reject(new Error('Failed to read file'));\n reader.readAsArrayBuffer(file);\n });\n const decoder = new HeifDecoder();\n const images = decoder.decode(buffer);\n const image = images[0];\n\n if (!image) {\n throw new Error('HEIF processing error');\n }\n\n const width = image.get_width();\n const height = image.get_height();\n\n const canvas = new OffscreenCanvas(width, height);\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Failed to get canvas context');\n }\n\n const imageData = ctx.createImageData(width, height);\n\n await new Promise<void>((resolve, reject) => {\n image.display(imageData, (result) => {\n if (!result) return reject(new Error('HEIF processing error'));\n resolve();\n });\n });\n\n ctx.putImageData(imageData, 0, 0);\n const blob = await canvas.convertToBlob({ type: 'image/jpeg', quality });\n return new File([blob], toJpegName(file.name), { type: 'image/jpeg' });\n}\n\nexport async function convertHeicIfNeeded(file: File): Promise<File> {\n if (!isHeic(file)) return file;\n\n console.debug('heic file detected, attempting to convert');\n\n const quality = 0.9;\n\n // Try native browser decoding first (Safari 17+, Chrome 120+).\n const native = await convertNative(file, quality);\n if (native) {\n console.debug('native heic conversion successful');\n return native;\n }\n\n // Fall back to libheif WASM for browsers without native HEIC support.\n console.debug('falling back to libheif conversion');\n return convertWithLibheif(file, quality);\n}\n","const ALLOWED_FILE_TYPES: Record<string, string> = {\n 'application/pdf': '.pdf',\n 'text/csv': '.csv',\n 'application/vnd.ms-excel': '.xls',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': '.xlsx',\n 'text/plain': '.txt',\n 'application/json': '.json',\n 'image/png': '.png',\n 'image/jpeg': '.jpg,.jpeg',\n 'image/gif': '.gif',\n 'image/webp': '.webp',\n 'image/heic': '.heic',\n 'image/heif': '.heif'\n};\n\nconst ALLOWED_TYPES = Object.keys(ALLOWED_FILE_TYPES);\n\nconst ALLOWED_EXTENSIONS = Object.values(ALLOWED_FILE_TYPES).flatMap((v) =>\n v.split(',')\n);\n/** Common image extensions used to detect image uploads when the browser provides an empty MIME type. */\nconst KNOWN_IMAGE_EXTENSIONS = [\n '.png',\n '.jpg',\n '.jpeg',\n '.gif',\n '.webp',\n '.heic',\n '.heif',\n '.bmp',\n '.tiff',\n '.tif',\n '.svg',\n '.avif'\n];\n\nexport const ACCEPTED_EXTENSIONS = ALLOWED_EXTENSIONS.join(',');\n/** Image MIME types accepted by camera inputs. Listing explicit types (instead of `image/*`)\n * forces iOS to convert HEIC captures to a supported format automatically. */\nexport const ACCEPTED_CAMERA_TYPES =\n 'image/png,image/jpeg,image/gif,image/webp';\nexport const ALLOWED_TYPES_DISPLAY = 'PDF, Excel, CSV, text, or image files';\nexport const ALLOWED_IMAGE_TYPES_DISPLAY = 'PNG, JPEG, GIF, or WebP';\n\n/** Display labels for the file type badges shown in upload UIs. */\nexport const FILE_TYPE_LABELS = ['PDF', 'Excel', 'CSV', 'Images'] as const;\nexport const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB\n\nexport interface FileValidationResult {\n valid: boolean;\n error?: string;\n}\n\nexport function validateFile(file: File): FileValidationResult {\n if (file.size > MAX_FILE_SIZE) {\n return {\n valid: false,\n error: 'File size exceeds 10MB limit. Please choose a smaller file.'\n };\n }\n\n if (!ALLOWED_TYPES.includes(file.type)) {\n const ext = file.name.includes('.')\n ? `.${file.name.split('.').pop()?.toLowerCase()}`\n : undefined;\n\n if (\n file.type.startsWith('image/') ||\n (ext && KNOWN_IMAGE_EXTENSIONS.includes(ext))\n ) {\n return {\n valid: false,\n error: `Image type not supported. Please upload ${ALLOWED_IMAGE_TYPES_DISPLAY} images.`\n };\n }\n\n return {\n valid: false,\n error: `File type not supported. Please upload ${ALLOWED_TYPES_DISPLAY}.`\n };\n }\n\n return { valid: true };\n}\n","import type { ChangeEvent, DragEvent } from 'react';\nimport { useCallback, useRef, useState } from 'react';\nimport { convertHeicIfNeeded, isHeic } from '../lib/convert-heic.js';\nimport { validateFile } from '../lib/file-validation.js';\n\nexport interface UseFileDropOptions {\n onFile: (file: File) => void;\n /** Called before file validation — useful for clearing external errors. */\n onBeforeValidate?: () => void;\n}\n\nexport type UseFileDropResult = ReturnType<typeof useFileDrop>;\n\nexport function useFileDrop({ onFile, onBeforeValidate }: UseFileDropOptions) {\n const [isDragging, setIsDragging] = useState(false);\n const [fileError, setFileError] = useState<string | null>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const cameraInputRef = useRef<HTMLInputElement>(null);\n\n const processFile = useCallback(\n async (file: File) => {\n onBeforeValidate?.();\n setFileError(null);\n\n let fileToValidate = file;\n if (isHeic(file)) {\n try {\n fileToValidate = await convertHeicIfNeeded(file);\n } catch {\n setFileError(\n 'Failed to convert HEIC image. Please convert to JPEG and try again.'\n );\n return;\n }\n }\n\n const result = validateFile(fileToValidate);\n if (!result.valid) {\n setFileError(result.error ?? null);\n return;\n }\n\n onFile(fileToValidate);\n },\n [onFile, onBeforeValidate]\n );\n\n const handleDragOver = useCallback((e: DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(true);\n }, []);\n\n const handleDragLeave = useCallback((e: DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n }, []);\n\n const handleDrop = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n\n const file = e.dataTransfer.files[0];\n if (file) {\n processFile(file);\n }\n },\n [processFile]\n );\n\n const handleFileChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (file) {\n processFile(file);\n }\n if (e.target) {\n e.target.value = '';\n }\n },\n [processFile]\n );\n\n const openFilePicker = useCallback(() => {\n fileInputRef.current?.click();\n }, []);\n\n const openCamera = useCallback(() => {\n cameraInputRef.current?.click();\n }, []);\n\n return {\n isDragging,\n fileError,\n fileInputRef,\n cameraInputRef,\n dragProps: {\n onDragOver: handleDragOver,\n onDragLeave: handleDragLeave,\n onDrop: handleDrop\n },\n handleFileChange,\n openFilePicker,\n openCamera\n };\n}\n","export const CartIcon = () => (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <title>Cart</title>\n <circle cx=\"9\" cy=\"21\" r=\"1\" />\n <circle cx=\"20\" cy=\"21\" r=\"1\" />\n <path d=\"M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6\" />\n </svg>\n);\n","interface CheckIconProps {\n size?: number;\n title?: string;\n}\n\nexport const CheckIcon = ({ size = 12, title = 'Saved' }: CheckIconProps) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"3\"\n >\n <title>{title}</title>\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n);\n","interface CopyIconProps {\n size?: number;\n}\n\nexport const CopyIcon = ({ size = 12 }: CopyIconProps) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <title>Copy</title>\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </svg>\n);\n","export const MaximizeIcon = ({ size = 16 }: { size?: number }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <title>Expand</title>\n <polyline points=\"15 3 21 3 21 9\" />\n <polyline points=\"9 21 3 21 3 15\" />\n <line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\" />\n <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" />\n </svg>\n);\n","export const MinimizeIcon = ({ size = 16 }: { size?: number }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <title>Minimize</title>\n <polyline points=\"4 14 10 14 10 20\" />\n <polyline points=\"20 10 14 10 14 4\" />\n <line x1=\"14\" y1=\"10\" x2=\"21\" y2=\"3\" />\n <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" />\n </svg>\n);\n","interface AlertCircleIconProps {\n size?: number;\n title?: string;\n}\n\nexport const AlertCircleIcon = ({\n size = 12,\n title = 'Error'\n}: AlertCircleIconProps) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <title>{title}</title>\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\" />\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\" />\n </svg>\n);\n","interface SpinnerIconProps {\n size?: number;\n}\n\nexport const SpinnerIcon = ({ size = 12 }: SpinnerIconProps) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n className=\"animate-spin\"\n >\n <title>Loading</title>\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n);\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { CHECKOUT_ADDRESS_ID } from '../../../constants.js';\nimport type { CustomerAddress } from '../../../lib/bigcommerce/index.js';\nimport { cn } from '../../../lib/utils.js';\nimport type { AddressUpdateStatus } from '../../../types.js';\nimport { AlertCircleIcon } from '../../icons/alert-circle-icon.js';\nimport { CheckIcon } from '../../icons/check-icon.js';\nimport { CopyIcon } from '../../icons/copy-icon.js';\nimport { SpinnerIcon } from '../../icons/spinner-icon.js';\n\nexport interface CartifactAddressProps {\n addresses: CustomerAddress[];\n selectedAddressId?: string;\n addressUpdateStatus?: AddressUpdateStatus;\n onAddressChange?: (addressId: string) => void;\n shipToAddress?: CustomerAddress;\n billingAddress?: CustomerAddress;\n selectedBillingAddressId?: string;\n billingAddressUpdateStatus?: AddressUpdateStatus;\n onBillingAddressChange?: (addressId: string) => void;\n}\n\nexport function CartifactAddress({\n addresses,\n selectedAddressId,\n addressUpdateStatus = 'idle',\n onAddressChange,\n shipToAddress,\n billingAddress,\n selectedBillingAddressId,\n billingAddressUpdateStatus = 'idle',\n onBillingAddressChange\n}: CartifactAddressProps) {\n const canShowDefaultAddressWarning =\n addresses.some((addr) => addr.isDefaultShipping) &&\n addresses.some((addr) => addr.isDefaultBilling);\n\n return (\n <div\n className={cn(\n 'grid gap-2',\n billingAddress ? 'grid-cols-2' : 'grid-cols-1'\n )}\n >\n {/* Billing Address */}\n {billingAddress && (\n <AddressSelect\n label=\"Bill to\"\n onAddressChange={onBillingAddressChange}\n addresses={addresses}\n selectedAddressId={selectedBillingAddressId}\n addressUpdateStatus={billingAddressUpdateStatus}\n poAddress={billingAddress}\n defaultAddressFilter={(addr) => addr.isDefaultShipping}\n addressFilter={(addr) => addr.isBilling}\n canShowDefaultAddressWarning={canShowDefaultAddressWarning}\n />\n )}\n\n {/* Ship To Address */}\n <AddressSelect\n label=\"Ship to\"\n onAddressChange={onAddressChange}\n addresses={addresses}\n selectedAddressId={selectedAddressId}\n addressUpdateStatus={addressUpdateStatus}\n poAddress={shipToAddress}\n defaultAddressFilter={(addr) => addr.isDefaultShipping}\n addressFilter={(addr) => addr.isShipping}\n canShowDefaultAddressWarning={canShowDefaultAddressWarning}\n />\n </div>\n );\n}\n\nexport interface AddressSelectProps {\n label: string;\n addresses: CustomerAddress[];\n selectedAddressId?: string;\n addressUpdateStatus?: AddressUpdateStatus;\n onAddressChange?: (addressId: string) => void;\n poAddress?: CustomerAddress;\n defaultAddressFilter?: (addr: CustomerAddress) => boolean;\n addressFilter?: (addr: CustomerAddress) => boolean;\n canShowDefaultAddressWarning: boolean;\n}\n\nfunction AddressSelect(props: AddressSelectProps) {\n const {\n label,\n addresses,\n selectedAddressId,\n addressUpdateStatus = 'idle',\n onAddressChange,\n poAddress,\n defaultAddressFilter = (addr) => addr.isDefaultShipping,\n addressFilter = (addr) => addr.isShipping,\n canShowDefaultAddressWarning\n } = props;\n\n const isCheckoutAddress = selectedAddressId === CHECKOUT_ADDRESS_ID;\n\n const defaultAddress = addresses.find(defaultAddressFilter);\n\n let showDefaultAddressWarning =\n canShowDefaultAddressWarning && !!selectedAddressId && !isCheckoutAddress;\n\n if (showDefaultAddressWarning && defaultAddress) {\n showDefaultAddressWarning = defaultAddress.id !== selectedAddressId;\n }\n\n const addressOptions = addresses.filter(addressFilter);\n\n return (\n <div\n className={`p-2 px-2.5 rounded border border-solid ${showDefaultAddressWarning ? 'bg-warning-bg border-warning' : 'bg-surface-secondary border-border'}`}\n >\n <div className=\"flex justify-between items-center mb-0.5\">\n <span className=\"text-2xs text-text-tertiary uppercase tracking-[0.05em]\">\n {label}\n </span>\n {addressUpdateStatus === 'updating' && (\n <span className=\"flex items-center gap-1 text-2xs font-medium text-text-tertiary uppercase tracking-[0.025em]\">\n <SpinnerIcon size={10} />\n Updating...\n </span>\n )}\n {addressUpdateStatus === 'success' && (\n <span className=\"flex items-center gap-0.5 text-2xs font-semibold text-success-text uppercase tracking-[0.025em]\">\n <CheckIcon size={10} title=\"Updated\" />\n Updated\n </span>\n )}\n {addressUpdateStatus === 'error' && (\n <span className=\"flex items-center gap-0.5 text-2xs font-semibold text-error-text uppercase tracking-[0.025em]\">\n <AlertCircleIcon size={12} title=\"Failed\" />\n Failed to update\n </span>\n )}\n </div>\n <select\n value={selectedAddressId ?? ''}\n onChange={(e) => onAddressChange?.(e.target.value)}\n disabled={addressUpdateStatus === 'updating'}\n className=\"w-full px-2 py-1.5 text-sm font-medium rounded cursor-pointer transition-colors focus:outline-none focus:border-border-focus disabled:opacity-50 disabled:cursor-not-allowed border border-solid font-[inherit] appearance-auto text-text bg-transparent border-border-strong\"\n >\n {poAddress && (\n <>\n <option key={poAddress.id} value={poAddress.id}>\n <AddressSelectOption address={poAddress} />\n </option>\n <option disabled>---</option>\n </>\n )}\n\n {addressOptions.map((addr) => (\n <option key={addr.id} value={addr.id}>\n <AddressSelectOption\n address={addr}\n isDefault={defaultAddressFilter}\n />\n </option>\n ))}\n\n {addressOptions.length > 0 && <option disabled>---</option>}\n\n <option key={CHECKOUT_ADDRESS_ID} value={CHECKOUT_ADDRESS_ID}>\n Enter an address at checkout\n </option>\n </select>\n\n {poAddress && <FormattedAddress address={poAddress} />}\n\n {/* Default address warning */}\n {showDefaultAddressWarning && (\n <p className=\"mt-1.5 pt-1.5 m-0 text-xs leading-[1.4]\">\n Your company has a default address set. Verify your address on the\n checkout page as it may not populate automatically.\n </p>\n )}\n </div>\n );\n}\n\ntype AddressSelectOptionProps = {\n address: CustomerAddress;\n isDefault?: (addr: CustomerAddress) => boolean;\n};\n\nfunction AddressSelectOption(props: AddressSelectOptionProps) {\n const { address, isDefault } = props;\n\n return (\n <>\n {isDefault?.(address) ? '[DEFAULT] ' : ''}\n {address.label ? `[${address.label.toUpperCase()}] ` : ''}\n {address.firstName} {address.lastName} - {address.address1},{' '}\n {address.city}, {address.stateOrProvince} {address.postalCode}\n </>\n );\n}\n\nfunction formatAddress(address: CustomerAddress): string {\n const parts = [address.address1];\n if (address.address2) parts.push(address.address2);\n if (address.city) parts.push(address.city);\n if (address.stateOrProvince) parts.push(address.stateOrProvince);\n // postalCode attaches to the state without a comma\n const lastPart = parts.pop();\n if (address.postalCode) {\n parts.push(`${lastPart} ${address.postalCode}`);\n } else if (lastPart) {\n parts.push(lastPart);\n }\n return parts.join(', ');\n}\n\nfunction FormattedAddress({ address }: { address: CustomerAddress }) {\n const [isCopied, setIsCopied] = useState(false);\n const timerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n useEffect(() => {\n return () => {\n if (timerRef.current) clearTimeout(timerRef.current);\n };\n }, []);\n\n const formattedAddress = formatAddress(address);\n\n const handleCopy = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(formattedAddress);\n setIsCopied(true);\n if (timerRef.current) clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => setIsCopied(false), 1500);\n } catch {\n // Clipboard API unavailable — fail silently\n }\n }, [formattedAddress]);\n\n return (\n <button\n type=\"button\"\n aria-label=\"Copy PO address to clipboard\"\n onClick={handleCopy}\n className={`mt-1.5 pt-1.5 m-0 text-xs leading-[1.4] cursor-pointer flex justify-between items-start gap-1 w-full bg-transparent text-left border-0 border-t border-solid p-0 font-[inherit] border-border-strong text-text-tertiary`}\n >\n <span>\n <span className=\"text-text-tertiary\">PO address:</span>{' '}\n {formattedAddress}\n </span>\n <span className=\"shrink-0 mt-0.5\">\n {isCopied ? (\n <CheckIcon size={12} title=\"Copied\" />\n ) : (\n <CopyIcon size={12} />\n )}\n </span>\n </button>\n );\n}\n","export const formatCurrency = (amount: number, currencyCode = 'USD') => {\n return new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: currencyCode\n }).format(amount);\n};\n","import { formatCurrency } from '../../../lib/formatting.js';\n\nfunction FooterRow({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"flex justify-between py-0.5\">\n <span className=\"text-sm text-text-tertiary\">{label}</span>\n <span className=\"text-sm text-text\">{value}</span>\n </div>\n );\n}\n\nfunction formatOptional(\n value: number | null | undefined,\n currencyCode?: string\n): string {\n return value !== null && value !== undefined\n ? formatCurrency(value, currencyCode)\n : '...';\n}\n\nexport interface CartifactFooterProps {\n subtotal: number;\n tax?: number | null;\n shipping?: number | null;\n total?: number | null;\n currencyCode?: string;\n totalQuantity: number;\n availableItemCount: number;\n onCheckout: () => void;\n isLoading?: boolean;\n allowCheckout?: boolean;\n}\n\nexport function CartifactFooter({\n subtotal,\n tax,\n shipping,\n total,\n currencyCode,\n totalQuantity,\n availableItemCount,\n onCheckout,\n isLoading,\n allowCheckout = true\n}: CartifactFooterProps) {\n return (\n <div className=\"px-4 py-2.5 shrink-0 bg-surface-secondary\">\n <FooterRow\n label=\"Subtotal\"\n value={formatCurrency(subtotal, currencyCode)}\n />\n <FooterRow label=\"Tax\" value={formatOptional(tax, currencyCode)} />\n <FooterRow\n label=\"Shipping\"\n value={formatOptional(shipping, currencyCode)}\n />\n <div className=\"flex justify-between mt-1 pt-1.5 border-t border-border\">\n <span className=\"text-sm font-semibold text-text\">Total</span>\n <span className=\"text-sm font-semibold text-text\">\n {formatOptional(total, currencyCode)}\n </span>\n </div>\n <button\n type=\"button\"\n onClick={onCheckout}\n disabled={availableItemCount === 0 || isLoading || !allowCheckout}\n className=\"bg-surface-invert shadow-button transition-all duration-200 ease-in-out enabled:hover:bg-surface-invert-hover enabled:hover:shadow-button-hover enabled:hover:-translate-y-px relative w-full mt-2.5 px-4 py-2.5 min-h-11 text-text-invert rounded-full text-sm font-semibold flex items-center justify-center gap-1.5 cursor-pointer overflow-hidden disabled:opacity-50 disabled:cursor-not-allowed\"\n aria-label={`Checkout with ${totalQuantity} items`}\n >\n {isLoading ? (\n 'Loading...'\n ) : (\n <>\n Checkout with {totalQuantity}{' '}\n {totalQuantity === 1 ? 'product' : 'products'}\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n aria-hidden=\"true\"\n >\n <title>Checkout</title>\n <path d=\"M5 12h14M12 5l7 7-7 7\" />\n </svg>\n </>\n )}\n </button>\n </div>\n );\n}\n","export const XIcon = () => (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <title>Remove</title>\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n);\n","import type { ButtonHTMLAttributes, ReactNode } from 'react';\nimport { cn } from '../lib/utils.js';\n\nexport interface StepButtonProps\n extends ButtonHTMLAttributes<HTMLButtonElement> {\n children: ReactNode;\n}\n\nconst baseClass =\n 'w-8 h-8 p-0 flex items-center justify-center bg-surface-tertiary border border-border rounded-sm text-text-tertiary cursor-pointer transition-all duration-150 hover:bg-surface-disabled hover:border-border-strong hover:text-text-secondary disabled:opacity-50 disabled:cursor-not-allowed';\n\nexport function StepButton({\n children,\n className,\n ...props\n}: StepButtonProps) {\n return (\n <button\n type=\"button\"\n className={className ? cn(baseClass, className) : baseClass}\n {...props}\n >\n {children}\n </button>\n );\n}","import type React from 'react';\nimport { useEffect, useRef, useState } from 'react';\nimport { CheckIcon } from './icons/check-icon.js';\nimport { SpinnerIcon } from './icons/spinner-icon.js';\nimport { StepButton } from './step-button.js';\n\nexport interface QuantitySelectorProps {\n value: number;\n onChange: (value: number) => void | Promise<void>;\n min?: number;\n max?: number;\n className?: string;\n /** When true, updates happen on blur with status indicators. When false, updates are immediate. */\n asyncMode?: boolean;\n /** Test ID for the input element */\n testId?: string;\n}\n\nexport function QuantitySelector({\n value,\n onChange,\n min = 1,\n max,\n className = '',\n asyncMode = false,\n testId\n}: QuantitySelectorProps) {\n const [inputValue, setInputValue] = useState(String(value));\n const [status, setStatus] = useState<'idle' | 'saving' | 'success' | 'error'>(\n 'idle'\n );\n const statusTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Clear timeout on unmount\n useEffect(() => {\n return () => {\n if (statusTimeoutRef.current) {\n clearTimeout(statusTimeoutRef.current);\n }\n };\n }, []);\n\n // Sync local state when external value changes\n useEffect(() => {\n setInputValue(String(value));\n }, [value]);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const rawValue = e.target.value;\n\n // Allow empty input temporarily while typing\n if (rawValue === '') {\n setInputValue('');\n return;\n }\n\n // Only allow numeric characters\n if (!/^\\d+$/.test(rawValue)) {\n return;\n }\n\n setInputValue(rawValue);\n\n // In sync mode, update immediately\n if (!asyncMode) {\n const newValue = Number.parseInt(rawValue, 10);\n if (!Number.isNaN(newValue)) {\n const clampedValue = Math.max(\n min,\n max !== undefined ? Math.min(newValue, max) : newValue\n );\n onChange(clampedValue);\n }\n }\n };\n\n const handleBlur = async () => {\n const newQty = Number.parseInt(inputValue, 10);\n\n if (asyncMode) {\n // Async mode: save on blur with status indicators\n if (!Number.isNaN(newQty) && newQty >= min && newQty !== value) {\n const clampedQty = max !== undefined ? Math.min(newQty, max) : newQty;\n setStatus('saving');\n try {\n await onChange(clampedQty);\n setStatus('success');\n statusTimeoutRef.current = setTimeout(() => {\n setStatus((prev) => (prev === 'success' ? 'idle' : prev));\n }, 1500);\n } catch {\n setInputValue(String(value));\n setStatus('error');\n statusTimeoutRef.current = setTimeout(() => {\n setStatus((prev) => (prev === 'error' ? 'idle' : prev));\n }, 3000);\n }\n } else if (Number.isNaN(newQty) || newQty < min) {\n setInputValue(String(value));\n }\n } else {\n // Sync mode: reset to min if empty or invalid\n if (inputValue === '' || Number.isNaN(newQty)) {\n setInputValue(String(min));\n onChange(min);\n }\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n e.currentTarget.blur();\n }\n };\n\n const handleStep = async (delta: number) => {\n const current = Number.parseInt(inputValue, 10);\n const base = Number.isNaN(current) ? value : current;\n const newValue = Math.max(\n min,\n max !== undefined ? Math.min(base + delta, max) : base + delta\n );\n if (newValue === base) return;\n\n setInputValue(String(newValue));\n\n if (asyncMode) {\n if (statusTimeoutRef.current) {\n clearTimeout(statusTimeoutRef.current);\n }\n setStatus('saving');\n try {\n await onChange(newValue);\n setStatus('success');\n statusTimeoutRef.current = setTimeout(() => {\n setStatus((prev) => (prev === 'success' ? 'idle' : prev));\n }, 1500);\n } catch {\n setInputValue(String(value));\n setStatus('error');\n statusTimeoutRef.current = setTimeout(() => {\n setStatus((prev) => (prev === 'error' ? 'idle' : prev));\n }, 3000);\n }\n } else {\n onChange(newValue);\n }\n };\n\n const atMin = value <= min;\n const atMax = max !== undefined && value >= max;\n const isSaving = status === 'saving';\n\n return (\n <span className={`inline-flex items-center gap-0.5 ${className}`}>\n <StepButton\n onClick={() => handleStep(-1)}\n disabled={atMin || isSaving}\n aria-label=\"Decrease quantity\"\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n aria-hidden=\"true\"\n >\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n </StepButton>\n <input\n type=\"text\"\n inputMode=\"numeric\"\n pattern=\"[0-9]*\"\n value={inputValue}\n disabled={isSaving}\n onChange={handleChange}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n data-testid={testId}\n className={`w-8 h-8 px-0.5 py-0.5 text-xs text-center focus:outline-none focus:border-border-focus text-text border border-solid ${\n isSaving\n ? 'border-border bg-surface-tertiary opacity-60'\n : 'border-border'\n }`}\n />\n <StepButton\n onClick={() => handleStep(1)}\n disabled={atMax || isSaving}\n aria-label=\"Increase quantity\"\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n aria-hidden=\"true\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n </StepButton>\n {isSaving && (\n <span className=\"text-text-tertiary ml-0.5\">\n <SpinnerIcon />\n </span>\n )}\n {status === 'success' && (\n <span className=\"text-success ml-0.5\">\n <CheckIcon />\n </span>\n )}\n {status === 'error' && (\n <span className=\"text-error text-xs ml-0.5\">Failed</span>\n )}\n </span>\n );\n}\n","import type { JSX } from 'react';\nimport { formatCurrency } from '../../../lib/formatting.js';\nimport type { CartItem } from '../../../types.js';\nimport { XIcon } from '../../icons/x-icon.js';\nimport { QuantitySelector } from '../../quantity-selector.js';\n\nexport interface CartifactLineItemProps {\n item: CartItem;\n onUpdateQuantity: (id: string, quantity: number) => void | Promise<void>;\n onRemove: (id: string) => void;\n onShowMoreLikeThis: (itemName: string, sku?: string) => void;\n onViewProduct?: (item: CartItem) => void;\n}\n\nexport function CartifactLineItem(props: CartifactLineItemProps) {\n const {\n item,\n onUpdateQuantity,\n onRemove,\n onShowMoreLikeThis,\n onViewProduct\n } = props;\n const poPriceValue = item.poPriceValue;\n const hasPriceMismatch =\n item.status === 'price-mismatch' &&\n poPriceValue !== undefined &&\n poPriceValue > 0;\n const currenciesDiffer =\n item.poPriceCurrencyCode &&\n item.catalogPriceCurrencyCode &&\n item.poPriceCurrencyCode !== item.catalogPriceCurrencyCode;\n const isFavorable =\n hasPriceMismatch &&\n poPriceValue !== undefined &&\n poPriceValue > (item.price ?? 0);\n\n return (\n <div className=\"group flex gap-3 p-2 rounded mb-2 last:mb-0\">\n {item.imageUrl ? (\n <img\n src={item.imageUrl}\n alt={item.name}\n className=\"w-12 h-12 object-cover rounded shrink-0\"\n />\n ) : (\n <div className=\"w-12 h-12 bg-surface-tertiary rounded shrink-0\" />\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex-1 min-w-0\">\n {onViewProduct ? (\n <button\n type=\"button\"\n onClick={() => onViewProduct(item)}\n className=\"text-sm font-medium text-text m-0 truncate bg-transparent border-none cursor-pointer p-0 text-left hover:underline\"\n title={item.name}\n >\n {item.name}\n </button>\n ) : (\n <p className=\"text-sm font-medium text-text m-0 truncate\">\n {item.name}\n </p>\n )}\n <p className=\"text-xs text-text-secondary m-0\">SKU: {item.sku}</p>\n </div>\n <div className=\"flex items-center gap-2 shrink-0\">\n <QuantitySelector\n value={item.quantity}\n onChange={(qty) => onUpdateQuantity(item.id, qty)}\n max={item.availableQuantity}\n asyncMode\n />\n <button\n type=\"button\"\n onClick={() => onRemove(item.id)}\n className=\"p-2 text-text-quaternary hover:text-text-secondary shrink-0\"\n aria-label=\"Remove item\"\n >\n <XIcon />\n </button>\n </div>\n </div>\n\n {/* Price Mismatch Badge */}\n {hasPriceMismatch && !currenciesDiffer && (\n <div\n className={`flex items-center gap-1.5 text-xs px-1.5 py-0.5 rounded mt-1 ${\n isFavorable\n ? 'bg-success-bg text-success-text'\n : 'bg-warning-bg text-warning-text'\n }`}\n >\n <span>\n {isFavorable ? 'Catalog price lower' : 'Catalog price higher'}\n {' · '}\n PO: {formatCurrency(poPriceValue, item.poPriceCurrencyCode)} →\n Catalog:{' '}\n {formatCurrency(item.price ?? 0, item.catalogPriceCurrencyCode)}\n </span>\n </div>\n )}\n\n {item.status === 'unavailable' && (\n <span className=\"inline-block text-xs font-medium px-1.5 py-0.5 rounded mt-1 bg-error/20 text-error-text\">\n Unavailable\n </span>\n )}\n\n {item.status === 'pending' && (\n <span className=\"inline-block text-xs font-medium px-1.5 py-0.5 rounded mt-1 bg-warning/20 text-warning-text\">\n Pending\n </span>\n )}\n\n <div className=\"flex items-center justify-between mt-2\">\n <div className=\"flex items-center gap-1.5\">\n <CartifactActionButton\n onClick={() => onShowMoreLikeThis(item.name, item.sku)}\n />\n </div>\n {item.price !== undefined && (\n <span className=\"text-sm font-semibold text-text\">\n {formatCurrency(\n item.price * item.quantity,\n item.catalogPriceCurrencyCode\n )}\n </span>\n )}\n </div>\n </div>\n </div>\n );\n}\n\nfunction CartifactActionButton(props: JSX.IntrinsicElements['button']) {\n return (\n <button\n type=\"button\"\n className=\"text-xs min-h-9 px-2.5 py-1.5 rounded transition-opacity text-text-secondary bg-surface-tertiary hover:bg-surface-disabled hover:text-text opacity-0 group-hover:opacity-100\"\n {...props}\n >\n Show more like this\n </button>\n );\n}\n","import type { ButtonHTMLAttributes, ReactNode } from 'react';\nimport { cn } from '../../../lib/utils.js';\n\nexport interface PanelActionButtonProps\n extends ButtonHTMLAttributes<HTMLButtonElement> {\n children: ReactNode;\n}\n\nconst baseClass =\n 'flex items-center gap-1 min-h-11 px-3 py-1 text-xs font-medium text-text bg-surface-secondary border border-border-focus/20 rounded-md hover:bg-surface-tertiary hover:border-border-focus/35 transition-all whitespace-nowrap';\n\nexport function PanelActionButton({\n children,\n className,\n ...props\n}: PanelActionButtonProps) {\n return (\n <button\n type=\"button\"\n className={className ? cn(baseClass, className) : baseClass}\n {...props}\n >\n {children}\n </button>\n );\n}","import { useEffect, useRef, useState } from 'react';\nimport { PanelActionButton } from './panel-action-button.js';\n\nexport interface CartifactNewOrderProps {\n onNewOrder: () => void | Promise<void>;\n}\n\nexport function CartifactNewOrder({ onNewOrder }: CartifactNewOrderProps) {\n const [confirmingReset, setConfirmingReset] = useState(false);\n const [isResetting, setIsResetting] = useState(false);\n const mountedRef = useRef(true);\n const resetTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined\n );\n\n const handleNewOrderClick = () => {\n if (!confirmingReset) {\n setConfirmingReset(true);\n resetTimerRef.current = setTimeout(() => setConfirmingReset(false), 3000);\n }\n };\n\n const handleConfirmReset = async () => {\n if (resetTimerRef.current) clearTimeout(resetTimerRef.current);\n setConfirmingReset(false);\n setIsResetting(true);\n try {\n await onNewOrder();\n } finally {\n if (mountedRef.current) {\n setIsResetting(false);\n }\n }\n };\n\n const handleCancelReset = () => {\n if (resetTimerRef.current) clearTimeout(resetTimerRef.current);\n setConfirmingReset(false);\n };\n\n useEffect(() => {\n return () => {\n mountedRef.current = false;\n if (resetTimerRef.current) clearTimeout(resetTimerRef.current);\n };\n }, []);\n\n if (isResetting) {\n return (\n <span className=\"flex items-center gap-1.5 text-xs animate-[fadeIn_0.15s_ease]\">\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n className=\"animate-spin\"\n aria-hidden=\"true\"\n >\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n <span className=\"text-text-tertiary font-medium\">Resetting…</span>\n </span>\n );\n }\n\n if (confirmingReset) {\n return (\n <span className=\"flex items-center gap-1.5 text-xs animate-[fadeIn_0.15s_ease]\">\n <span className=\"text-text-tertiary font-medium\">Reset?</span>\n <button\n type=\"button\"\n onClick={handleConfirmReset}\n className=\"min-h-11 min-w-11 px-3 py-1 text-xs font-semibold text-error-text bg-error-bg border border-error/30 rounded hover:bg-error/20 transition-all\"\n >\n Yes\n </button>\n <button\n type=\"button\"\n onClick={handleCancelReset}\n className=\"min-h-11 min-w-11 px-3 py-1 text-xs font-semibold text-text-tertiary bg-surface-secondary border border-border rounded hover:bg-surface-tertiary transition-all\"\n >\n No\n </button>\n </span>\n );\n }\n\n return (\n <PanelActionButton onClick={handleNewOrderClick} title=\"Start a new order\">\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n aria-hidden=\"true\"\n >\n <path d=\"M12 5v14M5 12h14\" />\n </svg>\n New Order\n </PanelActionButton>\n );\n}\n","export const OrderListIcon = () => (\n <svg\n width=\"48\"\n height=\"48\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <title>Order list</title>\n {/* Clipboard body */}\n <path d=\"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\" />\n {/* Clipboard tab */}\n <rect x=\"8\" y=\"2\" width=\"8\" height=\"4\" rx=\"1\" />\n {/* List lines */}\n <line x1=\"9\" y1=\"12\" x2=\"15\" y2=\"12\" />\n <line x1=\"9\" y1=\"16\" x2=\"13\" y2=\"16\" />\n </svg>\n);\n","import { cn } from '../../../lib/utils.js';\nimport { MaximizeIcon } from '../../icons/maximize-icon.js';\nimport { MinimizeIcon } from '../../icons/minimize-icon.js';\nimport { OrderListIcon } from '../../icons/order-list-icon.js';\nimport { CartifactNewOrder } from './cartifact-new-order.js';\nimport { PanelActionButton } from './panel-action-button.js';\n\nexport interface EmptyCartifactProps {\n className?: string;\n isDragging?: boolean;\n onNewOrder?: () => void | Promise<void>;\n onExpand?: () => void;\n onMinimize?: () => void;\n}\n\nexport function EmptyCartifact({\n className = '',\n isDragging = false,\n onNewOrder,\n onExpand,\n onMinimize\n}: EmptyCartifactProps) {\n const hasHeaderButtons = onNewOrder || onExpand || onMinimize;\n return (\n <div\n className={cn(\n 'rounded-lg flex flex-col h-full bg-surface-secondary relative transition-colors duration-200',\n isDragging && 'bg-surface-tertiary',\n className\n )}\n >\n {hasHeaderButtons && (\n <div className=\"absolute top-0 right-0 px-4 py-3 z-10 flex items-center gap-2\">\n {onNewOrder && <CartifactNewOrder onNewOrder={onNewOrder} />}\n {onExpand && (\n <PanelActionButton onClick={onExpand} aria-label=\"Expand\">\n <MaximizeIcon size={14} />\n Expand\n </PanelActionButton>\n )}\n {onMinimize && (\n <PanelActionButton onClick={onMinimize} aria-label=\"Minimize\">\n <MinimizeIcon size={14} />\n Minimize\n </PanelActionButton>\n )}\n </div>\n )}\n <div className=\"flex flex-col flex-1 items-center justify-center gap-4 py-3 px-8\">\n <div className=\"flex items-center justify-center w-16 h-16 rounded-2xl p-1 text-text\">\n <OrderListIcon />\n </div>\n <h3 className=\"m-0 text-base font-semibold text-text\">\n Your cart will appear here\n </h3>\n {/* Balances content below heading to match left panel's description+badges */}\n <div className=\"h-[50px]\" aria-hidden=\"true\" />\n </div>\n {/* Matches ChatInput height for vertical centering alignment with left panel */}\n <div className=\"shrink-0 h-[67px]\" />\n </div>\n );\n}\n","import type { StateCreator } from 'zustand';\nimport type { PurchaseOrderStore } from '../purchase-order-store.js';\n\n/**\n * Transient state for AI SDK coordination.\n * Not persisted - used for queueing messages to the AI SDK.\n */\nexport interface AISlice {\n ai: {\n /** Message queued to be sent to the AI SDK */\n pendingMessage: string | null;\n /** Whether to scroll to bottom after sending (default: true) */\n shouldScroll: boolean;\n };\n /**\n * Queue a message to send to ai sdk.\n * @param scroll - Whether to scroll to bottom after sending (default: true)\n */\n sendMessage: (message: string, options?: { scroll?: boolean }) => void;\n /**\n * Clear the queued message as it is consumed by ai sdk.\n */\n consumeMessage: () => void;\n}\n\nexport const initialAIState: AISlice['ai'] = {\n pendingMessage: null,\n shouldScroll: true\n};\n\nexport const createAISlice: StateCreator<\n PurchaseOrderStore,\n [['zustand/devtools', never], ['zustand/persist', unknown]],\n [],\n AISlice\n> = (set) => ({\n ai: { ...initialAIState },\n sendMessage: (message: string, options?: { scroll?: boolean }) =>\n set(\n (state) => ({\n ai: {\n ...state.ai,\n pendingMessage: message,\n shouldScroll: options?.scroll ?? true\n }\n }),\n false,\n 'ai/sendMessage'\n ),\n consumeMessage: () =>\n set(\n (state) => ({\n ai: { ...state.ai, pendingMessage: null, shouldScroll: true }\n }),\n false,\n 'ai/consumeMessage'\n )\n});\n","import type { StateCreator } from 'zustand';\nimport type { BatchResult, ToolCallResult } from '../../lib/batch-processor.js';\nimport type { PurchaseOrderStore } from '../purchase-order-store.js';\n\nexport type BatchProcessingStatus =\n | 'idle'\n | 'processing'\n | 'complete'\n | 'error';\nexport interface BatchProcessorSlice {\n batchProcessing: {\n status: BatchProcessingStatus;\n error: string | null;\n results: BatchResult[] | null;\n processingFailuresString: string;\n toolCalls: ToolCallResult[];\n revealedCount: number;\n threadIds: string[];\n };\n // Actions\n setBatchProcessingStatus: (status: BatchProcessingStatus) => void;\n setBatchProcessingError: (error: string | null) => void;\n setBatchProcessingResults: (\n results: BatchResult[],\n processingFailuresString: string\n ) => void;\n addToolCall: (newCall: ToolCallResult) => void;\n addBatchThreadId: (threadId: string) => void;\n incrementRevealed: () => void;\n resetBatchProcessing: () => void;\n}\n\nexport const initialBatchProcessorState: BatchProcessorSlice['batchProcessing'] =\n {\n status: 'idle',\n error: null,\n results: null,\n processingFailuresString: '',\n toolCalls: [],\n revealedCount: 0,\n threadIds: []\n };\n\nexport const createBatchProcessorSlice: StateCreator<\n PurchaseOrderStore,\n [['zustand/devtools', never], ['zustand/persist', unknown]],\n [],\n BatchProcessorSlice\n> = (set) => ({\n batchProcessing: { ...initialBatchProcessorState },\n\n setBatchProcessingStatus: (status) =>\n set(\n (state) => ({ batchProcessing: { ...state.batchProcessing, status } }),\n false,\n 'batchProcessing/setStatus'\n ),\n\n setBatchProcessingError: (error) =>\n set(\n (state) => ({ batchProcessing: { ...state.batchProcessing, error } }),\n false,\n 'batchProcessing/setError'\n ),\n\n setBatchProcessingResults: (results, processingFailuresString) =>\n set(\n (state) => ({\n batchProcessing: {\n ...state.batchProcessing,\n results,\n processingFailuresString\n }\n }),\n false,\n 'batchProcessing/setResults'\n ),\n\n addToolCall: (newCall) =>\n set(\n (state) => ({\n batchProcessing: {\n ...state.batchProcessing,\n toolCalls: [...state.batchProcessing.toolCalls, newCall]\n }\n }),\n false,\n 'batchProcessing/addToolCall'\n ),\n\n addBatchThreadId: (threadId) =>\n set(\n (state) => ({\n batchProcessing: {\n ...state.batchProcessing,\n threadIds: [...state.batchProcessing.threadIds, threadId]\n }\n }),\n false,\n 'batchProcessing/addThreadId'\n ),\n\n incrementRevealed: () =>\n set(\n (state) => ({\n batchProcessing: {\n ...state.batchProcessing,\n revealedCount: state.batchProcessing.revealedCount + 1\n }\n }),\n false,\n 'batchProcessing/incrementRevealed'\n ),\n\n resetBatchProcessing: () =>\n set(\n { batchProcessing: { ...initialBatchProcessorState } },\n false,\n 'batchProcessing/reset'\n )\n});\n","import type { StateCreator } from 'zustand';\nimport type { Cart, Checkout } from '../../lib/bigcommerce/storefront/types.js';\nimport type { PurchaseOrderStore } from '../purchase-order-store.js';\n\n/**\n * BigCommerce session state fetched from the API.\n * This data is not persisted to localStorage - it's fetched fresh each session.\n */\nexport interface BcSessionSlice {\n bcSession: {\n bcCart: Cart | null;\n checkout: Checkout | null;\n isLoading: boolean;\n productPaths: Record<number, string>;\n };\n setBcCart: (cart: Cart | null) => void;\n setCheckout: (checkout: Checkout | null) => void;\n setIsLoading: (loading: boolean) => void;\n setProductPaths: (paths: Record<number, string>) => void;\n clearBcSession: () => void;\n}\n\nexport const initialBcSessionState: BcSessionSlice['bcSession'] = {\n bcCart: null,\n checkout: null,\n isLoading: false,\n productPaths: {}\n};\n\nexport const createBcSessionSlice: StateCreator<\n PurchaseOrderStore,\n [['zustand/devtools', never], ['zustand/persist', unknown]],\n [],\n BcSessionSlice\n> = (set) => ({\n bcSession: { ...initialBcSessionState },\n setBcCart: (bcCart) =>\n set(\n (state) => ({ bcSession: { ...state.bcSession, bcCart } }),\n false,\n 'bcSession/setBcCart'\n ),\n setCheckout: (checkout) =>\n set(\n (state) => ({ bcSession: { ...state.bcSession, checkout } }),\n false,\n 'bcSession/setCheckout'\n ),\n setIsLoading: (isLoading) =>\n set(\n (state) => ({ bcSession: { ...state.bcSession, isLoading } }),\n false,\n 'bcSession/setIsLoading'\n ),\n setProductPaths: (productPaths) =>\n set(\n (state) => ({ bcSession: { ...state.bcSession, productPaths } }),\n false,\n 'bcSession/setProductPaths'\n ),\n clearBcSession: () =>\n set(\n () => ({ bcSession: { ...initialBcSessionState } }),\n false,\n 'bcSession/clearBcSession'\n )\n});\n","import type { StateCreator } from 'zustand';\nimport { PO_ADDRESS_ID, PO_BILLING_ADDRESS_ID } from '../../constants.js';\nimport type { CustomerAddress } from '../../lib/bigcommerce/storefront/types.js';\nimport { convertPoAddressToCustomerAddress } from '../../lib/bigcommerce/utils.js';\nimport type {\n Address,\n BuyerInfo,\n ItemWarning,\n SetPoMetadataInput\n} from '../../types.js';\nimport type { PurchaseOrderStore } from '../purchase-order-store.js';\n\n/** The poMetadata object from SetPoMetadataInput */\nexport type PoMetadata = SetPoMetadataInput['poMetadata'];\n\nexport interface POPriceInfo {\n productEntityId: number;\n variantEntityId?: number;\n poPrice: number;\n poCurrency: string;\n}\n\nexport interface CartifactSlice {\n cartifact: {\n cartEntityId: string | null;\n poItemPrices: Record<string, POPriceInfo>;\n // PO metadata\n orderId: string | null;\n buyerInfo: BuyerInfo | null;\n shipToAddress: CustomerAddress | null;\n billingAddress: CustomerAddress | null;\n poMetadataSet: boolean;\n itemWarnings: ItemWarning[];\n };\n // Actions\n setCartEntityId: (cartEntityId: string | null) => void;\n setPoItemPrice: (\n productEntityId: number,\n variantEntityId: number | undefined,\n poPrice: number,\n poCurrency: string\n ) => void;\n removePoItemPrice: (\n productEntityId: number,\n variantEntityId?: number\n ) => void;\n clearPoItemPrices: () => void;\n setOrderId: (orderId: string | null) => void;\n setBuyerInfo: (buyerInfo: BuyerInfo | null) => void;\n setShipToAddress: (address: Address | null) => void;\n setBillingAddress: (address: Address | null) => void;\n setPoMetadataSet: (set: boolean) => void;\n setItemWarnings: (warnings: ItemWarning[]) => void;\n removeItemWarning: (warning: ItemWarning) => void;\n clearCartifact: () => void;\n /** Apply all PO metadata fields at once (used by tool handler and batch processor) */\n applyPoMetadata: (poMetadata: PoMetadata) => void;\n}\n\nfunction makePoItemPriceKey(\n productEntityId: number,\n variantEntityId?: number\n): string {\n return `${productEntityId}-${variantEntityId}`;\n}\n\nexport const initialCartifactState: CartifactSlice['cartifact'] = {\n cartEntityId: null,\n poItemPrices: {},\n orderId: null,\n buyerInfo: null,\n shipToAddress: null,\n billingAddress: null,\n poMetadataSet: false,\n itemWarnings: []\n};\n\nexport const createCartifactSlice: StateCreator<\n PurchaseOrderStore,\n [['zustand/devtools', never], ['zustand/persist', unknown]],\n [],\n CartifactSlice\n> = (set) => ({\n cartifact: { ...initialCartifactState },\n setCartEntityId: (cartEntityId) =>\n set(\n (state) => ({ cartifact: { ...state.cartifact, cartEntityId } }),\n false,\n 'cartifact/setCartEntityId'\n ),\n setPoItemPrice: (productEntityId, variantEntityId, poPrice, poCurrency) =>\n set(\n (state) => ({\n cartifact: {\n ...state.cartifact,\n poItemPrices: {\n ...state.cartifact.poItemPrices,\n [makePoItemPriceKey(productEntityId, variantEntityId)]: {\n productEntityId,\n variantEntityId,\n poPrice,\n poCurrency\n }\n }\n }\n }),\n false,\n 'cartifact/setPoItemPrice'\n ),\n removePoItemPrice: (productEntityId, variantEntityId) =>\n set(\n (state) => {\n const newPrices = { ...state.cartifact.poItemPrices };\n delete newPrices[makePoItemPriceKey(productEntityId, variantEntityId)];\n return { cartifact: { ...state.cartifact, poItemPrices: newPrices } };\n },\n false,\n 'cartifact/removePoItemPrice'\n ),\n clearPoItemPrices: () =>\n set(\n (state) => ({ cartifact: { ...state.cartifact, poItemPrices: {} } }),\n false,\n 'cartifact/clearPoItemPrices'\n ),\n setOrderId: (orderId) =>\n set(\n (state) => ({ cartifact: { ...state.cartifact, orderId } }),\n false,\n 'cartifact/setOrderId'\n ),\n setBuyerInfo: (buyerInfo) =>\n set(\n (state) => ({ cartifact: { ...state.cartifact, buyerInfo } }),\n false,\n 'cartifact/setBuyerInfo'\n ),\n setShipToAddress: (shipToAddress) =>\n set(\n (state) => ({\n cartifact: {\n ...state.cartifact,\n shipToAddress: shipToAddress\n ? convertPoAddressToCustomerAddress(shipToAddress, {\n id: PO_ADDRESS_ID\n })\n : null\n }\n }),\n false,\n 'cartifact/setShipToAddress'\n ),\n setBillingAddress: (billingAddress) =>\n set(\n (state) => ({\n cartifact: {\n ...state.cartifact,\n billingAddress: billingAddress\n ? convertPoAddressToCustomerAddress(billingAddress, {\n id: PO_BILLING_ADDRESS_ID\n })\n : null\n }\n }),\n false,\n 'cartifact/setBillingAddress'\n ),\n setPoMetadataSet: (poMetadataSet) =>\n set(\n (state) => ({ cartifact: { ...state.cartifact, poMetadataSet } }),\n false,\n 'cartifact/setPoMetadataSet'\n ),\n setItemWarnings: (itemWarnings) =>\n set(\n (state) => ({ cartifact: { ...state.cartifact, itemWarnings } }),\n false,\n 'cartifact/setItemWarnings'\n ),\n removeItemWarning: (warning) =>\n set(\n (state) => ({\n cartifact: {\n ...state.cartifact,\n itemWarnings: state.cartifact.itemWarnings.filter(\n (w) =>\n w.productSku !== warning.productSku ||\n w.productName !== warning.productName ||\n w.status !== warning.status\n )\n }\n }),\n false,\n 'cartifact/removeItemWarning'\n ),\n clearCartifact: () =>\n set(\n (state) => ({\n cartifact: {\n ...state.cartifact,\n cartEntityId: null,\n poItemPrices: {},\n orderId: null,\n buyerInfo: null,\n shipToAddress: null,\n billingAddress: null,\n poMetadataSet: false,\n itemWarnings: []\n }\n }),\n false,\n 'cartifact/clearCartifact'\n ),\n applyPoMetadata: (poMetadata) =>\n set(\n (state) => {\n const updates: Partial<CartifactSlice['cartifact']> = {\n poMetadataSet: true\n };\n\n if (poMetadata.orderId) {\n updates.orderId = poMetadata.orderId;\n }\n\n if (\n poMetadata.buyerEmail ||\n poMetadata.buyerFirstName ||\n poMetadata.buyerLastName\n ) {\n updates.buyerInfo = {\n email: poMetadata.buyerEmail,\n firstName: poMetadata.buyerFirstName,\n lastName: poMetadata.buyerLastName\n };\n }\n\n if (poMetadata.shipToAddress) {\n updates.shipToAddress = convertPoAddressToCustomerAddress(\n poMetadata.shipToAddress,\n { id: PO_ADDRESS_ID }\n );\n }\n\n if (poMetadata.billingAddress) {\n updates.billingAddress = convertPoAddressToCustomerAddress(\n poMetadata.billingAddress,\n { id: PO_BILLING_ADDRESS_ID }\n );\n }\n\n return { cartifact: { ...state.cartifact, ...updates } };\n },\n false,\n 'cartifact/applyPoMetadata'\n )\n});\n","import type { UIMessage } from 'ai';\nimport type { StateCreator } from 'zustand';\nimport type { PurchaseOrderStore } from '../purchase-order-store.js';\n\n/**\n * Chat state for the AI conversation.\n * Persisted to localStorage with truncation (last 100 messages, etc).\n */\nexport interface ChatSlice {\n chat: {\n messages: UIMessage[];\n input: string;\n threadId: string | null;\n toolCallErrors: Record<string, string>;\n };\n // Actions\n setMessages: (messages: UIMessage[]) => void;\n addMessage: (message: UIMessage) => void;\n setInput: (input: string) => void;\n setThreadId: (threadId: string | null) => void;\n setToolCallError: (toolCallId: string, error: string) => void;\n clearChat: () => void;\n}\n\nexport const initialChatState: ChatSlice['chat'] = {\n messages: [],\n input: '',\n threadId: null,\n toolCallErrors: {}\n};\n\nexport const createChatSlice: StateCreator<\n PurchaseOrderStore,\n [['zustand/devtools', never], ['zustand/persist', unknown]],\n [],\n ChatSlice\n> = (set) => ({\n chat: { ...initialChatState },\n setMessages: (messages) =>\n set(\n (state) => ({ chat: { ...state.chat, messages } }),\n false,\n 'chat/setMessages'\n ),\n addMessage: (message) =>\n set(\n (state) => ({\n chat: { ...state.chat, messages: [...state.chat.messages, message] }\n }),\n false,\n 'chat/addMessage'\n ),\n setInput: (input) =>\n set(\n (state) => ({ chat: { ...state.chat, input } }),\n false,\n 'chat/setInput'\n ),\n setThreadId: (threadId) =>\n set(\n (state) => ({ chat: { ...state.chat, threadId } }),\n false,\n 'chat/setThreadId'\n ),\n setToolCallError: (toolCallId, error) =>\n set(\n (state) => ({\n chat: {\n ...state.chat,\n toolCallErrors: {\n ...state.chat.toolCallErrors,\n [toolCallId]: error\n }\n }\n }),\n false,\n 'chat/setToolCallError'\n ),\n clearChat: () =>\n set(\n (state) => ({\n chat: {\n ...state.chat,\n messages: [],\n input: '',\n threadId: null,\n toolCallErrors: {}\n }\n }),\n false,\n 'chat/clearChat'\n )\n});\n","import type { StateCreator } from 'zustand';\nimport type {\n CustomerAddress,\n CustomerInfo\n} from '../../lib/bigcommerce/storefront/types.js';\nimport type { PurchaseOrderStore } from '../purchase-order-store.js';\n\n/**\n * Customer data fetched from BigCommerce on init.\n * This data is not persisted to localStorage - it's fetched fresh each page load.\n */\nexport interface CustomerSlice {\n customer: {\n customerInfo: CustomerInfo | null;\n customerAddresses: CustomerAddress[];\n };\n setCustomerInfo: (info: CustomerInfo | null) => void;\n setCustomerAddresses: (addresses: CustomerAddress[]) => void;\n}\n\nexport const initialCustomerState: CustomerSlice['customer'] = {\n customerInfo: null,\n customerAddresses: []\n};\n\nexport const createCustomerSlice: StateCreator<\n PurchaseOrderStore,\n [['zustand/devtools', never], ['zustand/persist', unknown]],\n [],\n CustomerSlice\n> = (set) => ({\n customer: { ...initialCustomerState },\n setCustomerInfo: (customerInfo) => {\n set(\n (state) => ({\n customer: { ...state.customer, customerInfo },\n customerEntityId: customerInfo?.entityId ?? null\n }),\n false,\n 'customer/setCustomerInfo'\n );\n },\n setCustomerAddresses: (customerAddresses) =>\n set(\n (state) => ({\n customer: { ...state.customer, customerAddresses }\n }),\n false,\n 'customer/setCustomerAddresses'\n )\n});\n","import type { StateCreator } from 'zustand';\nimport type { PurchaseOrderStore } from '../purchase-order-store.js';\n\nexport interface ParserSlice {\n parser: {\n uploadedFileName: string | null;\n parsedContent: string[] | null;\n hasProcessedDocument: boolean;\n threadId: string | null;\n };\n // Actions\n setUploadedFileName: (fileName: string | null) => void;\n setParsedContent: (content: string[] | null) => void;\n setHasProcessedDocument: (hasProcessed: boolean) => void;\n setParserThreadId: (threadId: string | null) => void;\n clearParser: () => void;\n}\n\nexport const initialParserState: ParserSlice['parser'] = {\n uploadedFileName: null,\n parsedContent: null,\n hasProcessedDocument: false,\n threadId: null\n};\n\nexport const createParserSlice: StateCreator<\n PurchaseOrderStore,\n [['zustand/devtools', never], ['zustand/persist', unknown]],\n [],\n ParserSlice\n> = (set) => ({\n parser: { ...initialParserState },\n setUploadedFileName: (uploadedFileName) =>\n set(\n (state) => ({ parser: { ...state.parser, uploadedFileName } }),\n false,\n 'parser/setUploadedFileName'\n ),\n setParsedContent: (parsedContent) =>\n set(\n (state) => ({ parser: { ...state.parser, parsedContent } }),\n false,\n 'parser/setParsedContent'\n ),\n setHasProcessedDocument: (hasProcessedDocument) =>\n set(\n (state) => ({ parser: { ...state.parser, hasProcessedDocument } }),\n false,\n 'parser/setHasProcessedDocument'\n ),\n setParserThreadId: (threadId) =>\n set(\n (state) => ({ parser: { ...state.parser, threadId } }),\n false,\n 'parser/setThreadId'\n ),\n clearParser: () =>\n set(\n (state) => ({\n parser: {\n ...state.parser,\n uploadedFileName: null,\n parsedContent: null,\n hasProcessedDocument: false,\n threadId: null\n }\n }),\n false,\n 'parser/clearParser'\n )\n});\n","import type { StateCreator } from 'zustand';\nimport type { TakeShapeConfig } from '../../lib/types.js';\nimport type { PurchaseOrderStore } from '../purchase-order-store.js';\n\nexport type { TakeShapeConfig } from '../../lib/types.js';\n\nconst INITIAL_STATE: TakeShapeConfig = {\n projectId: '',\n apiKey: '',\n origin: '',\n sseOrigin: ''\n};\n\nexport interface TakeShapeConfigSlice {\n takeshapeConfig: TakeShapeConfig;\n setTakeShapeConfig: (config: TakeShapeConfig) => void;\n}\n\nexport const createTakeShapeConfigSlice: StateCreator<\n PurchaseOrderStore,\n [['zustand/devtools', never], ['zustand/persist', unknown]],\n [],\n TakeShapeConfigSlice\n> = (set) => ({\n takeshapeConfig: { ...INITIAL_STATE },\n setTakeShapeConfig: (config: TakeShapeConfig) =>\n set({ takeshapeConfig: config }, false, 'setTakeShapeConfig')\n});\n","import type { StateCreator } from 'zustand';\nimport type { Cart } from '../../lib/bigcommerce/storefront/types.js';\nimport type { AddressUpdateStatus } from '../../types.js';\nimport type { PurchaseOrderStore } from '../purchase-order-store.js';\n\n/**\n * Initialization status for the store.\n * - 'pending': Waiting for validation\n * - 'existing-cart': Orphan cart detected, awaiting user confirmation\n * - 'ready': Initialization complete, app can render normally\n */\nexport type InitStatus = 'pending' | 'existing-cart' | 'ready';\n\n/**\n * Transient UI state.\n * It is not fetched or restored externally, nor is it persisted anywhere.\n */\nexport interface UISlice {\n ui: {\n initStatus: InitStatus;\n initError: string | null;\n /** Orphan cart detected during initialization, awaiting user confirmation */\n existingCart: Cart | null;\n /** IDs of assistant messages the user has explicitly expanded (not persisted) */\n expandedMessageIds: string[];\n /**\n * Selected shipping address ID\n * TODO: Restore selected address from checkout (and move out of UI state)\n */\n selectedAddressId: string | null;\n /** Shipping address update status */\n addressUpdateStatus: AddressUpdateStatus;\n /**\n * Selected billing address ID\n * TODO: Restore selected billing address from checkout (and move out of UI state)\n */\n selectedBillingAddressId: string | null;\n /** Billing address update status */\n billingAddressUpdateStatus: AddressUpdateStatus;\n };\n // Actions\n /** Toggle expanded state for a message */\n toggleMessageExpanded: (messageId: string) => void;\n setSelectedAddressId: (id: string | null) => void;\n setAddressUpdateStatus: (status: AddressUpdateStatus) => void;\n setSelectedBillingAddressId: (id: string | null) => void;\n setBillingAddressUpdateStatus: (status: AddressUpdateStatus) => void;\n clearAddressSelections: () => void;\n}\n\nexport const initialUIState: UISlice['ui'] = {\n initStatus: 'pending',\n initError: null,\n existingCart: null,\n expandedMessageIds: [],\n selectedAddressId: null,\n addressUpdateStatus: 'idle',\n selectedBillingAddressId: null,\n billingAddressUpdateStatus: 'idle'\n};\n\nexport const createUISlice: StateCreator<\n PurchaseOrderStore,\n [['zustand/devtools', never], ['zustand/persist', unknown]],\n [],\n UISlice\n> = (set) => ({\n ui: { ...initialUIState },\n toggleMessageExpanded: (messageId) =>\n set(\n (state) => {\n const ids = state.ui.expandedMessageIds;\n const isExpanded = ids.includes(messageId);\n return {\n ui: {\n ...state.ui,\n expandedMessageIds: isExpanded\n ? ids.filter((id) => id !== messageId)\n : [...ids, messageId]\n }\n };\n },\n false,\n 'ui/toggleMessageExpanded'\n ),\n setSelectedAddressId: (selectedAddressId) =>\n set(\n (state) => ({ ui: { ...state.ui, selectedAddressId } }),\n false,\n 'ui/setSelectedAddressId'\n ),\n setAddressUpdateStatus: (addressUpdateStatus) =>\n set(\n (state) => ({ ui: { ...state.ui, addressUpdateStatus } }),\n false,\n 'ui/setAddressUpdateStatus'\n ),\n setSelectedBillingAddressId: (selectedBillingAddressId) =>\n set(\n (state) => ({ ui: { ...state.ui, selectedBillingAddressId } }),\n false,\n 'ui/setSelectedBillingAddressId'\n ),\n setBillingAddressUpdateStatus: (billingAddressUpdateStatus) =>\n set(\n (state) => ({ ui: { ...state.ui, billingAddressUpdateStatus } }),\n false,\n 'ui/setBillingAddressUpdateStatus'\n ),\n clearAddressSelections: () =>\n set(\n (state) => ({\n ui: {\n ...state.ui,\n selectedAddressId: null,\n addressUpdateStatus: 'idle',\n selectedBillingAddressId: null,\n billingAddressUpdateStatus: 'idle'\n }\n }),\n false,\n 'ui/clearAddressSelections'\n )\n});\n","import type { UIMessage } from 'ai';\nimport { create } from 'zustand';\nimport { devtools, persist } from 'zustand/middleware';\nimport { STORAGE_KEY, STORAGE_VERSION } from '../constants.js';\nimport type {\n BigCommerceClient,\n MockBigCommerceClient\n} from '../lib/bigcommerce/index.js';\nimport type { Cart } from '../lib/bigcommerce/storefront/types.js';\nimport type { AppState } from '../types.js';\nimport {\n type AISlice,\n createAISlice,\n initialAIState\n} from './slices/ai-slice.js';\nimport {\n type BatchProcessorSlice,\n createBatchProcessorSlice,\n initialBatchProcessorState\n} from './slices/batch-processor-slice.js';\nimport {\n type BcSessionSlice,\n createBcSessionSlice\n} from './slices/bc-session-slice.js';\nimport {\n type CartifactSlice,\n createCartifactSlice,\n initialCartifactState\n} from './slices/cartifact-slice.js';\nimport { type ChatSlice, createChatSlice } from './slices/chat-slice.js';\nimport {\n type CustomerSlice,\n createCustomerSlice\n} from './slices/customer-slice.js';\nimport {\n createParserSlice,\n initialParserState,\n type ParserSlice\n} from './slices/parser-slice.js';\nimport {\n createTakeShapeConfigSlice,\n type TakeShapeConfigSlice\n} from './slices/takeshape-config-slice.js';\nimport {\n createUISlice,\n type InitStatus,\n type UISlice\n} from './slices/ui-slice.js';\nimport type { DeepPartial } from '../utils/type-utils.js';\n\n// Maximum number of messages to persist to localStorage\nconst MAX_PERSISTED_MESSAGES = 100;\n\n// Maximum number of tool call errors to persist to localStorage\nconst MAX_TOOL_CALL_ERRORS = 100;\n\nexport interface PurchaseOrderStore\n extends AISlice,\n ChatSlice,\n CartifactSlice,\n CustomerSlice,\n BcSessionSlice,\n ParserSlice,\n UISlice,\n BatchProcessorSlice,\n TakeShapeConfigSlice {\n // Top-level state\n appState: AppState;\n customerEntityId: number | null;\n fatalError: string | null;\n\n // Actions\n setCustomerEntityId: (id: number | null) => void;\n setFatalError: (error: string | null) => void;\n setAppState: (appState: AppState) => void;\n\n // Initialization actions\n /**\n * Call when all validation passes. Derives UI state from persisted data.\n * Transitions: pending → ready\n */\n completeValidation: () => void;\n\n /**\n * Call when validation fails. Clears persisted state and shows error.\n * Transitions: pending → ready with fresh state\n */\n failValidation: (error: string) => void;\n\n /**\n * Get current init status for conditional rendering.\n */\n getInitStatus: () => InitStatus;\n\n /**\n * Set an existing orphan cart and transition to 'existing-cart' status.\n * Called during initialization when an orphan cart is detected.\n */\n setExistingCart: (cart: Cart) => void;\n\n /**\n * Confirm clearing an existing orphan cart detected during initialization.\n * Deletes the cart via BigCommerce API, clears existingCart, and transitions to 'ready'.\n */\n confirmClearExistingCart: (\n client: BigCommerceClient | MockBigCommerceClient\n ) => Promise<void>;\n\n /**\n * Clear the init error message (after user acknowledges).\n */\n clearInitError: () => void;\n\n /**\n * Restore session from persisted data.\n * Called during initialization to bypass the persist middleware's rehydrate\n * (which can be overwritten by state changes during validation).\n */\n restoreSession: (data: PersistedStateData) => void;\n}\n\n/**\n * Canonical shape of persisted state.\n * This matches exactly what partialize() writes to localStorage.\n */\nexport interface PersistedState {\n customerEntityId: number | null;\n appState: AppState;\n chat: {\n messages: unknown[];\n input: string;\n threadId: string | null;\n toolCallErrors: Record<string, string>;\n };\n cartifact: {\n cartEntityId: string | null;\n poItemPrices: Record<string, unknown>;\n orderId: string | null;\n buyerInfo: unknown | null;\n shipToAddress: unknown | null;\n billingAddress: unknown | null;\n poMetadataSet: boolean;\n itemWarnings: unknown[];\n };\n parser: {\n uploadedFileName: string | null;\n parsedContent: string[] | null;\n hasProcessedDocument: boolean;\n threadId: string | null;\n };\n batchProcessing: {\n threadIds: string[];\n };\n}\n\n/**\n * Defensive type for untrusted persisted state data.\n * Used by restoreSession() which must handle potentially corrupted or incomplete data.\n */\nexport type PersistedStateData = DeepPartial<PersistedState>;\n\n/**\n * Clears all persisted state.\n */\nfunction getCleanState() {\n return {\n appState: 'upload' as const,\n customerEntityId: null,\n fatalError: null,\n ai: { ...initialAIState },\n chat: {\n messages: [],\n input: '',\n threadId: null,\n toolCallErrors: {}\n },\n cartifact: {\n cartEntityId: null,\n poItemPrices: {},\n orderId: null,\n buyerInfo: null,\n shipToAddress: null,\n billingAddress: null,\n poMetadataSet: false,\n itemWarnings: []\n },\n customer: {\n customerInfo: null,\n customerAddresses: []\n },\n bcSession: {\n bcCart: null,\n checkout: null,\n isLoading: false,\n productPaths: {}\n },\n parser: {\n uploadedFileName: null,\n parsedContent: null,\n hasProcessedDocument: false,\n threadId: null\n },\n ui: {\n initStatus: 'ready' as const,\n initError: null,\n existingCart: null,\n expandedMessageIds: [],\n selectedAddressId: null,\n addressUpdateStatus: 'idle' as const,\n selectedBillingAddressId: null,\n billingAddressUpdateStatus: 'idle' as const\n },\n batchProcessing: { ...initialBatchProcessorState }\n };\n}\n\nexport const usePurchaseOrderStore = create<PurchaseOrderStore>()(\n devtools(\n persist(\n (set, get) => ({\n // Combine all slices\n ...createAISlice(set, get, {} as never),\n ...createChatSlice(set, get, {} as never),\n ...createCartifactSlice(set, get, {} as never),\n ...createCustomerSlice(set, get, {} as never),\n ...createBcSessionSlice(set, get, {} as never),\n ...createParserSlice(set, get, {} as never),\n ...createUISlice(set, get, {} as never),\n ...createBatchProcessorSlice(set, get, {} as never),\n ...createTakeShapeConfigSlice(set, get, {} as never),\n\n // Top-level state\n appState: 'upload',\n customerEntityId: null,\n fatalError: null,\n\n // Top-level actions\n setCustomerEntityId: (customerEntityId) =>\n set({ customerEntityId }, false, 'setCustomerEntityId'),\n setFatalError: (fatalError) =>\n set({ fatalError }, false, 'setFatalError'),\n setAppState: (appState) => set({ appState }, false, 'setAppState'),\n\n /**\n * Complete validation successfully. Keeps existing UI state.\n */\n completeValidation: () => {\n set(\n (s) => ({\n ui: {\n ...s.ui,\n initStatus: 'ready',\n initError: null\n }\n }),\n false,\n 'completeValidation'\n );\n },\n\n /**\n * Set an existing orphan cart and transition to 'existing-cart' status.\n */\n setExistingCart: (cart: Cart) => {\n set(\n (s) => ({\n ui: {\n ...s.ui,\n existingCart: cart,\n initStatus: 'existing-cart' as const\n }\n }),\n false,\n 'setExistingCart'\n );\n },\n\n /**\n * Confirm clearing an existing orphan cart.\n * Deletes the cart, clears existingCart, transitions to 'ready'.\n */\n confirmClearExistingCart: async (\n client: BigCommerceClient | MockBigCommerceClient\n ) => {\n try {\n const existingCart = get().ui.existingCart;\n if (existingCart) {\n await client.deleteCart(existingCart.entityId);\n }\n set(\n (s) => ({\n ui: {\n ...s.ui,\n existingCart: null,\n initStatus: 'ready' as const\n }\n }),\n false,\n 'confirmClearExistingCart'\n );\n } catch (error) {\n console.error('Failed to delete existing cart:', error);\n get().setFatalError(\n 'Unable to clear your existing cart. Please refresh and try again.'\n );\n }\n },\n\n /**\n * Validation failed. Clear persisted state and start fresh.\n */\n failValidation: (error: string) => {\n set(\n {\n ...getCleanState(),\n appState: 'upload',\n ui: {\n initStatus: 'ready', // Ready with fresh state\n initError: error, // Keep error for display\n existingCart: null,\n expandedMessageIds: [],\n selectedAddressId: null,\n addressUpdateStatus: 'idle',\n selectedBillingAddressId: null,\n billingAddressUpdateStatus: 'idle'\n }\n },\n false,\n 'failValidation'\n );\n },\n\n /**\n * Get current init status.\n */\n getInitStatus: () => get().ui.initStatus,\n\n /**\n * Clear the init error message.\n */\n clearInitError: () => {\n set(\n (s) => ({\n ui: { ...s.ui, initError: null, initStatus: 'pending' as const }\n }),\n false,\n 'clearInitError'\n );\n },\n\n /**\n * Restore session from persisted data.\n * Bypasses the persist middleware's rehydrate to avoid race conditions\n * where state changes during validation overwrite localStorage.\n */\n restoreSession: (data: PersistedStateData) => {\n set(\n {\n customerEntityId: data.customerEntityId ?? null,\n appState: data.appState ?? 'upload',\n chat: {\n messages: (data.chat?.messages ?? []) as UIMessage[],\n input: data.chat?.input ?? '',\n threadId: data.chat?.threadId ?? null,\n toolCallErrors: (data.chat?.toolCallErrors ??\n {}) as Record<string, string>\n },\n cartifact: {\n ...initialCartifactState,\n ...(data.cartifact as CartifactSlice['cartifact'] | undefined)\n },\n parser: {\n ...initialParserState,\n ...(data.parser ?? {})\n },\n batchProcessing: {\n ...initialBatchProcessorState,\n threadIds: (data.batchProcessing?.threadIds ?? []) as string[]\n }\n },\n false,\n 'restoreSession'\n );\n }\n }),\n {\n name: STORAGE_KEY,\n version: STORAGE_VERSION,\n partialize: (state) => ({\n // Persist customer ID for validation\n customerEntityId: state.customerEntityId,\n\n // Persist app state (workflow phase)\n appState: state.appState,\n\n // Persist chat state with message truncation\n chat: {\n messages: state.chat.messages.slice(-MAX_PERSISTED_MESSAGES),\n input: state.chat.input,\n threadId: state.chat.threadId,\n toolCallErrors: Object.fromEntries(\n Object.entries(state.chat.toolCallErrors).slice(\n -MAX_TOOL_CALL_ERRORS\n )\n )\n },\n\n // Persist cartifact state\n cartifact: state.cartifact,\n\n // Persist parser state\n parser: state.parser,\n\n // Persist batch processing thread IDs for feedback context\n batchProcessing: {\n threadIds: state.batchProcessing.threadIds\n }\n }),\n // Skip automatic rehydration - we manually restore via restoreSession()\n // after validation to avoid race conditions with localStorage overwrites\n skipHydration: true\n }\n ),\n {\n name: 'PurchaseOrderStore',\n store: 'PurchaseOrderStore',\n enabled: true\n }\n )\n);\n","import type { ItemWarning } from '../../../types.js';\nimport { usePurchaseOrderStore } from '../../../stores/purchase-order-store.js';\nimport { XIcon } from '../../icons/x-icon.js';\n\nexport interface LineItemWarningProps {\n item: ItemWarning;\n onSuggestAlternatives: (identifier: string) => void;\n}\n\nexport function itemWarningToString({ productName, productSku }: ItemWarning) {\n if (productName && productSku) {\n return `${productName} (${productSku})`;\n }\n if (productName) {\n return productName;\n }\n if (productSku) {\n return productSku;\n }\n return 'Unknown Product';\n}\n\nexport function LineItemWarning({\n item,\n onSuggestAlternatives\n}: LineItemWarningProps) {\n const removeItemWarning = usePurchaseOrderStore(\n (state) => state.removeItemWarning\n );\n\n return (\n <div className=\"flex gap-3 p-2 rounded mb-2 bg-surface-secondary border border-dashed border-border opacity-70\">\n <div className=\"w-12 h-12 bg-surface-disabled rounded shrink-0 animate-pulse\" />\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex-1 min-w-0\">\n {(item.productName || item.productSku) && (\n <p className=\"text-sm font-medium text-text-secondary m-0 truncate\">\n {itemWarningToString(item)}\n </p>\n )}\n <div className=\"flex items-center gap-1.5 mt-1\">\n <span className=\"inline-flex items-center gap-1 text-2xs font-medium px-1.5 py-0.5 rounded bg-surface-tertiary text-text-secondary\">\n <span className=\"w-1.5 h-1.5 bg-text-secondary rounded-full animate-pulse\" />\n {item.status}\n </span>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => removeItemWarning(item)}\n className=\"p-1 text-text-quaternary hover:text-text-secondary shrink-0\"\n aria-label=\"Dismiss warning\"\n >\n <XIcon />\n </button>\n </div>\n {(item.productName || item.productSku) && (\n <div className=\"mt-2\">\n <button\n type=\"button\"\n onClick={() => onSuggestAlternatives(itemWarningToString(item))}\n className=\"text-xs px-1.5 py-1 rounded text-warning-text bg-warning/20 hover:bg-warning/30\"\n >\n Suggest alternatives\n </button>\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { useCallback, useRef, useState } from 'react';\nimport type { CustomerAddress } from '../../../lib/bigcommerce/index.js';\nimport type {\n AddressUpdateStatus,\n BuyerInfo,\n CartItem,\n CheckoutTotals,\n CustomerInfo,\n ItemWarning\n} from '../../../types.js';\nimport { CartIcon } from '../../icons/cart-icon.js';\nimport { CheckIcon } from '../../icons/check-icon.js';\nimport { CopyIcon } from '../../icons/copy-icon.js';\nimport { MaximizeIcon } from '../../icons/maximize-icon.js';\nimport { MinimizeIcon } from '../../icons/minimize-icon.js';\nimport { CartifactAddress } from './cartifact-address.js';\nimport { CartifactFooter } from './cartifact-footer.js';\nimport { CartifactLineItem } from './cartifact-line-item.js';\nimport { CartifactNewOrder } from './cartifact-new-order.js';\nimport { EmptyCartifact } from './empty-cartifact.js';\nimport { itemWarningToString, LineItemWarning } from './line-item-warning.js';\nimport { PanelActionButton } from './panel-action-button.js';\n\nexport interface CartPanelProps {\n items: CartItem[];\n itemWarnings?: ItemWarning[];\n onUpdateQuantity: (id: string, quantity: number) => void | Promise<void>;\n onRemove: (id: string) => void;\n onCheckout: () => void;\n onSuggestAlternatives: (itemName: string, sku?: string) => void;\n onShowMoreLikeThis: (itemName: string, sku?: string) => void;\n onViewProduct?: (item: CartItem) => void;\n className?: string;\n orderId?: string;\n buyerInfo?: BuyerInfo;\n customerInfo?: CustomerInfo;\n addresses?: CustomerAddress[];\n selectedAddressId?: string;\n addressUpdateStatus?: AddressUpdateStatus;\n onAddressChange?: (addressId: string) => void;\n selectedBillingAddressId?: string;\n billingAddressUpdateStatus?: AddressUpdateStatus;\n onBillingAddressChange?: (addressId: string) => void;\n shipToAddress?: CustomerAddress;\n billingAddress?: CustomerAddress;\n checkoutTotals?: CheckoutTotals;\n isLoading?: boolean;\n poMetadataSet?: boolean;\n isDragging?: boolean;\n onNewOrder?: () => void | Promise<void>;\n onExpand?: () => void;\n onMinimize?: () => void;\n}\n\nexport function CartPanel({\n items,\n itemWarnings = [],\n onUpdateQuantity,\n onRemove,\n onCheckout,\n onSuggestAlternatives,\n onShowMoreLikeThis,\n onViewProduct,\n className = '',\n orderId,\n addresses = [],\n selectedAddressId,\n addressUpdateStatus,\n onAddressChange,\n selectedBillingAddressId,\n billingAddressUpdateStatus,\n onBillingAddressChange,\n shipToAddress,\n billingAddress,\n checkoutTotals,\n isLoading,\n poMetadataSet = false,\n isDragging,\n onNewOrder,\n onExpand,\n onMinimize\n}: CartPanelProps) {\n const [copied, setCopied] = useState(false);\n const copyTimeoutRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n const handleCopyOrderId = useCallback(() => {\n if (!orderId) return;\n navigator.clipboard.writeText(orderId).then(() => {\n setCopied(true);\n clearTimeout(copyTimeoutRef.current);\n copyTimeoutRef.current = setTimeout(() => setCopied(false), 2000);\n });\n }, [orderId]);\n\n const subtotal = items\n .filter((item) => item.status !== 'unavailable')\n .reduce((sum, item) => sum + (item.price ?? 0) * item.quantity, 0);\n\n const availableItems = items.filter((item) => item.status !== 'unavailable');\n const totalQuantity = availableItems.reduce(\n (sum, item) => sum + item.quantity,\n 0\n );\n\n // Get currency code from first item\n const currencyCode = items.find(\n (item) => item.catalogPriceCurrencyCode\n )?.catalogPriceCurrencyCode;\n\n // Get display values\n const displayTax = checkoutTotals?.tax;\n const displayShipping = checkoutTotals?.shipping;\n const displayTotal =\n checkoutTotals?.grandTotal ??\n (displayTax !== null\n ? subtotal + (displayTax ?? 0) + (displayShipping ?? 0)\n : null);\n\n if (items.length === 0 && itemWarnings.length === 0 && !poMetadataSet) {\n return (\n <EmptyCartifact\n className={className}\n isDragging={isDragging}\n onNewOrder={onNewOrder}\n onExpand={onExpand}\n onMinimize={onMinimize}\n />\n );\n }\n\n return (\n <div\n className={`bg-surface-secondary rounded-lg flex flex-col h-full min-h-0 border border-solid border-border-strong ${className}`}\n style={{\n boxShadow:\n '0 2px 8px -2px rgba(0, 0, 0, 0.04), 0 1px 3px -1px rgba(0, 0, 0, 0.03)'\n }}\n >\n {/* Header */}\n <div className=\"px-4 py-3 shrink-0\">\n <div className=\"flex items-center justify-between mb-2\">\n <h2 className=\"text-lg font-normal text-text m-0\">Cart</h2>\n <div className=\"flex items-center gap-2\">\n {onNewOrder && <CartifactNewOrder onNewOrder={onNewOrder} />}\n {onExpand && (\n <PanelActionButton onClick={onExpand} aria-label=\"Expand\">\n <MaximizeIcon size={14} />\n Expand\n </PanelActionButton>\n )}\n {onMinimize && (\n <PanelActionButton onClick={onMinimize} aria-label=\"Minimize\">\n <MinimizeIcon size={14} />\n Minimize\n </PanelActionButton>\n )}\n </div>\n </div>\n\n {/* Order ID and Item Count */}\n {orderId && (\n <div className=\"flex gap-5 mb-2\">\n <div className=\"flex flex-col gap-0\">\n <span className=\"text-2xs text-text-tertiary uppercase tracking-[0.05em]\">\n PO Number\n </span>\n <button\n type=\"button\"\n onClick={handleCopyOrderId}\n className=\"flex items-center gap-1 text-sm font-semibold text-text bg-transparent border-none cursor-pointer p-0 hover:opacity-70 transition-opacity\"\n title={copied ? 'Copied!' : 'Copy PO Number'}\n >\n {orderId}\n <span className=\"text-text-tertiary\">\n {copied ? (\n <CheckIcon size={12} title=\"Copied\" />\n ) : (\n <CopyIcon size={12} />\n )}\n </span>\n </button>\n </div>\n <div className=\"flex flex-col gap-0\">\n <span className=\"text-2xs text-text-tertiary uppercase tracking-[0.05em]\">\n Items\n </span>\n <span className=\"text-sm font-semibold text-text\">\n {items.length}\n </span>\n </div>\n </div>\n )}\n\n {/* Address Section */}\n <CartifactAddress\n addresses={addresses}\n selectedAddressId={selectedAddressId}\n addressUpdateStatus={addressUpdateStatus}\n onAddressChange={onAddressChange}\n selectedBillingAddressId={selectedBillingAddressId}\n billingAddressUpdateStatus={billingAddressUpdateStatus}\n onBillingAddressChange={onBillingAddressChange}\n shipToAddress={shipToAddress}\n billingAddress={billingAddress}\n />\n </div>\n\n {/* Divider */}\n <div className=\"h-px shrink-0 bg-border\" />\n\n {/* Items Section */}\n <div className=\"flex-1 min-h-0 overflow-y-auto flex flex-col\">\n {/* Items List */}\n <div className=\"flex-1 min-h-0 overflow-y-auto p-2 bg-surface\">\n {/* Empty state when metadata exists but no items */}\n {items.length === 0 && itemWarnings.length === 0 && (\n <div className=\"flex flex-col items-center justify-center h-full text-center\">\n <div className=\"w-12 h-12 mx-auto mb-3 rounded-full bg-surface-tertiary flex items-center justify-center text-text-quaternary\">\n <CartIcon />\n </div>\n <p className=\"text-sm text-text-quaternary m-0\">\n No items in cart yet\n </p>\n </div>\n )}\n\n {/* Pending Items */}\n {itemWarnings.length > 0 && (\n <>\n {itemWarnings.map((warning) => (\n <LineItemWarning\n key={`${itemWarningToString(warning)}-${warning.status}`}\n item={warning}\n onSuggestAlternatives={(identifier) =>\n onSuggestAlternatives(identifier)\n }\n />\n ))}\n {items.length > 0 && (\n <div className=\"border-b border-border mb-2\" />\n )}\n </>\n )}\n\n {items.map((item) => (\n <CartifactLineItem\n key={item.id}\n item={item}\n onUpdateQuantity={onUpdateQuantity}\n onRemove={onRemove}\n onShowMoreLikeThis={onShowMoreLikeThis}\n onViewProduct={onViewProduct}\n />\n ))}\n </div>\n </div>\n\n {/* Divider */}\n <div className=\"h-px shrink-0 bg-border\" />\n\n {/* Footer */}\n <CartifactFooter\n subtotal={subtotal}\n tax={displayTax}\n shipping={displayShipping}\n total={displayTotal}\n currencyCode={currencyCode}\n totalQuantity={totalQuantity}\n availableItemCount={availableItems.length}\n onCheckout={onCheckout}\n isLoading={isLoading}\n allowCheckout={!!selectedAddressId}\n />\n </div>\n );\n}\n","export interface ChatErrorProps {\n error: Error | null;\n onRetry?: () => void;\n}\n\nconst networkErrorPatterns = [\n 'failed to fetch',\n 'networkerror',\n 'network request failed',\n 'internet connection appears to be offline',\n 'the network connection was lost',\n 'net::err_internet_disconnected',\n 'net::err_network_changed'\n];\n\nexport function isOfflineError(error: Error): boolean {\n if (typeof navigator !== 'undefined' && !navigator.onLine) {\n return true;\n }\n\n const message = error.message.toLowerCase();\n return networkErrorPatterns.some((pattern) => message.includes(pattern));\n}\n\nexport function ChatError({ error, onRetry }: ChatErrorProps) {\n if (!error) {\n return null;\n }\n\n const offline = isOfflineError(error);\n\n return (\n <div className=\"mx-4 my-3 px-4 py-3 bg-error-bg border border-error/30 rounded-lg\">\n <p className=\"text-sm text-error-text\">\n {offline\n ? \"You're offline. Please check your internet connection and try again.\"\n : 'Something went wrong. Please try again.'}\n </p>\n {onRetry && (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"mt-2 text-sm font-medium text-error-text underline\"\n >\n Retry\n </button>\n )}\n </div>\n );\n}\n","export const SendIcon = () => (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <title>Send</title>\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" />\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\n </svg>\n);\n","import type { ChangeEvent, FormEvent, KeyboardEvent } from 'react';\nimport { SendIcon } from '../../icons/send-icon.js';\n\nexport interface ChatInputProps {\n input: string;\n onInputChange: (e: ChangeEvent<HTMLTextAreaElement>) => void;\n onSubmit: (e: FormEvent<HTMLFormElement>) => void;\n isLoading: boolean;\n}\n\nexport function ChatInput({\n input,\n onInputChange,\n onSubmit,\n isLoading\n}: ChatInputProps) {\n const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n const form = e.currentTarget.form;\n if (form) {\n form.requestSubmit();\n }\n }\n };\n\n return (\n <div className=\"px-4 pb-4 pt-2 shrink-0\">\n <form\n onSubmit={onSubmit}\n className=\"flex items-center gap-1 rounded-xl border border-border bg-surface shadow-sm focus-within:border-border-focus focus-within:shadow-[0_0_0_3px_rgba(0,0,0,0.08)] transition-shadow\"\n >\n <textarea\n placeholder=\"Describe what you need...\"\n className=\"flex-1 resize-none border-none rounded-xl px-4 py-3 text-sm font-inherit bg-transparent min-h-[44px] max-h-[120px] leading-normal focus:outline-none placeholder:text-text-quaternary disabled:cursor-not-allowed\"\n rows={1}\n value={input}\n onChange={onInputChange}\n onKeyDown={handleKeyDown}\n disabled={isLoading}\n />\n <button\n type=\"submit\"\n className=\"w-10 h-10 mr-1.5 border-none rounded-lg bg-surface-invert text-text-invert cursor-pointer flex items-center justify-center transition-colors shrink-0 hover:bg-surface-invert-hover disabled:bg-surface-disabled disabled:cursor-not-allowed\"\n disabled={!input.trim() || isLoading}\n aria-label=\"Send message\"\n >\n <SendIcon />\n </button>\n </form>\n </div>\n );\n}\n","export const SHOW_PRODUCTS_TOOL_NAME = 'showProducts';\nexport const SEARCH_PRODUCTS_TOOL_NAME = 'searchProducts';\nexport const SEARCH_PRODUCTS_BY_SKU_TOOL_NAME = 'searchProductsBySku';\nexport const ADD_TO_CART_TOOL_NAME = 'addToCart';\nexport const UPDATE_CART_TOOL_NAME = 'updateCart';\nexport const REMOVE_FROM_CART_TOOL_NAME = 'removeFromCart';\nexport const CLEAR_CART_TOOL_NAME = 'clearCart';\nexport const GET_CART_TOOL_NAME = 'getCart';\nexport const GET_PURCHASE_ORDER_DATA_TOOL_NAME = 'getPurchaseOrderData';\nexport const SET_PO_METADATA_TOOL_NAME = 'setPoMetadata';\nexport const SET_ITEM_WARNINGS_TOOL_NAME = 'setItemWarnings';\nexport const REMOVE_ITEM_WARNINGS_TOOL_NAME = 'removeItemWarnings';\nexport const ADD_PROCESSING_FAILURES_TOOL_NAME = 'addProcessingFailures';\n","import { SHOW_PRODUCTS_TOOL_NAME } from '../components/tools/tool-names.js';\nimport type { RenderablePart, ToolPart } from '../types.js';\n\nexport interface ToolCallGroup {\n type: 'tool-group';\n tools: ToolPart[];\n}\n\nexport type GroupedPart = RenderablePart | ToolCallGroup;\n\nconst NON_COLLAPSIBLE_TOOLS = new Set([SHOW_PRODUCTS_TOOL_NAME]);\n\nfunction isCollapsibleTool(part: RenderablePart): part is ToolPart {\n return part.type === 'tool' && !NON_COLLAPSIBLE_TOOLS.has(part.toolName);\n}\n\nexport function groupRenderableParts(parts: RenderablePart[]): GroupedPart[] {\n const result: GroupedPart[] = [];\n let accumulator: ToolPart[] = [];\n\n function flush() {\n if (accumulator.length >= 2) {\n result.push({ type: 'tool-group', tools: accumulator });\n } else if (accumulator.length === 1) {\n result.push(accumulator[0]!);\n }\n accumulator = [];\n }\n\n for (const part of parts) {\n if (isCollapsibleTool(part)) {\n accumulator.push(part);\n } else {\n flush();\n result.push(part);\n }\n }\n\n flush();\n return result;\n}\n","export const FileIcon = () => (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <title>Attachment</title>\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <polyline points=\"14 2 14 8 20 8\" />\n </svg>\n);\n","export const ExpandChevronIcon = () => (\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <title>Expand</title>\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n);\n","import {\n type PurchaseOrderStore,\n usePurchaseOrderStore\n} from '../../stores/purchase-order-store.js';\n\nexport interface GenericToolMessageProps {\n toolCallId: string;\n loadingMessage?: string;\n failedMessage?: string;\n successMessage: string;\n toolOutput?: unknown;\n}\n\nexport function GenericToolMessage({\n toolCallId,\n loadingMessage,\n failedMessage,\n successMessage,\n toolOutput\n}: GenericToolMessageProps) {\n const hasError = usePurchaseOrderStore(\n (state: PurchaseOrderStore) => toolCallId in state.chat.toolCallErrors\n );\n const hasFailed = hasError && failedMessage;\n const isLoading = loadingMessage && toolOutput === undefined && !hasError;\n\n let message: string;\n let variant: 'default' | 'error' = 'default';\n\n if (hasFailed) {\n message = failedMessage;\n variant = 'error';\n } else if (isLoading) {\n message = loadingMessage;\n } else {\n message = successMessage;\n }\n\n return (\n <div\n className={`text-xs italic ${variant === 'error' ? 'text-red-500' : 'text-text-secondary'}`}\n >\n {message}\n </div>\n );\n}\n","export function parseToolOutput(output: unknown): unknown {\n if (!output) return undefined;\n try {\n return typeof output === 'string' ? JSON.parse(output) : output;\n } catch {\n return undefined;\n }\n}\n","import { GenericToolMessage } from './generic-tool-message.js';\nimport { parseToolOutput } from './parse-tool-output.js';\n\nexport interface SearchProductsBySkuToolProps {\n toolCallId: string;\n toolInput: unknown;\n toolOutput: unknown;\n toolState: string;\n}\n\nexport function SearchProductsBySkuTool({\n toolCallId,\n toolInput,\n toolOutput,\n toolState\n}: SearchProductsBySkuToolProps) {\n const sku = (toolInput as { sku?: string } | undefined)?.sku ?? '';\n const isComplete = toolState === 'output-available';\n\n if (!isComplete) {\n return (\n <GenericToolMessage\n toolCallId={toolCallId}\n loadingMessage={`Searching for SKU '${sku}'...`}\n successMessage=\"\"\n />\n );\n }\n\n const parsed = parseToolOutput(toolOutput);\n const count =\n (parsed as { data?: { searchProductsBySku?: { total?: number } } })?.data\n ?.searchProductsBySku?.total ?? 0;\n\n return (\n <GenericToolMessage\n toolCallId={toolCallId}\n successMessage={`Found ${count} product${count !== 1 ? 's' : ''} with SKU '${sku}'`}\n toolOutput={toolOutput}\n />\n );\n}\n","import { GenericToolMessage } from './generic-tool-message.js';\nimport { parseToolOutput } from './parse-tool-output.js';\n\nexport interface SearchProductsToolProps {\n toolCallId: string;\n toolInput: unknown;\n toolOutput: unknown;\n toolState: string;\n}\n\nexport function SearchProductsTool({\n toolCallId,\n toolInput,\n toolOutput,\n toolState\n}: SearchProductsToolProps) {\n const terms = (toolInput as { terms?: string } | undefined)?.terms ?? '';\n const isComplete = toolState === 'output-available';\n\n if (!isComplete) {\n return (\n <GenericToolMessage\n toolCallId={toolCallId}\n loadingMessage={`Searching for '${terms}'...`}\n successMessage=\"\"\n />\n );\n }\n\n const parsed = parseToolOutput(toolOutput);\n const count =\n (parsed as { data?: { searchProducts?: { total?: number } } })?.data\n ?.searchProducts?.total ?? 0;\n\n return (\n <GenericToolMessage\n toolCallId={toolCallId}\n successMessage={`Found ${count} product${count !== 1 ? 's' : ''} for '${terms}'`}\n toolOutput={toolOutput}\n />\n );\n}\n","'use client';\n\nimport { createContext, type ReactNode, useContext } from 'react';\nimport type { BigCommerceClient } from '../lib/bigcommerce/storefront/client.js';\nimport type { MockBigCommerceClient } from '../lib/bigcommerce/storefront/mock-client.js';\n\ntype BigCommerceClientType = BigCommerceClient | MockBigCommerceClient;\n\nconst BigCommerceClientContext = createContext<BigCommerceClientType | null>(\n null\n);\n\nexport interface BigCommerceClientProviderProps {\n client: BigCommerceClientType | null;\n children: ReactNode;\n}\n\nexport function BigCommerceClientProvider({\n client,\n children\n}: BigCommerceClientProviderProps) {\n return (\n <BigCommerceClientContext.Provider value={client}>\n {children}\n </BigCommerceClientContext.Provider>\n );\n}\n\nexport function useBigCommerceClient(): BigCommerceClientType | null {\n return useContext(BigCommerceClientContext);\n}\n","import { useQuery } from '@tanstack/react-query';\nimport type { BigCommerceClient } from '../lib/bigcommerce/index.js';\nimport type { ProductVariantDetails } from '../lib/bigcommerce/storefront/types.js';\n\n/**\n * Fetch product variant details for multiple products\n * Uses React Query for caching and deduplication\n */\nexport function useProductVariants(\n client: BigCommerceClient,\n productEntityIds: number[]\n) {\n return useQuery({\n queryKey: [\n 'productVariants',\n productEntityIds\n .slice()\n .sort((a, b) => a - b)\n .join(',')\n ],\n queryFn: () => client.getProductVariantDetails(productEntityIds),\n enabled: productEntityIds.length > 0,\n staleTime: 5 * 60 * 1000 // 5 minutes\n });\n}\n\n// Helper type for variant selections: Map of optionEntityId -> selected valueEntityId\nexport type VariantSelections = Map<number, number>;\n\n/**\n * Extract optionId -> valueId mapping from a variant's options\n */\nexport function getVariantOptionValues(\n variant: ProductVariantDetails['variants'][number]\n): Map<number, number> {\n const map = new Map<number, number>();\n for (const option of variant.options) {\n const selectedValue = option.values[0];\n if (selectedValue) {\n map.set(option.entityId, selectedValue.entityId);\n }\n }\n return map;\n}\n\n/**\n * Find the variant that matches the given selections\n */\nexport function findMatchingVariant(\n variants: ProductVariantDetails['variants'],\n selections: VariantSelections\n): ProductVariantDetails['variants'][number] | null {\n return (\n variants.find((variant) => {\n const variantValues = getVariantOptionValues(variant);\n return Array.from(selections.entries()).every(\n ([optionId, valueId]) => variantValues.get(optionId) === valueId\n );\n }) ?? null\n );\n}\n\n/**\n * Get the initial variant selection based on default values or first variant\n */\nexport function getInitialSelections(\n details: ProductVariantDetails\n): VariantSelections {\n const selections: VariantSelections = new Map();\n\n // Try to use default values from product options\n for (const option of details.productOptions) {\n const defaultValue = option.values.find((v) => v.isDefault);\n if (defaultValue) {\n selections.set(option.entityId, defaultValue.entityId);\n } else if (option.values[0]) {\n // Fall back to first value\n selections.set(option.entityId, option.values[0].entityId);\n }\n }\n\n // Verify the selection maps to a valid variant, otherwise use first variant\n const matchingVariant = findMatchingVariant(details.variants, selections);\n if (!matchingVariant && details.variants[0]) {\n // Use first variant's option values\n const firstVariant = details.variants[0];\n selections.clear();\n for (const option of firstVariant.options) {\n const value = option.values[0];\n if (value) {\n selections.set(option.entityId, value.entityId);\n }\n }\n }\n\n return selections;\n}\n\n/**\n * Get the initial variant entityId for a product\n */\nexport function getInitialVariantEntityId(\n details: ProductVariantDetails\n): number | null {\n const selections = getInitialSelections(details);\n const variant = findMatchingVariant(details.variants, selections);\n return variant?.entityId ?? null;\n}\n","export const PlaceholderImage = () => (\n <div className=\"w-full h-full bg-surface-tertiary flex items-center justify-center text-text-quaternary\">\n <svg\n width=\"40\"\n height=\"40\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n >\n <title>Product</title>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n <circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\" />\n <polyline points=\"21 15 16 10 5 21\" />\n </svg>\n </div>\n);\n","import {\n findMatchingVariant,\n type VariantSelections\n} from '../hooks/use-product-variants.js';\nimport type { ProductVariantDetails } from '../lib/bigcommerce/storefront/types.js';\n\nexport interface VariantPickerProps {\n variantDetails: ProductVariantDetails;\n selections: VariantSelections;\n onSelectionChange: (optionEntityId: number, valueEntityId: number) => void;\n}\n\nexport function VariantPicker({\n variantDetails,\n selections,\n onSelectionChange\n}: VariantPickerProps) {\n const matchingVariant = findMatchingVariant(\n variantDetails.variants,\n selections\n );\n const hasInvalidCombination = !matchingVariant;\n\n return (\n <div className=\"flex flex-col gap-2\">\n {variantDetails.productOptions.map((option) => (\n <div key={option.entityId} className=\"flex flex-col gap-1\">\n <label\n htmlFor={`option-${option.entityId}`}\n className=\"text-xs text-text-tertiary\"\n >\n {option.displayName}\n </label>\n <select\n id={`option-${option.entityId}`}\n value={selections.get(option.entityId) ?? ''}\n onChange={(e) =>\n onSelectionChange(option.entityId, Number(e.target.value))\n }\n className=\"w-full px-2 py-1 text-xs border border-border rounded bg-surface text-text cursor-pointer focus:outline-none focus:ring-1 focus:ring-border-focus focus:border-border-focus\"\n >\n {option.values.map((value) => (\n <option key={value.entityId} value={value.entityId}>\n {value.label}\n </option>\n ))}\n </select>\n </div>\n ))}\n {hasInvalidCombination && (\n <p className=\"text-xs text-error m-0\" role=\"alert\" aria-live=\"polite\">\n This combination is not available\n </p>\n )}\n </div>\n );\n}\n","import { useCallback, useState } from 'react';\nimport {\n findMatchingVariant,\n type VariantSelections\n} from '../hooks/use-product-variants.js';\nimport type { ProductVariantDetails } from '../lib/bigcommerce/storefront/types.js';\nimport { formatCurrency } from '../lib/formatting.js';\nimport type { CartItem, Product } from '../types.js';\nimport { PlaceholderImage } from './icons/placeholder-image-icon.js';\nimport { QuantitySelector } from './quantity-selector.js';\nimport { VariantPicker } from './variant-picker.js';\n\nexport interface ProductCardProps {\n product: Product;\n onAddToCart?: (\n product: Product,\n quantity: number,\n selectedVariantEntityId?: number\n ) => Promise<boolean> | boolean | undefined;\n cart?: CartItem[];\n className?: string;\n layout?: 'vertical' | 'horizontal';\n onViewProduct?: (product: Product) => void;\n // Variant support\n variantDetails?: ProductVariantDetails;\n selections?: VariantSelections;\n onSelectionChange?: (optionEntityId: number, valueEntityId: number) => void;\n}\n\nconst LOW_STOCK_QUANTITY = 10;\n\nfunction addToCartButtonClass(\n isAdding: boolean,\n showAdded: boolean,\n isDisabled: boolean\n): string {\n if (isAdding) return 'bg-surface-tertiary text-text cursor-not-allowed';\n if (showAdded) return 'bg-success/20 text-success-text cursor-not-allowed';\n if (isDisabled)\n return 'bg-surface-disabled text-text-quaternary cursor-not-allowed';\n return 'bg-surface-invert text-text-invert hover:bg-surface-invert-hover cursor-pointer';\n}\n\nexport function ProductCard({\n product,\n onAddToCart,\n cart = [],\n className = '',\n layout = 'vertical',\n onViewProduct,\n variantDetails,\n selections,\n onSelectionChange\n}: ProductCardProps) {\n const [quantity, setQuantity] = useState(1);\n const [isAdding, setIsAdding] = useState(false);\n const [showAdded, setShowAdded] = useState(false);\n\n const isHorizontal = layout === 'horizontal';\n\n // Find the selected variant if we have variant details and selections\n const selectedVariant =\n variantDetails && selections\n ? findMatchingVariant(variantDetails.variants, selections)\n : null;\n\n // Compute cart status using the selected variant\n const selectedVariantEntityId =\n selectedVariant?.entityId ?? product.variantEntityId;\n const cartItem = cart.find(\n (item) =>\n item.productEntityId === product.productEntityId &&\n item.variantEntityId === selectedVariantEntityId\n );\n const inCart = !!cartItem;\n const cartQuantity = cartItem?.quantity ?? 0;\n\n // Use variant data when available, fall back to product data\n const displaySku = selectedVariant?.sku ?? product.sku;\n const displayPrice = selectedVariant?.prices?.price?.value ?? product.price;\n const displayAvailableQuantity =\n selectedVariant?.inventory?.aggregated?.availableToSell ??\n product.availableQuantity;\n\n // Only show low stock warning if we have a positive quantity less than threshold\n // This prevents showing \"Only 0 left\" when inventory tracking is disabled (quantity=0)\n const lowStock =\n displayAvailableQuantity !== undefined &&\n displayAvailableQuantity > 0 &&\n displayAvailableQuantity < LOW_STOCK_QUANTITY;\n\n // Check if product is out of stock:\n // 1. If we have variant details loaded, check variant stock (isPurchasable, isInStock, availableToSell)\n // 2. If no variant details, fall back to product-level stock (isInStock, availableQuantity)\n // 3. If isInStock is explicitly set, use it (handles inventory tracking disabled)\n // 4. Otherwise check if quantity is 0\n const displayIsInStock =\n selectedVariant?.inventory?.isInStock ?? product.isInStock;\n const isOutOfStock =\n selectedVariant !== null\n ? // Have variant details: check variant stock\n !selectedVariant.isPurchasable ||\n displayIsInStock === false ||\n (displayIsInStock === undefined &&\n (selectedVariant.inventory?.aggregated?.availableToSell ?? 0) === 0)\n : // No variant details: check product-level stock\n displayIsInStock === false ||\n (displayIsInStock === undefined && product.availableQuantity === 0);\n\n const hasInvalidCombination =\n variantDetails && selections && !selectedVariant;\n\n const handleAddToCart = useCallback(async () => {\n if (!onAddToCart) return;\n if (hasInvalidCombination || isOutOfStock) return;\n if (quantity < 1) return; // Never allow adding with quantity < 1\n setIsAdding(true);\n try {\n const result = await onAddToCart(\n product,\n quantity,\n selectedVariant?.entityId\n );\n // Only show \"Added\" if the callback returned true (or didn't return anything for backwards compatibility)\n if (result !== false) {\n setShowAdded(true);\n setTimeout(() => {\n setShowAdded(false);\n setQuantity(1);\n }, 1500);\n }\n } finally {\n setIsAdding(false);\n }\n }, [\n onAddToCart,\n product,\n quantity,\n selectedVariant,\n hasInvalidCombination,\n isOutOfStock\n ]);\n\n // Use variant image if available, fall back to product image\n const variantImageUrl = selectedVariant?.defaultImage?.urlTemplate?.replace(\n '{:size}',\n '200w'\n );\n const productImageUrl =\n product.imageUrl ??\n product.defaultImage?.urlTemplate?.replace('{:size}', '200w');\n const imageUrl = variantImageUrl ?? productImageUrl;\n\n // Low stock warning - rendered in different positions based on variant\n const lowStockWarning = lowStock && !isOutOfStock && (\n <p className={`text-xs text-warning m-0 ${isHorizontal ? 'mt-1' : 'mb-2'}`}>\n Only {displayAvailableQuantity} left\n </p>\n );\n\n return (\n <div\n className={`bg-surface rounded-xl border overflow-hidden transition-[border-color,box-shadow] duration-150 flex ${\n isHorizontal\n ? 'flex-row border-border hover:shadow-md'\n : `w-[180px] max-w-full shrink-0 flex-col border-border hover:border-border-strong hover:shadow-[0_2px_8px_rgba(0,0,0,0.06)]${isOutOfStock ? ' opacity-70' : ''}`\n } ${className}`}\n >\n {/* Image section */}\n <div\n className={\n isHorizontal\n ? 'shrink-0 w-[120px] h-[120px]'\n : 'relative shrink-0 aspect-[4/3] overflow-hidden bg-surface-tertiary'\n }\n >\n {imageUrl ? (\n <img\n src={imageUrl}\n alt={product.name}\n className=\"w-full h-full object-cover\"\n />\n ) : (\n <PlaceholderImage />\n )}\n {!isHorizontal && isOutOfStock && (\n <div className=\"absolute top-2 right-2 bg-error text-text-invert text-xs font-semibold px-2 py-0.5 rounded\">\n Out of stock\n </div>\n )}\n </div>\n\n {/* Content section */}\n <div\n className={\n isHorizontal\n ? 'flex-1 p-3 flex flex-col justify-between min-w-0'\n : 'flex-1 flex flex-col'\n }\n >\n {/* Info: name, sku, price, out of stock */}\n <div className={isHorizontal ? '' : 'grow p-3 pb-0'}>\n {onViewProduct ? (\n <button\n type=\"button\"\n onClick={() => onViewProduct(product)}\n className=\"text-sm font-medium text-text m-0 truncate bg-transparent border-none cursor-pointer p-0 text-left hover:underline w-full\"\n title={product.name}\n >\n {product.name}\n </button>\n ) : (\n <h4\n className=\"text-sm font-medium text-text m-0 truncate\"\n title={product.name}\n >\n {product.name}\n </h4>\n )}\n <p className=\"text-xs text-text-quaternary m-0 mt-0.5\">\n {displaySku}\n </p>\n {displayPrice !== undefined && (\n <p className=\"text-sm font-semibold text-text m-0 mt-1\">\n {formatCurrency(displayPrice)}\n </p>\n )}\n {isOutOfStock && (\n <p className=\"text-xs text-error m-0 mt-1 font-medium\">\n Out of Stock\n </p>\n )}\n {!isHorizontal &&\n !isOutOfStock &&\n displayAvailableQuantity !== undefined &&\n displayAvailableQuantity > 0 && (\n <p className=\"text-2xs text-success font-medium m-0 mt-0.5\">\n {displayAvailableQuantity} in stock\n </p>\n )}\n {/* Low stock in info section for horizontal */}\n {isHorizontal && lowStockWarning}\n </div>\n\n {/* Variant picker */}\n {variantDetails && selections && onSelectionChange && (\n <div className={isHorizontal ? 'mt-2' : 'shrink-0 px-3 pt-2'}>\n <VariantPicker\n variantDetails={variantDetails}\n selections={selections}\n onSelectionChange={onSelectionChange}\n />\n </div>\n )}\n\n {/* Actions section */}\n <div\n className={\n isHorizontal ? 'flex items-center gap-2 mt-2' : 'shrink-0 p-3 pt-2'\n }\n >\n {/* Low stock in actions section for vertical */}\n {!isHorizontal && lowStockWarning}\n\n {inCart && (\n <p className=\"text-xs text-text-tertiary m-0 mb-1\">\n In cart (×{cartQuantity})\n </p>\n )}\n <div\n className={\n isHorizontal\n ? 'flex items-center gap-2 flex-wrap'\n : 'flex flex-col gap-2'\n }\n >\n <QuantitySelector\n value={quantity}\n onChange={setQuantity}\n max={\n displayAvailableQuantity && displayAvailableQuantity > 0\n ? displayAvailableQuantity\n : undefined\n }\n className={isHorizontal ? '' : 'justify-center'}\n testId={`quantity-input-${displaySku}`}\n />\n <button\n type=\"button\"\n onClick={handleAddToCart}\n disabled={\n isAdding || showAdded || !!hasInvalidCombination || isOutOfStock\n }\n className={`py-1.5 px-3 text-xs font-medium rounded border-none ${\n isHorizontal ? '' : 'w-full'\n } ${addToCartButtonClass(isAdding, showAdded, !!hasInvalidCombination || isOutOfStock)}`}\n >\n {isAdding ? 'Adding...' : showAdded ? '✓ Added' : 'Add to cart'}\n </button>\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport { useBigCommerceClient } from '../contexts/bigcommerce-client-context.js';\nimport {\n getInitialSelections,\n getVariantOptionValues,\n useProductVariants,\n type VariantSelections\n} from '../hooks/use-product-variants.js';\nimport type { BigCommerceClient } from '../lib/bigcommerce/index.js';\nimport type { CartItem, Product } from '../types.js';\nimport { ProductCard } from './product-card.js';\n\nexport interface ProductGridProps {\n products: Product[];\n onAddToCart?: (\n product: Product,\n quantity: number,\n selectedVariantEntityId?: number\n ) => Promise<boolean> | boolean | undefined;\n onViewProduct?: (product: Product) => void;\n cart: CartItem[];\n isLoading?: boolean;\n loadingText?: string;\n className?: string;\n}\n\nexport function ProductGrid({\n products,\n onAddToCart,\n onViewProduct,\n cart,\n isLoading = false,\n loadingText = 'Searching for products...',\n className = ''\n}: ProductGridProps) {\n const client = useBigCommerceClient();\n\n // Get product entity IDs for fetching variant details\n const productEntityIds = useMemo(\n () =>\n products\n .filter((p) => p.productEntityId !== undefined)\n .map((p) => p.productEntityId as number),\n [products]\n );\n\n // Fetch variant details for all products (if client available from context)\n const { data: variantDetailsArray } = useProductVariants(\n client as BigCommerceClient,\n client ? productEntityIds : []\n );\n\n // Create a map of productEntityId -> variantDetails\n const variantDetailsMap = useMemo(() => {\n const map = new Map<\n number,\n NonNullable<typeof variantDetailsArray>[number]\n >();\n if (variantDetailsArray) {\n for (const details of variantDetailsArray) {\n // Only include products with multiple variants (has variant options)\n if (details.productOptions.length > 0) {\n map.set(details.entityId, details);\n }\n }\n }\n return map;\n }, [variantDetailsArray]);\n\n // Track selections per product: Map<product.id, VariantSelections>\n const [selectionsMap, setSelectionsMap] = useState<\n Map<string, VariantSelections>\n >(new Map());\n\n // Initialize selections when variant details are loaded\n useEffect(() => {\n if (!variantDetailsArray) return;\n\n setSelectionsMap((prev) => {\n const next = new Map(prev);\n\n // Initialize selections for each product in the list\n for (const product of products) {\n if (product.productEntityId === undefined) continue;\n if (next.has(product.id)) continue; // Already initialized\n\n const details = variantDetailsArray.find(\n (d) => d.entityId === product.productEntityId\n );\n if (!details || details.productOptions.length === 0) continue;\n\n let selections: VariantSelections;\n if (product.variantEntityId) {\n // Find the specific variant and use its option values\n const requestedVariant = details.variants.find(\n (v) => v.entityId === product.variantEntityId\n );\n if (requestedVariant) {\n selections = getVariantOptionValues(requestedVariant);\n } else {\n selections = getInitialSelections(details);\n }\n } else {\n selections = getInitialSelections(details);\n }\n\n next.set(product.id, selections);\n }\n\n return next;\n });\n }, [variantDetailsArray, products]);\n\n // Handler for selection changes\n const handleSelectionChange = (\n productId: string,\n optionEntityId: number,\n valueEntityId: number\n ) => {\n setSelectionsMap((prev) => {\n const next = new Map(prev);\n const selections = new Map(next.get(productId) ?? new Map());\n selections.set(optionEntityId, valueEntityId);\n next.set(productId, selections);\n return next;\n });\n };\n\n if (isLoading) {\n return (\n <div className={`py-3 ${className}`}>\n <div className=\"flex items-center gap-2 text-sm text-text-tertiary\">\n <div className=\"w-4 h-4 border-2 border-border-focus border-t-transparent rounded-full animate-spin\" />\n <span>{loadingText}</span>\n </div>\n </div>\n );\n }\n\n const availableProducts = products.filter((product) => {\n // If isInStock is explicitly set, use it (handles inventory tracking disabled case)\n if (product.isInStock !== undefined) {\n return product.isInStock;\n }\n // Fallback to checking availableQuantity for older data or when isInStock is missing\n return product.availableQuantity !== 0;\n });\n\n if (availableProducts.length === 0) {\n return null;\n }\n\n // Single product: use horizontal layout\n const [singleProduct] = availableProducts;\n if (availableProducts.length === 1 && singleProduct) {\n const variantDetails =\n singleProduct.productEntityId !== undefined\n ? variantDetailsMap.get(singleProduct.productEntityId)\n : undefined;\n const selections = selectionsMap.get(singleProduct.id);\n\n return (\n <div className={`py-2 ${className}`}>\n <ProductCard\n layout=\"horizontal\"\n product={singleProduct}\n onAddToCart={onAddToCart}\n onViewProduct={onViewProduct}\n cart={cart}\n variantDetails={variantDetails}\n selections={selections}\n onSelectionChange={\n variantDetails\n ? (optionId, valueId) =>\n handleSelectionChange(singleProduct.id, optionId, valueId)\n : undefined\n }\n />\n </div>\n );\n }\n\n // Multiple products: use wrapping grid\n return (\n <div className={`flex flex-wrap gap-3 py-2 ${className}`}>\n {availableProducts.map((product) => {\n const variantDetails =\n product.productEntityId !== undefined\n ? variantDetailsMap.get(product.productEntityId)\n : undefined;\n const selections = selectionsMap.get(product.id);\n\n return (\n <ProductCard\n key={product.id}\n product={product}\n onAddToCart={onAddToCart}\n onViewProduct={onViewProduct}\n cart={cart}\n variantDetails={variantDetails}\n selections={selections}\n onSelectionChange={\n variantDetails\n ? (optionId, valueId) =>\n handleSelectionChange(product.id, optionId, valueId)\n : undefined\n }\n />\n );\n })}\n </div>\n );\n}\n","import { useEffect, useState } from 'react';\nimport { useBigCommerceClient } from '../../contexts/bigcommerce-client-context.js';\nimport type { CartItem, Product } from '../../types.js';\nimport { ProductGrid } from '../product-grid.js';\n\nexport interface ShowProductsInput {\n products: Array<{\n entityId: number;\n variantEntityId?: number;\n }>;\n}\n\nexport interface ShowProductsToolProps {\n toolInput?: ShowProductsInput;\n toolOutput: unknown;\n toolState: string;\n cart: CartItem[];\n onAddToCart?: (\n product: Product,\n quantity: number\n ) => Promise<boolean> | boolean | undefined;\n onViewProduct?: (product: Product) => void;\n}\n\nexport function ShowProductsTool({\n toolInput,\n toolState,\n cart,\n onAddToCart,\n onViewProduct\n}: ShowProductsToolProps) {\n const client = useBigCommerceClient();\n const [products, setProducts] = useState<Product[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const isToolLoading = toolState !== 'output-available';\n\n useEffect(() => {\n async function fetchProducts() {\n if (!client) {\n console.error('BigCommerce client not available');\n setError('Unable to load products');\n setIsLoading(false);\n return;\n }\n\n try {\n setError(null);\n if (!toolInput?.products?.length) {\n setProducts([]);\n setIsLoading(false);\n return;\n }\n\n // Extract unique product entity IDs\n const productEntityIds = [\n ...new Set(toolInput.products.map((p) => p.entityId))\n ];\n\n // Fetch product details\n const productsData =\n await client.getProductsForDisplay(productEntityIds);\n\n // Transform to Product[] format, matching specific variants if provided\n const transformedProducts: Product[] = [];\n\n for (const inputProduct of toolInput.products) {\n const productData = productsData.find(\n (p) => p.entityId === inputProduct.entityId\n );\n\n if (!productData) continue;\n\n // If a specific variant is requested, find it\n const variant = inputProduct.variantEntityId\n ? productData.variants.find(\n (v) => v.entityId === inputProduct.variantEntityId\n )\n : productData.variants[0];\n\n if (variant) {\n transformedProducts.push({\n id: `${productData.entityId}-${variant.entityId}`,\n sku: variant.sku,\n name: productData.name,\n path: productData.path,\n price: variant.prices?.price?.value,\n imageUrl:\n variant.defaultImage?.urlTemplate?.replace('{:size}', '200w') ??\n productData.defaultImage?.urlTemplate?.replace(\n '{:size}',\n '200w'\n ),\n availableQuantity:\n variant.inventory?.aggregated?.availableToSell ?? undefined,\n isInStock: variant.inventory?.isInStock ?? undefined,\n productEntityId: productData.entityId,\n variantEntityId: variant.entityId\n });\n }\n }\n\n setProducts(transformedProducts);\n } catch (err) {\n console.error('Failed to fetch products:', err);\n setError('Failed to load products');\n setProducts([]);\n } finally {\n setIsLoading(false);\n }\n }\n\n fetchProducts();\n }, [client, toolInput]);\n\n if (error) {\n return <div className=\"py-2 text-sm text-error-text\">{error}</div>;\n }\n\n return (\n <ProductGrid\n products={products}\n onAddToCart={onAddToCart}\n onViewProduct={onViewProduct}\n cart={cart}\n isLoading={isToolLoading || isLoading}\n loadingText=\"Loading suggested products...\"\n />\n );\n}\n","import type { CartItem, Product } from '../../types.js';\nimport { GenericToolMessage } from './generic-tool-message.js';\nimport { SearchProductsBySkuTool } from './search-products-by-sku-tool.js';\nimport { SearchProductsTool } from './search-products-tool.js';\nimport {\n type ShowProductsInput,\n ShowProductsTool\n} from './show-products-tool.js';\nimport {\n ADD_TO_CART_TOOL_NAME,\n CLEAR_CART_TOOL_NAME,\n GET_CART_TOOL_NAME,\n GET_PURCHASE_ORDER_DATA_TOOL_NAME,\n REMOVE_FROM_CART_TOOL_NAME,\n REMOVE_ITEM_WARNINGS_TOOL_NAME,\n SEARCH_PRODUCTS_BY_SKU_TOOL_NAME,\n SEARCH_PRODUCTS_TOOL_NAME,\n SET_ITEM_WARNINGS_TOOL_NAME,\n SET_PO_METADATA_TOOL_NAME,\n SHOW_PRODUCTS_TOOL_NAME,\n UPDATE_CART_TOOL_NAME\n} from './tool-names.js';\n\nexport interface ToolProps {\n toolCallId: string;\n toolName: string;\n toolInput?: unknown;\n toolOutput?: unknown;\n toolState?: string;\n cart: CartItem[];\n onAddToCart?: (\n product: Product,\n quantity: number,\n selectedVariantEntityId?: number\n ) => Promise<boolean> | boolean | undefined;\n onViewProduct?: (product: Product) => void;\n}\n\nexport function Tool({\n toolCallId,\n toolName,\n toolInput,\n toolOutput,\n toolState,\n cart,\n onAddToCart,\n onViewProduct\n}: ToolProps) {\n if (toolName === SHOW_PRODUCTS_TOOL_NAME) {\n return (\n <div className=\"mt-3\">\n <ShowProductsTool\n toolInput={toolInput as ShowProductsInput}\n toolOutput={toolOutput}\n toolState={toolState ?? ''}\n cart={cart}\n onAddToCart={onAddToCart}\n onViewProduct={onViewProduct}\n />\n </div>\n );\n }\n\n if (toolName === SEARCH_PRODUCTS_TOOL_NAME) {\n return (\n <SearchProductsTool\n toolCallId={toolCallId}\n toolInput={toolInput}\n toolOutput={toolOutput}\n toolState={toolState ?? ''}\n />\n );\n }\n\n if (toolName === SEARCH_PRODUCTS_BY_SKU_TOOL_NAME) {\n return (\n <SearchProductsBySkuTool\n toolCallId={toolCallId}\n toolInput={toolInput}\n toolOutput={toolOutput}\n toolState={toolState ?? ''}\n />\n );\n }\n\n if (toolName === ADD_TO_CART_TOOL_NAME) {\n return (\n <GenericToolMessage\n toolCallId={toolCallId}\n loadingMessage=\"Adding to cart...\"\n failedMessage=\"Failed to add to cart\"\n successMessage=\"Added to cart\"\n toolOutput={toolOutput}\n />\n );\n }\n\n if (toolName === UPDATE_CART_TOOL_NAME) {\n return (\n <GenericToolMessage\n toolCallId={toolCallId}\n loadingMessage=\"Updating cart...\"\n failedMessage=\"Failed to update cart\"\n successMessage=\"Updated cart\"\n toolOutput={toolOutput}\n />\n );\n }\n\n if (toolName === REMOVE_FROM_CART_TOOL_NAME) {\n return (\n <GenericToolMessage\n toolCallId={toolCallId}\n loadingMessage=\"Removing from cart...\"\n failedMessage=\"Failed to remove from cart\"\n successMessage=\"Removed from cart\"\n toolOutput={toolOutput}\n />\n );\n }\n\n if (toolName === CLEAR_CART_TOOL_NAME) {\n return (\n <GenericToolMessage\n toolCallId={toolCallId}\n loadingMessage=\"Clearing cart...\"\n failedMessage=\"Failed to clear cart\"\n successMessage=\"Cart cleared\"\n toolOutput={toolOutput}\n />\n );\n }\n\n if (toolName === GET_CART_TOOL_NAME) {\n return (\n <GenericToolMessage\n toolCallId={toolCallId}\n loadingMessage=\"Retrieving cart...\"\n successMessage=\"Retrieved cart\"\n toolOutput={toolOutput}\n />\n );\n }\n\n if (toolName === GET_PURCHASE_ORDER_DATA_TOOL_NAME) {\n return (\n <GenericToolMessage\n toolCallId={toolCallId}\n loadingMessage=\"Retrieving PO...\"\n successMessage=\"Retrieved PO\"\n toolOutput={toolOutput}\n />\n );\n }\n\n if (toolName === SET_PO_METADATA_TOOL_NAME) {\n return (\n <GenericToolMessage\n toolCallId={toolCallId}\n loadingMessage=\"Saving metadata...\"\n successMessage=\"Saved metadata\"\n toolOutput={toolOutput}\n />\n );\n }\n\n if (toolName === SET_ITEM_WARNINGS_TOOL_NAME) {\n return (\n <GenericToolMessage\n toolCallId={toolCallId}\n loadingMessage=\"Updating warnings...\"\n successMessage=\"Warnings updated\"\n toolOutput={toolOutput}\n />\n );\n }\n\n if (toolName === REMOVE_ITEM_WARNINGS_TOOL_NAME) {\n return (\n <GenericToolMessage\n toolCallId={toolCallId}\n loadingMessage=\"Removing warnings...\"\n successMessage=\"Warnings removed\"\n toolOutput={toolOutput}\n />\n );\n }\n\n return null;\n}\n","import { useState } from 'react';\nimport type { CartItem, Product, ToolPart } from '../../types.js';\nimport { ExpandChevronIcon } from '../icons/expand-chevron-icon.js';\nimport { Tool } from './tool.js';\n\ninterface CollapsibleToolCallsProps {\n tools: ToolPart[];\n messageId: string;\n cart: CartItem[];\n onAddToCart?: (\n product: Product,\n quantity: number,\n selectedVariantEntityId?: number\n ) => Promise<boolean> | boolean | undefined;\n onViewProduct?: (product: Product) => void;\n}\n\nexport function CollapsibleToolCalls({\n tools,\n messageId,\n cart,\n onAddToCart,\n onViewProduct\n}: CollapsibleToolCallsProps) {\n const [isExpanded, setIsExpanded] = useState(false);\n\n if (tools.length === 0) return null;\n\n return (\n <div>\n <button\n type=\"button\"\n aria-expanded={isExpanded}\n aria-controls={`collapsible-${messageId}`}\n onClick={() => setIsExpanded(!isExpanded)}\n className=\"flex items-center gap-1.5 text-xs text-text-secondary italic w-full group\"\n >\n <span\n className={`transition-transform duration-200 ${isExpanded ? 'rotate-90' : ''}`}\n aria-hidden=\"true\"\n >\n <ExpandChevronIcon />\n </span>\n <span className=\"flex-1 text-left\">\n {tools.length} tool call{tools.length !== 1 ? 's' : ''}\n </span>\n </button>\n <div\n id={`collapsible-${messageId}`}\n data-testid=\"collapsible-panel\"\n className={`collapsible-panel ${isExpanded ? 'collapsible-panel-open' : ''}`}\n >\n <div className=\"overflow-hidden\">\n <div className=\"pl-2.5 border-l border-gray-200 ml-[1px] my-2\">\n {tools.map((toolPart) => (\n <Tool\n key={toolPart.toolCallId}\n toolCallId={toolPart.toolCallId}\n toolName={toolPart.toolName}\n toolInput={toolPart.toolInput}\n toolOutput={toolPart.toolOutput}\n toolState={toolPart.toolState}\n cart={cart}\n onAddToCart={onAddToCart}\n onViewProduct={onViewProduct}\n />\n ))}\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import { z } from 'zod';\n\nexport const Thread = z.object({\n id: z.string()\n});\n\nexport type Thread = z.infer<typeof Thread>;\n","import { parseJsonEventStream, uiMessageChunkSchema } from 'ai';\nimport type { ToolCallResult } from './types.js';\n\nexport interface SSEStreamResult {\n textParts: string[];\n toolCalls: ToolCallResult[];\n serverHandledToolCallIds: Set<string>;\n finalMessage: string;\n finishReason: string | null;\n errorMessage: string | null;\n}\n\nexport interface SSEStreamCallbacks {\n onToolCall?: (toolCall: ToolCallResult) => void;\n}\n\nexport async function parseSSEStream(\n response: Response,\n callbacks?: SSEStreamCallbacks\n): Promise<SSEStreamResult> {\n if (!response.body) {\n throw new Error('No response body');\n }\n\n const toolCalls: ToolCallResult[] = [];\n const serverHandledToolCallIds = new Set<string>();\n const textParts: string[] = [];\n let finishReason: string | null = null;\n let errorMessage: string | null = null;\n\n // Use AI SDK for proper SSE parsing + schema validation\n const chunkStream = parseJsonEventStream({\n stream: response.body,\n schema: uiMessageChunkSchema\n });\n\n // Use getReader() instead of for-await-of for Safari compatibility.\n // Safari 26.4's new ReadableStream async iteration implementation has\n // issues with streams produced by chained pipeThrough() calls. The AI\n // SDK itself uses getReader() for all client-side stream consumption.\n const reader = chunkStream.getReader();\n try {\n while (true) {\n const { done, value: result } = await reader.read();\n if (done) break;\n\n if (!result.success) {\n console.warn('Invalid SSE chunk:', result.error);\n continue;\n }\n\n const chunk = result.value;\n\n switch (chunk.type) {\n case 'text-delta':\n textParts.push(chunk.delta);\n break;\n\n case 'tool-input-available': {\n const toolCall: ToolCallResult = {\n toolCallId: chunk.toolCallId,\n toolName: chunk.toolName,\n input: chunk.input\n };\n toolCalls.push(toolCall);\n callbacks?.onToolCall?.(toolCall);\n break;\n }\n\n case 'tool-output-available': {\n serverHandledToolCallIds.add(chunk.toolCallId);\n const toolCall = toolCalls.find(\n (tc) => tc.toolCallId === chunk.toolCallId\n );\n if (toolCall) {\n toolCall.output = chunk.output;\n }\n break;\n }\n\n case 'error':\n errorMessage = chunk.errorText;\n break;\n\n case 'finish':\n finishReason = chunk.finishReason ?? null;\n break;\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n return {\n textParts,\n toolCalls,\n serverHandledToolCallIds,\n finalMessage: textParts.join(''),\n finishReason,\n errorMessage\n };\n}\n","/**\n * Low-level TakeShape API primitives.\n *\n * These are pure fetch wrappers with no React, Zustand, or app-specific dependencies.\n * They can be shared across the production app, evals, and other contexts.\n */\n\nimport { Thread } from '../schema.js';\nimport { nativeFetch } from './native-fetch.js';\nimport { parseSSEStream } from './sse.js';\nimport type { AgentMessage, TakeShapeConfig } from './types.js';\n\n/**\n * Creates a new agent thread.\n *\n * @param takeshapeConfig - Config with origin, projectId, apiKey\n * @param agentName - The agent to create a thread for\n * @returns The thread ID\n */\nexport async function createAgentThread(\n takeshapeConfig: Pick<TakeShapeConfig, 'origin' | 'projectId' | 'apiKey'>,\n agentName: string\n): Promise<string> {\n const { origin, projectId, apiKey } = takeshapeConfig;\n\n const response = await nativeFetch(\n `${origin}/project/${projectId}/agents/threads`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`\n },\n body: JSON.stringify({ agentName })\n }\n );\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new Error(\n `Failed to create thread: ${response.status}${text ? ` - ${text}` : ''}`\n );\n }\n\n const data = await response.json();\n const parsed = Thread.parse(data);\n return parsed.id;\n}\n\n/**\n * Sends a message to the agent and returns the streaming response.\n *\n * @param takeshapeConfig - Config with sseOrigin, projectId, apiKey\n * @param agentName - The agent to send the message to\n * @param threadId - The thread ID to send the message on\n * @param messages - The messages to send\n * @returns The raw Response object for streaming\n */\nexport async function sendAgentMessage(\n takeshapeConfig: Pick<TakeShapeConfig, 'sseOrigin' | 'projectId' | 'apiKey'>,\n agentName: string,\n threadId: string,\n messages: AgentMessage[]\n): Promise<Response> {\n const { sseOrigin, projectId, apiKey } = takeshapeConfig;\n\n const response = await nativeFetch(\n `${sseOrigin}/project/${projectId}/agents/messages`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`\n },\n body: JSON.stringify({\n id: threadId,\n messages,\n metadata: {\n custom: {\n inputName: agentName\n }\n }\n })\n }\n );\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n // Try to extract errorText from SSE or JSON response\n let errorDetail = text;\n if (text) {\n try {\n const json = JSON.parse(text);\n if (json.errorText) errorDetail = json.errorText;\n } catch {\n // Check for SSE format: data: {\"type\":\"error\",\"errorText\":\"...\"}\n const match = text.match(/\"errorText\"\\s*:\\s*\"([^\"]+)\"/);\n if (match?.[1]) errorDetail = match[1];\n }\n }\n throw new Error(\n `Failed to send message: ${response.status}${errorDetail ? ` - ${errorDetail}` : ''}`\n );\n }\n\n return response;\n}\n\nexport interface DocumentAttachment {\n data: string; // Base64 encoded\n mediaType: string;\n filename?: string;\n}\n\nexport interface ParseDocumentResult {\n parsedContent: string;\n threadId: string;\n}\n\nexport interface FeedbackInput {\n messageId: string;\n name: string;\n email: string;\n text: string;\n}\n\n/**\n * Parse a document using the document parser agent.\n *\n * @param takeshapeConfig - Config with origin, sseOrigin, projectId, apiKey\n * @param attachment - The document to parse (base64 encoded)\n * @param agentName - The document parser agent name (default: 'documentParser')\n * @returns The parsed text content and thread ID\n */\nexport async function parseDocument(\n takeshapeConfig: TakeShapeConfig,\n attachment: DocumentAttachment,\n agentName = 'documentParser'\n): Promise<ParseDocumentResult> {\n // Create thread for document parser\n const threadId = await createAgentThread(takeshapeConfig, agentName);\n\n // Build the message with file attachment\n const messages: AgentMessage[] = [\n {\n role: 'user',\n parts: [\n { type: 'text', text: 'Please parse this document.' },\n {\n type: 'file',\n url: `data:${attachment.mediaType};base64,${attachment.data}`,\n mediaType: attachment.mediaType,\n filename: attachment.filename\n }\n ]\n }\n ];\n\n // Send message to document parser\n const response = await sendAgentMessage(\n takeshapeConfig,\n agentName,\n threadId,\n messages\n );\n\n // Parse the SSE response to extract text content\n const result = await parseSSEStream(response);\n\n const parsedContent = result.finalMessage;\n\n if (result.errorMessage) {\n throw new Error(`Document parser error: ${result.errorMessage}`);\n }\n\n return { parsedContent, threadId };\n}\n\nconst SEND_FEEDBACK_MUTATION = `\n mutation SendFeedback(\n $messageId: String!\n $name: String!\n $createdAt: Float!\n $text: String!\n $updatedBy: String\n ) {\n sendBigcommercePurchaseOrderAgentFeedback(\n messageId: $messageId\n name: $name\n createdAt: $createdAt\n text: $text\n updatedBy: $updatedBy\n )\n }\n`;\n\n/**\n * Sends feedback for a chat message.\n *\n * @param takeshapeConfig - Config with origin, projectId, apiKey\n * @param feedback - The feedback data to send\n * @returns True if feedback was sent successfully\n */\nexport async function sendFeedback(\n takeshapeConfig: Pick<TakeShapeConfig, 'origin' | 'projectId' | 'apiKey'>,\n feedback: FeedbackInput\n): Promise<boolean> {\n const { origin, projectId, apiKey } = takeshapeConfig;\n\n const response = await nativeFetch(`${origin}/project/${projectId}/graphql`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`\n },\n body: JSON.stringify({\n query: SEND_FEEDBACK_MUTATION,\n variables: {\n messageId: feedback.messageId,\n name: feedback.name,\n createdAt: Date.now(),\n text: feedback.text,\n updatedBy: feedback.email || undefined\n }\n })\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new Error(\n `Failed to send feedback: ${response.status}${text ? ` - ${text}` : ''}`\n );\n }\n\n const result = await response.json();\n\n if (result.errors?.length) {\n throw new Error(\n `GraphQL error: ${result.errors.map((e: { message: string }) => e.message).join(', ')}`\n );\n }\n\n return true;\n}\n","export interface TracingSpan {\n end: () => void;\n setStatus: (status: { code: number; message: string }) => void;\n setAttribute: (key: string, value: string | number | boolean) => void;\n}\n\nconst NOOP_SPAN: TracingSpan = {\n end: () => {},\n setStatus: () => {},\n setAttribute: () => {}\n};\n\n// biome-ignore lint/suspicious/noExplicitAny: Module type kept loose to avoid tight coupling to Sentry internals\nlet sentryModule: any = null;\n\n/**\n * Initialize tracing with a Sentry module instance.\n * Call with `import * as Sentry from '@sentry/react'` from the host app.\n */\nexport function initTracing(sentry: unknown): void {\n sentryModule = sentry;\n}\n\nexport function startInactiveSpan(options: {\n name: string;\n op?: string;\n attributes?: Record<string, string | number | boolean | undefined>;\n}): TracingSpan {\n if (!sentryModule) return NOOP_SPAN;\n return sentryModule.startInactiveSpan(options);\n}\n\n/**\n * Capture user feedback and send it to Sentry.\n * If Sentry is not initialized, this is a no-op.\n */\nexport function captureFeedback(\n feedback: {\n name?: string;\n email?: string;\n message: string;\n },\n options?: {\n tags?: Record<string, string>;\n }\n): void {\n if (!sentryModule) return;\n sentryModule.captureFeedback(\n feedback,\n options?.tags\n ? {\n captureContext: {\n tags: options.tags\n }\n }\n : undefined\n );\n}\n","import { useEffect, useRef, useState } from 'react';\nimport { sendFeedback } from '../../lib/takeshape-api.js';\nimport { captureFeedback } from '../../lib/tracing.js';\nimport { usePurchaseOrderStore } from '../../stores/purchase-order-store.js';\nimport { SpinnerIcon } from '../icons/spinner-icon.js';\nimport { XIcon } from '../icons/x-icon.js';\n\ninterface FeedbackDialogProps {\n messageId: string;\n isOpen: boolean;\n onClose: () => void;\n}\n\ntype SubmitStatus = 'idle' | 'submitting' | 'success' | 'error';\n\nexport function FeedbackDialog({\n messageId,\n isOpen,\n onClose\n}: FeedbackDialogProps) {\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [text, setText] = useState('');\n const [status, setStatus] = useState<SubmitStatus>('idle');\n const [errorMessage, setErrorMessage] = useState('');\n const nameInputRef = useRef<HTMLInputElement>(null);\n\n const takeshapeConfig = usePurchaseOrderStore(\n (state) => state.takeshapeConfig\n );\n const chatThreadId = usePurchaseOrderStore((state) => state.chat.threadId);\n const parserThreadId = usePurchaseOrderStore(\n (state) => state.parser.threadId\n );\n const batchThreadIds = usePurchaseOrderStore(\n (state) => state.batchProcessing.threadIds\n );\n\n // Reset form when dialog opens\n useEffect(() => {\n if (isOpen) {\n setName('');\n setEmail('');\n setText('');\n setStatus('idle');\n setErrorMessage('');\n nameInputRef.current?.focus();\n }\n }, [isOpen]);\n\n // Handle escape key\n useEffect(() => {\n if (!isOpen) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n onClose();\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [isOpen, onClose]);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n if (!name.trim() || !text.trim()) {\n return;\n }\n\n setStatus('submitting');\n setErrorMessage('');\n\n try {\n captureFeedback(\n {\n name: name.trim(),\n email: email.trim() || undefined,\n message: text.trim()\n },\n {\n tags: {\n messageId,\n projectId: takeshapeConfig.projectId,\n ...(chatThreadId && { chatThreadId }),\n ...(parserThreadId && { parserThreadId }),\n ...(batchThreadIds.length > 0 && {\n batchThreadIds: batchThreadIds.join(',')\n })\n }\n }\n );\n await sendFeedback(takeshapeConfig, {\n messageId,\n name: name.trim(),\n email: email.trim(),\n text: text.trim()\n });\n setStatus('success');\n } catch (error) {\n setStatus('error');\n setErrorMessage(\n error instanceof Error ? error.message : 'Failed to send feedback'\n );\n }\n };\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <div\n data-testid=\"feedback-dialog-overlay\"\n className=\"fixed inset-0 z-50 flex items-center justify-center p-4\"\n >\n {/* Backdrop - clicking closes the dialog */}\n <button\n type=\"button\"\n data-testid=\"feedback-dialog-backdrop\"\n className=\"absolute inset-0 bg-black/50 animate-modal-backdrop-in cursor-default\"\n onClick={onClose}\n aria-label=\"Close dialog\"\n tabIndex={-1}\n />\n\n {/* Dialog */}\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"feedback-dialog-title\"\n className=\"relative w-full max-w-md bg-surface rounded-lg shadow-2xl animate-modal-content-in\"\n >\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border\">\n <h2 id=\"feedback-dialog-title\" className=\"text-base font-semibold text-text\">\n Send Feedback\n </h2>\n <button\n type=\"button\"\n data-testid=\"feedback-dialog-close\"\n onClick={onClose}\n className=\"p-1 rounded-md hover:bg-surface-secondary transition-colors\"\n aria-label=\"Close dialog\"\n >\n <XIcon />\n </button>\n </div>\n\n {/* Form */}\n <form onSubmit={handleSubmit} className=\"p-4 space-y-4\">\n <p className=\"text-sm text-text-secondary\">\n Help us improve by sharing issues or suggestions about this\n response.\n </p>\n <div>\n <label\n htmlFor=\"feedback-name\"\n className=\"block text-sm font-medium text-text mb-1\"\n >\n Name\n </label>\n <input\n ref={nameInputRef}\n id=\"feedback-name\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"Your name\"\n required\n disabled={status === 'submitting' || status === 'success'}\n className=\"w-full px-3 py-2 text-sm border border-border rounded-md bg-surface text-text placeholder:text-text-quaternary focus:outline-none focus:ring-2 focus:ring-border-focus disabled:opacity-50\"\n />\n </div>\n\n <div>\n <label\n htmlFor=\"feedback-email\"\n className=\"block text-sm font-medium text-text mb-1\"\n >\n Email <span className=\"text-text-tertiary font-normal\">(optional)</span>\n </label>\n <input\n id=\"feedback-email\"\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"your@email.com\"\n disabled={status === 'submitting' || status === 'success'}\n className=\"w-full px-3 py-2 text-sm border border-border rounded-md bg-surface text-text placeholder:text-text-quaternary focus:outline-none focus:ring-2 focus:ring-border-focus disabled:opacity-50\"\n />\n </div>\n\n <div>\n <label\n htmlFor=\"feedback-text\"\n className=\"block text-sm font-medium text-text mb-1\"\n >\n Feedback\n </label>\n <textarea\n id=\"feedback-text\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n placeholder=\"Share your thoughts...\"\n required\n rows={4}\n disabled={status === 'submitting' || status === 'success'}\n className=\"w-full px-3 py-2 text-sm border border-border rounded-md bg-surface text-text placeholder:text-text-quaternary focus:outline-none focus:ring-2 focus:ring-border-focus resize-none disabled:opacity-50\"\n />\n </div>\n\n {/* Error message */}\n {status === 'error' && errorMessage && (\n <div className=\"p-3 text-sm bg-error-bg text-error-text rounded-md\">\n {errorMessage}\n </div>\n )}\n\n {/* Success message */}\n {status === 'success' && (\n <div className=\"p-3 text-sm bg-success-bg text-success-text rounded-md\">\n Thank you for your feedback!\n </div>\n )}\n\n {/* Submit button */}\n <button\n type=\"submit\"\n disabled={\n !name.trim() ||\n !text.trim() ||\n status === 'submitting' ||\n status === 'success'\n }\n className=\"w-full flex items-center justify-center gap-2 px-4 py-2 text-sm font-medium text-text-invert bg-surface-invert rounded-md hover:bg-surface-invert-hover transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {status === 'submitting' ? (\n <>\n <SpinnerIcon size={16} />\n Sending...\n </>\n ) : status === 'success' ? (\n 'Sent!'\n ) : (\n 'Send Feedback'\n )}\n </button>\n </form>\n </div>\n </div>\n );\n}\n","interface FeedbackIconProps {\n size?: number;\n}\n\nexport const FeedbackIcon = ({ size = 12 }: FeedbackIconProps) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <title>Feedback</title>\n <path d=\"M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z\" />\n <line x1=\"4\" x2=\"4\" y1=\"22\" y2=\"15\" />\n </svg>\n);\n","import { useMemo, useState } from 'react';\nimport { Streamdown } from 'streamdown';\nimport { usePurchaseOrderStore } from '../../../stores/purchase-order-store.js';\nimport { FeedbackDialog } from '../../feedback/feedback-dialog.js';\nimport { ExpandChevronIcon } from '../../icons/expand-chevron-icon.js';\nimport { FeedbackIcon } from '../../icons/feedback-icon.js';\n\ninterface CollapsibleAgentMessageProps {\n messagePartId: string;\n messageId: string;\n isLatestAssistantMessage: boolean;\n text: string;\n}\n\nexport function CollapsibleAgentMessage({\n messagePartId,\n messageId,\n isLatestAssistantMessage,\n text\n}: CollapsibleAgentMessageProps) {\n const previewText = useMemo(() => {\n return text.slice(0, 80);\n }, [text]);\n const expandedMessageIds = usePurchaseOrderStore(\n (state) => state.ui.expandedMessageIds\n );\n const toggleMessageExpanded = usePurchaseOrderStore(\n (state) => state.toggleMessageExpanded\n );\n\n // Latest assistant message is always expanded\n // Older messages are expanded only if explicitly toggled\n const isExpanded =\n isLatestAssistantMessage || expandedMessageIds.includes(messagePartId);\n\n const [isDialogOpen, setIsDialogOpen] = useState(false);\n\n // Latest message doesn't need the collapsible wrapper\n if (isLatestAssistantMessage) {\n return (\n <div className=\"my-2 flex items-center gap-2\">\n <div className=\"flex-1 min-w-0\">\n <Streamdown className=\"leading-relaxed text-text\" plugins={{}}>\n {text}\n </Streamdown>\n </div>\n <button\n type=\"button\"\n onClick={() => setIsDialogOpen(true)}\n className=\"shrink-0 p-1 rounded text-text-tertiary hover:text-text hover:bg-surface-secondary transition-colors\"\n aria-label=\"Send feedback\"\n title=\"Send feedback\"\n >\n <FeedbackIcon size={14} />\n </button>\n <FeedbackDialog\n messageId={messageId}\n isOpen={isDialogOpen}\n onClose={() => setIsDialogOpen(false)}\n />\n </div>\n );\n }\n\n return (\n <div className=\"group/collapsed\">\n <div className=\"flex items-center gap-2\">\n <div className=\"flex-1 min-w-0\">\n <button\n type=\"button\"\n aria-expanded={isExpanded}\n aria-controls={`collapsible-message-${messagePartId}`}\n onClick={() => toggleMessageExpanded(messagePartId)}\n className=\"flex items-center gap-1.5 text-xs text-text w-full\"\n >\n <span\n className={`transition-transform duration-200 ${isExpanded ? 'rotate-90' : ''}`}\n aria-hidden=\"true\"\n >\n <ExpandChevronIcon />\n </span>\n <span className=\"flex-1 text-left truncate\">\n {isExpanded ? 'Hide message' : previewText}\n </span>\n </button>\n <div\n id={`collapsible-message-${messagePartId}`}\n data-testid=\"collapsible-message-panel\"\n className={`collapsible-panel ${isExpanded ? 'collapsible-panel-open' : ''}`}\n >\n <div className=\"overflow-hidden\">\n <div className=\"pl-2.5 border-l border-gray-200 ml-[1px] my-2\">\n <Streamdown\n className=\"text-xs leading-relaxed text-text\"\n plugins={{}}\n >\n {text}\n </Streamdown>\n </div>\n </div>\n </div>\n </div>\n {isExpanded && (\n <button\n type=\"button\"\n onClick={() => setIsDialogOpen(true)}\n className=\"shrink-0 p-1 rounded text-text-tertiary hover:text-text hover:bg-surface-secondary transition-colors\"\n aria-label=\"Send feedback\"\n title=\"Send feedback\"\n >\n <FeedbackIcon size={14} />\n </button>\n )}\n </div>\n <FeedbackDialog\n messageId={messageId}\n isOpen={isDialogOpen}\n onClose={() => setIsDialogOpen(false)}\n />\n </div>\n );\n}\n","import type { UIMessage } from 'ai';\nimport { Streamdown } from 'streamdown';\nimport { CLIENT_TOOL_RESPONSE_MESSAGE } from '../../../constants.js';\nimport type { CartItem, Product, RenderablePart } from '../../../types.js';\nimport { groupRenderableParts } from '../../../utils/group-renderable-parts.js';\nimport { FileIcon } from '../../icons/file-icon.js';\nimport { CollapsibleToolCalls } from '../../tools/collapsible-tool-calls.js';\nimport { Tool } from '../../tools/tool.js';\nimport { CollapsibleAgentMessage } from './collapsible-agent-message.js';\n\nexport interface ChatMessageProps {\n message: UIMessage;\n isFirstUserMessage: boolean;\n isLatestAssistantMessage: boolean;\n isDocumentExpanded: boolean;\n onToggleDocument: () => void;\n uploadedFileName: string | null;\n cart: CartItem[];\n onAddToCart?: (\n product: Product,\n quantity: number\n ) => Promise<boolean> | boolean | undefined;\n onViewProduct?: (product: Product) => void;\n}\n\nfunction getOrderedParts(message: UIMessage): RenderablePart[] {\n if (!message.parts) {\n return [];\n }\n\n const results: RenderablePart[] = [];\n\n for (const part of message.parts) {\n if (part.type === 'text' && part.text !== CLIENT_TOOL_RESPONSE_MESSAGE) {\n results.push({\n type: 'text',\n text: part.text\n });\n } else if (part.type.startsWith('tool-') && 'state' in part) {\n const toolName = part.type.slice(5);\n const toolPart = part as {\n toolCallId: string;\n input?: unknown;\n output?: unknown;\n state: string;\n };\n results.push({\n type: 'tool',\n toolCallId: toolPart.toolCallId,\n toolName,\n toolInput: toolPart.input,\n toolOutput:\n toolPart.state === 'output-available' ? toolPart.output : undefined,\n toolState: toolPart.state\n });\n }\n }\n\n return results;\n}\n\nfunction getFilename(parts: UIMessage['parts']): string {\n const filePart = parts?.find((part) => part.type === 'file');\n if (\n filePart &&\n 'filename' in filePart &&\n typeof filePart.filename === 'string'\n ) {\n return filePart.filename;\n }\n return 'Attachment';\n}\n\nexport function ChatMessage({\n message,\n isFirstUserMessage,\n isLatestAssistantMessage,\n isDocumentExpanded,\n onToggleDocument,\n uploadedFileName,\n cart,\n onAddToCart,\n onViewProduct\n}: ChatMessageProps) {\n const isAssistant = message.role === 'assistant';\n const orderedParts = getOrderedParts(message);\n\n if (orderedParts.length === 0) {\n return null;\n }\n\n return (\n <div\n className={`flex px-5 ${isAssistant ? 'justify-start' : 'justify-end my-2'}`}\n >\n <div className={isAssistant ? 'min-w-0 w-full' : 'max-w-[80%]'}>\n {/* Render first user message as expandable attachment */}\n {isFirstUserMessage ? (\n <div className=\"rounded-2xl bg-surface-tertiary px-4 py-2.5\">\n <button\n type=\"button\"\n onClick={onToggleDocument}\n className=\"flex items-center gap-2 px-3 py-2 bg-surface hover:bg-surface-secondary rounded-lg transition-colors border border-border text-left w-full\"\n >\n <FileIcon />\n <span className=\"text-sm text-text font-medium truncate min-w-0\">\n {uploadedFileName || 'Uploaded Document'}\n </span>\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n className={`ml-auto transition-transform ${isDocumentExpanded ? 'rotate-180' : ''}`}\n >\n <title>{isDocumentExpanded ? 'Collapse' : 'Expand'}</title>\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </button>\n {isDocumentExpanded && (\n <div className=\"mt-2 p-3 bg-surface border border-border rounded-lg max-h-96 overflow-y-auto\">\n {orderedParts.map((part, index) => {\n if (part.type === 'text') {\n return (\n <Streamdown\n key={`text-${message.id}-${index}`}\n className=\"text-sm leading-normal text-text\"\n plugins={{}}\n >\n {part.text}\n </Streamdown>\n );\n }\n return null;\n })}\n </div>\n )}\n </div>\n ) : (\n <>\n {groupRenderableParts(orderedParts).map((part, index) => {\n if (part.type === 'tool-group') {\n return (\n <CollapsibleToolCalls\n key={`group-${message.id}-${index}`}\n tools={part.tools}\n messageId={`${message.id}-${index}`}\n cart={cart}\n onAddToCart={onAddToCart}\n onViewProduct={onViewProduct}\n />\n );\n }\n\n if (part.type === 'text') {\n return isAssistant ? (\n <CollapsibleAgentMessage\n key={`text-${message.id}-${index}`}\n messagePartId={`${message.id}-${index}`}\n messageId={message.id}\n isLatestAssistantMessage={isLatestAssistantMessage}\n text={part.text}\n />\n ) : (\n <div\n key={`text-${message.id}-${index}`}\n className=\"rounded-2xl bg-surface-tertiary px-4 py-2.5\"\n >\n <Streamdown\n className=\"text-sm leading-relaxed text-text\"\n plugins={{}}\n >\n {part.text}\n </Streamdown>\n </div>\n );\n }\n\n if (part.type === 'tool') {\n return (\n <div key={part.toolCallId} className=\"ml-5\">\n <Tool\n toolCallId={part.toolCallId}\n toolName={part.toolName}\n toolInput={part.toolInput}\n toolOutput={part.toolOutput}\n toolState={part.toolState}\n cart={cart}\n onAddToCart={onAddToCart}\n onViewProduct={onViewProduct}\n />\n </div>\n );\n }\n\n return null;\n })}\n {/* Show attachment indicator for user messages with files */}\n {!isAssistant &&\n message.parts?.some((part) => part.type === 'file') && (\n <div className=\"flex items-center gap-1.5 mt-2 text-xs text-text-tertiary\">\n <FileIcon />\n <span>{getFilename(message.parts)}</span>\n </div>\n )}\n </>\n )}\n </div>\n </div>\n );\n}\n","import { useEffect, useState } from 'react';\n\nexport function useTouchDevice(): boolean {\n const [isTouch, setIsTouch] = useState(false);\n\n useEffect(() => {\n if (typeof window.matchMedia !== 'function') {\n setIsTouch(\n 'ontouchstart' in window || navigator.maxTouchPoints > 0\n );\n return;\n }\n\n const mq = window.matchMedia('(pointer: coarse)');\n setIsTouch(mq.matches);\n const handler = (e: MediaQueryListEvent) => setIsTouch(e.matches);\n mq.addEventListener('change', handler);\n return () => mq.removeEventListener('change', handler);\n }, []);\n\n return isTouch;\n}\n","export const UploadDocumentIcon = () => (\n <svg\n width=\"48\"\n height=\"48\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n >\n <title>Upload file</title>\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <polyline points=\"14 2 14 8 20 8\" />\n <line x1=\"12\" y1=\"18\" x2=\"12\" y2=\"12\" />\n <polyline points=\"9 15 12 12 15 15\" />\n </svg>\n);\n","export const CameraIcon = () => (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <title>Take photo</title>\n <path d=\"M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z\" />\n <circle cx=\"12\" cy=\"13\" r=\"4\" />\n </svg>\n);\n","import { CameraIcon } from '../icons/camera-icon.js';\n\nexport interface CameraButtonProps {\n onClick: () => void;\n}\n\nexport function CameraButton({ onClick }: CameraButtonProps) {\n return (\n <button\n type=\"button\"\n className=\"flex items-center gap-2 min-h-11 py-2.5 px-5 bg-surface border border-border-strong rounded-full text-sm font-medium text-text cursor-pointer transition-colors hover:bg-surface-secondary focus-visible:outline-2 focus-visible:outline-border-focus focus-visible:outline-offset-2\"\n onClick={onClick}\n >\n <CameraIcon />\n Take a photo\n </button>\n );\n}","import type { ChangeEvent, RefObject } from 'react';\nimport { useTouchDevice } from '../../../hooks/use-touch-device.js';\nimport { ACCEPTED_CAMERA_TYPES, ACCEPTED_EXTENSIONS, FILE_TYPE_LABELS } from '../../../lib/file-validation.js';\nimport { cn } from '../../../lib/utils.js';\nimport { UploadDocumentIcon } from '../../icons/upload-document-icon.js';\nimport { CameraButton } from '../../uploader/camera-button.js';\n\nexport interface ChatPanelEmptyStateProps {\n isDragging?: boolean;\n fileInputRef: RefObject<HTMLInputElement | null>;\n cameraInputRef: RefObject<HTMLInputElement | null>;\n fileError: string | null;\n onFileChange: (e: ChangeEvent<HTMLInputElement>) => void;\n onDropZoneClick: () => void;\n onCameraClick: () => void;\n}\n\nexport function ChatPanelEmptyState({\n isDragging = false,\n fileInputRef,\n cameraInputRef,\n fileError,\n onFileChange,\n onDropZoneClick,\n onCameraClick\n}: ChatPanelEmptyStateProps) {\n const isTouchDevice = useTouchDevice();\n\n return (\n <div className=\"flex-1 flex items-center justify-center animate-fade-in-up\">\n <div className=\"flex flex-col items-center gap-4\">\n <button\n type=\"button\"\n className=\"flex flex-col items-center gap-4 bg-transparent border-none cursor-pointer p-6 rounded-2xl transition-colors hover:bg-surface-secondary\"\n onClick={onDropZoneClick}\n >\n <input\n ref={fileInputRef}\n type=\"file\"\n className=\"hidden\"\n onChange={onFileChange}\n accept={ACCEPTED_EXTENSIONS}\n />\n <input\n ref={cameraInputRef}\n type=\"file\"\n className=\"hidden\"\n onChange={onFileChange}\n accept={ACCEPTED_CAMERA_TYPES}\n capture=\"environment\"\n />\n <div\n className={cn(\n 'flex items-center justify-center w-16 h-16 rounded-2xl p-1 border-2 border-dashed border-border-focus text-text transition-transform duration-200',\n isDragging && 'animate-icon-bounce'\n )}\n >\n <UploadDocumentIcon />\n </div>\n <h3 className=\"m-0 text-base font-semibold text-text text-center\">\n Upload your Order\n </h3>\n <p className=\"m-0 text-sm text-text-tertiary text-center\">\n Your Order Assistant will match products and check stock availability\n </p>\n <div className=\"flex flex-wrap justify-center gap-2\">\n {FILE_TYPE_LABELS.map((label) => (\n <span\n key={label}\n className=\"py-1 px-3 bg-surface-invert/5 border border-border-strong rounded-full text-xs font-medium text-text\"\n >\n {label}\n </span>\n ))}\n </div>\n </button>\n {isTouchDevice && <CameraButton onClick={onCameraClick} />}\n {fileError && (\n <div className=\"flex items-center gap-2 py-3 px-4 bg-error-bg border border-error/30 rounded-lg text-error-text text-sm max-w-[400px] text-center\">\n {fileError}\n </div>\n )}\n </div>\n </div>\n );\n}\n","export function TypingIndicator() {\n return (\n <div className=\"flex justify-start px-5 py-2\">\n <div className=\"flex flex-col gap-2 w-3/4\">\n <div className=\"h-3 rounded-full animate-shimmer\" />\n <div\n className=\"h-3 w-1/2 rounded-full animate-shimmer\"\n style={{ animationDelay: '0.15s' }}\n />\n </div>\n </div>\n );\n}\n","import type { UIMessage } from 'ai';\nimport {\n type ChangeEvent,\n type FormEvent,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState\n} from 'react';\nimport type { UseFileDropResult } from '../../../hooks/use-file-drop.js';\nimport type { CartItem, Product } from '../../../types.js';\nimport { ChatError } from './chat-error.js';\nimport { ChatInput } from './chat-input.js';\nimport { ChatMessage } from './chat-message.js';\nimport { ChatPanelEmptyState } from './chat-panel-empty-state.js';\nimport { TypingIndicator } from './typing-indicator.js';\n\nexport interface ChatPanelProps {\n messages: UIMessage[];\n input: string;\n onInputChange: (e: ChangeEvent<HTMLTextAreaElement>) => void;\n onSubmit: (e: FormEvent<HTMLFormElement>) => void;\n isLoading: boolean;\n cart: CartItem[];\n onAddToCart?: (\n product: Product,\n quantity: number\n ) => Promise<boolean> | boolean | undefined;\n onViewProduct?: (product: Product) => void;\n className?: string;\n error?: Error | null;\n onRetry?: () => void;\n hasProcessedDocument?: boolean;\n uploadedFileName?: string | null;\n fileDrop?: UseFileDropResult;\n}\n\nexport interface ChatPanelRef {\n scrollToBottom: () => void;\n}\n\nexport const ChatPanel = forwardRef<ChatPanelRef, ChatPanelProps>(\n function ChatPanel(\n {\n messages,\n input,\n onInputChange,\n onSubmit,\n isLoading,\n cart,\n onAddToCart,\n onViewProduct,\n className = '',\n error = null,\n onRetry,\n hasProcessedDocument = false,\n uploadedFileName = null,\n fileDrop\n },\n ref\n ) {\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n const shouldAutoScrollRef = useRef(true);\n const [isDocumentExpanded, setIsDocumentExpanded] = useState(false);\n\n const latestAssistantMessageId = useMemo(() => {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i];\n if (msg?.role === 'assistant') {\n return msg.id;\n }\n }\n return null;\n }, [messages]);\n\n useImperativeHandle(ref, () => ({\n scrollToBottom: () => {\n const container = scrollContainerRef.current;\n if (container) {\n const distance =\n container.scrollHeight -\n container.scrollTop -\n container.clientHeight;\n if (distance > 500 || !container.scrollTo) {\n container.scrollTop = container.scrollHeight;\n } else {\n container.scrollTo({\n top: container.scrollHeight,\n behavior: 'smooth'\n });\n }\n }\n shouldAutoScrollRef.current = true;\n }\n }));\n\n // Autoscroll when new messages come in while scrolled to bottom\n useEffect(() => {\n const container = scrollContainerRef.current;\n if (!container) return;\n\n const handleScroll = () => {\n // Track if user is near bottom\n const isNearBottom =\n container.scrollHeight -\n container.scrollTop -\n container.clientHeight <\n 50;\n shouldAutoScrollRef.current = isNearBottom;\n };\n\n const observer = new MutationObserver(() => {\n if (shouldAutoScrollRef.current) {\n container.scrollTop = container.scrollHeight;\n }\n });\n\n container.addEventListener('scroll', handleScroll);\n observer.observe(container, {\n childList: true,\n subtree: true,\n characterData: true\n });\n\n return () => {\n container.removeEventListener('scroll', handleScroll);\n observer.disconnect();\n };\n }, []);\n\n return (\n <div className={`bg-white flex flex-col h-full min-h-0 ${className}`}>\n {/* Messages */}\n <div\n ref={scrollContainerRef}\n className=\"flex-1 min-h-0 overflow-y-auto py-3 flex flex-col\"\n >\n {messages.length === 0 && !isLoading && fileDrop && (\n <ChatPanelEmptyState\n isDragging={fileDrop.isDragging}\n fileInputRef={fileDrop.fileInputRef}\n cameraInputRef={fileDrop.cameraInputRef}\n fileError={fileDrop.fileError}\n onFileChange={fileDrop.handleFileChange}\n onDropZoneClick={fileDrop.openFilePicker}\n onCameraClick={fileDrop.openCamera}\n />\n )}\n {messages.map((message, messageIndex) => {\n const isFirstUserMessage =\n hasProcessedDocument &&\n message.role !== 'assistant' &&\n messageIndex === 0;\n\n const isLatestAssistantMessage =\n message.role === 'assistant' &&\n message.id === latestAssistantMessageId;\n\n return (\n <ChatMessage\n key={message.id}\n message={message}\n isFirstUserMessage={isFirstUserMessage}\n isLatestAssistantMessage={isLatestAssistantMessage}\n isDocumentExpanded={isDocumentExpanded}\n onToggleDocument={() =>\n setIsDocumentExpanded(!isDocumentExpanded)\n }\n uploadedFileName={uploadedFileName}\n cart={cart}\n onAddToCart={onAddToCart}\n onViewProduct={onViewProduct}\n />\n );\n })}\n\n {isLoading && <TypingIndicator />}\n <ChatError error={error} onRetry={onRetry} />\n </div>\n\n <ChatInput\n input={input}\n onInputChange={onInputChange}\n onSubmit={onSubmit}\n isLoading={isLoading}\n />\n </div>\n );\n }\n);\n","import { create } from 'zustand';\nimport { persist } from 'zustand/middleware';\n\nconst USER_SETTINGS_STORAGE_KEY = 'purchase-order-chat-user-settings';\n\n// Default panel width for the resizable panels (percentage: 0-100)\nexport const DEFAULT_PANEL_WIDTH = 25;\n\nexport interface UserSettingsState {\n /** Left panel width as percentage (0-100) */\n panelWidth: number;\n}\n\nexport interface UserSettingsStore extends UserSettingsState {\n /** Set left panel width as percentage (0-100) */\n setPanelWidth: (width: number) => void;\n}\n\n/**\n * Separate store for user settings with its own persistence.\n * This avoids complication when clearing sessions.\n */\nexport const useUserSettingsStore = create<UserSettingsStore>()(\n persist(\n (set) => ({\n panelWidth: DEFAULT_PANEL_WIDTH,\n setPanelWidth: (panelWidth) => set({ panelWidth })\n }),\n {\n name: USER_SETTINGS_STORAGE_KEY\n }\n )\n);\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { useUserSettingsStore } from '../../../stores/user-settings-store.js';\n\nexport function useResizablePanel() {\n // Read panel width from store (persisted across reloads)\n const leftPanelWidth = useUserSettingsStore((state) => state.panelWidth);\n const setPanelWidth = useUserSettingsStore((state) => state.setPanelWidth);\n\n const [isDesktop, setIsDesktop] = useState<boolean>(\n typeof window !== 'undefined' && window.innerWidth >= 1024\n );\n const containerRef = useRef<HTMLDivElement>(null);\n const isDragging = useRef(false);\n const leftPanelWidthRef = useRef<number>(leftPanelWidth);\n\n // Sync ref when store value changes\n useEffect(() => {\n leftPanelWidthRef.current = leftPanelWidth;\n }, [leftPanelWidth]);\n\n // Setup desktop detection\n useEffect(() => {\n const updateLayout = () => {\n setIsDesktop(window.innerWidth >= 1024);\n };\n\n updateLayout();\n window.addEventListener('resize', updateLayout);\n return () => {\n window.removeEventListener('resize', updateLayout);\n };\n }, []);\n\n const handleMouseMove = useCallback(\n (e: MouseEvent) => {\n if (!isDragging.current || !containerRef.current) return;\n\n const containerRect = containerRef.current.getBoundingClientRect();\n const newWidth =\n ((e.clientX - containerRect.left) / containerRect.width) * 100;\n const clampedWidth = Math.min(80, Math.max(20, newWidth));\n\n leftPanelWidthRef.current = clampedWidth;\n setPanelWidth(clampedWidth);\n },\n [setPanelWidth]\n );\n\n const handleMouseUp = useCallback(() => {\n isDragging.current = false;\n // Panel width is automatically persisted by Zustand store\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n }, [handleMouseMove]);\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n isDragging.current = true;\n document.body.style.cursor = 'col-resize';\n document.body.style.userSelect = 'none';\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n },\n [handleMouseMove, handleMouseUp]\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n const increment = 2; // 2% change per key press\n\n if (e.key === 'ArrowLeft') {\n e.preventDefault();\n const newWidth = Math.max(20, leftPanelWidthRef.current - increment);\n leftPanelWidthRef.current = newWidth;\n setPanelWidth(newWidth);\n } else if (e.key === 'ArrowRight') {\n e.preventDefault();\n const newWidth = Math.min(80, leftPanelWidthRef.current + increment);\n leftPanelWidthRef.current = newWidth;\n setPanelWidth(newWidth);\n }\n },\n [setPanelWidth]\n );\n\n const handleBlur = useCallback(() => {\n // Panel width is automatically persisted by Zustand store, no need to save manually\n }, []);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n handleMouseUp();\n };\n }, [handleMouseUp]);\n\n return {\n leftPanelWidth,\n isDesktop,\n containerRef,\n handleMouseDown,\n handleKeyDown,\n handleBlur\n };\n}\n","export type ActiveTab = 'cart' | 'chat';\n\nexport interface TabBarProps {\n activeTab: ActiveTab;\n onTabChange: (tab: ActiveTab) => void;\n hasUnread: boolean;\n}\n\nexport function TabBar({ activeTab, onTabChange, hasUnread }: TabBarProps) {\n const chatHasUnread = hasUnread && activeTab !== 'chat';\n\n return (\n <div className=\"flex border-b border-border-strong shrink-0\" role=\"tablist\">\n <button\n type=\"button\"\n role=\"tab\"\n id=\"tab-cart\"\n aria-selected={activeTab === 'cart'}\n aria-controls=\"tabpanel-cart\"\n className={`flex-1 min-h-11 py-2.5 px-4 text-sm font-medium border-b-2 transition-colors cursor-pointer bg-transparent ${activeTab === 'cart' ? 'border-border-focus text-text' : 'border-transparent text-text-tertiary hover:text-text-secondary hover:border-border'}`}\n onClick={() => onTabChange('cart')}\n >\n Cart\n </button>\n <button\n type=\"button\"\n role=\"tab\"\n id=\"tab-chat\"\n aria-selected={activeTab === 'chat'}\n aria-controls=\"tabpanel-chat\"\n aria-label={chatHasUnread ? 'Chat (new messages)' : 'Chat'}\n className={`relative flex-1 min-h-11 py-2.5 px-4 text-sm font-medium border-b-2 transition-colors cursor-pointer bg-transparent ${activeTab === 'chat' ? 'border-border-focus text-text' : 'border-transparent text-text-tertiary hover:text-text-secondary hover:border-border'}`}\n onClick={() => onTabChange('chat')}\n >\n Chat\n {chatHasUnread && (\n <span\n className=\"absolute top-2 right-[calc(50%-24px)] w-2 h-2 rounded-full bg-error\"\n aria-hidden=\"true\"\n />\n )}\n </button>\n </div>\n );\n}\n","import type { UIMessage } from 'ai';\nimport {\n type ChangeEvent,\n type FormEvent,\n type RefObject,\n useCallback,\n useEffect,\n useRef,\n useState\n} from 'react';\nimport { useFileDrop } from '../../hooks/use-file-drop.js';\nimport type { CustomerAddress } from '../../lib/bigcommerce/index.js';\nimport type {\n AddressUpdateStatus,\n BuyerInfo,\n CartItem,\n CheckoutTotals,\n CustomerInfo,\n ItemWarning,\n Product\n} from '../../types.js';\nimport { CartPanel } from './cartifact/cartifact.js';\nimport { ChatPanel, type ChatPanelRef } from './chat-panel/chat-panel.js';\nimport { useResizablePanel } from './hooks/use-resizable-panel.js';\nimport { type ActiveTab, TabBar } from './tab-bar.js';\n\nexport interface ChatViewProps {\n // Chat panel props\n messages: UIMessage[];\n input: string;\n onInputChange: (e: ChangeEvent<HTMLTextAreaElement>) => void;\n onSubmit: (e: FormEvent<HTMLFormElement>) => void;\n isLoading: boolean;\n error?: Error | null;\n onRetry?: () => void;\n hasProcessedDocument?: boolean;\n uploadedFileName?: string | null;\n chatPanelRef?: RefObject<ChatPanelRef | null>;\n onFileUpload?: (file: File) => void;\n\n // Cart panel props\n cartItems: CartItem[];\n itemWarnings?: ItemWarning[];\n onUpdateQuantity: (id: string, quantity: number) => void | Promise<void>;\n onRemove: (id: string) => void;\n onCheckout: () => void;\n onSuggestAlternatives: (itemName: string, sku?: string) => void;\n onShowMoreLikeThis: (itemName: string, sku?: string) => void;\n onViewProduct?: (item: {\n productEntityId?: number;\n sku: string;\n name: string;\n path?: string;\n }) => void;\n onAddToCart?: (\n product: Product,\n quantity: number\n ) => Promise<boolean> | boolean | undefined;\n orderId?: string | null;\n buyerInfo?: BuyerInfo | null;\n customerInfo?: CustomerInfo;\n addresses?: CustomerAddress[];\n selectedAddressId?: string;\n addressUpdateStatus?: AddressUpdateStatus;\n onAddressChange?: (addressId: string) => void;\n selectedBillingAddressId?: string;\n billingAddressUpdateStatus?: AddressUpdateStatus;\n onBillingAddressChange?: (addressId: string) => void;\n shipToAddress?: CustomerAddress | null;\n billingAddress?: CustomerAddress | null;\n checkoutTotals?: CheckoutTotals | null;\n isCartLoading?: boolean;\n poMetadataSet?: boolean;\n onNewOrder?: () => void | Promise<void>;\n onExpand?: () => void;\n onMinimize?: () => void;\n\n className?: string;\n}\n\nexport function ChatView({\n // Chat panel props\n messages,\n input,\n onInputChange,\n onSubmit,\n isLoading,\n error,\n onRetry,\n hasProcessedDocument,\n uploadedFileName,\n chatPanelRef,\n onFileUpload,\n\n // Cart panel props\n cartItems,\n itemWarnings,\n onUpdateQuantity,\n onRemove,\n onCheckout,\n onSuggestAlternatives,\n onShowMoreLikeThis,\n onViewProduct,\n onAddToCart,\n orderId,\n buyerInfo,\n customerInfo,\n addresses,\n selectedAddressId,\n addressUpdateStatus,\n onAddressChange,\n selectedBillingAddressId,\n billingAddressUpdateStatus,\n onBillingAddressChange,\n shipToAddress,\n billingAddress,\n checkoutTotals,\n isCartLoading,\n poMetadataSet,\n onNewOrder,\n onExpand,\n onMinimize,\n\n className = ''\n}: ChatViewProps) {\n const panel = useResizablePanel();\n const [activeTab, setActiveTab] = useState<ActiveTab>(\n cartItems.length > 0 ? 'cart' : 'chat'\n );\n const [hasUnread, setHasUnread] = useState(false);\n const prevMessageCount = useRef(messages.length);\n const activeTabRef = useRef(activeTab);\n activeTabRef.current = activeTab;\n\n const isBothEmpty =\n messages.length === 0 && cartItems.length === 0 && !!onFileUpload;\n\n const fileDrop = useFileDrop({\n onFile: onFileUpload ?? (() => {})\n });\n\n // Track new messages arriving while the chat tab is not active\n useEffect(() => {\n if (\n messages.length > prevMessageCount.current &&\n activeTabRef.current !== 'chat'\n ) {\n setHasUnread(true);\n }\n prevMessageCount.current = messages.length;\n }, [messages.length]);\n\n // Clear unread when switching to desktop (both panels are visible)\n useEffect(() => {\n if (panel.isDesktop) {\n setHasUnread(false);\n }\n }, [panel.isDesktop]);\n\n const handleTabChange = useCallback((tab: ActiveTab) => {\n setActiveTab(tab);\n if (tab === 'chat') {\n setHasUnread(false);\n }\n }, []);\n\n const chatPanel = (\n <ChatPanel\n ref={chatPanelRef}\n messages={messages}\n input={input}\n onInputChange={onInputChange}\n onSubmit={onSubmit}\n isLoading={isLoading}\n cart={cartItems}\n onAddToCart={onAddToCart}\n onViewProduct={onViewProduct}\n error={error}\n onRetry={onRetry}\n hasProcessedDocument={hasProcessedDocument}\n uploadedFileName={uploadedFileName}\n fileDrop={onFileUpload ? fileDrop : undefined}\n />\n );\n\n const cartPanel = (\n <CartPanel\n items={cartItems}\n itemWarnings={itemWarnings}\n onUpdateQuantity={onUpdateQuantity}\n onRemove={onRemove}\n onCheckout={onCheckout}\n onSuggestAlternatives={onSuggestAlternatives}\n onShowMoreLikeThis={onShowMoreLikeThis}\n onViewProduct={onViewProduct}\n orderId={orderId ?? undefined}\n buyerInfo={buyerInfo ?? undefined}\n customerInfo={customerInfo}\n addresses={addresses}\n selectedAddressId={selectedAddressId}\n addressUpdateStatus={addressUpdateStatus}\n onAddressChange={onAddressChange}\n selectedBillingAddressId={selectedBillingAddressId}\n billingAddressUpdateStatus={billingAddressUpdateStatus}\n onBillingAddressChange={onBillingAddressChange}\n shipToAddress={shipToAddress ?? undefined}\n billingAddress={billingAddress ?? undefined}\n checkoutTotals={checkoutTotals ?? undefined}\n isLoading={isCartLoading}\n poMetadataSet={poMetadataSet}\n isDragging={isBothEmpty && fileDrop.isDragging}\n onNewOrder={onNewOrder}\n onExpand={onExpand}\n onMinimize={onMinimize}\n className={panel.isDesktop ? 'rounded-l-none border-0' : ''}\n />\n );\n\n // Spread drag handlers on the container when both panels are empty\n const dragHandlers = isBothEmpty ? fileDrop.dragProps : undefined;\n\n if (!panel.isDesktop) {\n return (\n // biome-ignore lint/a11y/noStaticElementInteractions: dnd is optional\n <div\n ref={panel.containerRef}\n className={`flex flex-col h-full min-h-0 border border-solid border-border-strong rounded-md overflow-hidden ${className}`}\n {...dragHandlers}\n >\n <TabBar\n activeTab={activeTab}\n onTabChange={handleTabChange}\n hasUnread={hasUnread}\n />\n <div\n className=\"flex-1 min-h-0 overflow-hidden\"\n role=\"tabpanel\"\n id={`tabpanel-${activeTab}`}\n aria-labelledby={`tab-${activeTab}`}\n >\n {activeTab === 'cart' ? cartPanel : chatPanel}\n </div>\n </div>\n );\n }\n\n return (\n // biome-ignore lint/a11y/noStaticElementInteractions: dnd is optional\n <div\n ref={panel.containerRef}\n className={`flex flex-row h-full ${className}`}\n {...dragHandlers}\n >\n <div\n className=\"h-full border border-r-0 border-solid border-border-strong rounded-md rounded-r-none overflow-hidden\"\n style={{ width: `${panel.leftPanelWidth}%`, minWidth: 0 }}\n >\n {chatPanel}\n </div>\n {/* biome-ignore lint/a11y/useSemanticElements: hr cannot have children */}\n <div\n className=\"w-px cursor-col-resize bg-border shrink-0 z-10 relative transition-colors hover:bg-text-quaternary before:content-[''] before:absolute before:inset-y-0 before:-left-1.5 before:-right-1.5\"\n onMouseDown={panel.handleMouseDown}\n onKeyDown={panel.handleKeyDown}\n onBlur={panel.handleBlur}\n role=\"separator\"\n tabIndex={0}\n aria-orientation=\"vertical\"\n aria-label=\"Resize panels\"\n aria-valuenow={panel.leftPanelWidth}\n aria-valuemin={20}\n aria-valuemax={80}\n aria-valuetext={`Chat panel width: ${Math.round(panel.leftPanelWidth)}%`}\n />\n <div\n className=\"h-full border border-l-0 border-border-strong border-solid rounded-md rounded-l-none overflow-hidden\"\n style={{ width: `${100 - panel.leftPanelWidth}%`, minWidth: 0 }}\n >\n {cartPanel}\n </div>\n </div>\n );\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { useBigCommerceClient } from '../contexts/bigcommerce-client-context.js';\nimport { usePurchaseOrderStore } from '../stores/purchase-order-store.js';\nimport { SpinnerIcon } from './icons/spinner-icon.js';\n\nexport function ExistingCartPrompt() {\n const client = useBigCommerceClient();\n const existingCart = usePurchaseOrderStore((state) => state.ui.existingCart);\n const confirmClearExistingCart = usePurchaseOrderStore(\n (state) => state.confirmClearExistingCart\n );\n const [isClearing, setIsClearing] = useState(false);\n\n const itemCount = useMemo(\n () =>\n existingCart?.lineItems.physicalItems.reduce(\n (sum, item) => sum + item.quantity,\n 0\n ) ?? 0,\n [existingCart]\n );\n\n const handleClearCart = useCallback(async () => {\n if (!client || isClearing) return;\n setIsClearing(true);\n await confirmClearExistingCart(client);\n }, [confirmClearExistingCart, client, isClearing]);\n\n return (\n <div className=\"flex h-full items-center justify-center\">\n <div className=\"text-center max-w-md px-4\">\n <p className=\"text-lg text-text-secondary mb-2\">Existing cart found</p>\n <p className=\"text-sm text-text-tertiary mb-6\">\n You have {itemCount} {itemCount === 1 ? 'item' : 'items'} in an\n existing cart. This cart will be cleared to start a new purchase\n order.\n </p>\n <button\n type=\"button\"\n onClick={handleClearCart}\n disabled={isClearing}\n className=\"bg-surface-invert shadow-button transition-all duration-200 ease-in-out hover:bg-surface-invert-hover hover:shadow-button-hover hover:-translate-y-px px-4 py-2 text-text-invert rounded-full font-medium cursor-pointer disabled:opacity-50 disabled:pointer-events-none\"\n >\n {isClearing ? (\n <span className=\"flex items-center gap-2\">\n <SpinnerIcon size={14} />\n Clearing cart…\n </span>\n ) : (\n 'Clear Cart & Continue'\n )}\n </button>\n </div>\n </div>\n );\n}\n","export interface FatalErrorProps {\n message?: string;\n}\n\nexport function FatalError({ message }: FatalErrorProps) {\n const handleRefresh = () => {\n window.location.reload();\n };\n\n return (\n <div className=\"flex items-center justify-center h-full w-full bg-surface-secondary\">\n <div className=\"text-center max-w-md px-4\">\n <p className=\"text-lg text-text-secondary mb-2\">Something went wrong</p>\n <p className=\"text-sm text-text-tertiary mb-6\">\n {message ||\n 'An unexpected error occurred. Please refresh the page to try again.'}\n </p>\n <button\n type=\"button\"\n onClick={handleRefresh}\n className=\"bg-surface-invert shadow-button transition-all duration-200 ease-in-out hover:bg-surface-invert-hover hover:shadow-button-hover hover:-translate-y-px px-4 py-2 text-text-invert rounded-full font-medium cursor-pointer\"\n >\n Refresh page\n </button>\n </div>\n </div>\n );\n}\n","import { useMemo } from 'react';\nimport { usePurchaseOrderStore } from '../stores/purchase-order-store.js';\nimport type { ProcessingStep } from '../types.js';\n\nexport function useProcessingState(): ProcessingStep | null {\n const appState = usePurchaseOrderStore((state) => state.appState);\n const parsedContent = usePurchaseOrderStore(\n (state) => state.parser.parsedContent\n );\n const batchProcessingStatus = usePurchaseOrderStore(\n (state) => state.batchProcessing.status\n );\n\n return useMemo(() => {\n if (appState !== 'processing') {\n return null;\n }\n if (!parsedContent) {\n return 'reading';\n }\n if (\n batchProcessingStatus === 'idle' ||\n batchProcessingStatus === 'processing'\n ) {\n return 'matching';\n }\n return 'building';\n }, [appState, parsedContent, batchProcessingStatus]);\n}\n","const steps = [\n { label: 'Upload', number: 1 },\n { label: 'Match', number: 2 },\n { label: 'Checkout', number: 3 }\n];\n\n// biome-ignore lint/suspicious/noEmptyInterface: needed for storybook type inference\nexport interface ProcessingStepsProps {}\n\nexport function ProcessingSteps(_props: ProcessingStepsProps = {}) {\n return (\n <div className=\"flex items-center justify-center gap-0 p-4 md:py-1 md:px-0\">\n {steps.map((step, index) => (\n <div key={step.label} className=\"flex items-center gap-2\">\n {index > 0 && (\n <div className=\"w-6 md:w-10 h-px mx-2 md:mx-3 rounded-[1px] bg-border\" />\n )}\n <div className=\"flex items-center justify-center w-5 h-5 rounded-full shrink-0 bg-transparent border-[1.5px] border-border-strong text-text-quaternary\">\n <span className=\"text-xs font-medium\">{step.number}</span>\n </div>\n <span className=\"text-s font-normal whitespace-nowrap text-text-quaternary\">\n {step.label}\n </span>\n </div>\n ))}\n </div>\n );\n}\n","import type { ChangeEvent, RefObject } from 'react';\nimport { ACCEPTED_CAMERA_TYPES, FILE_TYPE_LABELS } from '../../lib/file-validation.js';\nimport { cn } from '../../lib/utils.js';\nimport { UploadDocumentIcon } from '../icons/upload-document-icon.js';\n\nexport interface UploadDropZoneProps {\n isDragging: boolean;\n fileInputRef: RefObject<HTMLInputElement | null>;\n cameraInputRef: RefObject<HTMLInputElement | null>;\n acceptedExtensions: string;\n onDropZoneClick: () => void;\n onFileChange: (e: ChangeEvent<HTMLInputElement>) => void;\n}\n\nexport function UploadDropZone({\n isDragging,\n fileInputRef,\n cameraInputRef,\n acceptedExtensions,\n onDropZoneClick,\n onFileChange\n}: UploadDropZoneProps) {\n return (\n <button\n type=\"button\"\n className=\"shadow-upload transition-all duration-[250ms] ease-[cubic-bezier(0.34,1.56,0.64,1)] flex flex-col items-center gap-4 pb-6 max-md:min-w-0 min-w-lg max-md:p-8 max-md:w-full max-md:max-w-[400px] cursor-pointer hover:-translate-y-[3px] hover:border-surface-invert-hover focus-visible:outline focus-visible:outline-border-focus focus-visible:outline-offset\"\n onClick={onDropZoneClick}\n >\n <input\n ref={fileInputRef}\n type=\"file\"\n className=\"hidden\"\n onChange={onFileChange}\n accept={acceptedExtensions}\n />\n <input\n ref={cameraInputRef}\n type=\"file\"\n className=\"hidden\"\n onChange={onFileChange}\n accept={ACCEPTED_CAMERA_TYPES}\n capture=\"environment\"\n />\n <div\n className={cn(\n 'flex items-center justify-center w-16 h-16 rounded-2xl p-1 border-2 border-dashed border-border-focus text-text transition-transform duration-200',\n isDragging && 'animate-icon-bounce'\n )}\n >\n <UploadDocumentIcon />\n </div>\n <h2 className=\"m-0 text-2xl max-md:text-xl font-semibold text-text text-center\">\n Upload your Order\n </h2>\n <p className=\"m-0 px-8 text-sm text-text-tertiary text-center\">\n Your Order Assistant will match products and check stock availability\n </p>\n <div className=\"flex flex-wrap justify-center gap-2 mt-2\">\n {FILE_TYPE_LABELS.map((label) => (\n <span\n key={label}\n className=\"py-1 px-3 bg-surface-invert/5 border border-border-strong rounded-full text-xs font-medium text-text backdrop-blur\"\n >\n {label}\n </span>\n ))}\n </div>\n </button>\n );\n}","import type { ChangeEvent, RefObject } from 'react';\nimport { useCallback, useRef } from 'react';\nimport { cn } from '../../lib/utils.js';\nimport { useTouchDevice } from '../../hooks/use-touch-device.js';\nimport { CameraButton } from './camera-button.js';\nimport { ProcessingSteps } from './processing-steps.js';\nimport { UploadDropZone } from './upload-drop-zone.js';\n\nexport interface InitialStateProps {\n isDragging: boolean;\n fileInputRef: RefObject<HTMLInputElement | null>;\n acceptedExtensions: string;\n displayError: string | null;\n onDropZoneClick: () => void;\n onFileChange: (e: ChangeEvent<HTMLInputElement>) => void;\n onSkip: () => void;\n}\n\nexport function InitialState({\n isDragging,\n fileInputRef,\n acceptedExtensions,\n displayError,\n onDropZoneClick,\n onFileChange,\n onSkip\n}: InitialStateProps) {\n const isTouchDevice = useTouchDevice();\n const cameraInputRef = useRef<HTMLInputElement>(null);\n\n const handleCameraClick = useCallback(() => {\n cameraInputRef.current?.click();\n }, []);\n\n return (\n <div\n className={cn(\n 'flex flex-col items-center gap-6 border-border border-solid bg-surface border rounded-2xl transition-all duration-[250ms] ease-[cubic-bezier(0.34,1.56,0.64,1)] hover:border-border-strong',\n isDragging &&\n 'ring-2 ring-border-focus border-border-focus bg-surface-tertiary shadow-upload-active'\n )}\n >\n <div className=\"upload-zone-steps mb-3 py-4 px-8 border-b border-solid border-border-strong\">\n <ProcessingSteps />\n </div>\n\n <UploadDropZone\n isDragging={isDragging}\n fileInputRef={fileInputRef}\n cameraInputRef={cameraInputRef}\n acceptedExtensions={acceptedExtensions}\n onDropZoneClick={onDropZoneClick}\n onFileChange={onFileChange}\n />\n\n {isTouchDevice && <CameraButton onClick={handleCameraClick} />}\n\n {displayError && (\n <div className=\"flex items-center gap-2 py-3 px-4 bg-error-bg border border-error/30 rounded-lg text-error-text text-sm max-w-[400px] text-center\">\n {displayError}\n </div>\n )}\n\n <div className=\"upload-zone-steps px-8 border-b border-solid border-border-strong\" />\n\n <button\n type=\"button\"\n className=\"border-none pt-4 pb-8 px-4 text-sm text-text-tertiary cursor-pointer transition-colors duration-150 hover:text-text hover:underline focus-visible:outline-2 focus-visible:outline-border-focus focus-visible:outline-offset-2 rounded\"\n onClick={onSkip}\n >\n Or start by describing what you need\n </button>\n </div>\n );\n}\n","import type { CartItem, ProcessingStep } from '../../types.js';\n\nexport interface CartPreviewProps {\n items: CartItem[];\n orderId?: string | null;\n parsedContent?: string[] | null;\n isUploading?: boolean;\n currentStep?: ProcessingStep | null;\n}\n\nexport function CartPreview({\n items,\n orderId,\n parsedContent,\n isUploading = false,\n currentStep = null\n}: CartPreviewProps) {\n const hasProducts = items.length > 0;\n const isReadingOrMatching =\n currentStep === 'reading' || currentStep === 'matching';\n const isBuildingCart = currentStep === 'building';\n\n return (\n <div className=\"w-full max-w-xs overflow-hidden rounded-xl bg-surface-secondary shadow-preview\">\n <div className=\"flex items-center justify-between px-6 py-4 text-text-invert bg-surface-invert\">\n <h3 className=\"m-0 text-base font-semibold\">Cart</h3>\n {orderId && <span className=\"text-xs opacity-80\">{orderId}</span>}\n </div>\n {parsedContent && !hasProducts && isReadingOrMatching && (\n <div className=\"flex h-40 flex-col items-center justify-center gap-4 px-4\">\n <svg\n className=\"text-text animate-icon-scan\"\n width=\"48\"\n height=\"48\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n >\n <title>Matching icon</title>\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <path d=\"m21 21-4.35-4.35\" />\n </svg>\n </div>\n )}\n <div className=\"max-h-72 overflow-y-auto p-3\">\n {items.map((item) => (\n <div\n key={item.id}\n className=\"flex items-center gap-3 rounded-md p-2 cart-preview-item-real animate-item-slide-in\"\n >\n {item.imageUrl ? (\n <img\n src={item.imageUrl}\n alt={item.name}\n className=\"size-10 shrink-0 rounded-md bg-surface-secondary object-cover\"\n />\n ) : (\n <div className=\"size-10 shrink-0 rounded-md bg-surface-secondary\" />\n )}\n <div className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n <p className=\"m-0 truncate text-sm font-medium text-text\">\n {item.name}\n </p>\n <p className=\"m-0 text-xs text-text-tertiary\">{item.sku}</p>\n <p className=\"m-0 text-xs text-text-tertiary\">\n Quantity: {item.quantity}\n </p>\n </div>\n </div>\n ))}\n\n {isUploading && !parsedContent && items.length === 0 && (\n <div className=\"flex h-40 flex-col items-center justify-center gap-4 px-4\">\n <svg\n className=\"text-text animate-icon-bounce\"\n width=\"48\"\n height=\"48\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n >\n <title>Upload icon</title>\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <polyline points=\"14 2 14 8 20 8\" />\n <line x1=\"12\" y1=\"18\" x2=\"12\" y2=\"12\" />\n <polyline points=\"9 15 12 12 15 15\" />\n </svg>\n </div>\n )}\n\n {items.length < 4 &&\n isBuildingCart &&\n Array.from({ length: 4 - items.length }).map((_, index) => (\n <div\n key={`skeleton-${items.length}-${index}`}\n className=\"flex items-center gap-3 rounded-md p-2 opacity-50\"\n >\n <div className=\"size-10 shrink-0 rounded-md animate-shimmer\" />\n <div className=\"flex min-w-0 flex-1 flex-col gap-1.5\">\n <div className=\"h-2.5 w-4/5 rounded animate-shimmer\" />\n <div className=\"h-2.5 w-2/5 rounded animate-shimmer\" />\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n","import { useEffect, useState } from 'react';\nimport { ADD_TO_CART_TOOL_NAME } from '../components/tools/tool-names.js';\nimport { usePurchaseOrderStore } from '../stores/purchase-order-store.js';\n\nconst TARGET_TOTAL_MS = 3000;\nconst MIN_INTERVAL_MS = 200;\n\nfunction computeInterval(totalItems: number): number {\n if (totalItems <= 0) return MIN_INTERVAL_MS;\n return Math.max(MIN_INTERVAL_MS, Math.round(TARGET_TOTAL_MS / totalItems));\n}\n\ninterface UseProgressiveCartItemsResult {\n revealedCount: number;\n totalItems: number;\n isRevealing: boolean;\n}\n\nexport function useProgressiveCartItems(): UseProgressiveCartItemsResult {\n const toolCalls = usePurchaseOrderStore(\n (state) => state.batchProcessing.toolCalls\n );\n const batchProcessingStatus = usePurchaseOrderStore(\n (state) => state.batchProcessing.status\n );\n\n // Only count when batch processing is complete (i.e., \"building\" step is active)\n const isReady = batchProcessingStatus === 'complete';\n\n // Aggregate items from ALL addToCart tool calls (batches run in parallel)\n const totalItems = toolCalls.reduce((sum, tc) => {\n if (tc.toolName !== ADD_TO_CART_TOOL_NAME) return sum;\n const input = tc.input;\n if (\n input &&\n typeof input === 'object' &&\n 'value' in input &&\n Array.isArray(input.value)\n ) {\n return sum + input.value.length;\n }\n return sum;\n }, 0);\n\n const [revealedCount, setRevealedCount] = useState(0);\n\n useEffect(() => {\n if (!isReady || totalItems === 0 || revealedCount >= totalItems) return;\n\n const interval = computeInterval(totalItems);\n const timer = setTimeout(() => {\n setRevealedCount((prev) => Math.min(prev + 1, totalItems));\n }, interval);\n\n return () => clearTimeout(timer);\n }, [isReady, totalItems, revealedCount]);\n\n return {\n revealedCount,\n totalItems,\n isRevealing: totalItems > 0 && revealedCount < totalItems\n };\n}\n","import { useEffect } from 'react';\n\nimport type { ToolCallResult } from '../lib/batch-processor.js';\nimport { usePurchaseOrderStore } from '../stores/purchase-order-store.js';\n\n/** Interval in ms between revealing each tool call */\nconst REVEAL_INTERVAL_MS = 1000;\n\ninterface UseProgressiveToolCallsResult {\n /** The currently visible tool call (most recently revealed) */\n currentToolCall: ToolCallResult | null;\n /** All tool calls revealed so far */\n visibleToolCalls: ToolCallResult[];\n /** Whether we're still revealing tool calls */\n isRevealing: boolean;\n}\n\n/**\n * Reveals tool calls one at a time.\n * When multiple tool calls come in at once, this ensures each one is displayed\n * sequentially rather than only showing the latest, giving a better sense of\n * progress by not skipping intermediate steps.\n */\nexport function useProgressiveToolCalls(): UseProgressiveToolCallsResult {\n const toolCalls = usePurchaseOrderStore(\n (state) => state.batchProcessing.toolCalls\n );\n const revealedCount = usePurchaseOrderStore(\n (state) => state.batchProcessing.revealedCount\n );\n const incrementRevealed = usePurchaseOrderStore(\n (state) => state.incrementRevealed\n );\n\n useEffect(() => {\n if (revealedCount >= toolCalls.length) {\n return;\n }\n\n const timer = setTimeout(incrementRevealed, REVEAL_INTERVAL_MS);\n return () => clearTimeout(timer);\n }, [toolCalls.length, revealedCount, incrementRevealed]);\n\n const visibleToolCalls = toolCalls.slice(0, revealedCount);\n const currentToolCall = visibleToolCalls[visibleToolCalls.length - 1] ?? null;\n\n return {\n currentToolCall,\n visibleToolCalls,\n isRevealing: revealedCount < toolCalls.length\n };\n}\n","import type { UIMessage } from 'ai';\nimport { ADD_TO_CART_TOOL_NAME } from '../components/tools/tool-names.js';\nimport type { ProcessingStep } from '../types.js';\n\n// Define step order for comparison (only the 3 UI steps)\nconst STEP_ORDER: ProcessingStep[] = ['reading', 'matching', 'building'];\n\nexport type StepStatus = 'pending' | 'active' | 'complete';\n\n// Get status for a processing step (used by both components)\nexport function getProcessingStepStatus(\n stepId: ProcessingStep,\n currentStep: ProcessingStep | null\n): StepStatus {\n if (!currentStep) return 'pending';\n\n const currentIndex = STEP_ORDER.indexOf(currentStep);\n const stepIndex = STEP_ORDER.indexOf(stepId);\n\n if (stepIndex < currentIndex) return 'complete';\n if (stepIndex === currentIndex) return 'active';\n return 'pending';\n}\n\n// Derive current step based on tool calls from the PO agent\n// Returns 'building' once addToCart has been called (actually building the cart)\n// The hook will default to 'reading' and upgrade to 'matching' based on parsedContent\nexport function deriveCurrentStep(\n messages: UIMessage[]\n): ProcessingStep | null {\n if (messages.length === 0) return null;\n\n // Check if addToCart has been called (cart is being built)\n for (const message of messages) {\n if (message.role !== 'assistant' || !message.parts) continue;\n\n for (const part of message.parts) {\n if (\n typeof part === 'object' &&\n part !== null &&\n 'type' in part &&\n typeof part.type === 'string'\n ) {\n const toolName = part.type.startsWith('tool-')\n ? part.type.slice(5)\n : null;\n\n if (toolName === ADD_TO_CART_TOOL_NAME) {\n return 'building';\n }\n }\n }\n }\n\n // Otherwise, let the hook determine the step based on parsedContent\n return null;\n}\n\n// Detect when first assistant response is complete\nexport function isFirstResponseComplete(\n messages: UIMessage[],\n status: string\n): boolean {\n // Check if we have at least 2 messages (user + assistant)\n // AND status is not 'submitted' or 'streaming'\n // Same logic as chat loading indicator\n return (\n messages.length >= 2 && status !== 'submitted' && status !== 'streaming'\n );\n}\n","import { get } from 'lodash';\nimport type { ReactNode } from 'react';\nimport { useProgressiveCartItems } from '../../hooks/use-progressive-cart-items.js';\nimport { useProgressiveToolCalls } from '../../hooks/use-progressive-tool-calls.js';\nimport type { ToolCallResult } from '../../lib/batch-processor.js';\nimport { usePurchaseOrderStore } from '../../stores/purchase-order-store.js';\nimport type { ProcessingStep } from '../../types.js';\nimport { getProcessingStepStatus } from '../../utils/processing-helpers.js';\nimport { CheckIcon } from '../icons/check-icon.js';\nimport { SpinnerIcon } from '../icons/spinner-icon.js';\nimport { parseToolOutput } from '../tools/parse-tool-output.js';\n\ninterface ToolCallRendererContext {\n visibleToolCalls: ToolCallResult[];\n resultCount: number | null;\n}\n\n/**\n * Extracts the result count from a tool call's output.\n * Returns null if the output cannot be parsed.\n * Handles GraphQL response shape: { data: { searchProductsBySku|searchProducts: { items, total } } }\n */\nfunction getResultCount(output: unknown): number | null {\n if (output === undefined) return null;\n\n const parsed = parseToolOutput(output);\n if (parsed === undefined) return null;\n\n const queryResult =\n get(parsed, 'data.searchProductsBySku') ??\n get(parsed, 'data.searchProducts');\n\n return get(queryResult, 'total', 0);\n}\n\n// Registry of custom tool call renderers\n// Tool calls without a renderer here will not be displayed\nconst TOOL_CALL_RENDERERS: Record<\n string,\n (args: Record<string, unknown>, context: ToolCallRendererContext) => ReactNode\n> = {\n searchProductsBySku: (args, { resultCount }) => {\n const sku = (args.sku as string) ?? '';\n if (resultCount === null) return `Looking up SKU ${sku}`;\n return (\n <>\n Looked up SKU {sku}\n <br />\n <span className=\"opacity-60 italic\">\n {resultCount} result{resultCount !== 1 ? 's' : ''}\n </span>\n </>\n );\n },\n searchProducts: (args, { resultCount }) => {\n const terms = (args.terms as string) ?? 'products';\n if (resultCount === null) return `Searching for \"${terms}\"`;\n return (\n <>\n Searched \"{terms}\"\n <br />\n <span className=\"opacity-60 italic\">\n {resultCount} result{resultCount !== 1 ? 's' : ''}\n </span>\n </>\n );\n }\n};\n\nfunction renderToolCall(\n toolCall: ToolCallResult,\n visibleToolCalls: ToolCallResult[]\n): ReactNode | null {\n const renderer = TOOL_CALL_RENDERERS[toolCall.toolName];\n if (!renderer) return null;\n return renderer(toolCall.input as Record<string, unknown>, {\n visibleToolCalls,\n resultCount: getResultCount(toolCall.output)\n });\n}\n\ninterface ProcessingStepsVerticalProps {\n currentStep: ProcessingStep | null;\n}\n\ninterface StepConfig {\n id: ProcessingStep;\n label: string;\n}\n\nconst STEPS: StepConfig[] = [\n { id: 'reading', label: 'Reading document...' },\n { id: 'matching', label: 'Matching products...' },\n { id: 'building', label: 'Building cart...' }\n];\n\nconst statusStyles = {\n pending: {\n row: 'opacity-40',\n icon: 'bg-surface-secondary border-2 border-border-strong'\n },\n active: {\n row: 'opacity-100',\n icon: 'border-2 border-border-focus text-text-invert'\n },\n complete: {\n row: 'opacity-100',\n icon: 'bg-surface border-2 border-success text-success'\n }\n} as const;\n\nexport function ProcessingStepsVertical({\n currentStep\n}: ProcessingStepsVerticalProps) {\n const { currentToolCall, visibleToolCalls } = useProgressiveToolCalls();\n const { revealedCount, totalItems } = useProgressiveCartItems();\n const uploadedFileName = usePurchaseOrderStore(\n (state) => state.parser.uploadedFileName\n );\n\n return (\n <div className=\"flex flex-col gap-6 w-64\">\n <div className=\"flex flex-col gap-6\">\n {STEPS.map((step) => {\n const status = getProcessingStepStatus(step.id, currentStep);\n // Only show tool call if we're in matching step, it's active, and there's a custom renderer\n const fileNameContent =\n step.id === 'reading' &&\n (status === 'active' || status === 'complete') &&\n uploadedFileName\n ? uploadedFileName\n : null;\n const toolCallContent =\n step.id === 'matching' && status === 'active' && currentToolCall\n ? renderToolCall(currentToolCall, visibleToolCalls)\n : null;\n const cartProgressContent =\n step.id === 'building' && status === 'active' && totalItems > 0\n ? revealedCount >= totalItems\n ? `Added ${totalItems} item${totalItems !== 1 ? 's' : ''}`\n : `Adding item ${revealedCount + 1} of ${totalItems}...`\n : null;\n\n return (\n <div\n key={step.id}\n data-testid=\"processing-step-row\"\n data-status={status}\n className={`flex items-center gap-4 transition-opacity duration-300 ${statusStyles[status].row}`}\n >\n <div\n className={`flex items-center justify-center w-8 h-8 rounded-full shrink-0 transition-all duration-300 ${statusStyles[status].icon}${status === 'complete' ? ' animate-step-pulse' : ''}${status === 'active' ? ' bg-surface-invert shadow-step' : ''}`}\n >\n {status === 'complete' && (\n <CheckIcon size={16} title=\"Complete\" />\n )}\n {status === 'active' && <SpinnerIcon size={16} />}\n {status === 'pending' && (\n <div className=\"w-2 h-2 rounded-full bg-border-strong\" />\n )}\n </div>\n <div className=\"flex flex-col min-w-0\">\n <span className=\"text-base font-medium text-text\">\n {step.label}\n </span>\n {fileNameContent && (\n <span\n className={`text-xs truncate ${status === 'active' ? 'animate-text-shimmer' : 'text-text-tertiary animate-ticker-enter'}`}\n >\n {fileNameContent}\n </span>\n )}\n {toolCallContent && currentToolCall && (\n <span\n key={visibleToolCalls.length}\n className=\"text-xs text-text-tertiary animate-ticker-enter\"\n >\n {toolCallContent}\n </span>\n )}\n {cartProgressContent && (\n <span\n key={revealedCount}\n className=\"text-xs text-text-tertiary animate-ticker-enter\"\n >\n {cartProgressContent}\n </span>\n )}\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n","import { useProcessingState } from '../../hooks/use-processing-state.js';\nimport { usePurchaseOrderStore } from '../../stores/purchase-order-store.js';\nimport type { CartItem } from '../../types.js';\nimport { CartPreview } from './cart-preview.js';\nimport { ProcessingStepsVertical } from './processing-steps-vertical.js';\n\nexport interface ProcessingProps {\n cartItems: CartItem[];\n isUploading?: boolean;\n}\n\nexport function Processing({\n cartItems,\n isUploading = false\n}: ProcessingProps) {\n const currentStep = useProcessingState();\n const orderId = usePurchaseOrderStore((state) => state.cartifact.orderId);\n const parsedContent = usePurchaseOrderStore(\n (state) => state.parser.parsedContent\n );\n\n return (\n <div className=\"animate-fade-in-scale flex flex-col w-full max-w-[900px] gap-10 bg-surface rounded-2xl p-10 max-md:p-6 border border-border-strong border-solid\">\n <div className=\"flex w-full justify-center gap-32 max-md:flex-col max-md:gap-8\">\n <div className=\"shrink-0 flex items-center justify-center\">\n <ProcessingStepsVertical currentStep={currentStep} />\n </div>\n <div className=\"shrink-0 flex items-center justify-center min-w-80\">\n <CartPreview\n items={cartItems}\n orderId={orderId}\n parsedContent={parsedContent}\n isUploading={isUploading}\n currentStep={currentStep}\n />\n </div>\n </div>\n </div>\n );\n}\n","import { useCallback } from 'react';\nimport { useFileDrop } from '../../hooks/use-file-drop.js';\nimport { useProcessingState } from '../../hooks/use-processing-state.js';\nimport { ACCEPTED_EXTENSIONS } from '../../lib/file-validation.js';\nimport type { CartItem } from '../../types.js';\nimport { InitialState } from './initial-state.js';\nimport { Processing } from './processing.js';\n\nexport interface UploaderProps {\n onFileUpload: (file: File) => void;\n onSkip: () => void;\n onClearError: () => void;\n cartItems?: CartItem[];\n isUploading?: boolean;\n parserError?: string | null;\n}\n\nexport function Uploader({\n onFileUpload,\n onSkip,\n onClearError,\n cartItems = [],\n isUploading = false,\n parserError = null\n}: UploaderProps) {\n const currentStep = useProcessingState();\n const isProcessing = currentStep !== null;\n\n const fileDrop = useFileDrop({\n onFile: onFileUpload,\n onBeforeValidate: onClearError\n });\n\n // Combine parser error with file validation error\n const displayError = parserError || fileDrop.fileError;\n\n const handleDropZoneClick = useCallback(() => {\n fileDrop.openFilePicker();\n }, [fileDrop.openFilePicker]);\n\n return (\n <div\n className={`upload-step flex flex-col w-full flex-1 min-h-0 ${fileDrop.isDragging ? 'upload-step-dragging' : ''} ${isProcessing ? 'upload-step-processing' : ''}`}\n {...fileDrop.dragProps}\n >\n <div className=\"upload-step-content animate-fade-in-up flex-1 flex items-center justify-center min-h-0 relative\">\n {!isProcessing ? (\n <InitialState\n isDragging={fileDrop.isDragging}\n fileInputRef={fileDrop.fileInputRef}\n acceptedExtensions={ACCEPTED_EXTENSIONS}\n displayError={displayError}\n onDropZoneClick={handleDropZoneClick}\n onFileChange={fileDrop.handleFileChange}\n onSkip={onSkip}\n />\n ) : (\n <Processing cartItems={cartItems} isUploading={isUploading} />\n )}\n </div>\n </div>\n );\n}\n","import type {\n Cart,\n CheckoutAddress,\n CustomerAddress\n} from '../lib/bigcommerce/storefront/types.js';\nimport type { CartItem, ItemWarning, SetCartItem } from '../types.js';\n\nexport function toCheckoutAddress(addr: CustomerAddress): CheckoutAddress {\n return {\n firstName: addr.firstName,\n lastName: addr.lastName,\n address1: addr.address1,\n address2: addr.address2,\n city: addr.city,\n stateOrProvince: addr.stateOrProvince,\n countryCode: addr.countryCode,\n postalCode: addr.postalCode,\n shouldSaveAddress: false\n };\n}\n\nexport function findMatchingCustomerAddress(\n poAddress: CustomerAddress,\n customerAddresses: CustomerAddress[]\n): CustomerAddress | undefined {\n if (!poAddress.address1 || !poAddress.postalCode) return undefined;\n return customerAddresses.find(\n (addr) =>\n addr.address1?.toLowerCase() === poAddress.address1.toLowerCase() &&\n addr.postalCode?.toLowerCase() === poAddress.postalCode?.toLowerCase()\n );\n}\n\nexport function hasPriceMismatch(\n poPriceValue: number | undefined,\n catalogPrice: number\n): boolean {\n return (\n poPriceValue !== undefined && Math.abs(poPriceValue - catalogPrice) > 0.01\n );\n}\n\n// Merge incoming items into existing stored items (for price tracking)\nexport function mergePoCartItems(\n existing: SetCartItem[],\n incoming: SetCartItem[]\n): SetCartItem[] {\n const merged = [...existing];\n for (const newItem of incoming) {\n const existingIndex = merged.findIndex(\n (item) =>\n item.productEntityId === newItem.productEntityId &&\n item.variantEntityId === newItem.variantEntityId\n );\n if (existingIndex >= 0) {\n merged[existingIndex] = newItem; // Replace with updated quantity/price\n } else {\n merged.push(newItem);\n }\n }\n return merged;\n}\n\n// Diff incoming items against current cart to determine adds/updates\nexport interface CartDiff {\n toAdd: SetCartItem[];\n toUpdate: Array<{\n lineItemEntityId: string;\n productEntityId: number;\n variantEntityId?: number;\n newQuantity: number;\n }>;\n}\n\nexport function diffCartItems(\n cartPhysicalItems: Cart['lineItems']['physicalItems'],\n incomingItems: SetCartItem[]\n): CartDiff {\n const toAdd: SetCartItem[] = [];\n const toUpdate: CartDiff['toUpdate'] = [];\n\n for (const incoming of incomingItems) {\n const existingCartItem = cartPhysicalItems.find(\n (ci) =>\n ci.productEntityId === incoming.productEntityId &&\n ci.variantEntityId === incoming.variantEntityId\n );\n\n if (!existingCartItem) {\n toAdd.push(incoming);\n } else if (existingCartItem.quantity !== incoming.quantity) {\n toUpdate.push({\n lineItemEntityId: existingCartItem.entityId,\n productEntityId: incoming.productEntityId,\n variantEntityId: existingCartItem.variantEntityId ?? undefined,\n newQuantity: incoming.quantity\n });\n }\n // If quantity matches, skip (no API call needed)\n }\n\n return { toAdd, toUpdate };\n}\n\n// Build CartItem list from a synced cart\nexport function buildSyncedCartResult(\n syncedCart: Cart,\n mergedItems: SetCartItem[]\n): { cartItems: CartItem[] } {\n const cartItems: CartItem[] = [];\n\n for (const item of syncedCart.lineItems.physicalItems) {\n const storedItem = mergedItems.find(\n (si) =>\n si.productEntityId === item.productEntityId &&\n si.variantEntityId === item.variantEntityId\n );\n\n const poPriceValue = storedItem?.poPriceValue;\n const catalogPrice = item.listPrice.value;\n const mismatch = hasPriceMismatch(poPriceValue, catalogPrice);\n\n cartItems.push({\n id: item.entityId,\n sku: item.sku,\n name: item.name,\n price: catalogPrice,\n imageUrl: item.imageUrl,\n productEntityId: item.productEntityId,\n variantEntityId: item.variantEntityId,\n quantity: item.quantity,\n bcLineItemEntityId: item.entityId,\n poPriceValue,\n poPriceCurrencyCode: storedItem?.poPriceCurrencyCode,\n status: mismatch ? 'price-mismatch' : 'matched'\n } as CartItem);\n }\n\n return { cartItems };\n}\n\nexport function normalizeProductSku(sku: string): string {\n return sku.replace(/-/g, '').toLowerCase();\n}\n\nexport function normalizeProductName(name: string): string {\n return name.toLowerCase();\n}\n\n// Filter out item warnings that are resolved by the given cart items\nexport function filterMatchingWarnings(\n warnings: ItemWarning[],\n cartItems: CartItem[]\n): ItemWarning[] {\n return warnings.filter(\n (w) =>\n !cartItems.some(\n (ci) =>\n (w.productSku &&\n ci.sku &&\n normalizeProductSku(w.productSku) ===\n normalizeProductSku(ci.sku)) ||\n (w.productName &&\n ci.name &&\n normalizeProductName(w.productName) ===\n normalizeProductName(ci.name))\n )\n );\n}\n","import { useCallback, useEffect, useMemo, useRef } from 'react';\nimport {\n CHECKOUT_ADDRESS_ID,\n PO_ADDRESS_ID,\n PO_BILLING_ADDRESS_ID\n} from '../constants.js';\nimport type {\n BigCommerceClient,\n MockBigCommerceClient\n} from '../lib/bigcommerce/index.js';\nimport type {\n Cart,\n CartBatchError,\n CartRedirectUrls,\n CheckoutAddress,\n CustomerAddress\n} from '../lib/bigcommerce/storefront/types.js';\nimport { usePurchaseOrderStore } from '../stores/purchase-order-store.js';\nimport type { POPriceInfo } from '../stores/slices/cartifact-slice.js';\nimport type { CartItem, CheckoutTotals, SetCartItem } from '../types.js';\nimport {\n buildSyncedCartResult,\n diffCartItems,\n filterMatchingWarnings,\n findMatchingCustomerAddress,\n hasPriceMismatch,\n mergePoCartItems,\n toCheckoutAddress\n} from '../utils/cart-sync-helpers.js';\n\nexport interface UseBigCommerceCartOptions {\n client: BigCommerceClient | MockBigCommerceClient;\n onError?: (error: Error) => void;\n}\n\nexport function useBigCommerceCart(options: UseBigCommerceCartOptions) {\n const { client, onError } = options;\n const clientRef = useRef<BigCommerceClient | MockBigCommerceClient>(client);\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n\n // Get cart state from store\n const bcCart = usePurchaseOrderStore((state) => state.bcSession.bcCart);\n const checkout = usePurchaseOrderStore((state) => state.bcSession.checkout);\n const customerInfo = usePurchaseOrderStore(\n (state) => state.customer.customerInfo\n );\n const customerAddresses = usePurchaseOrderStore(\n (state) => state.customer.customerAddresses\n );\n const selectedAddressId = usePurchaseOrderStore(\n (state) => state.ui.selectedAddressId\n );\n const addressUpdateStatus = usePurchaseOrderStore(\n (state) => state.ui.addressUpdateStatus\n );\n const isLoading = usePurchaseOrderStore((state) => state.bcSession.isLoading);\n const productPaths = usePurchaseOrderStore(\n (state) => state.bcSession.productPaths\n );\n const poItemPrices = usePurchaseOrderStore(\n (state) => state.cartifact.poItemPrices\n );\n\n // Get cart actions from store\n const setBcCart = usePurchaseOrderStore((state) => state.setBcCart);\n const setCheckout = usePurchaseOrderStore((state) => state.setCheckout);\n const setSelectedAddressId = usePurchaseOrderStore(\n (state) => state.setSelectedAddressId\n );\n const setAddressUpdateStatus = usePurchaseOrderStore(\n (state) => state.setAddressUpdateStatus\n );\n const setIsLoading = usePurchaseOrderStore((state) => state.setIsLoading);\n\n const setProductPaths = usePurchaseOrderStore(\n (state) => state.setProductPaths\n );\n const shipToAddress = usePurchaseOrderStore(\n (state) => state.cartifact.shipToAddress\n );\n const billingAddress = usePurchaseOrderStore(\n (state) => state.cartifact.billingAddress\n );\n const selectedBillingAddressId = usePurchaseOrderStore(\n (state) => state.ui.selectedBillingAddressId\n );\n const billingAddressUpdateStatus = usePurchaseOrderStore(\n (state) => state.ui.billingAddressUpdateStatus\n );\n const setSelectedBillingAddressId = usePurchaseOrderStore(\n (state) => state.setSelectedBillingAddressId\n );\n const setBillingAddressUpdateStatus = usePurchaseOrderStore(\n (state) => state.setBillingAddressUpdateStatus\n );\n const setItemWarnings = usePurchaseOrderStore(\n (state) => state.setItemWarnings\n );\n\n // Store cart items for price comparison (PO prices) - derived from store\n const storedCartItems = useMemo<SetCartItem[]>(() => {\n if (!bcCart) return [];\n\n return bcCart.lineItems.physicalItems.map((item) => {\n const key = `${item.productEntityId}-${item.variantEntityId}`;\n const priceData = poItemPrices[key] as POPriceInfo | undefined;\n return {\n productEntityId: item.productEntityId,\n variantEntityId: item.variantEntityId ?? undefined,\n quantity: item.quantity,\n poPriceValue: priceData?.poPrice,\n poPriceCurrencyCode: priceData?.poCurrency\n };\n });\n }, [bcCart, poItemPrices]);\n\n // Track which product paths we've already fetched\n const fetchedPathIdsRef = useRef<Set<number>>(new Set());\n\n const updateCheckoutShippingAddress = useCallback(\n async (cart: Cart, address: CheckoutAddress) => {\n if (!clientRef.current) {\n return;\n }\n\n const lineItems = cart.lineItems.physicalItems.map((item) => ({\n lineItemEntityId: item.entityId,\n quantity: item.quantity\n }));\n\n if (lineItems.length === 0) {\n console.warn(\n 'Skipping checkout shipping address update: cart has no physical line items.'\n );\n return;\n }\n\n try {\n const updatedCheckout =\n await clientRef.current.setCheckoutShippingAddress(\n cart.entityId,\n address,\n lineItems\n );\n\n if (updatedCheckout) {\n setCheckout(updatedCheckout);\n }\n } catch (err) {\n console.error('Failed to update checkout shipping address:', err);\n onErrorRef.current?.(\n err instanceof Error\n ? err\n : new Error('Failed to update shipping address')\n );\n }\n },\n [setCheckout]\n );\n\n const updateCheckoutBillingAddress = useCallback(\n async (cart: Cart, address: CheckoutAddress) => {\n if (!clientRef.current) {\n return;\n }\n\n try {\n const updatedCheckout =\n await clientRef.current.setCheckoutBillingAddress(\n cart.entityId,\n address\n );\n\n if (updatedCheckout) {\n setCheckout(updatedCheckout);\n }\n } catch (err) {\n console.error('Failed to update checkout billing address:', err);\n onErrorRef.current?.(\n err instanceof Error\n ? err\n : new Error('Failed to update billing address')\n );\n }\n },\n [setCheckout]\n );\n\n // Fetch product paths for cart items we haven't fetched yet\n useEffect(() => {\n if (!bcCart || !clientRef.current) return;\n\n const productEntityIds = [\n ...new Set(\n bcCart.lineItems.physicalItems.map((item) => item.productEntityId)\n )\n ];\n const missingIds = productEntityIds.filter(\n (id) => !fetchedPathIdsRef.current.has(id)\n );\n if (missingIds.length === 0) return;\n\n // Mark as fetched before the request to prevent duplicate fetches\n for (const id of missingIds) {\n fetchedPathIdsRef.current.add(id);\n }\n\n clientRef.current.getProductPaths(missingIds).then((newPaths) => {\n if (newPaths.size > 0) {\n const newPathsRecord: Record<number, string> = {};\n for (const [id, path] of newPaths) {\n newPathsRecord[id] = path;\n }\n const currentPaths =\n usePurchaseOrderStore.getState().bcSession.productPaths;\n setProductPaths({ ...currentPaths, ...newPathsRecord });\n }\n });\n }, [bcCart, setProductPaths]);\n\n // Track whether checkout addresses have been applied\n const shippingAddressAppliedRef = useRef(false);\n const billingAddressAppliedRef = useRef(false);\n\n // Auto-select shipping address from PO (or default to \"enter at checkout\")\n useEffect(() => {\n if (selectedAddressId) {\n return;\n }\n\n if (!shipToAddress) {\n // No PO address — default to \"enter at checkout\"\n if (customerAddresses.length === 0) {\n setSelectedAddressId(CHECKOUT_ADDRESS_ID);\n }\n return;\n }\n\n let addressId: string;\n\n if (customerAddresses.length > 0) {\n const match = findMatchingCustomerAddress(\n shipToAddress,\n customerAddresses\n );\n addressId = match ? match.id : PO_ADDRESS_ID;\n } else {\n addressId = PO_ADDRESS_ID;\n }\n\n shippingAddressAppliedRef.current = false;\n setSelectedAddressId(addressId);\n }, [\n customerAddresses,\n shipToAddress,\n setSelectedAddressId,\n selectedAddressId\n ]);\n\n // Apply shipping address to checkout once bcCart is ready\n useEffect(() => {\n if (\n shippingAddressAppliedRef.current ||\n !bcCart ||\n !selectedAddressId ||\n selectedAddressId === CHECKOUT_ADDRESS_ID\n ) {\n return;\n }\n\n let checkoutAddress: CustomerAddress | undefined;\n\n if (selectedAddressId === PO_ADDRESS_ID) {\n checkoutAddress = shipToAddress ?? undefined;\n } else {\n checkoutAddress =\n customerAddresses.find((a) => a.id === selectedAddressId) ?? undefined;\n }\n\n if (!checkoutAddress) return;\n\n shippingAddressAppliedRef.current = true;\n void updateCheckoutShippingAddress(\n bcCart,\n toCheckoutAddress(checkoutAddress)\n );\n }, [\n bcCart,\n selectedAddressId,\n customerAddresses,\n shipToAddress,\n updateCheckoutShippingAddress\n ]);\n\n // Auto-select billing address from PO\n useEffect(() => {\n if (!billingAddress || selectedBillingAddressId) {\n return;\n }\n\n let addressId: string;\n\n if (customerAddresses.length > 0) {\n const match = findMatchingCustomerAddress(\n billingAddress,\n customerAddresses\n );\n addressId = match ? match.id : PO_BILLING_ADDRESS_ID;\n } else {\n addressId = PO_BILLING_ADDRESS_ID;\n }\n\n billingAddressAppliedRef.current = false;\n setSelectedBillingAddressId(addressId);\n }, [\n customerAddresses,\n billingAddress,\n setSelectedBillingAddressId,\n selectedBillingAddressId\n ]);\n\n // Apply billing address to checkout once bcCart is ready\n useEffect(() => {\n if (\n billingAddressAppliedRef.current ||\n !bcCart ||\n !selectedBillingAddressId ||\n selectedBillingAddressId === CHECKOUT_ADDRESS_ID\n ) {\n return;\n }\n\n let checkoutAddress: CustomerAddress | undefined;\n\n if (selectedBillingAddressId === PO_BILLING_ADDRESS_ID) {\n checkoutAddress = billingAddress ?? undefined;\n } else {\n checkoutAddress =\n customerAddresses.find((a) => a.id === selectedBillingAddressId) ??\n undefined;\n }\n\n if (!checkoutAddress) return;\n\n billingAddressAppliedRef.current = true;\n void updateCheckoutBillingAddress(\n bcCart,\n toCheckoutAddress(checkoutAddress)\n );\n }, [\n bcCart,\n selectedBillingAddressId,\n customerAddresses,\n billingAddress,\n updateCheckoutBillingAddress\n ]);\n\n // Store timeout IDs for cleanup\n const addressStatusTimeoutRef = useRef<number | undefined>(undefined);\n const billingAddressStatusTimeoutRef = useRef<number | undefined>(undefined);\n\n // Convert BC cart line items to CartItem format with price comparison\n const cartItems = useMemo<CartItem[]>(() => {\n if (!bcCart) return [];\n\n return bcCart.lineItems.physicalItems.map((item) => {\n const storedItem = storedCartItems.find(\n (si) =>\n si.productEntityId === item.productEntityId &&\n si.variantEntityId === item.variantEntityId\n );\n\n const poPriceValue = storedItem?.poPriceValue;\n const catalogPrice = item.listPrice.value;\n const hasMismatch = hasPriceMismatch(poPriceValue, catalogPrice);\n\n return {\n id: item.entityId,\n sku: item.sku ?? '',\n name: item.name,\n path: productPaths[item.productEntityId],\n price: catalogPrice,\n imageUrl: item.imageUrl ?? undefined,\n productEntityId: item.productEntityId,\n variantEntityId: item.variantEntityId ?? undefined,\n quantity: item.quantity,\n bcLineItemEntityId: item.entityId,\n poPriceValue,\n poPriceCurrencyCode: storedItem?.poPriceCurrencyCode,\n catalogPriceCurrencyCode: item.listPrice.currencyCode,\n status: hasMismatch ? 'price-mismatch' : 'matched'\n };\n });\n }, [bcCart, storedCartItems, productPaths]);\n\n // Checkout totals\n const checkoutTotals = useMemo<CheckoutTotals>(\n () => ({\n subtotal: bcCart?.amount?.value ?? 0,\n tax: checkout?.taxTotal?.value ?? null,\n shipping: checkout?.shippingCostTotal?.value ?? null,\n grandTotal: checkout?.grandTotal?.value ?? null\n }),\n [bcCart, checkout]\n );\n\n // Helper: Re-apply shipping address after cart modifications to keep totals fresh\n const reapplyShippingAddressAfterCartChange = useCallback(\n async (updatedCart: Cart | null): Promise<void> => {\n // Only re-apply if we have a cart, selected address, and line items\n if (\n !clientRef.current ||\n !updatedCart ||\n !selectedAddressId ||\n selectedAddressId === CHECKOUT_ADDRESS_ID ||\n updatedCart.lineItems.physicalItems.length === 0\n ) {\n return;\n }\n\n let checkoutAddress: CheckoutAddress | null = null;\n\n if (selectedAddressId === PO_ADDRESS_ID) {\n if (shipToAddress) {\n checkoutAddress = toCheckoutAddress(shipToAddress);\n }\n } else {\n const address = customerAddresses.find(\n (a) => a.id === selectedAddressId\n );\n if (address) {\n checkoutAddress = toCheckoutAddress(address);\n }\n }\n\n if (!checkoutAddress) {\n return;\n }\n\n await updateCheckoutShippingAddress(updatedCart, checkoutAddress);\n },\n [\n selectedAddressId,\n customerAddresses,\n shipToAddress,\n updateCheckoutShippingAddress\n ]\n );\n\n // Create or update cart from cart items (incremental updates)\n const syncCartItems = useCallback(\n async (\n items: SetCartItem[]\n ): Promise<{\n cart: Cart | null;\n cartItems: CartItem[];\n errors: CartBatchError[];\n }> => {\n if (!clientRef.current) return { cart: null, cartItems: [], errors: [] };\n\n // Early return for empty items - don't modify cart\n if (items.length === 0) {\n return { cart: bcCart, cartItems: [], errors: [] };\n }\n\n setIsLoading(true);\n\n try {\n // Merge incoming items with stored items (for price tracking)\n const mergedItems = mergePoCartItems(storedCartItems, items);\n\n // Fetch current cart from BigCommerce\n const existingCart = await clientRef.current.getCart();\n\n let syncedCart: Cart | null = null;\n const allErrors: CartBatchError[] = [];\n\n if (!existingCart) {\n // No cart exists - create fresh cart\n const lineItems = items.map((item) => ({\n productEntityId: item.productEntityId,\n variantEntityId: item.variantEntityId,\n quantity: item.quantity\n }));\n\n const { cart: createdCart, errors: createErrors } =\n await clientRef.current.createCart(lineItems);\n syncedCart = createdCart;\n allErrors.push(...createErrors);\n\n // Store thread ID as cart metafield (fire-and-forget)\n if (syncedCart) {\n const threadId = usePurchaseOrderStore.getState().chat.threadId;\n if (threadId) {\n clientRef.current\n .createCartMetafield(syncedCart.entityId, 'thread_id', threadId)\n .catch((err: unknown) => {\n console.warn(\n '[useBigCommerceCart] Failed to set thread_id metafield:',\n err\n );\n });\n }\n }\n } else {\n // Cart exists and not first call - diff and apply incremental changes\n const { toAdd, toUpdate } = diffCartItems(\n existingCart.lineItems.physicalItems,\n items\n );\n syncedCart = existingCart;\n\n // Add new items in batch\n if (toAdd.length > 0) {\n const lineItems = toAdd.map((item) => ({\n productEntityId: item.productEntityId,\n variantEntityId: item.variantEntityId,\n quantity: item.quantity\n }));\n const { cart: addedCart, errors: addErrors } =\n await clientRef.current.addCartLineItems(\n existingCart.entityId,\n lineItems\n );\n if (addedCart) {\n syncedCart = addedCart;\n }\n allErrors.push(...addErrors);\n }\n\n // Update quantities one by one\n for (const update of toUpdate) {\n syncedCart =\n (await clientRef.current.updateCartLineItem(\n existingCart.entityId,\n update.lineItemEntityId,\n update.newQuantity,\n update.productEntityId,\n update.variantEntityId\n )) ?? syncedCart;\n }\n\n // Re-apply shipping address to refresh totals after cart modifications\n if (toAdd.length > 0 || toUpdate.length > 0) {\n await reapplyShippingAddressAfterCartChange(syncedCart);\n }\n }\n\n setBcCart(syncedCart);\n\n // Sync cart entity ID and PO item prices to Zustand store for persistence\n const store = usePurchaseOrderStore.getState();\n store.setCartEntityId(syncedCart?.entityId ?? null);\n\n // Sync PO item prices to store for persistence\n for (const item of mergedItems) {\n if (\n item.poPriceValue !== undefined &&\n item.poPriceCurrencyCode !== undefined\n ) {\n store.setPoItemPrice(\n item.productEntityId,\n item.variantEntityId,\n item.poPriceValue,\n item.poPriceCurrencyCode\n );\n }\n }\n\n // Clean up stale price entries for items not in the final cart\n // (handles cases where items failed to add or were externally removed)\n if (syncedCart) {\n const finalCartItemKeys = new Set(\n syncedCart.lineItems.physicalItems.map(\n (item) => `${item.productEntityId}-${item.variantEntityId}`\n )\n );\n const storedKeys = Object.keys(store.cartifact.poItemPrices);\n for (const key of storedKeys) {\n if (!finalCartItemKeys.has(key)) {\n const parts = key.split('-');\n const productId = Number(parts[0]);\n const variantId = Number(parts[1]);\n if (!Number.isNaN(productId) && !Number.isNaN(variantId)) {\n store.removePoItemPrice(productId, variantId);\n }\n }\n }\n }\n\n // Set shipping address on newly created checkout if address is selected\n if (syncedCart && !existingCart && selectedAddressId) {\n const address = customerAddresses.find(\n (a) => a.id === selectedAddressId\n );\n if (address && syncedCart.lineItems.physicalItems.length > 0) {\n shippingAddressAppliedRef.current = true;\n await updateCheckoutShippingAddress(\n syncedCart,\n toCheckoutAddress(address)\n );\n }\n }\n\n if (!syncedCart)\n return { cart: null, cartItems: [], errors: allErrors };\n\n const { cartItems: newCartItems } = buildSyncedCartResult(\n syncedCart,\n mergedItems\n );\n\n const currentWarnings =\n usePurchaseOrderStore.getState().cartifact.itemWarnings;\n const filteredWarnings = filterMatchingWarnings(\n currentWarnings,\n newCartItems\n );\n if (filteredWarnings.length !== currentWarnings.length) {\n setItemWarnings(filteredWarnings);\n }\n\n return { cart: syncedCart, cartItems: newCartItems, errors: allErrors };\n } finally {\n setIsLoading(false);\n }\n },\n [\n bcCart,\n storedCartItems,\n selectedAddressId,\n customerAddresses,\n reapplyShippingAddressAfterCartChange,\n setBcCart,\n setIsLoading,\n setItemWarnings,\n updateCheckoutShippingAddress\n ]\n );\n\n // Add items to cart (additive - merges quantities with existing items)\n const addToCart = useCallback(\n async (items: SetCartItem[]): Promise<{ errors: CartBatchError[] }> => {\n if (!clientRef.current) return { errors: [] };\n\n // Merge duplicate items within input (sum quantities)\n const mergedInput: SetCartItem[] = [];\n for (const item of items) {\n const existingIndex = mergedInput.findIndex(\n (i) =>\n i.productEntityId === item.productEntityId &&\n i.variantEntityId === item.variantEntityId\n );\n if (existingIndex >= 0) {\n const existing = mergedInput[existingIndex];\n if (existing) {\n existing.quantity += item.quantity;\n // Keep the price info from the latest item\n if (\n item.poPriceValue !== undefined &&\n item.poPriceCurrencyCode !== undefined\n ) {\n existing.poPriceValue = item.poPriceValue;\n existing.poPriceCurrencyCode = item.poPriceCurrencyCode;\n }\n }\n } else {\n mergedInput.push({ ...item });\n }\n }\n\n // Merge with existing cart items (add quantities for existing items)\n const itemsToSet: SetCartItem[] = [...storedCartItems];\n for (const item of mergedInput) {\n const existingIndex = itemsToSet.findIndex(\n (i) =>\n i.productEntityId === item.productEntityId &&\n i.variantEntityId === item.variantEntityId\n );\n if (existingIndex >= 0) {\n const existing = itemsToSet[existingIndex];\n if (existing) {\n // Add quantities together\n existing.quantity += item.quantity;\n // Update price info if provided\n if (\n item.poPriceValue !== undefined &&\n item.poPriceCurrencyCode !== undefined\n ) {\n existing.poPriceValue = item.poPriceValue;\n existing.poPriceCurrencyCode = item.poPriceCurrencyCode;\n }\n }\n } else {\n // New item\n itemsToSet.push(item);\n }\n }\n\n // Use syncCartItems to apply the changes\n const { errors } = await syncCartItems(itemsToSet);\n return { errors };\n },\n [syncCartItems, storedCartItems]\n );\n\n // Update line item quantity\n const updateLineItemQuantity = useCallback(\n async (\n lineItemId: string,\n quantity: number,\n productEntityId: number,\n variantEntityId?: number\n ): Promise<Cart | null> => {\n if (!clientRef.current || !bcCart?.entityId) {\n return null;\n }\n\n setIsLoading(true);\n try {\n const updatedCart = await clientRef.current.updateCartLineItem(\n bcCart.entityId,\n lineItemId,\n quantity,\n productEntityId,\n variantEntityId\n );\n if (updatedCart) {\n setBcCart(updatedCart);\n // Re-apply shipping address to refresh totals\n await reapplyShippingAddressAfterCartChange(updatedCart);\n }\n return updatedCart;\n } catch (err) {\n onErrorRef.current?.(\n err instanceof Error ? err : new Error('Failed to update quantity')\n );\n return null;\n } finally {\n setIsLoading(false);\n }\n },\n [\n bcCart?.entityId,\n reapplyShippingAddressAfterCartChange,\n setBcCart,\n setIsLoading\n ]\n );\n\n // Remove line item\n const removeLineItem = useCallback(\n async (lineItemId: string): Promise<Cart | null> => {\n if (!clientRef.current || !bcCart?.entityId) {\n return null;\n }\n\n setIsLoading(true);\n\n try {\n const updatedCart = await clientRef.current.deleteCartLineItem(\n bcCart.entityId,\n lineItemId\n );\n\n setBcCart(updatedCart);\n\n // Remove price info for deleted items from the store\n const store = usePurchaseOrderStore.getState();\n if (updatedCart) {\n const remainingItems = updatedCart.lineItems.physicalItems;\n // Find removed items and remove their price info from store\n const removedItems = storedCartItems.filter(\n (stored) =>\n !remainingItems.some(\n (item) =>\n item.productEntityId === stored.productEntityId &&\n item.variantEntityId === stored.variantEntityId\n )\n );\n for (const removed of removedItems) {\n store.removePoItemPrice(\n removed.productEntityId,\n removed.variantEntityId\n );\n }\n // Re-apply shipping address to refresh totals\n await reapplyShippingAddressAfterCartChange(updatedCart);\n } else {\n // Cart is now empty (deleted)\n store.setCartEntityId(null);\n store.clearPoItemPrices();\n // Clear checkout when cart is deleted\n setCheckout(null);\n }\n\n return updatedCart;\n } catch (err) {\n onErrorRef.current?.(\n err instanceof Error ? err : new Error('Failed to remove item')\n );\n return null;\n } finally {\n setIsLoading(false);\n }\n },\n [\n bcCart?.entityId,\n reapplyShippingAddressAfterCartChange,\n setBcCart,\n setIsLoading,\n setCheckout,\n storedCartItems\n ]\n );\n\n // Initiate checkout (create redirect URL)\n const initiateCheckout =\n useCallback(async (): Promise<CartRedirectUrls | null> => {\n if (!clientRef.current) {\n console.error('initiateCheckout: No BigCommerce client');\n return null;\n }\n if (!bcCart?.entityId) {\n console.error('initiateCheckout: No cart entity ID', { bcCart });\n return null;\n }\n\n setIsLoading(true);\n try {\n // Set customer message (orderId) before creating redirect URLs\n // If this fails, continue with checkout anyway\n const threadId = usePurchaseOrderStore.getState().chat.threadId;\n const orderId = usePurchaseOrderStore.getState().cartifact.orderId;\n if (threadId) {\n try {\n await clientRef.current.updateCheckoutCustomerMessage(\n bcCart.entityId,\n {\n purchaseOrderNumber: orderId,\n threadId\n }\n );\n } catch {\n // Ignore errors - checkout should continue\n }\n }\n\n return await clientRef.current.createCartRedirectUrls(bcCart.entityId);\n } catch (err) {\n console.error('initiateCheckout: API error', err);\n onErrorRef.current?.(\n err instanceof Error\n ? err\n : new Error('Failed to create checkout URL')\n );\n // Only clear loading on error; on success, keep loading until redirect\n setIsLoading(false);\n return null;\n }\n }, [bcCart, setIsLoading]);\n\n // Set shipping address on checkout\n const setShippingAddressOnCheckout = useCallback(\n async (addressId: string) => {\n // \"Enter at checkout\" — just update the selection, no API call\n if (addressId === CHECKOUT_ADDRESS_ID) {\n setSelectedAddressId(addressId);\n return;\n }\n\n if (!clientRef.current) {\n console.error('setShippingAddressOnCheckout: No BigCommerce client');\n return;\n }\n if (!bcCart?.entityId) {\n console.error('setShippingAddressOnCheckout: No cart entity ID');\n return;\n }\n\n // Find the address\n let checkoutAddress: CheckoutAddress | null = null;\n\n if (addressId === PO_ADDRESS_ID) {\n if (shipToAddress) {\n checkoutAddress = toCheckoutAddress(shipToAddress);\n }\n } else {\n const address = customerAddresses.find((a) => a.id === addressId);\n if (address) {\n checkoutAddress = toCheckoutAddress(address);\n }\n }\n\n if (!checkoutAddress) {\n console.error(\n 'setShippingAddressOnCheckout: Address not found',\n addressId\n );\n return;\n }\n\n // Build line items array from current cart\n const lineItems = bcCart.lineItems.physicalItems.map((item) => ({\n lineItemEntityId: item.entityId,\n quantity: item.quantity\n }));\n\n if (lineItems.length === 0) {\n console.error('setShippingAddressOnCheckout: No line items in cart');\n return;\n }\n\n shippingAddressAppliedRef.current = true;\n setIsLoading(true);\n setAddressUpdateStatus('updating');\n try {\n // Checkout entityId equals cart entityId\n const updatedCheckout =\n await clientRef.current.setCheckoutShippingAddress(\n bcCart.entityId,\n checkoutAddress,\n lineItems\n );\n\n if (updatedCheckout) {\n setCheckout(updatedCheckout);\n }\n\n // Update selected address ID\n setSelectedAddressId(addressId);\n setAddressUpdateStatus('success');\n\n // Reset to idle after showing success briefly\n if (addressStatusTimeoutRef.current !== undefined) {\n clearTimeout(addressStatusTimeoutRef.current);\n }\n addressStatusTimeoutRef.current = window.setTimeout(() => {\n setAddressUpdateStatus('idle');\n addressStatusTimeoutRef.current = undefined;\n }, 1500);\n } catch (err) {\n console.error('setShippingAddressOnCheckout: API error', err);\n setAddressUpdateStatus('error');\n onErrorRef.current?.(\n err instanceof Error\n ? err\n : new Error('Failed to set shipping address')\n );\n\n // Reset to idle after showing error briefly\n if (addressStatusTimeoutRef.current !== undefined) {\n clearTimeout(addressStatusTimeoutRef.current);\n }\n addressStatusTimeoutRef.current = window.setTimeout(() => {\n setAddressUpdateStatus('idle');\n addressStatusTimeoutRef.current = undefined;\n }, 3000);\n } finally {\n setIsLoading(false);\n }\n },\n [\n bcCart,\n customerAddresses,\n shipToAddress,\n setIsLoading,\n setAddressUpdateStatus,\n setCheckout,\n setSelectedAddressId\n ]\n );\n\n // Set billing address on checkout\n const setBillingAddressOnCheckout = useCallback(\n async (addressId: string) => {\n // \"Enter at checkout\" — just update the selection, no API call\n if (addressId === CHECKOUT_ADDRESS_ID) {\n setSelectedBillingAddressId(addressId);\n return;\n }\n\n if (!clientRef.current) {\n return;\n }\n if (!bcCart?.entityId) {\n return;\n }\n\n let checkoutAddress: CheckoutAddress | null = null;\n\n if (addressId === PO_BILLING_ADDRESS_ID) {\n if (billingAddress) {\n checkoutAddress = toCheckoutAddress(billingAddress);\n }\n } else {\n const address = customerAddresses.find((a) => a.id === addressId);\n if (address) {\n checkoutAddress = toCheckoutAddress(address);\n }\n }\n\n if (!checkoutAddress) {\n return;\n }\n\n billingAddressAppliedRef.current = true;\n setIsLoading(true);\n setBillingAddressUpdateStatus('updating');\n try {\n const updatedCheckout =\n await clientRef.current.setCheckoutBillingAddress(\n bcCart.entityId,\n checkoutAddress\n );\n\n if (updatedCheckout) {\n setCheckout(updatedCheckout);\n }\n\n setSelectedBillingAddressId(addressId);\n setBillingAddressUpdateStatus('success');\n\n if (billingAddressStatusTimeoutRef.current !== undefined) {\n clearTimeout(billingAddressStatusTimeoutRef.current);\n }\n billingAddressStatusTimeoutRef.current = window.setTimeout(() => {\n setBillingAddressUpdateStatus('idle');\n billingAddressStatusTimeoutRef.current = undefined;\n }, 1500);\n } catch (err) {\n setBillingAddressUpdateStatus('error');\n onErrorRef.current?.(\n err instanceof Error\n ? err\n : new Error('Failed to set billing address')\n );\n\n if (billingAddressStatusTimeoutRef.current !== undefined) {\n clearTimeout(billingAddressStatusTimeoutRef.current);\n }\n billingAddressStatusTimeoutRef.current = window.setTimeout(() => {\n setBillingAddressUpdateStatus('idle');\n billingAddressStatusTimeoutRef.current = undefined;\n }, 3000);\n } finally {\n setIsLoading(false);\n }\n },\n [\n bcCart,\n customerAddresses,\n billingAddress,\n setIsLoading,\n setBillingAddressUpdateStatus,\n setCheckout,\n setSelectedBillingAddressId\n ]\n );\n\n // Clear cart\n const clearCart = useCallback(async () => {\n if (clientRef.current && bcCart?.entityId) {\n try {\n await clientRef.current.deleteCart(bcCart.entityId);\n } catch {\n // Ignore errors when clearing\n }\n }\n // Clear any pending timeouts\n if (addressStatusTimeoutRef.current !== undefined) {\n clearTimeout(addressStatusTimeoutRef.current);\n addressStatusTimeoutRef.current = undefined;\n }\n if (billingAddressStatusTimeoutRef.current !== undefined) {\n clearTimeout(billingAddressStatusTimeoutRef.current);\n billingAddressStatusTimeoutRef.current = undefined;\n }\n setBcCart(null);\n setCheckout(null);\n\n // Sync cart state to Zustand store\n const store = usePurchaseOrderStore.getState();\n store.setCartEntityId(null);\n store.clearPoItemPrices();\n }, [bcCart?.entityId, setBcCart, setCheckout]);\n\n return {\n bcCart,\n checkout,\n customerInfo,\n customerAddresses,\n selectedAddressId,\n addressUpdateStatus,\n selectedBillingAddressId,\n billingAddressUpdateStatus,\n isLoading,\n checkoutTotals,\n cartItems,\n addToCart,\n updateLineItemQuantity,\n removeLineItem,\n initiateCheckout,\n setShippingAddressOnCheckout,\n setBillingAddressOnCheckout,\n clearCart,\n setSelectedAddressId,\n setSelectedBillingAddressId\n };\n}\n\nexport type UseBigCommerceCartReturn = ReturnType<typeof useBigCommerceCart>;\n","import { useCallback } from 'react';\nimport { usePurchaseOrderStore } from '../stores/purchase-order-store.js';\nimport type { CartItem, Product } from '../types.js';\nimport type { UseBigCommerceCartReturn } from './use-bigcommerce-cart.js';\n\ninterface UseCartHandlersOptions {\n bcCart: UseBigCommerceCartReturn;\n cartItems: CartItem[];\n onCheckoutInitiated?: (error?: Error) => void;\n onCheckout?: (checkoutUrl: string) => void | Promise<void>;\n}\n\nexport function useCartHandlers({\n bcCart,\n cartItems,\n onCheckoutInitiated,\n onCheckout\n}: UseCartHandlersOptions) {\n const sendMessage = usePurchaseOrderStore((state) => state.sendMessage);\n // Get cart actions from Zustand store\n const handleCheckout = useCallback(async () => {\n if (!bcCart.bcCart?.entityId) {\n console.error('No cart available for checkout');\n return;\n }\n\n const redirectUrls = await bcCart.initiateCheckout();\n if (redirectUrls?.redirectedCheckoutUrl) {\n onCheckoutInitiated?.();\n if (onCheckout) {\n await onCheckout(redirectUrls.redirectedCheckoutUrl);\n } else {\n window.location.href = redirectUrls.redirectedCheckoutUrl;\n }\n } else {\n const error = new Error('Failed to get checkout redirect URL');\n console.error(error.message, { redirectUrls, bcCart: bcCart.bcCart });\n onCheckoutInitiated?.(error);\n }\n }, [bcCart, onCheckoutInitiated, onCheckout]);\n\n const handleUpdateQuantity = useCallback(\n async (itemId: string, quantity: number) => {\n const item = cartItems.find((i) => i.id === itemId);\n if (!item?.productEntityId || !item?.variantEntityId) return;\n\n await bcCart.updateLineItemQuantity(\n itemId,\n quantity,\n item.productEntityId,\n item.variantEntityId\n );\n },\n [cartItems, bcCart]\n );\n\n const handleRemoveItem = useCallback(\n async (itemId: string) => {\n await bcCart.removeLineItem(itemId);\n },\n [bcCart]\n );\n\n const handleAddToCartFromSuggestion = useCallback(\n async (\n product: Product,\n quantity: number,\n selectedVariantEntityId?: number\n ): Promise<boolean> => {\n const { productEntityId } = product;\n // Use the selected variant if provided, otherwise fall back to product's default variant\n const variantEntityId =\n selectedVariantEntityId ?? product.variantEntityId;\n\n if (!productEntityId || !variantEntityId) {\n console.error('Cannot add to cart: missing entity IDs', product);\n return false;\n }\n\n const actualQuantity =\n product.availableQuantity !== undefined && product.availableQuantity > 0\n ? Math.min(quantity, product.availableQuantity)\n : quantity;\n\n try {\n await bcCart.addToCart([\n {\n productEntityId,\n variantEntityId: variantEntityId,\n quantity: actualQuantity\n }\n ]);\n\n return true;\n } catch (err) {\n console.error('Failed to add to cart:', err);\n return false;\n }\n },\n [bcCart]\n );\n\n const handleSuggestAlternatives = useCallback(\n (itemName: string, sku?: string) => {\n const message = sku\n ? `Suggest alternatives for \"${itemName}\" (SKU: ${sku})`\n : `Suggest alternatives for \"${itemName}\"`;\n sendMessage(message);\n },\n [sendMessage]\n );\n\n const handleShowMoreLikeThis = useCallback(\n (itemName: string, sku?: string) => {\n const message = sku\n ? `Show more products like \"${itemName}\" (SKU: ${sku})`\n : `Show more products like \"${itemName}\"`;\n sendMessage(message);\n },\n [sendMessage]\n );\n\n return {\n handleCheckout,\n handleUpdateQuantity,\n handleRemoveItem,\n handleAddToCartFromSuggestion,\n handleSuggestAlternatives,\n handleShowMoreLikeThis\n };\n}\n","/**\n * Core batch processing logic with dependency injection.\n *\n * This module contains the pure batch processing functions that can be shared\n * between the production app and evals. It has no React, Zustand, or BigCommerce\n * dependencies - those are injected via callbacks.\n */\n\nimport pMap from 'p-map';\nimport {\n ADD_PROCESSING_FAILURES_TOOL_NAME,\n ADD_TO_CART_TOOL_NAME,\n GET_PURCHASE_ORDER_DATA_TOOL_NAME,\n SET_PO_METADATA_TOOL_NAME\n} from '../components/tools/tool-names.js';\nimport { CLIENT_TOOL_RESPONSE_MESSAGE } from '../constants.js';\nimport { parseSSEStream } from './sse.js';\nimport { createAgentThread, sendAgentMessage } from './takeshape-api.js';\nimport type {\n AddToCartItem,\n AgentMessage,\n BatchProcessingCoreResult,\n BatchProcessorCallbacks,\n BatchResult,\n MergedClientToolCalls,\n ProcessingFailure,\n TakeShapeConfig,\n ToolCallResult\n} from './types.js';\n\nexport const BATCH_CLIENT_TOOLS = new Set([\n ADD_TO_CART_TOOL_NAME,\n GET_PURCHASE_ORDER_DATA_TOOL_NAME,\n SET_PO_METADATA_TOOL_NAME,\n ADD_PROCESSING_FAILURES_TOOL_NAME\n]);\n\nconst NO_OUTPUT_ERROR = 'did not produce any output';\n\n/**\n * Formats tool calls into a readable summary.\n */\nfunction formatToolCallsSummary(toolCalls: ToolCallResult[]): string {\n const clientToolNames = toolCalls\n .filter((tc) => BATCH_CLIENT_TOOLS.has(tc.toolName))\n .map((tc) => tc.toolName);\n\n if (clientToolNames.length === 0) return '';\n\n const uniqueNames = [...new Set(clientToolNames)];\n return `\\n\\nTools called: ${uniqueNames.join(', ')}`;\n}\n\n/**\n * Processes a single batch by sending it to the agent and handling tool calls.\n * Loops until the agent completes without pending tool calls.\n */\nexport async function processBatch(\n takeshapeConfig: TakeShapeConfig,\n agentName: string,\n threadId: string,\n batchContent: string,\n batchIndex: number,\n callbacks?: BatchProcessorCallbacks\n): Promise<BatchResult> {\n const allToolCalls: ToolCallResult[] = [];\n const allTextParts: string[] = [];\n const accumulatedMessages: string[] = [];\n const pendingClientToolCalls: ToolCallResult[] = [];\n\n let messages: AgentMessage[] = [\n {\n role: 'user',\n parts: [{ type: 'text', text: batchContent }]\n }\n ];\n\n const maxIterations = 20;\n let iterations = 0;\n\n while (iterations < maxIterations) {\n iterations++;\n\n const response = await sendAgentMessage(\n takeshapeConfig,\n agentName,\n threadId,\n messages\n );\n const streamResult = await parseSSEStream(response, {\n onToolCall: callbacks?.onToolCall\n });\n\n allTextParts.push(...streamResult.textParts);\n allToolCalls.push(...streamResult.toolCalls);\n if (streamResult.finalMessage) {\n accumulatedMessages.push(streamResult.finalMessage);\n }\n\n // Handle \"did not produce any output\" error gracefully\n if (streamResult.errorMessage?.includes(NO_OUTPUT_ERROR)) {\n callbacks?.logger?.debug(\n `Batch ${batchIndex}: Exiting loop - no output error`\n );\n break;\n }\n\n // Check for other errors\n if (streamResult.errorMessage) {\n callbacks?.logger?.debug(\n `Batch ${batchIndex}: Exiting loop - error: ${streamResult.errorMessage}`\n );\n return {\n batchIndex,\n threadId,\n output: '',\n toolCalls: allToolCalls,\n pendingClientToolCalls,\n error: streamResult.errorMessage\n };\n }\n\n // Find tool calls that need client-side execution\n const clientToolCalls = streamResult.toolCalls.filter(\n (tc) =>\n BATCH_CLIENT_TOOLS.has(tc.toolName) ||\n !streamResult.serverHandledToolCallIds.has(tc.toolCallId)\n );\n\n // Collect client tool calls for deferred execution\n for (const tc of clientToolCalls) {\n if (BATCH_CLIENT_TOOLS.has(tc.toolName)) {\n pendingClientToolCalls.push(tc);\n }\n }\n\n // If no client-side tool calls need response, we're done\n if (clientToolCalls.length === 0) {\n callbacks?.logger?.debug(\n `Batch ${batchIndex}: Exiting loop - no client tool calls to respond to`\n );\n break;\n }\n\n // Check for token limit - agent ran out of tokens before completing\n if (\n streamResult.finishReason === 'length' ||\n streamResult.finishReason === 'max_tokens'\n ) {\n callbacks?.logger?.debug(\n `Batch ${batchIndex}: Exiting loop - hit token limit (${streamResult.finishReason})`\n );\n return {\n batchIndex,\n threadId,\n output: allTextParts.join(''),\n toolCalls: allToolCalls,\n pendingClientToolCalls,\n error: `Agent hit token limit (${streamResult.finishReason}) before completing batch`\n };\n }\n\n // Exit when agent finishes normally\n if (streamResult.finishReason === 'stop') {\n callbacks?.logger?.debug(\n `Batch ${batchIndex}: Exiting loop - agent finished`\n );\n break;\n }\n\n // Build tool result parts for next iteration\n const toolResultParts = clientToolCalls.map((tc) => ({\n type: `tool-${tc.toolName}`,\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n state: 'output-available',\n input: tc.input,\n output: 'Success'\n }));\n\n // Send tool results and trigger continuation\n messages = [\n {\n role: 'assistant',\n parts: toolResultParts\n },\n {\n role: 'user',\n parts: [{ type: 'text', text: CLIENT_TOOL_RESPONSE_MESSAGE }]\n }\n ];\n }\n\n // Check if we hit the iteration limit\n if (iterations >= maxIterations) {\n callbacks?.logger?.debug(\n `Batch ${batchIndex}: WARNING - Hit max iterations limit (${maxIterations})`\n );\n }\n\n const textOutput =\n accumulatedMessages.length > 0\n ? accumulatedMessages.join('\\n\\n')\n : allTextParts.join('');\n const toolCallsSummary = formatToolCallsSummary(allToolCalls);\n const output = textOutput + toolCallsSummary;\n\n // Log per-batch results\n const addToCartCalls = pendingClientToolCalls.filter(\n (tc) => tc.toolName === ADD_TO_CART_TOOL_NAME\n );\n const addToCartItemCount = addToCartCalls.reduce((sum, tc) => {\n const items = (tc.input as { value?: unknown[] })?.value;\n return sum + (items?.length ?? 0);\n }, 0);\n const failureCalls = pendingClientToolCalls.filter(\n (tc) => tc.toolName === ADD_PROCESSING_FAILURES_TOOL_NAME\n );\n const failureCount = failureCalls.reduce((sum, tc) => {\n const failures = (tc.input as { processingFailures?: unknown[] })\n ?.processingFailures;\n return sum + (failures?.length ?? 0);\n }, 0);\n callbacks?.logger?.debug(\n `Batch ${batchIndex}: ${iterations} iteration(s), ${pendingClientToolCalls.length} client tool call(s), ${addToCartItemCount} addToCart item(s), ${failureCount} failure(s)`\n );\n if (output) {\n callbacks?.logger?.debug(`Batch ${batchIndex} output: ${output}`);\n }\n\n return {\n batchIndex,\n threadId,\n output,\n toolCalls: allToolCalls,\n pendingClientToolCalls\n };\n}\n\n/**\n * Processes multiple batches in parallel.\n * Each batch gets its own thread and runs independently.\n * Returns results with pending client tool calls - does NOT execute them.\n */\nexport async function processAllBatches(\n takeshapeConfig: TakeShapeConfig,\n agentName: string,\n batches: string[],\n callbacks?: BatchProcessorCallbacks\n): Promise<BatchProcessingCoreResult> {\n if (batches.length === 0) {\n return { results: [], hasErrors: false };\n }\n\n // Create threads for all batches in parallel\n const threadResults = await Promise.allSettled(\n batches.map(() => createAgentThread(takeshapeConfig, agentName))\n );\n\n const threadIds: (string | null)[] = threadResults.map((result, index) => {\n if (result.status === 'fulfilled') {\n callbacks?.onThreadCreated?.(index, result.value);\n return result.value;\n }\n const errorMsg =\n result.reason instanceof Error\n ? result.reason.message\n : 'Failed to create thread';\n callbacks?.logger?.error(\n `Failed to create thread for batch ${index}`,\n result.reason\n );\n callbacks?.onError?.(index, errorMsg);\n return null;\n });\n\n // Process all batches with limited concurrency (skip failed thread creations)\n const results = await pMap(\n batches,\n async (batch: string, index: number) => {\n const threadId = threadIds[index];\n if (!threadId) {\n const errorResult: BatchResult = {\n batchIndex: index,\n threadId: '',\n output: '',\n toolCalls: [],\n pendingClientToolCalls: [],\n error: 'Failed to create thread'\n };\n return errorResult;\n }\n\n try {\n const result = await processBatch(\n takeshapeConfig,\n agentName,\n threadId,\n batch,\n index,\n callbacks\n );\n callbacks?.onBatchComplete?.(result);\n return result;\n } catch (err) {\n const errorMessage =\n err instanceof Error ? err.message : 'Unknown error';\n callbacks?.onError?.(index, errorMessage);\n const errorResult: BatchResult = {\n batchIndex: index,\n threadId,\n output: '',\n toolCalls: [],\n pendingClientToolCalls: [],\n error: errorMessage\n };\n return errorResult;\n }\n },\n { concurrency: 10 }\n );\n const hasErrors = results.some((r) => r.error !== undefined);\n\n return { results, hasErrors };\n}\n\n/**\n * Merges client tool calls collected from all batch results.\n * Does NOT execute them - just aggregates for the caller to handle.\n *\n * Merge strategy:\n * - addToCart: concatenate all items\n * - setPoMetadata: last wins\n * - addProcessingFailures: concatenate all failures\n */\nexport function mergeClientToolCalls(\n results: BatchResult[]\n): MergedClientToolCalls {\n const addToCartItems: AddToCartItem[] = [];\n let setPoMetadataArgs: unknown | null = null;\n const processingFailures: ProcessingFailure[] = [];\n\n for (const result of results) {\n // Skip batches that failed\n if (result.error) {\n continue;\n }\n\n let batchAddToCartCount = 0;\n let batchFailureCount = 0;\n\n for (const tc of result.pendingClientToolCalls) {\n if (tc.toolName === ADD_TO_CART_TOOL_NAME) {\n const args = tc.input as { value?: AddToCartItem[] };\n if (args.value) {\n batchAddToCartCount += args.value.length;\n addToCartItems.push(...args.value);\n }\n } else if (tc.toolName === SET_PO_METADATA_TOOL_NAME) {\n setPoMetadataArgs = tc.input;\n } else if (tc.toolName === ADD_PROCESSING_FAILURES_TOOL_NAME) {\n const args = tc.input as { processingFailures?: ProcessingFailure[] };\n if (args.processingFailures) {\n batchFailureCount += args.processingFailures.length;\n processingFailures.push(...args.processingFailures);\n }\n }\n }\n }\n return { addToCartItems, setPoMetadataArgs, processingFailures };\n}\n\n/**\n * Formats processing failures into a human-readable string.\n */\nexport function formatProcessingFailures(\n failures: ProcessingFailure[]\n): string {\n if (failures.length === 0) {\n return '';\n }\n\n const lines = [\n '',\n '---',\n '## Processing Failures',\n '',\n 'The following line items could not be processed:',\n ''\n ];\n\n for (const f of failures) {\n lines.push(`- **\"${f.lineItemString}\"**: ${f.explanation}`);\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","/**\n * Batch processor for the production app.\n *\n * This module wraps the core batch processing logic with app-specific\n * integrations: Zustand store for state management and BigCommerce cart\n * for tool execution.\n */\n\nimport type { UseBigCommerceCartReturn } from '../hooks/use-bigcommerce-cart.js';\nimport type { CartBatchError } from '../lib/bigcommerce/storefront/types.js';\nimport { usePurchaseOrderStore } from '../stores/purchase-order-store.js';\nimport type { SetPoMetadataInput } from '../types.js';\nimport {\n formatProcessingFailures,\n mergeClientToolCalls,\n processAllBatches as processAllBatchesCore\n} from './batch-processor-core.js';\nimport type {\n BatchProcessingCoreResult,\n BatchResult,\n TakeShapeConfig,\n ToolCallResult\n} from './types.js';\n\n// Re-export core functions that don't need wrapping\nexport { processBatch } from './batch-processor-core.js';\nexport type {\n BatchResult,\n ToolCallResult\n} from './types.js';\n\nexport interface BatchProcessorConfig {\n takeshapeConfig: TakeShapeConfig;\n agentName: string;\n bcCart: UseBigCommerceCartReturn;\n}\n\nexport interface BatchProcessingResult {\n results: BatchResult[];\n processingFailuresString: string;\n hasErrors: boolean;\n}\n\n/**\n * Format cart batch errors for LLM output.\n * Shows the input items and error message for each failed batch.\n */\nfunction formatCartBatchErrors(errors: CartBatchError[]): string {\n if (errors.length === 0) return '';\n\n const lines = ['---', '## Failed Tool Calls', ''];\n\n for (const error of errors) {\n lines.push('### addToCart');\n lines.push('**Input:**');\n for (const item of error.items) {\n const variant = item.variantEntityId\n ? `, variantEntityId: ${item.variantEntityId}`\n : '';\n lines.push(\n `- productEntityId: ${item.productEntityId}${variant}, quantity: ${item.quantity}`\n );\n }\n lines.push('');\n lines.push(`**Error:** ${error.message}`);\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Executes merged client tool calls directly against cart/store.\n */\nasync function executeMergedClientToolCalls(\n results: BatchResult[],\n bcCart: UseBigCommerceCartReturn\n): Promise<string> {\n const merged = mergeClientToolCalls(results);\n\n // Execute setPoMetadata first (if any) - last wins\n // Call store method directly instead of going through tool handler\n if (merged.setPoMetadataArgs) {\n const args = merged.setPoMetadataArgs as SetPoMetadataInput;\n usePurchaseOrderStore.getState().applyPoMetadata(args.poMetadata);\n }\n\n // Execute addToCart with all merged items\n // Call bcCart.addToCart directly - returns { errors } instead of throwing\n let cartErrors: CartBatchError[] = [];\n if (merged.addToCartItems.length > 0) {\n const { errors } = await bcCart.addToCart(merged.addToCartItems);\n cartErrors = errors;\n\n if (errors.length > 0) {\n console.error('Failed to add some items to cart:', errors);\n }\n }\n\n // Format and return processing failures string (including cart errors)\n const processingFailuresString = formatProcessingFailures(\n merged.processingFailures\n );\n if (cartErrors.length > 0) {\n const cartErrorString = formatCartBatchErrors(cartErrors);\n return processingFailuresString\n ? `${processingFailuresString}\\n${cartErrorString}`\n : cartErrorString;\n }\n return processingFailuresString;\n}\n\n/**\n * Processes multiple batches in parallel with app integrations.\n * Each batch gets its own thread and runs independently.\n * Client tool calls are collected and executed after all batches complete.\n */\nexport async function processAllBatches(\n config: BatchProcessorConfig,\n batches: string[]\n): Promise<BatchProcessingResult> {\n if (batches.length === 0) {\n return { results: [], processingFailuresString: '', hasErrors: false };\n }\n\n // Process batches using core logic with Zustand callbacks\n const coreResult: BatchProcessingCoreResult = await processAllBatchesCore(\n config.takeshapeConfig,\n config.agentName,\n batches,\n {\n onToolCall: (tc: ToolCallResult) => {\n usePurchaseOrderStore.getState().addToolCall(tc);\n },\n onThreadCreated: (_batchIndex: number, threadId: string) => {\n usePurchaseOrderStore.getState().addBatchThreadId(threadId);\n }\n }\n );\n\n // Execute collected client tool calls after all batches complete\n let processingFailuresString = '';\n if (config.bcCart) {\n processingFailuresString = await executeMergedClientToolCalls(\n coreResult.results,\n config.bcCart\n );\n }\n\n return {\n results: coreResult.results,\n processingFailuresString,\n hasErrors: coreResult.hasErrors\n };\n}\n","import { useCallback } from 'react';\nimport {\n type BatchProcessingResult,\n type BatchProcessorConfig,\n processAllBatches\n} from '../lib/batch-processor.js';\nimport { usePurchaseOrderStore } from '../stores/purchase-order-store.js';\nimport type { UseBigCommerceCartReturn } from './use-bigcommerce-cart.js';\n\nexport interface UseBatchProcessorOptions {\n bcCart: UseBigCommerceCartReturn;\n}\n\nexport interface UseBatchProcessorReturn {\n processBatches: (batches: string[]) => Promise<BatchProcessingResult>;\n reset: () => void;\n}\n\nexport function useBatchProcessor(\n options: UseBatchProcessorOptions\n): UseBatchProcessorReturn {\n const { bcCart } = options;\n\n const takeshapeConfig = usePurchaseOrderStore(\n (state) => state.takeshapeConfig\n );\n const setBatchProcessingStatus = usePurchaseOrderStore(\n (state) => state.setBatchProcessingStatus\n );\n const setBatchProcessingError = usePurchaseOrderStore(\n (state) => state.setBatchProcessingError\n );\n const setBatchProcessingResults = usePurchaseOrderStore(\n (state) => state.setBatchProcessingResults\n );\n const resetBatchProcessing = usePurchaseOrderStore(\n (state) => state.resetBatchProcessing\n );\n const sendMessage = usePurchaseOrderStore((state) => state.sendMessage);\n\n const processBatches = useCallback(\n async (batches: string[]): Promise<BatchProcessingResult> => {\n if (batches.length === 0) {\n return { results: [], processingFailuresString: '', hasErrors: false };\n }\n\n setBatchProcessingStatus('processing');\n setBatchProcessingError(null);\n\n const config: BatchProcessorConfig = {\n takeshapeConfig,\n agentName: 'batchProcessor',\n bcCart\n };\n\n try {\n const result = await processAllBatches(config, batches);\n\n setBatchProcessingResults(\n result.results,\n result.processingFailuresString\n );\n\n if (result.hasErrors) {\n setBatchProcessingStatus('error');\n const failedCount = result.results.filter((r) => r.error).length;\n setBatchProcessingError(\n `${failedCount} of ${batches.length} batches failed to process`\n );\n } else {\n setBatchProcessingStatus('complete');\n }\n\n // Send message with failures or success\n if (result.processingFailuresString) {\n sendMessage(result.processingFailuresString);\n } else {\n sendMessage('No failures detected.');\n }\n\n return result;\n } catch (err) {\n const errorMessage =\n err instanceof Error ? err.message : 'Unknown error';\n setBatchProcessingError(errorMessage);\n setBatchProcessingStatus('error');\n throw err;\n }\n },\n [\n takeshapeConfig,\n bcCart,\n setBatchProcessingStatus,\n setBatchProcessingError,\n setBatchProcessingResults,\n sendMessage\n ]\n );\n\n return {\n processBatches,\n reset: resetBatchProcessing\n };\n}\n","import { useEffect, useRef } from 'react';\nimport type { ChatPanelRef } from '../components/chat-view/chat-panel/chat-panel.js';\nimport { usePurchaseOrderStore } from '../stores/purchase-order-store.js';\nimport type { AppState } from '../types.js';\nimport { useBatchProcessor } from './use-batch-processor.js';\nimport type { UseBigCommerceCartReturn } from './use-bigcommerce-cart.js';\nimport type { useDocumentParser } from './use-document-parser.js';\n\ninterface UseChatOrchestrationOptions {\n appState: AppState;\n setAppState: (value: AppState) => void;\n parser: ReturnType<typeof useDocumentParser>;\n firstResponseComplete: boolean;\n chatPanelRef: React.RefObject<ChatPanelRef | null>;\n bcCart: UseBigCommerceCartReturn;\n}\n\nexport function useChatOrchestration({\n appState,\n setAppState,\n parser,\n firstResponseComplete,\n chatPanelRef,\n bcCart\n}: UseChatOrchestrationOptions) {\n const hasSentToPOAgent = useRef(false);\n const hasProcessedDocument = usePurchaseOrderStore(\n (state) => state.parser.hasProcessedDocument\n );\n const setHasProcessedDocument = usePurchaseOrderStore(\n (state) => state.setHasProcessedDocument\n );\n const { processBatches } = useBatchProcessor({ bcCart });\n\n // When parser finishes streaming, send the parsed content to PO agent\n useEffect(() => {\n if (\n appState === 'processing' &&\n parser.parserStatus !== 'streaming' &&\n parser.parserStatus !== 'submitted' &&\n parser.parsedContent &&\n parser.parserMessages.length > 0 &&\n !hasSentToPOAgent.current\n ) {\n hasSentToPOAgent.current = true;\n setHasProcessedDocument(true);\n processBatches(parser.parsedContent);\n }\n }, [\n parser.parserStatus,\n parser.parsedContent,\n appState,\n parser.parserMessages.length,\n setHasProcessedDocument,\n processBatches\n ]);\n\n // Auto-transition from processing to ready when first response completes\n useEffect(() => {\n if (appState === 'processing' && firstResponseComplete) {\n const timer = setTimeout(() => {\n setAppState('chatting');\n requestAnimationFrame(() => {\n chatPanelRef.current?.scrollToBottom();\n });\n }, 500);\n return () => clearTimeout(timer);\n }\n }, [appState, firstResponseComplete, setAppState, chatPanelRef]);\n\n const reset = () => {\n hasSentToPOAgent.current = false;\n setHasProcessedDocument(false);\n };\n\n return {\n hasProcessedDocument,\n reset\n };\n}\n","const DOCUMENT_PARSER_BATCH_DELIMITER = '<!-- BATCH -->';\n\nexport function splitDocumentParserOutput(input: string): string[] {\n return input\n .split(DOCUMENT_PARSER_BATCH_DELIMITER)\n .map((s) => s.trim())\n .filter(Boolean);\n}\n","export function readFileAsText(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = () => reject(new Error('Failed to read file'));\n reader.readAsText(file);\n });\n}\n\nexport function readFileAsDataUrl(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = () => reject(new Error('Failed to read file'));\n reader.readAsDataURL(file);\n });\n}\n","const SPREADSHEET_TYPES = new Set([\n 'application/vnd.ms-excel',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'\n]);\n\nexport function isSpreadsheet(mimeType: string): boolean {\n return SPREADSHEET_TYPES.has(mimeType);\n}\n\nexport async function convertSpreadsheetToCsv(file: File): Promise<string> {\n const xlsx = await import('xlsx');\n const buffer = await file.arrayBuffer();\n const workbook = xlsx.read(buffer, { type: 'array' });\n\n if (workbook.SheetNames.length === 0) {\n throw new Error('Workbook contains no sheets');\n }\n\n const allRows: Record<string, unknown>[] = [];\n for (const name of workbook.SheetNames) {\n const sheet = workbook.Sheets[name]!;\n const rows = xlsx.utils.sheet_to_json<Record<string, unknown>>(sheet);\n allRows.push(...rows);\n }\n\n const merged = xlsx.utils.json_to_sheet(allRows);\n return xlsx.utils.sheet_to_csv(merged);\n}\n","const PDF_HEADER = '%PDF-';\nconst PDF_EOF = '%%EOF';\nconst MIN_PDF_SIZE = 256;\n\nexport type PdfValidationResult =\n | { valid: true }\n | { valid: false; reason: 'invalid' | 'password-protected' };\n\nfunction readFileAsArrayBuffer(file: Blob): Promise<ArrayBuffer> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as ArrayBuffer);\n reader.onerror = () => reject(reader.error);\n reader.readAsArrayBuffer(file);\n });\n}\n\nexport async function validatePdf(file: File): Promise<PdfValidationResult> {\n if (file.size < MIN_PDF_SIZE) return { valid: false, reason: 'invalid' };\n\n let buffer: Uint8Array;\n try {\n buffer = new Uint8Array(await readFileAsArrayBuffer(file));\n } catch {\n return { valid: false, reason: 'invalid' };\n }\n\n const headerStr = String.fromCharCode(...buffer.slice(0, 5));\n if (!headerStr.startsWith(PDF_HEADER)) {\n return { valid: false, reason: 'invalid' };\n }\n\n const tailSize = Math.min(1024, buffer.length);\n const tailStr = String.fromCharCode(\n ...buffer.slice(buffer.length - tailSize)\n );\n if (!tailStr.includes(PDF_EOF)) {\n return { valid: false, reason: 'invalid' };\n }\n\n // Check for /Encrypt in the trailer dictionary (always near end of file)\n const trailerStart = Math.max(0, buffer.length - 8192);\n const trailerText = new TextDecoder().decode(buffer.slice(trailerStart));\n const start = trailerText.lastIndexOf('<<');\n const end = trailerText.lastIndexOf('>>');\n if (\n start !== -1 &&\n end !== -1 &&\n start < end &&\n trailerText.substring(start, end).includes('/Encrypt')\n ) {\n // The PDF is encrypted, but it may still be viewable without a password\n // (e.g., owner-password-only restrictions with an empty user password).\n // Use pdf.js to attempt opening — it will throw PasswordException only\n // when a user password is actually required.\n try {\n // Import the worker module first and register it on globalThis so pdf.js\n // can find it via its #mainThreadWorkerMessageHandler check. Without this,\n // pdf.js fails in the browser because GlobalWorkerOptions.workerSrc is only\n // auto-configured in Node.js, and the @vite-ignore on pdf.js's internal\n // worker import prevents Vite from bundling the worker file.\n const pdfjsWorker = await import(\n // @ts-expect-error -- no type declarations for the worker bundle\n 'pdfjs-dist/legacy/build/pdf.worker.mjs'\n );\n (globalThis as Record<string, unknown>).pdfjsWorker = pdfjsWorker;\n\n const { getDocument } = await import('pdfjs-dist/legacy/build/pdf.mjs');\n const loadingTask = getDocument({\n data: buffer,\n isEvalSupported: false\n });\n try {\n const doc = await loadingTask.promise;\n doc.destroy();\n } catch (e) {\n await loadingTask.destroy();\n if (e instanceof Error && e.name === 'PasswordException') {\n return { valid: false, reason: 'password-protected' };\n }\n return { valid: false, reason: 'invalid' };\n }\n } catch (e) {\n // Import or worker setup failed\n console.error('PDF validation error:', e);\n return { valid: false, reason: 'invalid' };\n }\n }\n\n return { valid: true };\n}\n","import type { useChat } from '@ai-sdk/react';\nimport { useCallback, useState } from 'react';\nimport { readFileAsDataUrl, readFileAsText } from '../lib/read-file.js';\nimport { convertSpreadsheetToCsv, isSpreadsheet } from '../lib/spreadsheet.js';\nimport { validatePdf } from '../lib/validate-pdf.js';\nimport { usePurchaseOrderStore } from '../stores/purchase-order-store.js';\n\nconst TEXT_BASED_TYPES = new Set([\n 'text/csv',\n 'text/plain',\n 'application/json'\n]);\n\nconst PARSE_PROMPT =\n 'Please parse this document and extract relevant purchase order information.';\n\nfunction buildTextParts(fileName: string, content: string) {\n return [\n {\n type: 'text' as const,\n text: `${PARSE_PROMPT.replace('this document', `this ${fileName} document`)}\\n\\n${content}`\n }\n ];\n}\n\nfunction buildFileParts(dataUrl: string, mediaType: string, filename: string) {\n return [\n { type: 'text' as const, text: PARSE_PROMPT },\n {\n type: 'file' as const,\n url: dataUrl,\n mediaType,\n filename\n }\n ];\n}\n\ninterface UseFileUploadOptions {\n createParserThread: () => Promise<void>;\n sendParserMessage: ReturnType<typeof useChat>['sendMessage'];\n}\n\nexport function useFileUpload({\n createParserThread,\n sendParserMessage\n}: UseFileUploadOptions) {\n const [isUploadingFile, setIsUploadingFile] = useState(false);\n const [parserError, setParserError] = useState<string | null>(null);\n\n const handleFileUpload = useCallback(\n async (file: File) => {\n const store = usePurchaseOrderStore.getState();\n store.setParsedContent(null);\n setIsUploadingFile(true);\n store.setUploadedFileName(file.name);\n setParserError(null);\n\n if (file.type === 'application/pdf') {\n const result = await validatePdf(file);\n if (!result.valid) {\n setParserError(\n result.reason === 'password-protected'\n ? 'The PDF appears to be password protected.'\n : 'The file does not appear to be a valid PDF.'\n );\n setIsUploadingFile(false);\n return false;\n }\n }\n\n await createParserThread();\n\n try {\n if (isSpreadsheet(file.type)) {\n const csvContent = await convertSpreadsheetToCsv(file);\n sendParserMessage({ parts: buildTextParts(file.name, csvContent) });\n } else if (TEXT_BASED_TYPES.has(file.type)) {\n const textContent = await readFileAsText(file);\n sendParserMessage({ parts: buildTextParts(file.name, textContent) });\n } else {\n const dataUrl = await readFileAsDataUrl(file);\n sendParserMessage({\n parts: buildFileParts(dataUrl, file.type, file.name)\n });\n }\n } catch (error) {\n console.error('Failed to read file:', error);\n if (isSpreadsheet(file.type)) {\n setParserError(\n 'Failed to read the spreadsheet file. Please try saving it as CSV and uploading again.'\n );\n } else {\n usePurchaseOrderStore.getState().setParsedContent(null);\n }\n setIsUploadingFile(false);\n }\n },\n [createParserThread, sendParserMessage]\n );\n\n return {\n isUploadingFile,\n setIsUploadingFile,\n parserError,\n setParserError,\n handleFileUpload\n };\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { createAgentThread } from '../lib/takeshape-api.js';\nimport { usePurchaseOrderStore } from '../stores/purchase-order-store.js';\n\nexport interface UseTakeShapeThreadOptions {\n agentName: string;\n createOnMount?: boolean;\n /**\n * If provided, the hook will use this thread ID instead of creating a new one.\n * Used for reconnecting to an existing thread after page reload.\n */\n existingThreadId?: string | null;\n /**\n * Whether to persist the thread ID to the store for session restoration.\n * Set to false for ephemeral threads like the document parser.\n * Defaults to true.\n */\n persist?: boolean;\n /**\n * Optional callback invoked when a new thread is created.\n * Useful for tracking thread IDs in custom locations.\n */\n onThreadCreated?: (threadId: string) => void;\n}\n\nexport function useTakeShapeThread(options: UseTakeShapeThreadOptions) {\n const {\n agentName,\n createOnMount,\n existingThreadId,\n persist = true,\n onThreadCreated\n } = options;\n\n const { projectId, apiKey, origin } = usePurchaseOrderStore(\n (state) => state.takeshapeConfig\n );\n\n const [isCreating, setIsCreating] = useState(false);\n // Initialize with existing thread ID if provided\n const thread = useRef<{ id: string } | null>(\n existingThreadId ? { id: existingThreadId } : null\n );\n\n const createThread = useCallback(async () => {\n setIsCreating(true);\n\n const maxRetries = 2;\n let attempt = 0;\n\n while (attempt <= maxRetries) {\n try {\n const threadId = await createAgentThread(\n { origin, projectId, apiKey },\n agentName\n );\n\n setIsCreating(false);\n thread.current = { id: threadId };\n if (persist) {\n usePurchaseOrderStore.getState().setThreadId(threadId);\n }\n onThreadCreated?.(threadId);\n return;\n } catch (error) {\n const isLastAttempt = attempt === maxRetries;\n\n if (isLastAttempt) {\n setIsCreating(false);\n console.error(\n `Failed to create thread after ${maxRetries + 1} attempts:`,\n error\n );\n return;\n }\n\n // Exponential backoff: 500ms, 1000ms\n const backoffMs = 500 * 2 ** attempt;\n console.warn(\n `Thread creation failed (attempt ${attempt + 1}/${maxRetries + 1}), retrying in ${backoffMs}ms...`,\n error\n );\n\n await new Promise((resolve) => setTimeout(resolve, backoffMs));\n attempt++;\n }\n }\n }, [agentName, apiKey, onThreadCreated, origin, persist, projectId]);\n\n useEffect(() => {\n if (createOnMount && !isCreating && !thread.current) {\n createThread();\n }\n }, [createThread, createOnMount, isCreating]);\n\n // If we have an existingThreadId and no thread yet, use it.\n // This handles Zustand rehydration happening after initial mount.\n // Idempotent - once thread.current is set, this is a no-op.\n if (existingThreadId && !thread.current) {\n thread.current = { id: existingThreadId };\n }\n\n return {\n thread,\n isCreating,\n createThread\n };\n}\n","import { useChat } from '@ai-sdk/react';\nimport { DefaultChatTransport } from 'ai';\nimport { useCallback, useEffect, useRef } from 'react';\nimport { splitDocumentParserOutput } from '../lib/batching.js';\nimport { startInactiveSpan } from '../lib/tracing.js';\nimport { usePurchaseOrderStore } from '../stores/purchase-order-store.js';\nimport { useFileUpload } from './use-file-upload.js';\nimport { useTakeShapeThread } from './use-takeshape-thread.js';\n\nexport function useDocumentParser() {\n const { sseOrigin, projectId, apiKey } = usePurchaseOrderStore(\n (state) => state.takeshapeConfig\n );\n const setParserThreadId = usePurchaseOrderStore(\n (state) => state.setParserThreadId\n );\n const { thread: parserThread, createThread: createParserThread } =\n useTakeShapeThread({\n agentName: 'documentParser',\n createOnMount: false,\n persist: false, // Document parser is ephemeral, don't overwrite main chat thread\n onThreadCreated: setParserThreadId\n });\n\n // Persisted state from Zustand store (read-only subscriptions)\n const parsedContent = usePurchaseOrderStore(\n (state) => state.parser.parsedContent\n );\n const uploadedFileName = usePurchaseOrderStore(\n (state) => state.parser.uploadedFileName\n );\n\n const parserSpanRef = useRef<ReturnType<typeof startInactiveSpan> | null>(\n null\n );\n\n const {\n messages: parserMessages,\n sendMessage: sendParserMessage,\n status: parserStatus,\n setMessages: setParserMessages\n } = useChat({\n transport: new DefaultChatTransport({\n api: `${sseOrigin}/project/${projectId}/agents/messages`,\n headers: {\n Authorization: `Bearer ${apiKey}`\n },\n prepareSendMessagesRequest: async (options) => {\n const lastMessage = options.messages[options.messages.length - 1];\n return {\n body: {\n id: parserThread.current?.id ?? '',\n messages: [lastMessage],\n trigger: options.trigger,\n messageId: options.messageId,\n metadata: {\n ...(options.requestMetadata as Record<string, unknown>),\n custom: {\n inputName: 'documentParser'\n }\n }\n }\n };\n }\n }),\n messages: [],\n onError: (error) => {\n console.error('Document parser error:', error);\n setParserError(\n 'Failed to process the document. Please try a different file.'\n );\n parserSpanRef.current?.setStatus({ code: 2, message: 'internal_error' });\n parserSpanRef.current?.end();\n parserSpanRef.current = null;\n setIsUploadingFile(false);\n }\n });\n\n const {\n isUploadingFile,\n setIsUploadingFile,\n parserError,\n setParserError,\n handleFileUpload: baseHandleFileUpload\n } = useFileUpload({\n createParserThread,\n sendParserMessage\n });\n\n const handleFileUpload = useCallback(\n async (file: File) => {\n parserSpanRef.current?.end();\n parserSpanRef.current = startInactiveSpan({\n name: 'document-parser',\n op: 'ai.parse',\n attributes: {\n 'file.name': file.name,\n 'file.type': file.type,\n 'file.size': file.size\n }\n });\n\n return baseHandleFileUpload(file);\n },\n [baseHandleFileUpload]\n );\n\n // Update parsed content as parser streams\n useEffect(() => {\n if (parserMessages.length > 0) {\n const lastMessage = parserMessages[parserMessages.length - 1];\n if (\n lastMessage?.role === 'assistant' &&\n Array.isArray(lastMessage.parts)\n ) {\n const textParts = lastMessage.parts\n .filter((part) => part.type === 'text')\n .map((part) => part.text)\n .filter(Boolean);\n const textContent = splitDocumentParserOutput(textParts.join(''));\n usePurchaseOrderStore.getState().setParsedContent(textContent);\n if (textContent) {\n setIsUploadingFile(false);\n }\n }\n }\n }, [parserMessages, setIsUploadingFile]);\n\n // Clean up open parser span on unmount\n useEffect(() => {\n return () => {\n parserSpanRef.current?.setStatus({ code: 2, message: 'cancelled' });\n parserSpanRef.current?.end();\n parserSpanRef.current = null;\n };\n }, []);\n\n // End parser span when parsing is fully complete (not on first streamed chunk)\n useEffect(() => {\n if (\n parserStatus === 'ready' &&\n parserSpanRef.current &&\n parsedContent !== null\n ) {\n parserSpanRef.current.setStatus({ code: 1, message: 'ok' });\n parserSpanRef.current.end();\n parserSpanRef.current = null;\n }\n }, [parserStatus, parsedContent]);\n\n const handleClearError = useCallback(() => {\n parserSpanRef.current?.setStatus({ code: 2, message: 'cancelled' });\n parserSpanRef.current?.end();\n parserSpanRef.current = null;\n setParserError(null);\n setParserMessages([]);\n usePurchaseOrderStore.getState().setParsedContent(null);\n }, [setParserError, setParserMessages]);\n\n const reset = useCallback(() => {\n parserSpanRef.current?.setStatus({ code: 2, message: 'cancelled' });\n parserSpanRef.current?.end();\n parserSpanRef.current = null;\n setParserMessages([]);\n usePurchaseOrderStore.getState().clearParser();\n setIsUploadingFile(false);\n setParserError(null);\n }, [setParserMessages, setIsUploadingFile, setParserError]);\n\n return {\n parsedContent,\n isUploadingFile,\n uploadedFileName,\n parserError,\n parserStatus,\n parserMessages,\n handleFileUpload,\n handleClearError,\n reset\n };\n}\n","// B2B Edition GraphQL Client\n// Handles authentication and address fetching from the BigCommerce B2B Edition API\n\nimport type { ResultOf, TadaDocumentNode } from 'gql.tada';\nimport { GraphQLClient, type Variables } from 'graphql-request';\nimport { B2B_APP_CLIENT_ID, B2B_GRAPHQL_URL } from '../../../constants.js';\nimport { nativeFetch } from '../../native-fetch.js';\nimport type { CustomerAddress } from '../storefront/types.js';\nimport type { TadaRequestOptions } from '../types.js';\nimport { convertCompanyAddressToCustomerAddress } from '../utils.js';\nimport { readFragment } from './graphql.js';\nimport {\n AuthorizationMutation,\n CheckoutLoginMutation,\n CompanyAddressesQuery,\n CurrentUserQuery,\n UserAuthorizationFragment,\n UserFragment\n} from './queries.js';\n\nexport interface B2BClientConfig {\n channelId: number;\n /** Optional B2B JWT fetcher. Receives channelId and returns a B2B storefront token. If not provided, B2B features are disabled. */\n getB2BJwt?: (channelId: number) => Promise<string | null>;\n}\n\nexport class B2BClient {\n private b2bToken: string | null = null;\n private companyId: number | null = null;\n private channelId: number;\n private graphQLClient: GraphQLClient;\n private getB2BJwt: ((channelId: number) => Promise<string | null>) | null;\n readonly initPromise: Promise<void>;\n\n constructor(config: B2BClientConfig) {\n this.channelId = config.channelId;\n this.getB2BJwt = config.getB2BJwt ?? null;\n\n this.graphQLClient = new GraphQLClient(B2B_GRAPHQL_URL, {\n fetch: nativeFetch,\n credentials: 'same-origin',\n headers: {\n 'content-type': 'application/json',\n accept: 'application/json'\n }\n });\n\n if (this.getB2BJwt) {\n this.initPromise = this.init();\n } else {\n this.initPromise = Promise.resolve();\n this.b2bToken = null;\n }\n }\n\n get isAvailable(): boolean {\n return this.b2bToken !== null && this.companyId !== null;\n }\n\n private async init(): Promise<void> {\n if (!this.getB2BJwt) {\n console.info(\n '[B2BClient] No B2B token fetcher provided, B2B features disabled'\n );\n this.b2bToken = null;\n return;\n }\n\n try {\n const jwt = await this.getB2BJwt(this.channelId);\n if (!jwt) {\n console.info('[B2BClient] No JWT returned, B2B features disabled');\n this.b2bToken = null;\n return;\n }\n this.b2bToken = jwt;\n this.companyId = await this.getB2BCompanyId(this.b2bToken);\n console.info('[B2BClient] B2B Edition authenticated successfully');\n } catch {\n console.info(\n '[B2BClient] B2B Edition not available, skipping B2B address enrichment'\n );\n this.b2bToken = null;\n }\n }\n\n /**\n * Execute a request with retry logic (up to 5 attempts with exponential backoff)\n */\n private async request<const R, V extends Variables | undefined>(\n options: TadaRequestOptions<R, V>,\n attempt = 1\n ): Promise<ResultOf<TadaDocumentNode<R, V>>> {\n const maxAttempts = 5;\n const delays = [1000, 2000, 4000, 8000, 16000]; // 1s, 2s, 4s, 8s, 16s\n\n try {\n const result = await this.graphQLClient.request(options);\n return result;\n } catch (error) {\n if (attempt !== -1 && attempt < maxAttempts) {\n const delay = delays[attempt - 1] ?? 16000;\n console.warn(\n `[BigCommerceClient] Request failed, retrying in ${delay / 1000}s (attempt ${attempt}/${maxAttempts})`,\n error\n );\n await new Promise((resolve) => setTimeout(resolve, delay));\n return this.request(options, attempt + 1);\n }\n console.error(\n `[BigCommerceClient] Request failed after ${maxAttempts} attempts:`,\n error\n );\n throw error;\n }\n }\n\n private async getB2BStorefrontToken(jwt: string): Promise<string> {\n const result = await this.request({\n document: AuthorizationMutation,\n variables: {\n authData: {\n bcToken: jwt,\n channelId: this.channelId\n }\n },\n requestHeaders: {\n Authorization: `Bearer ${jwt}`\n }\n });\n\n const userAuthorization = readFragment(\n UserAuthorizationFragment,\n result.authorization\n );\n const token = userAuthorization?.result?.token;\n\n if (!token) {\n throw new Error('No token returned from B2B authorization mutation');\n }\n\n return token;\n }\n\n private async getB2BCompanyId(jwt: string): Promise<number> {\n console.debug('[B2BClient] Requesting company ID with customer JWT');\n\n const result = await this.request(\n {\n document: CurrentUserQuery,\n requestHeaders: {\n Authorization: `Bearer ${jwt}`\n }\n },\n -1\n );\n\n const currentUser = readFragment(UserFragment, result.currentUser);\n const companyId = currentUser?.companyInfo?.companyId;\n\n if (!companyId) {\n throw new Error('No company ID returned from current user query');\n }\n\n console.debug('[B2BClient] Received company ID', companyId);\n\n return Number(companyId);\n }\n\n async getCompanyAddresses(): Promise<CustomerAddress[]> {\n await this.initPromise;\n\n if (!this.isAvailable) {\n return [];\n }\n\n try {\n const result = await this.request({\n document: CompanyAddressesQuery,\n variables: {\n companyId: this.companyId!\n },\n requestHeaders: {\n Authorization: `Bearer ${this.b2bToken!}`\n }\n });\n\n const addressEdges = result?.addresses?.edges;\n\n if (!addressEdges) {\n return [];\n }\n\n return addressEdges.map((edge) =>\n convertCompanyAddressToCustomerAddress(edge.node)\n );\n } catch (error) {\n console.info(\n '[B2BClient] Failed to fetch B2B company addresses, continuing without them',\n error\n );\n return [];\n }\n }\n\n async createCartRedirectUrls(\n cartId: string\n ): Promise<{ redirectedCheckoutUrl: string }> {\n await this.initPromise;\n\n if (!this.isAvailable) {\n throw new Error('B2B client is not available');\n }\n\n try {\n const result = await this.request({\n document: CheckoutLoginMutation,\n variables: {\n cartData: {\n cartId\n }\n },\n requestHeaders: {\n Authorization: `Bearer ${this.b2bToken!}`\n }\n });\n\n const redirectedCheckoutUrl = result?.checkoutLogin?.result?.redirectUrl;\n\n if (!redirectedCheckoutUrl) {\n throw new Error(\n 'No redirect URL returned from checkout login mutation'\n );\n }\n\n return {\n redirectedCheckoutUrl\n };\n } catch (error) {\n console.error('[B2BClient] Failed to create cart redirect URLs', error);\n throw error;\n }\n }\n}\n\n/**\n * Create a B2B client with the given configuration.\n */\nexport function createB2BClient(config: B2BClientConfig): B2BClient {\n console.debug(\n `[createB2BClient] Initializing B2B client for channelId=${config.channelId}`\n );\n return new B2BClient(config);\n}\n\n/**\n * B2B JWT fetcher for Stencil storefronts.\n * Fetches the customer JWT from /customer/current.jwt and exchanges it for a B2B storefront token.\n *\n * @param channelId - BigCommerce channel ID (passed by the B2BClient)\n * @returns B2B storefront token, or null if not available\n *\n * @example\n * ```tsx\n * import { stencilB2BJwt } from '@takeshape/purchase-order-chat';\n *\n * <PurchaseOrderChat\n * bigCommerce={{\n * endpoint: '/graphql',\n * channelId: 1,\n * getB2BJwt: stencilB2BJwt\n * }}\n * // ...\n * />\n * ```\n */\nexport async function stencilB2BJwt(channelId: number): Promise<string | null> {\n // Fetch customer JWT from Stencil's /customer/current.jwt endpoint\n let customerJwt: string | null = null;\n try {\n const resp = await nativeFetch(\n `/customer/current.jwt?app_client_id=${B2B_APP_CLIENT_ID}`,\n {\n method: 'GET',\n credentials: 'same-origin',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json'\n }\n }\n );\n\n if (resp.ok) {\n const data = await resp.json();\n customerJwt = data?.token ?? null;\n }\n } catch {\n return null;\n }\n\n if (!customerJwt) {\n return null;\n }\n\n // Exchange customer JWT for B2B storefront token\n try {\n console.debug(\n '[stencilB2BJwt] Exchanging customer JWT for B2B storefront token'\n );\n\n const client = new GraphQLClient(B2B_GRAPHQL_URL, {\n fetch: nativeFetch,\n credentials: 'same-origin',\n headers: {\n 'content-type': 'application/json',\n accept: 'application/json',\n Authorization: `Bearer ${customerJwt}`\n }\n });\n\n const result = await client.request({\n document: AuthorizationMutation,\n variables: {\n authData: {\n bcToken: customerJwt,\n channelId\n }\n }\n });\n\n const userAuthorization = readFragment(\n UserAuthorizationFragment,\n result.authorization\n );\n const token = userAuthorization?.result?.token;\n\n if (!token) {\n return null;\n }\n\n console.debug('[stencilB2BJwt] Received B2B storefront token');\n return token;\n } catch {\n return null;\n }\n}\n","import { ADD_TO_CART_TOOL_NAME } from '../../components/tools/tool-names.js';\nimport type { UseBigCommerceCartReturn } from '../../hooks/use-bigcommerce-cart.js';\nimport { usePurchaseOrderStore } from '../../stores/purchase-order-store.js';\nimport type { AddToCartInput } from '../../types.js';\nimport type { PendingToolOutput, ToolCall } from './types.js';\n\nexport async function handleAddToCart(\n toolCall: ToolCall,\n bcCart: UseBigCommerceCartReturn\n): Promise<PendingToolOutput> {\n const { setToolCallError } = usePurchaseOrderStore.getState();\n\n const input = toolCall.input as AddToCartInput;\n let output = 'No items provided to add to cart.';\n\n if (input.value && input.value.length > 0) {\n const { errors } = await bcCart.addToCart(input.value);\n\n if (errors.length > 0) {\n const message = errors.map((e) => e.message).join('; ');\n output = `Failed to add items to cart: ${message}`;\n setToolCallError(toolCall.toolCallId, message);\n } else {\n output = `Successfully added ${input.value.length} item(s) to cart.`;\n }\n }\n\n return {\n tool: ADD_TO_CART_TOOL_NAME,\n toolCallId: toolCall.toolCallId,\n output\n };\n}\n","import { CLEAR_CART_TOOL_NAME } from '../../components/tools/tool-names.js';\nimport type { UseBigCommerceCartReturn } from '../../hooks/use-bigcommerce-cart.js';\nimport { usePurchaseOrderStore } from '../../stores/purchase-order-store.js';\nimport type { PendingToolOutput, ToolCall } from './types.js';\n\nexport async function handleClearCart(\n toolCall: ToolCall,\n bcCart: UseBigCommerceCartReturn\n): Promise<PendingToolOutput> {\n const { setToolCallError } = usePurchaseOrderStore.getState();\n\n let output = 'Cart cleared successfully.';\n\n try {\n await bcCart.clearCart();\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n output = `Failed to clear cart: ${message}`;\n setToolCallError(toolCall.toolCallId, message);\n }\n\n return {\n tool: CLEAR_CART_TOOL_NAME,\n toolCallId: toolCall.toolCallId,\n output\n };\n}\n","import { GET_CART_TOOL_NAME } from '../../components/tools/tool-names.js';\nimport type { UseBigCommerceCartReturn } from '../../hooks/use-bigcommerce-cart.js';\nimport type { PendingToolOutput, ToolCall } from './types.js';\n\nexport function handleGetCart(\n toolCall: ToolCall,\n bcCart: UseBigCommerceCartReturn\n): PendingToolOutput {\n const cartData = {\n items: bcCart.cartItems.map((item) => ({\n productEntityId: item.productEntityId,\n variantEntityId: item.variantEntityId,\n sku: item.sku,\n name: item.name,\n quantity: item.quantity,\n price: item.price,\n poPriceValue: item.poPriceValue,\n status: item.status\n })),\n totals: bcCart.checkoutTotals\n };\n\n return {\n tool: GET_CART_TOOL_NAME,\n toolCallId: toolCall.toolCallId,\n output: JSON.stringify(cartData)\n };\n}\n","import { GET_PURCHASE_ORDER_DATA_TOOL_NAME } from '../../components/tools/tool-names.js';\nimport { usePurchaseOrderStore } from '../../stores/purchase-order-store.js';\nimport type { PendingToolOutput, ToolCall } from './types.js';\n\nexport function handleGetPurchaseOrderData(\n toolCall: ToolCall\n): PendingToolOutput {\n const { parser } = usePurchaseOrderStore.getState();\n\n const data = {\n uploadedFileName: parser.uploadedFileName,\n parsedContent: parser.parsedContent\n };\n\n return {\n tool: GET_PURCHASE_ORDER_DATA_TOOL_NAME,\n toolCallId: toolCall.toolCallId,\n output: JSON.stringify(data)\n };\n}\n","import { REMOVE_FROM_CART_TOOL_NAME } from '../../components/tools/tool-names.js';\nimport type { UseBigCommerceCartReturn } from '../../hooks/use-bigcommerce-cart.js';\nimport type { CartPhysicalItem } from '../../lib/bigcommerce/storefront/types.js';\nimport { usePurchaseOrderStore } from '../../stores/purchase-order-store.js';\nimport type { RemoveFromCartInput } from '../../types.js';\nimport type { PendingToolOutput, ToolCall } from './types.js';\n\nexport async function handleRemoveFromCart(\n toolCall: ToolCall,\n bcCart: UseBigCommerceCartReturn\n): Promise<PendingToolOutput> {\n const { setToolCallError } = usePurchaseOrderStore.getState();\n\n const input = toolCall.input as RemoveFromCartInput;\n let output = 'Item removed from cart successfully.';\n\n try {\n // Find ALL matching items (not just the first one)\n const matchingItems =\n bcCart.bcCart?.lineItems.physicalItems.filter(\n (i: CartPhysicalItem) =>\n i.productEntityId === input.productEntityId &&\n i.variantEntityId === input.variantEntityId\n ) ?? [];\n\n if (matchingItems.length === 0) {\n return {\n tool: REMOVE_FROM_CART_TOOL_NAME,\n toolCallId: toolCall.toolCallId,\n output: 'Cart item not found.'\n };\n }\n\n // Remove all matching items\n for (const item of matchingItems) {\n await bcCart.removeLineItem(item.entityId);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n output = `Failed to remove item from cart: ${message}`;\n setToolCallError(toolCall.toolCallId, message);\n }\n\n return {\n tool: 'removeFromCart',\n toolCallId: toolCall.toolCallId,\n output\n };\n}\n","import { REMOVE_ITEM_WARNINGS_TOOL_NAME } from '../../components/tools/tool-names.js';\nimport { usePurchaseOrderStore } from '../../stores/purchase-order-store.js';\nimport type { ItemWarning, RemoveItemWarningsInput } from '../../types.js';\nimport {\n normalizeProductName,\n normalizeProductSku\n} from '../../utils/cart-sync-helpers.js';\nimport type { PendingToolOutput, ToolCall } from './types.js';\n\nexport function handleRemoveItemWarnings(\n toolCall: ToolCall\n): PendingToolOutput {\n const {\n cartifact: { itemWarnings },\n setItemWarnings\n } = usePurchaseOrderStore.getState();\n\n const input = toolCall.input as RemoveItemWarningsInput;\n const remaining = itemWarnings.filter(\n (w: ItemWarning) =>\n !(\n (input.productSku !== undefined &&\n w.productSku !== undefined &&\n normalizeProductSku(w.productSku) ===\n normalizeProductSku(input.productSku)) ||\n (input.productName !== undefined &&\n w.productName !== undefined &&\n normalizeProductName(w.productName) ===\n normalizeProductName(input.productName))\n )\n );\n setItemWarnings(remaining);\n\n return {\n tool: REMOVE_ITEM_WARNINGS_TOOL_NAME,\n toolCallId: toolCall.toolCallId,\n output: 'Item warnings removed successfully.'\n };\n}\n","import { SET_ITEM_WARNINGS_TOOL_NAME } from '../../components/tools/tool-names.js';\nimport { usePurchaseOrderStore } from '../../stores/purchase-order-store.js';\nimport type { SetItemWarningsInput } from '../../types.js';\nimport type { PendingToolOutput, ToolCall } from './types.js';\n\nexport function handleSetItemWarnings(toolCall: ToolCall): PendingToolOutput {\n const { setItemWarnings } = usePurchaseOrderStore.getState();\n\n const input = toolCall.input as SetItemWarningsInput;\n if (input.itemWarnings) {\n setItemWarnings(input.itemWarnings);\n }\n\n return {\n tool: SET_ITEM_WARNINGS_TOOL_NAME,\n toolCallId: toolCall.toolCallId,\n output: 'Item warnings set successfully.'\n };\n}\n","import { SET_PO_METADATA_TOOL_NAME } from '../../components/tools/tool-names.js';\nimport { usePurchaseOrderStore } from '../../stores/purchase-order-store.js';\nimport type { SetPoMetadataInput } from '../../types.js';\nimport type { PendingToolOutput, ToolCall } from './types.js';\n\nexport function handleSetPoMetadata(toolCall: ToolCall): PendingToolOutput {\n const input = toolCall.input as SetPoMetadataInput;\n\n usePurchaseOrderStore.getState().applyPoMetadata(input.poMetadata);\n\n return {\n tool: SET_PO_METADATA_TOOL_NAME,\n toolCallId: toolCall.toolCallId,\n output: 'PO metadata set successfully.'\n };\n}\n","import { UPDATE_CART_TOOL_NAME } from '../../components/tools/tool-names.js';\nimport type { UseBigCommerceCartReturn } from '../../hooks/use-bigcommerce-cart.js';\nimport type { CartPhysicalItem } from '../../lib/bigcommerce/storefront/types.js';\nimport { usePurchaseOrderStore } from '../../stores/purchase-order-store.js';\nimport type { UpdateCartInput } from '../../types.js';\nimport type { PendingToolOutput, ToolCall } from './types.js';\n\nexport async function handleUpdateCart(\n toolCall: ToolCall,\n bcCart: UseBigCommerceCartReturn\n): Promise<PendingToolOutput> {\n const { setToolCallError, setPoItemPrice } = usePurchaseOrderStore.getState();\n\n const input = toolCall.input as UpdateCartInput;\n let itemsUpdated = 0;\n\n try {\n const bcCartItem = bcCart.bcCart?.lineItems.physicalItems.find(\n (i: CartPhysicalItem) =>\n i.productEntityId === input.where.productEntityId &&\n i.variantEntityId === input.where.variantEntityId\n );\n\n if (bcCartItem && input.data.quantity !== undefined) {\n await bcCart.updateLineItemQuantity(\n bcCartItem.entityId,\n input.data.quantity,\n bcCartItem.productEntityId,\n bcCartItem.variantEntityId ?? undefined\n );\n itemsUpdated++;\n }\n\n if (\n input.data.poPriceValue !== undefined &&\n input.data.poPriceCurrencyCode !== undefined\n ) {\n setPoItemPrice(\n input.where.productEntityId,\n input.where.variantEntityId,\n input.data.poPriceValue,\n input.data.poPriceCurrencyCode\n );\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n setToolCallError(toolCall.toolCallId, message);\n return {\n tool: UPDATE_CART_TOOL_NAME,\n toolCallId: toolCall.toolCallId,\n output: `Failed to update cart item: ${message}`\n };\n }\n\n return {\n tool: 'updateCart',\n toolCallId: toolCall.toolCallId,\n output: `${itemsUpdated} cart item(s) updated.`\n };\n}\n","import type { UseBigCommerceCartReturn } from '../../hooks/use-bigcommerce-cart.js';\nimport { handleAddToCart } from './add-to-cart.js';\nimport { handleClearCart } from './clear-cart.js';\nimport { handleGetCart } from './get-cart.js';\nimport { handleGetPurchaseOrderData } from './get-purchase-order-data.js';\nimport { handleRemoveFromCart } from './remove-from-cart.js';\nimport { handleRemoveItemWarnings } from './remove-item-warnings.js';\nimport { handleSetItemWarnings } from './set-item-warnings.js';\nimport { handleSetPoMetadata } from './set-po-metadata.js';\nimport type { PendingToolOutput, ToolCall, ToolHandler } from './types.js';\nimport { handleUpdateCart } from './update-cart.js';\n\nexport type { PendingToolOutput, ToolCall, ToolHandler } from './types.js';\n\nconst toolHandlers: Record<string, ToolHandler> = {\n addToCart: handleAddToCart,\n updateCart: handleUpdateCart,\n removeFromCart: handleRemoveFromCart,\n clearCart: handleClearCart,\n getCart: handleGetCart,\n getPurchaseOrderData: handleGetPurchaseOrderData,\n setPoMetadata: handleSetPoMetadata,\n setItemWarnings: handleSetItemWarnings,\n removeItemWarnings: handleRemoveItemWarnings\n};\n\n/** Set of all tool names that have client-side handlers in the chat flow */\nexport const CHAT_CLIENT_TOOL_NAMES = new Set(Object.keys(toolHandlers));\n\nexport async function handleToolCall(\n toolCall: ToolCall,\n bcCart: UseBigCommerceCartReturn\n): Promise<PendingToolOutput | undefined> {\n const handler = toolHandlers[toolCall.toolName];\n return handler?.(toolCall, bcCart);\n}\n","import type { UIMessage } from '@ai-sdk/react';\nimport type { UseBigCommerceCartReturn } from '../hooks/use-bigcommerce-cart.js';\nimport { usePurchaseOrderStore } from '../stores/purchase-order-store.js';\nimport {\n CHAT_CLIENT_TOOL_NAMES,\n handleToolCall\n} from './tool-handlers/index.js';\nimport type { PendingToolOutput, ToolCall } from './tool-handlers/types.js';\n\nexport type { ToolCall } from './tool-handlers/types.js';\n\ninterface ServerHandledToolPart {\n toolCallId: string;\n state: 'output-available' | 'output-error';\n errorText?: string;\n}\n\n/**\n * Finds a tool part in the last assistant message that was already handled by the server.\n * Returns the part if the server handled it (either success or error), null otherwise.\n */\nexport function findServerHandledTool(\n messages: UIMessage[],\n toolCallId: string\n): ServerHandledToolPart | null {\n const lastAssistantMsg = [...messages]\n .reverse()\n .find((m) => m.role === 'assistant');\n\n const part = lastAssistantMsg?.parts?.find(\n (p) =>\n 'toolCallId' in p &&\n p.toolCallId === toolCallId &&\n 'state' in p &&\n (p.state === 'output-available' || p.state === 'output-error')\n );\n\n if (!part || !('toolCallId' in part) || !('state' in part)) {\n return null;\n }\n\n return {\n toolCallId: part.toolCallId as string,\n state: part.state as 'output-available' | 'output-error',\n errorText: 'errorText' in part ? String(part.errorText) : undefined\n };\n}\n\nexport interface ExecuteDeferredToolCallsResult {\n /** Tool call IDs that were successfully executed client-side */\n completedToolCallIds: string[];\n /** Tool outputs to be added to the chat */\n outputs: PendingToolOutput[];\n}\n\n/**\n * Executes tool calls. We don't execute them onToolCall but instead defer\n * them so we can check if the server already handled them when streaming\n * completes.\n * This prevents us from executing tools that were rejected by the server,\n * such as due to input validation.\n */\nexport async function executeDeferredToolCalls(\n deferredCalls: ToolCall[],\n messages: UIMessage[],\n bcCart: UseBigCommerceCartReturn\n): Promise<ExecuteDeferredToolCallsResult> {\n const completedToolCallIds: string[] = [];\n const outputs: PendingToolOutput[] = [];\n\n for (const toolCall of deferredCalls) {\n // Only process client-side tools\n if (!CHAT_CLIENT_TOOL_NAMES.has(toolCall.toolName)) {\n continue;\n }\n\n // Check if server already handled this tool (either with output or error)\n const serverHandledTool = findServerHandledTool(\n messages,\n toolCall.toolCallId\n );\n\n if (serverHandledTool) {\n // Server already handled this tool, skip client execution\n console.warn(\n '[ToolCallSkipped] Server already handled tool, skipping client execution',\n {\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n state: serverHandledTool.state\n }\n );\n\n // If server returned an error, record it in the store so UI can display it\n if (serverHandledTool.state === 'output-error') {\n const errorText =\n serverHandledTool.errorText ?? 'Server validation failed';\n usePurchaseOrderStore\n .getState()\n .setToolCallError(toolCall.toolCallId, errorText);\n }\n continue;\n }\n\n // Server didn't handle this tool, execute the client-side handler now\n try {\n const output = await handleToolCall(toolCall, bcCart);\n if (output) {\n completedToolCallIds.push(output.toolCallId);\n outputs.push(output);\n }\n } catch (error) {\n console.error('[handleToolCall] Error:', { toolCall, error });\n const errorText =\n error instanceof Error ? error.message : 'Tool execution failed';\n usePurchaseOrderStore\n .getState()\n .setToolCallError(toolCall.toolCallId, errorText);\n }\n }\n\n return { completedToolCallIds, outputs };\n}\n","import { STORAGE_KEY, STORAGE_VERSION } from '../constants.js';\nimport type { B2BClient } from '../lib/bigcommerce/b2b/client.js';\nimport type { TakeShapeConfig } from './slices/takeshape-config-slice.js';\nimport type {\n BigCommerceClient,\n MockBigCommerceClient\n} from '../lib/bigcommerce/index.js';\nimport type {\n Cart,\n CustomerAddress,\n CustomerInfo\n} from '../lib/bigcommerce/storefront/types.js';\nimport {\n usePurchaseOrderStore,\n type PersistedState\n} from './purchase-order-store.js';\n\n/**\n * Dependencies required for session validation.\n */\nexport interface ValidationDependencies {\n storefrontClient: BigCommerceClient | MockBigCommerceClient;\n b2bClient: B2BClient;\n takeShapeConfig: TakeShapeConfig;\n}\n\ninterface ValidationResult {\n valid: boolean;\n error?: string;\n}\n\n\ninterface LoadSessionResult {\n /** Whether the data is valid (correct version) or absent */\n valid: boolean;\n /** Error message if version validation failed */\n error?: string;\n /** Full persisted state if valid and present, null if no session or invalid */\n data: PersistedState | null;\n /** Quick access to IDs for validation */\n threadId: string | null;\n cartEntityId: string | null;\n}\n\n/**\n * Load and validate persisted session data from localStorage.\n * Returns the full persisted state if valid, or null if no session exists.\n * Returns an error if the data exists but has an invalid version.\n */\nfunction loadPersistedSession(): LoadSessionResult {\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n if (!raw) {\n // No stored data - fresh session\n return {\n valid: true,\n data: null,\n threadId: null,\n cartEntityId: null\n };\n }\n\n const parsed = JSON.parse(raw);\n const storedVersion = parsed?.version;\n\n // Version validation\n if (storedVersion === undefined) {\n return {\n valid: false,\n error: 'Session data format is outdated.',\n data: null,\n threadId: null,\n cartEntityId: null\n };\n }\n\n if (storedVersion !== STORAGE_VERSION) {\n return {\n valid: false,\n error:\n 'The app version has changed. Your previous session is not compatible.',\n data: null,\n threadId: null,\n cartEntityId: null\n };\n }\n\n // Extract the full persisted state\n const state = parsed?.state as PersistedState | undefined;\n const threadId = state?.chat?.threadId ?? null;\n const cartEntityId = state?.cartifact?.cartEntityId ?? null;\n const appState = state?.appState ?? 'upload';\n\n // Only restore sessions that finished processing\n if (appState === 'upload' || appState === 'processing') {\n return {\n valid: true,\n data: null,\n threadId: null,\n cartEntityId: null\n };\n }\n\n return {\n valid: true,\n data: state ?? null,\n threadId,\n cartEntityId\n };\n } catch (error) {\n console.error('Failed to load persisted session:', error);\n return {\n valid: false,\n error: 'Unable to read session data.',\n data: null,\n threadId: null,\n cartEntityId: null\n };\n }\n}\n\n/**\n * Clear the persisted session from localStorage.\n * Call this when a session ends (e.g., checkout completed).\n */\nexport function clearPersistedSession(): void {\n try {\n localStorage.removeItem(STORAGE_KEY);\n } catch (error) {\n console.error('Failed to clear persisted session:', error);\n }\n}\n\n/**\n * Validate that the persisted customer matches the currently logged-in customer.\n * Allows restoring anonymous sessions (no persisted customer ID and no current customer).\n * Takes the fetched customerInfo as input rather than fetching it internally.\n */\nfunction validateCustomer(\n persistedCustomerEntityId: number | null,\n customerInfo: unknown | null\n): ValidationResult {\n // Case 1: Anonymous to anonymous - valid (restoring anonymous session)\n if (!persistedCustomerEntityId && !customerInfo) {\n return { valid: true };\n }\n\n // Case 2: Logged-in to anonymous - invalid (user logged out)\n if (persistedCustomerEntityId && !customerInfo) {\n return {\n valid: false,\n error: 'Your previous session was reset because you signed out.'\n };\n }\n\n // Case 3: Anonymous to logged-in - invalid (user logged in)\n if (!persistedCustomerEntityId && customerInfo) {\n return {\n valid: false,\n error: 'Your previous session was reset because you signed in.'\n };\n }\n\n // Case 4: Logged-in to logged-in with different ID - invalid (different user)\n if (\n persistedCustomerEntityId &&\n customerInfo &&\n (customerInfo as { entityId: number }).entityId !==\n persistedCustomerEntityId\n ) {\n return {\n valid: false,\n error:\n 'Your previous session was reset because you signed in as a different user.'\n };\n }\n\n // Case 5: Logged-in to logged-in with same ID - valid\n return { valid: true };\n}\n\n/**\n * Validate that a thread exists on TakeShape.\n * NOTE: Thread validation is not yet available via the TakeShape API.\n * For now, we skip thread validation and rely on error handling during message sending.\n */\nasync function validateThread(\n _threadId: string,\n _config: TakeShapeConfig\n): Promise<ValidationResult> {\n // Skip thread validation - not available yet\n // Thread errors will be handled during message send attempts\n return { valid: true };\n}\n\n/**\n * Validate that a cart exists and has the expected structure.\n * Takes the fetched cart as input rather than fetching it internally.\n */\nfunction validateCart(cart: unknown | null): ValidationResult {\n if (cart) {\n return { valid: true };\n }\n return {\n valid: false,\n error: 'The cart from your previous session is no longer available.'\n };\n}\n\n/**\n * Validate persisted session and initialize the store.\n *\n * This function:\n * 1. Loads persisted data from localStorage and validates the version\n * 2. If no data or invalid version → starts fresh (no rehydration)\n * 3. If valid data → validates thread/cart still exist remotely\n * 4. If remote validation passes → rehydrates the store with persisted data\n * 5. If remote validation fails → clears localStorage and starts fresh\n */\nexport async function validateAndInit(\n deps: ValidationDependencies\n): Promise<void> {\n const store = usePurchaseOrderStore.getState();\n\n // Already initialized or in progress\n if (store.ui.initStatus !== 'pending') {\n return;\n }\n\n // Load and validate persisted data BEFORE any store mutations\n const loadResult = loadPersistedSession();\n\n // Now safe to set TakeShape config - localStorage has been read\n store.setTakeShapeConfig(deps.takeShapeConfig);\n\n // Version validation failed - clear storage and start fresh\n if (!loadResult.valid) {\n clearPersistedSession();\n store.failValidation(loadResult.error ?? 'Session validation failed');\n return;\n }\n\n // Fetch customer addresses and info (always, for all valid paths)\n let fetchedAddresses: CustomerAddress[] = [];\n let fetchedCustomerInfo: CustomerInfo | null = null;\n try {\n const result = await deps.storefrontClient.getCustomerAddresses();\n\n fetchedCustomerInfo = result.customerInfo;\n fetchedAddresses = result.addresses;\n\n // Wait for B2B client initialization to complete\n await deps.b2bClient.initPromise;\n\n if (deps.b2bClient.isAvailable) {\n console.debug('[BigCommerceClient] Fetching B2B company addresses');\n const companyAddresses = await deps.b2bClient.getCompanyAddresses();\n if (companyAddresses.length > 0) {\n fetchedAddresses = [...companyAddresses];\n }\n }\n } catch (error) {\n console.error('Failed to fetch customer addresses:', error);\n if (loadResult.data) {\n // Persisted session: fail hard since we need to validate customer identity\n clearPersistedSession();\n store.failValidation('Unable to verify customer identity.');\n return;\n }\n // Fresh start: soft failure - continue without addresses\n }\n\n // No persisted session data - start fresh\n if (!loadResult.data) {\n if (fetchedCustomerInfo) {\n store.setCustomerInfo(fetchedCustomerInfo);\n }\n if (fetchedAddresses.length > 0) {\n store.setCustomerAddresses(fetchedAddresses);\n }\n\n // Check for an orphan cart (existing cart with no associated session)\n try {\n const orphanCart = await deps.storefrontClient.getCart();\n if (orphanCart) {\n store.setExistingCart(orphanCart);\n return;\n }\n } catch (error) {\n console.error('Failed to check for existing cart:', error);\n store.failValidation(\n 'Unable to check for an existing cart. Please try again.'\n );\n return;\n }\n\n store.completeValidation();\n return;\n }\n\n const { threadId, cartEntityId, data: persistedData } = loadResult;\n\n // Fetch cart first if we have a cartEntityId (before validation)\n let fetchedCart: Cart | null = null;\n if (cartEntityId) {\n try {\n fetchedCart = await deps.storefrontClient.getCart(cartEntityId);\n } catch (error) {\n console.error('Failed to fetch cart:', error);\n clearPersistedSession();\n store.failValidation('Unable to restore previous cart.');\n return;\n }\n }\n\n // Validate remote resources in parallel (don't update store yet to avoid overwriting localStorage)\n const validationPromises: Promise<ValidationResult>[] = [];\n\n // Always validate customer if we have persisted data\n validationPromises.push(\n Promise.resolve(\n validateCustomer(\n persistedData.customerEntityId ?? null,\n fetchedCustomerInfo\n )\n )\n );\n\n if (threadId) {\n validationPromises.push(validateThread(threadId, deps.takeShapeConfig));\n }\n if (cartEntityId) {\n validationPromises.push(Promise.resolve(validateCart(fetchedCart)));\n }\n\n const results = await Promise.all(validationPromises);\n\n // Check for any validation failures\n const failedResult = results.find((r) => !r.valid);\n if (failedResult) {\n clearPersistedSession();\n store.failValidation(failedResult.error ?? 'Session validation failed');\n return;\n }\n\n // All validations passed - restore state directly from the data we already read\n // (bypassing rehydrate() which would read from localStorage that may have been overwritten)\n if (persistedData) {\n store.restoreSession(persistedData);\n }\n\n // If we fetched a cart, store it in the cartifact slice for immediate display\n if (fetchedCart) {\n store.setBcCart(fetchedCart);\n }\n\n // Store fetched customer addresses and info (always from BC session, never from localStorage)\n if (fetchedCustomerInfo) {\n store.setCustomerInfo(fetchedCustomerInfo);\n }\n if (fetchedAddresses.length > 0) {\n store.setCustomerAddresses(fetchedAddresses);\n }\n\n store.completeValidation();\n}\n","import { isToolUIPart, type UIMessage } from 'ai';\n\n/**\n * Extract tool part types from the SDK's union type.\n */\ntype ToolPart = Extract<\n UIMessage['parts'][number],\n { type: `tool-${string}` } | { type: 'dynamic-tool' }\n>;\n\n/**\n * Type representing a tool UI part that has completed with output available.\n * Derived from the SDK's types to ensure assignability.\n */\nexport type CompletedToolPart = ToolPart & {\n state: 'output-available';\n toolCallId: string;\n output: unknown;\n};\n\n/**\n * Type predicate that checks if a message part is a completed tool part with output available.\n */\nfunction isCompletedToolPart(\n part: UIMessage['parts'][number]\n): part is CompletedToolPart {\n return (\n isToolUIPart(part) &&\n 'toolCallId' in part &&\n typeof part.toolCallId === 'string' &&\n 'output' in part &&\n part.output !== undefined &&\n 'state' in part &&\n part.state === 'output-available'\n );\n}\n\n/**\n * Extracts completed tool parts from a message's parts array.\n * Returns properly typed CompletedToolPart[] for type-safe access to toolCallId, input, output.\n */\nexport function getCompletedToolParts(\n parts: UIMessage['parts'] | undefined\n): CompletedToolPart[] {\n if (!parts) return [];\n return parts.filter(isCompletedToolPart);\n}\n\n/**\n * Extracts the tool name from a completed tool part.\n * For static tools (type: \"tool-{name}\"), extracts the name portion.\n * For dynamic tools, returns the toolName property.\n */\nexport function getToolNameFromPart(part: CompletedToolPart): string {\n if (part.type === 'dynamic-tool') {\n return part.toolName ?? 'unknown';\n }\n // Static tool: type is \"tool-{name}\"\n return part.type.slice(5);\n}\n","'use client';\n\nimport { useChat } from '@ai-sdk/react';\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { DefaultChatTransport } from 'ai';\nimport {\n type ChangeEvent,\n type FormEvent,\n useCallback,\n useEffect,\n useMemo,\n useRef\n} from 'react';\nimport type { ChatPanelRef } from './components/chat-view/chat-panel/chat-panel.js';\nimport { ExpandedChatView } from './components/chat-view/expanded-chat-view.js';\nimport { ChatView } from './components/chat-view/index.js';\nimport { ExistingCartPrompt } from './components/existing-cart-prompt.js';\nimport { FatalError } from './components/fatal-error.js';\nimport { SpinnerIcon } from './components/icons/spinner-icon.js';\nimport { Uploader } from './components/uploader/index.js';\nimport {\n CLIENT_TOOL_RESPONSE_MESSAGE,\n DEFAULT_AGENT_NAME\n} from './constants.js';\nimport { BigCommerceClientProvider } from './contexts/bigcommerce-client-context.js';\nimport { useBigCommerceCart } from './hooks/use-bigcommerce-cart.js';\nimport { useCartHandlers } from './hooks/use-cart-handlers.js';\nimport { useChatOrchestration } from './hooks/use-chat-orchestration.js';\nimport { useDocumentParser } from './hooks/use-document-parser.js';\nimport { useTakeShapeThread } from './hooks/use-takeshape-thread.js';\nimport { createB2BClient } from './lib/bigcommerce/b2b/client.js';\nimport {\n executeDeferredToolCalls,\n type ToolCall\n} from './lib/chat-tool-execution.js';\nimport { startInactiveSpan } from './lib/tracing.js';\nimport { useChatDisplayStore } from './stores/chat-display-store.js';\nimport { usePurchaseOrderStore } from './stores/purchase-order-store.js';\nimport { validateAndInit } from './stores/session-validation.js';\nimport type { PurchaseOrderChatProps } from './types.js';\nimport {\n getCompletedToolParts,\n getToolNameFromPart\n} from './utils/ai-sdk-helpers.js';\nimport { isFirstResponseComplete } from './utils/processing-helpers.js';\n\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 5 * 60 * 1000 // 5 minutes\n }\n }\n});\n\nexport function PurchaseOrderChat(props: PurchaseOrderChatProps) {\n // NOTE: Do NOT call any store setters here - it triggers the persist middleware\n // which overwrites localStorage before validateAndInit can read the persisted session.\n // TakeShape config is set in validateAndInit after reading localStorage.\n return (\n <QueryClientProvider client={queryClient}>\n <BigCommerceClientProvider client={props.bigcommerce.client}>\n <PurchaseOrderChatInitializer {...props} />\n </BigCommerceClientProvider>\n </QueryClientProvider>\n );\n}\n\n/**\n * Handles session validation before rendering the main app.\n * Validates persisted thread/cart exist, then renders PurchaseOrderChatInner.\n */\nfunction PurchaseOrderChatInitializer(props: PurchaseOrderChatProps) {\n const initStatus = usePurchaseOrderStore((state) => state.ui.initStatus);\n const initError = usePurchaseOrderStore((state) => state.ui.initError);\n const fatalError = usePurchaseOrderStore((state) => state.fatalError);\n const clearInitError = usePurchaseOrderStore((state) => state.clearInitError);\n\n // Run validation when pending (on mount, or after error dismissal)\n useEffect(() => {\n if (initStatus === 'pending') {\n validateAndInit({\n storefrontClient: props.bigcommerce.client,\n b2bClient: createB2BClient({\n channelId: props.bigcommerce.client.channelId,\n getB2BJwt: props.bigcommerce.getB2BJwt\n }),\n takeShapeConfig: props.takeshape\n });\n }\n }, [initStatus, props.bigcommerce, props.takeshape]);\n\n // Show fatal error immediately, regardless of init status\n if (fatalError) {\n return (\n <div\n className={`flex h-full items-center justify-center ${props.className ?? ''}`}\n >\n <FatalError message={fatalError} />\n </div>\n );\n }\n\n // Show loading while pending\n if (initStatus === 'pending') {\n return (\n <div\n className={`flex h-full items-center justify-center ${props.className ?? ''}`}\n >\n <div className=\"flex items-center\">\n <SpinnerIcon size={16} />\n </div>\n </div>\n );\n }\n\n // Show existing cart prompt if orphan cart detected\n if (initStatus === 'existing-cart') {\n return (\n <div\n className={`flex h-full items-center justify-center ${props.className ?? ''}`}\n >\n <ExistingCartPrompt />\n </div>\n );\n }\n\n // Show error screen if validation failed\n if (initError) {\n return (\n <div\n className={`flex h-full flex-col items-center justify-center gap-4 ${props.className ?? ''}`}\n >\n <div className=\"text-center\">\n <p className=\"text-gray-600\">{initError}</p>\n </div>\n <button\n type=\"button\"\n onClick={clearInitError}\n className=\"rounded-md bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2\"\n >\n Start New Session\n </button>\n </div>\n );\n }\n\n return <PurchaseOrderChatInner {...props} />;\n}\n\nfunction PurchaseOrderChatInner({\n className = '',\n agentName = DEFAULT_AGENT_NAME,\n inputName = DEFAULT_AGENT_NAME,\n bigcommerce,\n expandOnReady\n}: PurchaseOrderChatProps) {\n const { sseOrigin, projectId, apiKey } = usePurchaseOrderStore(\n (state) => state.takeshapeConfig\n );\n\n // Get persisted state from store (guaranteed valid - parent checks isInitializing)\n const persistedThreadId = usePurchaseOrderStore(\n (state) => state.chat.threadId\n );\n const input = usePurchaseOrderStore((state) => state.chat.input);\n const persistedMessages = usePurchaseOrderStore(\n (state) => state.chat.messages\n );\n\n const {\n thread,\n isCreating: isCreatingThread,\n createThread\n } = useTakeShapeThread({\n agentName,\n createOnMount: !persistedThreadId, // Only create if no existing thread\n existingThreadId: persistedThreadId\n });\n\n const appState = usePurchaseOrderStore((state) => state.appState);\n const setAppState = usePurchaseOrderStore((state) => state.setAppState);\n const chatPanelRef = useRef<ChatPanelRef | null>(null);\n const agentTurnSpanRef = useRef<ReturnType<typeof startInactiveSpan> | null>(\n null\n );\n const sessionSpanRef = useRef<ReturnType<typeof startInactiveSpan> | null>(\n null\n );\n\n const isExpanded = useChatDisplayStore((state) => state.isExpanded);\n const setExpanded = useChatDisplayStore((state) => state.setExpanded);\n const resetChatDisplay = useChatDisplayStore((state) => state.reset);\n\n // Document parser\n const parser = useDocumentParser();\n\n const bcCart = useBigCommerceCart({\n client: bigcommerce.client,\n onError: (err) => console.error('BigCommerce error:', err)\n });\n\n // Get cart state from Zustand store (persisted)\n const orderId = usePurchaseOrderStore((state) => state.cartifact.orderId);\n const buyerInfo = usePurchaseOrderStore((state) => state.cartifact.buyerInfo);\n const shipToAddress = usePurchaseOrderStore(\n (state) => state.cartifact.shipToAddress\n );\n const billingAddress = usePurchaseOrderStore(\n (state) => state.cartifact.billingAddress\n );\n const poMetadataSet = usePurchaseOrderStore(\n (state) => state.cartifact.poMetadataSet\n );\n const itemWarnings = usePurchaseOrderStore(\n (state) => state.cartifact.itemWarnings\n );\n\n // Get cart actions from Zustand store\n const clearCartifact = usePurchaseOrderStore((state) => state.clearCartifact);\n const clearBcSession = usePurchaseOrderStore((state) => state.clearBcSession);\n const clearAddressSelections = usePurchaseOrderStore(\n (state) => state.clearAddressSelections\n );\n const clearChat = usePurchaseOrderStore((state) => state.clearChat);\n\n // Keep these from bcCart hook - they're API-related state\n const { cartItems } = bcCart;\n\n // Deferred tool calls — recorded in onToolCall, executed after streaming ends.\n // We defer execution because the server may reject the tool call (e.g., validation error).\n // If the server rejects it, we skip client execution to avoid unintended side effects.\n const deferredToolCallsRef = useRef<ToolCall[]>([]);\n\n const onToolCall = useCallback(\n async ({ toolCall }: { toolCall: ToolCall }) => {\n deferredToolCallsRef.current.push(toolCall);\n },\n []\n );\n\n // Tracks toolCallIds of completed async tool outputs, so prepareSendMessagesRequest\n // can filter the assistant message to only include those specific tool results\n const completedToolCallIdsRef = useRef<Set<string>>(new Set());\n\n const { messages, sendMessage, status, error, setMessages, addToolOutput } =\n useChat({\n transport: new DefaultChatTransport({\n api: `${sseOrigin}/project/${projectId}/agents/messages`,\n headers: {\n Authorization: `Bearer ${apiKey}`\n },\n prepareSendMessagesRequest: async (options) => {\n const lastMessage = options.messages[options.messages.length - 1];\n if (!lastMessage) {\n throw new Error('No messages to send');\n }\n\n // When sending a user message, check if the previous message is an assistant\n // message with completed yield tools - if so, include it so the server can\n // extract the tool results and merge them into the conversation history.\n let messagesToSend = [lastMessage];\n if (lastMessage.role === 'user' && options.messages.length >= 2) {\n const prevMessage = options.messages[options.messages.length - 2];\n const ids = completedToolCallIdsRef.current;\n\n if (prevMessage?.role === 'assistant' && ids.size > 0) {\n // Only include tool parts for client-side async tools (yield tools).\n // Server-side tools already have their results in the session history.\n const allCompletedParts = getCompletedToolParts(\n prevMessage.parts\n );\n\n const completedParts = allCompletedParts.filter((p) =>\n ids.has(p.toolCallId)\n );\n\n ids.clear();\n\n if (completedParts.length > 0) {\n const transformedPrevMessage = {\n ...prevMessage,\n parts: completedParts.map((part) => ({\n type: part.type,\n toolName: getToolNameFromPart(part),\n toolCallId: part.toolCallId,\n state: part.state,\n input: part.input,\n output: part.output\n }))\n };\n\n messagesToSend = [transformedPrevMessage, lastMessage];\n }\n }\n }\n\n return {\n body: {\n id: thread.current?.id ?? '',\n messages: messagesToSend,\n trigger: options.trigger,\n messageId: options.messageId,\n metadata: {\n ...(options.requestMetadata as Record<string, unknown>),\n custom: {\n inputName\n }\n }\n }\n };\n }\n }),\n messages: persistedMessages,\n onToolCall,\n onError: (err) => {\n console.error('[useChat onError]', err);\n agentTurnSpanRef.current?.setStatus({\n code: 2,\n message: 'internal_error'\n });\n agentTurnSpanRef.current?.end();\n agentTurnSpanRef.current = null;\n }\n });\n\n const tracedSendMessage = useCallback(\n (params: { text: string }) => {\n agentTurnSpanRef.current?.end();\n agentTurnSpanRef.current = startInactiveSpan({\n name: 'po-agent-turn',\n op: 'ai.agent',\n attributes: {\n 'agent.name': inputName\n }\n });\n sendMessage(params);\n },\n [sendMessage, inputName]\n );\n\n // End agent turn span when status returns to ready\n useEffect(() => {\n if (status === 'ready' && agentTurnSpanRef.current) {\n agentTurnSpanRef.current.setStatus({ code: 1, message: 'ok' });\n agentTurnSpanRef.current.end();\n agentTurnSpanRef.current = null;\n }\n }, [status]);\n\n // Clean up open spans on unmount\n useEffect(() => {\n return () => {\n agentTurnSpanRef.current?.end();\n sessionSpanRef.current?.end();\n };\n }, []);\n\n // When streaming completes and there are deferred tool calls, check if the server\n // already handled each one. If not, execute the client-side handler and send the result.\n // This deferred execution prevents side effects (like adding to cart) when the server\n // rejects a tool call due to validation errors.\n useEffect(() => {\n if (status === 'ready' && deferredToolCallsRef.current.length > 0) {\n const deferredCalls = [...deferredToolCallsRef.current];\n deferredToolCallsRef.current = [];\n\n executeDeferredToolCalls(deferredCalls, messages, bcCart)\n .then(async (result) => {\n for (const output of result.outputs) {\n completedToolCallIdsRef.current.add(output.toolCallId);\n await addToolOutput(output);\n }\n\n if (result.outputs.length > 0) {\n tracedSendMessage({ text: CLIENT_TOOL_RESPONSE_MESSAGE });\n }\n })\n .catch((error) => {\n console.error('[executeDeferredToolCalls] Error:', error);\n });\n }\n }, [status, messages, bcCart, addToolOutput, tracedSendMessage]);\n\n // Sync messages to store for persistence\n useEffect(() => {\n usePurchaseOrderStore.getState().setMessages(messages);\n }, [messages]);\n\n // Send pending messages from the store (allows other components to trigger chat messages)\n const pendingMessage = usePurchaseOrderStore(\n (state) => state.ai.pendingMessage\n );\n const shouldScroll = usePurchaseOrderStore((state) => state.ai.shouldScroll);\n const consumeMessage = usePurchaseOrderStore((state) => state.consumeMessage);\n useEffect(() => {\n if (pendingMessage) {\n tracedSendMessage({ text: pendingMessage });\n consumeMessage();\n if (shouldScroll) {\n requestAnimationFrame(() => {\n chatPanelRef.current?.scrollToBottom();\n });\n }\n }\n }, [pendingMessage, shouldScroll, tracedSendMessage, consumeMessage]);\n\n // Auto-expand when transitioning to chatting state\n // TODO handle this w/o useEffect, eg in an onReady callback\n useEffect(() => {\n if (expandOnReady && appState === 'chatting') {\n setExpanded(true);\n }\n }, [expandOnReady, appState, setExpanded]);\n\n const isLoading =\n isCreatingThread || status === 'submitted' || status === 'streaming';\n\n const firstResponseComplete = useMemo(() => {\n return isFirstResponseComplete(messages, status);\n }, [messages, status]);\n\n // Chat orchestration - handles parser→agent flow and UI state transitions.\n const orchestration = useChatOrchestration({\n appState,\n setAppState,\n parser,\n firstResponseComplete,\n chatPanelRef,\n bcCart\n });\n\n // Cart handlers\n const cartHandlers = useCartHandlers({\n bcCart,\n cartItems,\n onCheckoutInitiated: (error?: Error) => {\n if (error) {\n sessionSpanRef.current?.setStatus({ code: 2, message: error.message });\n } else {\n sessionSpanRef.current?.setStatus({ code: 1, message: 'ok' });\n }\n sessionSpanRef.current?.end();\n sessionSpanRef.current = null;\n },\n onCheckout: bigcommerce.onCheckout\n });\n\n const handleInputChange = (e: ChangeEvent<HTMLTextAreaElement>) => {\n usePurchaseOrderStore.getState().setInput(e.target.value);\n };\n\n const handleSubmit = (e: FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n if (input.trim()) {\n usePurchaseOrderStore.getState().sendMessage(input);\n usePurchaseOrderStore.getState().setInput('');\n }\n };\n\n const handleFileUpload = async (file: File) => {\n sessionSpanRef.current?.end();\n sessionSpanRef.current = startInactiveSpan({\n name: 'upload-to-checkout',\n op: 'purchase-order.session',\n attributes: {\n 'file.name': file.name\n }\n });\n setAppState('processing');\n orchestration.reset();\n const ok = await parser.handleFileUpload(file);\n if (ok === false) {\n setAppState('upload');\n }\n };\n\n const handleViewProduct = useCallback(\n (item: {\n productEntityId?: number;\n sku: string;\n name: string;\n path?: string;\n }) => {\n if (bigcommerce.onViewProduct) {\n bigcommerce.onViewProduct({\n productEntityId: item.productEntityId,\n sku: item.sku,\n name: item.name,\n path: item.path\n });\n }\n },\n [bigcommerce.onViewProduct]\n );\n\n const handleRetry = useCallback(() => {\n const lastUserMessage = [...messages]\n .reverse()\n .find((m) => m.role === 'user');\n if (!lastUserMessage) return;\n\n // Extract text from message parts\n const text = lastUserMessage.parts\n ?.filter(\n (part): part is { type: 'text'; text: string } => part.type === 'text'\n )\n .map((part) => part.text)\n .join('\\n');\n if (!text) return;\n\n // Remove the last user message and any failed response after it\n const lastUserIndex = messages.lastIndexOf(lastUserMessage);\n setMessages(messages.slice(0, lastUserIndex));\n\n // Resend the last user message\n usePurchaseOrderStore.getState().sendMessage(text);\n }, [messages, setMessages]);\n\n const handleSkip = useCallback(() => {\n setAppState('chatting');\n }, [setAppState]);\n\n const resetBatchProcessing = usePurchaseOrderStore(\n (state) => state.resetBatchProcessing\n );\n\n const handleStartOver = useCallback(async () => {\n sessionSpanRef.current?.setStatus({ code: 2, message: 'cancelled' });\n sessionSpanRef.current?.end();\n sessionSpanRef.current = null;\n\n // Clear BigCommerce cart via API\n await bcCart.clearCart();\n\n // Clear Zustand store state\n clearCartifact();\n clearBcSession();\n clearAddressSelections();\n\n // Clear chat state in Zustand store (messages, input, threadId)\n // Also clear useChat's internal state to stay in sync\n clearChat();\n setMessages([]);\n resetBatchProcessing();\n resetChatDisplay();\n parser.reset();\n orchestration.reset();\n\n setAppState('upload');\n\n createThread();\n }, [\n bcCart.clearCart,\n clearCartifact,\n clearBcSession,\n clearAddressSelections,\n clearChat,\n setMessages,\n resetBatchProcessing,\n resetChatDisplay,\n parser.reset,\n orchestration.reset,\n createThread,\n setAppState\n ]);\n\n // Upload step - shown before chat/cart, and during processing\n if (appState === 'upload' || appState === 'processing') {\n return (\n <div className={`flex h-full ${className}`}>\n <Uploader\n onFileUpload={handleFileUpload}\n onSkip={handleSkip}\n onClearError={parser.handleClearError}\n cartItems={cartItems}\n isUploading={parser.isUploadingFile}\n parserError={parser.parserError}\n />\n </div>\n );\n }\n\n const chatViewProps = {\n className,\n messages,\n input,\n onInputChange: handleInputChange,\n onSubmit: handleSubmit,\n isLoading,\n error,\n onRetry: error ? handleRetry : undefined,\n hasProcessedDocument: orchestration.hasProcessedDocument,\n uploadedFileName: parser.uploadedFileName,\n chatPanelRef,\n onFileUpload: handleFileUpload,\n cartItems,\n itemWarnings,\n onUpdateQuantity: cartHandlers.handleUpdateQuantity,\n onRemove: cartHandlers.handleRemoveItem,\n onCheckout: cartHandlers.handleCheckout,\n onSuggestAlternatives: cartHandlers.handleSuggestAlternatives,\n onShowMoreLikeThis: cartHandlers.handleShowMoreLikeThis,\n onViewProduct: bigcommerce.onViewProduct ? handleViewProduct : undefined,\n onAddToCart: cartHandlers.handleAddToCartFromSuggestion,\n orderId,\n buyerInfo,\n customerInfo: bcCart.customerInfo ?? undefined,\n addresses: bcCart.customerAddresses,\n selectedAddressId: bcCart.selectedAddressId ?? undefined,\n addressUpdateStatus: bcCart.addressUpdateStatus,\n onAddressChange: bcCart.setShippingAddressOnCheckout,\n selectedBillingAddressId: bcCart.selectedBillingAddressId ?? undefined,\n billingAddressUpdateStatus: bcCart.billingAddressUpdateStatus,\n onBillingAddressChange: bcCart.setBillingAddressOnCheckout,\n shipToAddress,\n billingAddress: billingAddress ?? undefined,\n checkoutTotals: bcCart.checkoutTotals,\n isCartLoading: bcCart.isLoading,\n poMetadataSet,\n onNewOrder: handleStartOver\n };\n\n if (expandOnReady && isExpanded) {\n return (\n <ExpandedChatView>\n <ChatView {...chatViewProps} onMinimize={() => setExpanded(false)} />\n </ExpandedChatView>\n );\n }\n\n return (\n <div className=\"h-full max-w-[1440px] mx-auto\">\n <ChatView\n {...chatViewProps}\n onExpand={expandOnReady ? () => setExpanded(true) : undefined}\n />\n </div>\n );\n}\n","'use client';\n\nimport { useMemo } from 'react';\nimport { DEFAULT_AGENT_NAME, DEFAULT_ORIGIN } from './constants.js';\nimport { createBigCommerceClient } from './lib/bigcommerce/storefront/client.js';\nimport { PurchaseOrderChat } from './purchase-order-chat.js';\nimport type { PurchaseOrderChatWidgetProps } from './types.js';\n\n/**\n * Simplified PurchaseOrderChatWidget component that handles all configuration internally.\n * This is the recommended way to integrate the component in most applications.\n *\n * For advanced use cases requiring custom provider setup, use PurchaseOrderChat directly.\n */\nexport function PurchaseOrderChatWidget({\n takeshape,\n bigcommerce,\n agentName = DEFAULT_AGENT_NAME,\n inputName = DEFAULT_AGENT_NAME,\n onViewProduct,\n onCheckout,\n className,\n expandOnReady\n}: PurchaseOrderChatWidgetProps) {\n const bigCommerceClient = useMemo(\n () =>\n createBigCommerceClient({\n endpoint: bigcommerce.endpoint,\n storefrontToken: bigcommerce.storefrontToken,\n channelId: bigcommerce.channelId\n }),\n [bigcommerce.endpoint, bigcommerce.storefrontToken, bigcommerce.channelId]\n );\n\n return (\n <PurchaseOrderChat\n agentName={agentName}\n inputName={inputName}\n className={className}\n expandOnReady={expandOnReady}\n takeshape={{\n projectId: takeshape.projectId,\n apiKey: takeshape.apiKey,\n origin: takeshape.origin ?? DEFAULT_ORIGIN,\n sseOrigin: takeshape.sseOrigin ?? DEFAULT_ORIGIN\n }}\n bigcommerce={{\n client: bigCommerceClient,\n onViewProduct,\n onCheckout,\n getB2BJwt: bigcommerce.getB2BJwt\n }}\n />\n );\n}\n"],"names":["cn","inputs","twMerge","clsx","resolveProductPath","template","product","_","key","value","globalVarName","eventName","getCurrent","StylesTarget","props","stylesMap","setStylesMap","useState","version","setVersion","useEffect","updateListener","_e","newValues","v","entry","createElement","DEFAULT_AGENT_NAME","DEFAULT_ORIGIN","B2B_GRAPHQL_URL","B2B_APP_CLIENT_ID","CLIENT_TOOL_RESPONSE_MESSAGE","PO_ADDRESS_ID","PO_BILLING_ADDRESS_ID","CHECKOUT_ADDRESS_ID","STORAGE_KEY","STORAGE_VERSION","getNativeFetch","iframe","iframeFetch","_nativeFetch","nativeFetch","graphql","initGraphQLTada","UserAuthorizationFragment","AuthorizationMutation","UserFragment","CurrentUserQuery","CompanyAddressFragment","CompanyAddressesQuery","CheckoutLoginMutation","CartFragment","GetCartQuery","CreateCartMutation","AddCartLineItemsMutation","UpdateCartLineItemMutation","DeleteCartLineItemMutation","DeleteCartMutation","CreateCartRedirectUrlsMutation","CreateCartMetafieldMutation","CheckoutFragment","GetCheckoutQuery","AddCheckoutShippingConsignmentsMutation","AddCheckoutBillingAddressMutation","UpdateCheckoutCustomerMessageMutation","GetProductVariantDetailsQuery","GetProductsForDisplayQuery","GetProductVariantsForDisplayPageQuery","CustomerAddressFragment","GetCustomerAddressesQuery","GetProductVariantsPageQuery","GetProductOptionsPageQuery","GetProductPathsQuery","GetProductOptionValuesPageQuery","convertCompanyAddressToCustomerAddress","companyAddress","address","readFragment","convertCustomerAddressToCustomerAddress","customerAddress","index","convertPoAddressToCustomerAddress","addr","options","MAX_PAGES","fetchAllPages","client","document","baseVariables","getConnection","allEdges","after","pages","variables","result","connection","CART_BATCH_SIZE","toCart","raw","toCheckout","resolveEndpoint","endpoint","BigCommerceClient","config","headers","GraphQLClient","attempt","delays","error","delay","resolve","err","ClientError","next","retry","reject","cartEntityId","cart","lineItems","previousErrors","errors","firstBatch","remainingItems","updatedCart","batchErrors","isolatedCart","isolatedErrors","batch","rawCart","item","message","mid","left","right","leftResult","rightResult","i","lineItemEntityId","quantity","productEntityId","variantEntityId","existingCartId","checkoutEntityId","rawCheckout","customerInfo","allAddressEdges","additionalEdges","r","addresses","edge","productEntityIds","products","allVariantEdges","additionalVariants","allOptionEdges","additionalOptions","paginatedValueEdges","optionEdge","node","additionalValues","firstEdge","values","valueEdge","variantEdge","paths","createBigCommerceEndpoint","storeHash","createBigCommerceClient","useChatDisplayStore","create","set","expanded","state","ExpandedChatView","children","isExpanded","setExpanded","overlayRef","useRef","handleKeyDown","e","useLayoutEffect","scrollY","originalOverflow","originalPosition","originalTop","originalWidth","root","host","prev","jsxs","jsx","HEIC_MIME_TYPES","HEIC_EXTENSIONS","getExtension","filename","dot","isHeic","file","toJpegName","name","convertNative","quality","bitmap","canvas","blob","convertWithLibheif","HeifDecoder","buffer","reader","image","width","height","ctx","imageData","convertHeicIfNeeded","native","ALLOWED_FILE_TYPES","ALLOWED_TYPES","ALLOWED_EXTENSIONS","KNOWN_IMAGE_EXTENSIONS","ACCEPTED_EXTENSIONS","ACCEPTED_CAMERA_TYPES","ALLOWED_TYPES_DISPLAY","ALLOWED_IMAGE_TYPES_DISPLAY","FILE_TYPE_LABELS","MAX_FILE_SIZE","validateFile","ext","useFileDrop","onFile","onBeforeValidate","isDragging","setIsDragging","fileError","setFileError","fileInputRef","cameraInputRef","processFile","useCallback","fileToValidate","handleDragOver","handleDragLeave","handleDrop","handleFileChange","openFilePicker","openCamera","CartIcon","CheckIcon","size","title","CopyIcon","MaximizeIcon","MinimizeIcon","AlertCircleIcon","SpinnerIcon","CartifactAddress","selectedAddressId","addressUpdateStatus","onAddressChange","shipToAddress","billingAddress","selectedBillingAddressId","billingAddressUpdateStatus","onBillingAddressChange","canShowDefaultAddressWarning","AddressSelect","label","poAddress","defaultAddressFilter","addressFilter","isCheckoutAddress","defaultAddress","showDefaultAddressWarning","addressOptions","Fragment","AddressSelectOption","FormattedAddress","isDefault","formatAddress","parts","lastPart","isCopied","setIsCopied","timerRef","formattedAddress","handleCopy","formatCurrency","amount","currencyCode","FooterRow","formatOptional","CartifactFooter","subtotal","tax","shipping","total","totalQuantity","availableItemCount","onCheckout","isLoading","allowCheckout","XIcon","baseClass","StepButton","className","QuantitySelector","onChange","min","max","asyncMode","testId","inputValue","setInputValue","status","setStatus","statusTimeoutRef","handleChange","rawValue","newValue","clampedValue","handleBlur","newQty","clampedQty","handleStep","delta","current","base","atMin","atMax","isSaving","CartifactLineItem","onUpdateQuantity","onRemove","onShowMoreLikeThis","onViewProduct","poPriceValue","hasPriceMismatch","currenciesDiffer","isFavorable","qty","CartifactActionButton","PanelActionButton","CartifactNewOrder","onNewOrder","confirmingReset","setConfirmingReset","isResetting","setIsResetting","mountedRef","resetTimerRef","handleNewOrderClick","handleConfirmReset","handleCancelReset","OrderListIcon","EmptyCartifact","onExpand","onMinimize","hasHeaderButtons","initialAIState","createAISlice","initialBatchProcessorState","createBatchProcessorSlice","results","processingFailuresString","newCall","threadId","initialBcSessionState","createBcSessionSlice","bcCart","checkout","productPaths","makePoItemPriceKey","initialCartifactState","createCartifactSlice","poPrice","poCurrency","newPrices","orderId","buyerInfo","poMetadataSet","itemWarnings","warning","w","poMetadata","updates","initialChatState","createChatSlice","messages","input","toolCallId","initialCustomerState","createCustomerSlice","customerAddresses","initialParserState","createParserSlice","uploadedFileName","parsedContent","hasProcessedDocument","INITIAL_STATE","createTakeShapeConfigSlice","initialUIState","createUISlice","messageId","ids","id","getCleanState","usePurchaseOrderStore","devtools","persist","get","customerEntityId","fatalError","appState","s","existingCart","data","itemWarningToString","productName","productSku","LineItemWarning","onSuggestAlternatives","removeItemWarning","CartPanel","items","checkoutTotals","copied","setCopied","copyTimeoutRef","handleCopyOrderId","sum","availableItems","displayTax","displayShipping","displayTotal","identifier","networkErrorPatterns","isOfflineError","pattern","ChatError","onRetry","offline","SendIcon","ChatInput","onInputChange","onSubmit","form","SHOW_PRODUCTS_TOOL_NAME","SEARCH_PRODUCTS_TOOL_NAME","SEARCH_PRODUCTS_BY_SKU_TOOL_NAME","ADD_TO_CART_TOOL_NAME","UPDATE_CART_TOOL_NAME","REMOVE_FROM_CART_TOOL_NAME","CLEAR_CART_TOOL_NAME","GET_CART_TOOL_NAME","GET_PURCHASE_ORDER_DATA_TOOL_NAME","SET_PO_METADATA_TOOL_NAME","SET_ITEM_WARNINGS_TOOL_NAME","REMOVE_ITEM_WARNINGS_TOOL_NAME","ADD_PROCESSING_FAILURES_TOOL_NAME","NON_COLLAPSIBLE_TOOLS","isCollapsibleTool","part","groupRenderableParts","accumulator","flush","FileIcon","ExpandChevronIcon","GenericToolMessage","loadingMessage","failedMessage","successMessage","toolOutput","hasError","hasFailed","variant","parseToolOutput","output","SearchProductsBySkuTool","toolInput","toolState","sku","count","SearchProductsTool","terms","BigCommerceClientContext","createContext","BigCommerceClientProvider","useBigCommerceClient","useContext","useProductVariants","useQuery","a","b","getVariantOptionValues","map","option","selectedValue","findMatchingVariant","variants","selections","variantValues","optionId","valueId","getInitialSelections","details","defaultValue","firstVariant","PlaceholderImage","VariantPicker","variantDetails","onSelectionChange","hasInvalidCombination","LOW_STOCK_QUANTITY","addToCartButtonClass","isAdding","showAdded","isDisabled","ProductCard","onAddToCart","layout","setQuantity","setIsAdding","setShowAdded","isHorizontal","selectedVariant","selectedVariantEntityId","cartItem","inCart","cartQuantity","displaySku","displayPrice","displayAvailableQuantity","lowStock","displayIsInStock","isOutOfStock","handleAddToCart","variantImageUrl","productImageUrl","imageUrl","lowStockWarning","ProductGrid","loadingText","useMemo","p","variantDetailsArray","variantDetailsMap","selectionsMap","setSelectionsMap","d","requestedVariant","handleSelectionChange","productId","optionEntityId","valueEntityId","availableProducts","singleProduct","ShowProductsTool","setProducts","setIsLoading","setError","isToolLoading","fetchProducts","productsData","transformedProducts","inputProduct","productData","Tool","toolName","CollapsibleToolCalls","tools","setIsExpanded","toolPart","Thread","z","parseSSEStream","response","callbacks","toolCalls","serverHandledToolCallIds","textParts","finishReason","errorMessage","parseJsonEventStream","uiMessageChunkSchema","done","chunk","toolCall","tc","createAgentThread","takeshapeConfig","agentName","origin","projectId","apiKey","text","sendAgentMessage","sseOrigin","errorDetail","json","match","SEND_FEEDBACK_MUTATION","sendFeedback","feedback","NOOP_SPAN","sentryModule","initTracing","sentry","startInactiveSpan","captureFeedback","FeedbackDialog","isOpen","onClose","setName","email","setEmail","setText","setErrorMessage","nameInputRef","chatThreadId","parserThreadId","batchThreadIds","handleSubmit","FeedbackIcon","CollapsibleAgentMessage","messagePartId","isLatestAssistantMessage","previewText","expandedMessageIds","toggleMessageExpanded","isDialogOpen","setIsDialogOpen","Streamdown","getOrderedParts","getFilename","filePart","ChatMessage","isFirstUserMessage","isDocumentExpanded","onToggleDocument","isAssistant","orderedParts","useTouchDevice","isTouch","setIsTouch","mq","handler","UploadDocumentIcon","CameraIcon","CameraButton","onClick","ChatPanelEmptyState","onFileChange","onDropZoneClick","onCameraClick","isTouchDevice","TypingIndicator","ChatPanel","forwardRef","fileDrop","ref","scrollContainerRef","shouldAutoScrollRef","setIsDocumentExpanded","latestAssistantMessageId","msg","useImperativeHandle","container","handleScroll","isNearBottom","observer","messageIndex","USER_SETTINGS_STORAGE_KEY","DEFAULT_PANEL_WIDTH","useUserSettingsStore","panelWidth","useResizablePanel","leftPanelWidth","setPanelWidth","isDesktop","setIsDesktop","containerRef","leftPanelWidthRef","updateLayout","handleMouseMove","containerRect","newWidth","clampedWidth","handleMouseUp","handleMouseDown","TabBar","activeTab","onTabChange","hasUnread","chatHasUnread","ChatView","chatPanelRef","onFileUpload","cartItems","isCartLoading","panel","setActiveTab","setHasUnread","prevMessageCount","activeTabRef","isBothEmpty","handleTabChange","tab","chatPanel","cartPanel","dragHandlers","ExistingCartPrompt","confirmClearExistingCart","isClearing","setIsClearing","itemCount","handleClearCart","FatalError","useProcessingState","batchProcessingStatus","steps","ProcessingSteps","_props","step","UploadDropZone","acceptedExtensions","InitialState","displayError","onSkip","handleCameraClick","CartPreview","isUploading","currentStep","hasProducts","isReadingOrMatching","isBuildingCart","TARGET_TOTAL_MS","MIN_INTERVAL_MS","computeInterval","totalItems","useProgressiveCartItems","isReady","revealedCount","setRevealedCount","interval","timer","REVEAL_INTERVAL_MS","useProgressiveToolCalls","incrementRevealed","visibleToolCalls","STEP_ORDER","getProcessingStepStatus","stepId","currentIndex","stepIndex","isFirstResponseComplete","getResultCount","parsed","queryResult","TOOL_CALL_RENDERERS","args","resultCount","renderToolCall","renderer","STEPS","statusStyles","ProcessingStepsVertical","currentToolCall","fileNameContent","toolCallContent","cartProgressContent","Processing","Uploader","onClearError","parserError","isProcessing","handleDropZoneClick","toCheckoutAddress","findMatchingCustomerAddress","catalogPrice","mergePoCartItems","existing","incoming","merged","newItem","existingIndex","diffCartItems","cartPhysicalItems","incomingItems","toAdd","toUpdate","existingCartItem","ci","buildSyncedCartResult","syncedCart","mergedItems","storedItem","si","mismatch","normalizeProductSku","normalizeProductName","filterMatchingWarnings","warnings","useBigCommerceCart","onError","clientRef","onErrorRef","poItemPrices","setBcCart","setCheckout","setSelectedAddressId","setAddressUpdateStatus","setProductPaths","setSelectedBillingAddressId","setBillingAddressUpdateStatus","setItemWarnings","storedCartItems","priceData","fetchedPathIdsRef","updateCheckoutShippingAddress","updatedCheckout","updateCheckoutBillingAddress","missingIds","newPaths","newPathsRecord","path","currentPaths","shippingAddressAppliedRef","billingAddressAppliedRef","addressId","checkoutAddress","addressStatusTimeoutRef","billingAddressStatusTimeoutRef","hasMismatch","reapplyShippingAddressAfterCartChange","syncCartItems","allErrors","addedCart","addErrors","update","createdCart","createErrors","store","finalCartItemKeys","storedKeys","variantId","newCartItems","currentWarnings","filteredWarnings","addToCart","mergedInput","itemsToSet","updateLineItemQuantity","lineItemId","removeLineItem","removedItems","stored","removed","initiateCheckout","setShippingAddressOnCheckout","setBillingAddressOnCheckout","clearCart","useCartHandlers","onCheckoutInitiated","sendMessage","handleCheckout","redirectUrls","handleUpdateQuantity","itemId","handleRemoveItem","handleAddToCartFromSuggestion","actualQuantity","handleSuggestAlternatives","itemName","handleShowMoreLikeThis","BATCH_CLIENT_TOOLS","NO_OUTPUT_ERROR","formatToolCallsSummary","clientToolNames","processBatch","batchContent","batchIndex","allToolCalls","allTextParts","accumulatedMessages","pendingClientToolCalls","maxIterations","iterations","streamResult","clientToolCalls","textOutput","toolCallsSummary","addToCartItemCount","failureCount","failures","processAllBatches","batches","threadIds","errorMsg","pMap","hasErrors","mergeClientToolCalls","addToCartItems","setPoMetadataArgs","processingFailures","batchAddToCartCount","batchFailureCount","formatProcessingFailures","lines","f","formatCartBatchErrors","executeMergedClientToolCalls","cartErrors","cartErrorString","coreResult","processAllBatchesCore","_batchIndex","useBatchProcessor","setBatchProcessingStatus","setBatchProcessingError","setBatchProcessingResults","resetBatchProcessing","failedCount","useChatOrchestration","setAppState","parser","firstResponseComplete","hasSentToPOAgent","setHasProcessedDocument","processBatches","DOCUMENT_PARSER_BATCH_DELIMITER","splitDocumentParserOutput","readFileAsText","readFileAsDataUrl","SPREADSHEET_TYPES","isSpreadsheet","mimeType","convertSpreadsheetToCsv","xlsx","workbook","allRows","sheet","rows","PDF_HEADER","PDF_EOF","MIN_PDF_SIZE","readFileAsArrayBuffer","validatePdf","tailSize","trailerStart","trailerText","start","end","pdfjsWorker","getDocument","loadingTask","TEXT_BASED_TYPES","PARSE_PROMPT","buildTextParts","fileName","content","buildFileParts","dataUrl","mediaType","useFileUpload","createParserThread","sendParserMessage","isUploadingFile","setIsUploadingFile","setParserError","handleFileUpload","csvContent","textContent","useTakeShapeThread","createOnMount","existingThreadId","onThreadCreated","isCreating","setIsCreating","thread","createThread","maxRetries","backoffMs","useDocumentParser","setParserThreadId","parserThread","parserSpanRef","parserMessages","parserStatus","setParserMessages","useChat","DefaultChatTransport","lastMessage","baseHandleFileUpload","handleClearError","reset","B2BClient","jwt","token","companyId","addressEdges","cartId","redirectedCheckoutUrl","createB2BClient","stencilB2BJwt","channelId","customerJwt","resp","setToolCallError","handleGetCart","cartData","handleGetPurchaseOrderData","handleRemoveFromCart","matchingItems","handleRemoveItemWarnings","remaining","handleSetItemWarnings","handleSetPoMetadata","handleUpdateCart","setPoItemPrice","itemsUpdated","bcCartItem","toolHandlers","CHAT_CLIENT_TOOL_NAMES","handleToolCall","findServerHandledTool","m","executeDeferredToolCalls","deferredCalls","completedToolCallIds","outputs","serverHandledTool","errorText","loadPersistedSession","storedVersion","clearPersistedSession","validateCustomer","persistedCustomerEntityId","validateThread","_threadId","_config","validateCart","validateAndInit","deps","loadResult","fetchedAddresses","fetchedCustomerInfo","companyAddresses","orphanCart","persistedData","fetchedCart","validationPromises","failedResult","isCompletedToolPart","isToolUIPart","getCompletedToolParts","getToolNameFromPart","queryClient","QueryClient","PurchaseOrderChat","QueryClientProvider","PurchaseOrderChatInitializer","initStatus","initError","clearInitError","PurchaseOrderChatInner","inputName","bigcommerce","expandOnReady","persistedThreadId","persistedMessages","isCreatingThread","agentTurnSpanRef","sessionSpanRef","resetChatDisplay","clearCartifact","clearBcSession","clearAddressSelections","clearChat","deferredToolCallsRef","onToolCall","completedToolCallIdsRef","setMessages","addToolOutput","messagesToSend","prevMessage","completedParts","tracedSendMessage","params","pendingMessage","shouldScroll","consumeMessage","orchestration","cartHandlers","handleInputChange","handleViewProduct","handleRetry","lastUserMessage","lastUserIndex","handleSkip","handleStartOver","chatViewProps","PurchaseOrderChatWidget","takeshape","bigCommerceClient"],"mappings":"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"}
|