siluzan-website-cli 1.0.1-beta.6 → 1.0.1-beta.8

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 CHANGED
@@ -14,13 +14,13 @@ siluzan-website login
14
14
 
15
15
  ## 开通建站
16
16
 
17
+ 对话顺序:**`templates catalog`(JSON)→ `present_website_templates` → `present_website_provision_form`(试用)→ create**。
18
+
17
19
  ```bash
18
- siluzan-website packages list
19
- siluzan-website templates list --package <packageId>
20
+ siluzan-website templates catalog # JSON → present_website_templates
21
+ siluzan-website templates get --id <siteTemplateId>
20
22
  siluzan-website trial status
21
- siluzan-website bills create --package <packageId> --channel Monthly
22
- siluzan-website bills get --id <billId>
23
- siluzan-website sites create --name "Acme" --region US --package <id> --template <id> --site-lang en_US --admin-lang en_US [--bill <billId>] [--wait]
23
+ siluzan-website sites create --name "Acme" --region US --package <id> --template <id> --site-lang en_US --admin-lang en_US [--wait]
24
24
  siluzan-website sites status --site <guid> --region US
25
25
  siluzan-website sites bind --site <guid> --region US --name "Acme"
26
26
  ```
package/dist/index.js CHANGED
@@ -3319,6 +3319,7 @@ var DEFAULT_API_BASE = "https://api-ci.siluzan.com";
3319
3319
  var DEFAULT_CSO_BASE = "https://cso-ci.siluzan.com";
3320
3320
  var DEFAULT_CSO_PLUGIN_API = "https://cso-api-ci.siluzan.com";
3321
3321
  var DEFAULT_WEB_BASE = "https://www-ci.siluzan.com";
3322
+ var DEFAULT_SITEMAN_BASE = "https://api-ussiteman-ci.mysiluzan.com";
3322
3323
  var DEFAULT_SITE_STAGE = "ci";
3323
3324
 
3324
3325
  // src/utils/version.ts
@@ -4189,8 +4190,81 @@ function unwrapList2(raw) {
4189
4190
  if (Array.isArray(obj.data)) {
4190
4191
  return obj.data.map(asRecord3).filter((x) => Boolean(x));
4191
4192
  }
4193
+ if (Array.isArray(obj.items)) {
4194
+ return obj.items.map(asRecord3).filter((x) => Boolean(x));
4195
+ }
4192
4196
  return [];
4193
4197
  }
4198
+ function siteManBase() {
4199
+ return (process.env.SILUZAN_SITEMAN_BASE ?? DEFAULT_SITEMAN_BASE).replace(/\/+$/, "");
4200
+ }
4201
+ function enrichTemplatePreview(t) {
4202
+ const out = { ...t };
4203
+ const base = siteManBase();
4204
+ const coverId = readString3(t, "cover") || readString3(t, "Cover");
4205
+ const imageId = readString3(t, "image") || readString3(t, "Image");
4206
+ if (!readString3(t, "coverUrl") && coverId) out.coverUrl = `${base}/api/Attachments/${coverId}`;
4207
+ if (!readString3(t, "imageUrl") && imageId) out.imageUrl = `${base}/api/Attachments/${imageId}`;
4208
+ const colors = Array.isArray(t.colors) ? t.colors : Array.isArray(t.Colors) ? t.Colors : [];
4209
+ const first = asRecord3(colors[0]);
4210
+ const preview = readString3(first, "colorSchemePreview") || readString3(first, "ColorSchemePreview");
4211
+ if (!readString3(t, "previewUrl") && preview) out.previewUrl = preview;
4212
+ const colorPreviewId = readString3(first, "colorPreview") || readString3(first, "ColorPreview");
4213
+ if (!readString3(t, "colorPreviewUrl") && colorPreviewId) {
4214
+ out.colorPreviewUrl = `${base}/api/Attachments/${colorPreviewId}`;
4215
+ }
4216
+ return out;
4217
+ }
4218
+ function templateBelongsToPackage(t, packageId) {
4219
+ const packages = readString3(t, "packages") || readString3(t, "Packages");
4220
+ if (!packages) return false;
4221
+ if (packages.toLowerCase().includes(`|${packageId.toLowerCase()}|`)) return true;
4222
+ return packages.split(/[|,;]/).map((s) => s.trim()).some((p) => p.toLowerCase() === packageId.toLowerCase());
4223
+ }
4224
+ function pickPreviewFields(t) {
4225
+ const e = enrichTemplatePreview(t);
4226
+ return {
4227
+ id: readString3(e, "siteTemplateId") || readString3(e, "SiteTemplateId"),
4228
+ name: readString3(e, "name") || readString3(e, "Name"),
4229
+ industry: readString3(e, "industrys") || readString3(e, "Industrys") || "-",
4230
+ coverUrl: readString3(e, "coverUrl") || readString3(e, "CoverUrl") || "",
4231
+ previewUrl: readString3(e, "previewUrl") || readString3(e, "PreviewUrl") || "",
4232
+ hot: String(e.hotTag ?? e.HotTag ?? "-"),
4233
+ neu: String(e.newTag ?? e.NewTag ?? "-"),
4234
+ version: readString3(e, "version") || readString3(e, "Version") || "-"
4235
+ };
4236
+ }
4237
+ async function composeCatalogLocally(config, verbose) {
4238
+ const [pkgRaw, tplRaw] = await Promise.all([
4239
+ apiFetch2(`${config.apiBaseUrl}/website-provision/packages`, config, {}, verbose),
4240
+ apiFetch2(
4241
+ `${config.apiBaseUrl}/website-provision/templates?pageSize=500&pageIndex=1`,
4242
+ config,
4243
+ {},
4244
+ verbose
4245
+ )
4246
+ ]);
4247
+ const packages = unwrapList2(pkgRaw).filter((p) => !(p.sunset === true || p.Sunset === true));
4248
+ const templates = unwrapList2(tplRaw).map(enrichTemplatePreview);
4249
+ const groups = packages.map((p) => {
4250
+ const packageId = readString3(p, "packageId") || readString3(p, "PackageId");
4251
+ const matched = templates.filter((t) => templateBelongsToPackage(t, packageId));
4252
+ return {
4253
+ packageId,
4254
+ packageName: readString3(p, "packageName") || readString3(p, "PackageName"),
4255
+ monthPriceUSD: p.monthPriceUSD ?? p.MonthPriceUSD,
4256
+ yearlyPriceUSD: p.yearlyPriceUSD ?? p.YearlyPriceUSD,
4257
+ templates: matched,
4258
+ templateCount: matched.length
4259
+ };
4260
+ });
4261
+ return {
4262
+ packages,
4263
+ groups,
4264
+ totalTemplates: templates.length,
4265
+ source: "cli-fallback"
4266
+ };
4267
+ }
4194
4268
  async function runTemplatesList(opts) {
4195
4269
  const config = loadConfig();
4196
4270
  const params = new URLSearchParams({ pageSize: "100", pageIndex: "1" });
@@ -4208,7 +4282,7 @@ async function runTemplatesList(opts) {
4208
4282
  process.exit(1);
4209
4283
  return;
4210
4284
  }
4211
- const list = unwrapList2(raw);
4285
+ const list = unwrapList2(raw).map(enrichTemplatePreview);
4212
4286
  if (opts.json) {
4213
4287
  console.log(JSON.stringify({ total: list.length, templates: list }, null, 2));
4214
4288
  return;
@@ -4221,23 +4295,101 @@ async function runTemplatesList(opts) {
4221
4295
  { key: "id", header: "siteTemplateId" },
4222
4296
  { key: "name", header: "\u540D\u79F0" },
4223
4297
  { key: "industry", header: "\u884C\u4E1A" },
4224
- { key: "version", header: "\u7248\u672C" },
4298
+ { key: "preview", header: "\u9884\u89C8" },
4225
4299
  { key: "hot", header: "\u70ED\u95E8" },
4226
4300
  { key: "neu", header: "\u65B0\u54C1" }
4227
4301
  ];
4228
- const rows = list.map((t) => ({
4229
- id: readString3(t, "siteTemplateId") || readString3(t, "SiteTemplateId"),
4230
- name: readString3(t, "name") || readString3(t, "Name"),
4231
- industry: readString3(t, "industrys") || readString3(t, "Industrys") || "-",
4232
- version: readString3(t, "version") || readString3(t, "Version") || "-",
4233
- hot: String(t.hotTag ?? t.HotTag ?? "-"),
4234
- neu: String(t.newTag ?? t.NewTag ?? "-")
4235
- }));
4302
+ const rows = list.map((t) => {
4303
+ const p = pickPreviewFields(t);
4304
+ return {
4305
+ id: p.id,
4306
+ name: p.name,
4307
+ industry: p.industry,
4308
+ preview: p.previewUrl || (p.coverUrl ? "(\u6709\u5C01\u9762)" : "-"),
4309
+ hot: p.hot,
4310
+ neu: p.neu
4311
+ };
4312
+ });
4236
4313
  console.log(`
4237
4314
  \u6A21\u677F\u5217\u8868\uFF08\u5171 ${list.length} \u4E2A\uFF09
4238
4315
  `);
4239
4316
  printCliTable(rows, columns);
4240
- console.log("\n\u8BE6\u60C5\uFF1Asiluzan-website templates get --id <siteTemplateId>\n");
4317
+ console.log("\n\u6A21\u677F\u76EE\u5F55\uFF1Asiluzan-website templates catalog");
4318
+ console.log("\u8BE6\u60C5\uFF1Asiluzan-website templates get --id <siteTemplateId>\n");
4319
+ }
4320
+ async function runTemplatesCatalog(opts) {
4321
+ const config = loadConfig();
4322
+ const url = `${config.apiBaseUrl}/website-provision/template-catalog`;
4323
+ let raw;
4324
+ let usedFallback = false;
4325
+ try {
4326
+ raw = await apiFetch2(url, config, {}, opts.verbose);
4327
+ } catch (e) {
4328
+ const msg = e.message || "";
4329
+ if (/HTTP 404/.test(msg)) {
4330
+ console.error("\u2139\uFE0F \u4E3B\u7AD9\u5C1A\u672A\u90E8\u7F72 template-catalog\uFF0C\u6539\u7528 packages+templates \u672C\u5730\u62FC\u88C5\u76EE\u5F55\u2026");
4331
+ try {
4332
+ raw = await composeCatalogLocally(config, opts.verbose);
4333
+ usedFallback = true;
4334
+ } catch (e2) {
4335
+ console.error(`
4336
+ \u274C \u62FC\u88C5\u6A21\u677F\u76EE\u5F55\u5931\u8D25\uFF1A${e2.message}`);
4337
+ process.exit(1);
4338
+ return;
4339
+ }
4340
+ } else {
4341
+ console.error(`
4342
+ \u274C \u83B7\u53D6\u6A21\u677F\u76EE\u5F55\u5931\u8D25\uFF1A${msg}`);
4343
+ if (!opts.verbose) console.error(" \u52A0 --verbose \u53EF\u67E5\u770B\u8BE6\u7EC6\u9519\u8BEF");
4344
+ process.exit(1);
4345
+ return;
4346
+ }
4347
+ }
4348
+ const root = asRecord3(raw);
4349
+ let groups = (Array.isArray(root?.groups) ? root.groups : []).map(asRecord3).filter((x) => Boolean(x)).map((g) => ({
4350
+ ...g,
4351
+ templates: Array.isArray(g.templates) ? g.templates.map((t) => enrichTemplatePreview(asRecord3(t) ?? {})) : []
4352
+ }));
4353
+ if (opts.package?.trim()) {
4354
+ const pkg = opts.package.trim();
4355
+ groups = groups.filter((g) => readString3(g, "packageId") === pkg);
4356
+ }
4357
+ if (!opts.table) {
4358
+ console.log(
4359
+ JSON.stringify(
4360
+ {
4361
+ totalGroups: groups.length,
4362
+ totalTemplates: root?.totalTemplates ?? groups.reduce((n, g) => n + (Array.isArray(g.templates) ? g.templates.length : 0), 0),
4363
+ source: usedFallback ? "cli-fallback" : root?.source ?? "api",
4364
+ groups
4365
+ },
4366
+ null,
4367
+ 2
4368
+ )
4369
+ );
4370
+ return;
4371
+ }
4372
+ for (const g of groups) {
4373
+ const pkgId = readString3(g, "packageId");
4374
+ const pkgName = readString3(g, "packageName") || pkgId;
4375
+ const templates = Array.isArray(g.templates) ? g.templates : [];
4376
+ console.log(`
4377
+ ## ${pkgName} (${pkgId}) \u2014 ${templates.length} \u4E2A\u6A21\u677F
4378
+ `);
4379
+ const columns = [
4380
+ { key: "id", header: "siteTemplateId" },
4381
+ { key: "name", header: "\u540D\u79F0" },
4382
+ { key: "industry", header: "\u884C\u4E1A" },
4383
+ { key: "preview", header: "\u9884\u89C8URL" }
4384
+ ];
4385
+ const rows = templates.map((item) => {
4386
+ const t = asRecord3(item) ?? {};
4387
+ const p = pickPreviewFields(t);
4388
+ return { id: p.id, name: p.name, industry: p.industry, preview: p.previewUrl || "-" };
4389
+ });
4390
+ printCliTable(rows, columns);
4391
+ }
4392
+ console.log();
4241
4393
  }
4242
4394
  async function runTemplatesGet(opts) {
4243
4395
  const id = opts.id?.trim();
@@ -4256,22 +4408,35 @@ async function runTemplatesGet(opts) {
4256
4408
  process.exit(1);
4257
4409
  return;
4258
4410
  }
4411
+ const enriched = enrichTemplatePreview(asRecord3(raw) ?? {});
4259
4412
  if (opts.json) {
4260
- console.log(JSON.stringify(raw, null, 2));
4413
+ console.log(JSON.stringify(enriched, null, 2));
4261
4414
  return;
4262
4415
  }
4263
- const t = asRecord3(raw);
4416
+ const p = pickPreviewFields(enriched);
4264
4417
  console.log("\n\u6A21\u677F\u8BE6\u60C5\n");
4265
- console.log(` siteTemplateId : ${readString3(t, "siteTemplateId") || readString3(t, "SiteTemplateId") || id}`);
4266
- console.log(` name : ${readString3(t, "name") || readString3(t, "Name")}`);
4267
- console.log(` description : ${readString3(t, "description") || readString3(t, "Description") || "-"}`);
4268
- console.log(` industrys : ${readString3(t, "industrys") || readString3(t, "Industrys") || "-"}`);
4269
- console.log(` version : ${readString3(t, "version") || readString3(t, "Version") || "-"}`);
4270
- console.log(` hasTheme : ${String(t?.hasTheme ?? "-")}`);
4418
+ console.log(` siteTemplateId : ${p.id || id}`);
4419
+ console.log(` name : ${p.name}`);
4420
+ console.log(` description : ${readString3(enriched, "description") || readString3(enriched, "Description") || "-"}`);
4421
+ console.log(` industrys : ${p.industry}`);
4422
+ console.log(` version : ${p.version}`);
4423
+ console.log(` hasTheme : ${String(enriched.hasTheme ?? "-")}`);
4424
+ console.log(` coverUrl : ${p.coverUrl || "-"}`);
4425
+ console.log(` previewUrl : ${p.previewUrl || "-"}`);
4426
+ if (p.coverUrl) console.log(`
4427
+ ![${p.name || p.id}](${p.coverUrl})`);
4271
4428
  console.log("\n\uFF08\u5B89\u88C5\u5305\u5730\u5740\u5DF2\u8131\u654F\uFF0C\u4E0D\u4F1A\u8F93\u51FA\uFF09\n");
4272
4429
  }
4273
4430
  function register7(program2) {
4274
4431
  const templates = program2.command("templates").description("\u5EFA\u7AD9\u6A21\u677F\uFF08website-provision\uFF09");
4432
+ templates.command("catalog").description("\u5957\u9910+\u6A21\u677F\u76EE\u5F55 JSON\uFF08\u4F9B DeerFlow present_website_templates\uFF1B\u5F00\u7AD9\u7B2C\u4E00\u6B65\uFF09").option("--package <packageId>", "\u53EA\u8FD4\u56DE\u67D0\u4E00\u5957\u9910").option("--json", "\u8F93\u51FA JSON\uFF08\u9ED8\u8BA4\u5DF2\u662F JSON\uFF0C\u4FDD\u7559\u517C\u5BB9\uFF09", false).option("--table", "\u7EC8\u7AEF\u8868\u683C\u8F93\u51FA\uFF08\u8C03\u8BD5\u7528\uFF09", false).option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
4433
+ await runTemplatesCatalog({
4434
+ package: opts.package,
4435
+ json: true,
4436
+ table: opts.table,
4437
+ verbose: opts.verbose
4438
+ });
4439
+ });
4275
4440
  templates.command("list").description("\u6309\u5957\u9910\u7B49\u6761\u4EF6\u5217\u51FA\u6A21\u677F").option("--package <packageId>", "\u5957\u9910 ID \u8FC7\u6EE4").option("--industry <industry>", "\u884C\u4E1A\u8FC7\u6EE4").option("--keyword <keyword>", "\u5173\u952E\u8BCD").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
4276
4441
  await runTemplatesList(opts);
4277
4442
  });
@@ -40,7 +40,8 @@ Windows 注意:部分 Agent 通过 PowerShell / cmd 代执行时可能失败
40
40
  | `siluzan-website config show/set/clear` | 查看 / 写入凭据 | [references/setup.md](references/setup.md) |
41
41
  | `siluzan-website init` / `update` | 写入 / 刷新 Skill 文件 | [references/setup.md](references/setup.md) |
42
42
  | `siluzan-website packages list` | 可售套餐 | [references/provision.md](references/provision.md) |
43
- | `siluzan-website templates list/get` | 建站模板 | [references/provision.md](references/provision.md) |
43
+ | `siluzan-website templates catalog` | 模板目录 JSON(开站第一步;交 `present_website_templates`) | [references/provision.md](references/provision.md) |
44
+ | `siluzan-website templates list/get` | 建站模板列表 / 详情 | [references/provision.md](references/provision.md) |
44
45
  | `siluzan-website trial status` | 试用额度 | [references/provision.md](references/provision.md) |
45
46
  | `siluzan-website bills create/get` | 套餐账单与支付状态 | [references/provision.md](references/provision.md) |
46
47
  | `siluzan-website sites list` | 列出我的 WordPress 站点 | [references/sites.md](references/sites.md) |
@@ -61,7 +62,7 @@ Windows 注意:部分 Agent 通过 PowerShell / cmd 代执行时可能失败
61
62
  | 用户在做什么 | 先读 | 再执行 |
62
63
  |--------------|------|--------|
63
64
  | 首次安装 / 登录 | `references/setup.md` | `login` 或复用已有 CSO/TSO 凭据 |
64
- | **选套餐 / 选模板 / 试用或付费开站** | `references/provision.md` | packages → templates → trial/bills → 确认 → sites create |
65
+ | **开通新站 / 选模板建站** | `references/provision.md` | **先** `templates catalog` → **`present_website_templates`** → **`present_website_provision_form`(试用)** → trial → 确认 → `sites create` |
65
66
  | 我有哪些网站 | `references/sites.md` | `sites list`,不要猜 guid |
66
67
  | 加一页 / 改一页正文 | `references/pages.md` | 先 `sites list` 再 `pages add/update` |
67
68
  | 改页面 slug / 状态 / 回收站 | `references/pages.md` | `pages meta` / `pages trash` |
@@ -84,7 +85,8 @@ Windows 注意:部分 Agent 通过 PowerShell / cmd 代执行时可能失败
84
85
  - 写操作(`bills create`、`sites create/bind`、`pages add/update/meta/trash`、`content add/update/trash`、`media upload`、`terms add/update/delete`、`plugins install/update/uninstall/update-helper`、`zasp set/sync`)会立刻生效,执行前必须复述目标与内容,获得用户确认。
85
86
  - 只读(`packages/templates/trial`、`bills get`、`sites list/status`、`pages list/get`、`content types/list/get`、`media list/get`、`terms taxonomies/list`、`search`、`plugins list/catalog/helper-status`、`zasp settings/schema/status/diagnostics`、`config show`)可直接跑。
86
87
  2. **不猜 ID**:站点用 `sites list` 的 `guid`;页面用 `pages list` 的 `id`;套餐/模板用 list 返回的 id。
87
- 3. **先查再写**:改页面前先 `pages list`;开站前先 `trial status` 或 `bills get`。
88
+ 3. **先查再写**:改页面前先 `pages list`;**开站必须先 `templates catalog` + `present_website_templates` 选定模板**,再 `present_website_provision_form` 收齐试用字段;创建前再查 `trial status`。
89
+ 禁止未选模板就追问站名/区域/语言;禁止在对话里贴 Markdown 封面画廊。
88
90
  4. **只认 API Key**:所有命令走 `x-api-key`。Agent 沙箱只注入 Key,不要向用户要 JWT,也不要设 `SILUZAN_AUTH_TOKEN`,不要直连 ussiteman。
89
91
  5. **命令透明**:用一句话说明意图;用户要细节时再给完整命令。
90
92
  6. **失败先自救**:401 → 重新 `login`;开站失败勿盲目重试 POST;`site_created_unbound` → `sites bind`;helper 404 → 自动升 helper。不要编造成功。
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "slug": "siluzan-website",
3
- "version": "1.0.1-beta.6",
4
- "publishedAt": 1790567480723,
3
+ "version": "1.0.1-beta.8",
4
+ "publishedAt": 1790660435749,
5
5
  "homepage": "https://www.siluzan.com",
6
6
  "source": "https://dev.azure.com/jack4it/Sammamish/_git/siluzan-skill",
7
7
  "requiredBinaries": [
@@ -1,35 +1,82 @@
1
1
  # 对话开通站点(provision)
2
2
 
3
- 通过主站 `website-provision` API 完成选套餐 → 支付/试用 → 选模板 → 创建站。
4
- **禁止**直连 ussiteman,**禁止**向用户要 JWT。只使用 API Key + 本 Skill CLI。
3
+ 通过主站 `website-provision` API 完成:**选模板 → 试用表单 → 创建**。
4
+ **禁止**直连 ussiteman,**禁止**向用户要 JWT。只使用 API Key + 本 Skill CLI。
5
+ **禁止**在对话里粘贴 Markdown 封面画廊;图文选模与表单由 DeerFlow `present_*` 工具渲染。
5
6
 
6
- ## 对话 SOP
7
+ ## 对话 SOP(必须按此顺序)
7
8
 
8
- 1. `packages list` — 列套餐并与用户选定(或确认走试用)
9
- 2. 付费:`bills create --package <id>` → 把 `checkoutUrl` 给用户 → 用户付完后 `bills get --id <billId>` 确认 Paid
10
- 3. `templates list --package <id>` — 选定模板;需要时 `templates get --id`
11
- 4. `trial status` — 试用路径先看剩余次数(上限 3)
12
- 5. **复述计划并获用户确认**(站名、区域 US/CN、语种、套餐、模板、试用或账单号)
13
- 6. `sites create --name … --region … --package … --template … --site-lang … --admin-lang … [--bill …] [--wait]`
14
- 7. 若返回 `site_created_unbound`:`sites bind --site <guid> --name <同名> --region …`
15
- 8. `sites status` / `sites list` 核对 Online 后,再交给 pages / plugins 等运维命令
9
+ ### 1. 拉取模板目录(JSON)
10
+
11
+ ```bash
12
+ siluzan-website templates catalog
13
+ # 或只看某套餐:siluzan-website templates catalog --package BasicEdition
14
+ ```
15
+
16
+ CLI **默认输出 JSON**(含 `groups[].templates[].coverUrl / previewUrl`)。
17
+ 拿到 JSON 后立刻调用内置工具(**不要**把 JSON/Markdown 图文贴进回复):
18
+
19
+ ```
20
+ present_website_templates(groups_json=<catalog.groups 的 JSON 字符串>)
21
+ ```
22
+
23
+ 用户在卡片上点选模板后,会回传 `packageId` + `siteTemplateId`。
24
+
25
+ ### 2. 试用建站表单(确认模板之后)
26
+
27
+ 调用:
28
+
29
+ ```
30
+ present_website_provision_form(
31
+ package_id=…,
32
+ site_template_id=…,
33
+ package_name=…, template_name=…,
34
+ cover_url=…, preview_url=…, # 可选,用于卡片摘要
35
+ default_region=US|CN,
36
+ default_site_lang=…,
37
+ default_admin_lang=…
38
+ )
39
+ ```
40
+
41
+ 表单字段(试用):站名、区域、前台语言、后台语言。
42
+ 套餐/模板已锁定,表单内只读展示。**本版不做付费/账单路径**。
43
+
44
+ ### 3. 额度
45
+
46
+ 提交表单后:`trial status`;若 `remaining=0` 告知用户试用已满,勿强行 create。
47
+
48
+ ### 4. 复述计划并确认后创建
49
+
50
+ 复述:站名、区域、语种、套餐、模板、试用 → 用户明确同意后:
51
+
52
+ ```bash
53
+ siluzan-website sites create \
54
+ --name "…" --region US|CN \
55
+ --package <packageId> --template <siteTemplateId> \
56
+ --site-lang … --admin-lang … \
57
+ [--wait]
58
+ ```
59
+
60
+ 不要传 `--bill`。
61
+
62
+ ### 5. 收尾
63
+
64
+ - `site_created_unbound` → `sites bind --site <guid> --name <同名> --region …`
65
+ - `sites status` / `sites list` 核对 Online 后,再交给 pages / plugins
16
66
 
17
67
  ## 写操作确认
18
68
 
19
- `bills create`、`sites create`、`sites bind` 执行前必须复述参数并获得用户明确同意。
20
- 创建站**不可盲目重试**;失败后先 `sites list` / `trial status` / `bills get` 排查。
69
+ `sites create`、`sites bind` 执行前必须复述参数并获得用户明确同意。
70
+ 创建站**不可盲目重试**;失败后先 `sites list` / `trial status` 排查。
21
71
 
22
72
  ## 命令速查
23
73
 
24
74
  ```bash
25
- siluzan-website packages list
26
- siluzan-website templates list --package <packageId>
75
+ siluzan-website templates catalog
76
+ siluzan-website templates catalog --package BasicEdition
27
77
  siluzan-website templates get --id <siteTemplateId>
28
78
  siluzan-website trial status
29
- siluzan-website bills create --package <packageId> --channel Monthly
30
- siluzan-website bills get --id <billId>
31
79
  siluzan-website sites create --name "Acme" --region US --package <id> --template <id> --site-lang en_US --admin-lang en_US
32
- siluzan-website sites create ... --bill <billId> --wait
33
80
  siluzan-website sites status --site <guid> --region US
34
81
  siluzan-website sites bind --site <guid> --region US --name "Acme"
35
82
  ```
@@ -38,13 +85,15 @@ siluzan-website sites bind --site <guid> --region US --name "Acme"
38
85
 
39
86
  | 现象 | 处理 |
40
87
  |------|------|
41
- | trial_exhausted / trials | 试用已满 3 次,引导付费账单路径 |
42
- | bill_unpaid / bill_owner_mismatch | 查 `bills get`;勿用他人账单号 |
88
+ | trial_exhausted / trials | 试用已满 3 次,告知用户 |
43
89
  | site_created_unbound | 跑 `sites bind`,再 `sites list` |
44
90
  | 503 disabled | 主站 WebsiteProvision 功能开关关闭 |
91
+ | template-catalog 404 | CLI 会自动 packages+templates 拼装;仍用 JSON + `present_website_templates` |
45
92
 
46
93
  ## 明确不做
47
94
 
95
+ - 对话 Markdown 封面画廊 / 多轮零散追问建站字段
48
96
  - CLI 直连 SiteMan / 注入 `SILUZAN_AUTH_TOKEN` 开通
97
+ - 付费账单 / 收银台(本版仅试用)
49
98
  - 删除站、重启、绑域名、CDN、SSL
50
99
  - AI Sites / LPS 静态建站
@@ -9,7 +9,7 @@ $ErrorActionPreference = 'Stop'
9
9
  # -- Package info (injected at build time) ------------------------------------
10
10
  $PKG_NAME = 'siluzan-website-cli'
11
11
  # PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
12
- $PKG_VERSION = '1.0.1-beta.6'
12
+ $PKG_VERSION = '1.0.1-beta.8'
13
13
  $CLI_BIN = 'siluzan-website'
14
14
  $SKILL_LABEL = 'Siluzan Website'
15
15
  $INSTALL_CMD = 'npm install -g siluzan-website-cli@beta'
@@ -9,7 +9,7 @@ set -euo pipefail
9
9
  # -- Package info (injected at build time) ------------------------------------
10
10
  readonly PKG_NAME="siluzan-website-cli"
11
11
  # PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
12
- readonly PKG_VERSION="1.0.1-beta.6"
12
+ readonly PKG_VERSION="1.0.1-beta.8"
13
13
  readonly CLI_BIN="siluzan-website"
14
14
  readonly SKILL_LABEL="Siluzan Website"
15
15
  readonly INSTALL_CMD="npm install -g siluzan-website-cli@beta"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "siluzan-website-cli",
3
- "version": "1.0.1-beta.6",
3
+ "version": "1.0.1-beta.8",
4
4
  "description": "Siluzan WordPress 站点管理 Skill CLI — 列出站点、新增/编辑页面、安装/升级插件。",
5
5
  "keywords": [
6
6
  "ai-skill",