@datarails-ai/dr-cli 1.6.113 → 1.6.114

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
@@ -8,7 +8,7 @@ import { fileURLToPath as fileURLToPath3 } from "url";
8
8
  // package.json
9
9
  var package_default = {
10
10
  name: "@datarails-ai/dr-cli",
11
- version: "1.6.113",
11
+ version: "1.6.114",
12
12
  description: "Datarails CLI",
13
13
  type: "module",
14
14
  engines: {
@@ -69,7 +69,7 @@ var package_default = {
69
69
  };
70
70
 
71
71
  // src/buildInfo.ts
72
- var BUILD_TIME = "2026-10-09T10:02:15.002Z";
72
+ var BUILD_TIME = "2026-10-09T16:30:45.883Z";
73
73
  function formatBuildTime(iso) {
74
74
  if (iso === "") return "";
75
75
  const d = new Date(iso);
@@ -3863,7 +3863,10 @@ var PROD_GATE_TIER_B = /* @__PURE__ */ new Set([
3863
3863
  // org export cleanup (dr organizations export delete). Removes the export's
3864
3864
  // server-side record + blob folder — migration ARTIFACTS only; no org data
3865
3865
  // is touched, and the state is recoverable by re-running the export.
3866
- "org-export|delete"
3866
+ "org-export|delete",
3867
+ // connectors poll item skip (dr connectors poll skip). The item is never landed,
3868
+ // but `dr connectors poll retry` queues it again, so the token alone is enough.
3869
+ "connector-poll-item|skip"
3867
3870
  ]);
3868
3871
  var PROD_GATE_TIER_A = /* @__PURE__ */ new Set([
3869
3872
  // workflow / mec — soft-delete + cascade deletes. `archive` also covers the
@@ -3998,7 +4001,15 @@ var PROD_GATE_TIER_A = /* @__PURE__ */ new Set([
3998
4001
  // imported-org delete (dr organizations import delete-orgs) — PERMANENTLY
3999
4002
  // deletes whole organizations via the org-delete chord. The single most
4000
4003
  // destructive verb in the CLI; the word gate stays on prod unconditionally.
4001
- "org-import|delete-orgs"
4004
+ "org-import|delete-orgs",
4005
+ // connectors polled ingestion (dr connectors poll seed / set / resume --source land).
4006
+ // A seed marks items landed so they never land; `set` is gated (as `set-land-or-seed`)
4007
+ // only when it lands a wider window or seeds / lands on a change-policy switch;
4008
+ // `resume --source land` lands everything a changed source holds. Versions landed in
4009
+ // a customer filebox, or files hidden from it, cannot be taken back from the CLI.
4010
+ "connector-poll|seed",
4011
+ "connector-poll|set-land-or-seed",
4012
+ "connector-poll|resume-land"
4002
4013
  ]);
4003
4014
  function classifyTier(action) {
4004
4015
  const key = `${action.resource}|${action.verb}`;
@@ -19023,6 +19034,14 @@ async function setVersionAutoSave(client, versionId, autoSave, reqOptions) {
19023
19034
  reqOptions
19024
19035
  );
19025
19036
  }
19037
+ async function setVersionNameLabel(client, versionId, label, reqOptions) {
19038
+ return client.do(
19039
+ "PUT",
19040
+ `/api/documents/versions/${versionId}/name`,
19041
+ JSON.stringify({ label }),
19042
+ reqOptions
19043
+ );
19044
+ }
19026
19045
  async function setVersionIncludeFile(client, versionId, includeFile, reqOptions) {
19027
19046
  return client.do(
19028
19047
  "PUT",
@@ -35947,7 +35966,10 @@ async function runFileboxVersions(cfg) {
35947
35966
  writeJSONIndented(cfg.out, selected);
35948
35967
  return;
35949
35968
  }
35950
- renderFileboxVersionsTable(cfg.out, selected, includeArchived, wantIncluded);
35969
+ const forTable = selected.map(
35970
+ (v) => typeof v.label === "string" ? { ...v, label: decodeHtmlEntitiesDeep(v.label) } : v
35971
+ );
35972
+ renderFileboxVersionsTable(cfg.out, forTable, includeArchived, wantIncluded);
35951
35973
  }
35952
35974
  async function runFileboxTags(cfg) {
35953
35975
  const tags = await listTags(cfg.client, { signal: cfg.signal });
@@ -36214,6 +36236,9 @@ async function runFileboxUploadVersion(cfg) {
36214
36236
  "--date and --scenario must be used together (planning fileboxes set both at once)"
36215
36237
  );
36216
36238
  }
36239
+ if (cfg.label !== void 0) {
36240
+ validateVersionLabel(cfg.label);
36241
+ }
36217
36242
  let blob;
36218
36243
  try {
36219
36244
  blob = await fileToBlob(cfg.filePath);
@@ -36314,6 +36339,26 @@ async function runFileboxUploadVersion(cfg) {
36314
36339
  throw new Error(confirmation.failure);
36315
36340
  }
36316
36341
  }
36342
+ let appliedLabel = null;
36343
+ let labelFailed = false;
36344
+ let labelFailure;
36345
+ if (cfg.label !== void 0) {
36346
+ if (id <= 0) {
36347
+ throw new Error(
36348
+ `uploaded, but could not read the new version id from the response to label it \u2014 set the label with \`dr filebox set-version-label\`. Server response: ${JSON.stringify(result)}`
36349
+ );
36350
+ }
36351
+ try {
36352
+ appliedLabel = await writeVersionLabel(cfg.client, id, cfg.label, cfg.signal);
36353
+ } catch (err) {
36354
+ labelFailed = true;
36355
+ labelFailure = err;
36356
+ }
36357
+ }
36358
+ const labelJSON = cfg.label === void 0 ? {} : labelFailed ? {
36359
+ label_error: labelFailure instanceof Error ? labelFailure.message : String(labelFailure)
36360
+ } : { label: appliedLabel };
36361
+ const errStream = cfg.err ?? process.stderr;
36317
36362
  if (cfg.asJson) {
36318
36363
  if (prepared !== void 0) {
36319
36364
  writeJSONIndented(cfg.out, {
@@ -36324,11 +36369,15 @@ async function runFileboxUploadVersion(cfg) {
36324
36369
  cycle_tag_id: prepared.cycleTagId,
36325
36370
  date: prepared.cycleDate,
36326
36371
  scenario: cfg.scenario,
36372
+ ...labelJSON,
36327
36373
  ...cycleTagVerdictJSON(confirmation)
36328
36374
  });
36329
- return;
36375
+ } else if (cfg.label !== void 0) {
36376
+ cfg.out.write(JSON.stringify({ ...asRecord2(result), ...labelJSON }) + "\n");
36377
+ } else {
36378
+ cfg.out.write(JSON.stringify(result) + "\n");
36330
36379
  }
36331
- cfg.out.write(JSON.stringify(result) + "\n");
36380
+ if (labelFailed) throw uploadLabelFailure(id, labelFailure, errStream);
36332
36381
  return;
36333
36382
  }
36334
36383
  if (renamed !== null) {
@@ -36355,6 +36404,26 @@ ${JSON.stringify(result)}
36355
36404
  `
36356
36405
  );
36357
36406
  }
36407
+ if (labelFailed) throw uploadLabelFailure(id, labelFailure, errStream);
36408
+ if (cfg.label !== void 0) {
36409
+ cfg.out.write(`Set label on version ${id}: ${JSON.stringify(appliedLabel)}.
36410
+ `);
36411
+ }
36412
+ }
36413
+ function uploadLabelFailure(versionId, err, errStream) {
36414
+ const retry = `retry with \`dr filebox set-version-label ${versionId} --label <text>\``;
36415
+ if (isTypedError(err)) {
36416
+ errStream.write(`uploaded version ${versionId}, but setting its label failed \u2014 ${retry}
36417
+ `);
36418
+ return err;
36419
+ }
36420
+ const msg = err instanceof Error ? err.message : String(err);
36421
+ return new Error(
36422
+ `uploaded version ${versionId}, but setting its label failed: ${msg} \u2014 ${retry}`,
36423
+ {
36424
+ cause: err
36425
+ }
36426
+ );
36358
36427
  }
36359
36428
  async function runFileboxUpdate(cfg) {
36360
36429
  if (cfg.id <= 0) {
@@ -36903,6 +36972,12 @@ async function resolveVersionByNumber(client, docId, target, signal) {
36903
36972
  }
36904
36973
  if (target.number === void 0) {
36905
36974
  const latest = pool.reduce((a, b) => b.version > a.version ? b : a);
36975
+ const tied = pool.filter((v) => v.version === latest.version);
36976
+ if (target.refuseTiedLatest === true && tied.length > 1) {
36977
+ throw new Error(
36978
+ `ambiguous latest: ${tied.length} ${setLabel} versions of filebox ${docId} share version number ${latest.version} (ids ${tied.map((v) => v.id).join(", ")}); pass the global version id instead`
36979
+ );
36980
+ }
36906
36981
  return { id: latest.id, version: latest.version };
36907
36982
  }
36908
36983
  const matches = pool.filter((v) => v.version === target.number);
@@ -36970,6 +37045,116 @@ async function runFileboxSetVersionDateTag(cfg) {
36970
37045
  const body = await res.text();
36971
37046
  throw new Error(`set version date-tag refused (HTTP ${res.status}): ${body.trim()}`);
36972
37047
  }
37048
+ var VERSION_LABEL_MAX = 256;
37049
+ var RESERVED_VERSION_LABEL = "auto-calculated";
37050
+ var CONTROL_CHARS = /[\u0000-\u001f\u007f-\u009f]/g;
37051
+ function validateVersionLabel(label) {
37052
+ if (label.trim() === "") {
37053
+ throw new Error("--label must not be empty \u2014 use --clear to remove a label");
37054
+ }
37055
+ if (new RegExp(CONTROL_CHARS.source).test(label)) {
37056
+ throw new Error("--label must not contain control characters (newlines, tabs and the like)");
37057
+ }
37058
+ if (label.trim().toLowerCase() === RESERVED_VERSION_LABEL) {
37059
+ throw new Error(
37060
+ `--label "${RESERVED_VERSION_LABEL}" is reserved: the server uses it to mark versions it generated itself, which scanning can skip and archiving can move to cold storage`
37061
+ );
37062
+ }
37063
+ const length = [...label].length;
37064
+ if (length > VERSION_LABEL_MAX) {
37065
+ throw new Error(`--label must be at most ${VERSION_LABEL_MAX} characters (got ${length})`);
37066
+ }
37067
+ return label;
37068
+ }
37069
+ function renderVersionLabelCell(label) {
37070
+ if (label === null || label === void 0) return "";
37071
+ return label.replace(CONTROL_CHARS, (c) => {
37072
+ if (c === "\n") return "\\n";
37073
+ if (c === "\r") return "\\r";
37074
+ if (c === " ") return "\\t";
37075
+ return `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`;
37076
+ });
37077
+ }
37078
+ function parseVersionLabelFlags(label, clear) {
37079
+ if (label !== void 0 && clear) {
37080
+ throw new Error("pass either --label <text> or --clear, not both");
37081
+ }
37082
+ if (clear) return null;
37083
+ if (label === void 0) {
37084
+ throw new Error("one of --label <text> or --clear is required");
37085
+ }
37086
+ return validateVersionLabel(label);
37087
+ }
37088
+ function isTypedError(err) {
37089
+ return !(err instanceof Error) || err.constructor !== Error || "code" in err;
37090
+ }
37091
+ async function writeVersionLabel(client, versionId, label, signal) {
37092
+ const res = await setVersionNameLabel(client, versionId, label, { signal });
37093
+ if (res.status < 200 || res.status >= 300) {
37094
+ const body = (await res.text()).trim();
37095
+ const detail = body === "" && res.status === 405 ? "no permission \u2014 changing a version's label needs change rights on the filebox, or to be the user who uploaded the version" : body;
37096
+ throw new Error(
37097
+ `${label === null ? "clear" : "set"} version label refused (HTTP ${res.status}): ${detail}`
37098
+ );
37099
+ }
37100
+ let readBack;
37101
+ try {
37102
+ readBack = await getVersion(client, versionId, { signal });
37103
+ } catch (err) {
37104
+ if (isTypedError(err)) throw err;
37105
+ const msg = err instanceof Error ? err.message : String(err);
37106
+ throw new Error(`label written to version ${versionId}, but reading it back failed: ${msg}`, {
37107
+ cause: err
37108
+ });
37109
+ }
37110
+ const stored = readBack.label === null || readBack.label === void 0 ? null : decodeHtmlEntitiesDeep(readBack.label);
37111
+ const expected = label === null ? null : label.trim();
37112
+ const matches = expected === null ? stored === null || stored === "" : stored === expected;
37113
+ if (!matches) {
37114
+ throw new Error(
37115
+ `the server accepted the label for version ${versionId} but reports ${JSON.stringify(stored)} on read-back, not ${JSON.stringify(expected)}`
37116
+ );
37117
+ }
37118
+ return expected === null ? null : stored;
37119
+ }
37120
+ async function runFileboxSetVersionLabel(cfg) {
37121
+ if (cfg.versionId <= 0) {
37122
+ throw new Error("version id must be positive");
37123
+ }
37124
+ let current;
37125
+ try {
37126
+ current = decodeHtmlEntitiesDeep(
37127
+ await getVersion(cfg.client, cfg.versionId, { signal: cfg.signal })
37128
+ );
37129
+ } catch (err) {
37130
+ if (isTypedError(err)) throw err;
37131
+ const msg = err instanceof Error ? err.message : String(err);
37132
+ if (/HTTP 404\b/.test(msg)) {
37133
+ throw new Error(
37134
+ `version ${cfg.versionId} not found \u2014 label not changed (find the id with \`dr filebox versions <doc_id>\`)`,
37135
+ { cause: err }
37136
+ );
37137
+ }
37138
+ throw new Error(`load version ${cfg.versionId}: ${msg} \u2014 label not changed`, { cause: err });
37139
+ }
37140
+ const stored = await writeVersionLabel(cfg.client, cfg.versionId, cfg.label, cfg.signal);
37141
+ if (cfg.asJson) {
37142
+ writeJSONIndented(cfg.out, {
37143
+ version_id: cfg.versionId,
37144
+ doc_id: current.document,
37145
+ version: current.version,
37146
+ label: stored,
37147
+ previous_label: current.label ?? null
37148
+ });
37149
+ return;
37150
+ }
37151
+ const target = versionLabel(cfg.versionId, current.version);
37152
+ cfg.out.write(
37153
+ stored === null ? `Cleared label on ${target}.
37154
+ ` : `Set label on ${target}: ${JSON.stringify(stored)}.
37155
+ `
37156
+ );
37157
+ }
36973
37158
  var WORKFLOW_STATUSES = [
36974
37159
  "Not Started",
36975
37160
  "In Progress",
@@ -38248,7 +38433,7 @@ function renderFileboxVersionsTable(out, versions, showArchived = false, showInc
38248
38433
  out.write("(no versions)\n");
38249
38434
  return;
38250
38435
  }
38251
- const header = ["VERSION_ID", "VERSION", "NAME", "STATUS", "DOC_ID", "CREATED"];
38436
+ const header = ["VERSION_ID", "VERSION", "NAME", "LABEL", "STATUS", "DOC_ID", "CREATED"];
38252
38437
  if (showArchived) header.push("ARCHIVED");
38253
38438
  if (showIncluded) header.push("INCLUDED");
38254
38439
  const rows = [{ cells: header }];
@@ -38257,6 +38442,7 @@ function renderFileboxVersionsTable(out, versions, showArchived = false, showInc
38257
38442
  String(v.id),
38258
38443
  String(v.version),
38259
38444
  v.name,
38445
+ renderVersionLabelCell(v.label),
38260
38446
  v.status,
38261
38447
  String(v.document),
38262
38448
  renderCreateTime(v.create_time)
@@ -38527,6 +38713,9 @@ function registerFileboxCommand(root) {
38527
38713
  "--scenario <name>",
38528
38714
  "Forecast/budget filebox: scenario/cycle name (must already exist). Use with --date."
38529
38715
  ).option("--date-tag-name <name>", "Date tag to use when the filebox has more than one DATE tag").option(
38716
+ "--label <text>",
38717
+ "Label the new version right after the upload (same as `set-version-label --label`)"
38718
+ ).option(
38530
38719
  "--no-reconcile",
38531
38720
  `Upload under the file's literal name without correcting its extension to the byte content. Use only when you intend a wrong-but-deliberate name; the server may then reject it with HTTP 400 "Invalid file signature".`
38532
38721
  ).option("--json", "Output raw JSON instead of a summary", false).action(
@@ -38543,6 +38732,7 @@ function registerFileboxCommand(root) {
38543
38732
  ...opts.date !== void 0 ? { dateInput: opts.date } : {},
38544
38733
  ...opts.scenario !== void 0 ? { scenario: opts.scenario } : {},
38545
38734
  ...opts.dateTagName !== void 0 ? { dateTagName: opts.dateTagName } : {},
38735
+ ...opts.label !== void 0 ? { label: opts.label } : {},
38546
38736
  reconcile: opts.reconcile !== false,
38547
38737
  asJson: opts.json === true,
38548
38738
  signal: setup.signal,
@@ -38881,6 +39071,46 @@ function registerFileboxCommand(root) {
38881
39071
  );
38882
39072
  addServerFlag(setVersionDateTagCmd);
38883
39073
  addAccountFlag(setVersionDateTagCmd);
39074
+ const setVersionLabelCmd = fb.command("set-version-label").description(
39075
+ "Set or clear a filebox version's label (date and dimension tags are left unchanged). Address it by global version id, or by --doc with --version-number/--latest-active."
39076
+ ).argument(
39077
+ "[version_id]",
39078
+ "document version id (global). Omit to address by --doc + --version-number/--latest-active."
39079
+ ).option("--label <text>", "the new label (at most 256 characters)").option("--clear", "remove the label", false).option("--doc <doc_id>", "filebox id \u2014 resolve the version within this filebox").option("--version-number <n>", "per-filebox version number to label (requires --doc)").option("--latest-active", "label the latest active version of --doc (requires --doc)", false).option(
39080
+ "--json",
39081
+ "Output a JSON record (version_id, doc_id, version, label, previous_label)",
39082
+ false
39083
+ ).action(
39084
+ async (idStr, opts) => {
39085
+ const label = parseVersionLabelFlags(opts.label, opts.clear === true);
39086
+ const addressing = parseVersionAddressing(
39087
+ idStr,
39088
+ { doc: opts.doc, versionNumber: opts.versionNumber, latest: opts.latestActive },
39089
+ "--latest-active"
39090
+ );
39091
+ const setup = await setupCall(opts.server, opts.account);
39092
+ try {
39093
+ const versionId = addressing.mode === "direct" ? addressing.versionId : (await resolveVersionByNumber(
39094
+ setup.client,
39095
+ addressing.docId,
39096
+ { number: addressing.number, from: "active", refuseTiedLatest: true },
39097
+ setup.signal
39098
+ )).id;
39099
+ await runFileboxSetVersionLabel({
39100
+ client: setup.client,
39101
+ versionId,
39102
+ label,
39103
+ asJson: opts.json === true,
39104
+ signal: setup.signal,
39105
+ out: process.stdout
39106
+ });
39107
+ } finally {
39108
+ setup.cleanup();
39109
+ }
39110
+ }
39111
+ );
39112
+ addServerFlag(setVersionLabelCmd);
39113
+ addAccountFlag(setVersionLabelCmd);
38884
39114
  const setVersionWorkflowCmd = fb.command("set-version-workflow").description(
38885
39115
  "Set the WORKFLOW tag value on a single document version (Approve / Reject / move to In Progress / etc.)"
38886
39116
  ).argument("<version_id>", "document version id (positive integer)").requiredOption(
@@ -40928,6 +41158,82 @@ async function cancelSync(client, fileboxUuid, target = {}, reqOptions) {
40928
41158
  }
40929
41159
  return out;
40930
41160
  }
41161
+ async function getPoll(client, queryId, reqOptions) {
41162
+ const path12 = `/connector-queries/${queryId}/poll`;
41163
+ let out;
41164
+ try {
41165
+ out = await client.getJSON(path12, reqOptions);
41166
+ } catch (err) {
41167
+ throw toControlPlaneError("GET", path12, err);
41168
+ }
41169
+ if (out === null) {
41170
+ throw new Error(`GET ${path12}: empty response from control-plane poll get`);
41171
+ }
41172
+ return out;
41173
+ }
41174
+ async function putPoll(client, queryId, fields, reqOptions) {
41175
+ const path12 = `/connector-queries/${queryId}/poll`;
41176
+ let out;
41177
+ try {
41178
+ out = await client.putJSON(path12, fields, reqOptions);
41179
+ } catch (err) {
41180
+ throw toControlPlaneError("PUT", path12, err);
41181
+ }
41182
+ if (out === null) {
41183
+ throw new Error(`PUT ${path12}: empty response from control-plane poll set`);
41184
+ }
41185
+ return out;
41186
+ }
41187
+ async function postPollJSON(client, path12, body, what, reqOptions) {
41188
+ let out;
41189
+ try {
41190
+ out = await client.postJSON(path12, body, reqOptions);
41191
+ } catch (err) {
41192
+ throw toControlPlaneError("POST", path12, err);
41193
+ }
41194
+ if (out === null) {
41195
+ throw new Error(`POST ${path12}: empty response from control-plane ${what}`);
41196
+ }
41197
+ return out;
41198
+ }
41199
+ async function runPoll(client, queryId, reqOptions) {
41200
+ const path12 = `/connector-queries/${queryId}/poll/run`;
41201
+ return postPollJSON(client, path12, {}, "poll run", reqOptions);
41202
+ }
41203
+ async function seedPoll(client, queryId, body, reqOptions) {
41204
+ const path12 = `/connector-queries/${queryId}/poll/seed`;
41205
+ return postPollJSON(client, path12, body, "poll seed", reqOptions);
41206
+ }
41207
+ async function resumePoll(client, queryId, body, reqOptions) {
41208
+ const path12 = `/connector-queries/${queryId}/poll/resume`;
41209
+ return postPollJSON(client, path12, body, "poll resume", reqOptions);
41210
+ }
41211
+ async function listPollItems(client, queryId, query = {}, reqOptions) {
41212
+ const params = new URLSearchParams();
41213
+ if (query.state !== void 0) params.set("state", query.state);
41214
+ if (query.limit !== void 0) params.set("limit", String(query.limit));
41215
+ if (query.after !== void 0) params.set("after", String(query.after));
41216
+ const suffix = params.toString() === "" ? "" : `?${params.toString()}`;
41217
+ const path12 = `/connector-queries/${queryId}/poll/items${suffix}`;
41218
+ let out;
41219
+ try {
41220
+ out = await client.getJSON(path12, reqOptions);
41221
+ } catch (err) {
41222
+ throw toControlPlaneError("GET", path12, err);
41223
+ }
41224
+ if (out === null) {
41225
+ throw new Error(`GET ${path12}: empty response from control-plane poll items`);
41226
+ }
41227
+ return out;
41228
+ }
41229
+ async function retryPollItem(client, queryId, itemId, reqOptions) {
41230
+ const path12 = `/connector-queries/${queryId}/poll/items/${itemId}/retry`;
41231
+ return postPollJSON(client, path12, {}, "poll item retry", reqOptions);
41232
+ }
41233
+ async function skipPollItem(client, queryId, itemId, reqOptions) {
41234
+ const path12 = `/connector-queries/${queryId}/poll/items/${itemId}/skip`;
41235
+ return postPollJSON(client, path12, {}, "poll item skip", reqOptions);
41236
+ }
40931
41237
  function toControlPlaneError(method, path12, err) {
40932
41238
  const msg = err instanceof Error ? err.message : String(err);
40933
41239
  const m = /HTTP (\d{3})(?::\s*([\s\S]*))?$/.exec(msg);
@@ -41157,6 +41463,962 @@ function registerDevFetch(connectors) {
41157
41463
  );
41158
41464
  }
41159
41465
 
41466
+ // src/commands/connectorsPoll.ts
41467
+ import * as readline2 from "readline";
41468
+ import { createHash as createHash10 } from "crypto";
41469
+
41470
+ // src/types/connectors.ts
41471
+ var POLL_ITEM_STATES = [
41472
+ "seen",
41473
+ "new",
41474
+ "dispatched",
41475
+ "running",
41476
+ "retry_wait",
41477
+ "landed",
41478
+ "failed",
41479
+ "skipped",
41480
+ "seeded",
41481
+ "superseded"
41482
+ ];
41483
+
41484
+ // src/commands/connectorsPoll.ts
41485
+ var DURATION_UNIT_SECONDS = { s: 1, m: 60, h: 3600, d: 86400 };
41486
+ var DURATION_BOUNDS = {
41487
+ "--interval": [300, 7 * 86400],
41488
+ "--settle": [0, 86400]
41489
+ };
41490
+ var LOOKBACK_MAX_DAYS = 3650;
41491
+ function parseDurationSeconds(raw, flag) {
41492
+ const m = /^(\d+)([smhd])?$/.exec(raw.trim());
41493
+ const seconds = m === null ? NaN : Number(m[1]) * (DURATION_UNIT_SECONDS[m[2] ?? "s"] ?? 1);
41494
+ const [min, max] = DURATION_BOUNDS[flag] ?? [0, Number.MAX_SAFE_INTEGER];
41495
+ if (m === null) {
41496
+ throw new Error(`invalid ${flag} "${raw}": expected a duration like 90s, 5m or 1h`);
41497
+ }
41498
+ if (!Number.isSafeInteger(seconds) || seconds < min || seconds > max) {
41499
+ throw new Error(
41500
+ `invalid ${flag} "${raw}": must be between ${formatSeconds(min)} and ${formatSeconds(max)}`
41501
+ );
41502
+ }
41503
+ return seconds;
41504
+ }
41505
+ function parseLookbackDays(raw) {
41506
+ const m = /^(\d+)d?$/.exec(raw.trim());
41507
+ const days = m === null ? 0 : Number(m[1]);
41508
+ if (days < 1 || days > LOOKBACK_MAX_DAYS) {
41509
+ throw new Error(
41510
+ `invalid --lookback "${raw}": must be between 1 and ${LOOKBACK_MAX_DAYS} days, e.g. 180d`
41511
+ );
41512
+ }
41513
+ return days;
41514
+ }
41515
+ var DATE_ONLY_RE = /^(\d{4})-(\d{2})-(\d{2})$/;
41516
+ var DATE_TIME_RE = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2})(?:\.\d+)?)?(?:Z|[+-](\d{2}):(\d{2}))$/;
41517
+ function inRange(value, max, min = 0) {
41518
+ const n = Number(value ?? "0");
41519
+ return n >= min && n <= max;
41520
+ }
41521
+ function isCalendarDay(y, m, d) {
41522
+ if (!inRange(m, 12, 1)) return false;
41523
+ const daysInMonth3 = new Date(Date.UTC(Number(y), Number(m), 0)).getUTCDate();
41524
+ return inRange(d, daysInMonth3, 1);
41525
+ }
41526
+ function parseTimestampFlag(raw, flag) {
41527
+ const invalid = new Error(
41528
+ `invalid ${flag} "${raw}": expected YYYY-MM-DD or a timestamp with a zone (e.g. 2026-10-08T17:30:00+03:00)`
41529
+ );
41530
+ const value = raw.trim();
41531
+ const dateOnly = DATE_ONLY_RE.exec(value);
41532
+ if (dateOnly !== null) {
41533
+ if (!isCalendarDay(dateOnly[1], dateOnly[2], dateOnly[3])) throw invalid;
41534
+ return (/* @__PURE__ */ new Date(`${value}T00:00:00Z`)).toISOString();
41535
+ }
41536
+ const dt = DATE_TIME_RE.exec(value);
41537
+ const valid = dt !== null && isCalendarDay(dt[1], dt[2], dt[3]) && inRange(dt[4], 23) && inRange(dt[5], 59) && inRange(dt[6], 59) && inRange(dt[7], 23) && inRange(dt[8], 59);
41538
+ const ms = valid ? Date.parse(value) : NaN;
41539
+ if (Number.isNaN(ms)) throw invalid;
41540
+ return new Date(ms).toISOString();
41541
+ }
41542
+ function parseSameName(raw) {
41543
+ if (raw === "new-version") return "new_version";
41544
+ if (raw === "ignore") return "ignore";
41545
+ throw new Error(`--same-name must be new-version or ignore (got "${raw}")`);
41546
+ }
41547
+ function parseChoice(raw, flag, choices) {
41548
+ const match = choices.find((c) => c === raw);
41549
+ if (match === void 0) {
41550
+ throw new Error(`${flag} must be ${choices.join(" or ")} (got "${raw}")`);
41551
+ }
41552
+ return match;
41553
+ }
41554
+ var WIDEN_CHOICES = ["seed", "land"];
41555
+ var POLICY_CHOICES = ["rekey", "seed", "land"];
41556
+ function parseSettings(opts) {
41557
+ const fields = {};
41558
+ if (opts.interval !== void 0) {
41559
+ fields.interval_seconds = parseDurationSeconds(opts.interval, "--interval");
41560
+ }
41561
+ if (opts.since !== void 0) fields.since = parseTimestampFlag(opts.since, "--since");
41562
+ if (opts.lookback !== void 0) fields.lookback_days = parseLookbackDays(opts.lookback);
41563
+ if (opts.settle !== void 0) {
41564
+ fields.settle_seconds = parseDurationSeconds(opts.settle, "--settle");
41565
+ }
41566
+ if (opts.sameName !== void 0) fields.change_policy = parseSameName(opts.sameName);
41567
+ return fields;
41568
+ }
41569
+ function settingsArgs(opts) {
41570
+ const pairs = [
41571
+ ["--interval", opts.interval],
41572
+ ["--since", opts.since],
41573
+ ["--lookback", opts.lookback],
41574
+ ["--settle", opts.settle],
41575
+ ["--same-name", opts.sameName]
41576
+ ];
41577
+ return pairs.filter((p) => p[1] !== void 0).map(([flag, value]) => ` ${flag} ${value.trim()}`).join("");
41578
+ }
41579
+ async function resolvePollBinding(client, filebox, signal) {
41580
+ const wanted = filebox.trim();
41581
+ const byId = /^\d+$/.test(wanted);
41582
+ const rows = await listQueries(client, { signal });
41583
+ const matches = rows.filter(
41584
+ (q) => byId ? q.filebox_id === Number(wanted) : q.filebox_uuid.toLowerCase() === wanted.toLowerCase()
41585
+ );
41586
+ const [first] = matches;
41587
+ if (first === void 0) {
41588
+ throw new Error(
41589
+ `no connector binding for filebox ${wanted} in this org (see dr connectors query list)`
41590
+ );
41591
+ }
41592
+ if (matches.length > 1) {
41593
+ const ids = matches.map((q) => `#${q.query_id}`).join(", ");
41594
+ throw new Error(`filebox ${wanted} has several connector bindings (${ids})`);
41595
+ }
41596
+ return first;
41597
+ }
41598
+ function isNotPolled(err) {
41599
+ return err instanceof ControlPlaneError && err.status === 404 && err.body.includes("not polled");
41600
+ }
41601
+ function isPollThrottled(err) {
41602
+ return err instanceof ControlPlaneError && err.status === 409 && (err.body.includes("discover is in flight") || err.body.includes("polled less than"));
41603
+ }
41604
+ async function explainNotPolled(filebox, call) {
41605
+ try {
41606
+ return await call;
41607
+ } catch (err) {
41608
+ if (isNotPolled(err)) {
41609
+ throw new Error(
41610
+ `filebox ${filebox} is not set to polled ingestion; run dr connectors poll enable ${filebox}`,
41611
+ { cause: err }
41612
+ );
41613
+ }
41614
+ throw err;
41615
+ }
41616
+ }
41617
+ async function readFileboxDateTag(monolith, fileboxId, signal) {
41618
+ const details = await getDetails(monolith, fileboxId, { signal });
41619
+ const dateTags = (details.tags_config ?? []).filter((t) => t.type === "DATE");
41620
+ const [only] = dateTags;
41621
+ if (only === void 0) return {};
41622
+ if (dateTags.length > 1) {
41623
+ const names = dateTags.map((t) => t.name).join(", ");
41624
+ throw new Error(
41625
+ `filebox ${fileboxId} has several DATE tags (${names}); a polled filebox needs exactly one`
41626
+ );
41627
+ }
41628
+ return { id: only.id, name: only.name };
41629
+ }
41630
+ function formatSeconds(sec) {
41631
+ if (sec > 0 && sec % 86400 === 0) return `${sec / 86400}d`;
41632
+ if (sec > 0 && sec % 3600 === 0) return `${sec / 3600}h`;
41633
+ if (sec > 0 && sec % 60 === 0) return `${sec / 60}m`;
41634
+ return `${sec}s`;
41635
+ }
41636
+ function oneLine3(s) {
41637
+ return s.replace(/\s+/g, " ").trim();
41638
+ }
41639
+ function sameNameLabel(policy) {
41640
+ return policy === "new_version" ? "new-version" : String(policy);
41641
+ }
41642
+ function formatDateTag(tag) {
41643
+ if (tag?.id === void 0) return "none (undated filebox)";
41644
+ return `${tag.name ?? "?"} (id ${tag.id})`;
41645
+ }
41646
+ function bindingTarget(binding) {
41647
+ return `filebox ${binding.filebox_uuid} (query #${binding.query_id})`;
41648
+ }
41649
+ function renderPoll(out, headline, binding, p) {
41650
+ const row = (label, value) => {
41651
+ out.write(` ${`${label}:`.padEnd(15)}${value}
41652
+ `);
41653
+ };
41654
+ const status2 = `${p.enabled ? "enabled" : "disabled"}${p.paused_reason === null ? "" : `, paused: ${oneLine3(p.paused_reason)}`}`;
41655
+ const counts = Object.entries(p.counts).sort(([a], [b]) => a.localeCompare(b)).map(([state, n]) => `${state}=${n}`).join(" ");
41656
+ out.write(`${headline} for ${bindingTarget(binding)}
41657
+ `);
41658
+ row("Status", status2);
41659
+ row("Interval", formatSeconds(p.interval_seconds));
41660
+ row("Date tag", formatDateTag(p.date_tag));
41661
+ row("Since", p.since ?? "-");
41662
+ row("Lookback", `${p.lookback_days}d`);
41663
+ row("Settle", formatSeconds(p.settle_seconds));
41664
+ row("Same name", sameNameLabel(p.change_policy));
41665
+ row("Max attempts", String(p.max_attempts));
41666
+ row("Last poll", `${p.last_poll_at ?? "-"} ${oneLine3(p.last_poll_status ?? "")}`.trimEnd());
41667
+ row("Next poll", p.next_poll_at);
41668
+ row("Failures", String(p.consecutive_failures));
41669
+ row("Discover", p.discover_in_flight ? `in flight since ${p.discover_sent_at ?? "?"}` : "-");
41670
+ row("Last digest", p.last_digest ?? "-");
41671
+ row("Pending seed", p.poll_run_seed_until ?? "-");
41672
+ row(
41673
+ "Pending rekey",
41674
+ p.poll_run_rekey_to === null ? "-" : `to ${sameNameLabel(p.poll_run_rekey_to)}`
41675
+ );
41676
+ row("Items", counts === "" ? "(none)" : counts);
41677
+ }
41678
+ function writeTable26(out, rows) {
41679
+ const widths = [];
41680
+ for (const r of rows) {
41681
+ r.forEach((cell, i) => {
41682
+ widths[i] = Math.max(widths[i] ?? 0, cell.length);
41683
+ });
41684
+ }
41685
+ for (const r of rows) {
41686
+ const cells = r.map(
41687
+ (cell, i) => i === r.length - 1 ? cell : cell.padEnd((widths[i] ?? 0) + 2)
41688
+ );
41689
+ out.write(`${cells.join("").trimEnd()}
41690
+ `);
41691
+ }
41692
+ }
41693
+ function renderItemTable(out, items) {
41694
+ const rows = [["ID", "LABEL", "DATE", "STATE", "ATTEMPTS", "VERSION", "ERROR"]];
41695
+ for (const it of items) {
41696
+ const error = it.last_error ?? (it.skip_reason === null ? null : `skipped: ${it.skip_reason}`);
41697
+ rows.push([
41698
+ String(it.id),
41699
+ oneLine3(it.label),
41700
+ it.item_date ?? "-",
41701
+ it.state,
41702
+ String(it.attempts),
41703
+ it.version_id === null ? "-" : String(it.version_id),
41704
+ error === null ? "-" : truncate3(oneLine3(error), 80)
41705
+ ]);
41706
+ }
41707
+ writeTable26(out, rows);
41708
+ }
41709
+ async function runPollEnable(cfg) {
41710
+ const binding = await resolvePollBinding(cfg.client, cfg.filebox, cfg.signal);
41711
+ let existing;
41712
+ try {
41713
+ existing = await getPoll(cfg.client, binding.query_id, { signal: cfg.signal });
41714
+ } catch (err) {
41715
+ if (!isNotPolled(err)) throw err;
41716
+ existing = null;
41717
+ }
41718
+ const s = cfg.settings;
41719
+ if (existing !== null && (s.since !== void 0 || s.lookback_days !== void 0 || s.change_policy !== void 0)) {
41720
+ throw new Error(
41721
+ `filebox ${cfg.filebox} is already polled; change --since, --lookback or --same-name with dr connectors poll set ${cfg.filebox}, which asks what to do with a wider window or a policy switch`
41722
+ );
41723
+ }
41724
+ if (binding.filebox_id <= 0) {
41725
+ throw new Error(
41726
+ `connector-query #${binding.query_id} has no filebox id recorded, so its date tag cannot be read; record it with dr connectors query repoint ${binding.query_id} --filebox-id <id>`
41727
+ );
41728
+ }
41729
+ const dateTag = await readFileboxDateTag(cfg.monolith, binding.filebox_id, cfg.signal);
41730
+ const stored = await putPoll(
41731
+ cfg.client,
41732
+ binding.query_id,
41733
+ { enabled: true, date_tag: dateTag, ...s },
41734
+ { signal: cfg.signal }
41735
+ );
41736
+ if (cfg.asJson) {
41737
+ writeJSONIndented(cfg.out, stored);
41738
+ return;
41739
+ }
41740
+ renderPoll(cfg.out, "Polling enabled", binding, stored);
41741
+ }
41742
+ function windowStart(since, lookbackDays, now) {
41743
+ const start = now - lookbackDays * 864e5;
41744
+ return since === null ? start : Math.max(start, Date.parse(since));
41745
+ }
41746
+ function widening(current, changes, now) {
41747
+ if (changes.since === void 0 && changes.lookback_days === void 0) return null;
41748
+ const from = windowStart(current.since, current.lookback_days, now);
41749
+ const to = windowStart(
41750
+ changes.since ?? current.since,
41751
+ changes.lookback_days ?? current.lookback_days,
41752
+ now
41753
+ );
41754
+ if (to >= from) return null;
41755
+ return { from: new Date(from).toISOString(), to: new Date(to).toISOString() };
41756
+ }
41757
+ async function ask(cfg, message, choices, defaultChoice) {
41758
+ const answer = await cfg.prompt(message, choices, defaultChoice);
41759
+ if (answer === null) throw new Error("poll set cancelled; nothing was changed");
41760
+ return parseChoice(answer, "the answer", choices);
41761
+ }
41762
+ var WIDEN_HELP = "seed = mark the newly exposed items as already landed, land = land them all";
41763
+ var POLICY_HELP = "rekey = re-key the ledger from a fresh listing (nothing lands again), seed = mark everything in the window as landed, land = land everything in the window";
41764
+ async function runPollSet(cfg) {
41765
+ if (Object.keys(cfg.changes).length === 0) {
41766
+ throw new Error(
41767
+ "poll set: pass at least one of --interval, --since, --lookback, --settle, --same-name"
41768
+ );
41769
+ }
41770
+ const binding = await resolvePollBinding(cfg.client, cfg.filebox, cfg.signal);
41771
+ const current = await explainNotPolled(
41772
+ cfg.filebox,
41773
+ getPoll(cfg.client, binding.query_id, { signal: cfg.signal })
41774
+ );
41775
+ const body = { ...cfg.changes };
41776
+ const detail = [`target: ${bindingTarget(binding)}`];
41777
+ const wider = widening(current, cfg.changes, cfg.now ?? Date.now());
41778
+ if (wider !== null) {
41779
+ const what = `the polling window widens (start ${wider.from} -> ${wider.to})`;
41780
+ if (cfg.widen === void 0 && !cfg.interactive) {
41781
+ throw new Error(`${what}; pass --widen seed or --widen land (${WIDEN_HELP})`);
41782
+ }
41783
+ body.widen = cfg.widen ?? await ask(cfg, `${what}. ${WIDEN_HELP}.`, WIDEN_CHOICES);
41784
+ detail.push(`window: start ${wider.from} -> ${wider.to}, widen ${body.widen}`);
41785
+ } else if (cfg.widen !== void 0) {
41786
+ body.widen = cfg.widen;
41787
+ }
41788
+ const newPolicy = cfg.changes.change_policy;
41789
+ const policySwitch = newPolicy !== void 0 && newPolicy !== current.change_policy;
41790
+ if (policySwitch) {
41791
+ const change = `${sameNameLabel(current.change_policy)} -> ${sameNameLabel(newPolicy)}`;
41792
+ const what = `--same-name changes ${change}`;
41793
+ if (cfg.onPolicyChange === void 0 && !cfg.interactive) {
41794
+ throw new Error(`${what}; pass --on-policy-change rekey, seed or land (${POLICY_HELP})`);
41795
+ }
41796
+ body.on_policy_change = cfg.onPolicyChange ?? await ask(cfg, `${what}. ${POLICY_HELP}.`, POLICY_CHOICES, "rekey");
41797
+ detail.push(`same name: ${change}, on policy change ${body.on_policy_change}`);
41798
+ } else if (cfg.onPolicyChange !== void 0) {
41799
+ body.on_policy_change = cfg.onPolicyChange;
41800
+ }
41801
+ const put = async () => {
41802
+ const stored = await putPoll(cfg.client, binding.query_id, body, {
41803
+ signal: cfg.signal
41804
+ });
41805
+ if (cfg.asJson) {
41806
+ writeJSONIndented(cfg.out, stored);
41807
+ return;
41808
+ }
41809
+ renderPoll(cfg.out, "Polling settings updated", binding, stored);
41810
+ };
41811
+ const landsOrHides = wider !== null && body.widen === "land" || policySwitch && (body.on_policy_change === "seed" || body.on_policy_change === "land");
41812
+ if (!landsOrHides) {
41813
+ await put();
41814
+ return;
41815
+ }
41816
+ const flags = `${body.widen === void 0 ? "" : ` --widen ${body.widen}`}${body.on_policy_change === void 0 ? "" : ` --on-policy-change ${body.on_policy_change}`}`;
41817
+ cfg.deadline?.pause();
41818
+ await twoStepConfirm({
41819
+ out: cfg.out,
41820
+ action: pollConfirmAction(cfg.filebox, "set-land-or-seed", cfg.scope, { ...body }),
41821
+ token: cfg.token,
41822
+ server: cfg.scope.serverKey,
41823
+ confirmCmd: `dr connectors poll set ${cfg.filebox}${cfg.settingsArgs}${flags}${cfg.targetArgs}`,
41824
+ describe: async () => detail,
41825
+ execute: async () => {
41826
+ cfg.deadline?.resume();
41827
+ await put();
41828
+ }
41829
+ });
41830
+ }
41831
+ function confirmDigest(scope, payload) {
41832
+ const canonical = JSON.stringify({
41833
+ server: scope.serverKey,
41834
+ account: scope.account ?? "",
41835
+ controlPlane: scope.controlPlane,
41836
+ payload: Object.fromEntries(Object.entries(payload).sort(([a], [b]) => a.localeCompare(b)))
41837
+ });
41838
+ return createHash10("sha256").update(canonical).digest("hex").slice(0, 12);
41839
+ }
41840
+ function pollConfirmAction(filebox, verb, scope, payload = {}) {
41841
+ return {
41842
+ resource: "connector-poll",
41843
+ id: `${filebox.trim()}#${confirmDigest(scope, payload)}`,
41844
+ verb
41845
+ };
41846
+ }
41847
+ function pollItemConfirmAction(filebox, item, scope) {
41848
+ return {
41849
+ resource: "connector-poll-item",
41850
+ id: `${filebox.trim()}/${item}#${confirmDigest(scope, {})}`,
41851
+ verb: "skip"
41852
+ };
41853
+ }
41854
+ async function runPollDisable(cfg) {
41855
+ const binding = await resolvePollBinding(cfg.client, cfg.filebox, cfg.signal);
41856
+ await explainNotPolled(
41857
+ cfg.filebox,
41858
+ getPoll(cfg.client, binding.query_id, { signal: cfg.signal })
41859
+ );
41860
+ const stored = await putPoll(
41861
+ cfg.client,
41862
+ binding.query_id,
41863
+ { enabled: false },
41864
+ { signal: cfg.signal }
41865
+ );
41866
+ if (cfg.asJson) {
41867
+ writeJSONIndented(cfg.out, stored);
41868
+ return;
41869
+ }
41870
+ renderPoll(cfg.out, "Polling disabled", binding, stored);
41871
+ }
41872
+ async function runPollGet(cfg) {
41873
+ const binding = await resolvePollBinding(cfg.client, cfg.filebox, cfg.signal);
41874
+ const p = await explainNotPolled(
41875
+ cfg.filebox,
41876
+ getPoll(cfg.client, binding.query_id, { signal: cfg.signal })
41877
+ );
41878
+ if (cfg.asJson) {
41879
+ writeJSONIndented(cfg.out, p);
41880
+ return;
41881
+ }
41882
+ renderPoll(cfg.out, "Polling", binding, p);
41883
+ }
41884
+ async function runPollRun(cfg) {
41885
+ const binding = await resolvePollBinding(cfg.client, cfg.filebox, cfg.signal);
41886
+ let p;
41887
+ try {
41888
+ p = await explainNotPolled(
41889
+ cfg.filebox,
41890
+ runPoll(cfg.client, binding.query_id, { signal: cfg.signal })
41891
+ );
41892
+ } catch (err) {
41893
+ if (isPollThrottled(err)) {
41894
+ throw new Error(
41895
+ `a poll of filebox ${cfg.filebox} is running or ran less than a minute ago; try again shortly`,
41896
+ { cause: err }
41897
+ );
41898
+ }
41899
+ throw err;
41900
+ }
41901
+ if (cfg.asJson) {
41902
+ writeJSONIndented(cfg.out, p);
41903
+ return;
41904
+ }
41905
+ renderPoll(cfg.out, "Poll requested", binding, p);
41906
+ }
41907
+ async function runPollResume(cfg) {
41908
+ const binding = await resolvePollBinding(cfg.client, cfg.filebox, cfg.signal);
41909
+ const resume = async () => {
41910
+ const p = await explainNotPolled(
41911
+ cfg.filebox,
41912
+ resumePoll(
41913
+ cfg.client,
41914
+ binding.query_id,
41915
+ cfg.source === void 0 ? {} : { source: cfg.source },
41916
+ { signal: cfg.signal }
41917
+ )
41918
+ );
41919
+ if (cfg.asJson) {
41920
+ writeJSONIndented(cfg.out, p);
41921
+ return;
41922
+ }
41923
+ renderPoll(cfg.out, "Polling resumed", binding, p);
41924
+ };
41925
+ if (cfg.source !== "land") {
41926
+ await resume();
41927
+ return;
41928
+ }
41929
+ cfg.deadline?.pause();
41930
+ await twoStepConfirm({
41931
+ out: cfg.out,
41932
+ action: pollConfirmAction(cfg.filebox, "resume-land", cfg.scope),
41933
+ token: cfg.token,
41934
+ server: cfg.scope.serverKey,
41935
+ confirmCmd: `dr connectors poll resume ${cfg.filebox} --source land${cfg.targetArgs}`,
41936
+ describe: async () => [
41937
+ `target: ${bindingTarget(binding)}`,
41938
+ "source: land every item the changed source holds now"
41939
+ ],
41940
+ execute: async () => {
41941
+ cfg.deadline?.resume();
41942
+ await resume();
41943
+ }
41944
+ });
41945
+ }
41946
+ async function countSeedable(cfg, binding) {
41947
+ const untilMs = Date.parse(cfg.until);
41948
+ let count = 0;
41949
+ for (const state of ["seen", "new"]) {
41950
+ let after = null;
41951
+ do {
41952
+ cfg.deadline?.resume();
41953
+ const page = await explainNotPolled(
41954
+ cfg.filebox,
41955
+ listPollItems(
41956
+ cfg.client,
41957
+ binding.query_id,
41958
+ { state, ...after === null ? {} : { after } },
41959
+ { signal: cfg.signal }
41960
+ )
41961
+ );
41962
+ count += page.items.filter(
41963
+ (it) => it.source_modified_at !== null && Date.parse(it.source_modified_at) <= untilMs
41964
+ ).length;
41965
+ after = page.next_after;
41966
+ } while (after !== null);
41967
+ }
41968
+ return count;
41969
+ }
41970
+ async function runPollSeed(cfg) {
41971
+ const binding = await resolvePollBinding(cfg.client, cfg.filebox, cfg.signal);
41972
+ if (cfg.dryRun) {
41973
+ const wouldSeed = await countSeedable(cfg, binding);
41974
+ if (cfg.asJson) {
41975
+ writeJSONIndented(cfg.out, { dry_run: true, until: cfg.until, would_seed: wouldSeed });
41976
+ return;
41977
+ }
41978
+ cfg.out.write(`Seed dry run for ${bindingTarget(binding)}: nothing was changed.
41979
+ `);
41980
+ cfg.out.write(
41981
+ `${wouldSeed} already-discovered items would be seeded (items not yet discovered are not counted).
41982
+ `
41983
+ );
41984
+ return;
41985
+ }
41986
+ cfg.deadline?.pause();
41987
+ await twoStepConfirm({
41988
+ out: cfg.out,
41989
+ action: pollConfirmAction(cfg.filebox, "seed", cfg.scope, { until: cfg.until }),
41990
+ token: cfg.token,
41991
+ server: cfg.scope.serverKey,
41992
+ confirmCmd: `dr connectors poll seed ${cfg.filebox} --until ${cfg.untilArg}${cfg.targetArgs}`,
41993
+ describe: async () => [
41994
+ `target: ${bindingTarget(binding)}`,
41995
+ `until: ${cfg.until}`,
41996
+ "effect: items modified at or before it are marked landed and never land"
41997
+ ],
41998
+ execute: async () => {
41999
+ cfg.deadline?.resume();
42000
+ const p = await explainNotPolled(
42001
+ cfg.filebox,
42002
+ seedPoll(
42003
+ cfg.client,
42004
+ binding.query_id,
42005
+ { until: cfg.until },
42006
+ {
42007
+ signal: cfg.signal
42008
+ }
42009
+ )
42010
+ );
42011
+ if (cfg.asJson) {
42012
+ writeJSONIndented(cfg.out, p);
42013
+ return;
42014
+ }
42015
+ renderPoll(cfg.out, "Seed requested", binding, p);
42016
+ }
42017
+ });
42018
+ }
42019
+ async function runPollItems(cfg) {
42020
+ const binding = await resolvePollBinding(cfg.client, cfg.filebox, cfg.signal);
42021
+ const page = await explainNotPolled(
42022
+ cfg.filebox,
42023
+ listPollItems(
42024
+ cfg.client,
42025
+ binding.query_id,
42026
+ {
42027
+ ...cfg.state !== void 0 ? { state: cfg.state } : {},
42028
+ ...cfg.limit !== void 0 ? { limit: cfg.limit } : {},
42029
+ ...cfg.after !== void 0 ? { after: cfg.after } : {}
42030
+ },
42031
+ { signal: cfg.signal }
42032
+ )
42033
+ );
42034
+ if (cfg.asJson) {
42035
+ writeJSONIndented(cfg.out, page);
42036
+ return;
42037
+ }
42038
+ if (page.items.length === 0) {
42039
+ cfg.out.write(`No items${cfg.state === void 0 ? "" : ` in state ${cfg.state}`}.
42040
+ `);
42041
+ return;
42042
+ }
42043
+ renderItemTable(cfg.out, page.items);
42044
+ if (page.next_after !== null) {
42045
+ const state = cfg.state === void 0 ? "" : ` --state ${cfg.state}`;
42046
+ const limit = cfg.limit === void 0 ? "" : ` --limit ${cfg.limit}`;
42047
+ cfg.out.write(
42048
+ `
42049
+ More: dr connectors poll items ${cfg.filebox}${state}${limit} --after ${page.next_after}
42050
+ `
42051
+ );
42052
+ }
42053
+ }
42054
+ function renderItemResult(cfg, binding, headline, item) {
42055
+ if (cfg.asJson) {
42056
+ writeJSONIndented(cfg.out, item);
42057
+ return;
42058
+ }
42059
+ cfg.out.write(`${headline} (${bindingTarget(binding)})
42060
+ `);
42061
+ renderItemTable(cfg.out, [item]);
42062
+ }
42063
+ async function runPollRetry(cfg) {
42064
+ const binding = await resolvePollBinding(cfg.client, cfg.filebox, cfg.signal);
42065
+ const item = await explainNotPolled(
42066
+ cfg.filebox,
42067
+ retryPollItem(cfg.client, binding.query_id, cfg.itemId, { signal: cfg.signal })
42068
+ );
42069
+ renderItemResult(cfg, binding, `Item ${cfg.itemId} queued for retry`, item);
42070
+ }
42071
+ async function runPollSkip(cfg) {
42072
+ const binding = await resolvePollBinding(cfg.client, cfg.filebox, cfg.signal);
42073
+ cfg.deadline?.pause();
42074
+ await twoStepConfirm({
42075
+ out: cfg.out,
42076
+ action: pollItemConfirmAction(cfg.filebox, cfg.itemId, cfg.scope),
42077
+ token: cfg.token,
42078
+ server: cfg.scope.serverKey,
42079
+ confirmCmd: `dr connectors poll skip ${cfg.filebox} ${cfg.itemId}${cfg.targetArgs}`,
42080
+ describe: async () => [
42081
+ `item: ${cfg.itemId} of ${bindingTarget(binding)}`,
42082
+ "effect: the item is never landed (dr connectors poll retry queues it again)"
42083
+ ],
42084
+ execute: async () => {
42085
+ cfg.deadline?.resume();
42086
+ const item = await explainNotPolled(
42087
+ cfg.filebox,
42088
+ skipPollItem(cfg.client, binding.query_id, cfg.itemId, {
42089
+ signal: cfg.signal
42090
+ })
42091
+ );
42092
+ renderItemResult(cfg, binding, `Item ${cfg.itemId} skipped`, item);
42093
+ }
42094
+ });
42095
+ }
42096
+ async function withMonolith(opts, action) {
42097
+ const monolithHost = resolve(resolveServer(opts.server)).host;
42098
+ const setup = await setupCall(opts.server, opts.account, {
42099
+ host: monolithHost,
42100
+ authHost: monolithHost
42101
+ });
42102
+ try {
42103
+ await action(setup.client);
42104
+ } finally {
42105
+ setup.cleanup();
42106
+ }
42107
+ }
42108
+ function scopeOf(opts) {
42109
+ const serverKey = resolveServer(opts.server);
42110
+ return {
42111
+ serverKey,
42112
+ account: normaliseAccount(opts.account),
42113
+ controlPlane: resolveConnectorsUrl(serverKey, opts.connectorsUrl)
42114
+ };
42115
+ }
42116
+ function targetArgsOf(opts) {
42117
+ const url = (opts.connectorsUrl ?? "").trim();
42118
+ return ` --server ${resolveServer(opts.server)}${url === "" ? "" : ` --connectors-url ${url}`}`;
42119
+ }
42120
+ function addCommonFlags(cmd, jsonHelp) {
42121
+ cmd.option("--json", jsonHelp, false);
42122
+ addServerFlag(cmd);
42123
+ addAccountFlag(cmd);
42124
+ addConnectorsUrlFlag(cmd);
42125
+ }
42126
+ function addConfirmTokenFlag(cmd) {
42127
+ return cmd.option("--confirm-token <token>", "Token from a prior plan run \u2014 required to proceed");
42128
+ }
42129
+ function addSettingsFlags(cmd) {
42130
+ return cmd.option("--interval <duration>", "how often to poll, 5m to 7d (default: per source)").option("--since <date>", "never pick up items modified before this date or timestamp").option("--lookback <days>", "window every poll lists, 1d to 3650d (default: per source)").option("--settle <duration>", "how long an item must stay unchanged before landing, 0s to 1d").option(
42131
+ "--same-name <policy>",
42132
+ "a changed file under the same name: new-version (lands again) or ignore"
42133
+ );
42134
+ }
42135
+ function ttyChoicePrompt(message, choices, defaultChoice, io = { input: process.stdin, output: process.stderr }) {
42136
+ return new Promise((resolvePrompt) => {
42137
+ const rl = readline2.createInterface({
42138
+ input: io.input,
42139
+ output: io.output,
42140
+ ...io.terminal !== void 0 ? { terminal: io.terminal } : {}
42141
+ });
42142
+ let settled = false;
42143
+ const settle = (value) => {
42144
+ if (settled) return;
42145
+ settled = true;
42146
+ rl.close();
42147
+ resolvePrompt(value);
42148
+ };
42149
+ rl.on("SIGINT", () => settle(null));
42150
+ rl.on("close", () => settle(null));
42151
+ io.output.write(`${message}
42152
+ `);
42153
+ const question = defaultChoice === void 0 ? `[${choices.join("/")}]: ` : `[${choices.join("/")}] (Enter = ${defaultChoice}): `;
42154
+ const askOnce = () => {
42155
+ rl.question(question, (answer) => {
42156
+ const picked = answer.trim().toLowerCase();
42157
+ if (picked === "" && defaultChoice !== void 0) {
42158
+ settle(defaultChoice);
42159
+ } else if (choices.includes(picked)) {
42160
+ settle(picked);
42161
+ } else {
42162
+ io.output.write(`Answer one of: ${choices.join(", ")}
42163
+ `);
42164
+ askOnce();
42165
+ }
42166
+ });
42167
+ };
42168
+ askOnce();
42169
+ });
42170
+ }
42171
+ function registerConnectorsPoll(connectors) {
42172
+ const poll2 = connectors.command("poll").description("Polled file ingestion: the control-plane lands each new file as one version");
42173
+ const enableCmd = addSettingsFlags(
42174
+ poll2.command("enable").description("Poll a filebox's binding (dated with the filebox's DATE tag)").argument("<filebox>", "filebox id or uuid")
42175
+ ).action(async (filebox, opts) => {
42176
+ const settings = parseSettings(opts);
42177
+ await withConnectorsSetup(opts, async ({ client, signal }) => {
42178
+ await withMonolith(opts, async (monolith) => {
42179
+ await runPollEnable({
42180
+ client,
42181
+ monolith,
42182
+ filebox,
42183
+ settings,
42184
+ asJson: opts.json === true,
42185
+ signal,
42186
+ out: process.stdout
42187
+ });
42188
+ });
42189
+ });
42190
+ });
42191
+ addCommonFlags(enableCmd, "Output the stored binding as JSON");
42192
+ const setCmd = addConfirmTokenFlag(
42193
+ addSettingsFlags(
42194
+ poll2.command("set").description("Change polling settings (only the given flags change)").argument("<filebox>", "filebox id or uuid")
42195
+ ).option(
42196
+ "--widen <seed|land>",
42197
+ "a wider window: seed (mark exposed items landed) or land them"
42198
+ ).option("--on-policy-change <rekey|seed|land>", "a --same-name switch: rekey, seed or land")
42199
+ ).action(
42200
+ async (filebox, opts) => {
42201
+ const changes = parseSettings(opts);
42202
+ const widen = opts.widen === void 0 ? void 0 : parseChoice(opts.widen, "--widen", WIDEN_CHOICES);
42203
+ const onPolicyChange = opts.onPolicyChange === void 0 ? void 0 : parseChoice(opts.onPolicyChange, "--on-policy-change", POLICY_CHOICES);
42204
+ await preflightConfirmToken(
42205
+ pollConfirmAction(filebox, "set-land-or-seed", scopeOf(opts), {
42206
+ ...changes,
42207
+ ...widen !== void 0 ? { widen } : {},
42208
+ ...onPolicyChange !== void 0 ? { on_policy_change: onPolicyChange } : {}
42209
+ }),
42210
+ opts.confirmToken
42211
+ );
42212
+ await withConnectorsSetup(opts, async (setup) => {
42213
+ const deadline = {
42214
+ pause: () => setup.pauseTimeout(),
42215
+ resume: () => setup.extendTimeout(DEFAULT_CALL_TIMEOUT_MS)
42216
+ };
42217
+ await runPollSet({
42218
+ client: setup.client,
42219
+ filebox,
42220
+ changes,
42221
+ settingsArgs: settingsArgs(opts),
42222
+ ...widen !== void 0 ? { widen } : {},
42223
+ ...onPolicyChange !== void 0 ? { onPolicyChange } : {},
42224
+ interactive: process.stdin.isTTY === true && process.stderr.isTTY === true,
42225
+ prompt: async (message, choices, defaultChoice) => {
42226
+ deadline.pause();
42227
+ try {
42228
+ return await ttyChoicePrompt(message, choices, defaultChoice);
42229
+ } finally {
42230
+ deadline.resume();
42231
+ }
42232
+ },
42233
+ deadline,
42234
+ ...opts.confirmToken !== void 0 ? { token: opts.confirmToken } : {},
42235
+ scope: scopeOf(opts),
42236
+ targetArgs: targetArgsOf(opts),
42237
+ asJson: opts.json === true,
42238
+ signal: setup.signal,
42239
+ out: process.stdout
42240
+ });
42241
+ });
42242
+ }
42243
+ );
42244
+ addCommonFlags(setCmd, "Output the stored binding as JSON");
42245
+ const disableCmd = poll2.command("disable").description("Stop polling (an item already in flight still finishes)").argument("<filebox>", "filebox id or uuid").action(async (filebox, opts) => {
42246
+ await withConnectorsSetup(opts, async ({ client, signal }) => {
42247
+ await runPollDisable({
42248
+ client,
42249
+ filebox,
42250
+ asJson: opts.json === true,
42251
+ signal,
42252
+ out: process.stdout
42253
+ });
42254
+ });
42255
+ });
42256
+ addCommonFlags(disableCmd, "Output the stored binding as JSON");
42257
+ const getCmd = poll2.command("get").description("Show polling settings, last poll, pending seed / rekey and item counts").argument("<filebox>", "filebox id or uuid").action(async (filebox, opts) => {
42258
+ await withConnectorsSetup(opts, async ({ client, signal }) => {
42259
+ await runPollGet({
42260
+ client,
42261
+ filebox,
42262
+ asJson: opts.json === true,
42263
+ signal,
42264
+ out: process.stdout
42265
+ });
42266
+ });
42267
+ });
42268
+ addCommonFlags(getCmd, "Output the raw binding as JSON");
42269
+ const runCmd = poll2.command("run").description("Poll now").argument("<filebox>", "filebox id or uuid").action(async (filebox, opts) => {
42270
+ await withConnectorsSetup(opts, async ({ client, signal }) => {
42271
+ await runPollRun({
42272
+ client,
42273
+ filebox,
42274
+ asJson: opts.json === true,
42275
+ signal,
42276
+ out: process.stdout
42277
+ });
42278
+ });
42279
+ });
42280
+ addCommonFlags(runCmd, "Output the binding as JSON");
42281
+ const resumeCmd = addConfirmTokenFlag(
42282
+ poll2.command("resume").description("Resume a paused binding (after fixing credentials, or a source change)").argument("<filebox>", "filebox id or uuid").option(
42283
+ "--source <seed|land>",
42284
+ "after a source change: seed (mark present items landed) or land them"
42285
+ )
42286
+ ).action(async (filebox, opts) => {
42287
+ const source = opts.source === void 0 ? void 0 : parseChoice(opts.source, "--source", WIDEN_CHOICES);
42288
+ if (source === "land") {
42289
+ await preflightConfirmToken(
42290
+ pollConfirmAction(filebox, "resume-land", scopeOf(opts)),
42291
+ opts.confirmToken
42292
+ );
42293
+ }
42294
+ await withConnectorsSetup(opts, async (setup) => {
42295
+ await runPollResume({
42296
+ client: setup.client,
42297
+ filebox,
42298
+ ...source !== void 0 ? { source } : {},
42299
+ deadline: {
42300
+ pause: () => setup.pauseTimeout(),
42301
+ resume: () => setup.extendTimeout(DEFAULT_CALL_TIMEOUT_MS)
42302
+ },
42303
+ ...opts.confirmToken !== void 0 ? { token: opts.confirmToken } : {},
42304
+ scope: scopeOf(opts),
42305
+ targetArgs: targetArgsOf(opts),
42306
+ asJson: opts.json === true,
42307
+ signal: setup.signal,
42308
+ out: process.stdout
42309
+ });
42310
+ });
42311
+ });
42312
+ addCommonFlags(resumeCmd, "Output the binding as JSON");
42313
+ const itemsCmd = poll2.command("items").description("List the item ledger: label, date, state, attempts, version, error").argument("<filebox>", "filebox id or uuid").option("--state <state>", `only items in this state (${POLL_ITEM_STATES.join("|")})`).option("--limit <n>", "page size (default and maximum: the control-plane page size, 100)").option("--after <id>", "start after this item id (the next-page cursor)").action(
42314
+ async (filebox, opts) => {
42315
+ const state = opts.state === void 0 ? void 0 : POLL_ITEM_STATES.find((s) => s === opts.state);
42316
+ if (opts.state !== void 0 && state === void 0) {
42317
+ throw new Error(
42318
+ `invalid --state "${opts.state}": expected one of ${POLL_ITEM_STATES.join(", ")}`
42319
+ );
42320
+ }
42321
+ const limit = opts.limit === void 0 ? void 0 : parsePositiveIntArg2(opts.limit, "--limit");
42322
+ const after = opts.after === void 0 ? void 0 : parsePositiveIntArg2(opts.after, "--after");
42323
+ await withConnectorsSetup(opts, async ({ client, signal }) => {
42324
+ await runPollItems({
42325
+ client,
42326
+ filebox,
42327
+ ...state !== void 0 ? { state } : {},
42328
+ ...limit !== void 0 ? { limit } : {},
42329
+ ...after !== void 0 ? { after } : {},
42330
+ asJson: opts.json === true,
42331
+ signal,
42332
+ out: process.stdout
42333
+ });
42334
+ });
42335
+ }
42336
+ );
42337
+ addCommonFlags(itemsCmd, "Output the raw page as JSON");
42338
+ const retryCmd = poll2.command("retry").description("Queue a failed, waiting or skipped item again").argument("<filebox>", "filebox id or uuid").argument("<item>", "item id (from poll items)").action(async (filebox, item, opts) => {
42339
+ const itemId = parsePositiveIntArg2(item, "item id");
42340
+ await withConnectorsSetup(opts, async ({ client, signal }) => {
42341
+ await runPollRetry({
42342
+ client,
42343
+ filebox,
42344
+ itemId,
42345
+ asJson: opts.json === true,
42346
+ signal,
42347
+ out: process.stdout
42348
+ });
42349
+ });
42350
+ });
42351
+ addCommonFlags(retryCmd, "Output the item as JSON");
42352
+ const skipCmd = addConfirmTokenFlag(
42353
+ poll2.command("skip").description("Skip an item so it is never landed (two-step confirmation)").argument("<filebox>", "filebox id or uuid").argument("<item>", "item id (from poll items)")
42354
+ ).action(async (filebox, item, opts) => {
42355
+ const itemId = parsePositiveIntArg2(item, "item id");
42356
+ await preflightConfirmToken(
42357
+ pollItemConfirmAction(filebox, itemId, scopeOf(opts)),
42358
+ opts.confirmToken
42359
+ );
42360
+ await withConnectorsSetup(opts, async (setup) => {
42361
+ await runPollSkip({
42362
+ client: setup.client,
42363
+ filebox,
42364
+ itemId,
42365
+ deadline: {
42366
+ pause: () => setup.pauseTimeout(),
42367
+ resume: () => setup.extendTimeout(DEFAULT_CALL_TIMEOUT_MS)
42368
+ },
42369
+ ...opts.confirmToken !== void 0 ? { token: opts.confirmToken } : {},
42370
+ scope: scopeOf(opts),
42371
+ targetArgs: targetArgsOf(opts),
42372
+ asJson: opts.json === true,
42373
+ signal: setup.signal,
42374
+ out: process.stdout
42375
+ });
42376
+ });
42377
+ });
42378
+ addCommonFlags(skipCmd, "Output the item as JSON");
42379
+ const seedCmd = addConfirmTokenFlag(
42380
+ poll2.command("seed").description("Mark items modified at or before --until as already landed (cut-over)").argument("<filebox>", "filebox id or uuid").requiredOption(
42381
+ "--until <timestamp>",
42382
+ "date or timestamp with a zone, e.g. 2026-10-08T17:30:00Z"
42383
+ ).option(
42384
+ "--dry-run",
42385
+ "count the already-discovered items it would mark, without changing anything",
42386
+ false
42387
+ )
42388
+ ).action(
42389
+ async (filebox, opts) => {
42390
+ const until = parseTimestampFlag(opts.until, "--until");
42391
+ const dryRun = opts.dryRun === true;
42392
+ if (!dryRun) {
42393
+ await preflightConfirmToken(
42394
+ pollConfirmAction(filebox, "seed", scopeOf(opts), { until }),
42395
+ opts.confirmToken
42396
+ );
42397
+ }
42398
+ await withConnectorsSetup(opts, async (setup) => {
42399
+ await runPollSeed({
42400
+ client: setup.client,
42401
+ filebox,
42402
+ until,
42403
+ untilArg: opts.until.trim(),
42404
+ dryRun,
42405
+ deadline: {
42406
+ pause: () => setup.pauseTimeout(),
42407
+ resume: () => setup.extendTimeout(DEFAULT_CALL_TIMEOUT_MS)
42408
+ },
42409
+ ...opts.confirmToken !== void 0 ? { token: opts.confirmToken } : {},
42410
+ scope: scopeOf(opts),
42411
+ targetArgs: targetArgsOf(opts),
42412
+ asJson: opts.json === true,
42413
+ signal: setup.signal,
42414
+ out: process.stdout
42415
+ });
42416
+ });
42417
+ }
42418
+ );
42419
+ addCommonFlags(seedCmd, "Output the binding (or the dry-run count) as JSON");
42420
+ }
42421
+
41160
42422
  // src/commands/connectors.ts
41161
42423
  var CONTROL_PLANE_HOST = (subDomain) => `https://${subDomain}-connectors-control-plane.datarails.io`;
41162
42424
  function resolveConnectorsUrl(serverKey, connectorsUrlFlag) {
@@ -41202,7 +42464,12 @@ async function withConnectorsSetup(opts, action) {
41202
42464
  authHost: resolve(serverKey).host
41203
42465
  });
41204
42466
  try {
41205
- await action({ client: setup.client, signal: setup.signal });
42467
+ await action({
42468
+ client: setup.client,
42469
+ signal: setup.signal,
42470
+ pauseTimeout: setup.pauseTimeout,
42471
+ extendTimeout: setup.extendTimeout
42472
+ });
41206
42473
  } catch (err) {
41207
42474
  throw augmentTlsCertError(err);
41208
42475
  } finally {
@@ -41808,6 +43075,7 @@ ${TLS_VPN_HELP}`);
41808
43075
  addAccountFlag(activeGetCmd);
41809
43076
  addConnectorsUrlFlag(activeGetCmd);
41810
43077
  registerDevFetch(connectors);
43078
+ registerConnectorsPoll(connectors);
41811
43079
  }
41812
43080
 
41813
43081
  // src/types/dashboards.ts
@@ -43088,7 +44356,7 @@ async function buildFiltersForCfg(resolver, cfg) {
43088
44356
  dateFlags: cfg.dateFlags
43089
44357
  });
43090
44358
  }
43091
- function writeTable26(out, rows) {
44359
+ function writeTable27(out, rows) {
43092
44360
  if (rows.length === 0) return;
43093
44361
  const widths = [];
43094
44362
  for (const r of rows) {
@@ -43122,7 +44390,7 @@ function renderWidgetsTable(out, widgets) {
43122
44390
  ]
43123
44391
  });
43124
44392
  }
43125
- writeTable26(out, rows);
44393
+ writeTable27(out, rows);
43126
44394
  }
43127
44395
  function registerWidgetsCommand(root) {
43128
44396
  const widgets = root.command("widgets").alias("widget").description("Operations on Datarails dashboard widgets");
@@ -43554,7 +44822,7 @@ function registerWidgetsCommand(root) {
43554
44822
  }
43555
44823
 
43556
44824
  // src/commands/reconciliation.ts
43557
- import { createHash as createHash10 } from "crypto";
44825
+ import { createHash as createHash11 } from "crypto";
43558
44826
  import { promises as fs18 } from "fs";
43559
44827
 
43560
44828
  // src/api/reconciliation.ts
@@ -44298,7 +45566,7 @@ function dash(v) {
44298
45566
  if (typeof v === "string" && v === "") return "-";
44299
45567
  return String(v);
44300
45568
  }
44301
- function writeTable27(out, rows) {
45569
+ function writeTable28(out, rows) {
44302
45570
  if (rows.length === 0) return;
44303
45571
  const widths = [];
44304
45572
  for (const r of rows) {
@@ -44336,7 +45604,7 @@ function renderEvidenceList(out, items) {
44336
45604
  dash(e.note ?? null)
44337
45605
  ]);
44338
45606
  }
44339
- writeTable27(out, rows);
45607
+ writeTable28(out, rows);
44340
45608
  const word = items.length === 1 ? "evidence" : "evidences";
44341
45609
  out.write(`
44342
45610
  (${items.length} ${word})
@@ -44355,7 +45623,7 @@ function renderEvidenceSingle(out, e) {
44355
45623
  dash(e.file_url ?? null)
44356
45624
  ]
44357
45625
  ];
44358
- writeTable27(out, rows);
45626
+ writeTable28(out, rows);
44359
45627
  }
44360
45628
  function renderSupportingItemsList(out, items) {
44361
45629
  if (items.length === 0) {
@@ -44372,7 +45640,7 @@ function renderSupportingItemsList(out, items) {
44372
45640
  dash(e.url)
44373
45641
  ]);
44374
45642
  }
44375
- writeTable27(out, rows);
45643
+ writeTable28(out, rows);
44376
45644
  const word = items.length === 1 ? "supporting item" : "supporting items";
44377
45645
  out.write(`
44378
45646
  (${items.length} ${word})
@@ -44749,7 +46017,7 @@ function dash2(v) {
44749
46017
  if (typeof v === "string" && v === "") return "-";
44750
46018
  return String(v);
44751
46019
  }
44752
- function writeTable28(out, rows) {
46020
+ function writeTable29(out, rows) {
44753
46021
  if (rows.length === 0) return;
44754
46022
  const widths = [];
44755
46023
  for (const r of rows) {
@@ -44790,7 +46058,7 @@ function renderConnectionList(out, items) {
44790
46058
  String(c.sync_progress_percentage)
44791
46059
  ]);
44792
46060
  }
44793
- writeTable28(out, rows);
46061
+ writeTable29(out, rows);
44794
46062
  out.write(`
44795
46063
  (${items.length} connection${plural(items.length)})
44796
46064
  `);
@@ -44818,7 +46086,7 @@ function renderConnectionSingle(out, c) {
44818
46086
  String(c.initial_sync_total_files)
44819
46087
  ]
44820
46088
  ];
44821
- writeTable28(out, rows);
46089
+ writeTable29(out, rows);
44822
46090
  }
44823
46091
  function renderSyncProgress(out, resp) {
44824
46092
  out.write(`Status: ${dash2(resp.status)}
@@ -45181,7 +46449,7 @@ function chunkByJsonBytes(rows, maxBytes) {
45181
46449
  return chunks;
45182
46450
  }
45183
46451
  function settingsActionId(settings) {
45184
- return createHash10("sha256").update(JSON.stringify(settings)).digest("hex").slice(0, 12);
46452
+ return createHash11("sha256").update(JSON.stringify(settings)).digest("hex").slice(0, 12);
45185
46453
  }
45186
46454
  async function runReconciliationAccountsUpdateSettings(cfg) {
45187
46455
  const action = {
@@ -45268,7 +46536,7 @@ function dash4(v) {
45268
46536
  if (typeof v === "string" && v === "") return "-";
45269
46537
  return String(v);
45270
46538
  }
45271
- function writeTable29(out, rows) {
46539
+ function writeTable30(out, rows) {
45272
46540
  if (rows.length === 0) return;
45273
46541
  const widths = [];
45274
46542
  for (const r of rows) {
@@ -45308,7 +46576,7 @@ function renderAccountsList(out, items) {
45308
46576
  dash4(a.frequency)
45309
46577
  ]);
45310
46578
  }
45311
- writeTable29(out, rows);
46579
+ writeTable30(out, rows);
45312
46580
  out.write(`
45313
46581
  (${items.length} account${plural(items.length)})
45314
46582
  `);
@@ -45337,7 +46605,7 @@ function renderEntityCurrencies(out, resp) {
45337
46605
  for (const e of resp.entities) {
45338
46606
  rows.push([dash4(e.name), dash4(e.currency)]);
45339
46607
  }
45340
- writeTable29(out, rows);
46608
+ writeTable30(out, rows);
45341
46609
  }
45342
46610
  function renderAccountsInfo(out, items) {
45343
46611
  if (items.length === 0) {
@@ -45348,7 +46616,7 @@ function renderAccountsInfo(out, items) {
45348
46616
  for (const a of items) {
45349
46617
  rows.push([dash4(a.id), dash4(a.name), dash4(a.account_group ?? null), dash4(a.entity ?? null)]);
45350
46618
  }
45351
- writeTable29(out, rows);
46619
+ writeTable30(out, rows);
45352
46620
  out.write(`
45353
46621
  (${items.length} account${plural(items.length)})
45354
46622
  `);
@@ -45399,7 +46667,7 @@ function renderAccountsSettings(out, items) {
45399
46667
  String(a.threshold_to)
45400
46668
  ]);
45401
46669
  }
45402
- writeTable29(out, rows);
46670
+ writeTable30(out, rows);
45403
46671
  out.write(`
45404
46672
  (${items.length} account${plural(items.length)})
45405
46673
  `);
@@ -45559,7 +46827,7 @@ async function runReconciliationAccountsSetAssignee(cfg) {
45559
46827
  var ASSIGNEE_BATCH_CHUNK_SIZE = 100;
45560
46828
  function assigneeBatchActionId(date, rows) {
45561
46829
  const canonical = rows.map((r) => [r.accountId, r.type, r.userId, r.userName, r.userEmail]);
45562
- return createHash10("sha256").update(JSON.stringify([date, canonical])).digest("hex").slice(0, 12);
46830
+ return createHash11("sha256").update(JSON.stringify([date, canonical])).digest("hex").slice(0, 12);
45563
46831
  }
45564
46832
  async function runReconciliationAccountsSetAssigneeBatch(cfg) {
45565
46833
  const action = {
@@ -45713,7 +46981,7 @@ verify the date matches the accounts' reporting period (try \`dr reconciliation
45713
46981
  }
45714
46982
  function clearBatchActionId(date, rows) {
45715
46983
  const canonical = rows.map((r) => [r.accountId, r.type]);
45716
- return createHash10("sha256").update(JSON.stringify(["clear", date, canonical])).digest("hex").slice(0, 12);
46984
+ return createHash11("sha256").update(JSON.stringify(["clear", date, canonical])).digest("hex").slice(0, 12);
45717
46985
  }
45718
46986
  async function runReconciliationAccountsClearAssigneeBatch(cfg) {
45719
46987
  const action = {
@@ -47603,7 +48871,7 @@ function renderForError(v) {
47603
48871
  }
47604
48872
 
47605
48873
  // src/commands/mecWorkflow.ts
47606
- import { createHash as createHash11 } from "crypto";
48874
+ import { createHash as createHash12 } from "crypto";
47607
48875
 
47608
48876
  // src/api/workflow.ts
47609
48877
  function buildQueryString(params) {
@@ -49095,7 +50363,7 @@ function dash5(s) {
49095
50363
  if (s === "") return "-";
49096
50364
  return s;
49097
50365
  }
49098
- function writeTable30(out, rows) {
50366
+ function writeTable31(out, rows) {
49099
50367
  if (rows.length === 0) return;
49100
50368
  const widths = [];
49101
50369
  for (const r of rows) {
@@ -49217,7 +50485,7 @@ function renderMecWorkflowList(out, rows) {
49217
50485
  dash5(r.update_time)
49218
50486
  ]);
49219
50487
  }
49220
- writeTable30(out, tableRows);
50488
+ writeTable31(out, tableRows);
49221
50489
  out.write(`
49222
50490
  (${rows.length} MEC workflow${plural(rows.length)})
49223
50491
  `);
@@ -49245,7 +50513,7 @@ function renderMecWorkflowDetail(out, t) {
49245
50513
  ["updated:", dash5(t.update_time)],
49246
50514
  ["process_start_time:", dash5(t.process_start_time)]
49247
50515
  ];
49248
- writeTable30(out, rows);
50516
+ writeTable31(out, rows);
49249
50517
  out.write("\n");
49250
50518
  const perms = t.permissions ?? [];
49251
50519
  out.write("permissions: ");
@@ -49260,7 +50528,7 @@ function renderMecWorkflowDetail(out, t) {
49260
50528
  for (const tag of tags) {
49261
50529
  tagRows.push([` ${tag.id}`, dash5(tag.name), dash5(tag.label), String(tag.value)]);
49262
50530
  }
49263
- writeTable30(out, tagRows);
50531
+ writeTable31(out, tagRows);
49264
50532
  }
49265
50533
  out.write("\nprocess_instances:\n");
49266
50534
  const instances = t.process_instances ?? [];
@@ -49277,7 +50545,7 @@ function renderMecWorkflowDetail(out, t) {
49277
50545
  dash5(pi.create_time)
49278
50546
  ]);
49279
50547
  }
49280
- writeTable30(out, piRows);
50548
+ writeTable31(out, piRows);
49281
50549
  }
49282
50550
  }
49283
50551
  async function runMecProcessList(cfg) {
@@ -49311,7 +50579,7 @@ function renderMecProcessList(out, rows) {
49311
50579
  dash5(r.create_time)
49312
50580
  ]);
49313
50581
  }
49314
- writeTable30(out, tableRows);
50582
+ writeTable31(out, tableRows);
49315
50583
  out.write(`
49316
50584
  (${rows.length} MEC process${rows.length === 1 ? "" : "es"})
49317
50585
  `);
@@ -49337,7 +50605,7 @@ function renderMecProcessDetail(out, p) {
49337
50605
  ["active:", p.is_active === true ? "yes" : p.is_active === false ? "no" : "-"],
49338
50606
  ["created:", dash5(p.create_time)]
49339
50607
  ];
49340
- writeTable30(out, rows);
50608
+ writeTable31(out, rows);
49341
50609
  out.write("\nsteps:\n");
49342
50610
  const steps = p.steps ?? [];
49343
50611
  if (steps.length === 0) {
@@ -49355,7 +50623,7 @@ function renderMecProcessDetail(out, p) {
49355
50623
  dash5(s.due_date)
49356
50624
  ]);
49357
50625
  }
49358
- writeTable30(out, stepRows);
50626
+ writeTable31(out, stepRows);
49359
50627
  }
49360
50628
  async function runMecStepGet(cfg) {
49361
50629
  await requireMec(cfg.client, { signal: cfg.signal });
@@ -49384,7 +50652,7 @@ function renderMecStepDetail(out, s) {
49384
50652
  ["starting_date:", dash5(s.starting_date)],
49385
50653
  ["due_date:", dash5(s.due_date)]
49386
50654
  ];
49387
- writeTable30(out, rows);
50655
+ writeTable31(out, rows);
49388
50656
  out.write("\ntasks:\n");
49389
50657
  const tasks = allStepTasks(s);
49390
50658
  if (tasks.length === 0) {
@@ -49409,7 +50677,7 @@ function renderMecTaskTable(out, tasks, indent) {
49409
50677
  reconciliationTagsSummary(t.reconciliation_tags)
49410
50678
  ]);
49411
50679
  }
49412
- writeTable30(out, tableRows);
50680
+ writeTable31(out, tableRows);
49413
50681
  }
49414
50682
  async function runMecTaskList(cfg) {
49415
50683
  await requireMec(cfg.client, { signal: cfg.signal });
@@ -49475,7 +50743,7 @@ function renderMecTaskDetail(out, t) {
49475
50743
  rows.push(["description:", dash5(nf.description)]);
49476
50744
  rows.push(["display_reviewer:", nf.display_reviewer ? "yes" : "no"]);
49477
50745
  }
49478
- writeTable30(out, rows);
50746
+ writeTable31(out, rows);
49479
50747
  }
49480
50748
  async function runMecMemberList(cfg) {
49481
50749
  await requireMec(cfg.client, { signal: cfg.signal });
@@ -49497,7 +50765,7 @@ function renderMecMemberList(out, rows) {
49497
50765
  for (const r of rows) {
49498
50766
  tableRows.push([dash5(r.id), dash5(r.email), memberRoleName(r.role), memberRoleId(r.role)]);
49499
50767
  }
49500
- writeTable30(out, tableRows);
50768
+ writeTable31(out, tableRows);
49501
50769
  out.write(`
49502
50770
  (${rows.length} member${plural(rows.length)})
49503
50771
  `);
@@ -49533,7 +50801,7 @@ async function runMecMemberCheck(cfg) {
49533
50801
  for (const d of docs) {
49534
50802
  tableRows.push([String(d.id), dash5(d.name)]);
49535
50803
  }
49536
- writeTable30(cfg.out, tableRows);
50804
+ writeTable31(cfg.out, tableRows);
49537
50805
  cfg.out.write(`
49538
50806
  (${docs.length} doc${plural(docs.length)})
49539
50807
  `);
@@ -49562,7 +50830,7 @@ function renderMecGroupList(out, rows) {
49562
50830
  dash5(typeof r.role === "string" ? r.role : r.role)
49563
50831
  ]);
49564
50832
  }
49565
- writeTable30(out, tableRows);
50833
+ writeTable31(out, tableRows);
49566
50834
  out.write(`
49567
50835
  (${rows.length} group${plural(rows.length)})
49568
50836
  `);
@@ -49585,7 +50853,7 @@ function renderMecPeriods(out, rows) {
49585
50853
  for (const r of rows) {
49586
50854
  tableRows.push([String(r), unixSecondsToYmd(r)]);
49587
50855
  }
49588
- writeTable30(out, tableRows);
50856
+ writeTable31(out, tableRows);
49589
50857
  out.write(`
49590
50858
  (${rows.length} period${plural(rows.length)})
49591
50859
  `);
@@ -49654,7 +50922,7 @@ async function runMecAccountsTaskStatuses(cfg) {
49654
50922
  renderMecAccountsTasksOrStatuses(cfg.out, resp, "statuses");
49655
50923
  }
49656
50924
  function shortHash4(input) {
49657
- return createHash11("sha256").update(input).digest("hex").slice(0, 12);
50925
+ return createHash12("sha256").update(input).digest("hex").slice(0, 12);
49658
50926
  }
49659
50927
  async function runMecWorkflowCreate(cfg) {
49660
50928
  const action = {
@@ -51907,7 +53175,7 @@ async function runMecCloseDatesSet(cfg) {
51907
53175
  cfg.out.write(`Updated ${monthCount} ${monthWord} across ${yearCount} ${yearWord}.
51908
53176
  `);
51909
53177
  }
51910
- function writeTable31(out, rows) {
53178
+ function writeTable32(out, rows) {
51911
53179
  if (rows.length === 0) return;
51912
53180
  const widths = [];
51913
53181
  for (const r of rows) {
@@ -51960,7 +53228,7 @@ function renderCloseDatesTable(out, map) {
51960
53228
  tableRows.push([String(r.year), String(r.month), String(r.rawValue), "-"]);
51961
53229
  }
51962
53230
  }
51963
- writeTable31(out, tableRows);
53231
+ writeTable32(out, tableRows);
51964
53232
  const word = rows.length === 1 ? "month" : "months";
51965
53233
  out.write(`
51966
53234
  (${rows.length} ${word})
@@ -52038,14 +53306,14 @@ function wireMec(program) {
52038
53306
  }
52039
53307
 
52040
53308
  // src/commands/workflow.ts
52041
- import { createHash as createHash12 } from "crypto";
53309
+ import { createHash as createHash13 } from "crypto";
52042
53310
  function dash6(s) {
52043
53311
  if (s === null || s === void 0) return "-";
52044
53312
  if (typeof s === "number") return String(s);
52045
53313
  if (s === "") return "-";
52046
53314
  return s;
52047
53315
  }
52048
- function writeTable32(out, rows) {
53316
+ function writeTable33(out, rows) {
52049
53317
  if (rows.length === 0) return;
52050
53318
  const widths = [];
52051
53319
  for (const r of rows) {
@@ -52146,7 +53414,7 @@ function renderWorkflowList(out, rows) {
52146
53414
  dash6(r.update_time)
52147
53415
  ]);
52148
53416
  }
52149
- writeTable32(out, tableRows);
53417
+ writeTable33(out, tableRows);
52150
53418
  out.write(`
52151
53419
  (${rows.length} workflow${plural(rows.length)})
52152
53420
  `);
@@ -52176,7 +53444,7 @@ function renderWorkflowDetail(out, t) {
52176
53444
  ["updated:", dash6(t.update_time)],
52177
53445
  ["process_start_time:", dash6(t.process_start_time)]
52178
53446
  ];
52179
- writeTable32(out, rows);
53447
+ writeTable33(out, rows);
52180
53448
  out.write("\n");
52181
53449
  const perms = t.permissions ?? [];
52182
53450
  out.write("permissions: ");
@@ -52191,7 +53459,7 @@ function renderWorkflowDetail(out, t) {
52191
53459
  for (const tag of tags) {
52192
53460
  tagRows.push([` ${tag.id}`, dash6(tag.name), dash6(tag.label), String(tag.value)]);
52193
53461
  }
52194
- writeTable32(out, tagRows);
53462
+ writeTable33(out, tagRows);
52195
53463
  }
52196
53464
  out.write("\nprocess_instances:\n");
52197
53465
  const instances = t.process_instances ?? [];
@@ -52207,7 +53475,7 @@ function renderWorkflowDetail(out, t) {
52207
53475
  dash6(pi.create_time)
52208
53476
  ]);
52209
53477
  }
52210
- writeTable32(out, piRows);
53478
+ writeTable33(out, piRows);
52211
53479
  }
52212
53480
  }
52213
53481
  async function runProcessList(cfg) {
@@ -52240,7 +53508,7 @@ function renderProcessList(out, rows) {
52240
53508
  dash6(r.create_time)
52241
53509
  ]);
52242
53510
  }
52243
- writeTable32(out, tableRows);
53511
+ writeTable33(out, tableRows);
52244
53512
  out.write(`
52245
53513
  (${rows.length} process${rows.length === 1 ? "" : "es"})
52246
53514
  `);
@@ -52268,7 +53536,7 @@ function renderProcessDetail(out, p) {
52268
53536
  ["active:", p.is_active === true ? "yes" : p.is_active === false ? "no" : "-"],
52269
53537
  ["created:", dash6(p.create_time)]
52270
53538
  ];
52271
- writeTable32(out, rows);
53539
+ writeTable33(out, rows);
52272
53540
  out.write("\nsteps:\n");
52273
53541
  const steps = p.steps ?? [];
52274
53542
  if (steps.length === 0) {
@@ -52286,7 +53554,7 @@ function renderProcessDetail(out, p) {
52286
53554
  dash6(s.due_date)
52287
53555
  ]);
52288
53556
  }
52289
- writeTable32(out, stepRows);
53557
+ writeTable33(out, stepRows);
52290
53558
  }
52291
53559
  async function runStepGet(cfg) {
52292
53560
  await requireWorkflowV2(cfg.client, { signal: cfg.signal });
@@ -52317,7 +53585,7 @@ function renderStepDetail(out, s) {
52317
53585
  ["starting_date:", dash6(s.starting_date)],
52318
53586
  ["due_date:", dash6(s.due_date)]
52319
53587
  ];
52320
- writeTable32(out, rows);
53588
+ writeTable33(out, rows);
52321
53589
  out.write("\ntasks:\n");
52322
53590
  const tasks = allStepTasks2(s);
52323
53591
  if (tasks.length === 0) {
@@ -52341,7 +53609,7 @@ function renderTaskTable(out, tasks, indent) {
52341
53609
  dash6(t.task_status)
52342
53610
  ]);
52343
53611
  }
52344
- writeTable32(out, tableRows);
53612
+ writeTable33(out, tableRows);
52345
53613
  }
52346
53614
  async function runTaskList(cfg) {
52347
53615
  await requireWorkflowV2(cfg.client, { signal: cfg.signal });
@@ -52408,7 +53676,7 @@ function renderTaskDetail(out, t) {
52408
53676
  rows.push(["description:", dash6(nf.description)]);
52409
53677
  rows.push(["display_reviewer:", nf.display_reviewer ? "yes" : "no"]);
52410
53678
  }
52411
- writeTable32(out, rows);
53679
+ writeTable33(out, rows);
52412
53680
  }
52413
53681
  async function runMemberList(cfg) {
52414
53682
  await requireWorkflowV2(cfg.client, { signal: cfg.signal });
@@ -52432,7 +53700,7 @@ function renderMemberList(out, rows) {
52432
53700
  for (const r of rows) {
52433
53701
  tableRows.push([dash6(r.id), dash6(r.email), memberRoleName2(r.role), memberRoleId2(r.role)]);
52434
53702
  }
52435
- writeTable32(out, tableRows);
53703
+ writeTable33(out, tableRows);
52436
53704
  out.write(`
52437
53705
  (${rows.length} member${plural(rows.length)})
52438
53706
  `);
@@ -52470,7 +53738,7 @@ async function runMemberCheck(cfg) {
52470
53738
  for (const d of docs) {
52471
53739
  tableRows.push([String(d.id), dash6(d.name)]);
52472
53740
  }
52473
- writeTable32(cfg.out, tableRows);
53741
+ writeTable33(cfg.out, tableRows);
52474
53742
  cfg.out.write(`
52475
53743
  (${docs.length} doc${plural(docs.length)})
52476
53744
  `);
@@ -52501,13 +53769,13 @@ function renderGroupList(out, rows) {
52501
53769
  dash6(typeof r.role === "string" ? r.role : r.role)
52502
53770
  ]);
52503
53771
  }
52504
- writeTable32(out, tableRows);
53772
+ writeTable33(out, tableRows);
52505
53773
  out.write(`
52506
53774
  (${rows.length} group${plural(rows.length)})
52507
53775
  `);
52508
53776
  }
52509
53777
  function shortHash5(input) {
52510
- return createHash12("sha256").update(input).digest("hex").slice(0, 12);
53778
+ return createHash13("sha256").update(input).digest("hex").slice(0, 12);
52511
53779
  }
52512
53780
  async function runWorkflowCreate(cfg) {
52513
53781
  const action = {
@@ -54666,7 +55934,7 @@ function wireWorkflow(root) {
54666
55934
  }
54667
55935
 
54668
55936
  // src/commands/cash.ts
54669
- import { createHash as createHash13 } from "crypto";
55937
+ import { createHash as createHash14 } from "crypto";
54670
55938
  import { promises as fs25 } from "fs";
54671
55939
 
54672
55940
  // src/api/cash.ts
@@ -55346,7 +56614,7 @@ function truncate7(s, max) {
55346
56614
  function dash7(s) {
55347
56615
  return s === null || s === void 0 || s === "" ? "-" : s;
55348
56616
  }
55349
- function writeTable33(out, rows) {
56617
+ function writeTable34(out, rows) {
55350
56618
  if (rows.length === 0) return;
55351
56619
  const widths = [];
55352
56620
  for (const r of rows) {
@@ -55401,7 +56669,7 @@ async function runCashCurrenciesList(cfg) {
55401
56669
  }
55402
56670
  const tableRows = [["CODE", "FULL_NAME"]];
55403
56671
  for (const r of rows) tableRows.push([r.code, r.full_name]);
55404
- writeTable33(cfg.out, tableRows);
56672
+ writeTable34(cfg.out, tableRows);
55405
56673
  cfg.out.write(`
55406
56674
  (${rows.length} currenc${rows.length === 1 ? "y" : "ies"})
55407
56675
  `);
@@ -55470,7 +56738,7 @@ function renderOrgCurrencies(out, rows) {
55470
56738
  r.is_system_default ? "yes" : ""
55471
56739
  ]);
55472
56740
  }
55473
- writeTable33(out, tableRows);
56741
+ writeTable34(out, tableRows);
55474
56742
  out.write(`
55475
56743
  (${rows.length} currenc${rows.length === 1 ? "y" : "ies"})
55476
56744
  `);
@@ -55506,7 +56774,7 @@ function renderTransactions(out, resp) {
55506
56774
  })
55507
56775
  );
55508
56776
  }
55509
- writeTable33(out, tableRows);
56777
+ writeTable34(out, tableRows);
55510
56778
  const shown = resp.results.length;
55511
56779
  const pageHint = resp.next !== null ? ` \u2014 next page: ${resp.next}` : "";
55512
56780
  out.write(`
@@ -55757,7 +57025,7 @@ async function runCashRulesDeleteAll(cfg) {
55757
57025
  return;
55758
57026
  }
55759
57027
  const ids = targets.map((r) => r.id).sort((a, b) => a - b);
55760
- const sha = createHash13("sha256").update(ids.join(",")).digest("hex").slice(0, 12);
57028
+ const sha = createHash14("sha256").update(ids.join(",")).digest("hex").slice(0, 12);
55761
57029
  const action = {
55762
57030
  resource: "cash-rules-batch",
55763
57031
  id: `${templateId}:${sha}`,
@@ -56131,7 +57399,7 @@ function renderRulesTable2(out, rules) {
56131
57399
  truncate3(dash7(r.description), 40)
56132
57400
  ]);
56133
57401
  }
56134
- writeTable33(out, rows);
57402
+ writeTable34(out, rows);
56135
57403
  out.write(`
56136
57404
  (${rules.length} rule${plural(rules.length)})
56137
57405
  `);
@@ -56935,7 +58203,7 @@ function renderManageCompanies(out, resp) {
56935
58203
  out.write("Groups:\n");
56936
58204
  const rows = [["NAME", "DOCUMENTS"]];
56937
58205
  for (const g of resp.groups) rows.push([dash8(g.name), formatDocs(g.documents)]);
56938
- writeTable34(out, rows);
58206
+ writeTable35(out, rows);
56939
58207
  out.write("\n");
56940
58208
  }
56941
58209
  if (resp.companies.length > 0) {
@@ -56950,7 +58218,7 @@ function renderManageCompanies(out, resp) {
56950
58218
  dashOrNull(e.group)
56951
58219
  ]);
56952
58220
  }
56953
- writeTable34(out, rows);
58221
+ writeTable35(out, rows);
56954
58222
  out.write(`
56955
58223
  (${resp.companies.length} entit${resp.companies.length === 1 ? "y" : "ies"})
56956
58224
  `);
@@ -56967,7 +58235,7 @@ function dashOrNull(s) {
56967
58235
  if (typeof s !== "string" || s === "") return "-";
56968
58236
  return s;
56969
58237
  }
56970
- function writeTable34(out, rows) {
58238
+ function writeTable35(out, rows) {
56971
58239
  if (rows.length === 0) return;
56972
58240
  const widths = [];
56973
58241
  for (const r of rows) {
@@ -57653,7 +58921,7 @@ async function runCalcmodelsDelete(cfg) {
57653
58921
  }
57654
58922
  });
57655
58923
  }
57656
- function writeTable35(out, rows) {
58924
+ function writeTable36(out, rows) {
57657
58925
  if (rows.length === 0) return;
57658
58926
  const widths = [];
57659
58927
  for (const r of rows) {
@@ -57709,7 +58977,7 @@ function renderCalcmodelTable(out, models) {
57709
58977
  ]
57710
58978
  });
57711
58979
  }
57712
- writeTable35(out, rows);
58980
+ writeTable36(out, rows);
57713
58981
  }
57714
58982
  function parseCalcmodelIdArg(idStr) {
57715
58983
  const n = Number(idStr);
@@ -58069,7 +59337,7 @@ async function runCalcValsDelete(cfg) {
58069
59337
  }
58070
59338
  });
58071
59339
  }
58072
- function writeTable36(out, rows) {
59340
+ function writeTable37(out, rows) {
58073
59341
  if (rows.length === 0) return;
58074
59342
  const widths = [];
58075
59343
  for (const r of rows) {
@@ -58107,7 +59375,7 @@ function renderCalcValTable(out, vals) {
58107
59375
  ]
58108
59376
  });
58109
59377
  }
58110
- writeTable36(out, rows);
59378
+ writeTable37(out, rows);
58111
59379
  }
58112
59380
  function parseCalcValIdArg(idStr) {
58113
59381
  const n = Number(idStr);
@@ -58408,7 +59676,7 @@ async function runCyclesList(cfg) {
58408
59676
  ]
58409
59677
  });
58410
59678
  }
58411
- writeTable37(cfg.out, tableRows);
59679
+ writeTable38(cfg.out, tableRows);
58412
59680
  }
58413
59681
  async function runCyclesGet(cfg) {
58414
59682
  const allScenarios = await listScenarios(cfg.client, {}, { signal: cfg.signal });
@@ -58451,7 +59719,7 @@ async function runCyclesGet(cfg) {
58451
59719
  ]
58452
59720
  });
58453
59721
  }
58454
- writeTable37(cfg.out, rows);
59722
+ writeTable38(cfg.out, rows);
58455
59723
  }
58456
59724
  cfg.out.write("\nRelated documents:\n");
58457
59725
  if (docIds.length === 0) {
@@ -58488,7 +59756,7 @@ async function runCyclesDocuments(cfg) {
58488
59756
  }
58489
59757
  rows.push({ cells: [String(id), name] });
58490
59758
  }
58491
- writeTable37(cfg.out, rows);
59759
+ writeTable38(cfg.out, rows);
58492
59760
  }
58493
59761
  async function runScenariosList(cfg) {
58494
59762
  const scenarios = await listScenarios(
@@ -58525,7 +59793,7 @@ async function runScenariosList(cfg) {
58525
59793
  ]
58526
59794
  });
58527
59795
  }
58528
- writeTable37(cfg.out, rows);
59796
+ writeTable38(cfg.out, rows);
58529
59797
  }
58530
59798
  async function runScenariosVersions(cfg) {
58531
59799
  const found = await findScenarioById(cfg.client, cfg.scenarioId, cfg.signal);
@@ -58561,7 +59829,7 @@ async function runScenariosVersions(cfg) {
58561
59829
  ]
58562
59830
  });
58563
59831
  }
58564
- writeTable37(cfg.out, rows);
59832
+ writeTable38(cfg.out, rows);
58565
59833
  }
58566
59834
  async function runScenariosGet(cfg) {
58567
59835
  const found = await findScenarioById(cfg.client, cfg.scenarioId, cfg.signal);
@@ -58635,7 +59903,7 @@ async function runScenariosGet(cfg) {
58635
59903
  ]
58636
59904
  });
58637
59905
  }
58638
- writeTable37(cfg.out, rows);
59906
+ writeTable38(cfg.out, rows);
58639
59907
  cfg.out.write("\n");
58640
59908
  }
58641
59909
  }
@@ -59196,7 +60464,7 @@ async function runScenariosBulkEdit(cfg) {
59196
60464
  }
59197
60465
  });
59198
60466
  }
59199
- function writeTable37(out, rows) {
60467
+ function writeTable38(out, rows) {
59200
60468
  if (rows.length === 0) return;
59201
60469
  const widths = [];
59202
60470
  for (const r of rows) {
@@ -61640,7 +62908,7 @@ function printVendorRows(out, items) {
61640
62908
  }
61641
62909
  rows.push({ cells });
61642
62910
  }
61643
- writeTable38(out, rows);
62911
+ writeTable39(out, rows);
61644
62912
  }
61645
62913
  var LISTING_FETCH = {
61646
62914
  all: listVendors,
@@ -61720,7 +62988,7 @@ async function runVendorCategories(cfg) {
61720
62988
  }
61721
62989
  const rows = [{ cells: ["VALUE", "DISPLAY NAME"] }];
61722
62990
  for (const c of items) rows.push({ cells: [c.value, c.display_name] });
61723
- writeTable38(cfg.out, rows);
62991
+ writeTable39(cfg.out, rows);
61724
62992
  cfg.out.write(`
61725
62993
  ${items.length} categor${items.length === 1 ? "y" : "ies"}.
61726
62994
  `);
@@ -61745,7 +63013,7 @@ async function runVendorOwners(cfg) {
61745
63013
  }
61746
63014
  const rows = [{ cells: ["VENDOR ID", "OWNER ID"] }];
61747
63015
  for (const o of ids) rows.push({ cells: [owners.id, String(o.owner_id)] });
61748
- writeTable38(cfg.out, rows);
63016
+ writeTable39(cfg.out, rows);
61749
63017
  cfg.out.write(`
61750
63018
  ${ids.length} owner(s).
61751
63019
  `);
@@ -62147,7 +63415,7 @@ function printAlertRows(out, items) {
62147
63415
  ]
62148
63416
  });
62149
63417
  }
62150
- writeTable38(out, rows);
63418
+ writeTable39(out, rows);
62151
63419
  }
62152
63420
  async function runAlertsList(cfg) {
62153
63421
  if (cfg.params.status === void 0) {
@@ -62242,7 +63510,7 @@ async function runAlertsDismiss(cfg) {
62242
63510
  });
62243
63511
  }
62244
63512
  }
62245
- writeTable38(cfg.out, rows);
63513
+ writeTable39(cfg.out, rows);
62246
63514
  cfg.out.write(
62247
63515
  `
62248
63516
  dismiss: ${cfg.alertIds.length - failed.length} ok, ${failed.length} failed.
@@ -62287,7 +63555,7 @@ async function runAlertSettingsGet(cfg) {
62287
63555
  rows.push({
62288
63556
  cells: ["user_ids", (s.user_ids ?? []).join(", ") || "(none)"]
62289
63557
  });
62290
- writeTable38(cfg.out, rows);
63558
+ writeTable39(cfg.out, rows);
62291
63559
  }
62292
63560
  async function runAlertSettingsUpdate(cfg) {
62293
63561
  if (Object.keys(cfg.changes).length === 0) {
@@ -62372,7 +63640,7 @@ async function runContractCategories(cfg) {
62372
63640
  }
62373
63641
  const rows = [{ cells: ["VALUE", "DISPLAY NAME"] }];
62374
63642
  for (const c of items) rows.push({ cells: [c.value, c.display_name] });
62375
- writeTable38(cfg.out, rows);
63643
+ writeTable39(cfg.out, rows);
62376
63644
  cfg.out.write(`
62377
63645
  ${items.length} categor${items.length === 1 ? "y" : "ies"}.
62378
63646
  `);
@@ -62401,7 +63669,7 @@ async function runContractHistory(cfg) {
62401
63669
  ]
62402
63670
  });
62403
63671
  }
62404
- writeTable38(cfg.out, rows);
63672
+ writeTable39(cfg.out, rows);
62405
63673
  cfg.out.write(`
62406
63674
  ${items.length} change(s).
62407
63675
  `);
@@ -62611,7 +63879,7 @@ var MIME_MAGIC = {
62611
63879
  function magicMatches(buf, mime) {
62612
63880
  return matchesAny(buf, MIME_MAGIC[mime] ?? []);
62613
63881
  }
62614
- function writeTable38(out, rows) {
63882
+ function writeTable39(out, rows) {
62615
63883
  if (rows.length === 0) return;
62616
63884
  const header = rows[0];
62617
63885
  const cols = header.cells.length;
@@ -62705,7 +63973,7 @@ async function runBillingFrequenciesList(cfg) {
62705
63973
  for (const bf of items) {
62706
63974
  rows.push({ cells: [bf.name, String(bf.period_months), bf.id] });
62707
63975
  }
62708
- writeTable38(cfg.out, rows);
63976
+ writeTable39(cfg.out, rows);
62709
63977
  }
62710
63978
  async function runExtractFromFiles(cfg) {
62711
63979
  if (cfg.files.length === 0) {
@@ -62937,7 +64205,7 @@ function printFileRows(out, items) {
62937
64205
  ]
62938
64206
  });
62939
64207
  }
62940
- writeTable38(out, rows);
64208
+ writeTable39(out, rows);
62941
64209
  }
62942
64210
  async function runFilesUpload(cfg) {
62943
64211
  if (cfg.files.length === 0) {
@@ -62978,7 +64246,7 @@ async function runFilesUpload(cfg) {
62978
64246
  if (cfg.asJson) {
62979
64247
  writeJSONIndented(cfg.out, { uploaded, failed: failures });
62980
64248
  } else {
62981
- writeTable38(cfg.out, rows);
64249
+ writeTable39(cfg.out, rows);
62982
64250
  cfg.out.write(`
62983
64251
  ${uploaded.length} uploaded, ${failedPaths.length} failed.
62984
64252
  `);
@@ -63111,7 +64379,7 @@ per-file results (${outcomes.length - failed.length} ok, ${failed.length} failed
63111
64379
  for (const o of outcomes) {
63112
64380
  rows.push({ cells: [o.path, o.ok ? "ok" : "FAILED", o.detail] });
63113
64381
  }
63114
- writeTable38(err, rows);
64382
+ writeTable39(err, rows);
63115
64383
  if (abortedMidRun) {
63116
64384
  err.write(
63117
64385
  `
@@ -63250,7 +64518,7 @@ batch ${i + 1}/${batches.length} failed: ${msg}
63250
64518
  ]
63251
64519
  });
63252
64520
  }
63253
- writeTable38(cfg.out, rows);
64521
+ writeTable39(cfg.out, rows);
63254
64522
  }
63255
64523
  });
63256
64524
  }
@@ -63302,7 +64570,7 @@ async function runContractUpdate(cfg) {
63302
64570
  String(updated.status)
63303
64571
  ]
63304
64572
  });
63305
- writeTable38(cfg.out, rows);
64573
+ writeTable39(cfg.out, rows);
63306
64574
  }
63307
64575
  var DESCRIBE_PREVIEW_ROWS3 = 5;
63308
64576
  var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
@@ -63492,7 +64760,7 @@ function printContractRows(out, items) {
63492
64760
  ]
63493
64761
  });
63494
64762
  }
63495
- writeTable38(out, rows);
64763
+ writeTable39(out, rows);
63496
64764
  }
63497
64765
  async function runContractsGet(cfg) {
63498
64766
  const contract = await getContract(
@@ -63516,7 +64784,7 @@ function reportIdOutcomes(out, outcomes, verb) {
63516
64784
  for (const o of outcomes) {
63517
64785
  rows.push({ cells: [o.id, o.ok ? "ok" : "FAILED", o.detail] });
63518
64786
  }
63519
- writeTable38(out, rows);
64787
+ writeTable39(out, rows);
63520
64788
  const failed = outcomes.filter((o) => !o.ok);
63521
64789
  const okCount = outcomes.length - failed.length;
63522
64790
  out.write(`
@@ -64268,7 +65536,7 @@ async function runRhConfigVersionTemplates(cfg) {
64268
65536
  }
64269
65537
  renderTemplateTable2(cfg.out, filteredData);
64270
65538
  }
64271
- function writeTable39(out, rows) {
65539
+ function writeTable40(out, rows) {
64272
65540
  if (rows.length === 0) return;
64273
65541
  const widths = [];
64274
65542
  for (const r of rows) {
@@ -64317,7 +65585,7 @@ function renderConfigInfo(out, info) {
64317
65585
  for (const t of info.tables) {
64318
65586
  rows.push({ cells: [t] });
64319
65587
  }
64320
- writeTable39(out, rows);
65588
+ writeTable40(out, rows);
64321
65589
  const n = info.tables.length;
64322
65590
  out.write(`
64323
65591
  (${n} table${n === 1 ? "" : "s"})
@@ -64340,7 +65608,7 @@ function renderTemplateTable2(out, templates) {
64340
65608
  ]
64341
65609
  });
64342
65610
  }
64343
- writeTable39(out, rows);
65611
+ writeTable40(out, rows);
64344
65612
  }
64345
65613
  function parsePositiveIdArg(label, raw) {
64346
65614
  const n = Number(raw);
@@ -64496,7 +65764,7 @@ async function runProductContentList(cfg) {
64496
65764
  }
64497
65765
  const rows = [["ID", "NAME", "TYPE"]];
64498
65766
  for (const pc of resp) rows.push([String(pc.id), pc.name, pc.type]);
64499
- writeTable40(cfg.out, rows);
65767
+ writeTable41(cfg.out, rows);
64500
65768
  cfg.out.write(`
64501
65769
  (${resp.length} row${plural(resp.length)})
64502
65770
  `);
@@ -64584,7 +65852,7 @@ function countItems(body) {
64584
65852
  for (const g of body) items += g.items.length;
64585
65853
  return { items, groups: body.length };
64586
65854
  }
64587
- function writeTable40(out, rows) {
65855
+ function writeTable41(out, rows) {
64588
65856
  if (rows.length === 0) return;
64589
65857
  const widths = [];
64590
65858
  for (const r of rows) {
@@ -64888,7 +66156,7 @@ function writeWarnings(out, warnings) {
64888
66156
  for (const w of warnings) out.write(`warning: ${w}
64889
66157
  `);
64890
66158
  }
64891
- function writeTable41(out, rows) {
66159
+ function writeTable42(out, rows) {
64892
66160
  if (rows.length === 0) return;
64893
66161
  const widths = [];
64894
66162
  for (const r of rows) {
@@ -64923,7 +66191,7 @@ async function runTeamsList(cfg) {
64923
66191
  for (const t of resp.teams) {
64924
66192
  rows.push([String(t.team_id), t.name ?? "", t.support_email ?? "(none set)"]);
64925
66193
  }
64926
- writeTable41(cfg.out, rows);
66194
+ writeTable42(cfg.out, rows);
64927
66195
  cfg.out.write(`
64928
66196
  (${resp.teams.length} team${plural(resp.teams.length)})
64929
66197
  `);
@@ -65346,7 +66614,7 @@ function renderSendgridStatus(out, resp, asJson) {
65346
66614
  r.valid === true ? "yes" : r.valid === false ? "NO" : "-"
65347
66615
  ]);
65348
66616
  }
65349
- writeTable41(out, rows);
66617
+ writeTable42(out, rows);
65350
66618
  for (const r of resp.records) {
65351
66619
  if (r.valid === false && r.reason !== void 0 && r.reason !== null && r.reason !== "") {
65352
66620
  out.write(` ${r.name}: ${r.reason}
@@ -66126,7 +67394,7 @@ function writeCloneReport(out, report) {
66126
67394
  String(t.members_added.length) + (t.members_unmapped.length > 0 ? ` (${t.members_unmapped.length} unmapped)` : "")
66127
67395
  ]);
66128
67396
  }
66129
- writeTable41(out, rows);
67397
+ writeTable42(out, rows);
66130
67398
  const tables = report.import_result.tables;
66131
67399
  const counts = Object.entries(tables).filter(([, c]) => c.imported + c.skipped + c.updated > 0).map(([name, c]) => `${name}: ${c.imported} imported, ${c.skipped} skipped`);
66132
67400
  out.write(`
@@ -66581,7 +67849,7 @@ function parsePaletteFile(raw) {
66581
67849
  }
66582
67850
  return payload;
66583
67851
  }
66584
- function writeTable42(out, rows) {
67852
+ function writeTable43(out, rows) {
66585
67853
  if (rows.length === 0) return;
66586
67854
  const widths = [];
66587
67855
  for (const r of rows) {
@@ -66621,7 +67889,7 @@ function renderPalettesTable(out, palettes) {
66621
67889
  ]
66622
67890
  });
66623
67891
  }
66624
- writeTable42(out, rows);
67892
+ writeTable43(out, rows);
66625
67893
  }
66626
67894
  function renderColorsPreview(colors) {
66627
67895
  if (colors.length === 0) return "(none)";