@koda-sl/baker-cli 0.367.0 → 0.369.0
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 +4 -2
- package/dist/cli.js +265 -27
- package/dist/cli.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -943,7 +943,8 @@ baker ads meta creatives create --account-id act_123 --page 555 --instagram-us
|
|
|
943
943
|
baker ads meta ads create --account-id act_123 --name "Ad 1" --adset meta_temp_as --creative meta_temp_cr
|
|
944
944
|
|
|
945
945
|
# review + edit before publish
|
|
946
|
-
baker ads meta draft
|
|
946
|
+
baker ads meta draft # one line per op: ref · kind · summary · after <refs>, then advisories
|
|
947
|
+
baker ads meta draft --json # raw JSON envelope for scripting
|
|
947
948
|
baker ads meta draft show meta_temp_cr # full staged payload — the receipt before publish
|
|
948
949
|
baker ads meta draft remove meta_temp_cr # removing a create cascades to dependents
|
|
949
950
|
baker ads meta draft clear
|
|
@@ -3458,7 +3459,8 @@ baker actions list # default: bucketed (claimable, myCla
|
|
|
3458
3459
|
# then most recent. The `blocked` bucket is ordered closest-to-ready first.
|
|
3459
3460
|
baker actions list --bucketed=false --status pending
|
|
3460
3461
|
baker actions list --bucketed=false --sort priority # flat list, do-first order (default); use --sort recent for newest-first
|
|
3461
|
-
baker actions list --output md # id-first Markdown;
|
|
3462
|
+
baker actions list --output md # id-first Markdown; each bucket's guidance on its heading, blockers/holder under a row; flat rows add a one-line summary
|
|
3463
|
+
baker actions list --full # whole descriptions and full records (large on a real backlog)
|
|
3462
3464
|
baker actions list --search "conversion goal" --output md # find Tasks by words in name/description/tags (flat, best match first)
|
|
3463
3465
|
# With BAKER_CHAT_ID, the bucketed list folds in THIS chat's draft: staged creates appear in
|
|
3464
3466
|
# `draftCreates`; published actions being completed/discarded/updated carry a `draftStatus` marker.
|
package/dist/cli.js
CHANGED
|
@@ -9258,9 +9258,10 @@ var linkCommand = defineCommand7({
|
|
|
9258
9258
|
|
|
9259
9259
|
// src/commands/actions/list.ts
|
|
9260
9260
|
import { defineCommand as defineCommand8 } from "citty";
|
|
9261
|
+
import { Lexer } from "marked";
|
|
9261
9262
|
registerSchema({
|
|
9262
9263
|
command: "actions.list",
|
|
9263
|
-
description: 'List actions for the current company. Default: pre-bucketed (claimable/myClaims/blocked/claimedByOthers/completed/discarded), each bucket ordered do-first (blockers before blocked, then highest-leverage). The bucketed view reads the whole open backlog, so nothing pending is ever hidden from it. Set --bucketed=false for a flat list filterable by --status, orderable by --sort, and windowed by --limit. Looking for one Task by name? --search "conversion goal" --output md returns only the matching Tasks instead of the whole backlog.',
|
|
9264
|
+
description: 'List actions for the current company. Compact by default: a bucketed Task is its id and name (plus its blockers, holder or staged change); a flat row (--search, --bucketed=false) adds status, priority, tags and a one-line `summary` of its description. Checking whether a Task already exists? --search "<words>" returns the matches with their summaries. --full prints whole descriptions (or `baker actions get <id>` for one Task). Default: pre-bucketed (claimable/myClaims/blocked/claimedByOthers/completed/discarded), each bucket ordered do-first (blockers before blocked, then highest-leverage). The bucketed view reads the whole open backlog, so nothing pending is ever hidden from it. Set --bucketed=false for a flat list filterable by --status, orderable by --sort, and windowed by --limit. Looking for one Task by name? --search "conversion goal" --output md returns only the matching Tasks instead of the whole backlog.',
|
|
9264
9265
|
args: {
|
|
9265
9266
|
search: {
|
|
9266
9267
|
type: "string",
|
|
@@ -9288,13 +9289,19 @@ registerSchema({
|
|
|
9288
9289
|
description: `How many Tasks a flat list reads, newest first (only with --bucketed=false). Default: ${ACTIONS_LIST_DEFAULT_LIMIT}. When the read comes back full, hints[] says so \u2014 raise --limit to reach older Tasks.`,
|
|
9289
9290
|
required: false
|
|
9290
9291
|
},
|
|
9292
|
+
full: {
|
|
9293
|
+
type: "boolean",
|
|
9294
|
+
description: "Print every Task's whole description and full record instead of the compact row. Large on a real backlog \u2014 prefer --search, or `baker actions get <id>` for one Task.",
|
|
9295
|
+
required: false,
|
|
9296
|
+
default: false
|
|
9297
|
+
},
|
|
9291
9298
|
output: { type: "string", description: "Output format: json|md. Default: json", required: false }
|
|
9292
9299
|
}
|
|
9293
9300
|
});
|
|
9294
9301
|
var listCommand2 = defineCommand8({
|
|
9295
9302
|
meta: {
|
|
9296
9303
|
name: "list",
|
|
9297
|
-
description: "List actions. Default: bucketed view (claimable, myClaims, blocked, claimedByOthers). Use --bucketed=false for raw filter by --status,
|
|
9304
|
+
description: "List actions, one short row per Task (id and name; --search rows add a one-line summary). Default: bucketed view (claimable, myClaims, blocked, claimedByOthers). Use --bucketed=false for raw filter by --status, --search <text> to find Tasks by name, --full for whole descriptions."
|
|
9298
9305
|
},
|
|
9299
9306
|
args: {
|
|
9300
9307
|
search: { type: "string", description: "Find Tasks by words in name/description/tags", required: false },
|
|
@@ -9302,6 +9309,12 @@ var listCommand2 = defineCommand8({
|
|
|
9302
9309
|
status: { type: "string", description: "Status filter (raw mode)", required: false },
|
|
9303
9310
|
sort: { type: "string", description: "Order (raw mode): priority|recent", required: false },
|
|
9304
9311
|
limit: { type: "string", description: "How many Tasks to read (raw mode)", required: false },
|
|
9312
|
+
full: {
|
|
9313
|
+
type: "boolean",
|
|
9314
|
+
description: "Whole descriptions and full records",
|
|
9315
|
+
required: false,
|
|
9316
|
+
default: false
|
|
9317
|
+
},
|
|
9305
9318
|
output: { type: "string", description: "Output format: json|md", required: false }
|
|
9306
9319
|
},
|
|
9307
9320
|
run: async ({ args: args5 }) => {
|
|
@@ -9309,9 +9322,16 @@ var listCommand2 = defineCommand8({
|
|
|
9309
9322
|
const body = buildListRequest(args5, getEnv().BAKER_CHAT_ID);
|
|
9310
9323
|
const response = await apiPost("/api/actions/list", body);
|
|
9311
9324
|
const hints2 = body.bucketed === false && body.limit !== void 0 && response.ok && Array.isArray(response.data) ? buildListHints({ returned: response.data.length, limit: body.limit }) : [];
|
|
9312
|
-
|
|
9313
|
-
|
|
9314
|
-
|
|
9325
|
+
if (args5.output === "md" && response.ok) {
|
|
9326
|
+
process.stdout.write(renderMarkdown(response.data, hints2, { full: args5.full === true }));
|
|
9327
|
+
return;
|
|
9328
|
+
}
|
|
9329
|
+
const compact3 = !args5.full && response.ok;
|
|
9330
|
+
const shaped = compact3 ? { ...response, data: compactListData(response.data) } : response;
|
|
9331
|
+
const envelope = hints2.length > 0 ? { ...shaped, hints: hints2 } : shaped;
|
|
9332
|
+
if (compact3) {
|
|
9333
|
+
process.stdout.write(`${JSON.stringify(envelope)}
|
|
9334
|
+
`);
|
|
9315
9335
|
return;
|
|
9316
9336
|
}
|
|
9317
9337
|
writeJson(envelope);
|
|
@@ -9341,6 +9361,81 @@ function buildListRequest(args5, chatId) {
|
|
|
9341
9361
|
}
|
|
9342
9362
|
return body;
|
|
9343
9363
|
}
|
|
9364
|
+
var SUMMARY_MAX_CHARS = 100;
|
|
9365
|
+
function plainText(tokens) {
|
|
9366
|
+
return tokens.map((token) => {
|
|
9367
|
+
if (token.type === "image" || token.type === "html") {
|
|
9368
|
+
return "";
|
|
9369
|
+
}
|
|
9370
|
+
if (token.type === "br") {
|
|
9371
|
+
return " ";
|
|
9372
|
+
}
|
|
9373
|
+
if ("tokens" in token && Array.isArray(token.tokens)) {
|
|
9374
|
+
return plainText(token.tokens);
|
|
9375
|
+
}
|
|
9376
|
+
return "text" in token && typeof token.text === "string" ? token.text : "";
|
|
9377
|
+
}).join("");
|
|
9378
|
+
}
|
|
9379
|
+
function firstProse(tokens) {
|
|
9380
|
+
for (const token of tokens) {
|
|
9381
|
+
let text2 = "";
|
|
9382
|
+
if (token.type === "paragraph" || token.type === "text") {
|
|
9383
|
+
text2 = plainText(Array.isArray(token.tokens) ? token.tokens : [token]);
|
|
9384
|
+
} else if (token.type === "list") {
|
|
9385
|
+
text2 = firstProse(token.items.flatMap((item) => item.tokens));
|
|
9386
|
+
} else if (token.type === "blockquote") {
|
|
9387
|
+
text2 = firstProse(token.tokens ?? []);
|
|
9388
|
+
}
|
|
9389
|
+
const line = text2.replace(/\s+/g, " ").trim();
|
|
9390
|
+
if (line) {
|
|
9391
|
+
return line;
|
|
9392
|
+
}
|
|
9393
|
+
}
|
|
9394
|
+
return "";
|
|
9395
|
+
}
|
|
9396
|
+
function summarizeDescription(description) {
|
|
9397
|
+
const line = firstProse(Lexer.lex(description));
|
|
9398
|
+
if (line.length <= SUMMARY_MAX_CHARS) {
|
|
9399
|
+
return line;
|
|
9400
|
+
}
|
|
9401
|
+
const cut = line.slice(0, SUMMARY_MAX_CHARS - 1);
|
|
9402
|
+
const lastSpace = cut.lastIndexOf(" ");
|
|
9403
|
+
return `${(lastSpace > SUMMARY_MAX_CHARS / 2 ? cut.slice(0, lastSpace) : cut).trimEnd()}\u2026`;
|
|
9404
|
+
}
|
|
9405
|
+
function compactBucketEntry(entry) {
|
|
9406
|
+
const { description: _description, status: _status, hint: _hint, ...rest } = entry;
|
|
9407
|
+
return rest;
|
|
9408
|
+
}
|
|
9409
|
+
function compactFlatRow(entry) {
|
|
9410
|
+
const nested = entry.action;
|
|
9411
|
+
const doc = nested && typeof nested === "object" ? nested : entry;
|
|
9412
|
+
const { id, name, status, hint } = toRow(entry);
|
|
9413
|
+
const assignee = entry.assignee && typeof entry.assignee === "object" ? entry.assignee : null;
|
|
9414
|
+
return {
|
|
9415
|
+
id,
|
|
9416
|
+
name,
|
|
9417
|
+
status,
|
|
9418
|
+
...typeof doc.priority === "string" ? { priority: doc.priority } : {},
|
|
9419
|
+
...Array.isArray(doc.tags) && doc.tags.length > 0 ? { tags: doc.tags } : {},
|
|
9420
|
+
summary: summarizeDescription(typeof doc.description === "string" ? doc.description : ""),
|
|
9421
|
+
...hint ? { hint } : {},
|
|
9422
|
+
...typeof assignee?.name === "string" ? { assignee: assignee.name } : {}
|
|
9423
|
+
};
|
|
9424
|
+
}
|
|
9425
|
+
function compactListData(data) {
|
|
9426
|
+
if (Array.isArray(data)) {
|
|
9427
|
+
return data.map((entry) => compactFlatRow(entry));
|
|
9428
|
+
}
|
|
9429
|
+
if (!data || typeof data !== "object") {
|
|
9430
|
+
return data;
|
|
9431
|
+
}
|
|
9432
|
+
return Object.fromEntries(
|
|
9433
|
+
Object.entries(data).map(([bucket, entries]) => [
|
|
9434
|
+
bucket,
|
|
9435
|
+
Array.isArray(entries) ? entries.map((entry) => compactBucketEntry(entry)) : entries
|
|
9436
|
+
])
|
|
9437
|
+
);
|
|
9438
|
+
}
|
|
9344
9439
|
function toRow(entry) {
|
|
9345
9440
|
const nested = entry.action;
|
|
9346
9441
|
const doc = nested && typeof nested === "object" ? nested : entry;
|
|
@@ -9358,35 +9453,69 @@ function toRow(entry) {
|
|
|
9358
9453
|
hint
|
|
9359
9454
|
};
|
|
9360
9455
|
}
|
|
9361
|
-
function renderEntry(entry) {
|
|
9456
|
+
function renderEntry(entry, full) {
|
|
9362
9457
|
const row = toRow(entry);
|
|
9363
9458
|
const suffix = row.status ? ` [${row.status}]` : "";
|
|
9364
9459
|
const lines = [`- \`${row.id}\` ${row.name}${suffix}`];
|
|
9460
|
+
const nested = entry.action;
|
|
9461
|
+
const doc = nested && typeof nested === "object" ? nested : entry;
|
|
9462
|
+
const description = typeof doc.description === "string" ? doc.description : "";
|
|
9463
|
+
const text2 = typeof entry.summary === "string" ? entry.summary : full ? description : summarizeDescription(description);
|
|
9464
|
+
if (typeof text2 === "string" && text2.trim()) {
|
|
9465
|
+
lines.push(
|
|
9466
|
+
...text2.trim().split("\n").map((line) => line ? ` ${line}` : "")
|
|
9467
|
+
);
|
|
9468
|
+
}
|
|
9365
9469
|
if (row.hint) {
|
|
9366
9470
|
lines.push(` ${row.hint}`);
|
|
9367
9471
|
}
|
|
9368
9472
|
return lines;
|
|
9369
9473
|
}
|
|
9370
|
-
function
|
|
9474
|
+
function sharedHint(entries) {
|
|
9475
|
+
const first = entries[0]?.hint;
|
|
9476
|
+
return typeof first === "string" && entries.every((entry) => entry.hint === first) ? first : "";
|
|
9477
|
+
}
|
|
9478
|
+
function renderBucketRow(entry, shared) {
|
|
9479
|
+
const { id, name } = toRow(entry);
|
|
9480
|
+
const suffix = typeof entry.draftStatus === "string" ? ` [${entry.draftStatus}]` : "";
|
|
9481
|
+
const lines = [`- \`${id}\` ${name}${suffix}`];
|
|
9482
|
+
if (typeof entry.hint === "string" && entry.hint && entry.hint !== shared) {
|
|
9483
|
+
lines.push(` ${entry.hint}`);
|
|
9484
|
+
}
|
|
9485
|
+
if (Array.isArray(entry.blockedBy) && entry.blockedBy.length > 0) {
|
|
9486
|
+
const blockers = entry.blockedBy.map((b) => `\`${b.id}\` ${b.name}`);
|
|
9487
|
+
lines.push(` blocked by: ${blockers.join(", ")}`);
|
|
9488
|
+
}
|
|
9489
|
+
const holder = entry.claimedByChat;
|
|
9490
|
+
if (typeof holder?.title === "string") {
|
|
9491
|
+
lines.push(` held by chat: ${holder.title}`);
|
|
9492
|
+
}
|
|
9493
|
+
return lines;
|
|
9494
|
+
}
|
|
9495
|
+
function renderBuckets(data, full) {
|
|
9371
9496
|
const lines = [];
|
|
9372
9497
|
for (const [bucket, entries] of Object.entries(data)) {
|
|
9373
9498
|
if (!Array.isArray(entries) || entries.length === 0) {
|
|
9374
9499
|
continue;
|
|
9375
9500
|
}
|
|
9376
|
-
|
|
9377
|
-
|
|
9378
|
-
lines.push(...renderEntry(entry));
|
|
9501
|
+
const rows = entries;
|
|
9502
|
+
if (full) {
|
|
9503
|
+
lines.push(`## ${bucket} (${rows.length})`, ...rows.flatMap((entry) => renderEntry(entry, true)));
|
|
9504
|
+
} else {
|
|
9505
|
+
const shared = sharedHint(rows);
|
|
9506
|
+
lines.push(`## ${bucket} (${rows.length})${shared ? `: ${shared}` : ""}`);
|
|
9507
|
+
lines.push(...rows.flatMap((entry) => renderBucketRow(entry, shared)));
|
|
9379
9508
|
}
|
|
9380
9509
|
lines.push("");
|
|
9381
9510
|
}
|
|
9382
9511
|
return lines;
|
|
9383
9512
|
}
|
|
9384
|
-
function renderMarkdown(data, hints2) {
|
|
9513
|
+
function renderMarkdown(data, hints2, { full = false } = {}) {
|
|
9385
9514
|
let lines;
|
|
9386
9515
|
if (Array.isArray(data)) {
|
|
9387
|
-
lines = data.flatMap((entry) => renderEntry(entry));
|
|
9516
|
+
lines = data.flatMap((entry) => renderEntry(entry, full));
|
|
9388
9517
|
} else if (data && typeof data === "object") {
|
|
9389
|
-
lines = renderBuckets(data);
|
|
9518
|
+
lines = renderBuckets(data, full);
|
|
9390
9519
|
} else {
|
|
9391
9520
|
lines = [];
|
|
9392
9521
|
}
|
|
@@ -9829,7 +9958,7 @@ import { defineCommand as defineCommand19 } from "citty";
|
|
|
9829
9958
|
function listed(resources) {
|
|
9830
9959
|
return resources.map((resource) => resource.label ? `${resource.id} (${resource.label})` : resource.id).join("; ");
|
|
9831
9960
|
}
|
|
9832
|
-
function connectedResourceHints({ plural, singular, flag, resources }) {
|
|
9961
|
+
function connectedResourceHints({ plural: plural2, singular, flag, resources }) {
|
|
9833
9962
|
if (resources.length === 0) {
|
|
9834
9963
|
return [];
|
|
9835
9964
|
}
|
|
@@ -9837,7 +9966,7 @@ function connectedResourceHints({ plural, singular, flag, resources }) {
|
|
|
9837
9966
|
return [`This company connected one ${singular}: ${listed(resources)}. Commands use it unless you pass ${flag}.`];
|
|
9838
9967
|
}
|
|
9839
9968
|
return [
|
|
9840
|
-
`This company connected ${resources.length} ${
|
|
9969
|
+
`This company connected ${resources.length} ${plural2}: ${listed(resources)}. Each command works on one, so pass ${flag} \u2014 nothing is picked for you. A question about the whole business covers all ${resources.length}: answering from one and reporting it as the total is wrong.`
|
|
9841
9970
|
];
|
|
9842
9971
|
}
|
|
9843
9972
|
|
|
@@ -27041,11 +27170,114 @@ Examples:
|
|
|
27041
27170
|
|
|
27042
27171
|
// src/commands/ads/meta/draft.ts
|
|
27043
27172
|
import { defineCommand as defineCommand65 } from "citty";
|
|
27044
|
-
|
|
27173
|
+
|
|
27174
|
+
// src/commands/ads/meta/draft-status.ts
|
|
27175
|
+
var STATUS_HEADINGS = {
|
|
27176
|
+
active: "staged",
|
|
27177
|
+
publishing: "publishing",
|
|
27178
|
+
applied: "published",
|
|
27179
|
+
partial: "published with failures",
|
|
27180
|
+
discarded: "discarded",
|
|
27181
|
+
none: "none"
|
|
27182
|
+
};
|
|
27183
|
+
function plural(count2, word) {
|
|
27184
|
+
return `${count2} ${word}${count2 === 1 ? "" : "s"}`;
|
|
27185
|
+
}
|
|
27186
|
+
function headingLine(draft) {
|
|
27187
|
+
const heading = STATUS_HEADINGS[draft.status];
|
|
27188
|
+
if (draft.status === "active" || draft.status === "discarded") {
|
|
27189
|
+
return `Meta Ads \u2014 ${plural(draft.count, "change")} ${heading} \xB7 ${draft.mode}`;
|
|
27190
|
+
}
|
|
27191
|
+
const counts = /* @__PURE__ */ new Map();
|
|
27192
|
+
for (const op of draft.ops) {
|
|
27193
|
+
const status = op.result?.status ?? "pending";
|
|
27194
|
+
counts.set(status, (counts.get(status) ?? 0) + 1);
|
|
27195
|
+
}
|
|
27196
|
+
const summary = [...counts].map(([status, count2]) => `${count2} ${status}`).join(", ");
|
|
27197
|
+
return `Meta Ads \u2014 ${heading} \xB7 ${summary} \xB7 ${draft.mode}`;
|
|
27198
|
+
}
|
|
27199
|
+
function resultPart(op) {
|
|
27200
|
+
const result = op.result;
|
|
27201
|
+
if (!result) {
|
|
27202
|
+
return void 0;
|
|
27203
|
+
}
|
|
27204
|
+
if (result.status === "failed") {
|
|
27205
|
+
return `\u2717 failed: ${result.error ?? "no reason recorded"}`;
|
|
27206
|
+
}
|
|
27207
|
+
if (result.status === "skipped") {
|
|
27208
|
+
const because = result.skippedBecause;
|
|
27209
|
+
if (because && op.dependsOn.includes(because)) {
|
|
27210
|
+
return `\u2717 skipped: ${because} did not apply`;
|
|
27211
|
+
}
|
|
27212
|
+
return `\u2717 skipped: ${because ?? "a change it needs did not apply"}`;
|
|
27213
|
+
}
|
|
27214
|
+
const id = result.id ?? result.hash;
|
|
27215
|
+
const applied = `\u2713 ${result.status}${id ? ` \u2192 ${id}` : ""}`;
|
|
27216
|
+
const verification = result.verification;
|
|
27217
|
+
if (verification && verification.status !== "confirmed") {
|
|
27218
|
+
return `${applied} (read-back ${verification.status}${verification.note ? `: ${verification.note}` : ""})`;
|
|
27219
|
+
}
|
|
27220
|
+
return applied;
|
|
27221
|
+
}
|
|
27222
|
+
function opLine(op, showAccount) {
|
|
27223
|
+
const parts = [op.ref, op.kind, op.summary];
|
|
27224
|
+
if (op.target && op.target !== op.ref) {
|
|
27225
|
+
parts.push(`target ${op.target}`);
|
|
27226
|
+
}
|
|
27227
|
+
if (showAccount) {
|
|
27228
|
+
parts.push(`account ${op.accountId}`);
|
|
27229
|
+
}
|
|
27230
|
+
if (op.dependsOn.length > 0) {
|
|
27231
|
+
parts.push(`after ${op.dependsOn.join(", ")}`);
|
|
27232
|
+
}
|
|
27233
|
+
const result = resultPart(op);
|
|
27234
|
+
if (result) {
|
|
27235
|
+
parts.push(result);
|
|
27236
|
+
}
|
|
27237
|
+
return ` ${parts.join(" \xB7 ").replace(/[\r\n]+/g, " ")}`;
|
|
27238
|
+
}
|
|
27239
|
+
function renderDraftStatus3(draft) {
|
|
27240
|
+
if (draft.status === "none" || draft.count === 0) {
|
|
27241
|
+
return "No staged Meta changes on this chat.";
|
|
27242
|
+
}
|
|
27243
|
+
const lines = [headingLine(draft)];
|
|
27244
|
+
if (draft.status === "active") {
|
|
27245
|
+
lines.push("Publishing makes every change real on the ad account.");
|
|
27246
|
+
}
|
|
27247
|
+
lines.push("");
|
|
27248
|
+
const showAccount = new Set(draft.ops.map((op) => op.accountId)).size > 1;
|
|
27249
|
+
for (const op of draft.ops) {
|
|
27250
|
+
lines.push(opLine(op, showAccount));
|
|
27251
|
+
}
|
|
27252
|
+
if (draft.advisories.length > 0) {
|
|
27253
|
+
lines.push("", "Advisories");
|
|
27254
|
+
for (const advisory of draft.advisories) {
|
|
27255
|
+
lines.push(` ! ${advisory.ref}: ${advisory.message}`);
|
|
27256
|
+
}
|
|
27257
|
+
}
|
|
27258
|
+
lines.push("", "Full staged payload for one op: baker ads meta draft show <ref> \xB7 raw envelope: --json");
|
|
27259
|
+
return lines.join("\n");
|
|
27260
|
+
}
|
|
27261
|
+
|
|
27262
|
+
// src/commands/ads/meta/draft.ts
|
|
27263
|
+
registerSchema({
|
|
27264
|
+
command: "ads.meta.draft",
|
|
27265
|
+
description: "Review every Meta op staged on this chat, one line each: ref \xB7 kind \xB7 summary \xB7 what it waits on, and after a publish \u2713 applied \u2192 id or \u2717 failed: <error>. `draft show <ref>` prints one op's full payload.",
|
|
27266
|
+
args: {
|
|
27267
|
+
json: { type: "boolean", description: "Raw JSON envelope instead of the readable list", required: false },
|
|
27268
|
+
chat: { type: "string", description: "Read another chat's draft instead of this one", required: false }
|
|
27269
|
+
}
|
|
27270
|
+
});
|
|
27271
|
+
async function listDraft2(json, chat) {
|
|
27045
27272
|
try {
|
|
27046
27273
|
const chatId = resolveChatId(chat);
|
|
27047
27274
|
const response = await apiPost("/api/ads/meta/draft", { chatId });
|
|
27048
|
-
|
|
27275
|
+
if (json || !response.ok || !response.data) {
|
|
27276
|
+
writeJsonEnvelope(response);
|
|
27277
|
+
return;
|
|
27278
|
+
}
|
|
27279
|
+
process.stdout.write(`${renderDraftStatus3(response.data)}
|
|
27280
|
+
`);
|
|
27049
27281
|
} catch (err) {
|
|
27050
27282
|
handleMetaError(err);
|
|
27051
27283
|
}
|
|
@@ -27053,11 +27285,14 @@ async function listDraft2(chat) {
|
|
|
27053
27285
|
var listCommand10 = defineCommand65({
|
|
27054
27286
|
meta: {
|
|
27055
27287
|
name: "list",
|
|
27056
|
-
description: "Show every Meta write op staged in this chat,
|
|
27288
|
+
description: "Show every Meta write op staged in this chat, one line each (ref \xB7 kind \xB7 summary \xB7 dependencies \xB7 post-publish result); --json for the raw envelope. Publishing reaches the real ad account, so review this before you finish. Example: baker ads meta draft"
|
|
27289
|
+
},
|
|
27290
|
+
args: {
|
|
27291
|
+
json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list" },
|
|
27292
|
+
chat: CHAT_READ_ARG
|
|
27057
27293
|
},
|
|
27058
|
-
args: { chat: CHAT_READ_ARG },
|
|
27059
27294
|
run: async ({ args: args5 }) => {
|
|
27060
|
-
await listDraft2(args5.chat);
|
|
27295
|
+
await listDraft2(args5.json === true, args5.chat);
|
|
27061
27296
|
}
|
|
27062
27297
|
});
|
|
27063
27298
|
var showCommand2 = defineCommand65({
|
|
@@ -27127,7 +27362,10 @@ var metaDraftCommand = defineCommand65({
|
|
|
27127
27362
|
},
|
|
27128
27363
|
// Declared on the parent too: `default: "list"` dispatches the bare `draft --chat <id>` form, and
|
|
27129
27364
|
// citty prints help for a flag the parent does not know instead of forwarding it.
|
|
27130
|
-
args: {
|
|
27365
|
+
args: {
|
|
27366
|
+
json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list" },
|
|
27367
|
+
chat: CHAT_READ_ARG
|
|
27368
|
+
},
|
|
27131
27369
|
subCommands: { list: listCommand10, show: showCommand2, remove: removeCommand3, clear: clearCommand3 },
|
|
27132
27370
|
// `default` (not `run`) dispatches the bare invocation: citty falls through to `run`
|
|
27133
27371
|
// after dispatching a subcommand, so a `run` here would list the draft a second time
|
|
@@ -28940,7 +29178,7 @@ function renderNode3(node, depth, showAccount, out) {
|
|
|
28940
29178
|
}
|
|
28941
29179
|
}
|
|
28942
29180
|
var NO_CHANGES = "No X Ads changes staged";
|
|
28943
|
-
var
|
|
29181
|
+
var STATUS_HEADINGS2 = {
|
|
28944
29182
|
active: "staged",
|
|
28945
29183
|
publishing: "publishing",
|
|
28946
29184
|
applied: "published",
|
|
@@ -28952,8 +29190,8 @@ function didNotApply(op) {
|
|
|
28952
29190
|
function didApply(op) {
|
|
28953
29191
|
return op.result?.status === "applied" || op.result?.status === "simulated";
|
|
28954
29192
|
}
|
|
28955
|
-
function
|
|
28956
|
-
const heading =
|
|
29193
|
+
function headingLine2(draft) {
|
|
29194
|
+
const heading = STATUS_HEADINGS2[draft.status] ?? draft.status;
|
|
28957
29195
|
if (draft.status !== "applied" && draft.status !== "publishing") {
|
|
28958
29196
|
return `X Ads: ${draft.count} change${draft.count === 1 ? "" : "s"} ${heading}`;
|
|
28959
29197
|
}
|
|
@@ -28967,11 +29205,11 @@ function problemLines(draft) {
|
|
|
28967
29205
|
return `\u2717 ${op.summary} \u2014 failed: ${reason}`;
|
|
28968
29206
|
});
|
|
28969
29207
|
}
|
|
28970
|
-
function
|
|
29208
|
+
function renderDraftStatus4(draft) {
|
|
28971
29209
|
if (draft.status === "none" || draft.count === 0) {
|
|
28972
29210
|
return NO_CHANGES;
|
|
28973
29211
|
}
|
|
28974
|
-
const out = [
|
|
29212
|
+
const out = [headingLine2(draft), ""];
|
|
28975
29213
|
const tree = draft.tree ?? [];
|
|
28976
29214
|
const showAccount = accountsInTree3(tree).size > 1;
|
|
28977
29215
|
for (const node of tree) {
|
|
@@ -29009,7 +29247,7 @@ async function listDraft3(json, chat) {
|
|
|
29009
29247
|
writeJsonEnvelope(response);
|
|
29010
29248
|
return;
|
|
29011
29249
|
}
|
|
29012
|
-
process.stdout.write(`${
|
|
29250
|
+
process.stdout.write(`${renderDraftStatus4(response.data)}
|
|
29013
29251
|
`);
|
|
29014
29252
|
} catch (err) {
|
|
29015
29253
|
handleDraftError(err);
|