@geoly-ai/social-hub-cli 0.3.3 → 0.3.5
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 +17 -0
- package/dist/client-delivery.test.d.ts +2 -0
- package/dist/client-delivery.test.d.ts.map +1 -0
- package/dist/client-delivery.test.js +201 -0
- package/dist/client-delivery.test.js.map +1 -0
- package/dist/cmd-manifest.json +45 -2
- package/dist/cmd-manifest.test.js +28 -0
- package/dist/cmd-manifest.test.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +302 -0
- package/dist/index.js.map +1 -1
- package/dist/permissions-gates-notify.d.ts +26 -0
- package/dist/permissions-gates-notify.d.ts.map +1 -0
- package/dist/permissions-gates-notify.js +118 -0
- package/dist/permissions-gates-notify.js.map +1 -0
- package/dist/permissions-gates-notify.test.d.ts +2 -0
- package/dist/permissions-gates-notify.test.d.ts.map +1 -0
- package/dist/permissions-gates-notify.test.js +107 -0
- package/dist/permissions-gates-notify.test.js.map +1 -0
- package/dist/permissions.d.ts.map +1 -1
- package/dist/permissions.js +2 -0
- package/dist/permissions.js.map +1 -1
- package/dist/register-extensions.d.ts.map +1 -1
- package/dist/register-extensions.js +5 -9
- package/dist/register-extensions.js.map +1 -1
- package/dist/register-notify.d.ts +172 -0
- package/dist/register-notify.d.ts.map +1 -0
- package/dist/register-notify.js +1148 -0
- package/dist/register-notify.js.map +1 -0
- package/dist/register-notify.test.d.ts +2 -0
- package/dist/register-notify.test.d.ts.map +1 -0
- package/dist/register-notify.test.js +309 -0
- package/dist/register-notify.test.js.map +1 -0
- package/package.json +3 -3
- package/skills/README.md +1 -0
- package/skills/manifest.json +6 -1
- package/skills/reddit-content-rewrite/SKILL.md +58 -3
- package/skills/reddit-content-writing/SKILL.md +43 -5
- package/skills/reddit-content-writing/references/phase4-writing.md +3 -1
- package/skills/reddit-matrix.lock.json +4 -4
- package/skills/reddit-phase-brief/SKILL.md +30 -13
- package/skills/reddit-phase-brief/references/phase4-brief-workflow.md +39 -4
- package/skills/reddit-strategy-shared/references/content-diversity-contract.md +60 -5
- package/skills/reddit-strategy-shared/references/evidence-policy.md +30 -0
- package/skills/reddit-strategy-shared/references/handoff-schemas.md +7 -3
- package/skills/social-hub-notifications/SKILL.md +351 -0
- package/skills/social-hub-posts/SKILL.md +36 -0
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import { registerAccountsExtensions, registerAuthAndConfig, registerAuthzEvaluat
|
|
|
6
6
|
import { registerAdminCommands } from "./register-admin.js";
|
|
7
7
|
import { registerSubredditStyleCommands } from "./register-subreddit-style.js";
|
|
8
8
|
import { registerContentClassificationCommands } from "./register-content-classification.js";
|
|
9
|
+
import { registerNotifyCommands } from "./register-notify.js";
|
|
9
10
|
import { assertApplyOrDryRun } from "./dry-run.js";
|
|
10
11
|
import { withPermissionGate } from "./permission-runner.js";
|
|
11
12
|
import { registerBatchAndExport } from "./register-batch.js";
|
|
@@ -33,6 +34,7 @@ registerAgentContext(program);
|
|
|
33
34
|
registerAdminCommands(program);
|
|
34
35
|
registerSubredditStyleCommands(program);
|
|
35
36
|
registerContentClassificationCommands(program);
|
|
37
|
+
registerNotifyCommands(program);
|
|
36
38
|
registerBatchAndExport(program);
|
|
37
39
|
program
|
|
38
40
|
.command("health")
|
|
@@ -357,6 +359,27 @@ reddit
|
|
|
357
359
|
}, { fetchAll: Boolean(opts.all) });
|
|
358
360
|
console.log(JSON.stringify(res, null, 2));
|
|
359
361
|
});
|
|
362
|
+
reddit
|
|
363
|
+
.command("team-buckets")
|
|
364
|
+
.description("GET /v1/system/reddit-post-team-buckets(归属桶:未配置/外部)。外部来源帖回填前先用它拿桶 UUID")
|
|
365
|
+
.option("--slug <slug>", "只输出该 slug 的桶(便于脚本精确取一个)")
|
|
366
|
+
.option("--id-only", "只输出 UUID(每行一个),便于 shell 变量赋值")
|
|
367
|
+
.action(async (opts) => {
|
|
368
|
+
const res = await requireClient().listRedditPostTeamBuckets();
|
|
369
|
+
const items = opts.slug
|
|
370
|
+
? res.items.filter((item) => item.slug === opts.slug)
|
|
371
|
+
: res.items;
|
|
372
|
+
if (opts.slug && items.length === 0) {
|
|
373
|
+
console.error(`no team bucket with slug=${opts.slug}(可先不带 --slug 列出全部)`);
|
|
374
|
+
process.exit(1);
|
|
375
|
+
}
|
|
376
|
+
if (opts.idOnly) {
|
|
377
|
+
for (const item of items)
|
|
378
|
+
console.log(item.id);
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
console.log(JSON.stringify({ items }, null, 2));
|
|
382
|
+
});
|
|
360
383
|
reddit
|
|
361
384
|
.command("create-snapshot")
|
|
362
385
|
.description("POST /reddit-post-snapshots(手工补录)")
|
|
@@ -1208,6 +1231,285 @@ commentDrafts
|
|
|
1208
1231
|
const res = await requireClient().scheduleCommentDraft(resolveTeamId(opts.team), opts.draft, body);
|
|
1209
1232
|
console.log(JSON.stringify(res, null, 2));
|
|
1210
1233
|
});
|
|
1234
|
+
// --- 客户面内容审核(Client Content Delivery)---
|
|
1235
|
+
//
|
|
1236
|
+
// staff 管理面(clientDeliveryAdmin):建 bundle/item/revision + 产品/事实/政策。
|
|
1237
|
+
// 客户 portal 面(clientDelivery):读、决策(approve/request-changes,走 CAS
|
|
1238
|
+
// expectedRevisionHash;不符 → 409)、字段级评论。**客户决策/评论/事实提交须用 user 凭证
|
|
1239
|
+
// (`social-hub auth login`),api_key 会被服务端拒**——CLI 如实透传服务端错误。
|
|
1240
|
+
const clientDelivery = program
|
|
1241
|
+
.command("client-delivery")
|
|
1242
|
+
.description("客户面内容审核交付(bundle/item/revision + 客户 approve/request-changes;决策须 user 凭证)");
|
|
1243
|
+
// ── staff 管理面 ──────────────────────────────────────────────────────────────
|
|
1244
|
+
clientDelivery
|
|
1245
|
+
.command("create-bundle")
|
|
1246
|
+
.description("POST client-delivery/bundles — staff 建 bundle")
|
|
1247
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1248
|
+
.option("-j, --json <json>", "{ brandId, bundleCode, name, clientDueAt? }。也可 -j @<path> / -j -(stdin)")
|
|
1249
|
+
.option("--json-file <path>", "从文件读 body JSON(路径,或 - 表示 stdin);与 -j 二选一(Windows 友好)")
|
|
1250
|
+
.action(async (opts) => {
|
|
1251
|
+
const body = readJsonArgOrExit({
|
|
1252
|
+
inline: opts.json,
|
|
1253
|
+
file: opts.jsonFile,
|
|
1254
|
+
});
|
|
1255
|
+
const res = await requireClient().clientDeliveryCreateBundle(resolveTeamId(opts.team), body);
|
|
1256
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1257
|
+
});
|
|
1258
|
+
clientDelivery
|
|
1259
|
+
.command("upsert-item")
|
|
1260
|
+
.description("POST client-delivery/bundles/:id/items — staff upsert 条目(帖/评 + 矩阵字段)")
|
|
1261
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1262
|
+
.requiredOption("--bundle <uuid>", "Bundle UUID")
|
|
1263
|
+
.option("-j, --json <json>", "{ kind(post|comment), itemCode, contentDraftId?, commentDraftId?, ordinal?, boundProductId?, ...矩阵字段 }")
|
|
1264
|
+
.option("--json-file <path>", "从文件读 body JSON(路径,或 -);与 -j 二选一")
|
|
1265
|
+
.action(async (opts) => {
|
|
1266
|
+
const body = readJsonArgOrExit({
|
|
1267
|
+
inline: opts.json,
|
|
1268
|
+
file: opts.jsonFile,
|
|
1269
|
+
});
|
|
1270
|
+
const res = await requireClient().clientDeliveryUpsertItem(resolveTeamId(opts.team), opts.bundle, body);
|
|
1271
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1272
|
+
});
|
|
1273
|
+
clientDelivery
|
|
1274
|
+
.command("create-revision")
|
|
1275
|
+
.description("POST client-delivery/items/:id/revisions — staff 建不可变送审快照")
|
|
1276
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1277
|
+
.requiredOption("--item <uuid>", "Item UUID")
|
|
1278
|
+
.action(async (opts) => {
|
|
1279
|
+
const res = await requireClient().clientDeliveryCreateRevision(resolveTeamId(opts.team), opts.item);
|
|
1280
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1281
|
+
});
|
|
1282
|
+
clientDelivery
|
|
1283
|
+
.command("submit-revision")
|
|
1284
|
+
.description("POST client-delivery/revisions/:id/submit — staff 送审(not_submitted|withdrawn → pending)")
|
|
1285
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1286
|
+
.requiredOption("--revision <uuid>", "Revision UUID")
|
|
1287
|
+
.option("--note <text>", "送审备注(可选)")
|
|
1288
|
+
.action(async (opts) => {
|
|
1289
|
+
const body = {};
|
|
1290
|
+
if (opts.note !== undefined)
|
|
1291
|
+
body.note = opts.note;
|
|
1292
|
+
const res = await requireClient().clientDeliverySubmitRevision(resolveTeamId(opts.team), opts.revision, body);
|
|
1293
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1294
|
+
});
|
|
1295
|
+
clientDelivery
|
|
1296
|
+
.command("create-product")
|
|
1297
|
+
.description("POST client-delivery/products — staff 建产品身份")
|
|
1298
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1299
|
+
.option("-j, --json <json>", "{ brandId, sku, brandRegistryId?, modelName?, market?, status? }")
|
|
1300
|
+
.option("--json-file <path>", "从文件读 body JSON(路径,或 -);与 -j 二选一")
|
|
1301
|
+
.action(async (opts) => {
|
|
1302
|
+
const body = readJsonArgOrExit({
|
|
1303
|
+
inline: opts.json,
|
|
1304
|
+
file: opts.jsonFile,
|
|
1305
|
+
});
|
|
1306
|
+
const res = await requireClient().clientDeliveryCreateProduct(resolveTeamId(opts.team), body);
|
|
1307
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1308
|
+
});
|
|
1309
|
+
clientDelivery
|
|
1310
|
+
.command("create-fact-version")
|
|
1311
|
+
.description("POST client-delivery/products/:productId/fact-versions(staff 面)— provenance 默认 staff")
|
|
1312
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1313
|
+
.requiredOption("--product <uuid>", "Product UUID")
|
|
1314
|
+
.option("-j, --json <json>", "{ provenance?, positioning?, materials?, priceAmount?, priceCurrency?, inventoryStatus?, factsJson?, effectiveAt?, expiresAt?, sourceRef?, ... }")
|
|
1315
|
+
.option("--json-file <path>", "从文件读 body JSON(路径,或 -);与 -j 二选一")
|
|
1316
|
+
.action(async (opts) => {
|
|
1317
|
+
const body = readJsonArgOrExit({
|
|
1318
|
+
inline: opts.json,
|
|
1319
|
+
file: opts.jsonFile,
|
|
1320
|
+
});
|
|
1321
|
+
const res = await requireClient().clientDeliveryCreateFactVersion(resolveTeamId(opts.team), opts.product, body);
|
|
1322
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1323
|
+
});
|
|
1324
|
+
clientDelivery
|
|
1325
|
+
.command("activate-fact-version")
|
|
1326
|
+
.description("POST client-delivery/products/:productId/fact-versions/:fvId/activate — staff 激活 + stale 传播")
|
|
1327
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1328
|
+
.requiredOption("--product <uuid>", "Product UUID")
|
|
1329
|
+
.requiredOption("--fact-version <uuid>", "Fact version UUID")
|
|
1330
|
+
.action(async (opts) => {
|
|
1331
|
+
const res = await requireClient().clientDeliveryActivateFactVersion(resolveTeamId(opts.team), opts.product, opts.factVersion);
|
|
1332
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1333
|
+
});
|
|
1334
|
+
clientDelivery
|
|
1335
|
+
.command("create-policy-version")
|
|
1336
|
+
.description("POST client-delivery/policy-versions — staff 建品牌内容政策版本")
|
|
1337
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1338
|
+
.option("-j, --json <json>", "{ brandId, market?, provenance?, policyJson?, effectiveAt? }")
|
|
1339
|
+
.option("--json-file <path>", "从文件读 body JSON(路径,或 -);与 -j 二选一")
|
|
1340
|
+
.action(async (opts) => {
|
|
1341
|
+
const body = readJsonArgOrExit({
|
|
1342
|
+
inline: opts.json,
|
|
1343
|
+
file: opts.jsonFile,
|
|
1344
|
+
});
|
|
1345
|
+
const res = await requireClient().clientDeliveryCreatePolicyVersion(resolveTeamId(opts.team), body);
|
|
1346
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1347
|
+
});
|
|
1348
|
+
clientDelivery
|
|
1349
|
+
.command("activate-policy-version")
|
|
1350
|
+
.description("POST client-delivery/policy-versions/:id/activate — staff 激活政策版本")
|
|
1351
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1352
|
+
.requiredOption("--policy-version <uuid>", "Policy version UUID")
|
|
1353
|
+
.action(async (opts) => {
|
|
1354
|
+
const res = await requireClient().clientDeliveryActivatePolicyVersion(resolveTeamId(opts.team), opts.policyVersion);
|
|
1355
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1356
|
+
});
|
|
1357
|
+
// ── 客户 portal 面(读/决策/评论)──────────────────────────────────────────────
|
|
1358
|
+
clientDelivery
|
|
1359
|
+
.command("list-bundles")
|
|
1360
|
+
.description("GET client-delivery/bundles — 客户面 bundle 列表(brandId 必填)")
|
|
1361
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1362
|
+
.requiredOption("--brand <uuid>", "brandId(服务端必填)")
|
|
1363
|
+
.option("--status <st>", "状态过滤:open | closed | cancelled")
|
|
1364
|
+
.option("-n, --limit <n>", "limit")
|
|
1365
|
+
.option("--offset <n>", "offset")
|
|
1366
|
+
.action(async (opts) => {
|
|
1367
|
+
const params = { brandId: opts.brand };
|
|
1368
|
+
if (opts.status)
|
|
1369
|
+
params.status = opts.status;
|
|
1370
|
+
if (opts.limit !== undefined)
|
|
1371
|
+
params.limit = Number(opts.limit);
|
|
1372
|
+
if (opts.offset !== undefined)
|
|
1373
|
+
params.offset = Number(opts.offset);
|
|
1374
|
+
const res = await requireClient().clientDeliveryListBundles(resolveTeamId(opts.team), params);
|
|
1375
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1376
|
+
});
|
|
1377
|
+
clientDelivery
|
|
1378
|
+
.command("get-bundle")
|
|
1379
|
+
.description("GET client-delivery/bundles/:id")
|
|
1380
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1381
|
+
.requiredOption("--bundle <uuid>", "Bundle UUID")
|
|
1382
|
+
.action(async (opts) => {
|
|
1383
|
+
const res = await requireClient().clientDeliveryGetBundle(resolveTeamId(opts.team), opts.bundle);
|
|
1384
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1385
|
+
});
|
|
1386
|
+
clientDelivery
|
|
1387
|
+
.command("list-items")
|
|
1388
|
+
.description("GET client-delivery/bundles/:id/items")
|
|
1389
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1390
|
+
.requiredOption("--bundle <uuid>", "Bundle UUID")
|
|
1391
|
+
.action(async (opts) => {
|
|
1392
|
+
const res = await requireClient().clientDeliveryListItems(resolveTeamId(opts.team), opts.bundle);
|
|
1393
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1394
|
+
});
|
|
1395
|
+
clientDelivery
|
|
1396
|
+
.command("get-item")
|
|
1397
|
+
.description("GET client-delivery/items/:id")
|
|
1398
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1399
|
+
.requiredOption("--item <uuid>", "Item UUID")
|
|
1400
|
+
.action(async (opts) => {
|
|
1401
|
+
const res = await requireClient().clientDeliveryGetItem(resolveTeamId(opts.team), opts.item);
|
|
1402
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1403
|
+
});
|
|
1404
|
+
clientDelivery
|
|
1405
|
+
.command("list-revisions")
|
|
1406
|
+
.description("GET client-delivery/items/:id/revisions")
|
|
1407
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1408
|
+
.requiredOption("--item <uuid>", "Item UUID")
|
|
1409
|
+
.action(async (opts) => {
|
|
1410
|
+
const res = await requireClient().clientDeliveryListRevisions(resolveTeamId(opts.team), opts.item);
|
|
1411
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1412
|
+
});
|
|
1413
|
+
clientDelivery
|
|
1414
|
+
.command("get-revision")
|
|
1415
|
+
.description("GET client-delivery/revisions/:id(含 sourceContentHash 作 approve/request-changes 的 CAS 凭证)")
|
|
1416
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1417
|
+
.requiredOption("--revision <uuid>", "Revision UUID")
|
|
1418
|
+
.action(async (opts) => {
|
|
1419
|
+
const res = await requireClient().clientDeliveryGetRevision(resolveTeamId(opts.team), opts.revision);
|
|
1420
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1421
|
+
});
|
|
1422
|
+
clientDelivery
|
|
1423
|
+
.command("list-comments")
|
|
1424
|
+
.description("GET client-delivery/revisions/:id/comments")
|
|
1425
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1426
|
+
.requiredOption("--revision <uuid>", "Revision UUID")
|
|
1427
|
+
.action(async (opts) => {
|
|
1428
|
+
const res = await requireClient().clientDeliveryListComments(resolveTeamId(opts.team), opts.revision);
|
|
1429
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1430
|
+
});
|
|
1431
|
+
clientDelivery
|
|
1432
|
+
.command("list-events")
|
|
1433
|
+
.description("GET client-delivery/revisions/:id/events — 决策事件链")
|
|
1434
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1435
|
+
.requiredOption("--revision <uuid>", "Revision UUID")
|
|
1436
|
+
.action(async (opts) => {
|
|
1437
|
+
const res = await requireClient().clientDeliveryListEvents(resolveTeamId(opts.team), opts.revision);
|
|
1438
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1439
|
+
});
|
|
1440
|
+
clientDelivery
|
|
1441
|
+
.command("approve")
|
|
1442
|
+
.description("POST client-delivery/revisions/:id/approve — 客户批准(CAS;须 user 凭证,api_key 被拒;hash 不符 → 409)")
|
|
1443
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1444
|
+
.requiredOption("--revision <uuid>", "Revision UUID")
|
|
1445
|
+
.requiredOption("--expected-hash <hash>", "expectedRevisionHash(取自 get-revision 的 sourceContentHash;不符 → 409)")
|
|
1446
|
+
.option("--note <text>", "批准备注(可选)")
|
|
1447
|
+
.action(async (opts) => {
|
|
1448
|
+
const body = {
|
|
1449
|
+
expectedRevisionHash: opts.expectedHash,
|
|
1450
|
+
};
|
|
1451
|
+
if (opts.note !== undefined)
|
|
1452
|
+
body.note = opts.note;
|
|
1453
|
+
const res = await requireClient().clientDeliveryApproveRevision(resolveTeamId(opts.team), opts.revision, body);
|
|
1454
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1455
|
+
});
|
|
1456
|
+
clientDelivery
|
|
1457
|
+
.command("request-changes")
|
|
1458
|
+
.description("POST client-delivery/revisions/:id/request-changes — 客户请求修改 + 字段级评论(CAS;须 user 凭证;hash 不符 → 409)")
|
|
1459
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1460
|
+
.requiredOption("--revision <uuid>", "Revision UUID")
|
|
1461
|
+
.option("-j, --json <json>", "{ expectedRevisionHash, comments:[{ fieldKey, quotedText?, body }], note? }。也可 -j @<path> / -j -")
|
|
1462
|
+
.option("--json-file <path>", "从文件读 body JSON(路径,或 -);与 -j 二选一")
|
|
1463
|
+
.action(async (opts) => {
|
|
1464
|
+
const body = readJsonArgOrExit({
|
|
1465
|
+
inline: opts.json,
|
|
1466
|
+
file: opts.jsonFile,
|
|
1467
|
+
});
|
|
1468
|
+
const res = await requireClient().clientDeliveryRequestChanges(resolveTeamId(opts.team), opts.revision, body);
|
|
1469
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1470
|
+
});
|
|
1471
|
+
clientDelivery
|
|
1472
|
+
.command("add-comment")
|
|
1473
|
+
.description("POST client-delivery/revisions/:id/comments — 客户字段级讨论(须 user 凭证)")
|
|
1474
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1475
|
+
.requiredOption("--revision <uuid>", "Revision UUID")
|
|
1476
|
+
.requiredOption("--field-key <key>", "字段定位(如 title/body/price)")
|
|
1477
|
+
.requiredOption("--body <text>", "评论正文")
|
|
1478
|
+
.option("--quoted-text <text>", "引用的原文片段(可选)")
|
|
1479
|
+
.action(async (opts) => {
|
|
1480
|
+
const body = {
|
|
1481
|
+
fieldKey: opts.fieldKey,
|
|
1482
|
+
body: opts.body,
|
|
1483
|
+
};
|
|
1484
|
+
if (opts.quotedText !== undefined)
|
|
1485
|
+
body.quotedText = opts.quotedText;
|
|
1486
|
+
const res = await requireClient().clientDeliveryAddComment(resolveTeamId(opts.team), opts.revision, body);
|
|
1487
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1488
|
+
});
|
|
1489
|
+
clientDelivery
|
|
1490
|
+
.command("resolve-comment")
|
|
1491
|
+
.description("POST client-delivery/comments/:id/resolve — 客户关闭讨论(幂等;须 user 凭证)")
|
|
1492
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1493
|
+
.requiredOption("--comment <uuid>", "Comment UUID")
|
|
1494
|
+
.action(async (opts) => {
|
|
1495
|
+
const res = await requireClient().clientDeliveryResolveComment(resolveTeamId(opts.team), opts.comment);
|
|
1496
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1497
|
+
});
|
|
1498
|
+
clientDelivery
|
|
1499
|
+
.command("create-client-fact-version")
|
|
1500
|
+
.description("POST client-delivery/products/:productId/fact-versions(客户面)— provenance 强制 client(须 user 凭证)")
|
|
1501
|
+
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
1502
|
+
.requiredOption("--product <uuid>", "Product UUID")
|
|
1503
|
+
.option("-j, --json <json>", "{ positioning?, materials?, priceAmount?, priceCurrency?, inventoryStatus?, factsJson?, effectiveAt?, expiresAt?, sourceRef?, ... }")
|
|
1504
|
+
.option("--json-file <path>", "从文件读 body JSON(路径,或 -);与 -j 二选一")
|
|
1505
|
+
.action(async (opts) => {
|
|
1506
|
+
const body = readJsonArgOrExit({
|
|
1507
|
+
inline: opts.json,
|
|
1508
|
+
file: opts.jsonFile,
|
|
1509
|
+
});
|
|
1510
|
+
const res = await requireClient().clientDeliveryCreateClientFactVersion(resolveTeamId(opts.team), opts.product, body);
|
|
1511
|
+
console.log(JSON.stringify(res, null, 2));
|
|
1512
|
+
});
|
|
1211
1513
|
// --- compliance ---
|
|
1212
1514
|
const compliance = program.command("compliance").description("合规 / 风控");
|
|
1213
1515
|
compliance
|