@koda-sl/baker-cli 0.366.0-dev.9bf895443 → 0.366.0-dev.daafff067

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/dist/cli.js CHANGED
@@ -77,8 +77,9 @@ import {
77
77
  handleMetaError,
78
78
  resolveAccountIdArg,
79
79
  resolveEffectiveStatus,
80
+ statusFilterHints,
80
81
  todayIso
81
- } from "./chunk-BLMXG42J.js";
82
+ } from "./chunk-L4QXAYIC.js";
82
83
  import {
83
84
  buildQueryCacheKey,
84
85
  cacheGet,
@@ -94,7 +95,7 @@ import {
94
95
  writeAdsJson,
95
96
  writeAdsOutput,
96
97
  writeJsonEnvelope
97
- } from "./chunk-A2LM5EDF.js";
98
+ } from "./chunk-FXVELNAS.js";
98
99
  import {
99
100
  ApiError,
100
101
  apiGet,
@@ -9221,9 +9222,10 @@ var linkCommand = defineCommand7({
9221
9222
 
9222
9223
  // src/commands/actions/list.ts
9223
9224
  import { defineCommand as defineCommand8 } from "citty";
9225
+ import { Lexer } from "marked";
9224
9226
  registerSchema({
9225
9227
  command: "actions.list",
9226
- 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.',
9228
+ 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.',
9227
9229
  args: {
9228
9230
  search: {
9229
9231
  type: "string",
@@ -9251,13 +9253,19 @@ registerSchema({
9251
9253
  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.`,
9252
9254
  required: false
9253
9255
  },
9256
+ full: {
9257
+ type: "boolean",
9258
+ 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.",
9259
+ required: false,
9260
+ default: false
9261
+ },
9254
9262
  output: { type: "string", description: "Output format: json|md. Default: json", required: false }
9255
9263
  }
9256
9264
  });
9257
9265
  var listCommand2 = defineCommand8({
9258
9266
  meta: {
9259
9267
  name: "list",
9260
- description: "List actions. Default: bucketed view (claimable, myClaims, blocked, claimedByOthers). Use --bucketed=false for raw filter by --status, or --search <text> to find Tasks by name."
9268
+ 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."
9261
9269
  },
9262
9270
  args: {
9263
9271
  search: { type: "string", description: "Find Tasks by words in name/description/tags", required: false },
@@ -9265,6 +9273,12 @@ var listCommand2 = defineCommand8({
9265
9273
  status: { type: "string", description: "Status filter (raw mode)", required: false },
9266
9274
  sort: { type: "string", description: "Order (raw mode): priority|recent", required: false },
9267
9275
  limit: { type: "string", description: "How many Tasks to read (raw mode)", required: false },
9276
+ full: {
9277
+ type: "boolean",
9278
+ description: "Whole descriptions and full records",
9279
+ required: false,
9280
+ default: false
9281
+ },
9268
9282
  output: { type: "string", description: "Output format: json|md", required: false }
9269
9283
  },
9270
9284
  run: async ({ args: args5 }) => {
@@ -9272,11 +9286,18 @@ var listCommand2 = defineCommand8({
9272
9286
  const body = buildListRequest(args5, getEnv().BAKER_CHAT_ID);
9273
9287
  const response = await apiPost("/api/actions/list", body);
9274
9288
  const hints2 = body.bucketed === false && body.limit !== void 0 && response.ok && Array.isArray(response.data) ? buildListHints({ returned: response.data.length, limit: body.limit }) : [];
9275
- const envelope = hints2.length > 0 ? { ...response, hints: hints2 } : response;
9289
+ const compact3 = !args5.full && response.ok;
9290
+ const shaped = compact3 ? { ...response, data: compactListData(response.data) } : response;
9291
+ const envelope = hints2.length > 0 ? { ...shaped, hints: hints2 } : shaped;
9276
9292
  if (args5.output === "md" && envelope.ok) {
9277
9293
  process.stdout.write(renderMarkdown(envelope.data, hints2));
9278
9294
  return;
9279
9295
  }
9296
+ if (compact3) {
9297
+ process.stdout.write(`${JSON.stringify(envelope)}
9298
+ `);
9299
+ return;
9300
+ }
9280
9301
  writeJson(envelope);
9281
9302
  } catch (err) {
9282
9303
  failApi(err);
@@ -9304,6 +9325,81 @@ function buildListRequest(args5, chatId) {
9304
9325
  }
9305
9326
  return body;
9306
9327
  }
9328
+ var SUMMARY_MAX_CHARS = 100;
9329
+ function plainText(tokens) {
9330
+ return tokens.map((token) => {
9331
+ if (token.type === "image" || token.type === "html") {
9332
+ return "";
9333
+ }
9334
+ if (token.type === "br") {
9335
+ return " ";
9336
+ }
9337
+ if ("tokens" in token && Array.isArray(token.tokens)) {
9338
+ return plainText(token.tokens);
9339
+ }
9340
+ return "text" in token && typeof token.text === "string" ? token.text : "";
9341
+ }).join("");
9342
+ }
9343
+ function firstProse(tokens) {
9344
+ for (const token of tokens) {
9345
+ let text2 = "";
9346
+ if (token.type === "paragraph" || token.type === "text") {
9347
+ text2 = plainText(Array.isArray(token.tokens) ? token.tokens : [token]);
9348
+ } else if (token.type === "list") {
9349
+ text2 = firstProse(token.items.flatMap((item) => item.tokens));
9350
+ } else if (token.type === "blockquote") {
9351
+ text2 = firstProse(token.tokens ?? []);
9352
+ }
9353
+ const line = text2.replace(/\s+/g, " ").trim();
9354
+ if (line) {
9355
+ return line;
9356
+ }
9357
+ }
9358
+ return "";
9359
+ }
9360
+ function summarizeDescription(description) {
9361
+ const line = firstProse(Lexer.lex(description));
9362
+ if (line.length <= SUMMARY_MAX_CHARS) {
9363
+ return line;
9364
+ }
9365
+ const cut = line.slice(0, SUMMARY_MAX_CHARS - 1);
9366
+ const lastSpace = cut.lastIndexOf(" ");
9367
+ return `${(lastSpace > SUMMARY_MAX_CHARS / 2 ? cut.slice(0, lastSpace) : cut).trimEnd()}\u2026`;
9368
+ }
9369
+ function compactBucketEntry(entry) {
9370
+ const { description: _description, status: _status, hint: _hint, ...rest } = entry;
9371
+ return rest;
9372
+ }
9373
+ function compactFlatRow(entry) {
9374
+ const nested = entry.action;
9375
+ const doc = nested && typeof nested === "object" ? nested : entry;
9376
+ const { id, name, status, hint } = toRow(entry);
9377
+ const assignee = entry.assignee && typeof entry.assignee === "object" ? entry.assignee : null;
9378
+ return {
9379
+ id,
9380
+ name,
9381
+ status,
9382
+ ...typeof doc.priority === "string" ? { priority: doc.priority } : {},
9383
+ ...Array.isArray(doc.tags) && doc.tags.length > 0 ? { tags: doc.tags } : {},
9384
+ summary: summarizeDescription(typeof doc.description === "string" ? doc.description : ""),
9385
+ ...hint ? { hint } : {},
9386
+ ...typeof assignee?.name === "string" ? { assignee: assignee.name } : {}
9387
+ };
9388
+ }
9389
+ function compactListData(data) {
9390
+ if (Array.isArray(data)) {
9391
+ return data.map((entry) => compactFlatRow(entry));
9392
+ }
9393
+ if (!data || typeof data !== "object") {
9394
+ return data;
9395
+ }
9396
+ return Object.fromEntries(
9397
+ Object.entries(data).map(([bucket, entries]) => [
9398
+ bucket,
9399
+ Array.isArray(entries) ? entries.map((entry) => compactBucketEntry(entry)) : entries
9400
+ ])
9401
+ );
9402
+ }
9307
9403
  function toRow(entry) {
9308
9404
  const nested = entry.action;
9309
9405
  const doc = nested && typeof nested === "object" ? nested : entry;
@@ -9325,6 +9421,14 @@ function renderEntry(entry) {
9325
9421
  const row = toRow(entry);
9326
9422
  const suffix = row.status ? ` [${row.status}]` : "";
9327
9423
  const lines = [`- \`${row.id}\` ${row.name}${suffix}`];
9424
+ const nested = entry.action;
9425
+ const doc = nested && typeof nested === "object" ? nested : entry;
9426
+ const text2 = typeof entry.summary === "string" ? entry.summary : doc.description;
9427
+ if (typeof text2 === "string" && text2.trim()) {
9428
+ lines.push(
9429
+ ...text2.trim().split("\n").map((line) => line ? ` ${line}` : "")
9430
+ );
9431
+ }
9328
9432
  if (row.hint) {
9329
9433
  lines.push(` ${row.hint}`);
9330
9434
  }
@@ -9792,7 +9896,7 @@ import { defineCommand as defineCommand19 } from "citty";
9792
9896
  function listed(resources) {
9793
9897
  return resources.map((resource) => resource.label ? `${resource.id} (${resource.label})` : resource.id).join("; ");
9794
9898
  }
9795
- function connectedResourceHints({ plural: plural2, singular, flag, resources }) {
9899
+ function connectedResourceHints({ plural, singular, flag, resources }) {
9796
9900
  if (resources.length === 0) {
9797
9901
  return [];
9798
9902
  }
@@ -9800,7 +9904,7 @@ function connectedResourceHints({ plural: plural2, singular, flag, resources })
9800
9904
  return [`This company connected one ${singular}: ${listed(resources)}. Commands use it unless you pass ${flag}.`];
9801
9905
  }
9802
9906
  return [
9803
- `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.`
9907
+ `This company connected ${resources.length} ${plural}: ${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.`
9804
9908
  ];
9805
9909
  }
9806
9910
 
@@ -26381,8 +26485,8 @@ Example: baker ads meta ads retag 120252158038400247 --url-tags "utm_source={{si
26381
26485
  run: async ({ args: args5 }) => {
26382
26486
  const { apiPost: apiPost2 } = await import("./client-3DGBQ2H3.js");
26383
26487
  const { requireChatId: requireChatId2 } = await import("./env-BSG7TY5Y.js");
26384
- const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-M2DBCZFG.js");
26385
- const { handleMetaError: handleMetaError2 } = await import("./shared-BROA3UXS.js");
26488
+ const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-AT5SRVH7.js");
26489
+ const { handleMetaError: handleMetaError2 } = await import("./shared-HZ44PY2F.js");
26386
26490
  try {
26387
26491
  const accountId = bareAccountId2(args5);
26388
26492
  const urlTags = typeof args5["url-tags"] === "string" ? args5["url-tags"] : void 0;
@@ -26529,8 +26633,8 @@ function duplicateCommand2(entity, label) {
26529
26633
  run: async ({ args: args5 }) => {
26530
26634
  const { apiPost: apiPost2 } = await import("./client-3DGBQ2H3.js");
26531
26635
  const { requireChatId: requireChatId2 } = await import("./env-BSG7TY5Y.js");
26532
- const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-M2DBCZFG.js");
26533
- const { handleMetaError: handleMetaError2 } = await import("./shared-BROA3UXS.js");
26636
+ const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-AT5SRVH7.js");
26637
+ const { handleMetaError: handleMetaError2 } = await import("./shared-HZ44PY2F.js");
26534
26638
  try {
26535
26639
  const accountId = bareAccountId2(args5);
26536
26640
  const chatId = requireChatId2();
@@ -26590,12 +26694,7 @@ var listCommand4 = defineCommand58({
26590
26694
  if (args5.limit) params.limit = args5.limit;
26591
26695
  if (args5["no-cache"]) params["skip-cache"] = "true";
26592
26696
  const data = await apiGet("/api/ads/meta/ads", params);
26593
- const fmt = csvOrJson(args5);
26594
- if (fmt !== "json") {
26595
- writeAdsOutput(data, fmt);
26596
- return;
26597
- }
26598
- writeAdsJson({ ok: true, data });
26697
+ writeAdsOutput(data, csvOrJson(args5), void 0, statusFilterHints(data, effectiveStatus, "ads"));
26599
26698
  } catch (err) {
26600
26699
  handleMetaError(err);
26601
26700
  }
@@ -26661,12 +26760,7 @@ var listCommand5 = defineCommand59({
26661
26760
  if (args5.limit) params.limit = args5.limit;
26662
26761
  if (args5["no-cache"]) params["skip-cache"] = "true";
26663
26762
  const data = await apiGet("/api/ads/meta/adsets", params);
26664
- const fmt = csvOrJson(args5);
26665
- if (fmt !== "json") {
26666
- writeAdsOutput(data, fmt);
26667
- return;
26668
- }
26669
- writeAdsJson({ ok: true, data });
26763
+ writeAdsOutput(data, csvOrJson(args5), void 0, statusFilterHints(data, effectiveStatus, "ad sets"));
26670
26764
  } catch (err) {
26671
26765
  handleMetaError(err);
26672
26766
  }
@@ -26811,12 +26905,7 @@ var listCommand7 = defineCommand62({
26811
26905
  if (args5.limit) params.limit = args5.limit;
26812
26906
  if (args5["no-cache"]) params["skip-cache"] = "true";
26813
26907
  const data = await apiGet("/api/ads/meta/campaigns", params);
26814
- const fmt = csvOrJson(args5);
26815
- if (fmt !== "json") {
26816
- writeAdsOutput(data, fmt);
26817
- return;
26818
- }
26819
- writeAdsJson({ ok: true, data });
26908
+ writeAdsOutput(data, csvOrJson(args5), void 0, statusFilterHints(data, effectiveStatus, "campaigns"));
26820
26909
  } catch (err) {
26821
26910
  handleMetaError(err);
26822
26911
  }
@@ -27019,114 +27108,11 @@ Examples:
27019
27108
 
27020
27109
  // src/commands/ads/meta/draft.ts
27021
27110
  import { defineCommand as defineCommand65 } from "citty";
27022
-
27023
- // src/commands/ads/meta/draft-status.ts
27024
- var STATUS_HEADINGS = {
27025
- active: "staged",
27026
- publishing: "publishing",
27027
- applied: "published",
27028
- partial: "published with failures",
27029
- discarded: "discarded",
27030
- none: "none"
27031
- };
27032
- function plural(count2, word) {
27033
- return `${count2} ${word}${count2 === 1 ? "" : "s"}`;
27034
- }
27035
- function headingLine(draft) {
27036
- const heading = STATUS_HEADINGS[draft.status];
27037
- if (draft.status === "active" || draft.status === "discarded") {
27038
- return `Meta Ads \u2014 ${plural(draft.count, "change")} ${heading} \xB7 ${draft.mode}`;
27039
- }
27040
- const counts = /* @__PURE__ */ new Map();
27041
- for (const op of draft.ops) {
27042
- const status = op.result?.status ?? "pending";
27043
- counts.set(status, (counts.get(status) ?? 0) + 1);
27044
- }
27045
- const summary = [...counts].map(([status, count2]) => `${count2} ${status}`).join(", ");
27046
- return `Meta Ads \u2014 ${heading} \xB7 ${summary} \xB7 ${draft.mode}`;
27047
- }
27048
- function resultPart(op) {
27049
- const result = op.result;
27050
- if (!result) {
27051
- return void 0;
27052
- }
27053
- if (result.status === "failed") {
27054
- return `\u2717 failed: ${result.error ?? "no reason recorded"}`;
27055
- }
27056
- if (result.status === "skipped") {
27057
- const because = result.skippedBecause;
27058
- if (because && op.dependsOn.includes(because)) {
27059
- return `\u2717 skipped: ${because} did not apply`;
27060
- }
27061
- return `\u2717 skipped: ${because ?? "a change it needs did not apply"}`;
27062
- }
27063
- const id = result.id ?? result.hash;
27064
- const applied = `\u2713 ${result.status}${id ? ` \u2192 ${id}` : ""}`;
27065
- const verification = result.verification;
27066
- if (verification && verification.status !== "confirmed") {
27067
- return `${applied} (read-back ${verification.status}${verification.note ? `: ${verification.note}` : ""})`;
27068
- }
27069
- return applied;
27070
- }
27071
- function opLine(op, showAccount) {
27072
- const parts = [op.ref, op.kind, op.summary];
27073
- if (op.target && op.target !== op.ref) {
27074
- parts.push(`target ${op.target}`);
27075
- }
27076
- if (showAccount) {
27077
- parts.push(`account ${op.accountId}`);
27078
- }
27079
- if (op.dependsOn.length > 0) {
27080
- parts.push(`after ${op.dependsOn.join(", ")}`);
27081
- }
27082
- const result = resultPart(op);
27083
- if (result) {
27084
- parts.push(result);
27085
- }
27086
- return ` ${parts.join(" \xB7 ").replace(/[\r\n]+/g, " ")}`;
27087
- }
27088
- function renderDraftStatus3(draft) {
27089
- if (draft.status === "none" || draft.count === 0) {
27090
- return "No staged Meta changes on this chat.";
27091
- }
27092
- const lines = [headingLine(draft)];
27093
- if (draft.status === "active") {
27094
- lines.push("Publishing makes every change real on the ad account.");
27095
- }
27096
- lines.push("");
27097
- const showAccount = new Set(draft.ops.map((op) => op.accountId)).size > 1;
27098
- for (const op of draft.ops) {
27099
- lines.push(opLine(op, showAccount));
27100
- }
27101
- if (draft.advisories.length > 0) {
27102
- lines.push("", "Advisories");
27103
- for (const advisory of draft.advisories) {
27104
- lines.push(` ! ${advisory.ref}: ${advisory.message}`);
27105
- }
27106
- }
27107
- lines.push("", "Full staged payload for one op: baker ads meta draft show <ref> \xB7 raw envelope: --json");
27108
- return lines.join("\n");
27109
- }
27110
-
27111
- // src/commands/ads/meta/draft.ts
27112
- registerSchema({
27113
- command: "ads.meta.draft",
27114
- 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.",
27115
- args: {
27116
- json: { type: "boolean", description: "Raw JSON envelope instead of the readable list", required: false },
27117
- chat: { type: "string", description: "Read another chat's draft instead of this one", required: false }
27118
- }
27119
- });
27120
- async function listDraft2(json, chat) {
27111
+ async function listDraft2(chat) {
27121
27112
  try {
27122
27113
  const chatId = resolveChatId(chat);
27123
27114
  const response = await apiPost("/api/ads/meta/draft", { chatId });
27124
- if (json || !response.ok || !response.data) {
27125
- writeJsonEnvelope(response);
27126
- return;
27127
- }
27128
- process.stdout.write(`${renderDraftStatus3(response.data)}
27129
- `);
27115
+ writeJsonEnvelope(response);
27130
27116
  } catch (err) {
27131
27117
  handleMetaError(err);
27132
27118
  }
@@ -27134,14 +27120,11 @@ async function listDraft2(json, chat) {
27134
27120
  var listCommand10 = defineCommand65({
27135
27121
  meta: {
27136
27122
  name: "list",
27137
- 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"
27138
- },
27139
- args: {
27140
- json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list" },
27141
- chat: CHAT_READ_ARG
27123
+ description: "Show every Meta write op staged in this chat, its dependencies, and post-publish results. Publishing reaches the real ad account, so review this before you finish. Example: baker ads meta draft"
27142
27124
  },
27125
+ args: { chat: CHAT_READ_ARG },
27143
27126
  run: async ({ args: args5 }) => {
27144
- await listDraft2(args5.json === true, args5.chat);
27127
+ await listDraft2(args5.chat);
27145
27128
  }
27146
27129
  });
27147
27130
  var showCommand2 = defineCommand65({
@@ -27211,10 +27194,7 @@ var metaDraftCommand = defineCommand65({
27211
27194
  },
27212
27195
  // Declared on the parent too: `default: "list"` dispatches the bare `draft --chat <id>` form, and
27213
27196
  // citty prints help for a flag the parent does not know instead of forwarding it.
27214
- args: {
27215
- json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list" },
27216
- chat: CHAT_READ_ARG
27217
- },
27197
+ args: { chat: CHAT_READ_ARG },
27218
27198
  subCommands: { list: listCommand10, show: showCommand2, remove: removeCommand3, clear: clearCommand3 },
27219
27199
  // `default` (not `run`) dispatches the bare invocation: citty falls through to `run`
27220
27200
  // after dispatching a subcommand, so a `run` here would list the draft a second time
@@ -29027,7 +29007,7 @@ function renderNode3(node, depth, showAccount, out) {
29027
29007
  }
29028
29008
  }
29029
29009
  var NO_CHANGES = "No X Ads changes staged";
29030
- var STATUS_HEADINGS2 = {
29010
+ var STATUS_HEADINGS = {
29031
29011
  active: "staged",
29032
29012
  publishing: "publishing",
29033
29013
  applied: "published",
@@ -29039,8 +29019,8 @@ function didNotApply(op) {
29039
29019
  function didApply(op) {
29040
29020
  return op.result?.status === "applied" || op.result?.status === "simulated";
29041
29021
  }
29042
- function headingLine2(draft) {
29043
- const heading = STATUS_HEADINGS2[draft.status] ?? draft.status;
29022
+ function headingLine(draft) {
29023
+ const heading = STATUS_HEADINGS[draft.status] ?? draft.status;
29044
29024
  if (draft.status !== "applied" && draft.status !== "publishing") {
29045
29025
  return `X Ads: ${draft.count} change${draft.count === 1 ? "" : "s"} ${heading}`;
29046
29026
  }
@@ -29054,11 +29034,11 @@ function problemLines(draft) {
29054
29034
  return `\u2717 ${op.summary} \u2014 failed: ${reason}`;
29055
29035
  });
29056
29036
  }
29057
- function renderDraftStatus4(draft) {
29037
+ function renderDraftStatus3(draft) {
29058
29038
  if (draft.status === "none" || draft.count === 0) {
29059
29039
  return NO_CHANGES;
29060
29040
  }
29061
- const out = [headingLine2(draft), ""];
29041
+ const out = [headingLine(draft), ""];
29062
29042
  const tree = draft.tree ?? [];
29063
29043
  const showAccount = accountsInTree3(tree).size > 1;
29064
29044
  for (const node of tree) {
@@ -29096,7 +29076,7 @@ async function listDraft3(json, chat) {
29096
29076
  writeJsonEnvelope(response);
29097
29077
  return;
29098
29078
  }
29099
- process.stdout.write(`${renderDraftStatus4(response.data)}
29079
+ process.stdout.write(`${renderDraftStatus3(response.data)}
29100
29080
  `);
29101
29081
  } catch (err) {
29102
29082
  handleDraftError(err);