sophhub 0.1.2 → 0.1.4
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 +8 -1
- package/package.json +1 -1
- package/skills/VERSIONS.md +3 -1
- package/skills/builtin/skillhub/SKILL.md +111 -0
- package/skills/store/aippt/SKILL.md +235 -0
- package/skills/store/aippt/pyproject.toml +8 -0
- package/skills/store/aippt/scripts/auth.py +122 -0
- package/skills/store/aippt/scripts/ppt.py +361 -0
- package/skills/store/aippt/scripts/provider_docmee.py +299 -0
- package/skills/store/lawding-contract-review/SKILL.md +284 -0
- package/skills/store/lawding-contract-review/references/contract-types.md +334 -0
- package/skills/store/lawding-contract-review/references/jurisdiction-review-rules.md +362 -0
- package/skills/store/lawding-contract-review/references/legal-language-library.md +1385 -0
- package/skills/store/lawding-contract-review/references/review-methodology.md +225 -0
- package/skills/store/lawding-contract-review/references/risk-templates.md +193 -0
- package/skills/store/lawding-contract-review/scripts/build_reminders.py +471 -0
- package/skills/store/lawding-contract-review/scripts/register_contract_cron.py +457 -0
- package/src/commands/download.js +68 -41
- package/skills/builtin/clawhub/SKILL.md +0 -77
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ sophhub list --type store --json
|
|
|
40
40
|
|
|
41
41
|
### 下载 Skill
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
下载单个 Skill 到当前目录:
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
46
|
sophhub download weather
|
|
@@ -52,6 +52,13 @@ sophhub download weather
|
|
|
52
52
|
sophhub download didi-ride -o ./my-skills
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
+
批量下载某个类型的所有 Skill:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
sophhub download --type builtin -o ./skills
|
|
59
|
+
sophhub download --type store -o ./skills
|
|
60
|
+
```
|
|
61
|
+
|
|
55
62
|
### 查看版本
|
|
56
63
|
|
|
57
64
|
```bash
|
package/package.json
CHANGED
package/skills/VERSIONS.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
| Skill | Type | Version | Updated At | Display Name | Description |
|
|
4
4
|
| --- | --- | --- | --- | --- | --- |
|
|
5
|
-
|
|
|
5
|
+
| skillhub | builtin | 1.0.0 | 2026-04-09 | | |
|
|
6
6
|
| flight-booking | builtin | 1.1.0 | 2026-04-08 | | |
|
|
7
7
|
| inventory-management | builtin | 1.0.0 | 2026-04-08 | | |
|
|
8
8
|
| schedule-reminder | builtin | 1.0.0 | 2026-04-08 | | |
|
|
@@ -23,5 +23,7 @@
|
|
|
23
23
|
| weather | builtin | 1.0.0 | 2026-04-08 | | |
|
|
24
24
|
| web-scraper | builtin | 1.0.0 | 2026-04-08 | | |
|
|
25
25
|
| website-builder | builtin | 1.0.0 | 2026-04-08 | | |
|
|
26
|
+
| aippt | store | 1.0.0 | 2026-04-09 | AI PPT 生成 | 根据主题、文件、网址或大纲自动生成演示文稿 |
|
|
26
27
|
| didi-ride | store | 1.0.0 | 2026-04-09 | 滴滴出行 | 打车、路线规划、周边搜索、订单查询 |
|
|
27
28
|
| flyai | store | 1.0.10 | 2026-04-09 | 飞猪旅行 | 机票、酒店、景点门票、旅行搜索与预订 |
|
|
29
|
+
| lawding-contract-review | store | 1.0.0 | 2026-04-09 | 合同审查 | 合同审核、备份、合同到期提醒、应付应收提醒、违约提醒 |
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skillhub
|
|
3
|
+
description: 当用户要求搜索、安装 skill (包括Sophnet/Sophclaw平台和clawhub社区) 时使用此 skill。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SkillHub
|
|
7
|
+
|
|
8
|
+
统一的技能安装入口,整合 **SophHub**(Sophnet 平台 Sophclaw 产品的技能商店,优先)和 **ClawHub**(社区商店,兜底)。
|
|
9
|
+
|
|
10
|
+
## 安装流程
|
|
11
|
+
|
|
12
|
+
当用户需要安装一个技能时,按以下顺序操作:
|
|
13
|
+
|
|
14
|
+
### 第一步:从 SophHub 商店查找
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx -y sophhub list --type store
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
检查输出中是否有符合用户需求的技能。
|
|
21
|
+
|
|
22
|
+
- **找到合适的技能** → 将技能名称和描述反馈给用户,让用户确认是否安装。
|
|
23
|
+
- 用户确认安装后,执行下载:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npx -y sophhub download <技能名称> -o <目标目录>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
其中 `<目标目录>` 为当前技能工作目录(通常是 `~/.openclaw/skills/` 或由环境决定的目录)。
|
|
30
|
+
|
|
31
|
+
- **没有找到合适的技能** → 进入第二步。
|
|
32
|
+
|
|
33
|
+
### 第二步:从 ClawHub 查找(兜底)
|
|
34
|
+
|
|
35
|
+
如果 SophHub 商店中没有匹配的技能,使用 ClawHub 查找:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
clawhub search "<用户需求关键词>"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
如果找到合适的技能,反馈给用户确认后安装:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
clawhub install <技能名称>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## SophHub CLI 参考
|
|
48
|
+
|
|
49
|
+
列出所有商店类型的技能:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npx -y sophhub list --type store
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
列出所有技能(含内置技能):
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npx -y sophhub list
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
以 JSON 格式输出(便于程序解析):
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npx -y sophhub list --type store --json
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
下载指定技能到目标目录:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npx -y sophhub download <技能名称> -o <目标目录>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## ClawHub CLI 参考
|
|
74
|
+
|
|
75
|
+
安装
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npm i -g clawhub
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
搜索
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
clawhub search "postgres backups"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
安装技能
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
clawhub install my-skill
|
|
91
|
+
clawhub install my-skill --version 1.2.3
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
更新技能
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
clawhub update my-skill
|
|
98
|
+
clawhub update --all
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
列出已安装技能
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
clawhub list
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
说明
|
|
108
|
+
|
|
109
|
+
- 默认注册中心:https://clawhub.com(可通过 CLAWHUB_REGISTRY 或 --registry 覆盖)
|
|
110
|
+
- 默认工作目录:当前目录(回退到 OpenClaw 工作空间);安装目录:./skills(可通过 --workdir / --dir / CLAWHUB_WORKDIR 覆盖)
|
|
111
|
+
- 更新命令会对本地文件计算哈希、匹配版本,并升级到最新版本(除非指定了 --version)
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: aippt
|
|
3
|
+
description: Generate PPT or presentations with Docmee AiPPT. Use when the user asks to create PPT, slides, courseware, decks, or upload a custom PPT template and generate a presentation from a topic, file, URL, pasted text, or Markdown outline.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# aippt
|
|
7
|
+
|
|
8
|
+
基于文多多 AiPPT(`docmee.cn`)的 PPT 生成 skill。
|
|
9
|
+
|
|
10
|
+
它保留了现有 `aippt` skill 的统一入口思路:
|
|
11
|
+
|
|
12
|
+
- 根据输入自动识别生成模式
|
|
13
|
+
- 输出本地 `.pptx` 文件
|
|
14
|
+
- 支持标题/主题、文件、网页 URL、纯文本、Markdown 大纲
|
|
15
|
+
- 支持上传自定义模板并在生成时指定模板
|
|
16
|
+
- 支持在生成完成后调用接口更换 PPT 模板
|
|
17
|
+
- 支持传入已有 `pptId` 直接更换模板
|
|
18
|
+
|
|
19
|
+
## 工作目录
|
|
20
|
+
|
|
21
|
+
所有命令都在当前 skill 目录执行:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
SKILL_DIR="/path/to/skills/aippt-new"
|
|
25
|
+
cd "$SKILL_DIR"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Python 环境
|
|
29
|
+
|
|
30
|
+
脚本通过 `uv` 运行:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
cd "$SKILL_DIR"
|
|
34
|
+
uv sync
|
|
35
|
+
uv run scripts/ppt.py --title "AI 行业洞察"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 认证
|
|
39
|
+
|
|
40
|
+
`scripts/auth.py` 会自动按以下顺序读取 API Key:
|
|
41
|
+
|
|
42
|
+
1. 环境变量 `DOCMEE_API_KEY`
|
|
43
|
+
2. 技能目录中的本地文件 `docmee_api_key.json`
|
|
44
|
+
|
|
45
|
+
服务端调用默认直接把 API Key 作为 `token` 使用,无需额外创建临时 token。
|
|
46
|
+
|
|
47
|
+
### 首次调用规则
|
|
48
|
+
|
|
49
|
+
首次使用本 skill 前,先运行:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
cd "$SKILL_DIR"
|
|
53
|
+
uv run scripts/auth.py
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
如果提示缺少 API Key:
|
|
57
|
+
|
|
58
|
+
1. 不要继续生成 PPT。
|
|
59
|
+
2. 先向用户索取文多多 API Key。
|
|
60
|
+
3. 同时把注册链接发给用户:`https://docmee.cn/open`
|
|
61
|
+
4. 用户提供 key 后,立刻保存到 skill 本地文件:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
cd "$SKILL_DIR"
|
|
65
|
+
uv run scripts/auth.py --set-key "ak_xxx"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
5. 保存成功后,会在 skill 同级目录下创建 `docmee_api_key.json`,后续直接复用。
|
|
69
|
+
6. 再继续后续 PPT 操作。
|
|
70
|
+
|
|
71
|
+
后续调用默认直接复用 `docmee_api_key.json`,不再重复询问。
|
|
72
|
+
|
|
73
|
+
可单独验证认证:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
cd "$SKILL_DIR"
|
|
77
|
+
uv run scripts/auth.py
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
可查看本地 key 文件路径:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
cd "$SKILL_DIR"
|
|
84
|
+
uv run scripts/auth.py --show-path
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## 统一入口
|
|
88
|
+
|
|
89
|
+
主入口是 `scripts/ppt.py`。
|
|
90
|
+
|
|
91
|
+
### 自动识别规则
|
|
92
|
+
|
|
93
|
+
| 输入 | 模式 |
|
|
94
|
+
|---|---|
|
|
95
|
+
| `--file report.docx/pdf/pptx/txt/xlsx/...` | 上传文件生成 |
|
|
96
|
+
| `--file outline.md` | Markdown 大纲生成 |
|
|
97
|
+
| `--url https://...` | 网页 URL 生成 |
|
|
98
|
+
| `--content "# 标题\n## 章节"` | Markdown 大纲生成 |
|
|
99
|
+
| `--content "一段普通文本"` | 纯文本生成 |
|
|
100
|
+
| `--content-file outline.md` | Markdown 大纲生成 |
|
|
101
|
+
| `--content-file notes.txt` | 纯文本生成 |
|
|
102
|
+
| 无文件/URL/内容 | 主题智能生成 |
|
|
103
|
+
|
|
104
|
+
### 命令行参数
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
uv run scripts/ppt.py \
|
|
108
|
+
--title TITLE \
|
|
109
|
+
[--ppt-id PPT_ID] \
|
|
110
|
+
[--file FILE_PATH] \
|
|
111
|
+
[--url URL] \
|
|
112
|
+
[--content TEXT] \
|
|
113
|
+
[--content-file FILE] \
|
|
114
|
+
[--template-id ID] \
|
|
115
|
+
[--template-file FILE] \
|
|
116
|
+
[--replace-template-id ID] \
|
|
117
|
+
[--replace-template-file FILE] \
|
|
118
|
+
[--replace-template-sync] \
|
|
119
|
+
[--style "深蓝 科技"] \
|
|
120
|
+
[--outline-content TEXT] \
|
|
121
|
+
[--outline-file FILE] \
|
|
122
|
+
[--output /path/to/output.pptx]
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 典型用法
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
cd "$SKILL_DIR"
|
|
129
|
+
|
|
130
|
+
# 主题智能生成
|
|
131
|
+
uv run scripts/ppt.py --title "2026 年 AI 趋势"
|
|
132
|
+
|
|
133
|
+
# 上传文件生成
|
|
134
|
+
uv run scripts/ppt.py --title "年度报告" --file /path/to/report.docx
|
|
135
|
+
|
|
136
|
+
# 网页生成
|
|
137
|
+
uv run scripts/ppt.py --title "文章解读" --url "https://example.com/article"
|
|
138
|
+
|
|
139
|
+
# 纯文本生成
|
|
140
|
+
uv run scripts/ppt.py --title "AI 发展" --content "人工智能正在重塑软件和硬件产业。"
|
|
141
|
+
|
|
142
|
+
# Markdown 大纲生成
|
|
143
|
+
uv run scripts/ppt.py --title "技术方案" --content-file /path/to/outline.md
|
|
144
|
+
|
|
145
|
+
# 使用已有模板
|
|
146
|
+
uv run scripts/ppt.py --title "产品发布会" --template-id 12345
|
|
147
|
+
|
|
148
|
+
# 上传自定义模板并生成
|
|
149
|
+
uv run scripts/ppt.py \
|
|
150
|
+
--title "品牌方案" \
|
|
151
|
+
--file /path/to/brand-brief.docx \
|
|
152
|
+
--template-file /path/to/brand-template.pptx
|
|
153
|
+
|
|
154
|
+
# 上传模板并覆盖已有模板 ID
|
|
155
|
+
uv run scripts/ppt.py \
|
|
156
|
+
--title "品牌方案" \
|
|
157
|
+
--file /path/to/brand-brief.docx \
|
|
158
|
+
--template-id 12345 \
|
|
159
|
+
--template-file /path/to/brand-template.pptx
|
|
160
|
+
|
|
161
|
+
# 先生成,再更换为另一个模板
|
|
162
|
+
uv run scripts/ppt.py \
|
|
163
|
+
--title "品牌方案" \
|
|
164
|
+
--file /path/to/brand-brief.docx \
|
|
165
|
+
--replace-template-id 67890
|
|
166
|
+
|
|
167
|
+
# 先生成,再上传模板文件并更换
|
|
168
|
+
uv run scripts/ppt.py \
|
|
169
|
+
--title "品牌方案" \
|
|
170
|
+
--file /path/to/brand-brief.docx \
|
|
171
|
+
--replace-template-file /path/to/brand-template.pptx
|
|
172
|
+
|
|
173
|
+
# 对已有 PPT 直接更换模板
|
|
174
|
+
uv run scripts/ppt.py \
|
|
175
|
+
--ppt-id YOUR_PPT_ID \
|
|
176
|
+
--replace-template-id 67890
|
|
177
|
+
|
|
178
|
+
# 对已有 PPT 直接上传模板文件并更换
|
|
179
|
+
uv run scripts/ppt.py \
|
|
180
|
+
--ppt-id YOUR_PPT_ID \
|
|
181
|
+
--replace-template-file /path/to/brand-template.pptx
|
|
182
|
+
|
|
183
|
+
# 指定风格提示
|
|
184
|
+
uv run scripts/ppt.py --title "AI 芯片" --style "深蓝 科技"
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## 生成流程
|
|
188
|
+
|
|
189
|
+
### 普通模式
|
|
190
|
+
|
|
191
|
+
1. 自动识别输入模式
|
|
192
|
+
2. 若提供 `--template-file`,先上传自定义模板
|
|
193
|
+
3. 若未指定模板,则随机获取一个模板
|
|
194
|
+
4. 生成大纲
|
|
195
|
+
5. 生成大纲内容
|
|
196
|
+
6. 按模板生成 PPT
|
|
197
|
+
7. 若提供 `--replace-template-id` 或 `--replace-template-file`,生成后调用更换模板接口
|
|
198
|
+
8. 下载 `.pptx` 到本地
|
|
199
|
+
|
|
200
|
+
### Markdown 直出模式
|
|
201
|
+
|
|
202
|
+
当输入是 Markdown 大纲时:
|
|
203
|
+
|
|
204
|
+
1. 自动识别为 Markdown 模式
|
|
205
|
+
2. 若提供 `--template-file`,先上传模板
|
|
206
|
+
3. 若未指定模板,则随机获取一个模板
|
|
207
|
+
4. 直接按 Markdown 大纲生成 PPT
|
|
208
|
+
5. 若提供 `--replace-template-id` 或 `--replace-template-file`,生成后调用更换模板接口
|
|
209
|
+
6. 下载 `.pptx` 到本地
|
|
210
|
+
|
|
211
|
+
### 已有 PPT 直换模板模式
|
|
212
|
+
|
|
213
|
+
当提供 `--ppt-id` 时:
|
|
214
|
+
|
|
215
|
+
1. 读取已有 PPT 的 `pptId`
|
|
216
|
+
2. 使用 `--replace-template-id` / `--replace-template-file`,若未提供则回退到 `--template-id` / `--template-file`
|
|
217
|
+
3. 直接调用更换模板接口
|
|
218
|
+
4. 下载更新后的 `.pptx` 到本地
|
|
219
|
+
|
|
220
|
+
## 输出
|
|
221
|
+
|
|
222
|
+
默认输出目录:
|
|
223
|
+
|
|
224
|
+
```text
|
|
225
|
+
/home/node/.openclaw/workspace/media/inbound/ppt/
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
也可以通过 `--output` 指定保存路径。
|
|
229
|
+
|
|
230
|
+
脚本执行完成后,会同时输出:
|
|
231
|
+
|
|
232
|
+
- **保存路径**:本地 `.pptx` 文件路径(`PPT 下载完成,保存路径: ...`)
|
|
233
|
+
- **下载链接**:文件的下载 URL(`PPT 下载链接: ...`)
|
|
234
|
+
|
|
235
|
+
生成完毕后,请同时将保存路径和下载链接告知用户。
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""AIPPT-NEW 鉴权模块:自动获取并保存 Docmee API Key。
|
|
3
|
+
|
|
4
|
+
API Key 解析顺序:
|
|
5
|
+
1. 环境变量 DOCMEE_API_KEY
|
|
6
|
+
2. 技能目录中的本地文件 docmee_api_key.json
|
|
7
|
+
|
|
8
|
+
命令行:
|
|
9
|
+
python auth.py
|
|
10
|
+
python auth.py --set-key "ak_xxx"
|
|
11
|
+
python auth.py --clear-key
|
|
12
|
+
python auth.py --show-path
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import argparse
|
|
18
|
+
import json
|
|
19
|
+
import os
|
|
20
|
+
import stat
|
|
21
|
+
import sys
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
SKILL_DIR = Path(__file__).resolve().parent.parent
|
|
26
|
+
API_KEY_FILE = SKILL_DIR / "docmee_api_key.json"
|
|
27
|
+
REGISTER_URL = "https://docmee.cn/open"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def get_api_key_file_path() -> Path:
|
|
31
|
+
return API_KEY_FILE
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _read_local_api_key() -> str:
|
|
35
|
+
path = get_api_key_file_path()
|
|
36
|
+
try:
|
|
37
|
+
with path.open("r", encoding="utf-8") as file:
|
|
38
|
+
payload = json.load(file)
|
|
39
|
+
except FileNotFoundError:
|
|
40
|
+
return ""
|
|
41
|
+
except (OSError, json.JSONDecodeError):
|
|
42
|
+
return ""
|
|
43
|
+
return str(payload.get("apiKey", "")).strip()
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def save_api_key(api_key: str) -> Path:
|
|
47
|
+
value = api_key.strip()
|
|
48
|
+
if not value:
|
|
49
|
+
raise RuntimeError("API Key 为空,无法保存")
|
|
50
|
+
|
|
51
|
+
path = get_api_key_file_path()
|
|
52
|
+
payload = {"apiKey": value}
|
|
53
|
+
with path.open("w", encoding="utf-8") as file:
|
|
54
|
+
json.dump(payload, file, ensure_ascii=False, indent=2)
|
|
55
|
+
file.write("\n")
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
path.chmod(stat.S_IRUSR | stat.S_IWUSR)
|
|
59
|
+
except OSError:
|
|
60
|
+
pass
|
|
61
|
+
return path
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def clear_api_key() -> bool:
|
|
65
|
+
path = get_api_key_file_path()
|
|
66
|
+
if not path.exists():
|
|
67
|
+
return False
|
|
68
|
+
path.unlink()
|
|
69
|
+
return True
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def resolve_api_key() -> str:
|
|
73
|
+
"""自动获取 API Key:优先环境变量,其次技能目录本地文件。"""
|
|
74
|
+
key = os.environ.get("DOCMEE_API_KEY", "").strip()
|
|
75
|
+
if key:
|
|
76
|
+
return key
|
|
77
|
+
|
|
78
|
+
key = _read_local_api_key()
|
|
79
|
+
if key:
|
|
80
|
+
return key
|
|
81
|
+
|
|
82
|
+
raise RuntimeError(
|
|
83
|
+
"未找到 DOCMEE_API_KEY。请先向用户索取文多多 API Key 并执行 "
|
|
84
|
+
f'`uv run scripts/auth.py --set-key "ak_xxx"` 保存。注册链接:{REGISTER_URL}'
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def main() -> int:
|
|
89
|
+
parser = argparse.ArgumentParser(description="AIPPT-NEW 鉴权工具")
|
|
90
|
+
parser.add_argument("--set-key", dest="set_key", default=None, help="保存 Docmee API Key")
|
|
91
|
+
parser.add_argument("--clear-key", action="store_true", help="删除已保存的 Docmee API Key")
|
|
92
|
+
parser.add_argument("--show-path", action="store_true", help="显示本地 API Key 文件路径")
|
|
93
|
+
args = parser.parse_args()
|
|
94
|
+
|
|
95
|
+
try:
|
|
96
|
+
if args.show_path:
|
|
97
|
+
print(get_api_key_file_path())
|
|
98
|
+
return 0
|
|
99
|
+
|
|
100
|
+
if args.clear_key:
|
|
101
|
+
deleted = clear_api_key()
|
|
102
|
+
if deleted:
|
|
103
|
+
print(f"已删除本地 API Key 文件: {get_api_key_file_path()}")
|
|
104
|
+
else:
|
|
105
|
+
print(f"本地 API Key 文件不存在: {get_api_key_file_path()}")
|
|
106
|
+
return 0
|
|
107
|
+
|
|
108
|
+
if args.set_key is not None:
|
|
109
|
+
path = save_api_key(args.set_key)
|
|
110
|
+
print(f"API Key 保存成功: {path}")
|
|
111
|
+
return 0
|
|
112
|
+
|
|
113
|
+
api_key = resolve_api_key()
|
|
114
|
+
print(f"API Key 获取成功: {api_key[:8]}...{api_key[-4:]}")
|
|
115
|
+
return 0
|
|
116
|
+
except RuntimeError as exc:
|
|
117
|
+
print(f"错误:{exc}", file=sys.stderr)
|
|
118
|
+
return 1
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
if __name__ == "__main__":
|
|
122
|
+
raise SystemExit(main())
|