siluzan-tso-cli 1.0.0-beta.13 → 1.0.0-beta.15
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 +57 -14
- package/dist/commands/init.js +4 -4
- package/dist/index.js +5 -1
- package/{assets/siluzan-ads → dist/skill}/SKILL.md +1 -1
- package/dist/skill/_meta.json +5 -0
- package/{assets/siluzan-ads → dist/skill}/references/finance.md +5 -5
- package/{assets/siluzan-ads → dist/skill}/references/reporting.md +2 -2
- package/dist/skill/references/setup.md +119 -0
- package/{assets/siluzan-ads → dist/skill}/references/tso-home.md +1 -1
- package/{assets/siluzan-ads → dist/skill}/references/workflows.md +1 -1
- package/dist/templates/load-templates.d.ts +4 -3
- package/dist/templates/load-templates.js +4 -39
- package/dist/utils/version.d.ts +11 -0
- package/dist/utils/version.js +124 -0
- package/package.json +4 -5
- package/assets/siluzan-ads/references/setup.md +0 -80
- /package/{assets/siluzan-ads → dist/skill}/references/accounts.md +0 -0
- /package/{assets/siluzan-ads → dist/skill}/references/aigc.md +0 -0
- /package/{assets/siluzan-ads → dist/skill}/references/google-ads-test.md +0 -0
- /package/{assets/siluzan-ads → dist/skill}/references/google-ads.md +0 -0
- /package/{assets/siluzan-ads → dist/skill}/references/open-account-by-media.md +0 -0
- /package/{assets/siluzan-ads → dist/skill}/references/open-account-google-ui.md +0 -0
- /package/{assets/siluzan-ads → dist/skill}/references/tips.md +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Siluzan TSO Skill — 给大模型的安装说明
|
|
2
2
|
|
|
3
|
-
当用户发来本页面的 **URL**
|
|
3
|
+
当用户发来本页面的 **URL** 时,请按顺序协助用户完成安装。
|
|
4
4
|
|
|
5
5
|
## 1. 环境
|
|
6
6
|
|
|
@@ -13,10 +13,14 @@
|
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
15
|
npm install -g siluzan-tso-cli@beta
|
|
16
|
-
siluzan-tso init --ai cursor
|
|
16
|
+
siluzan-tso init --ai cursor # 写入 Cursor(默认)
|
|
17
|
+
siluzan-tso init --ai cursor,claude # 同时写入多个平台
|
|
18
|
+
siluzan-tso init --ai all # 写入所有支持的平台
|
|
19
|
+
siluzan-tso init -d /path/to/skills # 写入自定义目录
|
|
20
|
+
siluzan-tso init --force # 强制覆盖已存在文件
|
|
17
21
|
```
|
|
18
22
|
|
|
19
|
-
> **注意**:当前为测试版(1.0.0-beta.
|
|
23
|
+
> **注意**:当前为测试版(1.0.0-beta.15),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
|
|
20
24
|
|
|
21
25
|
| 助手 | 建议 `--ai` |
|
|
22
26
|
|------|-------------|
|
|
@@ -28,39 +32,78 @@ siluzan-tso init --ai cursor
|
|
|
28
32
|
| WorkBuddy(全局技能) | `workbuddy-global` |
|
|
29
33
|
| 一次写入多处 | `all` |
|
|
30
34
|
|
|
31
|
-
|
|
35
|
+
## 3. 登录 / 鉴权
|
|
32
36
|
|
|
33
|
-
|
|
37
|
+
`siluzan-tso` 与 `siluzan-cso` **共用同一个凭据**(存储在 `~/.siluzan/config.json`)。
|
|
34
38
|
|
|
35
|
-
|
|
39
|
+
**若用户已安装 `siluzan-cso` 并完成登录,无需重复操作,直接跳到第 4 步。**
|
|
36
40
|
|
|
37
|
-
|
|
41
|
+
### 方式 A:交互式登录(推荐)
|
|
38
42
|
|
|
39
|
-
|
|
43
|
+
```bash
|
|
44
|
+
siluzan-tso login
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
按提示访问丝路赞控制台「个人设置 → API Key 管理」页面创建 API Key 后粘贴到终端,自动保存。也可跳过交互直接传入:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
siluzan-tso login --api-key <YOUR_API_KEY>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 方式 B:直接设置(适合自动化场景)
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
siluzan-tso config set --api-key <你的ApiKey>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 方式 C:Token 登录(已有 siluzan-cso 账号)
|
|
40
60
|
|
|
41
61
|
```bash
|
|
42
62
|
npm install -g siluzan-cso-cli
|
|
43
63
|
siluzan-cso login
|
|
44
64
|
```
|
|
45
65
|
|
|
46
|
-
|
|
66
|
+
向导会提示用户访问 [https://www.siluzan.com](https://www.siluzan.com) 注册登录,在「个人设置 → API Token」页面复制 Token 粘贴到命令行,自动保存后 `siluzan-tso` 会读取该 Token。
|
|
47
67
|
|
|
48
|
-
提醒用户:**不要将 Token 提交到 Git。**
|
|
68
|
+
提醒用户:**不要将 Token / API Key 提交到 Git。**
|
|
49
69
|
|
|
50
70
|
## 4. 验证
|
|
51
71
|
|
|
52
|
-
确认以下路径已存在且含 `SKILL.md`:
|
|
72
|
+
确认以下路径已存在且含 `SKILL.md` 和 `_meta.json`:
|
|
53
73
|
|
|
54
74
|
| 助手 | Skill 文件路径 |
|
|
55
75
|
|------|----------------|
|
|
56
76
|
| Cursor | `.cursor/skills/siluzan-tso/SKILL.md` |
|
|
57
77
|
| Claude Code | `.claude/skills/siluzan-tso/SKILL.md` |
|
|
58
78
|
| OpenClaw 工作区 | `skills/siluzan-tso/SKILL.md` |
|
|
79
|
+
| OpenClaw 全局 | `~/.openclaw/skills/siluzan-tso/SKILL.md` |
|
|
59
80
|
| WorkBuddy 项目级 | `.workbuddy/skills/siluzan-tso/SKILL.md` |
|
|
60
81
|
| WorkBuddy 全局 | `~/.workbuddy/skills/siluzan-tso/SKILL.md` |
|
|
61
82
|
|
|
62
|
-
|
|
83
|
+
完成后,用户可在对话中描述广告账户管理需求(查账户、查余额、查消耗、充值、开户、绑定 MCC/BC/BM、管理 Google 广告等),由已加载的 Skill 指导 `siluzan-tso` CLI 的使用方式。
|
|
84
|
+
|
|
85
|
+
## 5. 更新
|
|
86
|
+
|
|
87
|
+
CLI 在每次命令执行后会静默检查是否有新版本可用,有更新时会提示:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
💡 发现新版本 x.x.x(测试版),运行以下命令升级:
|
|
91
|
+
npm install -g siluzan-tso-cli@beta
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**发现提示后,Agent 应主动执行以下两步完成升级:**
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# 第一步:升级 CLI
|
|
98
|
+
{{INSTALL_CMD}}
|
|
99
|
+
|
|
100
|
+
# 第二步:用新版 CLI 重新写入 Skill 文件(--force 覆盖旧版)
|
|
101
|
+
siluzan-tso init --ai xxx --force
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
> `--ai` 参数换成实际使用的平台(如 `claude`、`openclaw-global` 等)。
|
|
105
|
+
> 若不确定当前安装在哪个平台,可查看 `~/.siluzan/config.json` 中的 `tsoInstalledTargets` 字段。
|
|
63
106
|
|
|
64
|
-
##
|
|
107
|
+
## 6. Token 续期
|
|
65
108
|
|
|
66
|
-
Token 过期后,重新运行 `siluzan-cso login`
|
|
109
|
+
Token 过期后,重新运行 `siluzan-cso login` 或 `siluzan-tso config set --api-key <新Key>` 即可,`siluzan-tso` 自动读取新凭据,无需额外操作。
|
package/dist/commands/init.js
CHANGED
|
@@ -51,9 +51,9 @@ function parseTargets(raw) {
|
|
|
51
51
|
}
|
|
52
52
|
return [...new Set(result)];
|
|
53
53
|
}
|
|
54
|
-
function
|
|
55
|
-
// dist/commands/init.js →
|
|
56
|
-
return path.join(__dirname, "..", "
|
|
54
|
+
function skillRoot() {
|
|
55
|
+
// dist/commands/init.js → dist/skill/
|
|
56
|
+
return path.join(__dirname, "..", "skill");
|
|
57
57
|
}
|
|
58
58
|
/** 将 skill 文件写入指定目录,返回是否有文件被写入 */
|
|
59
59
|
async function writeSkillFilesToDir(destDir, skillFiles, force) {
|
|
@@ -106,7 +106,7 @@ function saveInstalledTargets(entries) {
|
|
|
106
106
|
}
|
|
107
107
|
export async function runInit(options) {
|
|
108
108
|
const home = os.homedir();
|
|
109
|
-
const skillFiles = await getSkillFiles(
|
|
109
|
+
const skillFiles = await getSkillFiles(skillRoot());
|
|
110
110
|
const installedEntries = [];
|
|
111
111
|
if (options.dir) {
|
|
112
112
|
// 自定义目录模式
|
package/dist/index.js
CHANGED
|
@@ -26,6 +26,7 @@ import { runKeywordSuggest } from "./commands/keyword.js";
|
|
|
26
26
|
import { runAccountDelink, runAccountShare, runAccountUnshare, runAccountShareDetail, runAccountAuth, runAccountMccBind, runAccountMccUnbind, runAccountClose, runAccountBmBind, runAccountWithdrawList, runAccountWithdrawSubmit, runAccountBcBind, runAccountBcUnbind, runAccountEmailAuthList, runAccountEmailAuth, runAccountEmailDeauth, } from "./commands/account-manage.js";
|
|
27
27
|
import { runListAdvertiserGroups, runOpenAccountYandex, runOpenAccountBing, runOpenAccountKwai, runOpenAccountGoogleTimezones, runOpenAccountGoogleWizard, runOpenAccountGoogle, runOpenAccountTikTok, runOpenAccountTikTokTimezones, runOpenAccountTikTokIndustries, runOpenAccountTikTokAreas, runOpenAccountBingIndustries, } from "./commands/open-account.js";
|
|
28
28
|
import { runLogin } from "./commands/login.js";
|
|
29
|
+
import { notifyIfOutdated } from "./utils/version.js";
|
|
29
30
|
/** 从 package.json 读取当前版本号 */
|
|
30
31
|
function getVersion() {
|
|
31
32
|
try {
|
|
@@ -1970,4 +1971,7 @@ program
|
|
|
1970
1971
|
console.log(" 诊断入口(测试):https://www-ci.siluzan.com/diagnostics/\n");
|
|
1971
1972
|
console.log(" 请在浏览器中打开上述地址完成诊断操作。\n");
|
|
1972
1973
|
});
|
|
1973
|
-
|
|
1974
|
+
// parseAsync 支持异步 action;命令执行完后触发版本检查(不阻塞主流程)
|
|
1975
|
+
program.parseAsync().then(() => {
|
|
1976
|
+
notifyIfOutdated();
|
|
1977
|
+
});
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
## invoice-info — 发票抬头管理
|
|
9
9
|
|
|
10
|
-
对应页面:`
|
|
10
|
+
对应页面:`https://www-ci.siluzan.com/v3/foreign_trade/settings/invoiceInformation`
|
|
11
11
|
|
|
12
12
|
发票抬头是开票申请时使用的公司/企业信息模板,支持三种类型:
|
|
13
13
|
- **PI**:形式发票(境外美金账户,英文信息)
|
|
@@ -130,10 +130,10 @@ siluzan-tso config show
|
|
|
130
130
|
**示例:**
|
|
131
131
|
|
|
132
132
|
```
|
|
133
|
-
- 现金充值(单笔):
|
|
134
|
-
- 现金充值(批量):
|
|
135
|
-
- 月结充值:
|
|
136
|
-
- 丝路赞钱包:
|
|
133
|
+
- 现金充值(单笔):https://www-ci.siluzan.com/recharge/pay
|
|
134
|
+
- 现金充值(批量):https://www-ci.siluzan.com/recharge/pay_batch
|
|
135
|
+
- 月结充值: https://www-ci.siluzan.com/recharge/accountBillingQuota
|
|
136
|
+
- 丝路赞钱包: https://www-ci.siluzan.com/recharge/siluzanWallet
|
|
137
137
|
```
|
|
138
138
|
|
|
139
139
|
---
|
|
@@ -132,10 +132,10 @@ siluzan-tso report list -m Google --json
|
|
|
132
132
|
|
|
133
133
|
# 第二步:查看 webUrl
|
|
134
134
|
siluzan-tso config show
|
|
135
|
-
# webUrl:
|
|
135
|
+
# webUrl: https://www-ci.siluzan.com
|
|
136
136
|
|
|
137
137
|
# 第三步:拼接链接(Google 日报)
|
|
138
|
-
#
|
|
138
|
+
# https://www-ci.siluzan.com/media-report/publish/rpt_abc123?culture=zh-CN
|
|
139
139
|
```
|
|
140
140
|
|
|
141
141
|
---
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# 安装与配置
|
|
2
|
+
|
|
3
|
+
## 安装 CLI
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install -g siluzan-tso-cli@beta
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
环境要求:Node.js 18+
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 初始化 Skill 文件
|
|
14
|
+
|
|
15
|
+
将 Skill 文件写入 AI 助手目录,使 Agent 能读取到本文档:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
siluzan-tso init # 写入 Cursor(默认)
|
|
19
|
+
siluzan-tso init --ai cursor,claude,workbuddy,openclaw # 同时写入多个平台
|
|
20
|
+
siluzan-tso init --ai all # 写入所有支持的平台
|
|
21
|
+
siluzan-tso init -d /path/to/skills # 写入自定义目录
|
|
22
|
+
siluzan-tso init --force # 强制覆盖已存在文件
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
根据你的平台,使用不同的安装命令,如果没有列出你的平台,则使用 `init -d /path/to/skills`的方式,将skill复制到你的skill目录下
|
|
26
|
+
支持的 `--ai` 目标:
|
|
27
|
+
|
|
28
|
+
| 值 | 写入路径 |
|
|
29
|
+
|----|---------|
|
|
30
|
+
| `cursor` | `.cursor/skills/siluzan-tso/` |
|
|
31
|
+
| `claude` | `.claude/skills/siluzan-tso/` |
|
|
32
|
+
| `openclaw-workspace` | `skills/siluzan-tso/` |
|
|
33
|
+
| `openclaw-global` | `~/.openclaw/skills/siluzan-tso/` |
|
|
34
|
+
| `workbuddy-workspace` | `.workbuddy/skills/siluzan-tso/` |
|
|
35
|
+
| `workbuddy-global` | `~/.workbuddy/skills/siluzan-tso/` |
|
|
36
|
+
| `all` | 以上全部 |
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 首次登录 / 配置凭据
|
|
41
|
+
|
|
42
|
+
`siluzan-tso` 与 `siluzan-cso` **共用同一份凭据**,存储在 `~/.siluzan/config.json`,配置一次两个 CLI 均可使用。
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
siluzan-tso login # 交互式登录,按提示创建 API Key 后粘贴
|
|
46
|
+
siluzan-tso login --api-key <YOUR_API_KEY> # 直接设置 API Key(跳过交互)
|
|
47
|
+
siluzan-tso config set --api-key <Key> # 或通过 config set 直接写入
|
|
48
|
+
siluzan-tso config set --token <Token> # 备用:设置 JWT Token
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
API Key 获取入口:`https://www-ci.siluzan.com/v3/foreign_trade/settings/apiKeyManagement`
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 查看当前配置
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
siluzan-tso config show
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
输出示例:
|
|
62
|
+
```
|
|
63
|
+
构建环境 : production
|
|
64
|
+
apiBaseUrl : https://tso-api-ci.siluzan.com
|
|
65
|
+
googleApiUrl : https://googleapi-ci.mysiluzan.com
|
|
66
|
+
webUrl : https://www-ci.siluzan.com
|
|
67
|
+
apiKey : abcd****1234
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`webUrl` 是前端页面基地址,需要引导用户打开网页时用此值拼接路径。
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 更新 CLI 与 Skill 文件
|
|
75
|
+
|
|
76
|
+
CLI 在每次命令执行后会静默检查新版本,有更新时提示:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
💡 发现新版本 x.x.x,运行以下命令升级:
|
|
80
|
+
npm install -g siluzan-tso-cli@beta
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
发现提示后主动执行:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
npm install -g siluzan-tso-cli@beta # 升级 CLI
|
|
87
|
+
siluzan-tso init --force # 重新写入 Skill 文件(--ai 与初始安装时一致)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
已安装过的目标平台记录在 `~/.siluzan/config.json` 的 `tsoInstalledTargets` 字段,可用于确认需要更新哪些平台。
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 修改其他配置
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
siluzan-tso config set --api-base <url> # 切换 TSO API 地址
|
|
98
|
+
siluzan-tso config set --google-api <url> # 切换 Google 网关地址
|
|
99
|
+
siluzan-tso config clear # 清空所有凭据
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## 环境切换
|
|
105
|
+
|
|
106
|
+
| 配置项 | 生产环境(默认) | 测试环境 |
|
|
107
|
+
|--------|----------------|---------|
|
|
108
|
+
| `apiBaseUrl` | `https://tso-api.siluzan.com` | `https://tso-api-ci.siluzan.com` |
|
|
109
|
+
| `googleApiUrl` | `https://googleapi.mysiluzan.com` | `https://googleapi-ci.mysiluzan.com` |
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# 切换到测试环境
|
|
113
|
+
siluzan-tso config set --api-base https://tso-api-ci.siluzan.com
|
|
114
|
+
siluzan-tso config set --google-api https://googleapi-ci.mysiluzan.com
|
|
115
|
+
|
|
116
|
+
# 切回生产环境
|
|
117
|
+
siluzan-tso config set --api-base https://tso-api.siluzan.com
|
|
118
|
+
siluzan-tso config set --google-api https://googleapi.mysiluzan.com
|
|
119
|
+
```
|
|
@@ -252,7 +252,7 @@ Failed / HasFailed(部分或全部失败)
|
|
|
252
252
|
# 前置:确认 Google API 地址已配置
|
|
253
253
|
siluzan-tso config show
|
|
254
254
|
# 若 googleApiUrl 为空,先配置:
|
|
255
|
-
# siluzan-tso config set --google-api
|
|
255
|
+
# siluzan-tso config set --google-api https://googleapi-ci.mysiluzan.com
|
|
256
256
|
|
|
257
257
|
# 第一步:确认目标账户
|
|
258
258
|
siluzan-tso list-accounts -m Google --json
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* 读取 dist/skill/ 目录下所有文件,返回 { 相对路径: 文件内容 } 映射。
|
|
3
|
+
*
|
|
4
|
+
* 占位符替换已在构建阶段(copy-skill-assets.mjs)完成,此处无需二次处理。
|
|
4
5
|
*/
|
|
5
|
-
export declare function getSkillFiles(
|
|
6
|
+
export declare function getSkillFiles(skillDir: string): Promise<Record<string, string>>;
|
|
@@ -1,45 +1,11 @@
|
|
|
1
1
|
import * as fs from "node:fs/promises";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import { DEFAULT_API_BASE, DEFAULT_GOOGLE_API } from "../config/defaults.js";
|
|
4
3
|
/**
|
|
5
|
-
*
|
|
6
|
-
* tso-api.siluzan.com → www.siluzan.com
|
|
7
|
-
* tso-api-ci.siluzan.com → www-ci.siluzan.com
|
|
8
|
-
*/
|
|
9
|
-
function deriveWebBaseUrl(tsoApiBase) {
|
|
10
|
-
try {
|
|
11
|
-
const u = new URL(tsoApiBase);
|
|
12
|
-
u.hostname = u.hostname.replace(/^tso-api/, "www");
|
|
13
|
-
return u.origin;
|
|
14
|
-
}
|
|
15
|
-
catch {
|
|
16
|
-
return "https://www.siluzan.com";
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
// 构建时确定的环境变量,用于替换 markdown 中的占位符
|
|
20
|
-
const WEB_URL = deriveWebBaseUrl(DEFAULT_API_BASE);
|
|
21
|
-
const TSO_API_URL = DEFAULT_API_BASE;
|
|
22
|
-
const GOOGLE_API_URL = DEFAULT_GOOGLE_API;
|
|
23
|
-
/**
|
|
24
|
-
* 将 markdown 内容中的环境占位符替换为当前构建环境对应的真实地址。
|
|
4
|
+
* 读取 dist/skill/ 目录下所有文件,返回 { 相对路径: 文件内容 } 映射。
|
|
25
5
|
*
|
|
26
|
-
*
|
|
27
|
-
* {{WEB_URL}} → 前端页面基地址(如 https://www.siluzan.com)
|
|
28
|
-
* {{TSO_API_URL}} → TSO 主 API 地址
|
|
29
|
-
* {{GOOGLE_API_URL}} → Google 广告网关地址
|
|
30
|
-
*/
|
|
31
|
-
function applyEnvPlaceholders(content) {
|
|
32
|
-
return content
|
|
33
|
-
.replaceAll("{{WEB_URL}}", WEB_URL)
|
|
34
|
-
.replaceAll("{{TSO_API_URL}}", TSO_API_URL)
|
|
35
|
-
.replaceAll("{{GOOGLE_API_URL}}", GOOGLE_API_URL);
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* 从 assets/siluzan-ads/ 目录读取所有 skill 文件,返回 { 相对路径: 文件内容 } 映射。
|
|
39
|
-
* 读取后自动将环境占位符替换为当前构建环境对应的真实地址。
|
|
6
|
+
* 占位符替换已在构建阶段(copy-skill-assets.mjs)完成,此处无需二次处理。
|
|
40
7
|
*/
|
|
41
|
-
export async function getSkillFiles(
|
|
42
|
-
const skillDir = path.join(assetsDir, "siluzan-ads");
|
|
8
|
+
export async function getSkillFiles(skillDir) {
|
|
43
9
|
const out = {};
|
|
44
10
|
async function walk(dir, prefix) {
|
|
45
11
|
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
@@ -50,8 +16,7 @@ export async function getSkillFiles(assetsDir) {
|
|
|
50
16
|
await walk(full, rel);
|
|
51
17
|
}
|
|
52
18
|
else {
|
|
53
|
-
|
|
54
|
-
out[rel] = applyEnvPlaceholders(raw);
|
|
19
|
+
out[rel] = await fs.readFile(full, "utf8");
|
|
55
20
|
}
|
|
56
21
|
}
|
|
57
22
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** 读取 CLI 自身的当前版本(来自 package.json) */
|
|
2
|
+
export declare function getCurrentVersion(): string;
|
|
3
|
+
/** 比较语义化版本,支持 beta 后缀,返回 true 表示 b > a */
|
|
4
|
+
export declare function isNewer(a: string, b: string): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* 静默版本检查:命令完成后异步触发。
|
|
7
|
+
* - 当前为 beta 版 → 对比 npm beta tag 的最新版本
|
|
8
|
+
* - 当前为正式版 → 对比 npm latest tag 的最新版本
|
|
9
|
+
* 有更新时打印一行提示,不阻塞主命令,不抛出异常。
|
|
10
|
+
*/
|
|
11
|
+
export declare function notifyIfOutdated(): Promise<void>;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import * as os from "node:os";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
const CONFIG_FILE = path.join(os.homedir(), ".siluzan", "config.json");
|
|
6
|
+
const PKG_NAME = "siluzan-tso-cli";
|
|
7
|
+
/** 读取 CLI 自身的当前版本(来自 package.json) */
|
|
8
|
+
export function getCurrentVersion() {
|
|
9
|
+
try {
|
|
10
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
// dist/utils/version.js → ../../package.json
|
|
12
|
+
const pkgPath = path.join(__dirname, "..", "..", "package.json");
|
|
13
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
14
|
+
return pkg.version ?? "0.0.0";
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return "0.0.0";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** 判断当前版本是否为 beta(版本号含 -beta) */
|
|
21
|
+
function isBetaVersion(version) {
|
|
22
|
+
return version.includes("-beta");
|
|
23
|
+
}
|
|
24
|
+
/** 比较语义化版本,支持 beta 后缀,返回 true 表示 b > a */
|
|
25
|
+
export function isNewer(a, b) {
|
|
26
|
+
// 拆出纯数字部分,如 "1.0.0-beta.12" → [1,0,0,12]
|
|
27
|
+
const parse = (v) => {
|
|
28
|
+
const [base, pre] = v.replace(/^v/, "").split("-beta.");
|
|
29
|
+
const nums = base.split(".").map(Number);
|
|
30
|
+
// beta 版附加预发布号;无预发布号的正式版视为无穷大(正式版 > beta)
|
|
31
|
+
nums.push(pre !== undefined ? Number(pre) : Infinity);
|
|
32
|
+
return nums;
|
|
33
|
+
};
|
|
34
|
+
const av = parse(a);
|
|
35
|
+
const bv = parse(b);
|
|
36
|
+
for (let i = 0; i < Math.max(av.length, bv.length); i++) {
|
|
37
|
+
const ai = av[i] ?? 0;
|
|
38
|
+
const bi = bv[i] ?? 0;
|
|
39
|
+
if (bi !== ai)
|
|
40
|
+
return bi > ai;
|
|
41
|
+
}
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
function readConfigRaw() {
|
|
45
|
+
try {
|
|
46
|
+
return JSON.parse(fs.readFileSync(CONFIG_FILE, "utf8"));
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function writeConfigRaw(data) {
|
|
53
|
+
try {
|
|
54
|
+
fs.mkdirSync(path.dirname(CONFIG_FILE), { recursive: true });
|
|
55
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(data, null, 2), "utf8");
|
|
56
|
+
if (process.platform !== "win32") {
|
|
57
|
+
fs.chmodSync(CONFIG_FILE, 0o600);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// 写入失败不影响主流程
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 从 npm registry 查询指定 tag 的最新版本。
|
|
66
|
+
* 结果缓存于 config.json,24 小时内不重复请求。
|
|
67
|
+
*/
|
|
68
|
+
async function fetchVersionByTag(tag, cfg) {
|
|
69
|
+
const cacheKey = tag === "beta" ? "_tsoLatestBeta" : "_tsoLatestStable";
|
|
70
|
+
const hours24 = 24 * 60 * 60 * 1000;
|
|
71
|
+
// 检查 24 小时内的缓存(两个 tag 共用同一个检查时间戳)
|
|
72
|
+
if (cfg._tsoLastVersionCheck && cfg[cacheKey]) {
|
|
73
|
+
const lastCheck = new Date(cfg._tsoLastVersionCheck).getTime();
|
|
74
|
+
if (Date.now() - lastCheck < hours24) {
|
|
75
|
+
return cfg[cacheKey];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
const url = `https://registry.npmjs.org/${PKG_NAME}/${tag}`;
|
|
80
|
+
const controller = new AbortController();
|
|
81
|
+
const timer = setTimeout(() => controller.abort(), 4000);
|
|
82
|
+
const res = await fetch(url, { signal: controller.signal });
|
|
83
|
+
clearTimeout(timer);
|
|
84
|
+
if (!res.ok)
|
|
85
|
+
return null;
|
|
86
|
+
const data = await res.json();
|
|
87
|
+
return data.version ?? null;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 静默版本检查:命令完成后异步触发。
|
|
95
|
+
* - 当前为 beta 版 → 对比 npm beta tag 的最新版本
|
|
96
|
+
* - 当前为正式版 → 对比 npm latest tag 的最新版本
|
|
97
|
+
* 有更新时打印一行提示,不阻塞主命令,不抛出异常。
|
|
98
|
+
*/
|
|
99
|
+
export async function notifyIfOutdated() {
|
|
100
|
+
try {
|
|
101
|
+
const current = getCurrentVersion();
|
|
102
|
+
const isBeta = isBetaVersion(current);
|
|
103
|
+
const tag = isBeta ? "beta" : "latest";
|
|
104
|
+
const cfg = readConfigRaw();
|
|
105
|
+
const latest = await fetchVersionByTag(tag, cfg);
|
|
106
|
+
if (!latest)
|
|
107
|
+
return;
|
|
108
|
+
// 更新缓存
|
|
109
|
+
const cacheKey = isBeta ? "_tsoLatestBeta" : "_tsoLatestStable";
|
|
110
|
+
writeConfigRaw({
|
|
111
|
+
...cfg,
|
|
112
|
+
_tsoLastVersionCheck: new Date().toISOString(),
|
|
113
|
+
[cacheKey]: latest,
|
|
114
|
+
});
|
|
115
|
+
if (isNewer(current, latest)) {
|
|
116
|
+
const tagLabel = isBeta ? "(测试版)" : "(正式版)";
|
|
117
|
+
console.error(`\n💡 发现新版本 ${latest}${tagLabel}(当前 ${current}),运行以下命令升级:\n` +
|
|
118
|
+
` npm install -g ${PKG_NAME}@${tag}\n`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// 静默,不干扰用户
|
|
123
|
+
}
|
|
124
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "siluzan-tso-cli",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.15",
|
|
4
4
|
"description": "Siluzan 广告账户管理 CLI — 查询账户、余额、消耗数据,管理绑定关系与充值。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,14 +8,13 @@
|
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"dist",
|
|
11
|
-
"assets",
|
|
12
11
|
"README.md"
|
|
13
12
|
],
|
|
14
13
|
"scripts": {
|
|
15
14
|
"prebuild": "node scripts/write-defaults.mjs --env production",
|
|
16
|
-
"build": "tsc",
|
|
17
|
-
"build:prod": "node scripts/write-defaults.mjs --env production && tsc",
|
|
18
|
-
"build:test": "node scripts/write-defaults.mjs --env test && tsc",
|
|
15
|
+
"build": "tsc && node scripts/copy-skill-assets.mjs --env production",
|
|
16
|
+
"build:prod": "node scripts/write-defaults.mjs --env production && tsc && node scripts/copy-skill-assets.mjs --env production",
|
|
17
|
+
"build:test": "node scripts/write-defaults.mjs --env test && tsc && node scripts/copy-skill-assets.mjs --env test",
|
|
19
18
|
"start": "node dist/index.js",
|
|
20
19
|
"prepublishOnly": "npm run build:prod",
|
|
21
20
|
"prepublishOnly:test": "npm run build:test"
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# 安装、登录与配置
|
|
2
|
-
|
|
3
|
-
## 安装 Skill 文件(首次)
|
|
4
|
-
|
|
5
|
-
运行以下命令将 Skill 文件写入 AI 助手目录,使 AI Agent 能读取到本文档:
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
siluzan-tso init # 写入 Cursor(默认)
|
|
9
|
-
siluzan-tso init -a cursor,claude # 写入多个平台
|
|
10
|
-
siluzan-tso init -d /path/to/skills # 写入自定义目录
|
|
11
|
-
siluzan-tso init --force # 强制覆盖已存在文件
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
支持的目标(`-a`):`cursor` | `claude` | `openclaw-workspace` | `openclaw-global` | `workbuddy-workspace` | `workbuddy-global` | `all`
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
## 首次登录
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
siluzan-tso login
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
按提示访问 `{{WEB_URL}}/v3/foreign_trade/settings/apiKeyManagement`,创建 API Key 后粘贴到终端。
|
|
25
|
-
API Key 保存在 `~/.siluzan/config.json`,与 `siluzan-cso` 共用,配置一次两个 CLI 均可使用。
|
|
26
|
-
|
|
27
|
-
也可直接通过参数跳过交互:
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
siluzan-tso login --api-key <YOUR_API_KEY>
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## 查看当前配置
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
siluzan-tso config show
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
输出示例:
|
|
42
|
-
```
|
|
43
|
-
apiBaseUrl : {{TSO_API_URL}}
|
|
44
|
-
googleApiUrl : {{GOOGLE_API_URL}}
|
|
45
|
-
webUrl : {{WEB_URL}}
|
|
46
|
-
apiKey : abcd****1234
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
`webUrl` 是前端页面基地址,需要引导用户打开网页时用此值拼接路径。
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
## 修改配置
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
siluzan-tso config set --api-key <新ApiKey> # 推荐:设置 API Key
|
|
57
|
-
siluzan-tso config set --token <新Token> # 备用:设置 JWT Token
|
|
58
|
-
siluzan-tso config set --api-base <url> # 切换 TSO API 地址
|
|
59
|
-
siluzan-tso config set --google-api <url> # 切换 Google 网关地址
|
|
60
|
-
siluzan-tso config clear # 清空凭据
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
---
|
|
64
|
-
|
|
65
|
-
## 环境切换
|
|
66
|
-
|
|
67
|
-
| 配置项 | 生产环境(默认) | 测试环境 |
|
|
68
|
-
|--------|----------------|---------|
|
|
69
|
-
| `apiBaseUrl` | `https://tso-api.siluzan.com` | `https://tso-api-ci.siluzan.com` |
|
|
70
|
-
| `googleApiUrl` | `https://googleapi.mysiluzan.com` | `https://googleapi-ci.mysiluzan.com` |
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
# 切换到测试环境
|
|
74
|
-
siluzan-tso config set --api-base https://tso-api-ci.siluzan.com
|
|
75
|
-
siluzan-tso config set --google-api https://googleapi-ci.mysiluzan.com
|
|
76
|
-
|
|
77
|
-
# 切回生产环境
|
|
78
|
-
siluzan-tso config set --api-base https://tso-api.siluzan.com
|
|
79
|
-
siluzan-tso config set --google-api https://googleapi.mysiluzan.com
|
|
80
|
-
```
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|