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.
@@ -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