@geoly-ai/social-hub-cli 0.3.2 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,19 @@ All notable changes to `@geoly-ai/social-hub-cli` are documented in this file.
4
4
 
5
5
  Release workflow: `pnpm release:cli` → `pnpm publish:cli`.
6
6
 
7
+ ## [0.3.4] - 2026-07-31
8
+
9
+ ### Added
10
+
11
+ - 写作矩阵 P0-C —— 五项写作前置门与返工机制(vendored)
12
+ - 客户交付 Phase1 Wave2-A —— SDK/CLI 接 Block3 client-delivery API
13
+
14
+ ## [0.3.3] - 2026-07-31
15
+
16
+ ### Fixed
17
+
18
+ - 补 hot-posts↔Arctic history 跨 skill 划界 —— 历史帖别误用 Hub 缓存
19
+
7
20
  ## [0.3.2] - 2026-07-31
8
21
 
9
22
  ### Added
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=client-delivery.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-delivery.test.d.ts","sourceRoot":"","sources":["../src/client-delivery.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Integration tests for the `client-delivery` CLI command group:
3
+ * - staff + client subcommands register on the program;
4
+ * - request-changes reads its body via --json-file (Windows-friendly) and
5
+ * forwards it to the SDK;
6
+ * - approve forwards the CAS expectedRevisionHash and a 409 (hash conflict)
7
+ * propagates faithfully instead of being swallowed;
8
+ * - list-bundles forwards the required brandId filter.
9
+ */
10
+ import { beforeAll, afterEach, describe, expect, it, vi } from "vitest";
11
+ import { writeFileSync, mkdtempSync } from "node:fs";
12
+ import { tmpdir } from "node:os";
13
+ import { join } from "node:path";
14
+ const clientDeliveryRequestChanges = vi
15
+ .fn()
16
+ .mockResolvedValue({ revision: {} });
17
+ const clientDeliveryApproveRevision = vi
18
+ .fn()
19
+ .mockResolvedValue({ revision: {} });
20
+ const clientDeliveryListBundles = vi.fn().mockResolvedValue({ items: [] });
21
+ vi.mock("@geoly-ai/social-hub-sdk", () => ({
22
+ SocialHubClient: vi.fn(),
23
+ getSocialHubHealth: vi.fn(),
24
+ }));
25
+ vi.mock("./client.js", () => ({
26
+ requireClient: () => ({
27
+ clientDeliveryRequestChanges,
28
+ clientDeliveryApproveRevision,
29
+ clientDeliveryListBundles,
30
+ }),
31
+ resolveTeamId: (t) => t ?? "team-1",
32
+ getBaseUrl: () => "http://localhost",
33
+ }));
34
+ let program;
35
+ beforeAll(async () => {
36
+ program = (await import("./index.js")).program;
37
+ vi.spyOn(console, "log").mockImplementation(() => { });
38
+ }, 30000);
39
+ function group() {
40
+ return program.commands.find((c) => c.name() === "client-delivery");
41
+ }
42
+ function subNames() {
43
+ return group()?.commands.map((c) => c.name()) ?? [];
44
+ }
45
+ function subCmd(name) {
46
+ return group()?.commands.find((c) => c.name() === name);
47
+ }
48
+ afterEach(() => {
49
+ clientDeliveryRequestChanges.mockClear();
50
+ clientDeliveryApproveRevision.mockClear();
51
+ clientDeliveryListBundles.mockClear();
52
+ // Commander stores parsed option values on the singleton command; clear them
53
+ // so a value from one parseAsync run does not leak into the next.
54
+ for (const name of ["request-changes", "approve", "list-bundles"]) {
55
+ const cmd = subCmd(name);
56
+ for (const key of ["json", "jsonFile", "expectedHash", "note", "brand"]) {
57
+ cmd?.setOptionValue(key, undefined);
58
+ }
59
+ }
60
+ });
61
+ describe("client-delivery command registration", () => {
62
+ it("registers the group", () => {
63
+ expect(program.commands.map((c) => c.name())).toContain("client-delivery");
64
+ });
65
+ it("registers staff + client subcommands", () => {
66
+ const names = subNames();
67
+ for (const expected of [
68
+ // staff
69
+ "create-bundle",
70
+ "upsert-item",
71
+ "create-revision",
72
+ "submit-revision",
73
+ "create-product",
74
+ "create-fact-version",
75
+ "activate-fact-version",
76
+ "create-policy-version",
77
+ "activate-policy-version",
78
+ // client
79
+ "list-bundles",
80
+ "get-bundle",
81
+ "list-items",
82
+ "get-item",
83
+ "list-revisions",
84
+ "get-revision",
85
+ "list-comments",
86
+ "list-events",
87
+ "approve",
88
+ "request-changes",
89
+ "add-comment",
90
+ "resolve-comment",
91
+ "create-client-fact-version",
92
+ ]) {
93
+ expect(names).toContain(expected);
94
+ }
95
+ });
96
+ });
97
+ describe("client-delivery request-changes JSON input", () => {
98
+ const body = {
99
+ expectedRevisionHash: "hash-abc",
100
+ comments: [{ fieldKey: "title", body: "shorten" }],
101
+ };
102
+ function tmpFile() {
103
+ const dir = mkdtempSync(join(tmpdir(), "cd-json-"));
104
+ const file = join(dir, "body.json");
105
+ writeFileSync(file, JSON.stringify(body), "utf8");
106
+ return file;
107
+ }
108
+ it("reads body from --json-file and forwards to the SDK", async () => {
109
+ const file = tmpFile();
110
+ await program.parseAsync([
111
+ "node",
112
+ "social-hub",
113
+ "client-delivery",
114
+ "request-changes",
115
+ "--revision",
116
+ "r-1",
117
+ "--json-file",
118
+ file,
119
+ ]);
120
+ expect(clientDeliveryRequestChanges).toHaveBeenCalledWith("team-1", "r-1", body);
121
+ });
122
+ it("reads body from -j @file", async () => {
123
+ const file = tmpFile();
124
+ await program.parseAsync([
125
+ "node",
126
+ "social-hub",
127
+ "client-delivery",
128
+ "request-changes",
129
+ "--revision",
130
+ "r-1",
131
+ "-j",
132
+ `@${file}`,
133
+ ]);
134
+ expect(clientDeliveryRequestChanges).toHaveBeenCalledWith("team-1", "r-1", body);
135
+ });
136
+ });
137
+ describe("client-delivery approve (CAS)", () => {
138
+ it("forwards --expected-hash as expectedRevisionHash", async () => {
139
+ await program.parseAsync([
140
+ "node",
141
+ "social-hub",
142
+ "client-delivery",
143
+ "approve",
144
+ "--revision",
145
+ "r-1",
146
+ "--expected-hash",
147
+ "hash-abc",
148
+ "--note",
149
+ "lgtm",
150
+ ]);
151
+ expect(clientDeliveryApproveRevision).toHaveBeenCalledWith("team-1", "r-1", {
152
+ expectedRevisionHash: "hash-abc",
153
+ note: "lgtm",
154
+ });
155
+ });
156
+ it("propagates a 409 hash conflict instead of swallowing it", async () => {
157
+ clientDeliveryApproveRevision.mockRejectedValueOnce(new Error("HTTP 409: revision changed; reload before deciding"));
158
+ await expect(program.parseAsync([
159
+ "node",
160
+ "social-hub",
161
+ "client-delivery",
162
+ "approve",
163
+ "--revision",
164
+ "r-1",
165
+ "--expected-hash",
166
+ "stale",
167
+ ])).rejects.toThrow(/HTTP 409/);
168
+ });
169
+ it("propagates a 403 (api_key rejected; decision needs a user credential)", async () => {
170
+ // Client decisions require an auth-login user; a static api_key is refused
171
+ // server-side and the SDK surfaces it as HTTP 403. The CLI must not swallow
172
+ // it — credentials are decided by `auth login`, the CLI only relays.
173
+ clientDeliveryApproveRevision.mockRejectedValueOnce(new Error("HTTP 403: this action requires an authenticated user"));
174
+ await expect(program.parseAsync([
175
+ "node",
176
+ "social-hub",
177
+ "client-delivery",
178
+ "approve",
179
+ "--revision",
180
+ "r-1",
181
+ "--expected-hash",
182
+ "hash-abc",
183
+ ])).rejects.toThrow(/HTTP 403/);
184
+ });
185
+ });
186
+ describe("client-delivery list-bundles", () => {
187
+ it("forwards the required brandId filter", async () => {
188
+ await program.parseAsync([
189
+ "node",
190
+ "social-hub",
191
+ "client-delivery",
192
+ "list-bundles",
193
+ "--brand",
194
+ "brand-9",
195
+ ]);
196
+ expect(clientDeliveryListBundles).toHaveBeenCalledWith("team-1", {
197
+ brandId: "brand-9",
198
+ });
199
+ });
200
+ });
201
+ //# sourceMappingURL=client-delivery.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-delivery.test.js","sourceRoot":"","sources":["../src/client-delivery.test.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  {
2
- "generatedAt": "2026-07-31T06:25:46.989Z",
3
- "cliVersion": "0.3.2",
2
+ "generatedAt": "2026-07-31T10:50:16.756Z",
3
+ "cliVersion": "0.3.4",
4
4
  "commands": [
5
5
  "accounts",
6
6
  "accounts brand-bindings",
@@ -121,6 +121,29 @@
121
121
  "campaigns get",
122
122
  "campaigns list",
123
123
  "campaigns update",
124
+ "client-delivery",
125
+ "client-delivery activate-fact-version",
126
+ "client-delivery activate-policy-version",
127
+ "client-delivery add-comment",
128
+ "client-delivery approve",
129
+ "client-delivery create-bundle",
130
+ "client-delivery create-client-fact-version",
131
+ "client-delivery create-fact-version",
132
+ "client-delivery create-policy-version",
133
+ "client-delivery create-product",
134
+ "client-delivery create-revision",
135
+ "client-delivery get-bundle",
136
+ "client-delivery get-item",
137
+ "client-delivery get-revision",
138
+ "client-delivery list-bundles",
139
+ "client-delivery list-comments",
140
+ "client-delivery list-events",
141
+ "client-delivery list-items",
142
+ "client-delivery list-revisions",
143
+ "client-delivery request-changes",
144
+ "client-delivery resolve-comment",
145
+ "client-delivery submit-revision",
146
+ "client-delivery upsert-item",
124
147
  "comment-drafts",
125
148
  "comment-drafts create",
126
149
  "comment-drafts delete",
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoCpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AA+8D9B,8DAA8D;AAC9D,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,GAAG,IAAI,CAOf;AA2/BD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1D,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjE,CAAC;AAQF,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE;IACN,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC,GACA,OAAO,CAAC;IAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,CAkJnE;AA+1ED,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+CpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AA43E9B,8DAA8D;AAC9D,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,GAAG,IAAI,CAOf;AA2/BD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1D,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjE,CAAC;AAQF,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE;IACN,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC,GACA,OAAO,CAAC;IAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,CAkJnE;AA+1ED,OAAO,EAAE,OAAO,EAAE,CAAC"}
package/dist/index.js CHANGED
@@ -1208,6 +1208,285 @@ commentDrafts
1208
1208
  const res = await requireClient().scheduleCommentDraft(resolveTeamId(opts.team), opts.draft, body);
1209
1209
  console.log(JSON.stringify(res, null, 2));
1210
1210
  });
1211
+ // --- 客户面内容审核(Client Content Delivery)---
1212
+ //
1213
+ // staff 管理面(clientDeliveryAdmin):建 bundle/item/revision + 产品/事实/政策。
1214
+ // 客户 portal 面(clientDelivery):读、决策(approve/request-changes,走 CAS
1215
+ // expectedRevisionHash;不符 → 409)、字段级评论。**客户决策/评论/事实提交须用 user 凭证
1216
+ // (`social-hub auth login`),api_key 会被服务端拒**——CLI 如实透传服务端错误。
1217
+ const clientDelivery = program
1218
+ .command("client-delivery")
1219
+ .description("客户面内容审核交付(bundle/item/revision + 客户 approve/request-changes;决策须 user 凭证)");
1220
+ // ── staff 管理面 ──────────────────────────────────────────────────────────────
1221
+ clientDelivery
1222
+ .command("create-bundle")
1223
+ .description("POST client-delivery/bundles — staff 建 bundle")
1224
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1225
+ .option("-j, --json <json>", "{ brandId, bundleCode, name, clientDueAt? }。也可 -j @<path> / -j -(stdin)")
1226
+ .option("--json-file <path>", "从文件读 body JSON(路径,或 - 表示 stdin);与 -j 二选一(Windows 友好)")
1227
+ .action(async (opts) => {
1228
+ const body = readJsonArgOrExit({
1229
+ inline: opts.json,
1230
+ file: opts.jsonFile,
1231
+ });
1232
+ const res = await requireClient().clientDeliveryCreateBundle(resolveTeamId(opts.team), body);
1233
+ console.log(JSON.stringify(res, null, 2));
1234
+ });
1235
+ clientDelivery
1236
+ .command("upsert-item")
1237
+ .description("POST client-delivery/bundles/:id/items — staff upsert 条目(帖/评 + 矩阵字段)")
1238
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1239
+ .requiredOption("--bundle <uuid>", "Bundle UUID")
1240
+ .option("-j, --json <json>", "{ kind(post|comment), itemCode, contentDraftId?, commentDraftId?, ordinal?, boundProductId?, ...矩阵字段 }")
1241
+ .option("--json-file <path>", "从文件读 body JSON(路径,或 -);与 -j 二选一")
1242
+ .action(async (opts) => {
1243
+ const body = readJsonArgOrExit({
1244
+ inline: opts.json,
1245
+ file: opts.jsonFile,
1246
+ });
1247
+ const res = await requireClient().clientDeliveryUpsertItem(resolveTeamId(opts.team), opts.bundle, body);
1248
+ console.log(JSON.stringify(res, null, 2));
1249
+ });
1250
+ clientDelivery
1251
+ .command("create-revision")
1252
+ .description("POST client-delivery/items/:id/revisions — staff 建不可变送审快照")
1253
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1254
+ .requiredOption("--item <uuid>", "Item UUID")
1255
+ .action(async (opts) => {
1256
+ const res = await requireClient().clientDeliveryCreateRevision(resolveTeamId(opts.team), opts.item);
1257
+ console.log(JSON.stringify(res, null, 2));
1258
+ });
1259
+ clientDelivery
1260
+ .command("submit-revision")
1261
+ .description("POST client-delivery/revisions/:id/submit — staff 送审(not_submitted|withdrawn → pending)")
1262
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1263
+ .requiredOption("--revision <uuid>", "Revision UUID")
1264
+ .option("--note <text>", "送审备注(可选)")
1265
+ .action(async (opts) => {
1266
+ const body = {};
1267
+ if (opts.note !== undefined)
1268
+ body.note = opts.note;
1269
+ const res = await requireClient().clientDeliverySubmitRevision(resolveTeamId(opts.team), opts.revision, body);
1270
+ console.log(JSON.stringify(res, null, 2));
1271
+ });
1272
+ clientDelivery
1273
+ .command("create-product")
1274
+ .description("POST client-delivery/products — staff 建产品身份")
1275
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1276
+ .option("-j, --json <json>", "{ brandId, sku, brandRegistryId?, modelName?, market?, status? }")
1277
+ .option("--json-file <path>", "从文件读 body JSON(路径,或 -);与 -j 二选一")
1278
+ .action(async (opts) => {
1279
+ const body = readJsonArgOrExit({
1280
+ inline: opts.json,
1281
+ file: opts.jsonFile,
1282
+ });
1283
+ const res = await requireClient().clientDeliveryCreateProduct(resolveTeamId(opts.team), body);
1284
+ console.log(JSON.stringify(res, null, 2));
1285
+ });
1286
+ clientDelivery
1287
+ .command("create-fact-version")
1288
+ .description("POST client-delivery/products/:productId/fact-versions(staff 面)— provenance 默认 staff")
1289
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1290
+ .requiredOption("--product <uuid>", "Product UUID")
1291
+ .option("-j, --json <json>", "{ provenance?, positioning?, materials?, priceAmount?, priceCurrency?, inventoryStatus?, factsJson?, effectiveAt?, expiresAt?, sourceRef?, ... }")
1292
+ .option("--json-file <path>", "从文件读 body JSON(路径,或 -);与 -j 二选一")
1293
+ .action(async (opts) => {
1294
+ const body = readJsonArgOrExit({
1295
+ inline: opts.json,
1296
+ file: opts.jsonFile,
1297
+ });
1298
+ const res = await requireClient().clientDeliveryCreateFactVersion(resolveTeamId(opts.team), opts.product, body);
1299
+ console.log(JSON.stringify(res, null, 2));
1300
+ });
1301
+ clientDelivery
1302
+ .command("activate-fact-version")
1303
+ .description("POST client-delivery/products/:productId/fact-versions/:fvId/activate — staff 激活 + stale 传播")
1304
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1305
+ .requiredOption("--product <uuid>", "Product UUID")
1306
+ .requiredOption("--fact-version <uuid>", "Fact version UUID")
1307
+ .action(async (opts) => {
1308
+ const res = await requireClient().clientDeliveryActivateFactVersion(resolveTeamId(opts.team), opts.product, opts.factVersion);
1309
+ console.log(JSON.stringify(res, null, 2));
1310
+ });
1311
+ clientDelivery
1312
+ .command("create-policy-version")
1313
+ .description("POST client-delivery/policy-versions — staff 建品牌内容政策版本")
1314
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1315
+ .option("-j, --json <json>", "{ brandId, market?, provenance?, policyJson?, effectiveAt? }")
1316
+ .option("--json-file <path>", "从文件读 body JSON(路径,或 -);与 -j 二选一")
1317
+ .action(async (opts) => {
1318
+ const body = readJsonArgOrExit({
1319
+ inline: opts.json,
1320
+ file: opts.jsonFile,
1321
+ });
1322
+ const res = await requireClient().clientDeliveryCreatePolicyVersion(resolveTeamId(opts.team), body);
1323
+ console.log(JSON.stringify(res, null, 2));
1324
+ });
1325
+ clientDelivery
1326
+ .command("activate-policy-version")
1327
+ .description("POST client-delivery/policy-versions/:id/activate — staff 激活政策版本")
1328
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1329
+ .requiredOption("--policy-version <uuid>", "Policy version UUID")
1330
+ .action(async (opts) => {
1331
+ const res = await requireClient().clientDeliveryActivatePolicyVersion(resolveTeamId(opts.team), opts.policyVersion);
1332
+ console.log(JSON.stringify(res, null, 2));
1333
+ });
1334
+ // ── 客户 portal 面(读/决策/评论)──────────────────────────────────────────────
1335
+ clientDelivery
1336
+ .command("list-bundles")
1337
+ .description("GET client-delivery/bundles — 客户面 bundle 列表(brandId 必填)")
1338
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1339
+ .requiredOption("--brand <uuid>", "brandId(服务端必填)")
1340
+ .option("--status <st>", "状态过滤:open | closed | cancelled")
1341
+ .option("-n, --limit <n>", "limit")
1342
+ .option("--offset <n>", "offset")
1343
+ .action(async (opts) => {
1344
+ const params = { brandId: opts.brand };
1345
+ if (opts.status)
1346
+ params.status = opts.status;
1347
+ if (opts.limit !== undefined)
1348
+ params.limit = Number(opts.limit);
1349
+ if (opts.offset !== undefined)
1350
+ params.offset = Number(opts.offset);
1351
+ const res = await requireClient().clientDeliveryListBundles(resolveTeamId(opts.team), params);
1352
+ console.log(JSON.stringify(res, null, 2));
1353
+ });
1354
+ clientDelivery
1355
+ .command("get-bundle")
1356
+ .description("GET client-delivery/bundles/:id")
1357
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1358
+ .requiredOption("--bundle <uuid>", "Bundle UUID")
1359
+ .action(async (opts) => {
1360
+ const res = await requireClient().clientDeliveryGetBundle(resolveTeamId(opts.team), opts.bundle);
1361
+ console.log(JSON.stringify(res, null, 2));
1362
+ });
1363
+ clientDelivery
1364
+ .command("list-items")
1365
+ .description("GET client-delivery/bundles/:id/items")
1366
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1367
+ .requiredOption("--bundle <uuid>", "Bundle UUID")
1368
+ .action(async (opts) => {
1369
+ const res = await requireClient().clientDeliveryListItems(resolveTeamId(opts.team), opts.bundle);
1370
+ console.log(JSON.stringify(res, null, 2));
1371
+ });
1372
+ clientDelivery
1373
+ .command("get-item")
1374
+ .description("GET client-delivery/items/:id")
1375
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1376
+ .requiredOption("--item <uuid>", "Item UUID")
1377
+ .action(async (opts) => {
1378
+ const res = await requireClient().clientDeliveryGetItem(resolveTeamId(opts.team), opts.item);
1379
+ console.log(JSON.stringify(res, null, 2));
1380
+ });
1381
+ clientDelivery
1382
+ .command("list-revisions")
1383
+ .description("GET client-delivery/items/:id/revisions")
1384
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1385
+ .requiredOption("--item <uuid>", "Item UUID")
1386
+ .action(async (opts) => {
1387
+ const res = await requireClient().clientDeliveryListRevisions(resolveTeamId(opts.team), opts.item);
1388
+ console.log(JSON.stringify(res, null, 2));
1389
+ });
1390
+ clientDelivery
1391
+ .command("get-revision")
1392
+ .description("GET client-delivery/revisions/:id(含 sourceContentHash 作 approve/request-changes 的 CAS 凭证)")
1393
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1394
+ .requiredOption("--revision <uuid>", "Revision UUID")
1395
+ .action(async (opts) => {
1396
+ const res = await requireClient().clientDeliveryGetRevision(resolveTeamId(opts.team), opts.revision);
1397
+ console.log(JSON.stringify(res, null, 2));
1398
+ });
1399
+ clientDelivery
1400
+ .command("list-comments")
1401
+ .description("GET client-delivery/revisions/:id/comments")
1402
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1403
+ .requiredOption("--revision <uuid>", "Revision UUID")
1404
+ .action(async (opts) => {
1405
+ const res = await requireClient().clientDeliveryListComments(resolveTeamId(opts.team), opts.revision);
1406
+ console.log(JSON.stringify(res, null, 2));
1407
+ });
1408
+ clientDelivery
1409
+ .command("list-events")
1410
+ .description("GET client-delivery/revisions/:id/events — 决策事件链")
1411
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1412
+ .requiredOption("--revision <uuid>", "Revision UUID")
1413
+ .action(async (opts) => {
1414
+ const res = await requireClient().clientDeliveryListEvents(resolveTeamId(opts.team), opts.revision);
1415
+ console.log(JSON.stringify(res, null, 2));
1416
+ });
1417
+ clientDelivery
1418
+ .command("approve")
1419
+ .description("POST client-delivery/revisions/:id/approve — 客户批准(CAS;须 user 凭证,api_key 被拒;hash 不符 → 409)")
1420
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1421
+ .requiredOption("--revision <uuid>", "Revision UUID")
1422
+ .requiredOption("--expected-hash <hash>", "expectedRevisionHash(取自 get-revision 的 sourceContentHash;不符 → 409)")
1423
+ .option("--note <text>", "批准备注(可选)")
1424
+ .action(async (opts) => {
1425
+ const body = {
1426
+ expectedRevisionHash: opts.expectedHash,
1427
+ };
1428
+ if (opts.note !== undefined)
1429
+ body.note = opts.note;
1430
+ const res = await requireClient().clientDeliveryApproveRevision(resolveTeamId(opts.team), opts.revision, body);
1431
+ console.log(JSON.stringify(res, null, 2));
1432
+ });
1433
+ clientDelivery
1434
+ .command("request-changes")
1435
+ .description("POST client-delivery/revisions/:id/request-changes — 客户请求修改 + 字段级评论(CAS;须 user 凭证;hash 不符 → 409)")
1436
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1437
+ .requiredOption("--revision <uuid>", "Revision UUID")
1438
+ .option("-j, --json <json>", "{ expectedRevisionHash, comments:[{ fieldKey, quotedText?, body }], note? }。也可 -j @<path> / -j -")
1439
+ .option("--json-file <path>", "从文件读 body JSON(路径,或 -);与 -j 二选一")
1440
+ .action(async (opts) => {
1441
+ const body = readJsonArgOrExit({
1442
+ inline: opts.json,
1443
+ file: opts.jsonFile,
1444
+ });
1445
+ const res = await requireClient().clientDeliveryRequestChanges(resolveTeamId(opts.team), opts.revision, body);
1446
+ console.log(JSON.stringify(res, null, 2));
1447
+ });
1448
+ clientDelivery
1449
+ .command("add-comment")
1450
+ .description("POST client-delivery/revisions/:id/comments — 客户字段级讨论(须 user 凭证)")
1451
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1452
+ .requiredOption("--revision <uuid>", "Revision UUID")
1453
+ .requiredOption("--field-key <key>", "字段定位(如 title/body/price)")
1454
+ .requiredOption("--body <text>", "评论正文")
1455
+ .option("--quoted-text <text>", "引用的原文片段(可选)")
1456
+ .action(async (opts) => {
1457
+ const body = {
1458
+ fieldKey: opts.fieldKey,
1459
+ body: opts.body,
1460
+ };
1461
+ if (opts.quotedText !== undefined)
1462
+ body.quotedText = opts.quotedText;
1463
+ const res = await requireClient().clientDeliveryAddComment(resolveTeamId(opts.team), opts.revision, body);
1464
+ console.log(JSON.stringify(res, null, 2));
1465
+ });
1466
+ clientDelivery
1467
+ .command("resolve-comment")
1468
+ .description("POST client-delivery/comments/:id/resolve — 客户关闭讨论(幂等;须 user 凭证)")
1469
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1470
+ .requiredOption("--comment <uuid>", "Comment UUID")
1471
+ .action(async (opts) => {
1472
+ const res = await requireClient().clientDeliveryResolveComment(resolveTeamId(opts.team), opts.comment);
1473
+ console.log(JSON.stringify(res, null, 2));
1474
+ });
1475
+ clientDelivery
1476
+ .command("create-client-fact-version")
1477
+ .description("POST client-delivery/products/:productId/fact-versions(客户面)— provenance 强制 client(须 user 凭证)")
1478
+ .option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
1479
+ .requiredOption("--product <uuid>", "Product UUID")
1480
+ .option("-j, --json <json>", "{ positioning?, materials?, priceAmount?, priceCurrency?, inventoryStatus?, factsJson?, effectiveAt?, expiresAt?, sourceRef?, ... }")
1481
+ .option("--json-file <path>", "从文件读 body JSON(路径,或 -);与 -j 二选一")
1482
+ .action(async (opts) => {
1483
+ const body = readJsonArgOrExit({
1484
+ inline: opts.json,
1485
+ file: opts.jsonFile,
1486
+ });
1487
+ const res = await requireClient().clientDeliveryCreateClientFactVersion(resolveTeamId(opts.team), opts.product, body);
1488
+ console.log(JSON.stringify(res, null, 2));
1489
+ });
1211
1490
  // --- compliance ---
1212
1491
  const compliance = program.command("compliance").description("合规 / 风控");
1213
1492
  compliance