beervid-app-cli 0.2.4 → 0.2.6
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/README.md +30 -19
- package/dist/cli.mjs +1 -1
- package/package.json +6 -6
- package/{SKILL.md → skills/beervid-app-cli/SKILL.md} +6 -2
- package/{docs → skills/beervid-app-cli/docs}/oauth-callback.md +22 -19
- package/{example → skills/beervid-app-cli/example}/express/server.ts +8 -4
- package/{example → skills/beervid-app-cli/example}/nextjs/app/api/oauth/url/route.ts +3 -2
- package/{example → skills/beervid-app-cli/example}/standard/get-oauth-url.ts +3 -2
- package/agents/openai.yaml +0 -7
- /package/{docs → skills/beervid-app-cli/docs}/database-schema.md +0 -0
- /package/{docs → skills/beervid-app-cli/docs}/retry-and-idempotency.md +0 -0
- /package/{docs → skills/beervid-app-cli/docs}/tt-poll-task.md +0 -0
- /package/{docs → skills/beervid-app-cli/docs}/tts-product-cache.md +0 -0
- /package/{example → skills/beervid-app-cli/example}/express/README.md +0 -0
- /package/{example → skills/beervid-app-cli/example}/express/package.json +0 -0
- /package/{example → skills/beervid-app-cli/example}/express/tsconfig.json +0 -0
- /package/{example → skills/beervid-app-cli/example}/nextjs/.env.example +0 -0
- /package/{example → skills/beervid-app-cli/example}/nextjs/README.md +0 -0
- /package/{example → skills/beervid-app-cli/example}/nextjs/app/api/oauth/callback/route.ts +0 -0
- /package/{example → skills/beervid-app-cli/example}/nextjs/app/api/products/route.ts +0 -0
- /package/{example → skills/beervid-app-cli/example}/nextjs/app/api/publish/tt/route.ts +0 -0
- /package/{example → skills/beervid-app-cli/example}/nextjs/app/api/publish/tts/route.ts +0 -0
- /package/{example → skills/beervid-app-cli/example}/nextjs/app/api/status/[shareId]/route.ts +0 -0
- /package/{example → skills/beervid-app-cli/example}/nextjs/app/layout.tsx +0 -0
- /package/{example → skills/beervid-app-cli/example}/nextjs/app/page.tsx +0 -0
- /package/{example → skills/beervid-app-cli/example}/nextjs/lib/beervid-client.ts +0 -0
- /package/{example → skills/beervid-app-cli/example}/nextjs/next.config.ts +0 -0
- /package/{example → skills/beervid-app-cli/example}/nextjs/package.json +0 -0
- /package/{example → skills/beervid-app-cli/example}/nextjs/tsconfig.json +0 -0
- /package/{example → skills/beervid-app-cli/example}/standard/README.md +0 -0
- /package/{example → skills/beervid-app-cli/example}/standard/api-client.ts +0 -0
- /package/{example → skills/beervid-app-cli/example}/standard/package.json +0 -0
- /package/{example → skills/beervid-app-cli/example}/standard/query-products.ts +0 -0
- /package/{example → skills/beervid-app-cli/example}/standard/tsconfig.json +0 -0
- /package/{example → skills/beervid-app-cli/example}/standard/tt-publish-flow.ts +0 -0
- /package/{example → skills/beervid-app-cli/example}/standard/tts-publish-flow.ts +0 -0
- /package/{references → skills/beervid-app-cli/references}/api-reference.md +0 -0
package/README.md
CHANGED
|
@@ -30,28 +30,39 @@ node dist/cli.mjs --help
|
|
|
30
30
|
node dist/cli.mjs config --show
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
### 在 Claude Code / Codex / Antigravity
|
|
33
|
+
### 在 Claude Code / Codex / Antigravity 中使用(以下说明面向 AI Agent)
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
#### 方式一:通过 `npx skills add` 安装(推荐)
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
```bash
|
|
38
|
+
npx skills add Lupeiwen0/beervid-app-cli
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
安装后 Skill 会自动注册到你的 skills 目录中,Claude Code 等 Agent 即可发现和调用。
|
|
42
|
+
|
|
43
|
+
#### 方式二:手动安装
|
|
38
44
|
|
|
39
|
-
|
|
40
|
-
- `references/`
|
|
41
|
-
- `docs/`
|
|
42
|
-
- `example/`
|
|
45
|
+
如果你是 Claude Code、Codex、Antigravity,或任何支持 Skill 的 AI Agent,请严格按下面规则执行:
|
|
43
46
|
|
|
44
|
-
|
|
47
|
+
- 用户把 GitHub 仓库链接发给你,**不等于**这个 Skill 已经安装到你的 skills 目录中。
|
|
48
|
+
- 只有当 `skills/beervid-app-cli/` 目录被完整安装到你的 skills 目录后,才算这个 Skill 可用。
|
|
49
|
+
|
|
50
|
+
你必须先把以下目录复制到你自己的 skills 目录中:
|
|
45
51
|
|
|
46
52
|
```text
|
|
47
|
-
beervid-app-cli/
|
|
53
|
+
skills/beervid-app-cli/
|
|
48
54
|
SKILL.md
|
|
49
55
|
references/
|
|
50
56
|
docs/
|
|
51
57
|
example/
|
|
52
58
|
```
|
|
53
59
|
|
|
54
|
-
|
|
60
|
+
安装完成后,你应从 skills 目录中的 `SKILL.md` 加载本 Skill,而不是只读取仓库根目录里的 `README.md` 或 `package.json`。
|
|
61
|
+
|
|
62
|
+
对 AI Agent 来说,应这样区分:
|
|
63
|
+
|
|
64
|
+
- 目标是使用 CLI:安装 npm 包即可。
|
|
65
|
+
- 目标是使用 Skill:必须额外安装 Skill 文件;仓库链接本身不完成这一步。
|
|
55
66
|
|
|
56
67
|
## 配置
|
|
57
68
|
|
|
@@ -106,7 +117,7 @@ beervid publish-tts-flow --creator-id open_user_abc --file ./video.mp4 --interac
|
|
|
106
117
|
beervid publish-tts-flow --creator-id open_user_abc --file ./video.mp4 --product-id prod_123 --product-title "Widget"
|
|
107
118
|
```
|
|
108
119
|
|
|
109
|
-
详细用法见 [SKILL.md](./SKILL.md)。完整 API 参考见 [references/api-reference.md](./references/api-reference.md)。
|
|
120
|
+
详细用法见 [SKILL.md](./skills/beervid-app-cli/SKILL.md)。完整 API 参考见 [references/api-reference.md](./skills/beervid-app-cli/references/api-reference.md)。
|
|
110
121
|
|
|
111
122
|
## 落地文档
|
|
112
123
|
|
|
@@ -114,11 +125,11 @@ beervid publish-tts-flow --creator-id open_user_abc --file ./video.mp4 --product
|
|
|
114
125
|
|
|
115
126
|
| 文档 | 内容 |
|
|
116
127
|
|------|------|
|
|
117
|
-
| [数据表字段建议](./docs/database-schema.md) | accounts/videos/products 表结构设计 |
|
|
118
|
-
| [OAuth 回调存储建议](./docs/oauth-callback.md) | State Token 防 CSRF、回调持久化、异步头像同步 |
|
|
119
|
-
| [TT 轮询任务建议](./docs/tt-poll-task.md) | 阶梯递增轮询间隔、Cron/队列三层保障 |
|
|
120
|
-
| [TTS 商品缓存建议](./docs/tts-product-cache.md) | 全量拉取、缓存过期、图片 URL 解析 |
|
|
121
|
-
| [失败重试与幂等建议](./docs/retry-and-idempotency.md) | 各 API 幂等性分析、指数退避、幂等键设计 |
|
|
128
|
+
| [数据表字段建议](./skills/beervid-app-cli/docs/database-schema.md) | accounts/videos/products 表结构设计 |
|
|
129
|
+
| [OAuth 回调存储建议](./skills/beervid-app-cli/docs/oauth-callback.md) | State Token 防 CSRF、回调持久化、异步头像同步 |
|
|
130
|
+
| [TT 轮询任务建议](./skills/beervid-app-cli/docs/tt-poll-task.md) | 阶梯递增轮询间隔、Cron/队列三层保障 |
|
|
131
|
+
| [TTS 商品缓存建议](./skills/beervid-app-cli/docs/tts-product-cache.md) | 全量拉取、缓存过期、图片 URL 解析 |
|
|
132
|
+
| [失败重试与幂等建议](./skills/beervid-app-cli/docs/retry-and-idempotency.md) | 各 API 幂等性分析、指数退避、幂等键设计 |
|
|
122
133
|
|
|
123
134
|
## 示例工程
|
|
124
135
|
|
|
@@ -126,6 +137,6 @@ beervid publish-tts-flow --creator-id open_user_abc --file ./video.mp4 --product
|
|
|
126
137
|
|
|
127
138
|
| 示例 | 场景 | 入口 |
|
|
128
139
|
|------|------|------|
|
|
129
|
-
| [Standard](./example/standard/) | 纯 Node.js 脚本,快速验证 | `npx tsx tt-publish-flow.ts` |
|
|
130
|
-
| [Express](./example/express/) | Express 后端服务,含 OAuth 回调 | `npx tsx server.ts` |
|
|
131
|
-
| [Next.js](./example/nextjs/) | Next.js App Router API Route | `npm run dev` |
|
|
140
|
+
| [Standard](./skills/beervid-app-cli/example/standard/) | 纯 Node.js 脚本,快速验证 | `npx tsx tt-publish-flow.ts` |
|
|
141
|
+
| [Express](./skills/beervid-app-cli/example/express/) | Express 后端服务,含 OAuth 回调 | `npx tsx server.ts` |
|
|
142
|
+
| [Next.js](./skills/beervid-app-cli/example/nextjs/) | Next.js App Router API Route | `npm run dev` |
|
package/dist/cli.mjs
CHANGED
|
@@ -1130,7 +1130,7 @@ function register10(cli2) {
|
|
|
1130
1130
|
|
|
1131
1131
|
// src/cli.ts
|
|
1132
1132
|
var cli = cac("beervid");
|
|
1133
|
-
var cliVersion = true ? "0.2.
|
|
1133
|
+
var cliVersion = true ? "0.2.6" : pkg.version;
|
|
1134
1134
|
register10(cli);
|
|
1135
1135
|
register(cli);
|
|
1136
1136
|
register2(cli);
|
package/package.json
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "beervid-app-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "BEERVID App CLI — TikTok video publish, account auth, and data query",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/Lupeiwen0/beervid-app-cli"
|
|
8
|
+
},
|
|
5
9
|
"type": "module",
|
|
6
10
|
"engines": {
|
|
7
11
|
"node": ">=20.0.0"
|
|
@@ -11,11 +15,7 @@
|
|
|
11
15
|
},
|
|
12
16
|
"files": [
|
|
13
17
|
"dist/",
|
|
14
|
-
"
|
|
15
|
-
"references/",
|
|
16
|
-
"docs/",
|
|
17
|
-
"example/",
|
|
18
|
-
"SKILL.md",
|
|
18
|
+
"skills/",
|
|
19
19
|
"README.md"
|
|
20
20
|
],
|
|
21
21
|
"scripts": {
|
|
@@ -184,9 +184,13 @@ creatorUserOpenId -> upload-tts-video -> fileId -> shoppable-publish -> videoId
|
|
|
184
184
|
- 上传请求头使用 `X-UPLOAD-TOKEN`
|
|
185
185
|
- 如需上传进度与取消能力,优先用 XHR 而非裸 `fetch`
|
|
186
186
|
|
|
187
|
-
## CLI
|
|
187
|
+
## CLI 工具
|
|
188
188
|
|
|
189
|
-
|
|
189
|
+
本 Skill 配套提供 `beervid` CLI;可直接在终端调用所有 Open API 能力。如需使用 CLI,请先安装:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
npm install -g beervid-app-cli
|
|
193
|
+
```
|
|
190
194
|
|
|
191
195
|
### CLI 前置
|
|
192
196
|
|
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
2. **用户跳转授权**:将用户重定向到返回的 URL
|
|
17
17
|
3. **接收回调**:用户授权后,TikTok 回调你的服务器
|
|
18
18
|
|
|
19
|
-
>
|
|
20
|
-
>
|
|
19
|
+
> **说明**:获取到的授权链接中**不一定**携带 `state` 参数。
|
|
20
|
+
> - 如果链接中已经包含 `state`,它的值一定是一个 JSON 字符串。你可以解析该 JSON,在其中追加自定义字段后再写回。
|
|
21
|
+
> - 如果链接中没有 `state`,而你需要透传参数(例如防 CSRF 的安全 token),应自行构造一个 JSON 对象作为 `state` 的值追加到授权链接上。
|
|
21
22
|
|
|
22
23
|
---
|
|
23
24
|
|
|
@@ -35,9 +36,11 @@ OAuth 授权完成后,回调 URL 会携带以下关键参数:
|
|
|
35
36
|
|
|
36
37
|
---
|
|
37
38
|
|
|
38
|
-
##
|
|
39
|
+
## 获取授权链接后如何设置或追加 State
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
授权链接中**可能包含也可能不包含** `state` 参数:
|
|
42
|
+
- 如果已包含 `state`,其值是一个 JSON 字符串,可以解析后追加字段再写回。
|
|
43
|
+
- 如果未包含 `state`,而你需要透传参数,应自行构造一个 JSON 对象设置为 `state`。
|
|
41
44
|
|
|
42
45
|
```typescript
|
|
43
46
|
function tryParseJsonObject(value: string): Record<string, unknown> | null {
|
|
@@ -52,25 +55,25 @@ function tryParseJsonObject(value: string): Record<string, unknown> | null {
|
|
|
52
55
|
}
|
|
53
56
|
}
|
|
54
57
|
|
|
55
|
-
function
|
|
58
|
+
function setOrAppendStateToken(
|
|
56
59
|
rawUrl: string,
|
|
57
60
|
customStateToken: string
|
|
58
61
|
): string {
|
|
59
62
|
const url = new URL(rawUrl)
|
|
60
63
|
const rawState = url.searchParams.get('state')
|
|
61
64
|
|
|
62
|
-
|
|
63
|
-
throw new Error('授权链接中缺少 state 参数')
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const parsedState = tryParseJsonObject(rawState)
|
|
67
|
-
if (!parsedState) {
|
|
68
|
-
throw new Error('授权链接中的 state 不是可追加字段的 JSON 对象')
|
|
69
|
-
}
|
|
65
|
+
let nextState: Record<string, unknown>
|
|
70
66
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
67
|
+
if (rawState) {
|
|
68
|
+
// 链接中已有 state,解析后追加字段
|
|
69
|
+
const parsedState = tryParseJsonObject(rawState)
|
|
70
|
+
if (!parsedState) {
|
|
71
|
+
throw new Error('授权链接中的 state 不是可追加字段的 JSON 对象')
|
|
72
|
+
}
|
|
73
|
+
nextState = { ...parsedState, customStateToken }
|
|
74
|
+
} else {
|
|
75
|
+
// 链接中没有 state,自行构造 JSON
|
|
76
|
+
nextState = { customStateToken }
|
|
74
77
|
}
|
|
75
78
|
|
|
76
79
|
url.searchParams.set('state', JSON.stringify(nextState))
|
|
@@ -80,7 +83,7 @@ function appendTokenToOAuthUrlState(
|
|
|
80
83
|
async function getTtOAuthUrlWithState(userId: string): Promise<string> {
|
|
81
84
|
const customStateToken = generateStateToken(userId)
|
|
82
85
|
const rawUrl = await openApiGet<string>('/api/v1/open/thirdparty-auth/tt-url')
|
|
83
|
-
return
|
|
86
|
+
return setOrAppendStateToken(rawUrl, customStateToken)
|
|
84
87
|
}
|
|
85
88
|
|
|
86
89
|
async function getTtsOAuthUrlWithState(userId: string): Promise<string> {
|
|
@@ -88,7 +91,7 @@ async function getTtsOAuthUrlWithState(userId: string): Promise<string> {
|
|
|
88
91
|
const data = await openApiGet<{ crossBorderUrl: string }>(
|
|
89
92
|
'/api/v1/open/thirdparty-auth/tts-url'
|
|
90
93
|
)
|
|
91
|
-
return
|
|
94
|
+
return setOrAppendStateToken(data.crossBorderUrl, customStateToken)
|
|
92
95
|
}
|
|
93
96
|
```
|
|
94
97
|
|
|
@@ -108,7 +111,7 @@ function parseCustomStateToken(state: string): string {
|
|
|
108
111
|
```
|
|
109
112
|
|
|
110
113
|
> **说明**:字段名 `customStateToken` 只是示例,你也可以改成 `token`、`nonce`、`appState` 等业务上更合适的名字。
|
|
111
|
-
>
|
|
114
|
+
> 无论链接中原先是否携带 `state`,你设置的 `state` 值都应该是一个 JSON 对象。
|
|
112
115
|
|
|
113
116
|
---
|
|
114
117
|
|
|
@@ -154,8 +154,10 @@ async function pollVideoStatusInBackground(record: VideoRecord): Promise<void> {
|
|
|
154
154
|
app.get('/oauth/tt', async (_req, res) => {
|
|
155
155
|
try {
|
|
156
156
|
const url = await openApiGet<string>('/api/v1/open/thirdparty-auth/tt-url')
|
|
157
|
-
//
|
|
158
|
-
//
|
|
157
|
+
// 生产环境:授权链接中不一定携带 state 参数。
|
|
158
|
+
// 如果已有 state,其值为 JSON,可解析后追加自定义字段;
|
|
159
|
+
// 如果没有 state,需透传参数时应自行构造 JSON 设置为 state。
|
|
160
|
+
// 详见 docs/oauth-callback.md
|
|
159
161
|
res.redirect(url)
|
|
160
162
|
} catch (err) {
|
|
161
163
|
res.status(500).json({ error: (err as Error).message })
|
|
@@ -168,8 +170,10 @@ app.get('/oauth/tts', async (_req, res) => {
|
|
|
168
170
|
const data = await openApiGet<{ crossBorderUrl: string }>(
|
|
169
171
|
'/api/v1/open/thirdparty-auth/tts-url'
|
|
170
172
|
)
|
|
171
|
-
//
|
|
172
|
-
//
|
|
173
|
+
// 生产环境:授权链接中不一定携带 state 参数。
|
|
174
|
+
// 如果已有 state,其值为 JSON,可解析后追加自定义字段;
|
|
175
|
+
// 如果没有 state,需透传参数时应自行构造 JSON 设置为 state。
|
|
176
|
+
// 详见 docs/oauth-callback.md
|
|
173
177
|
res.redirect(data.crossBorderUrl)
|
|
174
178
|
} catch (err) {
|
|
175
179
|
res.status(500).json({ error: (err as Error).message })
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* GET /api/oauth/url?type=tt|tts
|
|
3
3
|
* 获取 OAuth 授权 URL
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* 生产环境:授权链接中不一定携带 state 参数。
|
|
6
|
+
* 如果已有 state,其值为 JSON,可解析后追加自定义字段;
|
|
7
|
+
* 如果没有 state,需透传参数时应自行构造 JSON 设置为 state。
|
|
7
8
|
* 详见 docs/oauth-callback.md
|
|
8
9
|
*/
|
|
9
10
|
import { NextRequest, NextResponse } from 'next/server'
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
* npx tsx get-oauth-url.ts --type tt
|
|
6
6
|
* npx tsx get-oauth-url.ts --type tts
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* 生产环境:授权链接中不一定携带 state 参数。
|
|
9
|
+
* 如果已有 state,其值为 JSON,可解析后追加自定义字段;
|
|
10
|
+
* 如果没有 state,需透传参数时应自行构造 JSON 设置为 state。
|
|
10
11
|
* 详见 docs/oauth-callback.md
|
|
11
12
|
*/
|
|
12
13
|
|
package/agents/openai.yaml
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
interface:
|
|
2
|
-
display_name: "BEERVID App CLI"
|
|
3
|
-
short_description: "BEERVID third-party Open API CLI skill"
|
|
4
|
-
default_prompt: "Use $beervid-app-cli to implement or troubleshoot BEERVID third-party Open API flows for OAuth, TikTok publishing, status polling, and product queries."
|
|
5
|
-
|
|
6
|
-
policy:
|
|
7
|
-
allow_implicit_invocation: true
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/{example → skills/beervid-app-cli/example}/nextjs/app/api/status/[shareId]/route.ts
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|