siluzan-website-cli 1.0.1-beta.1
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 +35 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4192 -0
- package/dist/skill/SKILL.md +75 -0
- package/dist/skill/_meta.json +21 -0
- package/dist/skill/references/pages.md +57 -0
- package/dist/skill/references/plugins.md +54 -0
- package/dist/skill/references/setup.md +73 -0
- package/dist/skill/references/sites.md +35 -0
- package/dist/skill/scripts/install.ps1 +275 -0
- package/dist/skill/scripts/install.sh +180 -0
- package/package.json +59 -0
- package/scripts/postinstall.mjs +3 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: siluzan-website
|
|
3
|
+
description: >-
|
|
4
|
+
管理丝路赞 WordPress 站点(wp-k8s 托管):列出我的站点、新增/编辑页面、从丝路赞目录安装插件。
|
|
5
|
+
当用户提到 WordPress、建站后台、新增页面、改官网、装插件、站点 guid、
|
|
6
|
+
siluzan-website、zionbuilder、visual-edit 时使用。不是 LPS / AI Sites,也不是 SEO JSON 生成。
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# siluzan-website
|
|
10
|
+
|
|
11
|
+
管理用户账号下的 **WordPress 站点**(TSO 建站 / wp-k8s)。通过 CLI 调平台 all-sites 与站点 WP REST,不要手写 curl,不要猜 guid / 页面 ID。
|
|
12
|
+
|
|
13
|
+
**不是** `landing-page-system` 的 LPS Agent,也不是 `siluzan-seo` 的 schema 生成。用户要的是「我的官网加一页 / 看插件」才用本 Skill。
|
|
14
|
+
|
|
15
|
+
## 一键安装
|
|
16
|
+
|
|
17
|
+
如果 CLI 尚未安装,直接帮用户执行:
|
|
18
|
+
|
|
19
|
+
- **macOS / Linux / WSL:**
|
|
20
|
+
```bash
|
|
21
|
+
bash <(curl -fsSL https://unpkg.com/siluzan-website-cli@latest/dist/skill/scripts/install.sh)
|
|
22
|
+
```
|
|
23
|
+
- **Windows PowerShell:**
|
|
24
|
+
```powershell
|
|
25
|
+
irm https://unpkg.com/siluzan-website-cli@latest/dist/skill/scripts/install.ps1 | iex
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Windows 注意:部分 Agent 通过 PowerShell / cmd 代执行时可能失败。若异常,先装 [Git for Windows](https://git-scm.com/download/win),再在 Git Bash 里跑上面的 bash 命令。
|
|
29
|
+
|
|
30
|
+
脚本会检测 Node.js、全局安装 CLI、`init --global --force`,并引导 `login`。凭据与 CSO/TSO 共用 `~/.siluzan/config.json`。
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 命令索引
|
|
35
|
+
|
|
36
|
+
| 命令 | 作用 | 文档 |
|
|
37
|
+
|------|------|------|
|
|
38
|
+
| `siluzan-website login` / `send-login-code` | 登录并保存 API Key | [references/setup.md](references/setup.md) |
|
|
39
|
+
| `siluzan-website config show/set/clear` | 查看 / 写入凭据 | [references/setup.md](references/setup.md) |
|
|
40
|
+
| `siluzan-website init` / `update` | 写入 / 刷新 Skill 文件 | [references/setup.md](references/setup.md) |
|
|
41
|
+
| `siluzan-website sites list` | 列出我的 WordPress 站点 | [references/sites.md](references/sites.md) |
|
|
42
|
+
| `siluzan-website pages list/add/update` | 列出 / 新增 / 覆盖页面 | [references/pages.md](references/pages.md) |
|
|
43
|
+
| `siluzan-website plugins list/catalog/install` | 已装列表 / 目录 / 安装并启用 | [references/plugins.md](references/plugins.md) |
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 场景路由
|
|
48
|
+
|
|
49
|
+
| 用户在做什么 | 先读 | 再执行 |
|
|
50
|
+
|--------------|------|--------|
|
|
51
|
+
| 首次安装 / 登录 | `references/setup.md` | `login` 或复用已有 CSO/TSO 凭据 |
|
|
52
|
+
| 我有哪些网站 | `references/sites.md` | `sites list`,不要猜 guid |
|
|
53
|
+
| 加一页 / 改一页 | `references/pages.md` | 先 `sites list` 再 `pages add/update` |
|
|
54
|
+
| 这个站装了哪些插件 | `references/plugins.md` | `plugins list` |
|
|
55
|
+
| 安装 / 启用插件 | `references/plugins.md` | `catalog` 找 slug → 确认 → `install` |
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## AI 行为规范
|
|
60
|
+
|
|
61
|
+
1. **计划 → 确认 → 执行 → 验证**
|
|
62
|
+
- 写操作(`pages add` / `pages update` / `plugins install`)会立刻生效,执行前必须复述目标站点与内容,获得用户确认。
|
|
63
|
+
- 只读(`sites list` / `pages list` / `plugins list` / `plugins catalog` / `config show`)可直接跑。
|
|
64
|
+
2. **不猜 ID**:站点用 `sites list` 的 `guid`;页面用 `pages list` 的 `id`。
|
|
65
|
+
3. **先查再写**:改页面前先 `pages list` 确认目标页存在。
|
|
66
|
+
4. **只认 API Key**:所有命令走 `x-api-key`(`SILUZAN_API_KEY` 或 `login` 写入的 config)。Agent 沙箱只注入 Key,不要向用户要 JWT,也不要设 `SILUZAN_AUTH_TOKEN`。
|
|
67
|
+
5. **命令透明**:用一句话说明意图(「正在列出您的站点」),不要把整段命令当主回复;用户要细节时再给完整命令。
|
|
68
|
+
6. **失败先自救**:401 → 引导重新 `login`;站点找不到 → 再跑 `sites list`;不要编造成功。
|
|
69
|
+
|
|
70
|
+
### 本版明确不做
|
|
71
|
+
|
|
72
|
+
- 创建 / 删除 / 重启站点(SiteMan)
|
|
73
|
+
- 绑定域名 / CDN / SSL
|
|
74
|
+
- 停用 / 删除插件;安装目录里没有的第三方插件
|
|
75
|
+
- LPS / AI Sites / SEO JSON 灌入
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"slug": "siluzan-website",
|
|
3
|
+
"version": "1.0.1-beta.1",
|
|
4
|
+
"publishedAt": 1789609097006,
|
|
5
|
+
"homepage": "https://www.siluzan.com",
|
|
6
|
+
"source": "https://dev.azure.com/jack4it/Sammamish/_git/siluzan-skill",
|
|
7
|
+
"requiredBinaries": [
|
|
8
|
+
"node",
|
|
9
|
+
"npm"
|
|
10
|
+
],
|
|
11
|
+
"optionalBinaries": [],
|
|
12
|
+
"requiredEnv": [],
|
|
13
|
+
"optionalEnv": [
|
|
14
|
+
"SILUZAN_API_KEY",
|
|
15
|
+
"SILUZAN_AUTH_TOKEN"
|
|
16
|
+
],
|
|
17
|
+
"configPaths": [
|
|
18
|
+
"~/.siluzan/config.json"
|
|
19
|
+
],
|
|
20
|
+
"companionSkills": []
|
|
21
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# 页面管理
|
|
2
|
+
|
|
3
|
+
走站点 WordPress REST,鉴权与其它命令相同:**API Key(x-api-key)**。站点侧 `wp-oauth2` 会用 Key 调主站校验,并确认该账号拥有本站。
|
|
4
|
+
|
|
5
|
+
底层接口(已存在,本 CLI 只封装):
|
|
6
|
+
|
|
7
|
+
- 列表:`GET /wp-json/wp/v2/pages`
|
|
8
|
+
- 新增:`POST /wp-json/zionbuilder/v1/pages/add-visual-edit`
|
|
9
|
+
- 更新:`POST /wp-json/zionbuilder/v1/pages/{id}/save-visual-edit`
|
|
10
|
+
|
|
11
|
+
`add-visual-edit` / `save-visual-edit` 会把 HTML 转成 Zion Builder 组件,并且 **直接 publish**。执行前必须和用户确认目标站点与标题。
|
|
12
|
+
|
|
13
|
+
## 列出
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
siluzan-website pages list --site <guid>
|
|
17
|
+
siluzan-website pages list --url https://{guid}-prod.admin.mysiluzan.com --json
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
记下 `id`,更新时必须用这个 id,不要猜。
|
|
21
|
+
|
|
22
|
+
## 新增
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
siluzan-website pages add --site <guid> --title "关于我们" --content-file about.html
|
|
26
|
+
siluzan-website pages add --site <guid> --title "联系" --content "<h1>Contact</h1>"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
可选:`--css-file` / `--js-file` / `--post-type`(默认 `page`)。
|
|
30
|
+
|
|
31
|
+
正文用完整 HTML 片段即可(有标题、段落、图片)。不要传 Zion Builder JSON。图片尽量用已上传的绝对 URL;`s.coze.cn` 图站点侧会尝试拉到媒体库。
|
|
32
|
+
|
|
33
|
+
## 更新
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
siluzan-website pages update --site <guid> --id 123 --content-file about.html
|
|
37
|
+
siluzan-website pages update --site <guid> --id 123 --title "新标题" --content "<p>…</p>"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`update` 会覆盖该页 Builder 内容。先 `pages list` 确认 id。
|
|
41
|
+
|
|
42
|
+
## 写后验证
|
|
43
|
+
|
|
44
|
+
新增 / 更新成功后:
|
|
45
|
+
|
|
46
|
+
1. 看命令打印的 `post_id` 与 `url`
|
|
47
|
+
2. 再跑一次 `pages list --site <guid>`,确认标题和链接
|
|
48
|
+
3. 需要给用户可点链接时,只用接口返回的 `url` / `link`,不要手拼 permalink
|
|
49
|
+
|
|
50
|
+
## 失败
|
|
51
|
+
|
|
52
|
+
| 现象 | 处理 |
|
|
53
|
+
|------|------|
|
|
54
|
+
| 未找到认证凭据 | 按 setup.md 配置 `SILUZAN_API_KEY` |
|
|
55
|
+
| 401 / rest_forbidden | API Key 无效,或该账号没有这个站点 |
|
|
56
|
+
| 站点 404 | `--url` 或平台域名不对;用 `sites list` 的 url |
|
|
57
|
+
| Content cannot be empty | `--content` / `--content-file` 为空 |
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# 插件
|
|
2
|
+
|
|
3
|
+
鉴权一律 **API Key(x-api-key)**。安装走站点 `siluzan-helper-plugin` 的 REST,只允许丝路赞目录里的 zip,不接受任意 URL。
|
|
4
|
+
|
|
5
|
+
## 已装列表
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
siluzan-website plugins list --site <guid>
|
|
9
|
+
siluzan-website plugins list --site <guid> --json
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
`GET /wp-json/wp/v2/plugins`。字段:`plugin`、名称、`status`、版本。
|
|
13
|
+
|
|
14
|
+
## 可安装目录
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
siluzan-website plugins catalog --site <guid>
|
|
18
|
+
siluzan-website plugins catalog --site <guid> --json
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`GET /wp-json/siluzan-helper/v1/plugins/catalog`。记下 `slug`,安装必须用这个值(或 `plugin` 路径)。不要猜。
|
|
22
|
+
|
|
23
|
+
## 安装并启用
|
|
24
|
+
|
|
25
|
+
写操作,执行前必须和用户确认目标站点与插件名。
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
siluzan-website plugins install --site <guid> --slug <slug>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`POST /wp-json/siluzan-helper/v1/plugins/install`,body:`{ "slug": "..." }`。
|
|
32
|
+
|
|
33
|
+
成功后命令会再跑一次 `plugins list` 复核。已装且已启用会返回 `already: true`,视为成功,不要再装一遍。
|
|
34
|
+
|
|
35
|
+
## Agent 流程
|
|
36
|
+
|
|
37
|
+
1. `sites list` 确定 guid
|
|
38
|
+
2. `plugins catalog` 找到 slug(用户说中文名时按 `name` 匹配)
|
|
39
|
+
3. 复述「将在 {站点} 安装并启用 {名称}(slug)」并等确认
|
|
40
|
+
4. `plugins install --site <guid> --slug <slug>`
|
|
41
|
+
5. 看复核列表里是否 `active`
|
|
42
|
+
|
|
43
|
+
匹配到多个目录项时让用户选,不要猜。
|
|
44
|
+
|
|
45
|
+
## 失败
|
|
46
|
+
|
|
47
|
+
| 现象 | 处理 |
|
|
48
|
+
|------|------|
|
|
49
|
+
| catalog / install 404 或路由不存在 | 站点 helper 还没带 REST,需要更新 `siluzan-helper-plugin` |
|
|
50
|
+
| 401 | API Key 无效或无权操作该站 |
|
|
51
|
+
| Plugin not found | slug 不对,重新 `catalog` |
|
|
52
|
+
| 安装成功但激活失败 | 把站点返回的 message 原文告诉用户 |
|
|
53
|
+
|
|
54
|
+
本 Skill **不能**停用、删除插件,也不能装 wordpress.org 上目录里没有的插件。
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# 安装与登录
|
|
2
|
+
|
|
3
|
+
本 Skill **只支持 API Key 鉴权**(与 CSO / TSO 相同)。Agent 沙箱注入 `SILUZAN_API_KEY`,所有命令带 `x-api-key`。不要使用 JWT / `SILUZAN_AUTH_TOKEN`。
|
|
4
|
+
|
|
5
|
+
## 一键安装
|
|
6
|
+
|
|
7
|
+
- **macOS / Linux / WSL:**
|
|
8
|
+
```bash
|
|
9
|
+
bash <(curl -fsSL https://unpkg.com/siluzan-website-cli@latest/dist/skill/scripts/install.sh)
|
|
10
|
+
```
|
|
11
|
+
- **Windows PowerShell:**
|
|
12
|
+
```powershell
|
|
13
|
+
irm https://unpkg.com/siluzan-website-cli@latest/dist/skill/scripts/install.ps1 | iex
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
脚本:检测 Node 18+ → 全局安装 `siluzan-website-cli` → `siluzan-website init --global --force` → `siluzan-website login`。
|
|
17
|
+
|
|
18
|
+
手动安装:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install -g siluzan-website-cli@beta
|
|
22
|
+
siluzan-website init --global --force
|
|
23
|
+
siluzan-website login
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
测试包:`npm install -g siluzan-website-cli@beta`。
|
|
27
|
+
|
|
28
|
+
## 凭据
|
|
29
|
+
|
|
30
|
+
与 `siluzan-cso` / `siluzan-tso` 共用 `~/.siluzan/config.json` 的 `apiKey` 字段。
|
|
31
|
+
|
|
32
|
+
| 来源 | 说明 |
|
|
33
|
+
|------|------|
|
|
34
|
+
| `SILUZAN_API_KEY` | Agent / CI 优先 |
|
|
35
|
+
| `config.json` 的 `apiKey` | `login` 写入 |
|
|
36
|
+
| JWT / `SILUZAN_AUTH_TOKEN` | **本 Skill 不使用** |
|
|
37
|
+
|
|
38
|
+
已用 CSO/TSO 登录过、本地已有 API Key 时,无需再 login。
|
|
39
|
+
|
|
40
|
+
### 手机号两段式(签发 API Key)
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
siluzan-website send-login-code --phone 13800138000
|
|
44
|
+
siluzan-website login --phone 13800138000 --code 123456
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
拆成两步是为了避免 Agent 卡在交互输入时反复重发短信。
|
|
48
|
+
|
|
49
|
+
### 其他方式
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
siluzan-website login --api-key <KEY>
|
|
53
|
+
siluzan-website config show
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Agent 沙箱(`IS_SILUZAN_AGENT_ENV=true`)只读 `SILUZAN_API_KEY`,不读 config.json,也不要跑交互 `login`。
|
|
57
|
+
|
|
58
|
+
## Skill 初始化
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
siluzan-website init # 当前项目各 AI 目录
|
|
62
|
+
siluzan-website init --global # 全局目录
|
|
63
|
+
siluzan-website init --ai cursor # 只写 Cursor
|
|
64
|
+
siluzan-website update # 升级 CLI 并刷新已记录的 Skill
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## 常见错误
|
|
68
|
+
|
|
69
|
+
| 现象 | 处理 |
|
|
70
|
+
|------|------|
|
|
71
|
+
| 未找到认证凭据 | `login` 或设置 `SILUZAN_API_KEY` |
|
|
72
|
+
| 401 / API Key 无权访问本站 | Key 有效但账号没有该站点;换有权限的账号或换 `--site` |
|
|
73
|
+
| 站点找不到 | 先 `sites list`,用返回的 guid |
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# 站点列表
|
|
2
|
+
|
|
3
|
+
## 命令
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
siluzan-website sites list
|
|
7
|
+
siluzan-website sites list -q 品牌名
|
|
8
|
+
siluzan-website sites list --json
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
走主站 `GET /query/profile/steward-individual/all-sites`(与 TSO 建站后台同一接口)。
|
|
12
|
+
|
|
13
|
+
## 返回字段
|
|
14
|
+
|
|
15
|
+
| 字段 | 含义 |
|
|
16
|
+
|------|------|
|
|
17
|
+
| `guid` | 站点 ID,后续 `--site` 必须用它(名称可能重复) |
|
|
18
|
+
| `name` | 站点名称 |
|
|
19
|
+
| `region` | `us` / `cn` 或中文「美国」「中国」 |
|
|
20
|
+
| `siteState` | 例如 `Online` |
|
|
21
|
+
| `url` | 平台访问地址,按 TSO 规则拼接 |
|
|
22
|
+
|
|
23
|
+
平台地址规则(与 TSO `getDomainName` 一致):
|
|
24
|
+
|
|
25
|
+
- 国际:`https://{guid}-{stage}.admin.mysiluzan.com`
|
|
26
|
+
- 国内:`https://{guid}-{stage}.cn.siluzan.com`
|
|
27
|
+
|
|
28
|
+
`stage` 由 CLI 构建环境决定(生产 `prod`,测试 `ci`)。自定义域名本版不查 SiteMan DNS;要对已绑域名的站操作页面,可直接 `--url https://www.example.com`。
|
|
29
|
+
|
|
30
|
+
## Agent 用法
|
|
31
|
+
|
|
32
|
+
1. 用户说「我的网站」时先跑 `sites list`,把名称和 guid 给用户看。
|
|
33
|
+
2. 多个站点时让用户选,不要猜。
|
|
34
|
+
3. 后续页面 / 插件命令传 `--site <guid>`。名称唯一时 `--site 名称` 也可以。
|
|
35
|
+
4. 需要对返回结果做筛选时加 `--json`,再在本地处理;不要编造 guid。
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
#Requires -Version 5.1
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# siluzan-website-cli - One-click install script (PowerShell)
|
|
4
|
+
# Supported: Windows 10/11 (PowerShell 5.1+ or PowerShell 7+)
|
|
5
|
+
# =============================================================================
|
|
6
|
+
|
|
7
|
+
$ErrorActionPreference = 'Stop'
|
|
8
|
+
|
|
9
|
+
# -- Package info (injected at build time) ------------------------------------
|
|
10
|
+
$PKG_NAME = 'siluzan-website-cli'
|
|
11
|
+
# PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
|
|
12
|
+
$PKG_VERSION = '1.0.1-beta.1'
|
|
13
|
+
$CLI_BIN = 'siluzan-website'
|
|
14
|
+
$SKILL_LABEL = 'Siluzan Website'
|
|
15
|
+
$INSTALL_CMD = 'npm install -g siluzan-website-cli@beta'
|
|
16
|
+
$WEB_BASE = 'https://www-ci.siluzan.com'
|
|
17
|
+
|
|
18
|
+
# -- Constants ----------------------------------------------------------------
|
|
19
|
+
$NODE_MAJOR_MIN = 18
|
|
20
|
+
$NPM_MIRROR = 'https://registry.npmmirror.com'
|
|
21
|
+
# Git for Windows installer (mirrored on Siluzan CDN; bump version here when needed)
|
|
22
|
+
$GIT_INSTALLER_URL = 'https://staticpn.siluzan.com/assets/git/Git-2.54.0-64-bit.exe'
|
|
23
|
+
|
|
24
|
+
# -- Helpers ------------------------------------------------------------------
|
|
25
|
+
function Write-Info { param([string]$Msg) Write-Host "[OK] $Msg" -ForegroundColor Green }
|
|
26
|
+
function Write-Warn { param([string]$Msg) Write-Host "[!] $Msg" -ForegroundColor Yellow }
|
|
27
|
+
function Write-Err { param([string]$Msg) Write-Host "[X] $Msg" -ForegroundColor Red }
|
|
28
|
+
function Write-Step { param([string]$Msg) Write-Host "`n-- $Msg --" -ForegroundColor White }
|
|
29
|
+
|
|
30
|
+
function Refresh-Path {
|
|
31
|
+
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'Machine')
|
|
32
|
+
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
|
|
33
|
+
$env:Path = "$machinePath;$userPath"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
# -- Node.js ------------------------------------------------------------------
|
|
37
|
+
function Test-NodeVersion {
|
|
38
|
+
try {
|
|
39
|
+
$nodeCmd = Get-Command node -ErrorAction SilentlyContinue
|
|
40
|
+
if (-not $nodeCmd) { return $false }
|
|
41
|
+
$ver = (node -v) -replace '^v', ''
|
|
42
|
+
$major = [int]($ver.Split('.')[0])
|
|
43
|
+
return $major -ge $NODE_MAJOR_MIN
|
|
44
|
+
} catch {
|
|
45
|
+
return $false
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function Get-NodeVersionString {
|
|
50
|
+
try { return (node -v) } catch { return 'N/A' }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function Install-NodeJS {
|
|
54
|
+
$hasWinget = $null -ne (Get-Command winget -ErrorAction SilentlyContinue)
|
|
55
|
+
if ($hasWinget) {
|
|
56
|
+
Write-Info 'Installing Node.js LTS via winget...'
|
|
57
|
+
winget install -e --id OpenJS.NodeJS.LTS --silent --accept-package-agreements --accept-source-agreements
|
|
58
|
+
if ($LASTEXITCODE -ne 0) {
|
|
59
|
+
Write-Warn 'winget returned non-zero, trying fallback...'
|
|
60
|
+
Install-NodeFallback
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
Install-NodeFallback
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
Refresh-Path
|
|
68
|
+
if (-not (Test-NodeVersion)) {
|
|
69
|
+
Write-Warn 'Node.js not found after PATH refresh, locating install dir...'
|
|
70
|
+
$nodePath = "$env:ProgramFiles\nodejs"
|
|
71
|
+
if (Test-Path "$nodePath\node.exe") {
|
|
72
|
+
$env:Path = "$nodePath;$env:Path"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function Install-NodeFallback {
|
|
78
|
+
Write-Err 'Cannot auto-install Node.js'
|
|
79
|
+
Write-Host ''
|
|
80
|
+
Write-Host ' Please install Node.js manually:' -ForegroundColor Cyan
|
|
81
|
+
Write-Host ' https://nodejs.org/en/download/'
|
|
82
|
+
Write-Host ''
|
|
83
|
+
Write-Host ' After installation, reopen PowerShell and run this script again.'
|
|
84
|
+
throw 'Node.js is required'
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
# -- Git for Windows ----------------------------------------------------------
|
|
88
|
+
# Some agent clients (Cursor / Claude Code / etc.) have known quirks running
|
|
89
|
+
# PowerShell or cmd commands. We install Git for Windows ahead of time so the
|
|
90
|
+
# user always has a Git Bash fallback to run the equivalent bash installer
|
|
91
|
+
# (`bash <(curl -fsSL .../install.sh)`) when the PowerShell channel misbehaves.
|
|
92
|
+
function Test-GitInstalled {
|
|
93
|
+
return $null -ne (Get-Command git -ErrorAction SilentlyContinue)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function Test-IsAdmin {
|
|
97
|
+
try {
|
|
98
|
+
$id = [Security.Principal.WindowsIdentity]::GetCurrent()
|
|
99
|
+
$principal = New-Object Security.Principal.WindowsPrincipal($id)
|
|
100
|
+
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
|
101
|
+
} catch {
|
|
102
|
+
return $false
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function Install-Git {
|
|
107
|
+
$tmpFile = Join-Path $env:TEMP 'siluzan-git-installer.exe'
|
|
108
|
+
|
|
109
|
+
Write-Info "Downloading Git for Windows: $GIT_INSTALLER_URL"
|
|
110
|
+
try {
|
|
111
|
+
$prevProgress = $ProgressPreference
|
|
112
|
+
$ProgressPreference = 'SilentlyContinue'
|
|
113
|
+
Invoke-WebRequest -Uri $GIT_INSTALLER_URL -OutFile $tmpFile -UseBasicParsing
|
|
114
|
+
$ProgressPreference = $prevProgress
|
|
115
|
+
} catch {
|
|
116
|
+
Write-Warn "Git installer download failed: $($_.Exception.Message)"
|
|
117
|
+
return $false
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (-not (Test-Path $tmpFile)) {
|
|
121
|
+
Write-Warn 'Git installer file not found after download'
|
|
122
|
+
return $false
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
# Inno Setup silent flags. When not admin we point /DIR to %LOCALAPPDATA% so
|
|
126
|
+
# the installer doesn't try to write to Program Files (which would trigger UAC
|
|
127
|
+
# or just fail). The installer auto-detects ALLUSERS vs CURRENTUSER mode based
|
|
128
|
+
# on whether the current process is elevated, so we don't pass /CURRENTUSER
|
|
129
|
+
# explicitly (not all Git for Windows builds accept that flag).
|
|
130
|
+
$installArgs = @('/VERYSILENT', '/NORESTART', '/NOCANCEL', '/SP-', '/CLOSEAPPLICATIONS', '/RESTARTAPPLICATIONS')
|
|
131
|
+
if (Test-IsAdmin) {
|
|
132
|
+
Write-Info 'Installing Git for Windows system-wide (admin detected)...'
|
|
133
|
+
} else {
|
|
134
|
+
$userDir = Join-Path $env:LOCALAPPDATA 'Programs\Git'
|
|
135
|
+
Write-Info "Installing Git for Windows for current user: $userDir"
|
|
136
|
+
$installArgs += @("/DIR=$userDir")
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
Start-Process -FilePath $tmpFile -ArgumentList $installArgs -Wait -NoNewWindow
|
|
141
|
+
} catch {
|
|
142
|
+
Write-Warn "Git installer launch failed: $($_.Exception.Message)"
|
|
143
|
+
Remove-Item $tmpFile -ErrorAction SilentlyContinue
|
|
144
|
+
return $false
|
|
145
|
+
}
|
|
146
|
+
Remove-Item $tmpFile -ErrorAction SilentlyContinue
|
|
147
|
+
|
|
148
|
+
Refresh-Path
|
|
149
|
+
if (-not (Test-GitInstalled)) {
|
|
150
|
+
# 安装器有时不会立刻刷新 PATH,按已知路径手动补一次
|
|
151
|
+
$candidates = @(
|
|
152
|
+
(Join-Path $env:LOCALAPPDATA 'Programs\Git\cmd'),
|
|
153
|
+
(Join-Path $env:ProgramFiles 'Git\cmd')
|
|
154
|
+
)
|
|
155
|
+
foreach ($p in $candidates) {
|
|
156
|
+
if (Test-Path (Join-Path $p 'git.exe')) {
|
|
157
|
+
$env:Path = "$p;$env:Path"
|
|
158
|
+
break
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return Test-GitInstalled
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
# -- Main ---------------------------------------------------------------------
|
|
167
|
+
function Main {
|
|
168
|
+
Write-Host ''
|
|
169
|
+
Write-Host '+---------------------------------------------+' -ForegroundColor White
|
|
170
|
+
Write-Host "| $SKILL_LABEL -- Install |" -ForegroundColor White
|
|
171
|
+
Write-Host '+---------------------------------------------+' -ForegroundColor White
|
|
172
|
+
Write-Host ''
|
|
173
|
+
|
|
174
|
+
# Step 1: Environment check
|
|
175
|
+
Write-Step 'Step 1/4: Environment check'
|
|
176
|
+
|
|
177
|
+
if (Test-NodeVersion) {
|
|
178
|
+
Write-Info "Node.js $(Get-NodeVersionString) found"
|
|
179
|
+
} else {
|
|
180
|
+
$nodeCmd = Get-Command node -ErrorAction SilentlyContinue
|
|
181
|
+
if ($nodeCmd) {
|
|
182
|
+
Write-Warn "Node.js $(Get-NodeVersionString) is too old (need >= $NODE_MAJOR_MIN), upgrading..."
|
|
183
|
+
} else {
|
|
184
|
+
Write-Warn 'Node.js not found, installing...'
|
|
185
|
+
}
|
|
186
|
+
Install-NodeJS
|
|
187
|
+
if (-not (Test-NodeVersion)) {
|
|
188
|
+
Write-Err 'Node.js installation failed. Please install manually: https://nodejs.org/'
|
|
189
|
+
return
|
|
190
|
+
}
|
|
191
|
+
Write-Info "Node.js $(Get-NodeVersionString) installed"
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
$npmCmd = Get-Command npm -ErrorAction SilentlyContinue
|
|
195
|
+
if (-not $npmCmd) {
|
|
196
|
+
Refresh-Path
|
|
197
|
+
$npmCmd = Get-Command npm -ErrorAction SilentlyContinue
|
|
198
|
+
}
|
|
199
|
+
if (-not $npmCmd) {
|
|
200
|
+
Write-Err 'npm not found (Node.js installation may be incomplete)'
|
|
201
|
+
return
|
|
202
|
+
}
|
|
203
|
+
Write-Info 'npm ready'
|
|
204
|
+
|
|
205
|
+
# Git for Windows: pre-install as a Bash fallback path for agent clients
|
|
206
|
+
# whose PowerShell/cmd channel is unreliable. Failure here is non-fatal.
|
|
207
|
+
if (Test-GitInstalled) {
|
|
208
|
+
Write-Info 'Git for Windows already installed (Git Bash fallback ready)'
|
|
209
|
+
} else {
|
|
210
|
+
Write-Warn 'Git for Windows not found, installing as Bash fallback for agent clients...'
|
|
211
|
+
$gitOk = $false
|
|
212
|
+
try { $gitOk = Install-Git } catch { Write-Warn "Git install error: $($_.Exception.Message)" }
|
|
213
|
+
if ($gitOk) {
|
|
214
|
+
Write-Info 'Git for Windows installed (Git Bash fallback ready)'
|
|
215
|
+
} else {
|
|
216
|
+
Write-Warn 'Git for Windows install was skipped or failed; CLI install will continue.'
|
|
217
|
+
Write-Host ' If your agent later fails to run PowerShell commands, install Git manually:' -ForegroundColor DarkGray
|
|
218
|
+
Write-Host " $GIT_INSTALLER_URL" -ForegroundColor DarkGray
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
$currentRegistry = ''
|
|
223
|
+
try { $currentRegistry = (npm config get registry 2>$null).Trim() } catch {}
|
|
224
|
+
if ($currentRegistry -ne $NPM_MIRROR -and $currentRegistry -ne "$NPM_MIRROR/") {
|
|
225
|
+
Write-Info 'Switching npm registry to China mirror for faster downloads...'
|
|
226
|
+
npm config set registry $NPM_MIRROR
|
|
227
|
+
Write-Info "npm registry set to $NPM_MIRROR"
|
|
228
|
+
} else {
|
|
229
|
+
Write-Info 'npm registry already set to China mirror'
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
# Step 2: Install CLI
|
|
233
|
+
Write-Step "Step 2/4: Install $PKG_NAME"
|
|
234
|
+
|
|
235
|
+
# 用打包时锁定的 PKG_VERSION,保证脚本与同批 dist/skill 行为对齐
|
|
236
|
+
$installTarget = "$PKG_NAME@$PKG_VERSION"
|
|
237
|
+
Write-Info "Running: npm install -g $installTarget"
|
|
238
|
+
& npm install -g $installTarget
|
|
239
|
+
if ($LASTEXITCODE -ne 0) { Write-Err "npm install -g $installTarget failed"; return }
|
|
240
|
+
Write-Info "$installTarget installed"
|
|
241
|
+
|
|
242
|
+
Write-Info 'Registering Skill to all AI platform global directories...'
|
|
243
|
+
& $CLI_BIN init --global --force
|
|
244
|
+
|
|
245
|
+
if ($CLI_BIN -eq 'siluzan-seo') {
|
|
246
|
+
Write-Info 'siluzan-seo does not require login; skipping API Key setup.'
|
|
247
|
+
} else {
|
|
248
|
+
Write-Step 'Step 3/4: Configure API Key'
|
|
249
|
+
Write-Host ''
|
|
250
|
+
& $CLI_BIN login
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
# Step 4: Done
|
|
254
|
+
Write-Step 'Step 4/4: Complete'
|
|
255
|
+
Write-Host ''
|
|
256
|
+
Write-Host " $SKILL_LABEL installed successfully!" -ForegroundColor Green
|
|
257
|
+
Write-Host ''
|
|
258
|
+
Write-Host ' Skill registered to these global directories (all AI assistants):'
|
|
259
|
+
Write-Host ' ~/.cursor/skills/ ~/.claude/skills/ ~/.agents/skills/' -ForegroundColor DarkGray
|
|
260
|
+
Write-Host ' ~/.gemini/skills/ ~/.codex/skills/ ~/.kilo/skills/' -ForegroundColor DarkGray
|
|
261
|
+
Write-Host ' ~/.codeium/windsurf/skills/ ~/.config/opencode/skills/' -ForegroundColor DarkGray
|
|
262
|
+
Write-Host ' ~/.openclaw/skills/ ~/.workbuddy/skills/' -ForegroundColor DarkGray
|
|
263
|
+
Write-Host ''
|
|
264
|
+
Write-Host " Update CLI & Skill files: $CLI_BIN update"
|
|
265
|
+
Write-Host ''
|
|
266
|
+
if (Test-GitInstalled) {
|
|
267
|
+
Write-Host ' Tip: if your agent client has trouble running PowerShell/cmd commands later,' -ForegroundColor DarkGray
|
|
268
|
+
Write-Host ' open Git Bash and re-run the equivalent bash installer instead.' -ForegroundColor DarkGray
|
|
269
|
+
Write-Host ''
|
|
270
|
+
}
|
|
271
|
+
Write-Info "Need help? Visit $WEB_BASE"
|
|
272
|
+
Write-Host ''
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
Main
|