npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@keyueclaw/web-sdk

v0.1.64

Published

KeyueClaw Web SDK

Downloads

4,358

Readme

@keyueclaw/web-sdk

KeyueClaw Web SDK — 基于 Lit 的可嵌入 Web Component 集合,让外部系统一行代码接入 AI 对话、技能管理、接口管理和技能组件管理能力。

安装

npm install @keyueclaw/web-sdk
# 或
pnpm add @keyueclaw/web-sdk

模块一览

| 模块 | 元素标签 | 用途 | | ---------------- | ------------------------------ | --------------------------------------------------- | | chat | <keyueclaw-chat> | AI 对话聊天 | | skills | <keyueclaw-skills> | 技能管理(创建、编辑、AI 构建、版本发布) | | api-management | <keyueclaw-api-management> | 接口定义管理(CRUD、导入导出) | | skill-components | <keyueclaw-skill-components> | 技能组件管理(创建、编辑、版本发布、变量/API 引用) |

快速开始

ES Module

<link rel="stylesheet" href="@keyueclaw/web-sdk/chat.css" />

<script type="module">
  import "@keyueclaw/web-sdk/chat";

  const el = document.createElement("keyueclaw-chat");
  el.setAttribute("ws-base-url", "ws://your-server/keyueclaw");
  el.setAttribute("http-base-url", "http://your-server");
  el.setAttribute("tenant-id", "your-tenant-id");
  el.setAttribute("bot-id", "your-bot-id");
  el.setAttribute("phone", "13800138000");
  document.getElementById("chat-root").appendChild(el);
</script>

UMD (script 标签)

<link rel="stylesheet" href="@keyueclaw/web-sdk/chat.css" />
<script src="@keyueclaw/web-sdk/chat.umd.cjs"></script>
<script>
  const el = document.createElement("keyueclaw-chat");
  el.setAttribute("ws-base-url", "ws://your-server/keyueclaw");
  el.setAttribute("http-base-url", "http://your-server");
  el.setAttribute("tenant-id", "your-tenant-id");
  el.setAttribute("bot-id", "your-bot-id");
  el.setAttribute("phone", "13800138000");
  document.getElementById("chat-root").appendChild(el);
</script>

按需引入

每个模块独立引入,互不影响:

// 仅引入需要的模块
import "@keyueclaw/web-sdk/skills";
import "@keyueclaw/web-sdk/skills.css";

通用属性

所有元素共享以下属性(继承自 EmbeddedGatewayElementBase):

| 属性 | 类型 | 必填 | 说明 | | --------------- | -------- | ---- | -------------------------------------------- | | ws-base-url | string | 是 | WebSocket 网关地址,如 ws://host/keyueclaw | | http-base-url | string | 是 | HTTP 服务地址,如 http://host | | token | string | 否 | 认证令牌 | | theme | string | 否 | 主题名称,默认 "dash" |

组件属性

<keyueclaw-chat>

| 属性 | 类型 | 必填 | 说明 | | ------------- | ------------------------- | ---- | ----------------------------------------------------------------------------------------------- | | phone | string | 是 | 用户手机号,用于会话路由 | | tenant-id | string | 是 | 租户 ID | | tenant-name | string | 否 | 租户名称 | | bot-id | string | 是 | 机器人 ID | | operator-id | string | 否 | 操作者 ID | | deploy-mode | "offline" \| "online" | 否 | 部署模式,默认 "offline" | | variables | Record<string, unknown> | 否 | 外部注入的会话变量;仅当前会话 /api/v2/dialog/variable 返回的变量名会被下发,其他字段会被忽略 |

<keyueclaw-chat
  ws-base-url="ws://localhost:18789/keyueclaw"
  http-base-url="http://localhost:18789"
  phone="13800138000"
  tenant-id="tenant-001"
  bot-id="bot-001"
  operator-id="op-001"
  deploy-mode="offline"
></keyueclaw-chat>
const el = document.createElement("keyueclaw-chat");
el.setAttribute("tenant-id", "tenant-001");
el.setAttribute("bot-id", "bot-001");
el.variables = {
  city: "北京",
  date: "2026-05-19",
};

<keyueclaw-skills>

| 属性 | 类型 | 必填 | 说明 | | --------------- | -------- | ---- | ---------- | | tenant-id | string | 是 | 租户 ID | | tenant-name | string | 否 | 租户名称 | | bot-id | string | 否 | 机器人 ID | | operator-id | string | 否 | 操作者 ID | | operator-name | string | 否 | 操作者名称 |

<keyueclaw-skills
  ws-base-url="ws://localhost:18789/keyueclaw"
  http-base-url="http://localhost:18789"
  tenant-id="tenant-001"
  operator-id="op-001"
  operator-name="admin"
></keyueclaw-skills>

<keyueclaw-api-management>

| 属性 | 类型 | 必填 | 说明 | | ------------- | -------- | ---- | ----------------------------------------- | | service-url | string | 否 | API 服务地址(默认从 http-base-url 推导) | | tenant-id | string | 否 | 租户 ID(用于租户级接口过滤) |

<keyueclaw-api-management
  ws-base-url="ws://localhost:18789/keyueclaw"
  http-base-url="http://localhost:18789"
  service-url="http://localhost:18789"
  tenant-id="tenant-001"
></keyueclaw-api-management>

<keyueclaw-skill-components>

| 属性 | 类型 | 必填 | 说明 | | ----------- | -------- | ---- | ------- | | tenant-id | string | 是 | 租户 ID |

<keyueclaw-skill-components
  ws-base-url="ws://localhost:18789/keyueclaw"
  http-base-url="http://localhost:18789"
  tenant-id="tenant-001"
></keyueclaw-skill-components>

自定义事件

| 元素 | 事件名 | Detail | 说明 | | ------------------------------ | ---------------------------- | ------------------------------------------- | ------------------ | | <keyueclaw-skill-components> | keyueclaw-component-detail | { tenantId: string, componentId: string } | 新建组件成功后触发 |

document
  .querySelector("keyueclaw-skill-components")
  .addEventListener("keyueclaw-component-detail", (e) => {
    console.log("新组件:", e.detail.componentId);
  });

编写与构建

项目结构

packages/web-sdk/
├── src/
│   ├── chat.ts                          # chat 入口
│   ├── skills.ts                        # skills 入口
│   ├── api-management.ts                # api-management 入口
│   ├── skill-components.ts              # skill-components 入口
│   ├── elements/
│   │   ├── chat-element.ts              # <keyueclaw-chat> 实现
│   │   ├── skills-element.ts            # <keyueclaw-skills> 实现
│   │   ├── api-management-element.ts    # <keyueclaw-api-management> 实现
│   │   └── skill-components-element.ts  # <keyueclaw-skill-components> 实现
│   └── shared/
│       ├── embedded-gateway-element.ts  # 共享基类(WebSocket 连接、主题同步)
│       ├── connection.ts                # URL 解析、token 注入
│       └── theme.ts                     # 主题同步
├── postcss.chat.config.js               # chat 的 PostCSS 配置
├── postcss.skills.config.js
├── postcss.api-management.config.js
├── postcss.skill-components.config.js
├── postcss-prefix-vars.js               # CSS 变量前缀插件
├── vite.config.ts                       # Vite 构建配置
└── dist/                                # 构建产物
    ├── chat.js / chat.umd.cjs / chat.css
    ├── skills.js / skills.umd.cjs / skills.css
    ├── api-management.js / api-management.umd.cjs / api-management.css
    └── skill-components.js / skill-components.umd.cjs / skill-components.css

新增/修改组件

  1. src/elements/ 下创建或修改 xxx-element.ts
  2. 继承 EmbeddedGatewayElementBase,使用 @customElement("keyueclaw-xxx") 注册
  3. @property() 声明 HTML 属性,@state() 声明内部状态
  4. 重写 startEmbeddedGatewayConnection() 处理连接建立后的逻辑
  5. src/xxx.ts 入口文件中导出元素类并引入 @ui/styles.css

构建命令

默认按 bash 执行。修改 src/ 后,需重新构建 dist/,页面不会自动同步源码变更。

# 安装依赖(首次)
pnpm install

# 构建所有模块
pnpm build

# 单独构建某个模块
pnpm build:chat
pnpm build:skills
pnpm build:api-management
pnpm build:skill-components

# 开发模式(watch,文件修改后自动重新构建)
pnpm dev:chat
pnpm dev:skills
pnpm dev:api-management
pnpm dev:skill-components

更新 dist

cd packages/web-sdk

# 更新全部 dist 产物
pnpm build

# 只更新某一个模块
pnpm build:chat
pnpm build:skills
pnpm build:api-management
pnpm build:skill-components

# 构建完成后检查 dist 时间戳
ls -l dist

如果本地页面仍表现为旧逻辑,强制刷新浏览器即可;dist/ 更新后不会自动替换已缓存的 SDK 模块。

构建产物

每个模块产出三个文件:

| 文件 | 格式 | 用途 | | ------------- | ---- | ---------------------------------------------------- | | xxx.js | ESM | 现代打包工具 / <script type="module"> | | xxx.umd.cjs | UMD | 传统 <script> 标签,挂载到 window.KeyueClawXxxUI | | xxx.css | CSS | 组件样式,需手动引入 |

PostCSS 处理

构建时 PostCSS 自动执行两个操作:

  1. CSS 变量前缀--bg--keyueclaw-bg,避免与宿主页面样式冲突
  2. 选择器作用域:所有样式限定在 keyueclaw-xxx .keyueclaw-xxx-scope

类型检查

cd packages/web-sdk
npx tsc --noEmit

已有的 TS5097 警告(.ts 扩展名导入)可通过 tsconfig 中的 allowImportingTsExtensions 抑制。其余来自 extensions/ 目录的错误与 web-sdk 无关。

调试

方式一:本地 Vite Dev Server(推荐)

  1. 启动后端网关服务(确保 http://127.0.0.1:18789 可访问)

  2. 启动 Vite Dev Server:

    cd ui
    pnpm dev

    访问 http://localhost:5173/

  3. 修改 web-sdk 源码后,手动重新构建对应模块:

    cd packages/web-sdk
    npx cross-env TARGET=skill-components vite build

    刷新浏览器即可看到变化(Vite 的 HMR 不覆盖 web-sdk dist,需手动 build)

方式二:Python HTTP Server(静态预览)

# 构建所有模块
cd packages/web-sdk && pnpm build

# 在项目根目录启动 HTTP 服务
cd ../..
python -m http.server 8080

访问 http://localhost:8080/ui/index.html

注意:Python server 下 index.html 的路径需使用 ../packages/web-sdk/dist/...(相对路径)

方式三:嵌入到自己的项目

<!-- 开发时直接指向 dist 目录 -->
<link rel="stylesheet" href="./node_modules/@keyueclaw/web-sdk/dist/chat.css" />
<script type="module" src="./node_modules/@keyueclaw/web-sdk/dist/chat.js"></script>

浏览器调试技巧

  1. 打开开发者工具(F12),在 Console 中查看元素注册和连接日志

  2. 检查自定义元素:在 Elements 面板中搜索 keyueclaw-chat 等标签,查看属性和状态

  3. 检查网络请求:在 Network 面板筛选 keyueclaw,查看 API 调用和 WebSocket 连接

  4. 常见问题排查

    | 现象 | 原因 | 解决 | | ------------------------ | ----------------------- | ----------------------------------------- | | 元素显示空白 | CSS 文件未引入 | 检查 <link> 标签路径 | | 控制台报 404 | dist 文件路径错误 | 检查 src / href 路径 | | "加载中…" 一直不消失 | WebSocket 连接失败 | 检查 ws-base-url 是否正确、网关是否运行 | | API 请求 404 | http-base-url 错误 | 检查 HTTP 地址,确认后端服务运行 | | 样式错乱 | CSS 变量冲突 | 确认引入了对应的 .css 文件 | | @ / & 触发面板不弹出 | 没有 API 定义或变量数据 | 检查后端是否有对应数据 |

  5. Lit DevTools:安装 Lit DevTools 浏览器扩展,可以查看 Lit 元素的 @state@property

发布到 npm

cd packages/web-sdk
pnpm build
npm publish --access public

发布前确认:

  • package.jsonversion 已更新
  • dist/ 目录包含所有四个模块的产物
  • exports 字段与实际产物一致

技术架构

┌─────────────────────────────────────────────┐
│              外部页面                         │
│  <keyueclaw-chat>  <keyueclaw-skills>  ...  │
└──────────────┬──────────────────────────────┘
               │ Lit Web Components
┌──────────────▼──────────────────────────────┐
│         packages/web-sdk                    │
│  ┌─────────────────────────────────────┐    │
│  │  EmbeddedGatewayElementBase         │    │
│  │  (WebSocket 连接、主题同步)          │    │
│  └─────────────────────────────────────┘    │
│  ┌────────┐ ┌────────┐ ┌─────┐ ┌────────┐  │
│  │  chat  │ │ skills │ │ api │ │ compo- │  │
│  │element │ │element │ │ mgmt│ │ nents  │  │
│  └────┬───┘ └────┬───┘ └──┬──┘ └───┬────┘  │
└───────┼──────────┼────────┼────────┼────────┘
        │          │        │        │
┌───────▼──────────▼────────▼────────▼────────┐
│              @ui (共享代码)                   │
│  views/  controllers/  api-client/  types/  │
└─────────────────────────────────────────────┘
  • web-sdk 是薄封装层,管理元素状态和生命周期
  • @ui 提供业务逻辑、渲染函数、API 客户端和类型定义
  • CSS 通过 PostCSS 自动加 keyueclaw- 前缀,避免样式冲突
  • 每个模块独立构建,产物包含 ESM (.js) + UMD (.umd.cjs) + CSS

License

MIT