@cimulate/copilot-widget

中文文档
1.55.1发布于 2026/11/07MITTypeScriptESM + CJS近 30 天下载 4606

A frontend SDK for Cimulate Copilot

原始使用文档
文档目录12 节
  1. Installation
  2. Bundle size snapshots
  3. Playgrounds
  4. React App Playground
  5. HTML / CDN Integration Playground
  6. Messaging Page Context
  7. Messaging Cart
  8. Linting and pre-commit hooks
  9. Publish Flow
  10. Creating Symlinks
  11. copilot-sdk
  12. agentforce-sdk

Copilot Widget SDK

Cimulate's Copilot Widget SDK is a React component library which allows you to embed our Copilot Widget into your app.

Installation

Requires Node >= 22.15.0 and npm >= 10.9.2

npm install @cimulate/copilot-widget

NPM hosts must provide react and react-dom (^18.3 || ^19). The published ESM artifacts import those peers from the host (they are not bundled). CDN/UMD <script> installs are unchanged and still bundle React.

Bundle size snapshots

Use npm run measure:bundle-sizes to capture before/after gzip sizes for an optimization. Run everything from this directory after a fresh npm run build so dist/ matches the code under test.

One session = one timestamp folder under .tmp/bundle-sizes/<DD-MM-YYYY-HHmmss>/ with bundle-sizes.before.json and bundle-sizes.after.json. .tmp/ is gitignored — paste the --diff table into the PR if you need a durable record.

# 1. Baseline (before the change)
npm run build
npm run measure:bundle-sizes -- --before

# 2. Apply the change, rebuild, capture after
npm run build
npm run measure:bundle-sizes -- --after

# 3. Diff the latest session
npm run measure:bundle-sizes -- --diff
  • Build before every capture; a stale dist/ produces wrong numbers.
  • One change per session — run a new --before for each optimization/PR.
  • Don’t start another --before until you’ve finished --after / --diff for the current pair; --after and bare --diff always use the latest timestamp directory.
  • To diff an older pair explicitly:
npm run measure:bundle-sizes -- --diff \
  .tmp/bundle-sizes/<timestamp>/bundle-sizes.before.json \
  .tmp/bundle-sizes/<timestamp>/bundle-sizes.after.json

Playgrounds

React App Playground

npm start

Simulates a React environment. Faster for local development because Vite serves source via hot-module replacement — no full build is required, and changes reflect instantly in the browser. This is the most appropriate testing playground for customers who will integrate the widget in a React-based storefront.

Settings are in src/App.tsx. Example configurations you can modify:

// Theme definitions
const THEMES: Record<string, ThemeConfig> = {
  sfra: {
    primaryColor: "#0070D2",
    fontFamily: '"Helvetica Neue", Arial, sans-serif',
    backgroundColor: "#F7F7F7",
    // ...
  },
  "storefront-next": {
    primaryColor: "#000000",
    fontFamily: '"Inter", sans-serif',
    backgroundColor: "#FFFFFF",
    // ...
  },
};

// Copilot mode props
<CopilotWidget
  apiKey={apiKey}
  theme={currentTheme}
  logoUrl="https://example.com/logo.png"
  headerText="Cimulate Copilot"
  isDevelopment={true}
/>

// Agentforce/Messaging mode props
<AgentForceWidget
  headerText="Commerce Client"
  disclaimerMarkdown="This is AI, *be careful*."
  isDevelopment={true}
  theme={currentTheme}
  searchConfig={{
    placeholder: "Find me cutting-edge outdoor gear",
    buttonType: "icon",
    buttonIcon: "arrow",
  }}
  messagingConfig={{
    scrt2Url: "",
    orgId: "",
    esDeveloperName: "AgentForce",
  }}
/>

Messaging mode: append ?ccDevMode=true to the page URL to force isDevelopment on at runtime (staging endpoints + verbose logging), with no redeploy required.

HTML / CDN Integration Playground

npm run preview

The most common integration method because it is framework-agnostic. Any changes to the widget should be tested on this playground. It is slower for local development because it must produce a full build of all three artifacts (main bundle, copilot sub-bundle, messaging sub-bundle) and requires a rebuild on every change.

Settings are in public/index.html. Example configurations you can modify:

<script>
  // Widget injection with configuration
  injectCopilotWidget({
    elementId: "root",
    apiKey: "INSERT_YOUR_API_KEY_HERE",
    componentConfig: { isOpen: true, options: { dialogPosition: "bottom-right" } },
    isDevelopment: true,
    mode: "copilot",
    theme: {
      primaryColor: "#000000",
      fontFamily: '"Inter", sans-serif',
      backgroundColor: "#FFFFFF",
    },
    headerText: "Commerce Client",
    searchConfig: {
      placeholder: "Find me cutting-edge outdoor gear",
      buttonType: "icon",
      buttonIcon: "arrow",
    },
  });

  // Event handlers for programmatic control
  const { eventHandlers } = window["cimulate-copilot-widget"];

  eventHandlers.search.updateSearchQuery("running shoes");
  eventHandlers.components.setWidgetType("modal"); // "chat" | "dialog" | "modal"
  eventHandlers.components.toggleWidgetOpen(true);
  eventHandlers.pdp.setPdpContext({ productId: "product-123" });
  eventHandlers.browse.setBrowseContext({ categoryId: "outdoor-gear" });

  // Messaging mode: submit a query from a storefront search bar or embedded question
  const { sendMessage, eventHandlers: messagingHandlers } = window.CimulateMessaging;
  sendMessage("running shoes");
  messagingHandlers.components.toggleWidgetOpen(true);
</script>

Messaging Page Context

Messaging integrations provide normalized Product Detail Page (PDP) or Search Results Page (SRP) storefront state through the generic page-context API:

import { eventHandlers } from "@cimulate/copilot-widget/messaging";

eventHandlers.pageContext.set({
  type: "pdp",
  id: "product-123",
  display: {
    name: "Deep Cleansing Foam",
    imageUrl: "https://store.example.com/products/foam.jpg",
  },
});

eventHandlers.pageContext.set({
  type: "srp",
  query: "running shoes",
  refinements: [{ name: "color", values: ["blue"] }],
  minPrice: 50,
  maxPrice: 150,
});

const current = eventHandlers.pageContext.get();

eventHandlers.pageContext.clear();

refinements, minPrice, and maxPrice are optional for SRP context. The widget omits empty refinements and undefined price bounds. PDP and SRP context are mutually exclusive.

To seed page context once at mount (same shape as eventHandlers.pageContext.set), pass messagingConfig.initialPageContext with enablePageContext: true. Later runtime updates still go through the event handler.

<AgentForceWidget
  mode="messaging"
  messagingConfig={{
    enablePageContext: true,
    initialPageContext: {
      type: "srp",
      query: "running shoes",
      refinements: [{ name: "color", values: ["blue"] }],
      minPrice: 50,
      maxPrice: 150,
    },
    // existing SCRT2 fields...
  }}
/>

With messagingConfig.enablePageContext, the widget snapshots the page context when a shopper sends a text message and reuses it for retries and session recovery. The first text message after each PDP or SRP context switch gets a divider above its user bubble. Changing pages never sends a message on its own. File uploads do not carry page context or create dividers.

The optional PDP display fields set the product chip and divider's name and image. SRP context shows a removable chip with a search icon and Search: "query"; its divider uses the same label. Only one context chip is shown at a time. Removing either chip clears page context, so the next message has no context or divider. The chip remains visible for later messages on the same product or search query. Setting SRP context replaces the PDP chip, and setting PDP context replaces the SRP chip.

Messaging Cart

Messaging integrations push the shopper's current basket with eventHandlers.cart.update. Call it from the messaging entry only: window.CimulateMessaging.eventHandlers.cart.update(cart) on the CDN, or the NPM import below. The Copilot entry does not expose it.

import { eventHandlers } from "@cimulate/copilot-widget/messaging";

eventHandlers.cart.update({
  id: "cart-1",
  currencyCode: "USD",
  subtotal: 90,
  total: 90,
  items: [
    {
      itemId: "line-1",
      productId: "SKU-1",
      name: "Men's Rovereto Running Shoes",
      imageUrl: "https://store.example.com/products/shoes.jpg",
      quantity: 1,
      itemSubtotal: 90,
      originalSubtotal: 90,
      variants: [{ lbl: "Color", type: "color", value: "Black / White" }],
    },
  ],
});

The object is the full basket (CartDetails), not a quantity stub. An empty items array means an empty cart. A payload without an items array is ignored. A call before the widget is mounted is ignored.

Call it after the widget is mounted, on page load, after the shopper changes the basket outside the widget, and again after a restored conversation. The latest cart message in the chat updates to that basket. Older cart messages stay as they were. The call does not emit cimulate:cart-update. The next agent cart result is compared with that basket.

Linting and pre-commit hooks

Lint and format locally with the npm scripts:

npm run lint       # prettier --check + eslint
npm run lint:fix   # prettier --write + eslint --fix

ESLint enforces the commenting guardrails from AGENTS.md via two local rules (local/banner-comments, local/redundant-identifier-comment in eslint-rules/).

A pre-commit hook (.pre-commit-config.yaml) runs prettier + eslint on the copilot-widget files you're committing and fails the commit on formatting/lint errors. It uses the same pre-commit framework as the Python subprojects (see docs/development/development-workflow.md).

npm run start and npm run preview auto-install this hook for you (via scripts/ensure-precommit.sh) as long as the pre-commit tool is on your PATH. If you see a pre-commit' is NOT installed warning when starting the dev server, install the tool and it will wire itself up on the next start:

brew install pre-commit   # macOS (recommended — avoids pyenv/venv shim issues)
pip install pre-commit    # any platform

To set the hook up manually (or if you don't use the dev server), run once from this directory:

cd javascript/copilot-widget
brew install pre-commit   # or: pip install pre-commit
pre-commit install

The hook only lints staged files, so pre-existing issues elsewhere won't block your commit.

Publish Flow

This project follows trunk-based development — all changes merge directly to master. The package uses semantic versioning; bump the version in package.json before merging. Be mindful of backwards-compatibility since customers have existing implementations relying on the public API.

Publishing is handled automatically by the Build and Publish Javascript Packages GitHub Actions workflow (.github/workflows/build-and-publish-js.yaml).

Trigger: Push to master with changes under javascript/ (only runs for copilot-widget).

Steps:

  1. Install dependencies
  2. Run tests (npm run test)
  3. Build (npm run build)
  4. Publish to npm (npm publish --access public)
  5. Upload UMD bundles and CSS to a Google Cloud Storage bucket for CDN delivery, versioned by the package version:
    <bucket>/copilot-widget/<version>/*.umd.js
    <bucket>/copilot-widget/<version>/*.css
    

To develop against local versions of the SDK dependencies, use npm link:

copilot-sdk

# In javascript/copilot-sdk
npm install
npm run build
npm link

# In javascript/copilot-widget
npm link @cimulate/copilot-sdk

agentforce-sdk

# In javascript/agentforce-sdk
npm install
npm run build
npm link

# In javascript/copilot-widget
npm link @cimulate/agentforce-sdk

To unlink and restore the registry version:

npm unlink @cimulate/copilot-sdk
npm unlink @cimulate/agentforce-sdk
npm install

版本与发布记录

@cimulate/copilot-widget 共发布 183 个版本,首次发布于 2025/09/04;过去 12 个月发布了 170 个版本。

版本发布日期距今
1.55.1latest2026/11/072 天前
1.55.02026/11/072 天前
1.54.22026/11/063 天前
1.54.12026/11/063 天前
1.54.02026/11/046 天前
1.53.22026/10/3010 天前

关于 @cimulate/copilot-widget 的常见问题

@cimulate/copilot-widget 是什么?

A frontend SDK for Cimulate Copilot

如何安装 @cimulate/copilot-widget?

在项目目录运行 npm install @cimulate/copilot-widget,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(^18.3 || ^19)、react-dom(^18.3 || ^19)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@cimulate/copilot-widget 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cimulate/copilot-widget 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@cimulate/copilot-widget 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.15.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@cimulate/copilot-widget 可以商用吗?

@cimulate/copilot-widget 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@cimulate/copilot-widget 的下载量有多少?

根据 npm 官方下载统计,@cimulate/copilot-widget 在 2026/10/10 – 2026/11/08 这 30 天内被下载 4,606 次,日均约 154 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cimulate/copilot-widget 还在维护吗?

最新版本 1.55.1 发布于 2026/11/07(2 天前);至今共发布 183 个版本,其中过去 12 个月发布了 170 个;首次发布于 2025/09/04。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。