@hasna/domains 0.0.36 → 0.0.37

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/index.js CHANGED
@@ -16256,6 +16256,9 @@ function normalizeDnsRecordType(value) {
16256
16256
  }
16257
16257
  return recordType3;
16258
16258
  }
16259
+ function getVcardPropertyValue(entry) {
16260
+ return entry.length >= 4 ? entry[3] : entry[2];
16261
+ }
16259
16262
  async function rdapLookup(domainName) {
16260
16263
  const domain = normalizeDomainName(domainName);
16261
16264
  const url = `https://rdap.org/domain/${encodeURIComponent(domain)}`;
@@ -16304,17 +16307,19 @@ function extractRegistrantFromRdap(rdap) {
16304
16307
  for (const entry of vcard) {
16305
16308
  if (!Array.isArray(entry) || entry.length < 3)
16306
16309
  continue;
16307
- const [prop, _params, type] = entry;
16310
+ const [prop] = entry;
16311
+ const value = getVcardPropertyValue(entry);
16308
16312
  if (prop === "fn")
16309
- result.name = type ?? null;
16313
+ result.name = typeof value === "string" ? value : null;
16310
16314
  else if (prop === "email")
16311
- result.email = type ?? null;
16315
+ result.email = typeof value === "string" ? value : null;
16312
16316
  else if (prop === "tel")
16313
- result.phone = type ?? null;
16317
+ result.phone = typeof value === "string" ? value : null;
16314
16318
  else if (prop === "org") {
16315
- result.organization = Array.isArray(type) ? type[0] ?? null : type ?? null;
16319
+ const organization = Array.isArray(value) ? value[0] : value;
16320
+ result.organization = typeof organization === "string" ? organization : null;
16316
16321
  } else if (prop === "n" && !result.name) {
16317
- const parts = Array.isArray(type) ? type.filter(Boolean) : [type];
16322
+ const parts = Array.isArray(value) ? value.filter((part) => typeof part === "string" && part.length > 0) : typeof value === "string" ? [value] : [];
16318
16323
  result.name = parts.reverse().join(" ").trim() || null;
16319
16324
  }
16320
16325
  }
@@ -16331,8 +16336,10 @@ function extractRegistrarFromRdap(rdap) {
16331
16336
  if (entity.vcardArray?.[1]) {
16332
16337
  const vcard = entity.vcardArray[1];
16333
16338
  for (const entry of vcard) {
16334
- if (Array.isArray(entry) && entry[0] === "fn")
16335
- return entry[2] ?? null;
16339
+ if (Array.isArray(entry) && entry[0] === "fn") {
16340
+ const value = getVcardPropertyValue(entry);
16341
+ return typeof value === "string" ? value : null;
16342
+ }
16336
16343
  }
16337
16344
  }
16338
16345
  if (entity.remarks) {
@@ -28939,7 +28946,7 @@ var init_bowser = __esm(() => {
28939
28946
 
28940
28947
  // node_modules/@aws-sdk/core/dist-cjs/submodules/client/index.js
28941
28948
  var require_client2 = __commonJS((exports) => {
28942
- var __dirname = "/home/hasna/.hasna/repos/worktrees/open-domains/282f5cec-baae-438a-beed-bdf090475f02/node_modules/@aws-sdk/core/dist-cjs/submodules/client";
28949
+ var __dirname = "/home/hasna/.hasna/repos/worktrees/open-domains/2a0dcf21-d730-4a74-bfc3-12e59e51ecd5/node_modules/@aws-sdk/core/dist-cjs/submodules/client";
28943
28950
  var retry = require_retry();
28944
28951
  var protocols = require_protocols();
28945
28952
  var lambdaInvokeStore = require_invoke_store();
@@ -51383,6 +51390,65 @@ function compactHint(page, noun, detailHint, options = {}) {
51383
51390
  }
51384
51391
  var DEFAULT_LIST_LIMIT = 20, MAX_LIST_LIMIT = 200;
51385
51392
 
51393
+ // src/lib/stdout.ts
51394
+ import { writeSync } from "fs";
51395
+ import { format } from "util";
51396
+ function awaitDrain() {
51397
+ Atomics.wait(backpressureWait, 0, 0, BACKPRESSURE_WAIT_MS);
51398
+ }
51399
+ function errorCodeOf(error) {
51400
+ if (typeof error !== "object" || error === null)
51401
+ return null;
51402
+ const code = error.code;
51403
+ return typeof code === "string" ? code : null;
51404
+ }
51405
+ function writeAllBytesSync(bytes, writer) {
51406
+ let offset = 0;
51407
+ while (offset < bytes.length) {
51408
+ let accepted;
51409
+ try {
51410
+ accepted = writer(bytes.subarray(offset));
51411
+ } catch (error) {
51412
+ const code = errorCodeOf(error);
51413
+ if (code === "EAGAIN" || code === "EWOULDBLOCK") {
51414
+ awaitDrain();
51415
+ continue;
51416
+ }
51417
+ if (code === "EPIPE" || code === "ERR_STREAM_DESTROYED")
51418
+ return "reader-closed";
51419
+ throw error;
51420
+ }
51421
+ if (accepted <= 0) {
51422
+ awaitDrain();
51423
+ continue;
51424
+ }
51425
+ offset += accepted;
51426
+ }
51427
+ return "complete";
51428
+ }
51429
+ function writeAllSync(text, writer) {
51430
+ return writeAllBytesSync(Buffer.from(text, "utf8"), writer);
51431
+ }
51432
+ function writeStdout(text, writer = stdoutWriter) {
51433
+ return writeAllSync(text, writer);
51434
+ }
51435
+ function formatLine(...args) {
51436
+ return `${format(...args)}
51437
+ `;
51438
+ }
51439
+ function printLine(...args) {
51440
+ return writeStdout(formatLine(...args));
51441
+ }
51442
+ function printErrorLine(...args) {
51443
+ return writeAllSync(formatLine(...args), stderrWriter);
51444
+ }
51445
+ var BACKPRESSURE_WAIT_MS = 1, backpressureWait, fdWriter = (fd) => (chunk) => writeSync(fd, chunk), stdoutWriter, stderrWriter;
51446
+ var init_stdout = __esm(() => {
51447
+ backpressureWait = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
51448
+ stdoutWriter = fdWriter(1);
51449
+ stderrWriter = fdWriter(2);
51450
+ });
51451
+
51386
51452
  // src/db/history.ts
51387
51453
  function createHistoryEntry2(input) {
51388
51454
  return getStore().createHistoryEntry(input);
@@ -51772,22 +51838,22 @@ function registerMonitorCommand(program2) {
51772
51838
  try {
51773
51839
  const result = await monitorBrand(brand);
51774
51840
  if (opts.json) {
51775
- console.log(JSON.stringify(result, null, 2));
51841
+ printLine(JSON.stringify(result, null, 2));
51776
51842
  return;
51777
51843
  }
51778
51844
  const page = pageItemsOrExit(result.alerts, { limit: opts.limit, all: opts.all });
51779
- console.log(`Monitor: ${result.brand}${result.stub ? " [stub]" : ""}`);
51845
+ printLine(`Monitor: ${result.brand}${result.stub ? " [stub]" : ""}`);
51780
51846
  if (page.items.length === 0) {
51781
- console.log("No alerts.");
51847
+ printLine("No alerts.");
51782
51848
  return;
51783
51849
  }
51784
51850
  for (const alert of page.items) {
51785
- console.log(` ${alert.domain} [${alert.type}] registered:${alert.registered_at}`);
51851
+ printLine(` ${alert.domain} [${alert.type}] registered:${alert.registered_at}`);
51786
51852
  }
51787
- console.log(`
51853
+ printLine(`
51788
51854
  ${compactHint(page, "alert(s)", "Use --all for every alert or --json for full monitor details.", { paging: "limit" })}`);
51789
51855
  } catch (e4) {
51790
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
51856
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
51791
51857
  process.exit(1);
51792
51858
  }
51793
51859
  });
@@ -51795,21 +51861,21 @@ ${compactHint(page, "alert(s)", "Use --all for every alert or --json for full mo
51795
51861
  try {
51796
51862
  const result = await getSimilarDomains(domain);
51797
51863
  if (opts.json) {
51798
- console.log(JSON.stringify(result, null, 2));
51864
+ printLine(JSON.stringify(result, null, 2));
51799
51865
  return;
51800
51866
  }
51801
51867
  const page = pageItemsOrExit(result.similar, { limit: opts.limit, all: opts.all });
51802
- console.log(`Similar domains for ${result.domain}${result.stub ? " [stub]" : ""}:`);
51868
+ printLine(`Similar domains for ${result.domain}${result.stub ? " [stub]" : ""}:`);
51803
51869
  if (page.items.length === 0) {
51804
- console.log("No similar domains found.");
51870
+ printLine("No similar domains found.");
51805
51871
  return;
51806
51872
  }
51807
51873
  for (const name of page.items)
51808
- console.log(` ${name}`);
51809
- console.log(`
51874
+ printLine(` ${name}`);
51875
+ printLine(`
51810
51876
  ${compactHint(page, "domain(s)", "Use --all for every result or --json for full response metadata.", { paging: "limit" })}`);
51811
51877
  } catch (e4) {
51812
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
51878
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
51813
51879
  process.exit(1);
51814
51880
  }
51815
51881
  });
@@ -51817,28 +51883,29 @@ ${compactHint(page, "domain(s)", "Use --all for every result or --json for full
51817
51883
  try {
51818
51884
  const result = await getThreatAssessment(domain);
51819
51885
  if (opts.json) {
51820
- console.log(JSON.stringify(result, null, 2));
51886
+ printLine(JSON.stringify(result, null, 2));
51821
51887
  return;
51822
51888
  }
51823
51889
  const page = pageItemsOrExit(result.threats, { limit: opts.limit, all: opts.all });
51824
- console.log(`Threat assessment for ${result.domain}${result.stub ? " [stub]" : ""}: ${result.risk_level}`);
51890
+ printLine(`Threat assessment for ${result.domain}${result.stub ? " [stub]" : ""}: ${result.risk_level}`);
51825
51891
  if (page.items.length === 0) {
51826
- console.log("No immediate threats detected.");
51892
+ printLine("No immediate threats detected.");
51827
51893
  } else {
51828
51894
  for (const threat of page.items)
51829
- console.log(` - ${truncateText(threat, 100)}`);
51895
+ printLine(` - ${truncateText(threat, 100)}`);
51830
51896
  }
51831
- console.log(`Recommendation: ${truncateText(result.recommendation, 140)}`);
51832
- console.log(`
51897
+ printLine(`Recommendation: ${truncateText(result.recommendation, 140)}`);
51898
+ printLine(`
51833
51899
  ${compactHint(page, "threat(s)", "Use --all for every threat or --json for the full assessment.", { paging: "limit" })}`);
51834
51900
  } catch (e4) {
51835
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
51901
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
51836
51902
  process.exit(1);
51837
51903
  }
51838
51904
  });
51839
51905
  }
51840
51906
  var init_monitor = __esm(() => {
51841
51907
  init_brandsight();
51908
+ init_stdout();
51842
51909
  });
51843
51910
 
51844
51911
  // src/cli/commands/sedo.ts
@@ -51851,7 +51918,7 @@ function parseSedoLimit(value, fallback) {
51851
51918
  return fallback;
51852
51919
  const parsed = Number(value);
51853
51920
  if (!Number.isInteger(parsed) || parsed < 0) {
51854
- console.error("--limit must be a non-negative integer");
51921
+ printErrorLine("--limit must be a non-negative integer");
51855
51922
  process.exit(1);
51856
51923
  }
51857
51924
  return parsed;
@@ -51868,19 +51935,19 @@ function registerSedoCommand(program2) {
51868
51935
  maxPrice: opts.maxPrice ? parseInt(opts.maxPrice) : undefined
51869
51936
  });
51870
51937
  if (opts.json) {
51871
- console.log(JSON.stringify(result, null, 2));
51938
+ printLine(JSON.stringify(result, null, 2));
51872
51939
  } else {
51873
51940
  if (result.domains.length === 0) {
51874
- console.log(`No domains found for "${keyword}".`);
51941
+ printLine(`No domains found for "${keyword}".`);
51875
51942
  return;
51876
51943
  }
51877
- console.log(`Sedo marketplace \u2014 "${keyword}" (${result.total} total):`);
51944
+ printLine(`Sedo marketplace \u2014 "${keyword}" (${result.total} total):`);
51878
51945
  for (const d4 of result.domains) {
51879
51946
  const price = d4.price ? ` \u2014 ${d4.price.toLocaleString()} ${d4.currency || ""}`.trimEnd() : " \u2014 make offer";
51880
51947
  const premium = d4.isPremium ? " [PREMIUM]" : "";
51881
- console.log(` ${d4.domain}${price}${premium}`);
51948
+ printLine(` ${d4.domain}${price}${premium}`);
51882
51949
  }
51883
- console.log(`
51950
+ printLine(`
51884
51951
  Showing ${result.domains.length}/${result.total} marketplace result(s). Use --limit <n> for more or --json for full fields.`);
51885
51952
  }
51886
51953
  });
@@ -51888,12 +51955,12 @@ Showing ${result.domains.length}/${result.total} marketplace result(s). Use --li
51888
51955
  const { checkSedoStatus: checkSedoStatus2 } = await Promise.resolve().then(() => (init_sedo(), exports_sedo));
51889
51956
  const results = await checkSedoStatus2(domains);
51890
51957
  if (opts.json) {
51891
- console.log(JSON.stringify(results, null, 2));
51958
+ printLine(JSON.stringify(results, null, 2));
51892
51959
  } else {
51893
51960
  for (const r4 of results) {
51894
51961
  const listed = r4.listed ? "listed" : "not listed";
51895
51962
  const sale = r4.forSale ? ` for sale (${r4.price || "?"} ${r4.currency || ""})` : "";
51896
- console.log(` ${r4.domain}: ${listed}${sale}`);
51963
+ printLine(` ${r4.domain}: ${listed}${sale}`);
51897
51964
  }
51898
51965
  }
51899
51966
  });
@@ -51902,19 +51969,19 @@ Showing ${result.domains.length}/${result.total} marketplace result(s). Use --li
51902
51969
  const limit = parseSedoLimit(opts.limit, opts.json || opts.all ? 100 : 20);
51903
51970
  const domains = await listSedoPortfolio2({ limit });
51904
51971
  if (opts.json) {
51905
- console.log(JSON.stringify(domains, null, 2));
51972
+ printLine(JSON.stringify(domains, null, 2));
51906
51973
  } else {
51907
51974
  if (domains.length === 0) {
51908
- console.log("No domains in your Sedo portfolio.");
51975
+ printLine("No domains in your Sedo portfolio.");
51909
51976
  return;
51910
51977
  }
51911
51978
  const page = pageItemsOrExit(domains, { limit: opts.limit, all: opts.all });
51912
- console.log(`Sedo Portfolio:`);
51979
+ printLine(`Sedo Portfolio:`);
51913
51980
  for (const d4 of page.items) {
51914
51981
  const sale = d4.forSale ? `[for sale ${d4.price || "?"} ${d4.currency || ""}]` : "";
51915
- console.log(` ${d4.domain} ${sale}`);
51982
+ printLine(` ${d4.domain} ${sale}`);
51916
51983
  }
51917
- console.log(`
51984
+ printLine(`
51918
51985
  ${compactHint(page, "domain(s)", "Use --limit <n> for more or --json for full marketplace fields.", { paging: "limit" })}`);
51919
51986
  }
51920
51987
  });
@@ -51929,9 +51996,9 @@ ${compactHint(page, "domain(s)", "Use --limit <n> for more or --json for full ma
51929
51996
  buyNowPrice: opts.buyNowPrice ? parseInt(opts.buyNowPrice) : undefined
51930
51997
  });
51931
51998
  if (opts.json) {
51932
- console.log(JSON.stringify(result, null, 2));
51999
+ printLine(JSON.stringify(result, null, 2));
51933
52000
  } else {
51934
- console.log(`Added ${domain} to Sedo marketplace`);
52001
+ printLine(`Added ${domain} to Sedo marketplace`);
51935
52002
  }
51936
52003
  });
51937
52004
  sedo.command("edit").description("Update an existing domain on Sedo").argument("<domain>", "Domain name to update").option("--price <n>", "New asking price").option("--currency <currency>", "Currency").option("--buy-now-price <n>", "New buy-it-now price").option("--json", "Output as JSON", false).action(async (domain, opts) => {
@@ -51943,18 +52010,18 @@ ${compactHint(page, "domain(s)", "Use --limit <n> for more or --json for full ma
51943
52010
  buyNowPrice: opts.buyNowPrice ? parseInt(opts.buyNowPrice) : undefined
51944
52011
  });
51945
52012
  if (opts.json) {
51946
- console.log(JSON.stringify(result, null, 2));
52013
+ printLine(JSON.stringify(result, null, 2));
51947
52014
  } else {
51948
- console.log(`Updated ${domain} on Sedo`);
52015
+ printLine(`Updated ${domain} on Sedo`);
51949
52016
  }
51950
52017
  });
51951
52018
  sedo.command("remove").description("Remove a domain from Sedo marketplace").argument("<domain>", "Domain name to remove").action(async (domain) => {
51952
52019
  const { removeDomainFromSedo: removeDomainFromSedo2 } = await Promise.resolve().then(() => (init_sedo(), exports_sedo));
51953
52020
  const removed = await removeDomainFromSedo2(domain);
51954
52021
  if (removed) {
51955
- console.log(`Removed ${domain} from Sedo marketplace`);
52022
+ printLine(`Removed ${domain} from Sedo marketplace`);
51956
52023
  } else {
51957
- console.error(`Failed to remove ${domain} from Sedo`);
52024
+ printErrorLine(`Failed to remove ${domain} from Sedo`);
51958
52025
  process.exit(1);
51959
52026
  }
51960
52027
  });
@@ -51962,10 +52029,10 @@ ${compactHint(page, "domain(s)", "Use --limit <n> for more or --json for full ma
51962
52029
  const { checkSedoBlacklist: checkSedoBlacklist2 } = await Promise.resolve().then(() => (init_sedo(), exports_sedo));
51963
52030
  const results = await checkSedoBlacklist2(domains);
51964
52031
  if (opts.json) {
51965
- console.log(JSON.stringify(results, null, 2));
52032
+ printLine(JSON.stringify(results, null, 2));
51966
52033
  } else {
51967
52034
  for (const r4 of results) {
51968
- console.log(` ${r4.domain}: ${r4.blacklisted ? "BLACKLISTED" : "clean"}`);
52035
+ printLine(` ${r4.domain}: ${r4.blacklisted ? "BLACKLISTED" : "clean"}`);
51969
52036
  }
51970
52037
  }
51971
52038
  });
@@ -51974,13 +52041,15 @@ ${compactHint(page, "domain(s)", "Use --limit <n> for more or --json for full ma
51974
52041
  const price = parseInt(opts.price);
51975
52042
  const created = recordSedoPurchase2(domain, price, opts.orderId);
51976
52043
  if (opts.json) {
51977
- console.log(JSON.stringify(created, null, 2));
52044
+ printLine(JSON.stringify(created, null, 2));
51978
52045
  } else {
51979
- console.log(`Recorded Sedo purchase: ${domain} for $${price}`);
52046
+ printLine(`Recorded Sedo purchase: ${domain} for $${price}`);
51980
52047
  }
51981
52048
  });
51982
52049
  }
51983
- var init_sedo2 = () => {};
52050
+ var init_sedo2 = __esm(() => {
52051
+ init_stdout();
52052
+ });
51984
52053
 
51985
52054
  // src/db/owners.ts
51986
52055
  function createDomainOwner2(input) {
@@ -52073,7 +52142,7 @@ __export(exports_owner, {
52073
52142
  async function requireDomain2(identifier) {
52074
52143
  const details = await getDomainDetails2(identifier);
52075
52144
  if (!details) {
52076
- console.error(`Domain '${identifier}' not found.`);
52145
+ printErrorLine(`Domain '${identifier}' not found.`);
52077
52146
  process.exit(1);
52078
52147
  }
52079
52148
  return details;
@@ -52084,21 +52153,21 @@ function registerOwnerCommand(program2) {
52084
52153
  if (opts.withDomains) {
52085
52154
  const results = await listDomainsWithOwners2();
52086
52155
  if (opts.json) {
52087
- console.log(JSON.stringify({ owners: results, count: results.length }, null, 2));
52156
+ printLine(JSON.stringify({ owners: results, count: results.length }, null, 2));
52088
52157
  return;
52089
52158
  }
52090
52159
  const page2 = pageItemsOrExit(results, { limit: opts.limit, all: opts.all });
52091
52160
  if (page2.items.length === 0) {
52092
- console.log("No premium domain owners found.");
52161
+ printLine("No premium domain owners found.");
52093
52162
  return;
52094
52163
  }
52095
52164
  for (const r4 of page2.items) {
52096
52165
  const verified = r4.verified ? " [verified]" : "";
52097
52166
  const org = r4.owner_organization ? ` @ ${r4.owner_organization}` : "";
52098
52167
  const email = opts.verbose && r4.owner_email ? ` email:${r4.owner_email}` : "";
52099
- console.log(` ${r4.domain_name} (${r4.domain_status}) \u2014 ${r4.owner_name ?? r4.owner_email ?? "unknown"}${org}${verified}${email}`);
52168
+ printLine(` ${r4.domain_name} (${r4.domain_status}) \u2014 ${r4.owner_name ?? r4.owner_email ?? "unknown"}${org}${verified}${email}`);
52100
52169
  }
52101
- console.log(`
52170
+ printLine(`
52102
52171
  ${compactHint(page2, "domain(s) with owner info", "Use --verbose for email details or owner info <domain> for full details.", { paging: "limit" })}`);
52103
52172
  return;
52104
52173
  }
@@ -52108,87 +52177,87 @@ ${compactHint(page2, "domain(s) with owner info", "Use --verbose for email detai
52108
52177
  verified: opts.verifiedOnly ? true : undefined
52109
52178
  });
52110
52179
  if (opts.json) {
52111
- console.log(JSON.stringify({ owners, count: owners.length }, null, 2));
52180
+ printLine(JSON.stringify({ owners, count: owners.length }, null, 2));
52112
52181
  return;
52113
52182
  }
52114
52183
  const page = pageItemsOrExit(owners, { limit: opts.limit, all: opts.all });
52115
52184
  if (page.items.length === 0) {
52116
- console.log("No owners found.");
52185
+ printLine("No owners found.");
52117
52186
  return;
52118
52187
  }
52119
52188
  for (const o2 of page.items) {
52120
52189
  const verified = o2.verified ? " [verified]" : "";
52121
52190
  const org = o2.owner_organization ? ` @ ${o2.owner_organization}` : "";
52122
- console.log(` ${truncateText(o2.owner_name ?? o2.owner_email ?? "unknown", 48)}${org} [${o2.source}]${verified}`);
52191
+ printLine(` ${truncateText(o2.owner_name ?? o2.owner_email ?? "unknown", 48)}${org} [${o2.source}]${verified}`);
52123
52192
  if (opts.verbose && o2.owner_email)
52124
- console.log(` email: ${o2.owner_email}`);
52193
+ printLine(` email: ${o2.owner_email}`);
52125
52194
  if (opts.verbose && o2.owner_phone)
52126
- console.log(` phone: ${o2.owner_phone}`);
52195
+ printLine(` phone: ${o2.owner_phone}`);
52127
52196
  }
52128
- console.log(`
52197
+ printLine(`
52129
52198
  ${compactHint(page, "owner(s)", "Use --verbose for contact fields or owner get <id> for details.", { paging: "limit" })}`);
52130
52199
  });
52131
52200
  owner.command("get <ownerId>").description("Get owner details by ID").option("-j, --json", "Output JSON").action(async (ownerId, opts) => {
52132
52201
  const o2 = await getDomainOwner2(ownerId);
52133
52202
  if (!o2) {
52134
- console.error(`Owner '${ownerId}' not found.`);
52203
+ printErrorLine(`Owner '${ownerId}' not found.`);
52135
52204
  process.exit(1);
52136
52205
  }
52137
52206
  if (opts.json) {
52138
- console.log(JSON.stringify(o2, null, 2));
52207
+ printLine(JSON.stringify(o2, null, 2));
52139
52208
  return;
52140
52209
  }
52141
- console.log(`
52210
+ printLine(`
52142
52211
  Owner: ${o2.owner_name ?? o2.owner_email ?? "unknown"}`);
52143
52212
  if (o2.owner_organization)
52144
- console.log(` Organization: ${o2.owner_organization}`);
52213
+ printLine(` Organization: ${o2.owner_organization}`);
52145
52214
  if (o2.owner_email)
52146
- console.log(` Email: ${o2.owner_email}`);
52215
+ printLine(` Email: ${o2.owner_email}`);
52147
52216
  if (o2.owner_phone)
52148
- console.log(` Phone: ${o2.owner_phone}`);
52149
- console.log(` Source: ${o2.source}`);
52150
- console.log(` Verified: ${o2.verified ? "yes" : "no"}`);
52217
+ printLine(` Phone: ${o2.owner_phone}`);
52218
+ printLine(` Source: ${o2.source}`);
52219
+ printLine(` Verified: ${o2.verified ? "yes" : "no"}`);
52151
52220
  if (o2.contact_id)
52152
- console.log(` Contacts ID: ${o2.contact_id}`);
52221
+ printLine(` Contacts ID: ${o2.contact_id}`);
52153
52222
  if (o2.notes)
52154
- console.log(` Notes: ${truncateText(o2.notes, 160)}`);
52155
- console.log();
52223
+ printLine(` Notes: ${truncateText(o2.notes, 160)}`);
52224
+ printLine();
52156
52225
  });
52157
52226
  owner.command("info <identifier>").description("Show owner info for a specific domain").option("-j, --json", "Output JSON").action(async (identifier, opts) => {
52158
52227
  const details = await requireDomain2(identifier);
52159
52228
  const o2 = await getDomainOwnerByDomain2(details.domain.id);
52160
52229
  if (!o2) {
52161
52230
  if (opts.json) {
52162
- console.log(JSON.stringify({ domain: details.domain.name, owner: null }, null, 2));
52231
+ printLine(JSON.stringify({ domain: details.domain.name, owner: null }, null, 2));
52163
52232
  return;
52164
52233
  }
52165
- console.log(`No owner info for ${details.domain.name}.`);
52234
+ printLine(`No owner info for ${details.domain.name}.`);
52166
52235
  return;
52167
52236
  }
52168
52237
  const result = { domain: details.domain.name, owner: o2 };
52169
52238
  if (opts.json) {
52170
- console.log(JSON.stringify(result, null, 2));
52239
+ printLine(JSON.stringify(result, null, 2));
52171
52240
  return;
52172
52241
  }
52173
- console.log(`
52242
+ printLine(`
52174
52243
  Domain: ${details.domain.name} [${details.domain.status}]`);
52175
- console.log(` Owner: ${o2.owner_name ?? o2.owner_email ?? "unknown"}`);
52244
+ printLine(` Owner: ${o2.owner_name ?? o2.owner_email ?? "unknown"}`);
52176
52245
  if (o2.owner_organization)
52177
- console.log(` Organization: ${o2.owner_organization}`);
52246
+ printLine(` Organization: ${o2.owner_organization}`);
52178
52247
  if (o2.owner_email)
52179
- console.log(` Email: ${o2.owner_email}`);
52248
+ printLine(` Email: ${o2.owner_email}`);
52180
52249
  if (o2.owner_phone)
52181
- console.log(` Phone: ${o2.owner_phone}`);
52182
- console.log(` Source: ${o2.source}`);
52183
- console.log(` Verified: ${o2.verified ? "yes" : "no"}`);
52250
+ printLine(` Phone: ${o2.owner_phone}`);
52251
+ printLine(` Source: ${o2.source}`);
52252
+ printLine(` Verified: ${o2.verified ? "yes" : "no"}`);
52184
52253
  if (o2.contact_id)
52185
- console.log(` Contacts ID: ${o2.contact_id}`);
52186
- console.log();
52254
+ printLine(` Contacts ID: ${o2.contact_id}`);
52255
+ printLine();
52187
52256
  });
52188
52257
  owner.command("add <identifier>").description("Add owner info for a domain").option("--name <name>", "Owner name").option("--email <email>", "Owner email").option("--phone <phone>", "Owner phone").option("--organization <org>", "Owner organization").option("--source <source>", "Source (whois/manual/brandsight/import)", "manual").option("--contact-id <id>", "Link to existing open-contacts contact ID").option("--verified", "Mark as verified").option("--notes <text>", "Notes").option("-j, --json", "Output JSON").action(async (identifier, opts) => {
52189
52258
  const details = await requireDomain2(identifier);
52190
52259
  if (!opts.name && !opts.email && !opts.organization && !opts.contactId) {
52191
- console.error("At least one of --name, --email, --organization, or --contact-id is required.");
52260
+ printErrorLine("At least one of --name, --email, --organization, or --contact-id is required.");
52192
52261
  process.exit(1);
52193
52262
  }
52194
52263
  const input = {
@@ -52204,15 +52273,15 @@ Domain: ${details.domain.name} [${details.domain.status}]`);
52204
52273
  };
52205
52274
  const o2 = await createDomainOwner2(input);
52206
52275
  if (opts.json) {
52207
- console.log(JSON.stringify(o2, null, 2));
52276
+ printLine(JSON.stringify(o2, null, 2));
52208
52277
  return;
52209
52278
  }
52210
- console.log(`Added owner for ${details.domain.name}: ${o2.owner_name ?? o2.owner_email ?? "unknown"}`);
52279
+ printLine(`Added owner for ${details.domain.name}: ${o2.owner_name ?? o2.owner_email ?? "unknown"}`);
52211
52280
  });
52212
52281
  owner.command("update <ownerId>").description("Update owner info").option("--name <name>", "Owner name").option("--email <email>", "Owner email").option("--phone <phone>", "Owner phone").option("--organization <org>", "Owner organization").option("--contact-id <id>", "Link to open-contacts contact ID").option("--verified", "Mark as verified").option("--unverify", "Unmark as verified").option("--notes <text>", "Notes").option("-j, --json", "Output JSON").action(async (ownerId, opts) => {
52213
52282
  const existing = await getDomainOwner2(ownerId);
52214
52283
  if (!existing) {
52215
- console.error(`Owner '${ownerId}' not found.`);
52284
+ printErrorLine(`Owner '${ownerId}' not found.`);
52216
52285
  process.exit(1);
52217
52286
  }
52218
52287
  const update = {};
@@ -52234,72 +52303,72 @@ Domain: ${details.domain.name} [${details.domain.status}]`);
52234
52303
  update.notes = opts.notes;
52235
52304
  const o2 = await updateDomainOwner2(ownerId, update);
52236
52305
  if (!o2) {
52237
- console.error("Update failed.");
52306
+ printErrorLine("Update failed.");
52238
52307
  process.exit(1);
52239
52308
  }
52240
52309
  if (opts.json) {
52241
- console.log(JSON.stringify(o2, null, 2));
52310
+ printLine(JSON.stringify(o2, null, 2));
52242
52311
  return;
52243
52312
  }
52244
- console.log(`Updated owner: ${o2.owner_name ?? o2.owner_email ?? "unknown"}`);
52313
+ printLine(`Updated owner: ${o2.owner_name ?? o2.owner_email ?? "unknown"}`);
52245
52314
  });
52246
52315
  owner.command("delete <ownerId>").description("Delete an owner record").option("-f, --force", "Required confirmation").action(async (ownerId, opts) => {
52247
52316
  if (!opts.force) {
52248
- console.error(`Refusing to delete owner '${ownerId}' without --force.`);
52317
+ printErrorLine(`Refusing to delete owner '${ownerId}' without --force.`);
52249
52318
  process.exit(1);
52250
52319
  }
52251
52320
  const deleted = await deleteDomainOwner2(ownerId);
52252
52321
  if (!deleted) {
52253
- console.error(`Owner '${ownerId}' not found.`);
52322
+ printErrorLine(`Owner '${ownerId}' not found.`);
52254
52323
  process.exit(1);
52255
52324
  }
52256
- console.log(`Deleted owner ${ownerId}`);
52325
+ printLine(`Deleted owner ${ownerId}`);
52257
52326
  });
52258
52327
  owner.command("extract <identifier>").description("Extract owner info from WHOIS lookup").option("-j, --json", "Output JSON").action(async (identifier, opts) => {
52259
52328
  const details = await requireDomain2(identifier);
52260
52329
  const whois = await whoisLookup(details.domain.name);
52261
52330
  if (!whois.raw) {
52262
- console.error("WHOIS returned no data.");
52331
+ printErrorLine("WHOIS returned no data.");
52263
52332
  process.exit(1);
52264
52333
  }
52265
52334
  const o2 = await extractOwnerFromWhois(details.domain.name, whois.raw);
52266
52335
  if (!o2) {
52267
- console.log("No owner information found in WHOIS data.");
52336
+ printLine("No owner information found in WHOIS data.");
52268
52337
  return;
52269
52338
  }
52270
52339
  if (opts.json) {
52271
- console.log(JSON.stringify(o2, null, 2));
52340
+ printLine(JSON.stringify(o2, null, 2));
52272
52341
  return;
52273
52342
  }
52274
- console.log(`Extracted owner for ${details.domain.name}:`);
52343
+ printLine(`Extracted owner for ${details.domain.name}:`);
52275
52344
  if (o2.owner_name)
52276
- console.log(` Name: ${o2.owner_name}`);
52345
+ printLine(` Name: ${o2.owner_name}`);
52277
52346
  if (o2.owner_email)
52278
- console.log(` Email: ${o2.owner_email}`);
52347
+ printLine(` Email: ${o2.owner_email}`);
52279
52348
  if (o2.owner_phone)
52280
- console.log(` Phone: ${o2.owner_phone}`);
52349
+ printLine(` Phone: ${o2.owner_phone}`);
52281
52350
  if (o2.owner_organization)
52282
- console.log(` Organization: ${o2.owner_organization}`);
52283
- console.log();
52351
+ printLine(` Organization: ${o2.owner_organization}`);
52352
+ printLine();
52284
52353
  });
52285
52354
  owner.command("link <identifier>").description("Link domain owner to open-contacts contact").option("--contact-id <id>", "Existing contact ID in open-contacts").option("--auto", "Auto-create contact from owner info").option("-j, --json", "Output JSON").action(async (identifier, opts) => {
52286
52355
  const details = await requireDomain2(identifier);
52287
52356
  const o2 = await getDomainOwnerByDomain2(details.domain.id);
52288
52357
  if (!o2) {
52289
- console.error(`No owner record for ${details.domain.name}. Add one first.`);
52358
+ printErrorLine(`No owner record for ${details.domain.name}. Add one first.`);
52290
52359
  process.exit(1);
52291
52360
  }
52292
52361
  if (opts.contactId) {
52293
52362
  const updated = await updateDomainOwner2(o2.id, { contact_id: opts.contactId });
52294
52363
  if (!updated) {
52295
- console.error("Link failed.");
52364
+ printErrorLine("Link failed.");
52296
52365
  process.exit(1);
52297
52366
  }
52298
52367
  if (opts.json) {
52299
- console.log(JSON.stringify(updated, null, 2));
52368
+ printLine(JSON.stringify(updated, null, 2));
52300
52369
  return;
52301
52370
  }
52302
- console.log(`Linked ${details.domain.name} to contact ${opts.contactId}`);
52371
+ printLine(`Linked ${details.domain.name} to contact ${opts.contactId}`);
52303
52372
  return;
52304
52373
  }
52305
52374
  if (opts.auto) {
@@ -52311,64 +52380,65 @@ Domain: ${details.domain.name} [${details.domain.status}]`);
52311
52380
  getContactByEmail: (email) => contacts.getContactByEmail(email)
52312
52381
  });
52313
52382
  if (!contactId) {
52314
- console.error("Could not create/find contact \u2014 owner has no email.");
52383
+ printErrorLine("Could not create/find contact \u2014 owner has no email.");
52315
52384
  process.exit(1);
52316
52385
  }
52317
52386
  if (opts.json) {
52318
- console.log(JSON.stringify({ domain: details.domain.name, contact_id: contactId }, null, 2));
52387
+ printLine(JSON.stringify({ domain: details.domain.name, contact_id: contactId }, null, 2));
52319
52388
  return;
52320
52389
  }
52321
- console.log(`Created/linked contact ${contactId} for ${details.domain.name}`);
52390
+ printLine(`Created/linked contact ${contactId} for ${details.domain.name}`);
52322
52391
  } catch (e4) {
52323
52392
  const message = e4 instanceof Error ? e4.message : String(e4);
52324
52393
  if (typeof e4 === "object" && e4 !== null && "code" in e4 && e4.code === "MODULE_NOT_FOUND" || message.includes("@hasna/contacts")) {
52325
- console.error("@hasna/contacts is not installed. Install it alongside @hasna/domains, or pass --contact-id to link an existing contact ID.");
52394
+ printErrorLine("@hasna/contacts is not installed. Install it alongside @hasna/domains, or pass --contact-id to link an existing contact ID.");
52326
52395
  } else {
52327
- console.error(`Failed to link to open-contacts: ${message}`);
52396
+ printErrorLine(`Failed to link to open-contacts: ${message}`);
52328
52397
  }
52329
52398
  process.exit(1);
52330
52399
  }
52331
52400
  return;
52332
52401
  }
52333
- console.error("Use --contact-id <id> or --auto to link.");
52402
+ printErrorLine("Use --contact-id <id> or --auto to link.");
52334
52403
  process.exit(1);
52335
52404
  });
52336
52405
  owner.command("whois <identifier>").description("WHOIS lookup and save owner info").option("-j, --json", "Output JSON").action(async (identifier, opts) => {
52337
52406
  const details = await requireDomain2(identifier);
52338
52407
  const whois = await whoisLookup(details.domain.name);
52339
52408
  if (!whois.raw) {
52340
- console.error("WHOIS returned no data.");
52409
+ printErrorLine("WHOIS returned no data.");
52341
52410
  process.exit(1);
52342
52411
  }
52343
52412
  const o2 = await extractOwnerFromWhois(details.domain.name, whois.raw);
52344
52413
  if (!o2) {
52345
52414
  if (opts.json) {
52346
- console.log(JSON.stringify({ domain: details.domain.name, owner: null }, null, 2));
52415
+ printLine(JSON.stringify({ domain: details.domain.name, owner: null }, null, 2));
52347
52416
  return;
52348
52417
  }
52349
- console.log("No owner information found in WHOIS data.");
52418
+ printLine("No owner information found in WHOIS data.");
52350
52419
  return;
52351
52420
  }
52352
52421
  if (opts.json) {
52353
- console.log(JSON.stringify(o2, null, 2));
52422
+ printLine(JSON.stringify(o2, null, 2));
52354
52423
  return;
52355
52424
  }
52356
- console.log(`WHOIS owner for ${details.domain.name}:`);
52425
+ printLine(`WHOIS owner for ${details.domain.name}:`);
52357
52426
  if (o2.owner_name)
52358
- console.log(` Name: ${o2.owner_name}`);
52427
+ printLine(` Name: ${o2.owner_name}`);
52359
52428
  if (o2.owner_email)
52360
- console.log(` Email: ${o2.owner_email}`);
52429
+ printLine(` Email: ${o2.owner_email}`);
52361
52430
  if (o2.owner_phone)
52362
- console.log(` Phone: ${o2.owner_phone}`);
52431
+ printLine(` Phone: ${o2.owner_phone}`);
52363
52432
  if (o2.owner_organization)
52364
- console.log(` Organization: ${o2.owner_organization}`);
52365
- console.log(` Source: ${o2.source}`);
52366
- console.log();
52433
+ printLine(` Organization: ${o2.owner_organization}`);
52434
+ printLine(` Source: ${o2.source}`);
52435
+ printLine();
52367
52436
  });
52368
52437
  }
52369
52438
  var init_owner = __esm(() => {
52370
52439
  init_owners();
52371
52440
  init_domains();
52441
+ init_stdout();
52372
52442
  });
52373
52443
 
52374
52444
  // src/cli/commands/history.ts
@@ -52381,7 +52451,7 @@ function registerHistoryCommand(program2) {
52381
52451
  history.command("list <identifier>").description("List history entries for a domain").option("--type <type>", "Filter by type (whois/rdap/dns/ssl/reputation/exa_research)").option("--limit <n>", "Limit results", "20").option("-j, --json", "Output JSON").action(async (identifier, opts) => {
52382
52452
  const domain = await getDomainDetails2(identifier);
52383
52453
  if (!domain) {
52384
- console.error(`Domain '${identifier}' not found.`);
52454
+ printErrorLine(`Domain '${identifier}' not found.`);
52385
52455
  process.exit(1);
52386
52456
  }
52387
52457
  const entries = await getHistoryByDomain2(domain.domain.id, {
@@ -52389,94 +52459,95 @@ function registerHistoryCommand(program2) {
52389
52459
  limit: opts.limit ? parseInt(opts.limit) : undefined
52390
52460
  });
52391
52461
  if (opts.json) {
52392
- console.log(JSON.stringify({ domain: domain.domain.name, history: entries, count: entries.length }, null, 2));
52462
+ printLine(JSON.stringify({ domain: domain.domain.name, history: entries, count: entries.length }, null, 2));
52393
52463
  return;
52394
52464
  }
52395
52465
  if (entries.length === 0) {
52396
- console.log(`No history entries for ${domain.domain.name}.`);
52466
+ printLine(`No history entries for ${domain.domain.name}.`);
52397
52467
  return;
52398
52468
  }
52399
- console.log(`History for ${domain.domain.name}:`);
52469
+ printLine(`History for ${domain.domain.name}:`);
52400
52470
  for (const e4 of entries) {
52401
- console.log(` [${e4.created_at}] ${e4.snapshot_type} \u2014 ${e4.registrant_name ?? e4.registrant_email ?? "no owner info"}`);
52471
+ printLine(` [${e4.created_at}] ${e4.snapshot_type} \u2014 ${e4.registrant_name ?? e4.registrant_email ?? "no owner info"}`);
52402
52472
  if (e4.registrar)
52403
- console.log(` Registrar: ${e4.registrar}`);
52473
+ printLine(` Registrar: ${e4.registrar}`);
52404
52474
  if (e4.notes)
52405
- console.log(` Notes: ${truncateText(e4.notes, 120)}`);
52475
+ printLine(` Notes: ${truncateText(e4.notes, 120)}`);
52406
52476
  }
52407
- console.log(`
52477
+ printLine(`
52408
52478
  ${entries.length} entry(ies). Use --limit <n> for a different page size or --json for full snapshots.`);
52409
52479
  });
52410
52480
  history.command("timeline").description("Show all domains with history changes").option("--limit <n>", "Limit number of displayed domains").option("--all", "Show all domains with history").option("-j, --json", "Output JSON").action(async (opts) => {
52411
52481
  const results = await listDomainsWithHistoryChanges2();
52412
52482
  if (opts.json) {
52413
- console.log(JSON.stringify({ domains: results, count: results.length }, null, 2));
52483
+ printLine(JSON.stringify({ domains: results, count: results.length }, null, 2));
52414
52484
  return;
52415
52485
  }
52416
52486
  if (results.length === 0) {
52417
- console.log("No domains with history entries.");
52487
+ printLine("No domains with history entries.");
52418
52488
  return;
52419
52489
  }
52420
52490
  const page = pageItemsOrExit(results, { limit: opts.limit, all: opts.all });
52421
- console.log("Domain History Timeline:");
52491
+ printLine("Domain History Timeline:");
52422
52492
  for (const r4 of page.items) {
52423
- console.log(` ${r4.domain_name} \u2014 ${r4.snapshot_count} snapshots, latest: ${r4.latest_snapshot_type} at ${r4.latest_snapshot_at}`);
52493
+ printLine(` ${r4.domain_name} \u2014 ${r4.snapshot_count} snapshots, latest: ${r4.latest_snapshot_type} at ${r4.latest_snapshot_at}`);
52424
52494
  }
52425
- console.log(`
52495
+ printLine(`
52426
52496
  ${compactHint(page, "domain(s) with history", "Use history list <domain> for domain details or --json for full data.", { paging: "limit" })}`);
52427
52497
  });
52428
52498
  history.command("range").description("List history entries within a date range").requiredOption("--from <date>", "Start date (ISO)").requiredOption("--to <date>", "End date (ISO)").option("--domain <name>", "Filter by domain name").option("--limit <n>", "Limit number of displayed entries").option("--all", "Show all entries in range").option("--verbose", "Show truncated notes and registrar details").option("-j, --json", "Output JSON").action(async (opts) => {
52429
52499
  const entries = await getHistoryByDateRange2(opts.from, opts.to, opts.domain);
52430
52500
  if (opts.json) {
52431
- console.log(JSON.stringify({ history: entries, count: entries.length }, null, 2));
52501
+ printLine(JSON.stringify({ history: entries, count: entries.length }, null, 2));
52432
52502
  return;
52433
52503
  }
52434
52504
  if (entries.length === 0) {
52435
- console.log(`No history entries between ${opts.from} and ${opts.to}.`);
52505
+ printLine(`No history entries between ${opts.from} and ${opts.to}.`);
52436
52506
  return;
52437
52507
  }
52438
52508
  const page = pageItemsOrExit(entries, { limit: opts.limit, all: opts.all });
52439
- console.log(`History from ${opts.from} to ${opts.to}:`);
52509
+ printLine(`History from ${opts.from} to ${opts.to}:`);
52440
52510
  for (const e4 of page.items) {
52441
52511
  const extra = opts.verbose ? ` registrar:${truncateText(e4.registrar ?? "-", 40)} notes:${truncateText(e4.notes ?? "-", 80)}` : "";
52442
- console.log(` [${e4.created_at}] ${e4.snapshot_type} \u2014 domain ${e4.domain_id}${extra}`);
52512
+ printLine(` [${e4.created_at}] ${e4.snapshot_type} \u2014 domain ${e4.domain_id}${extra}`);
52443
52513
  }
52444
- console.log(`
52514
+ printLine(`
52445
52515
  ${compactHint(page, "entry(s)", "Use --verbose for more columns or --json for full snapshots.", { paging: "limit" })}`);
52446
52516
  });
52447
52517
  history.command("delete <entryId>").description("Delete a history entry").option("-f, --force", "Required confirmation").action(async (entryId, opts) => {
52448
52518
  if (!opts.force) {
52449
- console.error(`Refusing to delete history '${entryId}' without --force.`);
52519
+ printErrorLine(`Refusing to delete history '${entryId}' without --force.`);
52450
52520
  process.exit(1);
52451
52521
  }
52452
52522
  const deleted = await deleteHistoryEntry2(entryId);
52453
52523
  if (!deleted) {
52454
- console.error(`History entry '${entryId}' not found.`);
52524
+ printErrorLine(`History entry '${entryId}' not found.`);
52455
52525
  process.exit(1);
52456
52526
  }
52457
- console.log(`Deleted history entry ${entryId}`);
52527
+ printLine(`Deleted history entry ${entryId}`);
52458
52528
  });
52459
52529
  history.command("purge <identifier>").description("Delete all history for a domain").option("-f, --force", "Required confirmation").action(async (identifier, opts) => {
52460
52530
  if (!opts.force) {
52461
- console.error(`Refusing to purge history for '${identifier}' without --force.`);
52531
+ printErrorLine(`Refusing to purge history for '${identifier}' without --force.`);
52462
52532
  process.exit(1);
52463
52533
  }
52464
52534
  const domain = await getDomainDetails2(identifier);
52465
52535
  if (!domain) {
52466
- console.error(`Domain '${identifier}' not found.`);
52536
+ printErrorLine(`Domain '${identifier}' not found.`);
52467
52537
  process.exit(1);
52468
52538
  }
52469
52539
  const deleted = await deleteHistoryByDomain2(domain.domain.id);
52470
52540
  if (!deleted) {
52471
- console.error(`No history to purge for ${domain.domain.name}.`);
52541
+ printErrorLine(`No history to purge for ${domain.domain.name}.`);
52472
52542
  process.exit(1);
52473
52543
  }
52474
- console.log(`Purged all history for ${domain.domain.name}`);
52544
+ printLine(`Purged all history for ${domain.domain.name}`);
52475
52545
  });
52476
52546
  }
52477
52547
  var init_history2 = __esm(() => {
52478
52548
  init_history();
52479
52549
  init_domains();
52550
+ init_stdout();
52480
52551
  });
52481
52552
 
52482
52553
  // src/db/domain-research.ts
@@ -52643,13 +52714,13 @@ function registerResearchCommand(program2) {
52643
52714
  research.command("exa <identifier>").description("Research a domain using Exa AI (ownership, company info, history)").option("--limit <n>", "Limit number of displayed web/company results").option("--all", "Show all returned research results").option("-j, --json", "Output JSON").action(async (identifier, opts) => {
52644
52715
  const domain = await getDomainDetails2(identifier);
52645
52716
  if (!domain) {
52646
- console.error(`Domain '${identifier}' not found.`);
52717
+ printErrorLine(`Domain '${identifier}' not found.`);
52647
52718
  process.exit(1);
52648
52719
  }
52649
52720
  try {
52650
52721
  const result = await researchDomain(domain.domain.name);
52651
52722
  if (opts.json) {
52652
- console.log(JSON.stringify({
52723
+ printLine(JSON.stringify({
52653
52724
  domain: result.domain,
52654
52725
  summary: result.summary,
52655
52726
  results: result.results.map((r4) => ({ title: r4.title, url: r4.url, score: r4.score })),
@@ -52658,124 +52729,124 @@ function registerResearchCommand(program2) {
52658
52729
  }, null, 2));
52659
52730
  return;
52660
52731
  }
52661
- console.log(`Exa Research for ${result.domain}:`);
52732
+ printLine(`Exa Research for ${result.domain}:`);
52662
52733
  if (result.summary)
52663
- console.log(`
52734
+ printLine(`
52664
52735
  Summary: ${truncateText(result.summary, 240)}`);
52665
52736
  if (result.results.length > 0) {
52666
52737
  const page = pageItemsOrExit(result.results, { limit: opts.limit, all: opts.all });
52667
- console.log(`
52738
+ printLine(`
52668
52739
  Web Results:`);
52669
52740
  for (const r4 of page.items) {
52670
- console.log(` - ${truncateText(r4.title, 100)} (${r4.score.toFixed(2)})`);
52671
- console.log(` ${r4.url}`);
52741
+ printLine(` - ${truncateText(r4.title, 100)} (${r4.score.toFixed(2)})`);
52742
+ printLine(` ${r4.url}`);
52672
52743
  }
52673
- console.log(` ${compactHint(page, "web result(s)", "Use --all for every result or --json for structured output.", { paging: "limit" })}`);
52744
+ printLine(` ${compactHint(page, "web result(s)", "Use --all for every result or --json for structured output.", { paging: "limit" })}`);
52674
52745
  }
52675
52746
  if (result.companies.length > 0) {
52676
52747
  const page = pageItemsOrExit(result.companies, { limit: opts.limit, all: opts.all });
52677
- console.log(`
52748
+ printLine(`
52678
52749
  Companies:`);
52679
52750
  for (const c4 of page.items) {
52680
- console.log(` - ${c4.name}: ${c4.domain}`);
52751
+ printLine(` - ${c4.name}: ${c4.domain}`);
52681
52752
  }
52682
- console.log(` ${compactHint(page, "company result(s)", "Use --all for every company or --json for structured output.", { paging: "limit" })}`);
52753
+ printLine(` ${compactHint(page, "company result(s)", "Use --all for every company or --json for structured output.", { paging: "limit" })}`);
52683
52754
  }
52684
52755
  if (result.savedHistory) {
52685
- console.log(`
52756
+ printLine(`
52686
52757
  Saved to history: ${result.savedHistory.id}`);
52687
52758
  }
52688
- console.log();
52759
+ printLine();
52689
52760
  } catch (error) {
52690
- console.error(`Research failed: ${error instanceof Error ? error.message : String(error)}`);
52761
+ printErrorLine(`Research failed: ${error instanceof Error ? error.message : String(error)}`);
52691
52762
  process.exit(1);
52692
52763
  }
52693
52764
  });
52694
52765
  research.command("answer <identifier> <question>").description("Ask a specific question about a domain using Exa AI").option("-j, --json", "Output JSON").action(async (identifier, question, opts) => {
52695
52766
  const domain = await getDomainDetails2(identifier);
52696
52767
  if (!domain) {
52697
- console.error(`Domain '${identifier}' not found.`);
52768
+ printErrorLine(`Domain '${identifier}' not found.`);
52698
52769
  process.exit(1);
52699
52770
  }
52700
52771
  try {
52701
52772
  const answer = await answerAboutDomain(domain.domain.name, question);
52702
52773
  if (opts.json) {
52703
- console.log(JSON.stringify({ domain: domain.domain.name, question, answer }, null, 2));
52774
+ printLine(JSON.stringify({ domain: domain.domain.name, question, answer }, null, 2));
52704
52775
  return;
52705
52776
  }
52706
52777
  if (!answer) {
52707
- console.log("No answer found.");
52778
+ printLine("No answer found.");
52708
52779
  return;
52709
52780
  }
52710
- console.log(`Q: ${question}`);
52711
- console.log(`A: ${answer}`);
52781
+ printLine(`Q: ${question}`);
52782
+ printLine(`A: ${answer}`);
52712
52783
  } catch (error) {
52713
- console.error(`Answer failed: ${error instanceof Error ? error.message : String(error)}`);
52784
+ printErrorLine(`Answer failed: ${error instanceof Error ? error.message : String(error)}`);
52714
52785
  process.exit(1);
52715
52786
  }
52716
52787
  });
52717
52788
  research.command("reputation <identifier>").description("Check domain reputation and blacklist status").option("-j, --json", "Output JSON").action(async (identifier, opts) => {
52718
52789
  const domain = await getDomainDetails2(identifier);
52719
52790
  if (!domain) {
52720
- console.error(`Domain '${identifier}' not found.`);
52791
+ printErrorLine(`Domain '${identifier}' not found.`);
52721
52792
  process.exit(1);
52722
52793
  }
52723
52794
  const { reputation, dnsBlacklist } = await checkDomainReputation(domain.domain.name);
52724
52795
  if (opts.json) {
52725
- console.log(JSON.stringify({ domain: domain.domain.name, reputation, dnsBlacklist }, null, 2));
52796
+ printLine(JSON.stringify({ domain: domain.domain.name, reputation, dnsBlacklist }, null, 2));
52726
52797
  return;
52727
52798
  }
52728
- console.log(`Reputation for ${domain.domain.name}:`);
52799
+ printLine(`Reputation for ${domain.domain.name}:`);
52729
52800
  if (reputation) {
52730
- console.log(` Blacklisted: ${reputation.is_blacklisted ? "yes" : "no"}`);
52801
+ printLine(` Blacklisted: ${reputation.is_blacklisted ? "yes" : "no"}`);
52731
52802
  if (reputation.threat_score !== null)
52732
- console.log(` Threat Score: ${reputation.threat_score}`);
52803
+ printLine(` Threat Score: ${reputation.threat_score}`);
52733
52804
  if (reputation.spam_score !== null)
52734
- console.log(` Spam Score: ${reputation.spam_score}`);
52735
- console.log(` Malware: ${reputation.malware_detected ? "detected" : "clean"}`);
52736
- console.log(` Phishing: ${reputation.phishing_detected ? "detected" : "clean"}`);
52805
+ printLine(` Spam Score: ${reputation.spam_score}`);
52806
+ printLine(` Malware: ${reputation.malware_detected ? "detected" : "clean"}`);
52807
+ printLine(` Phishing: ${reputation.phishing_detected ? "detected" : "clean"}`);
52737
52808
  if (reputation.last_checked_at)
52738
- console.log(` Last Checked: ${reputation.last_checked_at}`);
52809
+ printLine(` Last Checked: ${reputation.last_checked_at}`);
52739
52810
  } else {
52740
- console.log(" No reputation data yet.");
52811
+ printLine(" No reputation data yet.");
52741
52812
  }
52742
- console.log(` DNS Blacklist: ${dnsBlacklist.listed ? `listed in ${dnsBlacklist.zones.join(", ")}` : "clean"}`);
52813
+ printLine(` DNS Blacklist: ${dnsBlacklist.listed ? `listed in ${dnsBlacklist.zones.join(", ")}` : "clean"}`);
52743
52814
  });
52744
52815
  research.command("blacklisted").description("List all blacklisted domains in the database").option("--limit <n>", "Limit number of displayed domains").option("--all", "Show all blacklisted domains").option("-j, --json", "Output JSON").action(async (opts) => {
52745
52816
  const domains = await listBlacklistedDomains2();
52746
52817
  if (opts.json) {
52747
- console.log(JSON.stringify({ domains, count: domains.length }, null, 2));
52818
+ printLine(JSON.stringify({ domains, count: domains.length }, null, 2));
52748
52819
  return;
52749
52820
  }
52750
52821
  if (domains.length === 0) {
52751
- console.log("No blacklisted domains.");
52822
+ printLine("No blacklisted domains.");
52752
52823
  return;
52753
52824
  }
52754
52825
  const page = pageItemsOrExit(domains, { limit: opts.limit, all: opts.all });
52755
- console.log("Blacklisted domains:");
52826
+ printLine("Blacklisted domains:");
52756
52827
  for (const d4 of page.items) {
52757
- console.log(` domain_id: ${d4.domain_id} (sources: ${truncateText(d4.blacklist_sources.join(", "), 100)})`);
52828
+ printLine(` domain_id: ${d4.domain_id} (sources: ${truncateText(d4.blacklist_sources.join(", "), 100)})`);
52758
52829
  }
52759
- console.log(`
52830
+ printLine(`
52760
52831
  ${compactHint(page, "blacklisted domain(s)", "Use --all for every domain or --json for full source arrays.", { paging: "limit" })}`);
52761
52832
  });
52762
52833
  research.command("threats").description("List domains with high threat scores").option("--threshold <n>", "Minimum threat score", "70").option("--limit <n>", "Limit number of displayed domains").option("--all", "Show all matching domains").option("-j, --json", "Output JSON").action(async (opts) => {
52763
52834
  const threshold = parseInt(opts.threshold ?? "70");
52764
52835
  const domains = await listHighThreatDomains2(threshold);
52765
52836
  if (opts.json) {
52766
- console.log(JSON.stringify({ domains, threshold, count: domains.length }, null, 2));
52837
+ printLine(JSON.stringify({ domains, threshold, count: domains.length }, null, 2));
52767
52838
  return;
52768
52839
  }
52769
52840
  if (domains.length === 0) {
52770
- console.log(`No domains with threat score >= ${threshold}.`);
52841
+ printLine(`No domains with threat score >= ${threshold}.`);
52771
52842
  return;
52772
52843
  }
52773
52844
  const page = pageItemsOrExit(domains, { limit: opts.limit, all: opts.all });
52774
- console.log(`Domains with threat score >= ${threshold}:`);
52845
+ printLine(`Domains with threat score >= ${threshold}:`);
52775
52846
  for (const d4 of page.items) {
52776
- console.log(` domain_id: ${d4.domain_id} \u2014 score: ${d4.threat_score ?? "?"}`);
52847
+ printLine(` domain_id: ${d4.domain_id} \u2014 score: ${d4.threat_score ?? "?"}`);
52777
52848
  }
52778
- console.log(`
52849
+ printLine(`
52779
52850
  ${compactHint(page, "domain(s)", "Use --all for every domain or --json for full reputation records.", { paging: "limit" })}`);
52780
52851
  });
52781
52852
  }
@@ -52783,6 +52854,7 @@ var init_research = __esm(() => {
52783
52854
  init_domain_research();
52784
52855
  init_domains();
52785
52856
  init_reputation();
52857
+ init_stdout();
52786
52858
  });
52787
52859
 
52788
52860
  // src/cli/commands/outreach.ts
@@ -52795,7 +52867,7 @@ import { promisify as promisify3 } from "util";
52795
52867
  async function requireDomainOwner(identifier) {
52796
52868
  const owner = await getDomainOwnerByDomainName2(identifier);
52797
52869
  if (!owner) {
52798
- console.error(`No owner info found for '${identifier}'.`);
52870
+ printErrorLine(`No owner info found for '${identifier}'.`);
52799
52871
  process.exit(1);
52800
52872
  }
52801
52873
  return owner;
@@ -52805,7 +52877,7 @@ function registerOutreachCommand(program2) {
52805
52877
  outreach.command("sms <identifier>").description("Send SMS to a domain owner").requiredOption("--message <text>", "SMS message body").option("-j, --json", "Output JSON").action(async (identifier, opts) => {
52806
52878
  const owner = await requireDomainOwner(identifier);
52807
52879
  if (!owner.owner_phone) {
52808
- console.error(`No phone number for '${identifier}'.`);
52880
+ printErrorLine(`No phone number for '${identifier}'.`);
52809
52881
  process.exit(1);
52810
52882
  }
52811
52883
  try {
@@ -52821,20 +52893,20 @@ function registerOutreachCommand(program2) {
52821
52893
  ], { encoding: "utf-8" });
52822
52894
  const result = JSON.parse(stdout);
52823
52895
  if (opts.json) {
52824
- console.log(JSON.stringify({ domain: identifier, to: owner.owner_phone, result }, null, 2));
52896
+ printLine(JSON.stringify({ domain: identifier, to: owner.owner_phone, result }, null, 2));
52825
52897
  } else {
52826
- console.log(`SMS sent to ${owner.owner_name ?? owner.owner_email} (${owner.owner_phone}): "${opts.message}"`);
52898
+ printLine(`SMS sent to ${owner.owner_name ?? owner.owner_email} (${owner.owner_phone}): "${opts.message}"`);
52827
52899
  }
52828
52900
  } catch (error) {
52829
52901
  const msg = error instanceof Error ? error.message : String(error);
52830
- console.error(`SMS send failed: ${msg}`);
52902
+ printErrorLine(`SMS send failed: ${msg}`);
52831
52903
  process.exit(1);
52832
52904
  }
52833
52905
  });
52834
52906
  outreach.command("whatsapp <identifier>").description("Send WhatsApp message to a domain owner").requiredOption("--message <text>", "Message body").option("-j, --json", "Output JSON").action(async (identifier, opts) => {
52835
52907
  const owner = await requireDomainOwner(identifier);
52836
52908
  if (!owner.owner_phone) {
52837
- console.error(`No phone number for '${identifier}'.`);
52909
+ printErrorLine(`No phone number for '${identifier}'.`);
52838
52910
  process.exit(1);
52839
52911
  }
52840
52912
  try {
@@ -52850,20 +52922,20 @@ function registerOutreachCommand(program2) {
52850
52922
  ], { encoding: "utf-8" });
52851
52923
  const result = JSON.parse(stdout);
52852
52924
  if (opts.json) {
52853
- console.log(JSON.stringify({ domain: identifier, to: owner.owner_phone, result }, null, 2));
52925
+ printLine(JSON.stringify({ domain: identifier, to: owner.owner_phone, result }, null, 2));
52854
52926
  } else {
52855
- console.log(`WhatsApp sent to ${owner.owner_name ?? owner.owner_email} (${owner.owner_phone}): "${opts.message}"`);
52927
+ printLine(`WhatsApp sent to ${owner.owner_name ?? owner.owner_email} (${owner.owner_phone}): "${opts.message}"`);
52856
52928
  }
52857
52929
  } catch (error) {
52858
52930
  const msg = error instanceof Error ? error.message : String(error);
52859
- console.error(`WhatsApp send failed: ${msg}`);
52931
+ printErrorLine(`WhatsApp send failed: ${msg}`);
52860
52932
  process.exit(1);
52861
52933
  }
52862
52934
  });
52863
52935
  outreach.command("email <identifier>").description("Send email to a domain owner").requiredOption("--subject <text>", "Email subject").requiredOption("--body <text>", "Email body (plain text)").option("--template <name>", "Use a template by name instead of --body").option("-j, --json", "Output JSON").action(async (identifier, opts) => {
52864
52936
  const owner = await requireDomainOwner(identifier);
52865
52937
  if (!owner.owner_email) {
52866
- console.error(`No email for '${identifier}'.`);
52938
+ printErrorLine(`No email for '${identifier}'.`);
52867
52939
  process.exit(1);
52868
52940
  }
52869
52941
  try {
@@ -52881,13 +52953,13 @@ function registerOutreachCommand(program2) {
52881
52953
  ], { encoding: "utf-8" });
52882
52954
  const result = JSON.parse(stdout);
52883
52955
  if (opts.json) {
52884
- console.log(JSON.stringify({ domain: identifier, to: owner.owner_email, result }, null, 2));
52956
+ printLine(JSON.stringify({ domain: identifier, to: owner.owner_email, result }, null, 2));
52885
52957
  } else {
52886
- console.log(`Email sent to ${owner.owner_name ?? owner.owner_email} (${owner.owner_email}): "${opts.subject}"`);
52958
+ printLine(`Email sent to ${owner.owner_name ?? owner.owner_email} (${owner.owner_email}): "${opts.subject}"`);
52887
52959
  }
52888
52960
  } catch (error) {
52889
52961
  const msg = error instanceof Error ? error.message : String(error);
52890
- console.error(`Email send failed: ${msg}`);
52962
+ printErrorLine(`Email send failed: ${msg}`);
52891
52963
  process.exit(1);
52892
52964
  }
52893
52965
  });
@@ -52895,6 +52967,7 @@ function registerOutreachCommand(program2) {
52895
52967
  var execFileAsync2;
52896
52968
  var init_outreach = __esm(() => {
52897
52969
  init_owners();
52970
+ init_stdout();
52898
52971
  execFileAsync2 = promisify3(execFile2);
52899
52972
  });
52900
52973
 
@@ -52934,22 +53007,22 @@ function registerWalletCommand(program2) {
52934
53007
  try {
52935
53008
  const cards = await getAvailableCards();
52936
53009
  if (opts.json) {
52937
- console.log(JSON.stringify(cards, null, 2));
53010
+ printLine(JSON.stringify(cards, null, 2));
52938
53011
  } else {
52939
53012
  if (cards.length === 0) {
52940
- console.log("No active wallet cards found.");
53013
+ printLine("No active wallet cards found.");
52941
53014
  return;
52942
53015
  }
52943
53016
  const page = pageItemsOrExit(cards, { limit: opts.limit, all: opts.all });
52944
- console.log("Available wallet cards:");
53017
+ printLine("Available wallet cards:");
52945
53018
  for (const c4 of page.items) {
52946
- console.log(` ${c4.brand} \u2022\u2022\u2022\u2022 ${c4.last_four} \u2014 ${c4.name} (${c4.balance} ${c4.currency})`);
53019
+ printLine(` ${c4.brand} \u2022\u2022\u2022\u2022 ${c4.last_four} \u2014 ${c4.name} (${c4.balance} ${c4.currency})`);
52947
53020
  }
52948
- console.log(`
53021
+ printLine(`
52949
53022
  ${compactHint(page, "card(s)", "Use --all for every card or --json for full card fields.", { paging: "limit" })}`);
52950
53023
  }
52951
53024
  } catch (error) {
52952
- console.error(`Failed to list cards: ${error instanceof Error ? error.message : String(error)}`);
53025
+ printErrorLine(`Failed to list cards: ${error instanceof Error ? error.message : String(error)}`);
52953
53026
  process.exit(1);
52954
53027
  }
52955
53028
  });
@@ -52961,15 +53034,15 @@ ${compactHint(page, "card(s)", "Use --all for every card or --json for full card
52961
53034
  if (!cardId) {
52962
53035
  const cards = await getAvailableCards();
52963
53036
  if (cards.length === 0) {
52964
- console.error("No active wallet cards found. Add a card first.");
53037
+ printErrorLine("No active wallet cards found. Add a card first.");
52965
53038
  process.exit(1);
52966
53039
  }
52967
53040
  if (cards.length === 1) {
52968
53041
  cardId = cards[0].external_id;
52969
53042
  } else {
52970
- console.error("Multiple cards available. Specify --card-id:");
53043
+ printErrorLine("Multiple cards available. Specify --card-id:");
52971
53044
  for (const c4 of cards) {
52972
- console.log(` ${c4.id}: ${c4.brand} \u2022\u2022\u2022\u2022 ${c4.last_four} (${c4.balance} ${c4.currency})`);
53045
+ printLine(` ${c4.id}: ${c4.brand} \u2022\u2022\u2022\u2022 ${c4.last_four} (${c4.balance} ${c4.currency})`);
52973
53046
  }
52974
53047
  process.exit(1);
52975
53048
  }
@@ -52977,16 +53050,16 @@ ${compactHint(page, "card(s)", "Use --all for every card or --json for full card
52977
53050
  const wallets = getWalletsModule();
52978
53051
  const card = wallets.getCard(cardId);
52979
53052
  if (!card) {
52980
- console.error(`Card '${cardId}' not found.`);
53053
+ printErrorLine(`Card '${cardId}' not found.`);
52981
53054
  process.exit(1);
52982
53055
  }
52983
53056
  if (card.balance < price) {
52984
- console.error(`Insufficient funds: need ${price} ${currency}, have ${card.balance} ${card.currency}`);
53057
+ printErrorLine(`Insufficient funds: need ${price} ${currency}, have ${card.balance} ${card.currency}`);
52985
53058
  process.exit(1);
52986
53059
  }
52987
53060
  const existing = await getDomainByName2(name);
52988
53061
  if (existing) {
52989
- console.error(`Domain '${name}' already exists in portfolio.`);
53062
+ printErrorLine(`Domain '${name}' already exists in portfolio.`);
52990
53063
  process.exit(1);
52991
53064
  }
52992
53065
  const domain = await createDomain2({
@@ -53010,13 +53083,13 @@ ${compactHint(page, "card(s)", "Use --all for every card or --json for full card
53010
53083
  notes: `Purchased ${name} for ${price} ${currency} via wallet card ${cardId}`
53011
53084
  });
53012
53085
  if (opts.json) {
53013
- console.log(JSON.stringify({ domain, card_id: cardId, price, currency }, null, 2));
53086
+ printLine(JSON.stringify({ domain, card_id: cardId, price, currency }, null, 2));
53014
53087
  } else {
53015
- console.log(`Purchased ${name} for ${price} ${currency} via wallet card`);
53016
- console.log(` Added to portfolio as ${domain.id}`);
53088
+ printLine(`Purchased ${name} for ${price} ${currency} via wallet card`);
53089
+ printLine(` Added to portfolio as ${domain.id}`);
53017
53090
  }
53018
53091
  } catch (error) {
53019
- console.error(`Wallet purchase failed: ${error instanceof Error ? error.message : String(error)}`);
53092
+ printErrorLine(`Wallet purchase failed: ${error instanceof Error ? error.message : String(error)}`);
53020
53093
  process.exit(1);
53021
53094
  }
53022
53095
  });
@@ -53024,7 +53097,7 @@ ${compactHint(page, "card(s)", "Use --all for every card or --json for full card
53024
53097
  const price = parseFloat(opts.price);
53025
53098
  const domain = await getDomainByName2(name);
53026
53099
  if (!domain) {
53027
- console.error(`Domain '${name}' not found in portfolio.`);
53100
+ printErrorLine(`Domain '${name}' not found in portfolio.`);
53028
53101
  process.exit(1);
53029
53102
  }
53030
53103
  try {
@@ -53032,7 +53105,7 @@ ${compactHint(page, "card(s)", "Use --all for every card or --json for full card
53032
53105
  if (!cardId) {
53033
53106
  const cards = await getAvailableCards();
53034
53107
  if (cards.length === 0) {
53035
- console.error("No active wallet cards found.");
53108
+ printErrorLine("No active wallet cards found.");
53036
53109
  process.exit(1);
53037
53110
  }
53038
53111
  cardId = cards[0].external_id;
@@ -53040,11 +53113,11 @@ ${compactHint(page, "card(s)", "Use --all for every card or --json for full card
53040
53113
  const wallets = getWalletsModule();
53041
53114
  const card = wallets.getCard(cardId);
53042
53115
  if (!card) {
53043
- console.error(`Card '${cardId}' not found.`);
53116
+ printErrorLine(`Card '${cardId}' not found.`);
53044
53117
  process.exit(1);
53045
53118
  }
53046
53119
  if (card.balance < price) {
53047
- console.error(`Insufficient funds: need ${price} ${opts.currency}, have ${card.balance} ${card.currency}`);
53120
+ printErrorLine(`Insufficient funds: need ${price} ${opts.currency}, have ${card.balance} ${card.currency}`);
53048
53121
  process.exit(1);
53049
53122
  }
53050
53123
  await createHistoryEntry2({
@@ -53060,13 +53133,13 @@ ${compactHint(page, "card(s)", "Use --all for every card or --json for full card
53060
53133
  purchase_price: price
53061
53134
  });
53062
53135
  if (opts.json) {
53063
- console.log(JSON.stringify({ domain: name, card_id: cardId, price, new_expiry: expiryDate.toISOString() }, null, 2));
53136
+ printLine(JSON.stringify({ domain: name, card_id: cardId, price, new_expiry: expiryDate.toISOString() }, null, 2));
53064
53137
  } else {
53065
- console.log(`Renewed ${name} for ${price} ${opts.currency} via wallet card`);
53066
- console.log(` New expiry: ${expiryDate.toISOString().split("T")[0]}`);
53138
+ printLine(`Renewed ${name} for ${price} ${opts.currency} via wallet card`);
53139
+ printLine(` New expiry: ${expiryDate.toISOString().split("T")[0]}`);
53067
53140
  }
53068
53141
  } catch (error) {
53069
- console.error(`Wallet renewal failed: ${error instanceof Error ? error.message : String(error)}`);
53142
+ printErrorLine(`Wallet renewal failed: ${error instanceof Error ? error.message : String(error)}`);
53070
53143
  process.exit(1);
53071
53144
  }
53072
53145
  });
@@ -53075,6 +53148,7 @@ var WALLET_MODULE_ENV = "DOMAINS_WALLET_MODULE";
53075
53148
  var init_wallet = __esm(() => {
53076
53149
  init_domains();
53077
53150
  init_history();
53151
+ init_stdout();
53078
53152
  });
53079
53153
 
53080
53154
  // src/lib/provision-state.ts
@@ -53249,23 +53323,23 @@ function registerProvisionCommand(program2) {
53249
53323
  signals["publicNsAreCloudflare"] = false;
53250
53324
  }
53251
53325
  } catch (e4) {
53252
- console.error(`Error gathering signals: ${e4 instanceof Error ? e4.message : String(e4)}`);
53326
+ printErrorLine(`Error gathering signals: ${e4 instanceof Error ? e4.message : String(e4)}`);
53253
53327
  }
53254
53328
  const state = deriveDomainState(signals);
53255
- console.log(`
53329
+ printLine(`
53256
53330
  Domain: ${name}`);
53257
- console.log(`State: ${state}`);
53258
- console.log(`Signals: ${JSON.stringify(signals)}`);
53331
+ printLine(`State: ${state}`);
53332
+ printLine(`Signals: ${JSON.stringify(signals)}`);
53259
53333
  const path = domainHappyPath();
53260
53334
  const idx = path.indexOf(state);
53261
- console.log(`Progress: ${idx >= 0 ? idx + 1 : "?"}/${path.length} [${path.join(" \u2192 ")}]`);
53335
+ printLine(`Progress: ${idx >= 0 ? idx + 1 : "?"}/${path.length} [${path.join(" \u2192 ")}]`);
53262
53336
  });
53263
53337
  provision.command("daemon").description("Reconcile domains toward ready (CF zone + NS delegation + propagation)").option("--domains <list>", "Comma-separated domains (default: all active in the portfolio)").option("--once", "Run a single reconcile tick and exit").option("--interval <sec>", "Seconds between ticks", "30").option("--max-ticks <n>", "Stop after N ticks").action(async (opts) => {
53264
53338
  const { applyPurchaseProfile: applyPurchaseProfile2 } = await Promise.resolve().then(() => (init_config(), exports_config));
53265
53339
  applyPurchaseProfile2();
53266
53340
  const { makeDomainDaemonDeps: makeDomainDaemonDeps2 } = await Promise.resolve().then(() => (init_domain_daemon_deps(), exports_domain_daemon_deps));
53267
53341
  const { reconcileDomainTick: reconcileDomainTick2, runDomainDaemon: runDomainDaemon2 } = await Promise.resolve().then(() => (init_domain_daemon(), exports_domain_daemon));
53268
- const deps = { ...makeDomainDaemonDeps2(), log: (e4, d4) => console.log(`[${e4}] ${JSON.stringify(d4)}`) };
53342
+ const deps = { ...makeDomainDaemonDeps2(), log: (e4, d4) => printLine(`[${e4}] ${JSON.stringify(d4)}`) };
53269
53343
  const listDomains4 = async () => {
53270
53344
  if (opts.domains)
53271
53345
  return opts.domains.split(",").map((d4) => d4.trim());
@@ -53274,16 +53348,16 @@ Domain: ${name}`);
53274
53348
  };
53275
53349
  if (opts.once) {
53276
53350
  const s2 = await reconcileDomainTick2(await listDomains4(), deps);
53277
- console.log(`\u2713 tick: ${s2.advanced} advanced, ${s2.ready} ready, ${s2.errors} errors (${s2.processed} processed)`);
53351
+ printLine(`\u2713 tick: ${s2.advanced} advanced, ${s2.ready} ready, ${s2.errors} errors (${s2.processed} processed)`);
53278
53352
  return;
53279
53353
  }
53280
- console.log(`Domain provisioning daemon started (interval ${opts.interval}s). Ctrl-C to stop.`);
53354
+ printLine(`Domain provisioning daemon started (interval ${opts.interval}s). Ctrl-C to stop.`);
53281
53355
  const total = await runDomainDaemon2(listDomains4, {
53282
53356
  ...deps,
53283
53357
  intervalSec: parseInt(opts.interval, 10),
53284
53358
  maxTicks: opts.maxTicks ? parseInt(opts.maxTicks, 10) : undefined
53285
53359
  });
53286
- console.log(`daemon stopped: ${total.advanced} advanced, ${total.ready} ready, ${total.errors} errors`);
53360
+ printLine(`daemon stopped: ${total.advanced} advanced, ${total.ready} ready, ${total.errors} errors`);
53287
53361
  });
53288
53362
  }
53289
53363
  var CF_NS_SUFFIX2 = ".ns.cloudflare.com";
@@ -53291,6 +53365,7 @@ var init_provision = __esm(() => {
53291
53365
  init_provision_state();
53292
53366
  init_route53();
53293
53367
  init_cloudflare();
53368
+ init_stdout();
53294
53369
  });
53295
53370
 
53296
53371
  // src/cli/tui/format.ts
@@ -54012,10 +54087,12 @@ __export(exports_interactive, {
54012
54087
  import chalk from "chalk";
54013
54088
  import { render } from "ink";
54014
54089
  import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
54015
- function assertInteractiveTty() {
54090
+ function assertInteractiveTty(emit = (line) => {
54091
+ printErrorLine(line);
54092
+ }) {
54016
54093
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
54017
- console.error(chalk.red("Interactive mode requires a TTY terminal."));
54018
- console.error(chalk.dim("Use `domains domain list` or `domains domain get <name>` for non-interactive use."));
54094
+ emit(chalk.red("Interactive mode requires a TTY terminal."));
54095
+ emit(chalk.dim("Use `domains domain list` or `domains domain get <name>` for non-interactive use."));
54019
54096
  process.exit(1);
54020
54097
  }
54021
54098
  }
@@ -54029,6 +54106,7 @@ function registerInteractiveCommand(program2) {
54029
54106
  }
54030
54107
  var init_interactive = __esm(() => {
54031
54108
  init_App();
54109
+ init_stdout();
54032
54110
  });
54033
54111
 
54034
54112
  // node_modules/@hasna/events/dist/commander.js
@@ -55589,6 +55667,7 @@ function getCapability(name) {
55589
55667
  }
55590
55668
 
55591
55669
  // src/cli/commands/domain.ts
55670
+ init_stdout();
55592
55671
  var DOMAIN_STATUS_HELP = DOMAIN_STATUSES.join("/");
55593
55672
  var DOMAIN_OFFER_STATUS_HELP = DOMAIN_OFFER_STATUSES.join("/");
55594
55673
  var DOMAIN_EMAIL_TYPE_HELP = DOMAIN_EMAIL_TYPES.join("/");
@@ -55615,7 +55694,7 @@ async function createDnsZoneForProvider(domain, provider) {
55615
55694
  async function requireDomain(identifier) {
55616
55695
  const details = await getDomainDetails2(identifier);
55617
55696
  if (!details) {
55618
- console.error(`Domain '${identifier}' not found.`);
55697
+ printErrorLine(`Domain '${identifier}' not found.`);
55619
55698
  process.exit(1);
55620
55699
  }
55621
55700
  return details;
@@ -55631,7 +55710,7 @@ function registerDomainCommand(program2) {
55631
55710
  jsonLimit = opts.limit === undefined ? undefined : parseLimit(opts.limit, undefined, Infinity);
55632
55711
  offset = parseOffset(opts.offset);
55633
55712
  } catch (error) {
55634
- console.error(error instanceof Error ? error.message : String(error));
55713
+ printErrorLine(error instanceof Error ? error.message : String(error));
55635
55714
  process.exit(1);
55636
55715
  }
55637
55716
  const filters = {
@@ -55648,7 +55727,7 @@ function registerDomainCommand(program2) {
55648
55727
  fallbackLimit: Infinity,
55649
55728
  maxLimit: Infinity
55650
55729
  });
55651
- console.log(JSON.stringify({
55730
+ printLine(JSON.stringify({
55652
55731
  domains: jsonPage.items,
55653
55732
  count: jsonPage.shown,
55654
55733
  total: jsonPage.total,
@@ -55661,7 +55740,7 @@ function registerDomainCommand(program2) {
55661
55740
  }
55662
55741
  const page = pageItemsOrExit(domains, { limit, offset, all: opts.all });
55663
55742
  if (page.items.length === 0) {
55664
- console.log("No domains found.");
55743
+ printLine("No domains found.");
55665
55744
  return;
55666
55745
  }
55667
55746
  for (const d4 of page.items) {
@@ -55670,47 +55749,47 @@ function registerDomainCommand(program2) {
55670
55749
  if (opts.verbose) {
55671
55750
  const registrar = d4.registrar ? ` reg:${truncateText(d4.registrar, 24)}` : "";
55672
55751
  const notes = d4.notes ? ` notes:${truncateText(d4.notes, 60)}` : "";
55673
- console.log(` ${d4.name} [${d4.status}]${registrar}${exp}${premium}${notes}`);
55752
+ printLine(` ${d4.name} [${d4.status}]${registrar}${exp}${premium}${notes}`);
55674
55753
  } else {
55675
- console.log(` ${d4.name} [${d4.status}]${exp}${premium}`);
55754
+ printLine(` ${d4.name} [${d4.status}]${exp}${premium}`);
55676
55755
  }
55677
55756
  }
55678
- console.log(`
55757
+ printLine(`
55679
55758
  ${compactHint(page, "domain(s)", "Use --verbose for registrar/notes or domain get <id|name> for details.")}`);
55680
55759
  });
55681
55760
  domain.command("get <identifier>").description("Get a domain by ID or name").option("-j, --json", "Output JSON").action(async (identifier, opts) => {
55682
55761
  const details = await getDomainDetails2(identifier);
55683
55762
  if (!details) {
55684
- console.error(`Domain '${identifier}' not found.`);
55763
+ printErrorLine(`Domain '${identifier}' not found.`);
55685
55764
  process.exit(1);
55686
55765
  }
55687
55766
  if (opts.json) {
55688
- console.log(JSON.stringify(details, null, 2));
55767
+ printLine(JSON.stringify(details, null, 2));
55689
55768
  return;
55690
55769
  }
55691
55770
  const d4 = details.domain;
55692
- console.log(`
55771
+ printLine(`
55693
55772
  ${d4.name} [${d4.status}]`);
55694
55773
  if (d4.registrar)
55695
- console.log(` Registrar: ${d4.registrar}`);
55774
+ printLine(` Registrar: ${d4.registrar}`);
55696
55775
  if (d4.expires_at)
55697
- console.log(` Expires: ${formatDate(d4.expires_at)}`);
55776
+ printLine(` Expires: ${formatDate(d4.expires_at)}`);
55698
55777
  if (d4.purchase_date)
55699
- console.log(` Purchased: ${formatDate(d4.purchase_date)}`);
55778
+ printLine(` Purchased: ${formatDate(d4.purchase_date)}`);
55700
55779
  if (d4.purchase_price !== null)
55701
- console.log(` Purchase price: ${d4.purchase_price}`);
55702
- console.log(` Auto-renew: ${d4.auto_renew ? "yes" : "no"}`);
55780
+ printLine(` Purchase price: ${d4.purchase_price}`);
55781
+ printLine(` Auto-renew: ${d4.auto_renew ? "yes" : "no"}`);
55703
55782
  if (d4.is_premium) {
55704
- console.log(` Premium: yes`);
55783
+ printLine(` Premium: yes`);
55705
55784
  if (d4.premium_price !== null)
55706
- console.log(` Premium ask: ${d4.premium_price}`);
55785
+ printLine(` Premium ask: ${d4.premium_price}`);
55707
55786
  }
55708
55787
  if (d4.standard_price !== null)
55709
- console.log(` Standard price: ${d4.standard_price}`);
55788
+ printLine(` Standard price: ${d4.standard_price}`);
55710
55789
  if (d4.notes)
55711
- console.log(` Notes: ${truncateText(d4.notes, 160)}`);
55790
+ printLine(` Notes: ${truncateText(d4.notes, 160)}`);
55712
55791
  if (details.offers.length > 0) {
55713
- console.log(`
55792
+ printLine(`
55714
55793
  Offers:`);
55715
55794
  const offerPage = pageItemsOrExit(details.offers, { fallbackLimit: 5 });
55716
55795
  for (const offer of offerPage.items) {
@@ -55721,23 +55800,23 @@ Offers:`);
55721
55800
  offer.their_ask !== null ? `their=${offer.their_ask}` : null,
55722
55801
  offer.notes
55723
55802
  ].filter(Boolean);
55724
- console.log(` - ${parts.join(" | ")}`);
55803
+ printLine(` - ${parts.join(" | ")}`);
55725
55804
  }
55726
55805
  if (offerPage.hasMore)
55727
- console.log(` ${compactHint(offerPage, "offer(s)", "Use --json for the full offer history.", { paging: "none" })}`);
55806
+ printLine(` ${compactHint(offerPage, "offer(s)", "Use --json for the full offer history.", { paging: "none" })}`);
55728
55807
  }
55729
55808
  if (details.emails.length > 0) {
55730
- console.log(`
55809
+ printLine(`
55731
55810
  Emails:`);
55732
55811
  const emailPage = pageItemsOrExit(details.emails, { fallbackLimit: 5 });
55733
55812
  for (const email of emailPage.items) {
55734
55813
  const threadPart = email.thread_id ? ` thread=${email.thread_id}` : "";
55735
- console.log(` - ${email.type}: ${email.email_id}${threadPart}`);
55814
+ printLine(` - ${email.type}: ${email.email_id}${threadPart}`);
55736
55815
  }
55737
55816
  if (emailPage.hasMore)
55738
- console.log(` ${compactHint(emailPage, "email link(s)", "Use --json for the full email list.", { paging: "none" })}`);
55817
+ printLine(` ${compactHint(emailPage, "email link(s)", "Use --json for the full email list.", { paging: "none" })}`);
55739
55818
  }
55740
- console.log();
55819
+ printLine();
55741
55820
  });
55742
55821
  domain.command("add").description("Add a domain to the portfolio").requiredOption("--name <name>", "Domain name").option("--registrar <name>", "Registrar name").option("--status <s>", `Status (${DOMAIN_STATUS_HELP})`, "active").option("--expires <date>", "Expiry date (YYYY-MM-DD)").option("--premium", "Mark the domain as premium").option("--premium-price <price>", "Premium asking price").option("--standard-price <price>", "Standard registration price").option("--purchase-price <price>", "Acquisition price paid").option("--purchase-date <date>", "Purchase date (ISO or YYYY-MM-DD)").option("--notes <text>", "Notes").option("-j, --json", "Output JSON").action(async (opts) => {
55743
55822
  const premiumPrice = parseOptionalNumber(opts.premiumPrice, "--premium-price");
@@ -55756,10 +55835,10 @@ Emails:`);
55756
55835
  notes: opts.notes
55757
55836
  });
55758
55837
  if (opts.json) {
55759
- console.log(JSON.stringify(d4, null, 2));
55838
+ printLine(JSON.stringify(d4, null, 2));
55760
55839
  return;
55761
55840
  }
55762
- console.log(`Created domain: ${d4.name} (${d4.id})`);
55841
+ printLine(`Created domain: ${d4.name} (${d4.id})`);
55763
55842
  });
55764
55843
  domain.command("update <id>").description("Update a domain").option("--registrar <name>", "Registrar").option("--status <s>", `Status (${DOMAIN_STATUS_HELP})`).option("--expires <date>", "Expiry date").option("--premium <bool>", "Premium flag (true/false)").option("--premium-price <price>", "Premium asking price").option("--standard-price <price>", "Standard registration price").option("--purchase-price <price>", "Purchase price paid").option("--purchase-date <date>", "Purchase date").option("--notes <text>", "Notes").option("-j, --json", "Output JSON").action(async (id, opts) => {
55765
55844
  const premiumPrice = parseOptionalNumber(opts.premiumPrice, "--premium-price");
@@ -55777,23 +55856,23 @@ Emails:`);
55777
55856
  notes: opts.notes
55778
55857
  });
55779
55858
  if (!d4) {
55780
- console.error(`Domain '${id}' not found.`);
55859
+ printErrorLine(`Domain '${id}' not found.`);
55781
55860
  process.exit(1);
55782
55861
  }
55783
55862
  if (opts.json) {
55784
- console.log(JSON.stringify(d4, null, 2));
55863
+ printLine(JSON.stringify(d4, null, 2));
55785
55864
  return;
55786
55865
  }
55787
- console.log(`Updated: ${d4.name}`);
55866
+ printLine(`Updated: ${d4.name}`);
55788
55867
  });
55789
55868
  domain.command("delete <id>").description("Delete a domain from the portfolio").option("-f, --force", "Required confirmation for destructive delete").option("-j, --json", "Output JSON").action(async (id, opts) => {
55790
55869
  if (!opts.force) {
55791
55870
  const message = `Refusing to delete domain '${id}' without --force.`;
55792
55871
  if (opts.json) {
55793
- console.log(JSON.stringify({ deleted: false, id, error: message }, null, 2));
55872
+ printLine(JSON.stringify({ deleted: false, id, error: message }, null, 2));
55794
55873
  } else {
55795
- console.error(message);
55796
- console.error("Re-run with --force to confirm deletion.");
55874
+ printErrorLine(message);
55875
+ printErrorLine("Re-run with --force to confirm deletion.");
55797
55876
  }
55798
55877
  process.exit(1);
55799
55878
  }
@@ -55801,105 +55880,105 @@ Emails:`);
55801
55880
  if (!deleted) {
55802
55881
  const message = `Domain '${id}' not found.`;
55803
55882
  if (opts.json) {
55804
- console.log(JSON.stringify({ deleted: false, id, error: message }, null, 2));
55883
+ printLine(JSON.stringify({ deleted: false, id, error: message }, null, 2));
55805
55884
  } else {
55806
- console.error(message);
55885
+ printErrorLine(message);
55807
55886
  }
55808
55887
  process.exit(1);
55809
55888
  }
55810
55889
  if (opts.json) {
55811
- console.log(JSON.stringify({ deleted: true, id }, null, 2));
55890
+ printLine(JSON.stringify({ deleted: true, id }, null, 2));
55812
55891
  return;
55813
55892
  }
55814
- console.log(`Deleted domain ${id}`);
55893
+ printLine(`Deleted domain ${id}`);
55815
55894
  });
55816
55895
  domain.command("search <query>").description("Search domains by name, registrar, or notes").option("--limit <n>", "Limit number of displayed domains").option("--offset <n>", "Skip first N domains", "0").option("--all", "Show all matching domains").option("--verbose", "Show registrar and truncated notes").option("-j, --json", "Output JSON").action(async (query, opts) => {
55817
55896
  const results = await searchDomains2(query);
55818
55897
  if (opts.json) {
55819
- console.log(JSON.stringify({ results, count: results.length }, null, 2));
55898
+ printLine(JSON.stringify({ results, count: results.length }, null, 2));
55820
55899
  return;
55821
55900
  }
55822
55901
  let page;
55823
55902
  try {
55824
55903
  page = pageItemsOrExit(results, { limit: opts.limit, offset: opts.offset, all: opts.all });
55825
55904
  } catch (error) {
55826
- console.error(error instanceof Error ? error.message : String(error));
55905
+ printErrorLine(error instanceof Error ? error.message : String(error));
55827
55906
  process.exit(1);
55828
55907
  }
55829
55908
  for (const d4 of page.items) {
55830
55909
  const notes = opts.verbose && d4.notes ? ` \u2014 ${truncateText(d4.notes, 80)}` : "";
55831
- console.log(` ${d4.name} [${d4.status}]${notes}`);
55910
+ printLine(` ${d4.name} [${d4.status}]${notes}`);
55832
55911
  }
55833
55912
  if (results.length === 0)
55834
- console.log("No results.");
55913
+ printLine("No results.");
55835
55914
  else
55836
- console.log(`
55915
+ printLine(`
55837
55916
  ${compactHint(page, "result(s)", "Use --verbose for notes or domain get <id|name> for details.")}`);
55838
55917
  });
55839
55918
  domain.command("expiring").description("List domains expiring soon").option("--days <n>", "Days threshold", "30").option("--limit <n>", "Limit number of displayed domains").option("--all", "Show all matching domains").option("-j, --json", "Output JSON").action(async (opts) => {
55840
55919
  const domains = await listExpiring2(parseInt(opts.days));
55841
55920
  if (opts.json) {
55842
- console.log(JSON.stringify(domains, null, 2));
55921
+ printLine(JSON.stringify(domains, null, 2));
55843
55922
  return;
55844
55923
  }
55845
55924
  const page = pageItemsOrExit(domains, { limit: opts.limit, all: opts.all });
55846
55925
  if (page.items.length === 0) {
55847
- console.log(`No domains expiring within ${opts.days} days.`);
55926
+ printLine(`No domains expiring within ${opts.days} days.`);
55848
55927
  return;
55849
55928
  }
55850
- console.log(`
55929
+ printLine(`
55851
55930
  Expiring within ${opts.days} days:`);
55852
55931
  for (const d4 of page.items)
55853
- console.log(` ${d4.name.padEnd(40)} expires ${formatDate(d4.expires_at)}`);
55854
- console.log(`
55932
+ printLine(` ${d4.name.padEnd(40)} expires ${formatDate(d4.expires_at)}`);
55933
+ printLine(`
55855
55934
  ${compactHint(page, "domain(s)", "Use --all to display every expiring domain.", { paging: "limit" })}`);
55856
55935
  });
55857
55936
  domain.command("stats").description("Show portfolio statistics").option("-j, --json", "Output JSON").action(async (opts) => {
55858
55937
  const stats = await getDomainStats2();
55859
55938
  if (opts.json) {
55860
- console.log(JSON.stringify(stats, null, 2));
55939
+ printLine(JSON.stringify(stats, null, 2));
55861
55940
  return;
55862
55941
  }
55863
- console.log("Domain Portfolio Stats:");
55942
+ printLine("Domain Portfolio Stats:");
55864
55943
  for (const [k4, v2] of Object.entries(stats)) {
55865
- console.log(` ${k4.replace(/_/g, " ")}: ${v2}`);
55944
+ printLine(` ${k4.replace(/_/g, " ")}: ${v2}`);
55866
55945
  }
55867
55946
  });
55868
55947
  domain.command("whois <name>").description("Run WHOIS lookup and update local DB record").option("-j, --json", "Output JSON").action(async (name, opts) => {
55869
55948
  try {
55870
55949
  const result = await whoisLookup(name);
55871
55950
  if (opts.json) {
55872
- console.log(JSON.stringify(result, null, 2));
55951
+ printLine(JSON.stringify(result, null, 2));
55873
55952
  return;
55874
55953
  }
55875
- console.log(`
55954
+ printLine(`
55876
55955
  WHOIS for ${result.domain} [${result.source}]:`);
55877
- console.log(` Registrar: ${result.registrar ?? "unknown"}`);
55878
- console.log(` Expires: ${result.expires_at ?? "unknown"}`);
55956
+ printLine(` Registrar: ${result.registrar ?? "unknown"}`);
55957
+ printLine(` Expires: ${result.expires_at ?? "unknown"}`);
55879
55958
  if (result.nameservers.length) {
55880
- console.log(` NS: ${result.nameservers.join(", ")}`);
55959
+ printLine(` NS: ${result.nameservers.join(", ")}`);
55881
55960
  }
55882
55961
  const r4 = result.registrant;
55883
55962
  if (r4?.name || r4?.email || r4?.organization) {
55884
- console.log(` Registrant:`);
55963
+ printLine(` Registrant:`);
55885
55964
  if (r4.name)
55886
- console.log(` Name: ${r4.name}`);
55965
+ printLine(` Name: ${r4.name}`);
55887
55966
  if (r4.email)
55888
- console.log(` Email: ${r4.email}`);
55967
+ printLine(` Email: ${r4.email}`);
55889
55968
  if (r4.phone)
55890
- console.log(` Phone: ${r4.phone}`);
55969
+ printLine(` Phone: ${r4.phone}`);
55891
55970
  if (r4.organization)
55892
- console.log(` Org: ${r4.organization}`);
55971
+ printLine(` Org: ${r4.organization}`);
55893
55972
  }
55894
- console.log();
55973
+ printLine();
55895
55974
  } catch (error) {
55896
- console.error(`WHOIS lookup failed: ${error instanceof Error ? error.message : String(error)}`);
55975
+ printErrorLine(`WHOIS lookup failed: ${error instanceof Error ? error.message : String(error)}`);
55897
55976
  process.exit(1);
55898
55977
  }
55899
55978
  });
55900
55979
  domain.command("export").description("Export all domains as CSV or JSON").option("--format <fmt>", "Format: csv or json", "json").action(async (opts) => {
55901
55980
  const output = await exportPortfolio(opts.format);
55902
- console.log(output);
55981
+ printLine(output);
55903
55982
  });
55904
55983
  domain.command("check <domains...>").description("Check domain availability via configured registrar").option("--provider <name>", "Registrar provider to use").option("-j, --json", "Output JSON").action(async (domains, opts) => {
55905
55984
  const cfg = loadConfig3();
@@ -55917,19 +55996,19 @@ WHOIS for ${result.domain} [${result.source}]:`);
55917
55996
  const error = reason instanceof Error ? reason.message : String(reason);
55918
55997
  output.push({ domain: domains[i4], error });
55919
55998
  if (!opts.json) {
55920
- console.error(`\u2717 ${domains[i4]}: ${error}`);
55999
+ printErrorLine(`\u2717 ${domains[i4]}: ${error}`);
55921
56000
  }
55922
56001
  anyError = true;
55923
56002
  } else {
55924
56003
  const result = r4.value;
55925
56004
  output.push({ domain: result.domain, available: result.available });
55926
56005
  if (!opts.json) {
55927
- console.log(`${result.available ? "\u2713" : "\u2717"} ${result.domain} is ${result.available ? "available" : "not available"}`);
56006
+ printLine(`${result.available ? "\u2713" : "\u2717"} ${result.domain} is ${result.available ? "available" : "not available"}`);
55928
56007
  }
55929
56008
  }
55930
56009
  }
55931
56010
  if (opts.json) {
55932
- console.log(JSON.stringify({
56011
+ printLine(JSON.stringify({
55933
56012
  provider: providerName,
55934
56013
  count: output.length,
55935
56014
  ok: !anyError,
@@ -55938,11 +56017,11 @@ WHOIS for ${result.domain} [${result.source}]:`);
55938
56017
  } else {
55939
56018
  for (const result of output) {
55940
56019
  if (result.available !== undefined && "is_premium" in result && result.is_premium) {
55941
- console.log(` Premium ask: ${result.premium_price ?? "unknown"}`);
56020
+ printLine(` Premium ask: ${result.premium_price ?? "unknown"}`);
55942
56021
  }
55943
56022
  if ("standard_price" in result && result.standard_price !== undefined) {
55944
56023
  const currency = "currency" in result && result.currency ? ` ${result.currency}` : "";
55945
- console.log(` Standard price: ${result.standard_price}${currency}`);
56024
+ printLine(` Standard price: ${result.standard_price}${currency}`);
55946
56025
  }
55947
56026
  }
55948
56027
  }
@@ -55968,11 +56047,11 @@ WHOIS for ${result.domain} [${result.source}]:`);
55968
56047
  try {
55969
56048
  const provider = getDomainInventoryProvider(name);
55970
56049
  const result = await provider.syncToLocalDb({ getDomainByName: getDomainByName2, createDomain: createDomain2, updateDomain: updateDomain2 });
55971
- console.log(`\u2713 [${name}] Synced ${result.synced} (${result.created} new, ${result.updated} updated)`);
56050
+ printLine(`\u2713 [${name}] Synced ${result.synced} (${result.created} new, ${result.updated} updated)`);
55972
56051
  if (result.errors.length > 0)
55973
- console.log(` Errors: ${result.errors.join(", ")}`);
56052
+ printLine(` Errors: ${result.errors.join(", ")}`);
55974
56053
  } catch (e4) {
55975
- console.error(`\u2717 [${name}] ${e4 instanceof Error ? e4.message : String(e4)}`);
56054
+ printErrorLine(`\u2717 [${name}] ${e4 instanceof Error ? e4.message : String(e4)}`);
55976
56055
  }
55977
56056
  }
55978
56057
  });
@@ -55981,14 +56060,14 @@ WHOIS for ${result.domain} [${result.source}]:`);
55981
56060
  const standardPrice = parseOptionalNumber(opts.standard, "--standard");
55982
56061
  const updated = await markDomainPremium2(identifier, premiumPrice, standardPrice);
55983
56062
  if (!updated) {
55984
- console.error(`Domain '${identifier}' not found.`);
56063
+ printErrorLine(`Domain '${identifier}' not found.`);
55985
56064
  process.exit(1);
55986
56065
  }
55987
56066
  if (opts.json) {
55988
- console.log(JSON.stringify(updated, null, 2));
56067
+ printLine(JSON.stringify(updated, null, 2));
55989
56068
  return;
55990
56069
  }
55991
- console.log(`Marked ${updated.name} as premium at ${premiumPrice}`);
56070
+ printLine(`Marked ${updated.name} as premium at ${premiumPrice}`);
55992
56071
  });
55993
56072
  domain.command("offer <identifier>").description("Record a negotiation step for a domain").option("--our <price>", "Our offer").option("--their <price>", "Their asking price").option("--status <status>", `Offer status (${DOMAIN_OFFER_STATUS_HELP})`, "pending").option("--notes <text>", "Negotiation notes").option("-j, --json", "Output JSON").action(async (identifier, opts) => {
55994
56073
  const details = await requireDomain(identifier);
@@ -56003,37 +56082,37 @@ WHOIS for ${result.domain} [${result.source}]:`);
56003
56082
  await updateDomainLifecycleStatus2(details.domain.id, opts.their || opts.our ? "negotiating" : "offered");
56004
56083
  }
56005
56084
  if (opts.json) {
56006
- console.log(JSON.stringify(offer, null, 2));
56085
+ printLine(JSON.stringify(offer, null, 2));
56007
56086
  return;
56008
56087
  }
56009
- console.log(`Logged offer for ${details.domain.name}: ${offer.status}`);
56088
+ printLine(`Logged offer for ${details.domain.name}: ${offer.status}`);
56010
56089
  });
56011
56090
  domain.command("status <identifier> <status>").description("Update the lifecycle status of a domain").option("--notes <text>", "Optional note to store with the status change").option("-j, --json", "Output JSON").action(async (identifier, status, opts) => {
56012
56091
  const updated = await updateDomainLifecycleStatus2(identifier, status, opts.notes);
56013
56092
  if (!updated) {
56014
- console.error(`Domain '${identifier}' not found.`);
56093
+ printErrorLine(`Domain '${identifier}' not found.`);
56015
56094
  process.exit(1);
56016
56095
  }
56017
56096
  if (opts.json) {
56018
- console.log(JSON.stringify(updated, null, 2));
56097
+ printLine(JSON.stringify(updated, null, 2));
56019
56098
  return;
56020
56099
  }
56021
- console.log(`Updated ${updated.name} to ${updated.status}`);
56100
+ printLine(`Updated ${updated.name} to ${updated.status}`);
56022
56101
  });
56023
56102
  domain.command("emails <identifier>").description("Show email threads linked to a domain").option("-j, --json", "Output JSON").action(async (identifier, opts) => {
56024
56103
  const details = await requireDomain(identifier);
56025
56104
  const emails = await listDomainEmailLinks2(details.domain.id);
56026
56105
  if (opts.json) {
56027
- console.log(JSON.stringify({ domain: details.domain.name, emails, count: emails.length }, null, 2));
56106
+ printLine(JSON.stringify({ domain: details.domain.name, emails, count: emails.length }, null, 2));
56028
56107
  return;
56029
56108
  }
56030
56109
  if (emails.length === 0) {
56031
- console.log(`No linked emails for ${details.domain.name}.`);
56110
+ printLine(`No linked emails for ${details.domain.name}.`);
56032
56111
  return;
56033
56112
  }
56034
56113
  for (const email of emails) {
56035
56114
  const threadPart = email.thread_id ? ` (${email.thread_id})` : "";
56036
- console.log(` ${email.type}: ${email.email_id}${threadPart}`);
56115
+ printLine(` ${email.type}: ${email.email_id}${threadPart}`);
56037
56116
  }
56038
56117
  });
56039
56118
  domain.command("link-email <identifier> <emailId>").description("Link an email or email thread to a domain").requiredOption("--type <type>", `Link type (${DOMAIN_EMAIL_TYPE_HELP})`).option("--thread-id <threadId>", "Email thread ID").option("-j, --json", "Output JSON").action(async (identifier, emailId, opts) => {
@@ -56045,25 +56124,25 @@ WHOIS for ${result.domain} [${result.source}]:`);
56045
56124
  type: opts.type
56046
56125
  });
56047
56126
  if (opts.json) {
56048
- console.log(JSON.stringify(link, null, 2));
56127
+ printLine(JSON.stringify(link, null, 2));
56049
56128
  return;
56050
56129
  }
56051
- console.log(`Linked ${emailId} to ${details.domain.name}`);
56130
+ printLine(`Linked ${emailId} to ${details.domain.name}`);
56052
56131
  });
56053
56132
  domain.command("renew <name>").description("Renew a domain via its registrar provider").option("--provider <name>", "Override provider").option("--years <n>", "Number of years to renew", "1").action(async (name, opts) => {
56054
56133
  const providerName = opts.provider ?? await autoDetectRegistrar(name, getDomainByName2) ?? loadConfig3().default_registrar;
56055
56134
  if (!providerName) {
56056
- console.error("Could not detect provider. Use --provider.");
56135
+ printErrorLine("Could not detect provider. Use --provider.");
56057
56136
  process.exit(1);
56058
56137
  }
56059
56138
  const provider = getRegistrarProvider(providerName);
56060
56139
  const result = await provider.renewDomain(name, parseInt(opts.years, 10));
56061
56140
  if (result.success) {
56062
- console.log(`\u2713 Renewed: ${name}`);
56141
+ printLine(`\u2713 Renewed: ${name}`);
56063
56142
  if (result.orderId)
56064
- console.log(` Order: ${result.orderId}`);
56143
+ printLine(` Order: ${result.orderId}`);
56065
56144
  } else {
56066
- console.error(`\u2717 Renewal failed or not supported for ${providerName}`);
56145
+ printErrorLine(`\u2717 Renewal failed or not supported for ${providerName}`);
56067
56146
  process.exit(1);
56068
56147
  }
56069
56148
  });
@@ -56080,13 +56159,13 @@ WHOIS for ${result.domain} [${result.source}]:`);
56080
56159
  auto_renew: opts.autoRenew ? opts.autoRenew === "true" : domainRecord.auto_renew
56081
56160
  });
56082
56161
  if (!purchased) {
56083
- console.error(`Domain '${name}' not found.`);
56162
+ printErrorLine(`Domain '${name}' not found.`);
56084
56163
  process.exit(1);
56085
56164
  }
56086
56165
  if (opts.wait) {
56087
56166
  await updateDomainLifecycleStatus2(purchased.id, "active");
56088
56167
  }
56089
- console.log(`Recorded purchase for ${purchased.name} at ${recordedPrice}`);
56168
+ printLine(`Recorded purchase for ${purchased.name} at ${recordedPrice}`);
56090
56169
  return;
56091
56170
  }
56092
56171
  const cfg = loadConfig3();
@@ -56094,44 +56173,44 @@ WHOIS for ${result.domain} [${result.source}]:`);
56094
56173
  const dnsProvider = opts.dns ?? cfg.default_dns ?? "cloudflare";
56095
56174
  const purchaseProfile = providerName === "route53" ? applyPurchaseProfile() : undefined;
56096
56175
  if (purchaseProfile)
56097
- console.log(`Using purchase AWS profile: ${purchaseProfile}`);
56176
+ printLine(`Using purchase AWS profile: ${purchaseProfile}`);
56098
56177
  if (providerName !== "route53") {
56099
56178
  try {
56100
56179
  const capability = getCapability(providerName);
56101
56180
  if (!capability.canBuy) {
56102
- console.error(`Direct domain purchase is not supported for ${providerName}. ${capability.notes} Use route53 or record a marketplace/manual purchase with --price.`);
56181
+ printErrorLine(`Direct domain purchase is not supported for ${providerName}. ${capability.notes} Use route53 or record a marketplace/manual purchase with --price.`);
56103
56182
  process.exit(1);
56104
56183
  }
56105
56184
  if (capability.gated && !opts.allowGated) {
56106
- console.error(`Registrar '${providerName}' is gated/enterprise-only. Pass --allow-gated only when this account is contract-approved. ${capability.notes}`);
56185
+ printErrorLine(`Registrar '${providerName}' is gated/enterprise-only. Pass --allow-gated only when this account is contract-approved. ${capability.notes}`);
56107
56186
  process.exit(1);
56108
56187
  }
56109
56188
  const provider = getRegistrarProvider(providerName);
56110
56189
  if (!provider.registerDomain) {
56111
- console.error(`Direct domain purchase is not supported for ${providerName}. Use route53 or record a marketplace/manual purchase with --price.`);
56190
+ printErrorLine(`Direct domain purchase is not supported for ${providerName}. Use route53 or record a marketplace/manual purchase with --price.`);
56112
56191
  process.exit(1);
56113
56192
  }
56114
56193
  const avail = await provider.checkAvailability(name);
56115
56194
  if (!avail.available) {
56116
- console.error(`\u2717 ${name} is not available`);
56195
+ printErrorLine(`\u2717 ${name} is not available`);
56117
56196
  process.exit(1);
56118
56197
  }
56119
- console.log(`\u2713 Available via ${providerName}`);
56198
+ printLine(`\u2713 Available via ${providerName}`);
56120
56199
  let contact;
56121
56200
  try {
56122
56201
  contact = resolveContact(opts);
56123
56202
  } catch (e4) {
56124
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56203
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56125
56204
  process.exit(1);
56126
56205
  }
56127
- console.log(`Registering ${name} via ${providerName}...`);
56206
+ printLine(`Registering ${name} via ${providerName}...`);
56128
56207
  const reg = await provider.registerDomain(name, contact, {
56129
56208
  years: parseInt(opts.years, 10),
56130
56209
  premiumPrice: avail.premium_price,
56131
56210
  autoRenew: opts.autoRenew ? opts.autoRenew === "true" : true
56132
56211
  });
56133
56212
  if (!reg.success) {
56134
- console.error(`\u2717 Registration failed via ${providerName}`);
56213
+ printErrorLine(`\u2717 Registration failed via ${providerName}`);
56135
56214
  process.exit(1);
56136
56215
  }
56137
56216
  const existing = await getDomainByName2(name);
@@ -56149,45 +56228,45 @@ WHOIS for ${result.domain} [${result.source}]:`);
56149
56228
  await updateDomain2(existing.id, dbInput);
56150
56229
  else
56151
56230
  await createDomain2({ name, ...dbInput });
56152
- console.log(`\u2713 Registered and added to portfolio`);
56231
+ printLine(`\u2713 Registered and added to portfolio`);
56153
56232
  if (reg.orderId)
56154
- console.log(` Order: ${reg.orderId}`);
56233
+ printLine(` Order: ${reg.orderId}`);
56155
56234
  if (opts.delegate !== false) {
56156
56235
  if (!provider.updateNameservers) {
56157
- console.log(` DNS: ${providerName} registration succeeded, but nameserver updates are not implemented for this provider.`);
56236
+ printLine(` DNS: ${providerName} registration succeeded, but nameserver updates are not implemented for this provider.`);
56158
56237
  } else {
56159
56238
  const zone = await createDnsZoneForProvider(name, dnsProvider);
56160
56239
  const nsUpdate = await provider.updateNameservers(name, zone.nameservers);
56161
56240
  const existing2 = await getDomainByName2(name);
56162
56241
  if (existing2)
56163
56242
  await updateDomain2(existing2.id, { nameservers: zone.nameservers });
56164
- console.log(`\u2713 ${dnsProvider} zone ${zone.zoneId}; nameservers updated${nsUpdate.operationId ? ` (op ${nsUpdate.operationId})` : ""}`);
56243
+ printLine(`\u2713 ${dnsProvider} zone ${zone.zoneId}; nameservers updated${nsUpdate.operationId ? ` (op ${nsUpdate.operationId})` : ""}`);
56165
56244
  }
56166
56245
  }
56167
56246
  return;
56168
56247
  } catch (e4) {
56169
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56248
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56170
56249
  process.exit(1);
56171
56250
  }
56172
56251
  }
56173
56252
  try {
56174
56253
  const avail = await checkAvailability3(name);
56175
56254
  if (!avail.available) {
56176
- console.error(`\u2717 ${name} is not available`);
56255
+ printErrorLine(`\u2717 ${name} is not available`);
56177
56256
  process.exit(1);
56178
56257
  }
56179
56258
  const price = avail.price ? ` (USD ${avail.price}/yr)` : "";
56180
- console.log(`\u2713 Available${price}`);
56259
+ printLine(`\u2713 Available${price}`);
56181
56260
  let contact;
56182
56261
  try {
56183
56262
  contact = resolveContact(opts);
56184
56263
  } catch (e4) {
56185
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56264
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56186
56265
  process.exit(1);
56187
56266
  }
56188
- console.log(`Registering ${name}...`);
56267
+ printLine(`Registering ${name}...`);
56189
56268
  const reg = await registerDomain2(name, contact, parseInt(opts.years));
56190
- console.log(`\u2713 Submitted (operation: ${reg.operationId})`);
56269
+ printLine(`\u2713 Submitted (operation: ${reg.operationId})`);
56191
56270
  if (opts.wait) {
56192
56271
  let status = "IN_PROGRESS";
56193
56272
  while (status === "IN_PROGRESS" || status === "SUBMITTED") {
@@ -56196,12 +56275,12 @@ WHOIS for ${result.domain} [${result.source}]:`);
56196
56275
  status = s2.status;
56197
56276
  process.stdout.write(` Status: ${status}\r`);
56198
56277
  }
56199
- console.log();
56278
+ printLine();
56200
56279
  if (status !== "SUCCESSFUL") {
56201
- console.error(`\u2717 Registration ${status}`);
56280
+ printErrorLine(`\u2717 Registration ${status}`);
56202
56281
  process.exit(1);
56203
56282
  }
56204
- console.log(`\u2713 Registration complete`);
56283
+ printLine(`\u2713 Registration complete`);
56205
56284
  }
56206
56285
  const existing = await getDomainByName2(name);
56207
56286
  if (existing) {
@@ -56224,13 +56303,13 @@ WHOIS for ${result.domain} [${result.source}]:`);
56224
56303
  standard_price: avail.price ? Number(avail.price) : undefined
56225
56304
  });
56226
56305
  }
56227
- console.log(`\u2713 Added to portfolio`);
56306
+ printLine(`\u2713 Added to portfolio`);
56228
56307
  if (opts.delegate !== false) {
56229
56308
  if (!opts.wait) {
56230
- console.log(` DNS: run 'domains domain buy ${name} --wait' or delegate later \u2014 registration must finish before NS can change.`);
56309
+ printLine(` DNS: run 'domains domain buy ${name} --wait' or delegate later \u2014 registration must finish before NS can change.`);
56231
56310
  } else {
56232
56311
  try {
56233
- console.log(`Delegating DNS to ${dnsProvider}...`);
56312
+ printLine(`Delegating DNS to ${dnsProvider}...`);
56234
56313
  const del = dnsProvider === "cloudflare" ? await delegateDomainToCloudflare(name, {
56235
56314
  createCloudflareZone: async (d4) => {
56236
56315
  const z = await ensureZone(d4);
@@ -56245,17 +56324,17 @@ WHOIS for ${result.domain} [${result.source}]:`);
56245
56324
  const existing2 = await getDomainByName2(name);
56246
56325
  if (existing2)
56247
56326
  await updateDomain2(existing2.id, { nameservers: del.nameservers });
56248
- console.log(`\u2713 ${dnsProvider} zone ${del.zoneId}; nameservers \u2192 ${del.nameservers.join(", ")} (op ${del.operationId})`);
56327
+ printLine(`\u2713 ${dnsProvider} zone ${del.zoneId}; nameservers \u2192 ${del.nameservers.join(", ")} (op ${del.operationId})`);
56249
56328
  } catch (e4) {
56250
- console.error(`\u26A0 DNS delegation failed (domain is registered): ${e4 instanceof Error ? e4.message : String(e4)}`);
56251
- console.error(` Retry: create the DNS zone and point Route53 NS at it.`);
56329
+ printErrorLine(`\u26A0 DNS delegation failed (domain is registered): ${e4 instanceof Error ? e4.message : String(e4)}`);
56330
+ printErrorLine(` Retry: create the DNS zone and point Route53 NS at it.`);
56252
56331
  }
56253
56332
  }
56254
56333
  }
56255
56334
  if (!opts.wait)
56256
- console.log(` Check: domains r53 status ${reg.operationId}`);
56335
+ printLine(` Check: domains r53 status ${reg.operationId}`);
56257
56336
  } catch (e4) {
56258
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56337
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56259
56338
  process.exit(1);
56260
56339
  }
56261
56340
  });
@@ -56263,34 +56342,34 @@ WHOIS for ${result.domain} [${result.source}]:`);
56263
56342
  const cfg = loadConfig3();
56264
56343
  const registrarName = opts.registrar ?? cfg.default_registrar ?? "route53";
56265
56344
  const dnsName = opts.dns ?? cfg.default_dns ?? "cloudflare";
56266
- console.log(`
56345
+ printLine(`
56267
56346
  Setting up ${name}`);
56268
- console.log(` Registrar: ${registrarName} | DNS: ${dnsName}
56347
+ printLine(` Registrar: ${registrarName} | DNS: ${dnsName}
56269
56348
  `);
56270
56349
  try {
56271
56350
  process.stdout.write(opts.wait ? "[1/5] Checking availability... " : "[1/4] Checking availability... ");
56272
56351
  const avail = await checkAvailability3(name);
56273
56352
  if (!avail.available) {
56274
- console.log("not available");
56275
- console.error(`\u2717 ${name} is not available`);
56353
+ printLine("not available");
56354
+ printErrorLine(`\u2717 ${name} is not available`);
56276
56355
  process.exit(1);
56277
56356
  }
56278
56357
  const price = avail.price ? `(USD ${avail.price}/yr)` : "";
56279
- console.log(`available ${price}`);
56358
+ printLine(`available ${price}`);
56280
56359
  if (registrarName !== "route53") {
56281
- console.error("Direct domain purchase currently only supported via route53.");
56360
+ printErrorLine("Direct domain purchase currently only supported via route53.");
56282
56361
  process.exit(1);
56283
56362
  }
56284
56363
  let contact;
56285
56364
  try {
56286
56365
  contact = resolveContact(opts);
56287
56366
  } catch (e4) {
56288
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56367
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56289
56368
  process.exit(1);
56290
56369
  }
56291
56370
  process.stdout.write(opts.wait ? "[2/5] Registering domain... " : "[2/4] Registering domain... ");
56292
56371
  const reg = await registerDomain2(name, contact, parseInt(opts.years));
56293
- console.log(`submitted (${reg.operationId})`);
56372
+ printLine(`submitted (${reg.operationId})`);
56294
56373
  if (opts.wait) {
56295
56374
  let status = "IN_PROGRESS";
56296
56375
  while (status === "IN_PROGRESS" || status === "SUBMITTED") {
@@ -56299,36 +56378,36 @@ Setting up ${name}`);
56299
56378
  status = s2.status;
56300
56379
  process.stdout.write(` Waiting: ${status}...\r`);
56301
56380
  }
56302
- console.log();
56381
+ printLine();
56303
56382
  if (status !== "SUCCESSFUL") {
56304
- console.error(`\u2717 Registration ${status}`);
56383
+ printErrorLine(`\u2717 Registration ${status}`);
56305
56384
  process.exit(1);
56306
56385
  }
56307
- console.log(" Registration confirmed");
56386
+ printLine(" Registration confirmed");
56308
56387
  }
56309
56388
  process.stdout.write(opts.wait ? "[3/5] Creating DNS zone... " : "[3/4] Creating DNS zone... ");
56310
56389
  let nameservers = [];
56311
56390
  if (dnsName === "cloudflare") {
56312
56391
  const zone = await ensureZone(name);
56313
56392
  nameservers = zone.nameservers ?? [];
56314
- console.log("ready (" + zone.id + ")");
56393
+ printLine("ready (" + zone.id + ")");
56315
56394
  } else {
56316
56395
  const zone = await createHostedZone(name, "Managed by domains CLI");
56317
56396
  nameservers = zone.name_servers ?? [];
56318
- console.log(`created (${zone.id})`);
56397
+ printLine(`created (${zone.id})`);
56319
56398
  }
56320
56399
  if (nameservers.length > 0) {
56321
56400
  if (opts.wait) {
56322
56401
  process.stdout.write("[4/5] Updating registrar nameservers... ");
56323
56402
  if (registrarName !== "route53") {
56324
- console.log("skipped");
56325
- console.error("Only Route53 nameserver delegation is currently implemented for setup.");
56403
+ printLine("skipped");
56404
+ printErrorLine("Only Route53 nameserver delegation is currently implemented for setup.");
56326
56405
  process.exit(1);
56327
56406
  }
56328
56407
  const nsUpdate = await updateNameservers2(name, nameservers);
56329
- console.log("submitted (" + nsUpdate.operationId + ")");
56408
+ printLine("submitted (" + nsUpdate.operationId + ")");
56330
56409
  } else {
56331
- console.log(" Nameserver delegation skipped until registration completes; re-run with --wait or use domains r53 domain-info/status first.");
56410
+ printLine(" Nameserver delegation skipped until registration completes; re-run with --wait or use domains r53 domain-info/status first.");
56332
56411
  }
56333
56412
  }
56334
56413
  process.stdout.write(opts.wait ? "[5/5] Adding to portfolio... " : "[4/4] Adding to portfolio... ");
@@ -56338,22 +56417,22 @@ Setting up ${name}`);
56338
56417
  await updateDomain2(existing.id, dbInput);
56339
56418
  else
56340
56419
  await createDomain2({ name, ...dbInput });
56341
- console.log("done");
56342
- console.log(`
56420
+ printLine("done");
56421
+ printLine(`
56343
56422
  \u2713 Setup complete for ${name}`);
56344
56423
  if (!opts.wait) {
56345
- console.log(` \u26A0 Registration pending \u2014 check: domains r53 status ${reg.operationId}`);
56346
- console.log(` \u26A0 If registration fails, clean up: domains zone delete <zoneId> --force`);
56424
+ printLine(` \u26A0 Registration pending \u2014 check: domains r53 status ${reg.operationId}`);
56425
+ printLine(` \u26A0 If registration fails, clean up: domains zone delete <zoneId> --force`);
56347
56426
  }
56348
56427
  if (nameservers.length > 0) {
56349
- console.log(`
56428
+ printLine(`
56350
56429
  Point your registrar to these name servers:`);
56351
56430
  for (const ns of nameservers)
56352
- console.log(` ${ns}`);
56431
+ printLine(` ${ns}`);
56353
56432
  }
56354
- console.log();
56433
+ printLine();
56355
56434
  } catch (e4) {
56356
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56435
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56357
56436
  process.exit(1);
56358
56437
  }
56359
56438
  });
@@ -56472,6 +56551,7 @@ function getDnsApplyBlockReason(plan, opts) {
56472
56551
  }
56473
56552
 
56474
56553
  // src/cli/commands/dns.ts
56554
+ init_stdout();
56475
56555
  var SUPPORTED_DNS_TYPES = new Set(["A", "AAAA", "CNAME", "MX", "TXT", "NS", "SRV"]);
56476
56556
  function partitionPullableRecords(records) {
56477
56557
  const keep = [];
@@ -56486,13 +56566,13 @@ function partitionPullableRecords(records) {
56486
56566
  return { keep, skipped };
56487
56567
  }
56488
56568
  function printDnsPlan(plan) {
56489
- console.log(`DNS plan for ${plan.domain}: ${plan.creates} create, ${plan.updates} update, ${plan.deletes} delete, ${plan.unchanged} unchanged`);
56569
+ printLine(`DNS plan for ${plan.domain}: ${plan.creates} create, ${plan.updates} update, ${plan.deletes} delete, ${plan.unchanged} unchanged`);
56490
56570
  for (const op of plan.operations) {
56491
56571
  if (op.op === "unchanged")
56492
56572
  continue;
56493
56573
  const priority = op.record.priority == null ? "" : ` priority=${op.record.priority}`;
56494
56574
  const currentTtl = op.current && op.current.ttl !== op.record.ttl ? ` ttl ${op.current.ttl}->${op.record.ttl}` : "";
56495
- console.log(` ${op.op.toUpperCase()} ${op.record.type} ${op.record.name} ${op.record.value} ttl=${op.record.ttl}${priority}${currentTtl}`);
56575
+ printLine(` ${op.op.toUpperCase()} ${op.record.type} ${op.record.name} ${op.record.value} ttl=${op.record.ttl}${priority}${currentTtl}`);
56496
56576
  }
56497
56577
  }
56498
56578
  async function loadDnsPlan(domain, providerName, file) {
@@ -56509,11 +56589,11 @@ function registerDnsCommands(program2) {
56509
56589
  try {
56510
56590
  const plan = await loadDnsPlan(domain, providerName, opts.file);
56511
56591
  if (opts.json)
56512
- console.log(JSON.stringify(plan, null, 2));
56592
+ printLine(JSON.stringify(plan, null, 2));
56513
56593
  else
56514
56594
  printDnsPlan(plan);
56515
56595
  } catch (e4) {
56516
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56596
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56517
56597
  process.exit(1);
56518
56598
  }
56519
56599
  });
@@ -56522,13 +56602,13 @@ function registerDnsCommands(program2) {
56522
56602
  try {
56523
56603
  const plan = await loadDnsPlan(domain, providerName, opts.file);
56524
56604
  if (opts.json)
56525
- console.log(JSON.stringify(plan, null, 2));
56605
+ printLine(JSON.stringify(plan, null, 2));
56526
56606
  else
56527
56607
  printDnsPlan(plan);
56528
56608
  if (planHasChanges(plan))
56529
56609
  process.exitCode = 2;
56530
56610
  } catch (e4) {
56531
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56611
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56532
56612
  process.exit(1);
56533
56613
  }
56534
56614
  });
@@ -56542,7 +56622,7 @@ function registerDnsCommands(program2) {
56542
56622
  const plan = createDnsPlan(planDomain, current, desired.records);
56543
56623
  if (!planHasChanges(plan)) {
56544
56624
  if (opts.json)
56545
- console.log(JSON.stringify({ applied: false, reason: "no-changes", plan }, null, 2));
56625
+ printLine(JSON.stringify({ applied: false, reason: "no-changes", plan }, null, 2));
56546
56626
  else
56547
56627
  printDnsPlan(plan);
56548
56628
  return;
@@ -56550,15 +56630,15 @@ function registerDnsCommands(program2) {
56550
56630
  const blockReason = getDnsApplyBlockReason(plan, { yes: opts.yes, allowDelete: opts.allowDelete });
56551
56631
  if (blockReason) {
56552
56632
  if (opts.json)
56553
- console.log(JSON.stringify({ applied: false, reason: blockReason, plan }, null, 2));
56633
+ printLine(JSON.stringify({ applied: false, reason: blockReason, plan }, null, 2));
56554
56634
  else {
56555
56635
  printDnsPlan(plan);
56556
56636
  if (blockReason === "confirmation-required")
56557
- console.error("Refusing to apply without --yes.");
56637
+ printErrorLine("Refusing to apply without --yes.");
56558
56638
  if (blockReason === "delete-confirmation-required")
56559
- console.error("Refusing to delete DNS records without --allow-delete.");
56639
+ printErrorLine("Refusing to delete DNS records without --allow-delete.");
56560
56640
  if (blockReason === "delete-apply-unsupported")
56561
- console.error(`Refusing to apply delete plan on ${providerName}: this provider path cannot guarantee delete convergence without partial mutation yet.`);
56641
+ printErrorLine(`Refusing to apply delete plan on ${providerName}: this provider path cannot guarantee delete convergence without partial mutation yet.`);
56562
56642
  }
56563
56643
  process.exit(1);
56564
56644
  }
@@ -56566,39 +56646,39 @@ function registerDnsCommands(program2) {
56566
56646
  const verified = createDnsPlan(planDomain, await provider.getDnsRecords(planDomain), desired.records);
56567
56647
  if (planHasChanges(verified)) {
56568
56648
  if (opts.json)
56569
- console.log(JSON.stringify({ applied: false, provider: providerName, reason: "verification-failed", plan, verification: verified }, null, 2));
56649
+ printLine(JSON.stringify({ applied: false, provider: providerName, reason: "verification-failed", plan, verification: verified }, null, 2));
56570
56650
  else {
56571
56651
  printDnsPlan(verified);
56572
- console.error(`Provider ${providerName} did not converge to the desired DNS state for ${planDomain}.`);
56652
+ printErrorLine(`Provider ${providerName} did not converge to the desired DNS state for ${planDomain}.`);
56573
56653
  }
56574
56654
  process.exit(1);
56575
56655
  }
56576
56656
  if (opts.json)
56577
- console.log(JSON.stringify({ applied: true, provider: providerName, plan, verification: verified }, null, 2));
56657
+ printLine(JSON.stringify({ applied: true, provider: providerName, plan, verification: verified }, null, 2));
56578
56658
  else {
56579
56659
  printDnsPlan(plan);
56580
- console.log(`\u2713 Applied and verified desired DNS state on ${providerName} for ${planDomain}`);
56660
+ printLine(`\u2713 Applied and verified desired DNS state on ${providerName} for ${planDomain}`);
56581
56661
  }
56582
56662
  } catch (e4) {
56583
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56663
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56584
56664
  process.exit(1);
56585
56665
  }
56586
56666
  });
56587
56667
  dnsCmd.command("list").description("List DNS records for a domain").argument("<domain-id>", "Domain ID").option("--type <type>", "Filter by record type (A/AAAA/CNAME/MX/TXT/NS/SRV)").option("--limit <n>", "Limit number of displayed records").option("--all", "Show all matching records").option("--json", "Output as JSON", false).action(async (domainId, opts) => {
56588
56668
  const records = await listDnsRecords2(domainId, opts.type);
56589
56669
  if (opts.json) {
56590
- console.log(JSON.stringify(records, null, 2));
56670
+ printLine(JSON.stringify(records, null, 2));
56591
56671
  } else {
56592
56672
  const page = pageItemsOrExit(records, { limit: opts.limit, all: opts.all });
56593
56673
  if (page.items.length === 0) {
56594
- console.log("No DNS records found.");
56674
+ printLine("No DNS records found.");
56595
56675
  return;
56596
56676
  }
56597
56677
  for (const r4 of page.items) {
56598
56678
  const priority = r4.priority !== null ? ` (priority: ${r4.priority})` : "";
56599
- console.log(` ${r4.type} ${r4.name} ${truncateText(r4.value, 80)} TTL:${r4.ttl}${priority}`);
56679
+ printLine(` ${r4.type} ${r4.name} ${truncateText(r4.value, 80)} TTL:${r4.ttl}${priority}`);
56600
56680
  }
56601
- console.log(`
56681
+ printLine(`
56602
56682
  ${compactHint(page, "record(s)", "Use --all for every record or --json for full values.", { paging: "limit" })}`);
56603
56683
  }
56604
56684
  });
@@ -56612,9 +56692,9 @@ ${compactHint(page, "record(s)", "Use --all for every record or --json for full
56612
56692
  priority: opts.priority ? parseInt(opts.priority) : undefined
56613
56693
  });
56614
56694
  if (opts.json) {
56615
- console.log(JSON.stringify(record, null, 2));
56695
+ printLine(JSON.stringify(record, null, 2));
56616
56696
  } else {
56617
- console.log(`Created DNS record: ${record.type} ${record.name} -> ${record.value} (${record.id})`);
56697
+ printLine(`Created DNS record: ${record.type} ${record.name} -> ${record.value} (${record.id})`);
56618
56698
  }
56619
56699
  });
56620
56700
  dnsCmd.command("update").description("Update a DNS record").argument("<id>", "Record ID").option("--type <type>", "Record type").option("--name <name>", "Record name").option("--value <value>", "Record value").option("--ttl <ttl>", "TTL in seconds").option("--priority <n>", "Priority").option("--json", "Output as JSON", false).action(async (id, opts) => {
@@ -56631,21 +56711,21 @@ ${compactHint(page, "record(s)", "Use --all for every record or --json for full
56631
56711
  input.priority = parseInt(opts.priority);
56632
56712
  const record = await updateDnsRecord2(id, input);
56633
56713
  if (!record) {
56634
- console.error(`DNS record '${id}' not found.`);
56714
+ printErrorLine(`DNS record '${id}' not found.`);
56635
56715
  process.exit(1);
56636
56716
  }
56637
56717
  if (opts.json) {
56638
- console.log(JSON.stringify(record, null, 2));
56718
+ printLine(JSON.stringify(record, null, 2));
56639
56719
  } else {
56640
- console.log(`Updated DNS record: ${record.type} ${record.name} -> ${record.value}`);
56720
+ printLine(`Updated DNS record: ${record.type} ${record.name} -> ${record.value}`);
56641
56721
  }
56642
56722
  });
56643
56723
  dnsCmd.command("remove").description("Remove a DNS record").argument("<id>", "Record ID").action(async (id) => {
56644
56724
  const deleted = await deleteDnsRecord2(id);
56645
56725
  if (deleted) {
56646
- console.log(`Deleted DNS record ${id}`);
56726
+ printLine(`Deleted DNS record ${id}`);
56647
56727
  } else {
56648
- console.error(`DNS record '${id}' not found.`);
56728
+ printErrorLine(`DNS record '${id}' not found.`);
56649
56729
  process.exit(1);
56650
56730
  }
56651
56731
  });
@@ -56653,32 +56733,32 @@ ${compactHint(page, "record(s)", "Use --all for every record or --json for full
56653
56733
  try {
56654
56734
  const result = await checkDnsPropagation(domain, opts.record);
56655
56735
  if (opts.json) {
56656
- console.log(JSON.stringify(result, null, 2));
56736
+ printLine(JSON.stringify(result, null, 2));
56657
56737
  } else {
56658
- console.log(`DNS Propagation for ${result.domain} (${result.record_type}):`);
56659
- console.log(` Consistent: ${result.consistent ? "yes" : "NO"}`);
56738
+ printLine(`DNS Propagation for ${result.domain} (${result.record_type}):`);
56739
+ printLine(` Consistent: ${result.consistent ? "yes" : "NO"}`);
56660
56740
  for (const s2 of result.servers) {
56661
56741
  const values = s2.values.length > 0 ? s2.values.join(", ") : "(empty)";
56662
56742
  const status = s2.status === "error" ? ` [ERROR: ${s2.error}]` : "";
56663
- console.log(` ${s2.name} (${s2.server}): ${values}${status}`);
56743
+ printLine(` ${s2.name} (${s2.server}): ${values}${status}`);
56664
56744
  }
56665
56745
  }
56666
56746
  } catch (error) {
56667
- console.error(`DNS propagation check failed: ${error instanceof Error ? error.message : String(error)}`);
56747
+ printErrorLine(`DNS propagation check failed: ${error instanceof Error ? error.message : String(error)}`);
56668
56748
  process.exit(1);
56669
56749
  }
56670
56750
  });
56671
56751
  dnsCmd.command("export").description("Export DNS records as BIND zone file").argument("<domain-id>", "Domain ID").option("--output <file>", "Write to file instead of stdout").action(async (domainId, opts) => {
56672
56752
  const zone = await exportZoneFile(domainId);
56673
56753
  if (!zone) {
56674
- console.error(`Domain '${domainId}' not found.`);
56754
+ printErrorLine(`Domain '${domainId}' not found.`);
56675
56755
  process.exit(1);
56676
56756
  }
56677
56757
  if (opts.output) {
56678
56758
  writeFileSync2(opts.output, zone, "utf-8");
56679
- console.log(`Exported zone file to ${opts.output}`);
56759
+ printLine(`Exported zone file to ${opts.output}`);
56680
56760
  } else {
56681
- console.log(zone);
56761
+ printLine(zone);
56682
56762
  }
56683
56763
  });
56684
56764
  dnsCmd.command("import").description("Import DNS records from a BIND zone file").argument("<domain-id>", "Domain ID").requiredOption("--file <path>", "Path to zone file").option("--json", "Output as JSON", false).action(async (domainId, opts) => {
@@ -56686,22 +56766,22 @@ ${compactHint(page, "record(s)", "Use --all for every record or --json for full
56686
56766
  try {
56687
56767
  content = readFileSync4(opts.file, "utf-8");
56688
56768
  } catch {
56689
- console.error(`Could not read file: ${opts.file}`);
56769
+ printErrorLine(`Could not read file: ${opts.file}`);
56690
56770
  process.exit(1);
56691
56771
  }
56692
56772
  const result = await importZoneFile(domainId, content);
56693
56773
  if (!result) {
56694
- console.error(`Domain '${domainId}' not found.`);
56774
+ printErrorLine(`Domain '${domainId}' not found.`);
56695
56775
  process.exit(1);
56696
56776
  }
56697
56777
  if (opts.json) {
56698
- console.log(JSON.stringify(result, null, 2));
56778
+ printLine(JSON.stringify(result, null, 2));
56699
56779
  } else {
56700
- console.log(`Imported ${result.imported} record(s), skipped ${result.skipped}`);
56780
+ printLine(`Imported ${result.imported} record(s), skipped ${result.skipped}`);
56701
56781
  if (result.errors.length > 0) {
56702
- console.log("Errors:");
56782
+ printLine("Errors:");
56703
56783
  for (const e4 of result.errors) {
56704
- console.log(` - ${e4}`);
56784
+ printLine(` - ${e4}`);
56705
56785
  }
56706
56786
  }
56707
56787
  }
@@ -56709,42 +56789,42 @@ ${compactHint(page, "record(s)", "Use --all for every record or --json for full
56709
56789
  dnsCmd.command("discover-subdomains").description("Discover subdomains via certificate transparency logs (crt.sh)").argument("<domain>", "Domain name").option("--limit <n>", "Limit number of displayed subdomains").option("--all", "Show all discovered subdomains").option("--json", "Output as JSON", false).action(async (domain, opts) => {
56710
56790
  const result = await discoverSubdomains(domain);
56711
56791
  if (opts.json) {
56712
- console.log(JSON.stringify(result, null, 2));
56792
+ printLine(JSON.stringify(result, null, 2));
56713
56793
  } else {
56714
56794
  if (result.error) {
56715
- console.error(`Discovery failed: ${result.error}`);
56795
+ printErrorLine(`Discovery failed: ${result.error}`);
56716
56796
  process.exit(1);
56717
56797
  }
56718
56798
  if (result.subdomains.length === 0) {
56719
- console.log(`No subdomains found for ${domain}.`);
56799
+ printLine(`No subdomains found for ${domain}.`);
56720
56800
  return;
56721
56801
  }
56722
56802
  const page = pageItemsOrExit(result.subdomains, { limit: opts.limit, all: opts.all });
56723
- console.log(`Subdomains for ${domain} (source: ${result.source}):`);
56803
+ printLine(`Subdomains for ${domain} (source: ${result.source}):`);
56724
56804
  for (const s2 of page.items) {
56725
- console.log(` ${s2}`);
56805
+ printLine(` ${s2}`);
56726
56806
  }
56727
- console.log(`
56807
+ printLine(`
56728
56808
  ${compactHint(page, "subdomain(s)", "Use --all for every discovered name or --json for the full result.", { paging: "limit" })}`);
56729
56809
  }
56730
56810
  });
56731
56811
  dnsCmd.command("validate").description("Validate DNS records for common issues").argument("<domain-id>", "Domain ID").option("--json", "Output as JSON", false).action(async (domainId, opts) => {
56732
56812
  const result = await validateDns(domainId);
56733
56813
  if (!result) {
56734
- console.error(`Domain '${domainId}' not found.`);
56814
+ printErrorLine(`Domain '${domainId}' not found.`);
56735
56815
  process.exit(1);
56736
56816
  }
56737
56817
  if (opts.json) {
56738
- console.log(JSON.stringify(result, null, 2));
56818
+ printLine(JSON.stringify(result, null, 2));
56739
56819
  } else {
56740
- console.log(`DNS Validation for ${result.domain_name}:`);
56741
- console.log(` Valid: ${result.valid ? "yes" : "NO"}`);
56820
+ printLine(`DNS Validation for ${result.domain_name}:`);
56821
+ printLine(` Valid: ${result.valid ? "yes" : "NO"}`);
56742
56822
  if (result.issues.length === 0) {
56743
- console.log(" No issues found.");
56823
+ printLine(" No issues found.");
56744
56824
  } else {
56745
56825
  for (const issue of result.issues) {
56746
56826
  const prefix = issue.type === "error" ? "ERROR" : "WARN";
56747
- console.log(` [${prefix}] ${issue.message}`);
56827
+ printLine(` [${prefix}] ${issue.message}`);
56748
56828
  }
56749
56829
  }
56750
56830
  }
@@ -56756,7 +56836,7 @@ ${compactHint(page, "subdomain(s)", "Use --all for every discovered name or --js
56756
56836
  const records = await provider.getDnsRecords(domain);
56757
56837
  const dbDomain = await getDomainByName2(domain);
56758
56838
  if (!dbDomain) {
56759
- console.error(`Domain '${domain}' not found in local DB. Add it first: domains domain add --name ${domain}`);
56839
+ printErrorLine(`Domain '${domain}' not found in local DB. Add it first: domains domain add --name ${domain}`);
56760
56840
  process.exit(1);
56761
56841
  }
56762
56842
  const { keep, skipped } = partitionPullableRecords(records);
@@ -56765,13 +56845,13 @@ ${compactHint(page, "subdomain(s)", "Use --all for every discovered name or --js
56765
56845
  await createDnsRecord2({ domain_id: dbDomain.id, type: r4.type, name: r4.name, value: r4.value, ttl: r4.ttl, priority: r4.priority });
56766
56846
  count++;
56767
56847
  }
56768
- console.log(`\u2713 Pulled ${count} record(s) from ${providerName} into local DB for ${domain}`);
56848
+ printLine(`\u2713 Pulled ${count} record(s) from ${providerName} into local DB for ${domain}`);
56769
56849
  if (skipped.size > 0) {
56770
56850
  const summary = Array.from(skipped.entries()).map(([t2, n2]) => `${n2} ${t2}`).join(", ");
56771
- console.log(` Skipped ${summary} record(s) (unsupported/provider-managed type).`);
56851
+ printLine(` Skipped ${summary} record(s) (unsupported/provider-managed type).`);
56772
56852
  }
56773
56853
  } catch (e4) {
56774
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56854
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56775
56855
  process.exit(1);
56776
56856
  }
56777
56857
  });
@@ -56780,7 +56860,7 @@ ${compactHint(page, "subdomain(s)", "Use --all for every discovered name or --js
56780
56860
  try {
56781
56861
  const records = await listDnsRecords2(domainId);
56782
56862
  if (records.length === 0) {
56783
- console.log("No local DNS records to push.");
56863
+ printLine("No local DNS records to push.");
56784
56864
  return;
56785
56865
  }
56786
56866
  const dbDomain = await getDomain2(domainId) ?? (() => {
@@ -56794,9 +56874,9 @@ ${compactHint(page, "subdomain(s)", "Use --all for every discovered name or --js
56794
56874
  ttl: r4.ttl,
56795
56875
  priority: r4.priority ?? undefined
56796
56876
  })));
56797
- console.log(`\u2713 Pushed ${records.length} record(s) to ${providerName} for ${dbDomain.name}`);
56877
+ printLine(`\u2713 Pushed ${records.length} record(s) to ${providerName} for ${dbDomain.name}`);
56798
56878
  } catch (e4) {
56799
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56879
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56800
56880
  process.exit(1);
56801
56881
  }
56802
56882
  });
@@ -56806,6 +56886,7 @@ ${compactHint(page, "subdomain(s)", "Use --all for every discovered name or --js
56806
56886
  init_config();
56807
56887
  init_route53();
56808
56888
  init_cloudflare();
56889
+ init_stdout();
56809
56890
  function resolveProvider(flag) {
56810
56891
  return flag ?? loadConfig3().default_dns ?? "route53";
56811
56892
  }
@@ -56821,24 +56902,24 @@ function registerZoneCommand(program2) {
56821
56902
  zones = await listHostedZones();
56822
56903
  }
56823
56904
  if (opts.json) {
56824
- console.log(JSON.stringify(zones, null, 2));
56905
+ printLine(JSON.stringify(zones, null, 2));
56825
56906
  return;
56826
56907
  }
56827
56908
  const page = pageItemsOrExit(zones, { limit: opts.limit, all: opts.all });
56828
56909
  if (page.items.length === 0) {
56829
- console.log("No hosted zones.");
56910
+ printLine("No hosted zones.");
56830
56911
  return;
56831
56912
  }
56832
- console.log(`
56913
+ printLine(`
56833
56914
  Hosted Zones (${provider}):`);
56834
56915
  for (const z of page.items) {
56835
56916
  const extra = z.record_count !== undefined ? ` ${z.record_count} records` : "";
56836
- console.log(` ${z.id.padEnd(32)} ${z.name}${extra}`);
56917
+ printLine(` ${z.id.padEnd(32)} ${z.name}${extra}`);
56837
56918
  }
56838
- console.log(`
56919
+ printLine(`
56839
56920
  ${compactHint(page, "zone(s)", "Use --all for every zone or zone info <zoneId> for details.", { paging: "limit" })}`);
56840
56921
  } catch (e4) {
56841
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56922
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56842
56923
  process.exit(1);
56843
56924
  }
56844
56925
  });
@@ -56847,23 +56928,23 @@ ${compactHint(page, "zone(s)", "Use --all for every zone or zone info <zoneId> f
56847
56928
  try {
56848
56929
  if (provider === "cloudflare") {
56849
56930
  const z = await createZone(domain);
56850
- console.log(`\u2713 Zone created: ${domain} (${z.id})`);
56931
+ printLine(`\u2713 Zone created: ${domain} (${z.id})`);
56851
56932
  if (z.nameservers?.length) {
56852
- console.log(` Name servers:`);
56933
+ printLine(` Name servers:`);
56853
56934
  for (const ns of z.nameservers)
56854
- console.log(` ${ns}`);
56935
+ printLine(` ${ns}`);
56855
56936
  }
56856
56937
  } else {
56857
56938
  const z = await createHostedZone(domain, opts.comment);
56858
- console.log(`\u2713 Zone created: ${domain} (${z.id})`);
56939
+ printLine(`\u2713 Zone created: ${domain} (${z.id})`);
56859
56940
  if (z.name_servers?.length) {
56860
- console.log(` Name servers:`);
56941
+ printLine(` Name servers:`);
56861
56942
  for (const ns of z.name_servers)
56862
- console.log(` ${ns}`);
56943
+ printLine(` ${ns}`);
56863
56944
  }
56864
56945
  }
56865
56946
  } catch (e4) {
56866
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56947
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56867
56948
  process.exit(1);
56868
56949
  }
56869
56950
  });
@@ -56874,44 +56955,44 @@ ${compactHint(page, "zone(s)", "Use --all for every zone or zone info <zoneId> f
56874
56955
  const zones = await listZones();
56875
56956
  const z = zones.find((z2) => z2.id === zoneId || z2.name === zoneId);
56876
56957
  if (!z) {
56877
- console.error(`Zone not found: ${zoneId}`);
56958
+ printErrorLine(`Zone not found: ${zoneId}`);
56878
56959
  process.exit(1);
56879
56960
  }
56880
56961
  if (opts.json) {
56881
- console.log(JSON.stringify(z, null, 2));
56962
+ printLine(JSON.stringify(z, null, 2));
56882
56963
  return;
56883
56964
  }
56884
- console.log(`
56965
+ printLine(`
56885
56966
  Zone: ${z.name}`);
56886
- console.log(` ID: ${z.id}`);
56887
- console.log(` Status: ${z.status}`);
56967
+ printLine(` ID: ${z.id}`);
56968
+ printLine(` Status: ${z.status}`);
56888
56969
  if (z.nameservers?.length) {
56889
- console.log(` Name servers:`);
56970
+ printLine(` Name servers:`);
56890
56971
  for (const ns of z.nameservers)
56891
- console.log(` ${ns}`);
56972
+ printLine(` ${ns}`);
56892
56973
  }
56893
- console.log();
56974
+ printLine();
56894
56975
  } else {
56895
56976
  const z = await getHostedZone(zoneId);
56896
56977
  if (opts.json) {
56897
- console.log(JSON.stringify(z, null, 2));
56978
+ printLine(JSON.stringify(z, null, 2));
56898
56979
  return;
56899
56980
  }
56900
- console.log(`
56981
+ printLine(`
56901
56982
  Zone: ${z.name}`);
56902
- console.log(` ID: ${z.id}`);
56903
- console.log(` Records: ${z.record_count}`);
56983
+ printLine(` ID: ${z.id}`);
56984
+ printLine(` Records: ${z.record_count}`);
56904
56985
  if (z.comment)
56905
- console.log(` Comment: ${z.comment}`);
56986
+ printLine(` Comment: ${z.comment}`);
56906
56987
  if (z.name_servers?.length) {
56907
- console.log(` Name servers:`);
56988
+ printLine(` Name servers:`);
56908
56989
  for (const ns of z.name_servers)
56909
- console.log(` ${ns}`);
56990
+ printLine(` ${ns}`);
56910
56991
  }
56911
- console.log();
56992
+ printLine();
56912
56993
  }
56913
56994
  } catch (e4) {
56914
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56995
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56915
56996
  process.exit(1);
56916
56997
  }
56917
56998
  });
@@ -56919,8 +57000,8 @@ Zone: ${z.name}`);
56919
57000
  const provider = resolveProvider(opts.provider);
56920
57001
  try {
56921
57002
  if (!opts.force) {
56922
- console.log(`Would delete zone: ${zoneId} (${provider})`);
56923
- console.log("Re-run with --force to confirm.");
57003
+ printLine(`Would delete zone: ${zoneId} (${provider})`);
57004
+ printLine("Re-run with --force to confirm.");
56924
57005
  return;
56925
57006
  }
56926
57007
  if (provider === "cloudflare") {
@@ -56928,9 +57009,9 @@ Zone: ${z.name}`);
56928
57009
  } else {
56929
57010
  await deleteHostedZone(zoneId);
56930
57011
  }
56931
- console.log(`\u2713 Zone deleted: ${zoneId}`);
57012
+ printLine(`\u2713 Zone deleted: ${zoneId}`);
56932
57013
  } catch (e4) {
56933
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
57014
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
56934
57015
  process.exit(1);
56935
57016
  }
56936
57017
  });
@@ -56938,52 +57019,54 @@ Zone: ${z.name}`);
56938
57019
 
56939
57020
  // src/cli/commands/ssl.ts
56940
57021
  init_domains();
57022
+ init_stdout();
56941
57023
  function registerSslCommand(program2) {
56942
57024
  const ssl = program2.command("ssl").description("SSL certificate management");
56943
57025
  ssl.command("check <domain>").description("Check SSL certificate for a domain and update the local DB record").option("--json", "Output JSON").action(async (domain, opts) => {
56944
57026
  try {
56945
57027
  const result = await checkSsl(domain);
56946
57028
  if (opts.json) {
56947
- console.log(JSON.stringify(result, null, 2));
57029
+ printLine(JSON.stringify(result, null, 2));
56948
57030
  return;
56949
57031
  }
56950
- console.log(`
57032
+ printLine(`
56951
57033
  SSL Certificate for ${result.domain}:`);
56952
57034
  if (result.error) {
56953
- console.log(` Error: ${result.error}`);
57035
+ printLine(` Error: ${result.error}`);
56954
57036
  } else {
56955
- console.log(` Issuer: ${result.issuer ?? "unknown"}`);
56956
- console.log(` Expires: ${result.expires_at ? result.expires_at.split("T")[0] : "unknown"}`);
57037
+ printLine(` Issuer: ${result.issuer ?? "unknown"}`);
57038
+ printLine(` Expires: ${result.expires_at ? result.expires_at.split("T")[0] : "unknown"}`);
56957
57039
  }
56958
- console.log();
57040
+ printLine();
56959
57041
  } catch (error) {
56960
- console.error(`SSL check failed: ${error instanceof Error ? error.message : String(error)}`);
57042
+ printErrorLine(`SSL check failed: ${error instanceof Error ? error.message : String(error)}`);
56961
57043
  process.exit(1);
56962
57044
  }
56963
57045
  });
56964
57046
  ssl.command("expiring").description("List domains with SSL certificates expiring soon").option("--days <n>", "Days threshold", "30").option("--limit <n>", "Limit number of displayed domains").option("--all", "Show all matching domains").option("--json", "Output JSON").action(async (opts) => {
56965
57047
  const domains = await listSslExpiring2(parseInt(opts.days));
56966
57048
  if (opts.json) {
56967
- console.log(JSON.stringify(domains, null, 2));
57049
+ printLine(JSON.stringify(domains, null, 2));
56968
57050
  return;
56969
57051
  }
56970
57052
  const page = pageItemsOrExit(domains, { limit: opts.limit, all: opts.all });
56971
57053
  if (page.items.length === 0) {
56972
- console.log(`No SSL certificates expiring within ${opts.days} days.`);
57054
+ printLine(`No SSL certificates expiring within ${opts.days} days.`);
56973
57055
  return;
56974
57056
  }
56975
- console.log(`
57057
+ printLine(`
56976
57058
  SSL expiring within ${opts.days} days:`);
56977
57059
  for (const d4 of page.items) {
56978
57060
  const exp = d4.ssl_expires_at ? formatDate(d4.ssl_expires_at) : "unknown";
56979
- console.log(` ${d4.name.padEnd(40)} expires ${exp}`);
57061
+ printLine(` ${d4.name.padEnd(40)} expires ${exp}`);
56980
57062
  }
56981
- console.log(`
57063
+ printLine(`
56982
57064
  ${compactHint(page, "domain(s)", "Use --all to display every matching SSL certificate.", { paging: "limit" })}`);
56983
57065
  });
56984
57066
  }
56985
57067
 
56986
57068
  // src/cli/commands/alerts.ts
57069
+ init_stdout();
56987
57070
  init_domains();
56988
57071
  function registerAlertCommands(program2) {
56989
57072
  const alertCmd = program2.command("alert").description("Alert management");
@@ -56994,40 +57077,41 @@ function registerAlertCommands(program2) {
56994
57077
  trigger_days_before: opts.daysBefore ? parseInt(opts.daysBefore) : undefined
56995
57078
  });
56996
57079
  if (opts.json) {
56997
- console.log(JSON.stringify(alert, null, 2));
57080
+ printLine(JSON.stringify(alert, null, 2));
56998
57081
  } else {
56999
57082
  const daysBefore = alert.trigger_days_before ? ` (${alert.trigger_days_before} days before)` : "";
57000
- console.log(`Created alert: ${alert.type}${daysBefore} for domain ${alert.domain_id} (${alert.id})`);
57083
+ printLine(`Created alert: ${alert.type}${daysBefore} for domain ${alert.domain_id} (${alert.id})`);
57001
57084
  }
57002
57085
  });
57003
57086
  alertCmd.command("list").description("List alerts for a domain").argument("<domain-id>", "Domain ID").option("--json", "Output as JSON", false).action(async (domainId, opts) => {
57004
57087
  const alerts = await listAlerts2(domainId);
57005
57088
  if (opts.json) {
57006
- console.log(JSON.stringify(alerts, null, 2));
57089
+ printLine(JSON.stringify(alerts, null, 2));
57007
57090
  } else {
57008
57091
  if (alerts.length === 0) {
57009
- console.log("No alerts set.");
57092
+ printLine("No alerts set.");
57010
57093
  return;
57011
57094
  }
57012
57095
  for (const a4 of alerts) {
57013
57096
  const daysBefore = a4.trigger_days_before ? ` (${a4.trigger_days_before} days before)` : "";
57014
57097
  const sent = a4.sent_at ? ` \u2014 sent ${a4.sent_at}` : "";
57015
- console.log(` ${a4.type}${daysBefore}${sent}`);
57098
+ printLine(` ${a4.type}${daysBefore}${sent}`);
57016
57099
  }
57017
57100
  }
57018
57101
  });
57019
57102
  alertCmd.command("remove").description("Remove an alert").argument("<id>", "Alert ID").action(async (id) => {
57020
57103
  const deleted = await deleteAlert2(id);
57021
57104
  if (deleted) {
57022
- console.log(`Deleted alert ${id}`);
57105
+ printLine(`Deleted alert ${id}`);
57023
57106
  } else {
57024
- console.error(`Alert '${id}' not found.`);
57107
+ printErrorLine(`Alert '${id}' not found.`);
57025
57108
  process.exit(1);
57026
57109
  }
57027
57110
  });
57028
57111
  }
57029
57112
 
57030
57113
  // src/cli/commands/provider.ts
57114
+ init_stdout();
57031
57115
  function isAwsAccessDenied(error) {
57032
57116
  const msg = error instanceof Error ? error.message : String(error);
57033
57117
  return msg.includes("AccessDenied") || msg.includes("route53domains:ListDomains");
@@ -57037,21 +57121,21 @@ function registerProviderCommand(program2) {
57037
57121
  provider.command("list").description("Show all providers and their configuration status").option("-j, --json", "Output JSON").action((opts) => {
57038
57122
  const providers = getAvailableProviders();
57039
57123
  if (opts.json) {
57040
- console.log(JSON.stringify(providers, null, 2));
57124
+ printLine(JSON.stringify(providers, null, 2));
57041
57125
  return;
57042
57126
  }
57043
- console.log(`
57127
+ printLine(`
57044
57128
  Registrar / DNS Providers:`);
57045
57129
  for (const p2 of providers) {
57046
57130
  const status = p2.configured ? "\u2713 configured" : "\u2717 not configured";
57047
57131
  const type = p2.type === "full" ? "registrar + dns" : p2.type;
57048
57132
  const capabilities = [type, p2.inventory ? "inventory" : null].filter(Boolean).join(", ");
57049
- console.log(` ${p2.name.padEnd(12)} [${capabilities}] ${status}`);
57133
+ printLine(` ${p2.name.padEnd(12)} [${capabilities}] ${status}`);
57050
57134
  if (!p2.configured) {
57051
- console.log(` Missing: ${p2.envVars.join(", ")}`);
57135
+ printLine(` Missing: ${p2.envVars.join(", ")}`);
57052
57136
  }
57053
57137
  }
57054
- console.log();
57138
+ printLine();
57055
57139
  });
57056
57140
  provider.command("test <name>").description("Live-test a provider's credentials").option("-j, --json", "Output JSON").action(async (name, opts) => {
57057
57141
  const providerName = name.toLowerCase();
@@ -57060,16 +57144,16 @@ Registrar / DNS Providers:`);
57060
57144
  if (!info) {
57061
57145
  const error = `Unknown provider: ${name}`;
57062
57146
  if (opts.json) {
57063
- console.log(JSON.stringify({ provider: providerName, ok: false, error }, null, 2));
57147
+ printLine(JSON.stringify({ provider: providerName, ok: false, error }, null, 2));
57064
57148
  } else {
57065
- console.error(error);
57149
+ printErrorLine(error);
57066
57150
  }
57067
57151
  process.exit(1);
57068
57152
  }
57069
57153
  if (!info.configured) {
57070
57154
  const error = `${providerName} is not configured. Set: ${info.envVars.join(", ")}`;
57071
57155
  if (opts.json) {
57072
- console.log(JSON.stringify({
57156
+ printLine(JSON.stringify({
57073
57157
  provider: providerName,
57074
57158
  ok: false,
57075
57159
  configured: false,
@@ -57077,12 +57161,12 @@ Registrar / DNS Providers:`);
57077
57161
  error
57078
57162
  }, null, 2));
57079
57163
  } else {
57080
- console.error(`\u2717 ${error}`);
57164
+ printErrorLine(`\u2717 ${error}`);
57081
57165
  }
57082
57166
  process.exit(1);
57083
57167
  }
57084
57168
  if (!opts.json) {
57085
- console.log(`Testing ${providerName}...`);
57169
+ printLine(`Testing ${providerName}...`);
57086
57170
  }
57087
57171
  let registrarOk = null;
57088
57172
  let dnsOk = null;
@@ -57096,21 +57180,21 @@ Registrar / DNS Providers:`);
57096
57180
  await listRegisteredDomains2();
57097
57181
  registrarOk = true;
57098
57182
  if (!opts.json)
57099
- console.log("\u2713 Registrar connection OK");
57183
+ printLine("\u2713 Registrar connection OK");
57100
57184
  } catch (error) {
57101
57185
  if (!isAwsAccessDenied(error))
57102
57186
  throw error;
57103
57187
  registrarOk = false;
57104
57188
  notes.push("route53domains-listdomains-access-denied");
57105
57189
  if (!opts.json)
57106
- console.log("\u2022 Route53 Domains registrar API is not available for these AWS credentials");
57190
+ printLine("\u2022 Route53 Domains registrar API is not available for these AWS credentials");
57107
57191
  }
57108
57192
  } else {
57109
57193
  const reg = getRegistrarProvider(providerName);
57110
57194
  await reg.listDomains();
57111
57195
  registrarOk = true;
57112
57196
  if (!opts.json)
57113
- console.log("\u2713 Registrar connection OK");
57197
+ printLine("\u2713 Registrar connection OK");
57114
57198
  }
57115
57199
  }
57116
57200
  if (info.type === "dns" || info.type === "full") {
@@ -57118,13 +57202,13 @@ Registrar / DNS Providers:`);
57118
57202
  dnsOk = null;
57119
57203
  notes.push("dns-not-probed-with-synthetic-invalid-domain");
57120
57204
  if (!opts.json)
57121
- console.log("\u2022 DNS not probed with synthetic invalid domain");
57205
+ printLine("\u2022 DNS not probed with synthetic invalid domain");
57122
57206
  } else {
57123
57207
  const dns = getDnsProvider(providerName);
57124
57208
  await dns.getDnsRecords("__test_nonexistent_domain__.invalid");
57125
57209
  dnsOk = true;
57126
57210
  if (!opts.json)
57127
- console.log("\u2713 DNS connection OK");
57211
+ printLine("\u2713 DNS connection OK");
57128
57212
  }
57129
57213
  }
57130
57214
  if (info.type === "marketplace") {
@@ -57134,10 +57218,10 @@ Registrar / DNS Providers:`);
57134
57218
  await listSedoPortfolio2({ limit: 1 });
57135
57219
  marketplaceOk = true;
57136
57220
  if (!opts.json)
57137
- console.log("\u2713 Marketplace connection OK");
57221
+ printLine("\u2713 Marketplace connection OK");
57138
57222
  }
57139
57223
  if (opts.json) {
57140
- console.log(JSON.stringify({
57224
+ printLine(JSON.stringify({
57141
57225
  provider: providerName,
57142
57226
  ok: true,
57143
57227
  configured: true,
@@ -57152,7 +57236,7 @@ Registrar / DNS Providers:`);
57152
57236
  const msg = e4 instanceof Error ? e4.message : String(e4);
57153
57237
  if (msg.includes("not found") || msg.includes("No hosted zone") || msg.includes("NXDOMAIN")) {
57154
57238
  if (opts.json) {
57155
- console.log(JSON.stringify({
57239
+ printLine(JSON.stringify({
57156
57240
  provider: providerName,
57157
57241
  ok: true,
57158
57242
  configured: true,
@@ -57164,12 +57248,12 @@ Registrar / DNS Providers:`);
57164
57248
  ...notes.length > 0 ? { notes } : {}
57165
57249
  }, null, 2));
57166
57250
  } else {
57167
- console.log("\u2713 Connection OK (no domains yet)");
57251
+ printLine("\u2713 Connection OK (no domains yet)");
57168
57252
  }
57169
57253
  return;
57170
57254
  }
57171
57255
  if (opts.json) {
57172
- console.log(JSON.stringify({
57256
+ printLine(JSON.stringify({
57173
57257
  provider: providerName,
57174
57258
  ok: false,
57175
57259
  configured: true,
@@ -57180,7 +57264,7 @@ Registrar / DNS Providers:`);
57180
57264
  error: msg
57181
57265
  }, null, 2));
57182
57266
  } else {
57183
- console.error(`\u2717 ${providerName} test failed: ${msg}`);
57267
+ printErrorLine(`\u2717 ${providerName} test failed: ${msg}`);
57184
57268
  }
57185
57269
  process.exit(1);
57186
57270
  }
@@ -57189,6 +57273,7 @@ Registrar / DNS Providers:`);
57189
57273
 
57190
57274
  // src/cli/commands/providers.ts
57191
57275
  init_config();
57276
+ init_stdout();
57192
57277
  init_domains();
57193
57278
  function registrarProviderNames() {
57194
57279
  return getAvailableProviders().filter((p2) => providerHasRegistrar(p2.name)).map((p2) => p2.name).join(", ");
@@ -57218,15 +57303,15 @@ function registerProviderCommands(program2) {
57218
57303
  program2.command("providers").description("Show which providers are configured").option("--json", "Output as JSON", false).action((opts) => {
57219
57304
  const providers = getAvailableProviders();
57220
57305
  if (opts.json) {
57221
- console.log(JSON.stringify(providers, null, 2));
57306
+ printLine(JSON.stringify(providers, null, 2));
57222
57307
  } else {
57223
- console.log("Providers:");
57308
+ printLine("Providers:");
57224
57309
  for (const p2 of providers) {
57225
57310
  const status = p2.configured ? "CONFIGURED" : "not configured";
57226
57311
  const capabilities = [p2.type, p2.inventory ? "inventory" : null].filter(Boolean).join(", ");
57227
- console.log(` ${p2.name} [${capabilities}]: ${status}`);
57312
+ printLine(` ${p2.name} [${capabilities}]: ${status}`);
57228
57313
  if (!p2.configured) {
57229
- console.log(` Accepted env: ${p2.envVars.join(", ")}`);
57314
+ printLine(` Accepted env: ${p2.envVars.join(", ")}`);
57230
57315
  }
57231
57316
  }
57232
57317
  }
@@ -57240,28 +57325,28 @@ function registerProviderCommands(program2) {
57240
57325
  updateDomain: updateDomain2
57241
57326
  });
57242
57327
  if (opts.json) {
57243
- console.log(JSON.stringify(result, null, 2));
57328
+ printLine(JSON.stringify(result, null, 2));
57244
57329
  } else {
57245
- console.log(`Synced ${result.totalSynced} domain(s) from ${result.providers.length} provider(s)`);
57330
+ printLine(`Synced ${result.totalSynced} domain(s) from ${result.providers.length} provider(s)`);
57246
57331
  for (const p2 of result.providers) {
57247
- console.log(` ${p2.name}: ${p2.result.synced} synced (${p2.result.created} new, ${p2.result.updated} updated)`);
57332
+ printLine(` ${p2.name}: ${p2.result.synced} synced (${p2.result.created} new, ${p2.result.updated} updated)`);
57248
57333
  }
57249
57334
  if (result.totalErrors.length > 0) {
57250
- console.log("Errors:");
57335
+ printLine("Errors:");
57251
57336
  for (const e4 of result.totalErrors) {
57252
- console.log(` - ${e4}`);
57337
+ printLine(` - ${e4}`);
57253
57338
  }
57254
57339
  }
57255
57340
  }
57256
57341
  } catch (error) {
57257
- console.error(`Sync failed: ${error instanceof Error ? error.message : String(error)}`);
57342
+ printErrorLine(`Sync failed: ${error instanceof Error ? error.message : String(error)}`);
57258
57343
  process.exit(1);
57259
57344
  }
57260
57345
  return;
57261
57346
  }
57262
57347
  const provider = (opts.provider || "").toLowerCase();
57263
57348
  if (!provider) {
57264
- console.error("Specify --provider <name> or --all");
57349
+ printErrorLine("Specify --provider <name> or --all");
57265
57350
  process.exit(1);
57266
57351
  }
57267
57352
  try {
@@ -57272,17 +57357,17 @@ function registerProviderCommands(program2) {
57272
57357
  updateDomain: updateDomain2
57273
57358
  });
57274
57359
  if (opts.json) {
57275
- console.log(JSON.stringify({ provider, ...result }, null, 2));
57360
+ printLine(JSON.stringify({ provider, ...result }, null, 2));
57276
57361
  } else {
57277
- console.log(`Synced ${result.synced} domain(s) from ${provider} (${result.created} new, ${result.updated} updated)`);
57362
+ printLine(`Synced ${result.synced} domain(s) from ${provider} (${result.created} new, ${result.updated} updated)`);
57278
57363
  if (result.errors.length > 0) {
57279
- console.log("Errors:");
57364
+ printLine("Errors:");
57280
57365
  for (const e4 of result.errors)
57281
- console.log(` - ${e4}`);
57366
+ printLine(` - ${e4}`);
57282
57367
  }
57283
57368
  }
57284
57369
  } catch (error) {
57285
- console.error(`Sync failed: ${error instanceof Error ? error.message : String(error)}`);
57370
+ printErrorLine(`Sync failed: ${error instanceof Error ? error.message : String(error)}`);
57286
57371
  process.exit(1);
57287
57372
  }
57288
57373
  });
@@ -57291,12 +57376,12 @@ function registerProviderCommands(program2) {
57291
57376
  if (!provider) {
57292
57377
  const detected = autoDetectRegistrar(name, getDomainByName2);
57293
57378
  if (!detected) {
57294
- console.error(`Could not auto-detect registrar for '${name}'. Use --provider.`);
57379
+ printErrorLine(`Could not auto-detect registrar for '${name}'. Use --provider.`);
57295
57380
  process.exit(1);
57296
57381
  }
57297
57382
  provider = detected;
57298
57383
  if (!opts.json)
57299
- console.log(`Auto-detected registrar: ${provider}`);
57384
+ printLine(`Auto-detected registrar: ${provider}`);
57300
57385
  }
57301
57386
  try {
57302
57387
  requireRegistrarProvider(provider);
@@ -57305,16 +57390,16 @@ function registerProviderCommands(program2) {
57305
57390
  throw new Error(`Renewal failed or is not supported for ${provider}`);
57306
57391
  }
57307
57392
  if (opts.json) {
57308
- console.log(JSON.stringify({ provider, ...result }, null, 2));
57393
+ printLine(JSON.stringify({ provider, ...result }, null, 2));
57309
57394
  } else {
57310
- console.log(`Renewed ${result.domain} successfully via ${provider}`);
57395
+ printLine(`Renewed ${result.domain} successfully via ${provider}`);
57311
57396
  if (result.chargedAmount)
57312
- console.log(` Charged: $${result.chargedAmount}`);
57397
+ printLine(` Charged: $${result.chargedAmount}`);
57313
57398
  if (result.orderId)
57314
- console.log(` Order ID: ${result.orderId}`);
57399
+ printLine(` Order ID: ${result.orderId}`);
57315
57400
  }
57316
57401
  } catch (error) {
57317
- console.error(`Renewal failed: ${error instanceof Error ? error.message : String(error)}`);
57402
+ printErrorLine(`Renewal failed: ${error instanceof Error ? error.message : String(error)}`);
57318
57403
  process.exit(1);
57319
57404
  }
57320
57405
  });
@@ -57324,18 +57409,18 @@ function registerProviderCommands(program2) {
57324
57409
  requireRegistrarProvider(providerName);
57325
57410
  const result = await getRegistrarProvider(providerName).checkAvailability(name);
57326
57411
  if (opts.json) {
57327
- console.log(JSON.stringify({ provider: providerName, ...result }, null, 2));
57412
+ printLine(JSON.stringify({ provider: providerName, ...result }, null, 2));
57328
57413
  } else {
57329
- console.log(`${result.domain} is ${result.available ? "AVAILABLE" : "NOT available"} (via ${providerName})`);
57414
+ printLine(`${result.domain} is ${result.available ? "AVAILABLE" : "NOT available"} (via ${providerName})`);
57330
57415
  if (result.is_premium)
57331
- console.log(` Premium ask: ${result.premium_price ?? "unknown"}`);
57416
+ printLine(` Premium ask: ${result.premium_price ?? "unknown"}`);
57332
57417
  if (result.standard_price !== undefined) {
57333
57418
  const currency = result.currency ? ` ${result.currency}` : "";
57334
- console.log(` Standard price: ${result.standard_price}${currency}`);
57419
+ printLine(` Standard price: ${result.standard_price}${currency}`);
57335
57420
  }
57336
57421
  }
57337
57422
  } catch (error) {
57338
- console.error(`Availability check failed: ${error instanceof Error ? error.message : String(error)}`);
57423
+ printErrorLine(`Availability check failed: ${error instanceof Error ? error.message : String(error)}`);
57339
57424
  process.exit(1);
57340
57425
  }
57341
57426
  });
@@ -57343,6 +57428,7 @@ function registerProviderCommands(program2) {
57343
57428
 
57344
57429
  // src/cli/commands/config.ts
57345
57430
  init_config();
57431
+ init_stdout();
57346
57432
  var VALID_KEYS = [
57347
57433
  "default-registrar",
57348
57434
  "default-dns",
@@ -57363,33 +57449,33 @@ function registerConfigCommands(program2) {
57363
57449
  config2.command("show").description("Show current configuration").option("--json", "Output JSON").action((opts) => {
57364
57450
  const cfg = loadConfig3();
57365
57451
  if (opts.json) {
57366
- console.log(JSON.stringify(cfg, null, 2));
57452
+ printLine(JSON.stringify(cfg, null, 2));
57367
57453
  return;
57368
57454
  }
57369
- console.log(`
57455
+ printLine(`
57370
57456
  Configuration:`);
57371
- console.log(` default-registrar: ${cfg.default_registrar ?? "(not set)"}`);
57372
- console.log(` default-dns: ${cfg.default_dns ?? "(not set)"}`);
57373
- console.log(` purchase-aws-profile: ${cfg.purchase_aws_profile ?? "(not set)"}`);
57457
+ printLine(` default-registrar: ${cfg.default_registrar ?? "(not set)"}`);
57458
+ printLine(` default-dns: ${cfg.default_dns ?? "(not set)"}`);
57459
+ printLine(` purchase-aws-profile: ${cfg.purchase_aws_profile ?? "(not set)"}`);
57374
57460
  if (cfg.contact && Object.keys(cfg.contact).length > 0) {
57375
- console.log(`
57461
+ printLine(`
57376
57462
  contact:`);
57377
57463
  for (const [k4, v2] of Object.entries(cfg.contact)) {
57378
57464
  if (v2)
57379
- console.log(` ${k4}: ${v2}`);
57465
+ printLine(` ${k4}: ${v2}`);
57380
57466
  }
57381
57467
  } else {
57382
- console.log(" contact: (not set)");
57468
+ printLine(" contact: (not set)");
57383
57469
  }
57384
- console.log();
57470
+ printLine();
57385
57471
  });
57386
57472
  config2.command("set <key> <value>").description(`Set a config value. Keys: ${VALID_KEYS.join(", ")}`).action((key, value) => {
57387
57473
  const normalized = key.replace(/-/g, "_");
57388
57474
  try {
57389
57475
  setConfigKey(normalized, value);
57390
- console.log(`\u2713 Set ${key} = ${value}`);
57476
+ printLine(`\u2713 Set ${key} = ${value}`);
57391
57477
  } catch (e4) {
57392
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
57478
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
57393
57479
  process.exit(1);
57394
57480
  }
57395
57481
  });
@@ -57403,13 +57489,14 @@ Configuration:`);
57403
57489
  delete cfg.contact[parts[1]];
57404
57490
  }
57405
57491
  saveConfig(cfg);
57406
- console.log(`\u2713 Unset ${key}`);
57492
+ printLine(`\u2713 Unset ${key}`);
57407
57493
  });
57408
57494
  }
57409
57495
 
57410
57496
  // src/cli/commands/doctor.ts
57411
57497
  init_config();
57412
57498
  init_domains();
57499
+ init_stdout();
57413
57500
  import { execSync } from "child_process";
57414
57501
  function registerDoctorCommand(program2) {
57415
57502
  program2.command("doctor").description("Run diagnostics \u2014 check credentials, DB, and provider connectivity").option("--json", "Output structured JSON").action(async (opts) => {
@@ -57420,22 +57507,22 @@ function registerDoctorCommand(program2) {
57420
57507
  function section(name) {
57421
57508
  currentSection = name;
57422
57509
  if (!opts.json) {
57423
- console.log(`
57510
+ printLine(`
57424
57511
  \u2500\u2500 ${name} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`);
57425
57512
  }
57426
57513
  }
57427
57514
  function ok(msg) {
57428
57515
  checks.push({ section: currentSection, status: "pass", message: msg });
57429
57516
  if (!opts.json)
57430
- console.log(` \u2713 ${msg}`);
57517
+ printLine(` \u2713 ${msg}`);
57431
57518
  passed++;
57432
57519
  }
57433
57520
  function fail(msg, fix) {
57434
57521
  checks.push({ section: currentSection, status: "fail", message: msg, fix });
57435
57522
  if (!opts.json) {
57436
- console.log(` \u2717 ${msg}`);
57523
+ printLine(` \u2717 ${msg}`);
57437
57524
  if (fix)
57438
- console.log(` \u2192 ${fix}`);
57525
+ printLine(` \u2192 ${fix}`);
57439
57526
  }
57440
57527
  failed++;
57441
57528
  }
@@ -57514,16 +57601,16 @@ function registerDoctorCommand(program2) {
57514
57601
  fail("whois not installed", "apt install whois / brew install whois");
57515
57602
  }
57516
57603
  if (opts.json) {
57517
- console.log(JSON.stringify({
57604
+ printLine(JSON.stringify({
57518
57605
  passed,
57519
57606
  failed,
57520
57607
  healthy: failed === 0,
57521
57608
  checks
57522
57609
  }, null, 2));
57523
57610
  } else {
57524
- console.log(`
57611
+ printLine(`
57525
57612
  ${"\u2500".repeat(45)}`);
57526
- console.log(` ${passed} passed / ${failed} failed
57613
+ printLine(` ${passed} passed / ${failed} failed
57527
57614
  `);
57528
57615
  }
57529
57616
  if (failed > 0)
@@ -57532,6 +57619,7 @@ ${"\u2500".repeat(45)}`);
57532
57619
  }
57533
57620
 
57534
57621
  // src/cli/commands/mcp-install.ts
57622
+ init_stdout();
57535
57623
  import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
57536
57624
  import { homedir as homedir4 } from "os";
57537
57625
  import { dirname as dirname5, join as join4 } from "path";
@@ -57577,28 +57665,28 @@ function registerMcpCommand(program2) {
57577
57665
  mcpServers[MCP_SERVER_NAME] = { command: binary, args: [] };
57578
57666
  config2.mcpServers = mcpServers;
57579
57667
  writeFileSync3(configPath2, JSON.stringify(config2, null, 2), "utf-8");
57580
- console.log(`\u2713 MCP server registered: ${MCP_SERVER_NAME}`);
57581
- console.log(` Config: ${configPath2}`);
57582
- console.log(` Binary: ${binary}`);
57583
- console.log(`
57668
+ printLine(`\u2713 MCP server registered: ${MCP_SERVER_NAME}`);
57669
+ printLine(` Config: ${configPath2}`);
57670
+ printLine(` Binary: ${binary}`);
57671
+ printLine(`
57584
57672
  Restart Claude Code to activate.`);
57585
57673
  });
57586
57674
  mcp.command("uninstall").description("Remove domains MCP server from Claude Code config").option("--project", "Remove from project config instead of global").action((opts) => {
57587
57675
  const paths = getClaudeConfigPaths();
57588
57676
  const configPath2 = opts.project ? paths.project : paths.global;
57589
57677
  if (!existsSync3(configPath2)) {
57590
- console.log("Config file not found \u2014 nothing to remove.");
57678
+ printLine("Config file not found \u2014 nothing to remove.");
57591
57679
  return;
57592
57680
  }
57593
57681
  const config2 = readConfig(configPath2);
57594
57682
  const mcpServers = config2.mcpServers;
57595
57683
  if (!mcpServers?.[MCP_SERVER_NAME]) {
57596
- console.log(`MCP server '${MCP_SERVER_NAME}' is not registered.`);
57684
+ printLine(`MCP server '${MCP_SERVER_NAME}' is not registered.`);
57597
57685
  return;
57598
57686
  }
57599
57687
  delete mcpServers[MCP_SERVER_NAME];
57600
57688
  writeFileSync3(configPath2, JSON.stringify(config2, null, 2), "utf-8");
57601
- console.log(`\u2713 MCP server removed: ${MCP_SERVER_NAME}`);
57689
+ printLine(`\u2713 MCP server removed: ${MCP_SERVER_NAME}`);
57602
57690
  });
57603
57691
  mcp.command("status").description("Check if domains MCP server is registered").option("-j, --json", "Output JSON").action((opts) => {
57604
57692
  const paths = getClaudeConfigPaths();
@@ -57628,22 +57716,22 @@ function registerMcpCommand(program2) {
57628
57716
  }
57629
57717
  }
57630
57718
  if (opts.json) {
57631
- console.log(JSON.stringify({ server: MCP_SERVER_NAME, checks: status }, null, 2));
57719
+ printLine(JSON.stringify({ server: MCP_SERVER_NAME, checks: status }, null, 2));
57632
57720
  return;
57633
57721
  }
57634
57722
  for (const item of status) {
57635
57723
  if (!item.exists) {
57636
- console.log(` ${item.scope}: not found`);
57724
+ printLine(` ${item.scope}: not found`);
57637
57725
  continue;
57638
57726
  }
57639
57727
  if (item.error) {
57640
- console.log(` ${item.scope}: error reading config`);
57728
+ printLine(` ${item.scope}: error reading config`);
57641
57729
  continue;
57642
57730
  }
57643
57731
  if (item.registered) {
57644
- console.log(` ${item.scope}: \u2713 registered`);
57732
+ printLine(` ${item.scope}: \u2713 registered`);
57645
57733
  } else {
57646
- console.log(` ${item.scope}: \u2717 not registered`);
57734
+ printLine(` ${item.scope}: \u2717 not registered`);
57647
57735
  }
57648
57736
  }
57649
57737
  });
@@ -57652,6 +57740,7 @@ function registerMcpCommand(program2) {
57652
57740
  // src/cli/commands/serve.ts
57653
57741
  init_domains();
57654
57742
  init_version();
57743
+ init_stdout();
57655
57744
  function registerServeCommand(program2) {
57656
57745
  const packageVersion = getPackageVersion();
57657
57746
  program2.command("serve").description("Start HTTP API server").option("--port <n>", "Port to listen on", "3000").option("--host <h>", "Host to bind to", "127.0.0.1").action(async (opts) => {
@@ -57719,16 +57808,16 @@ function registerServeCommand(program2) {
57719
57808
  }
57720
57809
  }
57721
57810
  });
57722
- console.log(`\u2713 domains API server running at http://${opts.host}:${port}`);
57723
- console.log(` GET /health`);
57724
- console.log(` GET /domains`);
57725
- console.log(` POST /domains`);
57726
- console.log(` GET /domains/:id`);
57727
- console.log(` PUT /domains/:id`);
57728
- console.log(` DELETE /domains/:id`);
57729
- console.log(` GET /domains/:id/dns`);
57730
- console.log(` POST /domains/:id/dns`);
57731
- console.log(`
57811
+ printLine(`\u2713 domains API server running at http://${opts.host}:${port}`);
57812
+ printLine(` GET /health`);
57813
+ printLine(` GET /domains`);
57814
+ printLine(` POST /domains`);
57815
+ printLine(` GET /domains/:id`);
57816
+ printLine(` PUT /domains/:id`);
57817
+ printLine(` DELETE /domains/:id`);
57818
+ printLine(` GET /domains/:id/dns`);
57819
+ printLine(` POST /domains/:id/dns`);
57820
+ printLine(`
57732
57821
  Press Ctrl+C to stop.`);
57733
57822
  await new Promise(() => {});
57734
57823
  });
@@ -58104,6 +58193,7 @@ async function runMigrations(opts = {}) {
58104
58193
  }
58105
58194
 
58106
58195
  // src/cli/commands/db.ts
58196
+ init_stdout();
58107
58197
  function registerDbCommands(program2) {
58108
58198
  const db = program2.command("db").description("Cloud database migrations (Postgres / RDS)");
58109
58199
  db.command("migrate").description("Apply all pending migrations to the cloud Postgres (owner DSN)").option("--dry-run", "Report the plan without applying", false).option("--json", "Output JSON", false).action(async (opts) => {
@@ -58112,22 +58202,22 @@ function registerDbCommands(program2) {
58112
58202
  const pending = result.plan.filter((p2) => p2.state === "pending").map((p2) => p2.migration.id);
58113
58203
  const applied = result.applied.map((a4) => a4.id);
58114
58204
  if (opts.json) {
58115
- console.log(JSON.stringify({ ok: true, dryRun: result.dryRun, pending, applied }, null, 2));
58205
+ printLine(JSON.stringify({ ok: true, dryRun: result.dryRun, pending, applied }, null, 2));
58116
58206
  } else if (result.dryRun) {
58117
- console.log(`Dry run \u2014 ${pending.length} pending migration(s):`);
58207
+ printLine(`Dry run \u2014 ${pending.length} pending migration(s):`);
58118
58208
  for (const id of pending)
58119
- console.log(` \u2022 ${id}`);
58209
+ printLine(` \u2022 ${id}`);
58120
58210
  if (pending.length === 0)
58121
- console.log(" (schema up to date)");
58211
+ printLine(" (schema up to date)");
58122
58212
  } else {
58123
- console.log(`\u2713 migrations applied \u2014 ${applied.length} total, ${pending.length} were pending`);
58213
+ printLine(`\u2713 migrations applied \u2014 ${applied.length} total, ${pending.length} were pending`);
58124
58214
  }
58125
58215
  } catch (e4) {
58126
58216
  const msg = e4 instanceof Error ? e4.message : String(e4);
58127
58217
  if (opts.json)
58128
- console.log(JSON.stringify({ ok: false, error: msg }, null, 2));
58218
+ printLine(JSON.stringify({ ok: false, error: msg }, null, 2));
58129
58219
  else
58130
- console.error(`\u2717 migration failed: ${msg}`);
58220
+ printErrorLine(`\u2717 migration failed: ${msg}`);
58131
58221
  process.exitCode = 1;
58132
58222
  }
58133
58223
  });
@@ -58137,18 +58227,18 @@ function registerDbCommands(program2) {
58137
58227
  const pending = result.plan.filter((p2) => p2.state === "pending").map((p2) => p2.migration.id);
58138
58228
  const applied = result.applied.map((a4) => a4.id);
58139
58229
  if (opts.json) {
58140
- console.log(JSON.stringify({ ok: true, pending, applied }, null, 2));
58230
+ printLine(JSON.stringify({ ok: true, pending, applied }, null, 2));
58141
58231
  } else {
58142
- console.log(`Applied: ${applied.length} Pending: ${pending.length}`);
58232
+ printLine(`Applied: ${applied.length} Pending: ${pending.length}`);
58143
58233
  for (const id of pending)
58144
- console.log(` pending: ${id}`);
58234
+ printLine(` pending: ${id}`);
58145
58235
  }
58146
58236
  } catch (e4) {
58147
58237
  const msg = e4 instanceof Error ? e4.message : String(e4);
58148
58238
  if (opts.json)
58149
- console.log(JSON.stringify({ ok: false, error: msg }, null, 2));
58239
+ printLine(JSON.stringify({ ok: false, error: msg }, null, 2));
58150
58240
  else
58151
- console.error(`\u2717 ${msg}`);
58241
+ printErrorLine(`\u2717 ${msg}`);
58152
58242
  process.exitCode = 1;
58153
58243
  }
58154
58244
  });
@@ -58197,6 +58287,7 @@ async function setupDomainZone(domain, deps) {
58197
58287
  // src/cli/commands/route53.ts
58198
58288
  init_domains();
58199
58289
  init_config();
58290
+ init_stdout();
58200
58291
  function registerRoute53Commands(program2) {
58201
58292
  const r53 = program2.command("r53").description("AWS Route 53 \u2014 domain purchase, hosted zones & DNS");
58202
58293
  r53.command("check <domains...>").description("Check if one or more domains are available for purchase").action(async (domains) => {
@@ -58207,7 +58298,7 @@ function registerRoute53Commands(program2) {
58207
58298
  const r4 = results[i4];
58208
58299
  if (r4.status === "rejected") {
58209
58300
  const reason = r4.reason;
58210
- console.error(`\u2717 ${domains[i4]}: ${reason instanceof Error ? reason.message : String(reason)}`);
58301
+ printErrorLine(`\u2717 ${domains[i4]}: ${reason instanceof Error ? reason.message : String(reason)}`);
58211
58302
  anyError = true;
58212
58303
  continue;
58213
58304
  }
@@ -58218,15 +58309,15 @@ function registerRoute53Commands(program2) {
58218
58309
  const ren = result.renewal_price ? `renew ${cur} ${result.renewal_price}` : "";
58219
58310
  const xfr = result.transfer_price ? `transfer ${cur} ${result.transfer_price}` : "";
58220
58311
  const pricing = [reg, ren, xfr].filter(Boolean).join(" / ");
58221
- console.log(`\u2713 ${result.domain} is available${pricing ? ` (${pricing})` : ""}`);
58312
+ printLine(`\u2713 ${result.domain} is available${pricing ? ` (${pricing})` : ""}`);
58222
58313
  } else {
58223
- console.log(`\u2717 ${result.domain} is not available`);
58314
+ printLine(`\u2717 ${result.domain} is not available`);
58224
58315
  }
58225
58316
  }
58226
58317
  if (anyError)
58227
58318
  process.exit(1);
58228
58319
  } catch (e4) {
58229
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58320
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58230
58321
  process.exit(1);
58231
58322
  }
58232
58323
  });
@@ -58234,36 +58325,36 @@ function registerRoute53Commands(program2) {
58234
58325
  try {
58235
58326
  const avail = await checkAvailability3(domain);
58236
58327
  if (!avail.available) {
58237
- console.error(`\u2717 ${domain} is not available for registration`);
58328
+ printErrorLine(`\u2717 ${domain} is not available for registration`);
58238
58329
  process.exit(1);
58239
58330
  }
58240
58331
  let contact;
58241
58332
  try {
58242
58333
  contact = resolveContact(opts);
58243
58334
  } catch (e4) {
58244
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58335
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58245
58336
  process.exit(1);
58246
58337
  }
58247
- console.log(`Registering ${domain}...`);
58338
+ printLine(`Registering ${domain}...`);
58248
58339
  const result = await registerDomain2(domain, contact, parseInt(opts.years), opts.autoRenew);
58249
- console.log(`\u2713 Registration submitted: ${domain}`);
58250
- console.log(` Operation ID: ${result.operationId}`);
58251
- console.log(` Check status: domains r53 status ${result.operationId}`);
58340
+ printLine(`\u2713 Registration submitted: ${domain}`);
58341
+ printLine(` Operation ID: ${result.operationId}`);
58342
+ printLine(` Check status: domains r53 status ${result.operationId}`);
58252
58343
  } catch (e4) {
58253
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58344
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58254
58345
  process.exit(1);
58255
58346
  }
58256
58347
  });
58257
58348
  r53.command("status <operationId>").description("Check domain registration status").action(async (operationId) => {
58258
58349
  try {
58259
58350
  const result = await getRegistrationStatus(operationId);
58260
- console.log(`Status: ${result.status}`);
58351
+ printLine(`Status: ${result.status}`);
58261
58352
  if (result.domain)
58262
- console.log(`Domain: ${result.domain}`);
58353
+ printLine(`Domain: ${result.domain}`);
58263
58354
  if (result.message)
58264
- console.log(`Message: ${result.message}`);
58355
+ printLine(`Message: ${result.message}`);
58265
58356
  } catch (e4) {
58266
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58357
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58267
58358
  process.exit(1);
58268
58359
  }
58269
58360
  });
@@ -58271,26 +58362,26 @@ function registerRoute53Commands(program2) {
58271
58362
  try {
58272
58363
  const domains = await listRegisteredDomains();
58273
58364
  if (opts.json) {
58274
- console.log(JSON.stringify(domains, null, 2));
58365
+ printLine(JSON.stringify(domains, null, 2));
58275
58366
  return;
58276
58367
  }
58277
58368
  const page = pageItemsOrExit(domains, { limit: opts.limit, all: opts.all });
58278
58369
  if (page.items.length === 0) {
58279
- console.log("No registered domains.");
58370
+ printLine("No registered domains.");
58280
58371
  return;
58281
58372
  }
58282
- console.log(`
58373
+ printLine(`
58283
58374
  Registered Domains:`);
58284
58375
  for (const d4 of page.items) {
58285
58376
  const expiry = d4.expiry ? ` (expires ${d4.expiry.split("T")[0]})` : "";
58286
58377
  const renew = d4.auto_renew ? " [auto-renew]" : "";
58287
58378
  const lock = d4.transfer_lock ? " [locked]" : "";
58288
- console.log(` ${d4.domain}${expiry}${renew}${lock}`);
58379
+ printLine(` ${d4.domain}${expiry}${renew}${lock}`);
58289
58380
  }
58290
- console.log(`
58381
+ printLine(`
58291
58382
  ${compactHint(page, "domain(s)", "Use --all for every Route53 domain or r53 domain-info <domain> for details.", { paging: "limit" })}`);
58292
58383
  } catch (e4) {
58293
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58384
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58294
58385
  process.exit(1);
58295
58386
  }
58296
58387
  });
@@ -58298,41 +58389,41 @@ ${compactHint(page, "domain(s)", "Use --all for every Route53 domain or r53 doma
58298
58389
  try {
58299
58390
  const detail = await getDomainDetail(domain);
58300
58391
  if (opts.json) {
58301
- console.log(JSON.stringify(detail, null, 2));
58392
+ printLine(JSON.stringify(detail, null, 2));
58302
58393
  return;
58303
58394
  }
58304
- console.log(`
58395
+ printLine(`
58305
58396
  Domain: ${detail.domain}`);
58306
- console.log(` Created: ${detail.created ? detail.created.split("T")[0] : "\u2014"}`);
58307
- console.log(` Expires: ${detail.expiry ? detail.expiry.split("T")[0] : "\u2014"}`);
58308
- console.log(` Auto-renew: ${detail.auto_renew ? "yes" : "no"}`);
58309
- console.log(` Transfer lock: ${detail.transfer_lock ? "yes" : "no"}`);
58397
+ printLine(` Created: ${detail.created ? detail.created.split("T")[0] : "\u2014"}`);
58398
+ printLine(` Expires: ${detail.expiry ? detail.expiry.split("T")[0] : "\u2014"}`);
58399
+ printLine(` Auto-renew: ${detail.auto_renew ? "yes" : "no"}`);
58400
+ printLine(` Transfer lock: ${detail.transfer_lock ? "yes" : "no"}`);
58310
58401
  if (detail.nameservers.length > 0) {
58311
- console.log(` Name servers:`);
58402
+ printLine(` Name servers:`);
58312
58403
  for (const ns of detail.nameservers)
58313
- console.log(` ${ns}`);
58404
+ printLine(` ${ns}`);
58314
58405
  }
58315
- console.log();
58406
+ printLine();
58316
58407
  } catch (e4) {
58317
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58408
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58318
58409
  process.exit(1);
58319
58410
  }
58320
58411
  });
58321
58412
  r53.command("zone-create <domain>").description("Create a hosted zone").option("--comment <text>", "Zone comment").action(async (domain, opts) => {
58322
58413
  try {
58323
58414
  const zone = await createHostedZone(domain, opts.comment);
58324
- console.log(`\u2713 Hosted zone created: ${domain}`);
58325
- console.log(` Zone ID: ${zone.id}`);
58415
+ printLine(`\u2713 Hosted zone created: ${domain}`);
58416
+ printLine(` Zone ID: ${zone.id}`);
58326
58417
  if (zone.name_servers && zone.name_servers.length > 0) {
58327
- console.log(`
58418
+ printLine(`
58328
58419
  Name servers (set at your registrar):`);
58329
58420
  for (const ns of zone.name_servers) {
58330
- console.log(` ${ns}`);
58421
+ printLine(` ${ns}`);
58331
58422
  }
58332
58423
  }
58333
- console.log();
58424
+ printLine();
58334
58425
  } catch (e4) {
58335
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58426
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58336
58427
  process.exit(1);
58337
58428
  }
58338
58429
  });
@@ -58340,24 +58431,24 @@ Domain: ${detail.domain}`);
58340
58431
  try {
58341
58432
  const zones = await listHostedZones();
58342
58433
  if (opts.json) {
58343
- console.log(JSON.stringify(zones, null, 2));
58434
+ printLine(JSON.stringify(zones, null, 2));
58344
58435
  return;
58345
58436
  }
58346
58437
  const page = pageItemsOrExit(zones, { limit: opts.limit, all: opts.all });
58347
58438
  if (page.items.length === 0) {
58348
- console.log("No hosted zones.");
58439
+ printLine("No hosted zones.");
58349
58440
  return;
58350
58441
  }
58351
- console.log(`
58442
+ printLine(`
58352
58443
  Hosted Zones:`);
58353
58444
  for (const z of page.items) {
58354
58445
  const comment = z.comment ? ` \u2014 ${truncateText(z.comment, 60)}` : "";
58355
- console.log(` ${z.id} ${z.name} ${z.record_count} records${comment}`);
58446
+ printLine(` ${z.id} ${z.name} ${z.record_count} records${comment}`);
58356
58447
  }
58357
- console.log(`
58448
+ printLine(`
58358
58449
  ${compactHint(page, "zone(s)", "Use --all for every zone or r53 zone-info <zoneId> for details.", { paging: "limit" })}`);
58359
58450
  } catch (e4) {
58360
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58451
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58361
58452
  process.exit(1);
58362
58453
  }
58363
58454
  });
@@ -58365,24 +58456,24 @@ ${compactHint(page, "zone(s)", "Use --all for every zone or r53 zone-info <zoneI
58365
58456
  try {
58366
58457
  const zone = await getHostedZone(zoneId);
58367
58458
  if (opts.json) {
58368
- console.log(JSON.stringify(zone, null, 2));
58459
+ printLine(JSON.stringify(zone, null, 2));
58369
58460
  return;
58370
58461
  }
58371
- console.log(`
58462
+ printLine(`
58372
58463
  Hosted Zone: ${zone.name}`);
58373
- console.log(` ID: ${zone.id}`);
58374
- console.log(` Records: ${zone.record_count}`);
58464
+ printLine(` ID: ${zone.id}`);
58465
+ printLine(` Records: ${zone.record_count}`);
58375
58466
  if (zone.comment)
58376
- console.log(` Comment: ${zone.comment}`);
58467
+ printLine(` Comment: ${zone.comment}`);
58377
58468
  if (zone.name_servers && zone.name_servers.length > 0) {
58378
- console.log(` Name servers:`);
58469
+ printLine(` Name servers:`);
58379
58470
  for (const ns of zone.name_servers) {
58380
- console.log(` ${ns}`);
58471
+ printLine(` ${ns}`);
58381
58472
  }
58382
58473
  }
58383
- console.log();
58474
+ printLine();
58384
58475
  } catch (e4) {
58385
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58476
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58386
58477
  process.exit(1);
58387
58478
  }
58388
58479
  });
@@ -58390,18 +58481,18 @@ Hosted Zone: ${zone.name}`);
58390
58481
  try {
58391
58482
  const zone = await getHostedZone(zoneId);
58392
58483
  if (!opts.force) {
58393
- console.log(`Would delete hosted zone:`);
58394
- console.log(` ID: ${zone.id}`);
58395
- console.log(` Domain: ${zone.name}`);
58396
- console.log(` Records: ${zone.record_count}`);
58397
- console.log(`
58484
+ printLine(`Would delete hosted zone:`);
58485
+ printLine(` ID: ${zone.id}`);
58486
+ printLine(` Domain: ${zone.name}`);
58487
+ printLine(` Records: ${zone.record_count}`);
58488
+ printLine(`
58398
58489
  This is irreversible. Re-run with --force to confirm.`);
58399
58490
  process.exit(0);
58400
58491
  }
58401
58492
  await deleteHostedZone(zoneId);
58402
- console.log(`\u2713 Hosted zone deleted: ${zone.name} (${zone.id})`);
58493
+ printLine(`\u2713 Hosted zone deleted: ${zone.name} (${zone.id})`);
58403
58494
  } catch (e4) {
58404
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58495
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58405
58496
  process.exit(1);
58406
58497
  }
58407
58498
  });
@@ -58409,30 +58500,30 @@ This is irreversible. Re-run with --force to confirm.`);
58409
58500
  try {
58410
58501
  const zone = await findHostedZoneByDomain(domain);
58411
58502
  if (!zone) {
58412
- console.error(`No hosted zone found for ${domain}`);
58503
+ printErrorLine(`No hosted zone found for ${domain}`);
58413
58504
  process.exit(1);
58414
58505
  }
58415
58506
  const records = await listRecords(zone.id);
58416
58507
  if (opts.json) {
58417
- console.log(JSON.stringify(records, null, 2));
58508
+ printLine(JSON.stringify(records, null, 2));
58418
58509
  return;
58419
58510
  }
58420
58511
  const page = pageItemsOrExit(records, { limit: opts.limit, all: opts.all });
58421
58512
  if (page.items.length === 0) {
58422
- console.log("No records.");
58513
+ printLine("No records.");
58423
58514
  return;
58424
58515
  }
58425
- console.log(`
58516
+ printLine(`
58426
58517
  DNS Records for ${domain}:`);
58427
58518
  for (const r4 of page.items) {
58428
58519
  const val = r4.alias_target ? `ALIAS \u2192 ${r4.alias_target.dns_name}` : truncateText(r4.values.join(", "), 90);
58429
58520
  const ttl = r4.alias_target ? "" : ` TTL:${r4.ttl}`;
58430
- console.log(` ${r4.type.padEnd(6)} ${r4.name.padEnd(40)}${ttl} ${val}`);
58521
+ printLine(` ${r4.type.padEnd(6)} ${r4.name.padEnd(40)}${ttl} ${val}`);
58431
58522
  }
58432
- console.log(`
58523
+ printLine(`
58433
58524
  ${compactHint(page, "record(s)", "Use --all for every record or --json for full values.", { paging: "limit" })}`);
58434
58525
  } catch (e4) {
58435
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58526
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58436
58527
  process.exit(1);
58437
58528
  }
58438
58529
  });
@@ -58443,20 +58534,20 @@ ${compactHint(page, "record(s)", "Use --all for every record or --json for full
58443
58534
  try {
58444
58535
  const isAlias = !!(opts.aliasZone && opts.aliasDns);
58445
58536
  if (!isAlias && (!opts.value || opts.value.length === 0)) {
58446
- console.error("Error: provide --value (repeatable) or both --alias-zone and --alias-dns");
58537
+ printErrorLine("Error: provide --value (repeatable) or both --alias-zone and --alias-dns");
58447
58538
  process.exit(1);
58448
58539
  }
58449
58540
  const zone = await findHostedZoneByDomain(domain);
58450
58541
  if (!zone) {
58451
- console.error(`No hosted zone found for ${domain}`);
58542
+ printErrorLine(`No hosted zone found for ${domain}`);
58452
58543
  process.exit(1);
58453
58544
  }
58454
58545
  const aliasTarget = isAlias ? { hosted_zone_id: opts.aliasZone, dns_name: opts.aliasDns } : undefined;
58455
58546
  await upsertRecord(zone.id, { name: opts.name, type: opts.type, ttl: parseInt(opts.ttl), values: opts.value, alias_target: aliasTarget });
58456
58547
  const desc = isAlias ? `alias \u2192 ${opts.aliasDns}` : `${opts.value.length} value(s)`;
58457
- console.log(`\u2713 Record upserted: ${opts.type} ${opts.name} (${desc})`);
58548
+ printLine(`\u2713 Record upserted: ${opts.type} ${opts.name} (${desc})`);
58458
58549
  } catch (e4) {
58459
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58550
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58460
58551
  process.exit(1);
58461
58552
  }
58462
58553
  });
@@ -58464,14 +58555,14 @@ ${compactHint(page, "record(s)", "Use --all for every record or --json for full
58464
58555
  try {
58465
58556
  const zone = await findHostedZoneByDomain(domain);
58466
58557
  if (!zone) {
58467
- console.error(`No hosted zone found for ${domain}`);
58558
+ printErrorLine(`No hosted zone found for ${domain}`);
58468
58559
  process.exit(1);
58469
58560
  }
58470
58561
  const records = await listRecords(zone.id);
58471
58562
  const normName = opts.name.endsWith(".") ? opts.name : `${opts.name}.`;
58472
58563
  const existing = records.find((r4) => r4.type === opts.type.toUpperCase() && (r4.name === opts.name || r4.name === normName));
58473
58564
  if (!existing) {
58474
- console.error(`\u2717 No ${opts.type} record found for ${opts.name} in zone ${domain}`);
58565
+ printErrorLine(`\u2717 No ${opts.type} record found for ${opts.name} in zone ${domain}`);
58475
58566
  process.exit(1);
58476
58567
  }
58477
58568
  await deleteRecord(zone.id, {
@@ -58481,9 +58572,9 @@ ${compactHint(page, "record(s)", "Use --all for every record or --json for full
58481
58572
  values: existing.values,
58482
58573
  alias_target: existing.alias_target
58483
58574
  });
58484
- console.log(`\u2713 Record deleted: ${existing.type} ${existing.name}`);
58575
+ printLine(`\u2713 Record deleted: ${existing.type} ${existing.name}`);
58485
58576
  } catch (e4) {
58486
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58577
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58487
58578
  process.exit(1);
58488
58579
  }
58489
58580
  });
@@ -58493,23 +58584,23 @@ ${compactHint(page, "record(s)", "Use --all for every record or --json for full
58493
58584
  try {
58494
58585
  raw = readFileSync7(opts.file, "utf-8");
58495
58586
  } catch {
58496
- console.error(`Could not read file: ${opts.file}`);
58587
+ printErrorLine(`Could not read file: ${opts.file}`);
58497
58588
  process.exit(1);
58498
58589
  }
58499
58590
  const records = JSON.parse(raw);
58500
58591
  if (!Array.isArray(records)) {
58501
- console.error("JSON file must be an array of record objects");
58592
+ printErrorLine("JSON file must be an array of record objects");
58502
58593
  process.exit(1);
58503
58594
  }
58504
58595
  const zone = await findHostedZoneByDomain(domain);
58505
58596
  if (!zone) {
58506
- console.error(`No hosted zone found for ${domain}`);
58597
+ printErrorLine(`No hosted zone found for ${domain}`);
58507
58598
  process.exit(1);
58508
58599
  }
58509
58600
  await upsertRecords(zone.id, records);
58510
- console.log(`\u2713 Upserted ${records.length} record(s) in ${domain}`);
58601
+ printLine(`\u2713 Upserted ${records.length} record(s) in ${domain}`);
58511
58602
  } catch (e4) {
58512
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58603
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58513
58604
  process.exit(1);
58514
58605
  }
58515
58606
  });
@@ -58521,36 +58612,36 @@ ${compactHint(page, "record(s)", "Use --all for every record or --json for full
58521
58612
  createDomain: createDomain2,
58522
58613
  updateDomain: updateDomain2
58523
58614
  });
58524
- console.log(`\u2713 Synced ${result.synced} domains (${result.created} new, ${result.updated} updated)`);
58615
+ printLine(`\u2713 Synced ${result.synced} domains (${result.created} new, ${result.updated} updated)`);
58525
58616
  if (result.errors.length > 0) {
58526
- console.log(` Errors: ${result.errors.join(", ")}`);
58617
+ printLine(` Errors: ${result.errors.join(", ")}`);
58527
58618
  }
58528
58619
  } catch (e4) {
58529
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58620
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58530
58621
  process.exit(1);
58531
58622
  }
58532
58623
  });
58533
58624
  r53.command("full-setup <domain>").description("Buy domain + create zone + sync to DB \u2014 all in one (contact defaults from: domains config set contact.*)").option("--email <email>", "Registrant email").option("--first-name <name>", "First name").option("--last-name <name>", "Last name").option("--phone <phone>", "Phone").option("--address <addr>", "Street address").option("--city <city>", "City").option("--state <state>", "State/province").option("--country <code>", "Country code").option("--zip <zip>", "ZIP code").option("--org <name>", "Organization name").option("--years <n>", "Registration years", "1").option("--wait", "Poll until registration completes (or fails)").action(async (domain, opts) => {
58534
58625
  try {
58535
- console.log(`[1/4] Checking availability...`);
58626
+ printLine(`[1/4] Checking availability...`);
58536
58627
  const avail = await checkAvailability3(domain);
58537
58628
  if (!avail.available) {
58538
- console.error(`\u2717 ${domain} is not available`);
58629
+ printErrorLine(`\u2717 ${domain} is not available`);
58539
58630
  process.exit(1);
58540
58631
  }
58541
58632
  const price = avail.price ? ` (${avail.currency ?? "USD"} ${avail.price}/yr)` : "";
58542
- console.log(` \u2713 Available${price}`);
58543
- console.log(`[2/4] Registering domain...`);
58633
+ printLine(` \u2713 Available${price}`);
58634
+ printLine(`[2/4] Registering domain...`);
58544
58635
  let contact;
58545
58636
  try {
58546
58637
  contact = resolveContact(opts);
58547
58638
  } catch (e4) {
58548
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58639
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58549
58640
  process.exit(1);
58550
58641
  }
58551
58642
  const reg = await registerDomain2(domain, contact, parseInt(opts.years));
58552
- console.log(` \u2713 Submitted (operation: ${reg.operationId})`);
58553
- console.log(` Waiting for registration to complete...`);
58643
+ printLine(` \u2713 Submitted (operation: ${reg.operationId})`);
58644
+ printLine(` Waiting for registration to complete...`);
58554
58645
  let status = "IN_PROGRESS";
58555
58646
  while (status === "IN_PROGRESS" || status === "SUBMITTED") {
58556
58647
  await new Promise((r4) => setTimeout(r4, 1e4));
@@ -58558,13 +58649,13 @@ ${compactHint(page, "record(s)", "Use --all for every record or --json for full
58558
58649
  status = s2.status;
58559
58650
  process.stdout.write(` Status: ${status}\r`);
58560
58651
  }
58561
- console.log();
58652
+ printLine();
58562
58653
  if (status !== "SUCCESSFUL") {
58563
- console.error(`\u2717 Registration ${status}`);
58654
+ printErrorLine(`\u2717 Registration ${status}`);
58564
58655
  process.exit(1);
58565
58656
  }
58566
- console.log(` \u2713 Registration complete`);
58567
- console.log(`[3/4] Configuring hosted zone...`);
58657
+ printLine(` \u2713 Registration complete`);
58658
+ printLine(`[3/4] Configuring hosted zone...`);
58568
58659
  const setup = await setupDomainZone(domain, {
58569
58660
  findExistingZone: async (d4) => {
58570
58661
  const z = await findHostedZoneByDomain(d4);
@@ -58582,8 +58673,8 @@ ${compactHint(page, "record(s)", "Use --all for every record or --json for full
58582
58673
  await updateNameservers2(d4, ns);
58583
58674
  }
58584
58675
  });
58585
- console.log(` \u2713 Zone ${setup.created ? "created" : "reused"} (${setup.zoneId})` + (setup.nsUpdated ? ` \u2014 registry NS repointed to this zone` : ``));
58586
- console.log(`[4/4] Adding to local database...`);
58676
+ printLine(` \u2713 Zone ${setup.created ? "created" : "reused"} (${setup.zoneId})` + (setup.nsUpdated ? ` \u2014 registry NS repointed to this zone` : ``));
58677
+ printLine(`[4/4] Adding to local database...`);
58587
58678
  createDomain2({
58588
58679
  name: domain,
58589
58680
  registrar: "AWS Route 53",
@@ -58591,20 +58682,20 @@ ${compactHint(page, "record(s)", "Use --all for every record or --json for full
58591
58682
  auto_renew: true,
58592
58683
  nameservers: setup.nameServers
58593
58684
  });
58594
- console.log(` \u2713 Added to portfolio`);
58595
- console.log(`
58685
+ printLine(` \u2713 Added to portfolio`);
58686
+ printLine(`
58596
58687
  \u2713 Full setup complete for ${domain}`);
58597
- console.log(` Check: domains r53 status ${reg.operationId}`);
58688
+ printLine(` Check: domains r53 status ${reg.operationId}`);
58598
58689
  if (setup.nameServers && setup.nameServers.length > 0) {
58599
- console.log(`
58690
+ printLine(`
58600
58691
  Name servers:`);
58601
58692
  for (const ns of setup.nameServers) {
58602
- console.log(` ${ns}`);
58693
+ printLine(` ${ns}`);
58603
58694
  }
58604
58695
  }
58605
- console.log();
58696
+ printLine();
58606
58697
  } catch (e4) {
58607
- console.error(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58698
+ printErrorLine(`Error: ${e4 instanceof Error ? e4.message : String(e4)}`);
58608
58699
  process.exit(1);
58609
58700
  }
58610
58701
  });
@@ -58971,6 +59062,7 @@ function coverageRegressions(current, baseline) {
58971
59062
  }
58972
59063
 
58973
59064
  // src/cli/commands/reconcile-expiry.ts
59065
+ init_stdout();
58974
59066
  var IANA_RDAP_BOOTSTRAP = "https://data.iana.org/rdap/dns.json";
58975
59067
  var TLD_WHOIS = {
58976
59068
  ag: "whois.nic.ag",
@@ -59065,18 +59157,18 @@ function registerReconcileExpiryCommand(program2) {
59065
59157
  program2.command("reconcile-expiry").description("READ-ONLY: compare each domain's REGISTRAR expiry against the REGISTRY's own expiry").option("--from <file>", "Registrar dump JSON (array of {domain, expiresAt, status, registrar})").option("--provider <name>", "Read the registrar inventory live via a configured provider").option("--bootstrap <file>", "Local RDAP bootstrap JSON (default: fetch from IANA)").option("--baseline <file>", "Prior run's JSON; enables coverage-regression detection").option("--only <list>", "Comma-separated domains, or a TLD like '.md'").option("--limit <n>", "Cap the number of domains checked").option("--sample <n>", "Deterministic every-Nth sample across the population").option("--rdap-delay <ms>", "Delay between RDAP queries", "1100").option("--whois-delay <ms>", "Delay between WHOIS queries", "2500").option("--self-test", "Run the pre-arm self-test and exit").option("--json", "Output JSON").action(async (opts) => {
59066
59158
  const arm = prearm();
59067
59159
  if (!opts.json) {
59068
- console.log("=== PRE-ARM SELF-TEST (two-sided) ===");
59160
+ printLine("=== PRE-ARM SELF-TEST (two-sided) ===");
59069
59161
  for (const c4 of arm.cases)
59070
- console.log(` [${c4.passed ? "PASS" : "FAIL"}] ${c4.name.padEnd(58)} -> ${c4.got}`);
59071
- console.log(`=== PRE-ARM ${arm.ok ? "PASS - instrument can fire AND can stay silent" : "FAIL - DO NOT TRUST ANY RESULT"} ===`);
59162
+ printLine(` [${c4.passed ? "PASS" : "FAIL"}] ${c4.name.padEnd(58)} -> ${c4.got}`);
59163
+ printLine(`=== PRE-ARM ${arm.ok ? "PASS - instrument can fire AND can stay silent" : "FAIL - DO NOT TRUST ANY RESULT"} ===`);
59072
59164
  }
59073
59165
  if (!arm.ok) {
59074
- console.error("REFUSING TO RUN: pre-arm failed.");
59166
+ printErrorLine("REFUSING TO RUN: pre-arm failed.");
59075
59167
  process.exit(3);
59076
59168
  }
59077
59169
  if (opts.selfTest) {
59078
59170
  if (opts.json)
59079
- console.log(JSON.stringify({ prearm: arm }, null, 2));
59171
+ printLine(JSON.stringify({ prearm: arm }, null, 2));
59080
59172
  process.exit(0);
59081
59173
  }
59082
59174
  let rows;
@@ -59084,8 +59176,8 @@ function registerReconcileExpiryCommand(program2) {
59084
59176
  rows = await loadRows(opts);
59085
59177
  } catch (e4) {
59086
59178
  const configured = getAvailableProviders().filter((p2) => p2.configured).map((p2) => p2.name).join(", ") || "none";
59087
- console.error(`${e4 instanceof Error ? e4.message : String(e4)}`);
59088
- console.error(`configured providers: ${configured}`);
59179
+ printErrorLine(`${e4 instanceof Error ? e4.message : String(e4)}`);
59180
+ printErrorLine(`configured providers: ${configured}`);
59089
59181
  process.exit(2);
59090
59182
  return;
59091
59183
  }
@@ -59124,9 +59216,9 @@ function registerReconcileExpiryCommand(program2) {
59124
59216
  }
59125
59217
  };
59126
59218
  if (!opts.json) {
59127
- console.log(`
59219
+ printLine(`
59128
59220
  REGISTRAR rows=${rows.length} unique=${unique.length} dupes_removed=${dupesRemoved}`);
59129
- console.log(`SELECTED=${selected.length}`);
59221
+ printLine(`SELECTED=${selected.length}`);
59130
59222
  }
59131
59223
  const report = await reconcileExpiry(selected, deps);
59132
59224
  let regressed = [];
@@ -59137,40 +59229,40 @@ REGISTRAR rows=${rows.length} unique=${unique.length} dupes_removed=${dupesRemov
59137
59229
  report.exitCode = Math.max(report.exitCode, 2);
59138
59230
  }
59139
59231
  if (opts.json) {
59140
- console.log(JSON.stringify({ ...report, coverageRegressions: regressed, queries }, null, 2));
59232
+ printLine(JSON.stringify({ ...report, coverageRegressions: regressed, queries }, null, 2));
59141
59233
  process.exit(report.exitCode);
59142
59234
  return;
59143
59235
  }
59144
59236
  const order = ["MATCH", "MISMATCH", "NOT_AT_REGISTRY", "UNVERIFIABLE_EXPECTED", "UNVERIFIABLE_UNEXPECTED"];
59145
- console.log(`
59237
+ printLine(`
59146
59238
  === VERDICT TALLY (n=${report.records.length}) ===`);
59147
59239
  for (const k4 of order)
59148
- console.log(` ${k4.padEnd(24)} ${String(report.tally[k4]).padStart(5)}`);
59240
+ printLine(` ${k4.padEnd(24)} ${String(report.tally[k4]).padStart(5)}`);
59149
59241
  const pct = report.records.length ? (100 * report.comparable / report.records.length).toFixed(1) : "0.0";
59150
- console.log(`COMPARABLE = ${report.comparable} of ${report.records.length} (${pct}%)`);
59242
+ printLine(`COMPARABLE = ${report.comparable} of ${report.records.length} (${pct}%)`);
59151
59243
  const show = (title, rs) => {
59152
59244
  if (rs.length === 0)
59153
59245
  return;
59154
- console.log(`
59246
+ printLine(`
59155
59247
  === ${title} ===`);
59156
59248
  for (const r4 of rs)
59157
- console.log(` ${r4.domain.padEnd(26)} ${r4.why.slice(0, 120)}`);
59249
+ printLine(` ${r4.domain.padEnd(26)} ${r4.why.slice(0, 120)}`);
59158
59250
  };
59159
59251
  show("MISMATCHES", report.records.filter((r4) => r4.verdict === "MISMATCH"));
59160
59252
  show("NOT AT REGISTRY", report.records.filter((r4) => r4.verdict === "NOT_AT_REGISTRY"));
59161
59253
  show("UNVERIFIABLE / UNEXPECTED (coverage loss - these are NOT clean)", report.records.filter((r4) => r4.verdict === "UNVERIFIABLE_UNEXPECTED"));
59162
- console.log(`
59254
+ printLine(`
59163
59255
  REGISTRY EXPIRY WITHIN ${STALE_SOON_DAYS}d: ${report.expiringSoon.length}`);
59164
59256
  for (const r4 of report.expiringSoon) {
59165
- console.log(` ${r4.domain.padEnd(26)} registry=${r4.registry} in ${r4.daysToRegistryExpiry}d verdict=${r4.verdict}`);
59257
+ printLine(` ${r4.domain.padEnd(26)} registry=${r4.registry} in ${r4.daysToRegistryExpiry}d verdict=${r4.verdict}`);
59166
59258
  }
59167
59259
  if (opts.baseline) {
59168
- console.log(`
59260
+ printLine(`
59169
59261
  COVERAGE REGRESSION vs baseline: ${regressed.length}`);
59170
59262
  for (const d4 of regressed.slice(0, 20))
59171
- console.log(` ${d4} was comparable, now unverifiable`);
59263
+ printLine(` ${d4} was comparable, now unverifiable`);
59172
59264
  }
59173
- console.log(`
59265
+ printLine(`
59174
59266
  EXIT=${report.exitCode}`);
59175
59267
  process.exit(report.exitCode);
59176
59268
  });
@@ -59178,6 +59270,7 @@ EXIT=${report.exitCode}`);
59178
59270
 
59179
59271
  // src/cli/index.ts
59180
59272
  init_version();
59273
+ init_stdout();
59181
59274
  var OPTIONAL_GROUPS = [
59182
59275
  "brandsight",
59183
59276
  "events",
@@ -59238,7 +59331,7 @@ async function registerOptionalCommands(program2, groups) {
59238
59331
  const { registerEventsCommands: registerEventsCommands2 } = await Promise.resolve().then(() => (init_commander(), exports_commander));
59239
59332
  registerEventsCommands2(program2, { source: "domains" });
59240
59333
  } catch (error) {
59241
- console.error(`Events command group is enabled but @hasna/events could not be loaded: ${error instanceof Error ? error.message : String(error)}`);
59334
+ printErrorLine(`Events command group is enabled but @hasna/events could not be loaded: ${error instanceof Error ? error.message : String(error)}`);
59242
59335
  }
59243
59336
  }
59244
59337
  }
@@ -59252,15 +59345,15 @@ function registerOptionalHelp(program2) {
59252
59345
  enable_some: "DOMAINS_COMMAND_GROUPS=marketplace,owner domains <command>"
59253
59346
  };
59254
59347
  if (opts.json) {
59255
- console.log(JSON.stringify(body, null, 2));
59348
+ printLine(JSON.stringify(body, null, 2));
59256
59349
  return;
59257
59350
  }
59258
- console.log("Optional command groups:");
59351
+ printLine("Optional command groups:");
59259
59352
  for (const group of body.available)
59260
- console.log(` ${groups.has(group) ? "\u2713" : " "} ${group}`);
59261
- console.log(`
59353
+ printLine(` ${groups.has(group) ? "\u2713" : " "} ${group}`);
59354
+ printLine(`
59262
59355
  Enable all: DOMAINS_ENABLE_EXTRAS=1 domains <command>`);
59263
- console.log("Enable some: DOMAINS_COMMAND_GROUPS=marketplace,owner domains <command>");
59356
+ printLine("Enable some: DOMAINS_COMMAND_GROUPS=marketplace,owner domains <command>");
59264
59357
  });
59265
59358
  }
59266
59359
  var program2 = new Command;