# @wujie-shell/business

轻量无界云端基础业务客户端。它封装账号认证、当前用户信息、API Key 获取、模型、Skill 市场、计费、模板、通用 HTTP 配置和 `WUJIE_AI_ROUTES` 路由常量。

这个包不读取 Vite、Electron 或 Node 环境变量，不依赖 React/Jotai/Electron，也不承载产品 UI 流程、页面状态或组件类型。产品默认参数、请求组合和 UI 类型应由调用方适配层决定，例如 `apps/desktop-cn/src/api/businessClient.ts`。

## 入口

```ts
import { createWujieAiBusiness, WUJIE_AI_ROUTES } from '@wujie-shell/business'
```

发布后 npm 入口指向 `dist/src/index.js`，类型入口为 `dist/src/index.d.ts`。

## 创建客户端

```ts
export const wujieBusiness = createWujieAiBusiness({
  env: import.meta.env.VITE_WUJIE_API_ENV,
  endpoint: import.meta.env.VITE_WUJIE_API_ENDPOINT,
  storagePrefix: `wujie:${import.meta.env.VITE_WUJIE_API_ENV}`,
  storage: window.localStorage,
  fetch: window.fetch.bind(window),
})
```

`storagePrefix` 用来隔离不同环境 token：

```text
wujie:test:gate-token
wujie:test:user-id
wujie:test:device_id
wujie:prod:gate-token
wujie:prod:user-id
wujie:prod:device_id
```

需要复用无前缀历史 key 时，可显式传入 `storagePrefix: ''`。

`createWujieAiBusiness()` 返回：

```ts
{
  env: string
  endpoint: string
  auth: WujieAuthService
  apiKey: WujieApiKeyService
  models: WujieModelService
  skills: WujieSkillService
  billing: WujieBillingService
  templates: WujieTemplateService
}
```

## 登录/注册

`areaCode` 会在包内规范成不带 `+` 的格式，例如 `+86` 会发送为 `86`。
密码登录时，调用方传入明文密码即可，包内会发送 MD5 后的密码。

```ts
await wujieBusiness.auth.sendCaptcha({
  mobile: '13800000000',
  areaCode: '+86',
  behaviorParam: captchaPayload,
})

await wujieBusiness.auth.loginOrRegister({
  mobile: '13800000000',
  areaCode: '+86',
  code: '123456',
})

await wujieBusiness.auth.loginOrRegister({
  mobile: '13800000000',
  areaCode: '+86',
  password: 'password',
})
```

登录成功后，包会自动写入当前 `storagePrefix` 下的 `gate-token` 和 `user-id`。后续请求会自动带上 `gate-token` 请求头。JSON 请求头与 wujie-ai 桌面端保持一致：

```text
Content-Type: application/json
app_code: trade
source_site: AIPC
device_id: <device id>
gate-token: <token>
```

登出：

```ts
await wujieBusiness.auth.logout()
```

## API Key

大模型配置：

```ts
const config = await wujieBusiness.apiKey.getBigModelConfig()
```

返回字段：

```ts
{
  provider: string
  apiKey: string
  modelName: string
  baseUrl: string
  raw: BigModelUserInfo
}
```

只取大模型 API Key：

```ts
const apiKey = await wujieBusiness.apiKey.getBigModelApiKey()
```

读取当前用户上的 AI gateway API Key：

```ts
const gatewayApiKey = await wujieBusiness.apiKey.getGatewayApiKey()
```

## 路由常量

`WUJIE_AI_ROUTES` 保留无界云端 API 路径定义，供产品适配层复用。它只定义协议路径，不携带产品默认参数，也不决定请求 body/query/header。

```ts
await fetch(`${endpoint}${WUJIE_AI_ROUTES.payTypeList}`, {
  method: 'POST',
  body: JSON.stringify({ payScene, payDevice }),
})
```

例如 Skill 市场接口的 `type=3`、支付接口的 `payScene=AIPC_INTEGRAL`、`payDevice=WEB`、充值类型默认值等，均属于产品策略，应由调用方决定。

## 不在包内处理

- UI 环境变量读取。
- React/Jotai 状态。
- 路由守卫。
- Electron IPC。
- `window.wujieShell` 或 `@wujie-shell/sdk` 调用。
- OpenClaw 模型配置写入。
- 产品接口默认参数、请求组合、分页转换、模板选择状态、附件类型映射和组件交互状态。

## 验证

```bash
pnpm --filter @wujie-shell/business test
pnpm --filter @wujie-shell/business build
```
