@signaliz/cli 1.0.51 → 1.0.53

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.
Files changed (3) hide show
  1. package/README.md +10 -3
  2. package/dist/bin.js +97 -15
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -35,6 +35,8 @@ signaliz signal-to-copy \
35
35
  signaliz signal-to-copy --company-domain example.com --person-name "Jane Doe" \
36
36
  --title "VP Sales" --campaign-offer "pipeline intelligence" --skip-cache --deep-search
37
37
 
38
+ # Omit --deep-search for bounded credit-free first-party and Bing grounding.
39
+
38
40
  # Signals Everything returns distinct companies with a source-backed signal.
39
41
  # It is asynchronous by default; add --wait or resume the returned run ID.
40
42
  signaliz signals "companies that just got funded" --limit 100 --sources web,news
@@ -74,10 +76,15 @@ Failed result lines preserve `errorCode`, `retryEligible`, and
74
76
  `retryAfterSeconds` when the API supplies recovery guidance.
75
77
 
76
78
  If a single request or batch submission response is lost, rerun the same
77
- command with `--idempotency-key <key>` to recover the original request or durable job
78
- without duplicate work. Add `--dry-run` to any product command, including one
79
+ command with `--idempotency-key <key>` to recover the original request, durable
80
+ job, or provider run without duplicate work or spend. The same key is portable
81
+ across CLI, SDK, REST API, and MCP calls for the same workspace and logical
82
+ input; chunked batches retain collision-free keys for each original row. Add
83
+ `--dry-run` to any product command, including one
79
84
  using `--input`, to receive a conservative credit ceiling without provider
80
- calls, jobs, writes, or spend.
85
+ calls, jobs, writes, or spend. JSON plans expose submitted, unique-fresh, and
86
+ duplicate-suppression counts; human output calls out exact duplicates whenever
87
+ they reduce the ceiling.
81
88
 
82
89
  Batch input is capped at 5,000 records, concurrency is bounded to `1-50`, input
83
90
  order is preserved, and a failed item does not abort successful items.
package/dist/bin.js CHANGED
@@ -124,6 +124,62 @@ function readBatchInput() {
124
124
  function record(value) {
125
125
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
126
126
  }
127
+ function customerEmailResult(value) {
128
+ const result = record(value);
129
+ if (String(result.status || "").toLowerCase() === "processing") return result;
130
+ const raw = record(result.raw);
131
+ const verifiedForSending = typeof raw.verified_for_sending === "boolean" ? raw.verified_for_sending : typeof raw._verified_for_sending === "boolean" ? raw._verified_for_sending : result.raw === void 0 && typeof result.verifiedForSending === "boolean" ? result.verifiedForSending : result.raw === void 0 && typeof result.isVerifiedForSending === "boolean" ? result.isVerifiedForSending : void 0;
132
+ const isCatchAll = typeof result.isCatchAll === "boolean" ? result.isCatchAll : void 0;
133
+ const isMalformed = result.isMalformed === true || raw.is_malformed === true;
134
+ const verificationStatus = result.verificationStatus || result.verificationVerdict;
135
+ return {
136
+ ...result,
137
+ email: typeof result.email === "string" && result.email.trim() ? result.email.trim() : null,
138
+ status: "completed",
139
+ success: result.success === true,
140
+ is_valid: verifiedForSending ?? result.isValid ?? result.isVerified ?? false,
141
+ credits_used: Number(result.creditsUsed || 0),
142
+ ...verifiedForSending !== void 0 ? { verified_for_sending: verifiedForSending } : {},
143
+ ...isCatchAll !== void 0 ? { email_is_catch_all: isCatchAll, is_catch_all: isCatchAll } : {},
144
+ ...typeof result.isMalformed === "boolean" || typeof raw.is_malformed === "boolean" ? { is_malformed: isMalformed } : {},
145
+ ...verificationStatus ? { verification_status: verificationStatus, verification_verdict: verificationStatus } : {},
146
+ ...result.billingMetadata ? { billing_metadata: result.billingMetadata } : {}
147
+ };
148
+ }
149
+ function customerEmailBatch(value) {
150
+ return {
151
+ ...value,
152
+ results: value.results.map((item) => {
153
+ const row = record(item);
154
+ return row.data ? { ...row, data: customerEmailResult(row.data) } : row;
155
+ })
156
+ };
157
+ }
158
+ function customerSignalResult(value) {
159
+ const result = record(value);
160
+ const raw = record(result.raw);
161
+ const billingMetadata = Object.keys(record(result.billingMetadata)).length > 0 ? record(result.billingMetadata) : record(raw.billing_metadata);
162
+ return {
163
+ ...result,
164
+ ...Object.keys(billingMetadata).length > 0 ? { billingMetadata } : {},
165
+ resultReturnedFrom: result.resultReturnedFrom ?? raw.result_returned_from,
166
+ cacheHit: result.cacheHit ?? raw.cache_hit,
167
+ freshEnrichmentUsed: result.freshEnrichmentUsed ?? raw.fresh_enrichment_used,
168
+ creditsUsed: result.creditsUsed ?? raw.credits_used,
169
+ liveProviderCalled: result.liveProviderCalled ?? raw.live_provider_called,
170
+ aiProviderCalled: result.aiProviderCalled ?? raw.ai_provider_called,
171
+ byoAiUsed: result.byoAiUsed ?? raw.byo_ai_used
172
+ };
173
+ }
174
+ function customerSignalBatch(value) {
175
+ return {
176
+ ...value,
177
+ results: value.results.map((item) => {
178
+ const row = record(item);
179
+ return row.data ? { ...row, data: customerSignalResult(row.data) } : row;
180
+ })
181
+ };
182
+ }
127
183
  function batchOptions() {
128
184
  return {
129
185
  concurrency: numberFlag("concurrency"),
@@ -159,10 +215,22 @@ function batchOutput(value) {
159
215
  });
160
216
  }
161
217
  function dryRunOutput(value) {
162
- output(value, () => {
163
- process.stdout.write(`Planned ${value.inputCount} ${value.capability} request(s).
218
+ const raw = record(value.raw);
219
+ const normalized = {
220
+ ...value,
221
+ freshInputCount: Number(value.freshInputCount ?? raw.fresh_input_count ?? value.inputCount),
222
+ uniqueFreshInputCount: Number(value.uniqueFreshInputCount ?? raw.unique_fresh_input_count ?? value.inputCount),
223
+ inputDuplicatesSuppressed: Number(value.inputDuplicatesSuppressed ?? raw.input_duplicates_suppressed ?? 0),
224
+ uniqueRecoveryReadCount: Number(value.uniqueRecoveryReadCount ?? raw.unique_recovery_read_count ?? 0)
225
+ };
226
+ output(normalized, () => {
227
+ process.stdout.write(`Planned ${normalized.inputCount} ${normalized.capability} request(s).
228
+ `);
229
+ if (normalized.inputDuplicatesSuppressed > 0) {
230
+ process.stdout.write(`Unique fresh tasks: ${normalized.uniqueFreshInputCount}; exact duplicates suppressed: ${normalized.inputDuplicatesSuppressed}.
164
231
  `);
165
- process.stdout.write(`Maximum estimated credits: ${value.estimatedCredits.max}
232
+ }
233
+ process.stdout.write(`Maximum estimated credits: ${normalized.estimatedCredits.max}
166
234
  `);
167
235
  process.stdout.write("No provider calls, jobs, writes, or credits were used.\n");
168
236
  });
@@ -404,7 +472,7 @@ async function findEmail() {
404
472
  return;
405
473
  }
406
474
  const result2 = await createClient().findEmails(requests, batchOptions());
407
- batchOutput(result2);
475
+ batchOutput(customerEmailBatch(result2));
408
476
  return;
409
477
  }
410
478
  const companyDomain = flag("company-domain") || flag("domain");
@@ -431,12 +499,19 @@ async function findEmail() {
431
499
  return;
432
500
  }
433
501
  const result = await createClient().findEmail(request);
434
- output(result, () => {
502
+ const publicResult = customerEmailResult(result);
503
+ output(publicResult, () => {
435
504
  process.stdout.write(`${result.email || "No email found"} (${result.verificationStatus})
505
+ `);
506
+ process.stdout.write(`Verified for sending: ${result.isVerifiedForSending}
507
+ `);
508
+ process.stdout.write(`Catch-all: ${result.isCatchAll}
436
509
  `);
437
510
  process.stdout.write(`Confidence: ${result.confidence}
438
511
  `);
439
512
  process.stdout.write(`Provider: ${result.providerUsed}
513
+ `);
514
+ process.stdout.write(`Credits used: ${result.creditsUsed || 0}
440
515
  `);
441
516
  if (result.needsReverification) {
442
517
  process.stdout.write("Send safety: stale verification; rerun with --skip-cache before sending\n");
@@ -460,7 +535,7 @@ async function verifyEmail(args) {
460
535
  ...batchOptions(),
461
536
  skipCache: hasFlag("skip-cache")
462
537
  });
463
- batchOutput(result2);
538
+ batchOutput(customerEmailBatch(result2));
464
539
  return;
465
540
  }
466
541
  const email = args[0] && !args[0].startsWith("--") ? args[0] : flag("email");
@@ -480,7 +555,8 @@ async function verifyEmail(args) {
480
555
  return;
481
556
  }
482
557
  const result = await createClient().verifyEmail(email, options);
483
- output(result, () => {
558
+ const publicResult = customerEmailResult(result);
559
+ output(publicResult, () => {
484
560
  if (result.status === "processing") {
485
561
  process.stdout.write(`Verification processing: ${result.verificationRunId}
486
562
  `);
@@ -494,6 +570,9 @@ async function verifyEmail(args) {
494
570
  Deliverable: ${result.isDeliverable}
495
571
  Catch-all: ${result.isCatchAll}
496
572
  Verdict: ${result.verificationVerdict}
573
+ `);
574
+ if (result.isMalformed) process.stdout.write("Malformed: true (rejected before provider call)\n");
575
+ process.stdout.write(`Credits used: ${result.creditsUsed || 0}
497
576
  `);
498
577
  });
499
578
  }
@@ -529,7 +608,7 @@ async function companySignals() {
529
608
  return;
530
609
  }
531
610
  const result2 = await createClient().enrichCompanies(requests, batchOptions());
532
- batchOutput(result2);
611
+ batchOutput(customerSignalBatch(result2));
533
612
  return;
534
613
  }
535
614
  const companyDomain = flag("domain") || flag("company-domain");
@@ -560,10 +639,13 @@ async function companySignals() {
560
639
  dryRunOutput(result2);
561
640
  return;
562
641
  }
563
- const result = await createClient().enrichCompanySignals(request);
642
+ const result = customerSignalResult(await createClient().enrichCompanySignals(request));
564
643
  output(result, () => {
565
644
  process.stdout.write(`Company: ${result.company.name || result.company.domain}
566
645
  Signals: ${result.signalCount}
646
+ `);
647
+ process.stdout.write(`Result source: ${result.resultReturnedFrom || "unknown"}
648
+ Credits used: ${result.creditsUsed || 0}
567
649
  `);
568
650
  for (const signal of result.signals.slice(0, 5)) {
569
651
  process.stdout.write(`- ${signal.title} [${signal.type}]
@@ -702,7 +784,7 @@ async function signalToCopy() {
702
784
  return;
703
785
  }
704
786
  const result2 = await createClient().createSignalCopyBatch(requests, batchOptions());
705
- batchOutput(result2);
787
+ batchOutput(customerSignalBatch(result2));
706
788
  return;
707
789
  }
708
790
  const companyDomain = flag("company-domain") || flag("domain");
@@ -710,9 +792,6 @@ async function signalToCopy() {
710
792
  const title = flag("title");
711
793
  const campaignOffer = flag("campaign-offer") || flag("offer");
712
794
  const signalRunId = flag("signal-run-id");
713
- if (!signalRunId && (!companyDomain || !personName || !title || !campaignOffer)) {
714
- fail('Usage: signaliz signal-to-copy --company-domain example.com --person-name "Jane Doe" --title "VP Sales" --campaign-offer "pipeline intelligence" OR signaliz signal-to-copy --signal-run-id copy_...');
715
- }
716
795
  const request = {
717
796
  companyDomain,
718
797
  personName,
@@ -730,7 +809,7 @@ async function signalToCopy() {
730
809
  dryRunOutput(result2);
731
810
  return;
732
811
  }
733
- const result = await createClient().signalToCopy(request);
812
+ const result = customerSignalResult(await createClient().signalToCopy(request));
734
813
  output(result, () => {
735
814
  if (result.variations.length === 0) {
736
815
  process.stdout.write(`${String(result.raw.message || "Signal research completed without supported evidence.")}
@@ -740,6 +819,9 @@ async function signalToCopy() {
740
819
  process.stdout.write(`Strongest signal: ${result.strongestSignal}
741
820
  Confidence: ${result.confidence}
742
821
  Evidence: ${result.evidenceUrl}
822
+ `);
823
+ process.stdout.write(`Result source: ${result.resultReturnedFrom || "unknown"}
824
+ Credits used: ${result.creditsUsed || 0}
743
825
  `);
744
826
  for (const variation of result.variations) {
745
827
  process.stdout.write(`
@@ -827,7 +909,7 @@ main().catch((error) => {
827
909
  process.stdout.write(`${stringifyMachineJson({
828
910
  success: false,
829
911
  error: "product_request_failed",
830
- error_code: signalizError?.code || (error instanceof RangeError ? "INPUT_001" : "CLI_ERROR"),
912
+ error_code: signalizError?.code || (error instanceof RangeError || error instanceof TypeError ? "INPUT_001" : "CLI_ERROR"),
831
913
  message,
832
914
  retry_eligible: signalizError?.isRetryable ?? false,
833
915
  ...signalizError?.retryAfter !== void 0 ? {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signaliz/cli",
3
- "version": "1.0.51",
3
+ "version": "1.0.53",
4
4
  "description": "Signaliz CLI for Signals Everything, Find Email, Verify Email, Company Signal Enrichment, and Signal to Copy AI.",
5
5
  "bin": {
6
6
  "signaliz": "dist/bin.js"