> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qoder.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK 认证

`query()` 需要认证配置才能启动会话。推荐使用 Personal Access Token (PAT) 并通过环境变量注入，适合脚本、CI 和宿主应用集成。

如果你已经在本机通过 `qodercli` 登录，也可以复用本机登录态。

<div id="获取-pat" />

## 获取 PAT

到 [qoder.com/account/integrations](https://qoder.com/account/integrations) 生成一个 Personal Access Token：

1. 登录 Qoder 账号
2. 打开 **Account → Integrations** 页面
3. 创建新的 PAT，按需选择有效期和权限范围
4. 生成后**立即复制**——页面关闭后无法再次查看，丢失只能重新生成

> 同一个账号可以生成多个 PAT，建议给不同环境（本地脚本、CI、生产服务）发独立的 token，方便单独吊销。

<div id="推荐用法" />

## 推荐用法

<div id="从默认环境变量读取-pat" />

### 从默认环境变量读取 PAT

默认环境变量名是 `QODER_PERSONAL_ACCESS_TOKEN`。

```bash theme={null}
export QODER_PERSONAL_ACCESS_TOKEN="<your-qoder-personal-access-token>"
node agent.mjs
```

```js theme={null}
import { accessTokenFromEnv, query } from '@qoder-ai/qoder-agent-sdk';

const q = query({
  prompt: 'Summarize the purpose of this project in one sentence.',
  options: {
    auth: accessTokenFromEnv(),
  },
});

try {
  for await (const message of q) {
    if (message.type === 'result') {
      console.log(message.subtype);
    }
  }
} finally {
  await q.close?.();
}
```

<div id="从自定义环境变量读取-pat" />

### 从自定义环境变量读取 PAT

```js theme={null}
import { accessTokenFromEnv, query } from '@qoder-ai/qoder-agent-sdk';

const q = query({
  prompt: 'Check whether the README contains installation steps.',
  options: {
    auth: accessTokenFromEnv('MY_QODER_PAT'),
  },
});
```

等价的显式写法：

```js theme={null}
auth: {
  type: 'accessToken',
  accessToken: { envVar: 'MY_QODER_PAT' },
}
```

如果同时设置了 `options.env` 和 `process.env` 中的同名变量，SDK 会优先读取 `options.env` 中的值。

<div id="直接传入-pat" />

### 直接传入 PAT

如果宿主应用已经从密钥管理服务、登录态或后端接口拿到了 PAT，可以直接传入。不要把 token 字面量写进源码。

```js theme={null}
import { accessToken, query } from '@qoder-ai/qoder-agent-sdk';

const token = await readTokenFromSecretManager();

const q = query({
  prompt: 'List the most recently modified files.',
  options: {
    auth: accessToken(token),
  },
});
```

<div id="复用-qodercli-登录态" />

### 复用 qodercli 登录态

如果本机已经通过 `qodercli` 完成登录，可以让 SDK 交给 CLI 读取本地登录态。该方式适合交互式本机环境，不建议用于无状态 CI。

```js theme={null}
import { qodercliAuth, query } from '@qoder-ai/qoder-agent-sdk';

const q = query({
  prompt: 'Summarize the current workspace.',
  options: {
    auth: qodercliAuth(),
  },
});
```

<div id="api-速览" />

## API 速览

| 选项                           | 用途                                              |
| ---------------------------- | ----------------------------------------------- |
| `accessTokenFromEnv()`       | 从 `QODER_PERSONAL_ACCESS_TOKEN` 读取 PAT。         |
| `accessTokenFromEnv(envVar)` | 从指定环境变量读取 PAT。                                  |
| `accessToken(token)`         | 使用调用方已经取得的 PAT。                                 |
| `qodercliAuth()`             | 复用本机 `qodercli` 登录状态。                           |
| `onAuthExpired`              | token 失效、认证失败或 CLI 认证错误退出时回调。每个 query 会话最多触发一次。 |

<div id="错误处理" />

## 错误处理

<div id="缺少-auth-配置" />

### 缺少 auth 配置

`query()` 会在启动前抛出 `auth_not_configured`：

```js theme={null}
try {
  query({ prompt: 'hello' });
} catch (error) {
  if (error?.code === 'auth_not_configured') {
    console.error('Please configure options.auth');
  }
}
```

<div id="环境变量未设置" />

### 环境变量未设置

当使用 `{ envVar }` 但变量为空时，SDK 会抛出 `auth_access_token_env_var_not_configured`：

```js theme={null}
try {
  const q = query({
    prompt: 'hello',
    options: {
      auth: accessTokenFromEnv('MY_QODER_PAT'),
    },
  });

  for await (const _message of q) {
    // Initialization failures do not reach this loop.
  }
} catch (error) {
  if (error?.code === 'auth_access_token_env_var_not_configured') {
    console.error('MY_QODER_PAT is not set');
  }
}
```

<div id="运行中认证失败" />

### 运行中认证失败

远端拒绝 token、token 过期或 CLI 以认证错误退出时，使用 `onAuthExpired` 触发重新登录或换 token 流程：

```js theme={null}
const q = query({
  prompt: 'Continue with the current task.',
  options: {
    auth: accessTokenFromEnv(),
    onAuthExpired() {
      showSignInRequired();
    },
  },
});

for await (const message of q) {
  if (message.type === 'result' && message.subtype !== 'success') {
    console.error(message.errors?.join('\n') ?? message.subtype);
  }
}
```

SDK 不会自动刷新 PAT。宿主应用应在拿到新 token 后创建新的 `query()` 会话并传入新的 `auth` 配置。

<div id="最佳实践" />

## 最佳实践

* 生产和 CI 中优先使用环境变量或密钥管理服务，不要硬编码 token。
* 不要把 token 写入日志、错误对象或调试输出。
* 自动化环境中建议使用 PAT，不建议依赖本机 `qodercli` 登录态。
* 对用户可见应用注册 `onAuthExpired`，把认证失败转成明确的登录提示。
* 需要轮换 token 时，新建 query 会话；不要复用已经认证失败的会话。
