@signaliz/cli 1.0.50 → 1.0.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -3
- package/dist/bin.js +121 -16
- 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
|
|
78
|
-
without duplicate work
|
|
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
|
-
|
|
163
|
-
|
|
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).
|
|
164
228
|
`);
|
|
165
|
-
|
|
229
|
+
if (normalized.inputDuplicatesSuppressed > 0) {
|
|
230
|
+
process.stdout.write(`Unique fresh tasks: ${normalized.uniqueFreshInputCount}; exact duplicates suppressed: ${normalized.inputDuplicatesSuppressed}.
|
|
231
|
+
`);
|
|
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
|
});
|
|
@@ -216,10 +284,16 @@ function normalizeSignalsEverythingResult(request, value) {
|
|
|
216
284
|
source: stringValue(item.source)
|
|
217
285
|
};
|
|
218
286
|
}).filter((item) => Boolean(item.url)) : [];
|
|
287
|
+
const eventDate = stringValue(signal.event_date || signal.date) || evidence[0]?.publishedAt || "";
|
|
288
|
+
const sourceUrl = stringValue(signal.source_url || signal.url) || evidence[0]?.url || null;
|
|
289
|
+
if (!eventDate || !sourceUrl || !evidence.some((item) => Boolean(item.publishedAt))) {
|
|
290
|
+
throw new Error("Signals Everything response violated the dated-evidence and source-URL contract.");
|
|
291
|
+
}
|
|
219
292
|
return {
|
|
220
293
|
company: { name, domain },
|
|
221
294
|
title: stringValue(signal.title || signal.summary || signal.content),
|
|
222
|
-
|
|
295
|
+
eventDate,
|
|
296
|
+
sourceUrl,
|
|
223
297
|
evidence
|
|
224
298
|
};
|
|
225
299
|
});
|
|
@@ -245,6 +319,9 @@ function normalizeSignalsEverythingResult(request, value) {
|
|
|
245
319
|
nextPollAfterSeconds: numberValue(value.next_poll_after_seconds),
|
|
246
320
|
signals: signals2,
|
|
247
321
|
signalCount: signals2.length,
|
|
322
|
+
...numberValue(value.available_company_signal_count) === void 0 ? {} : {
|
|
323
|
+
availableCompanySignalCount: numberValue(value.available_company_signal_count)
|
|
324
|
+
},
|
|
248
325
|
...maxCost === void 0 ? {} : {
|
|
249
326
|
costGuardrail: {
|
|
250
327
|
maxCostPerQualifiedSignalUsd: maxCost,
|
|
@@ -258,6 +335,7 @@ function normalizeSignalsEverythingResult(request, value) {
|
|
|
258
335
|
async function discoverSignalsEverything(request) {
|
|
259
336
|
const body = request.signalSearchRunId ? {
|
|
260
337
|
signal_search_run_id: request.signalSearchRunId,
|
|
338
|
+
...request.limit === void 0 ? {} : { limit: request.limit },
|
|
261
339
|
...request.dryRun === void 0 ? {} : { dry_run: request.dryRun },
|
|
262
340
|
...request.idempotencyKey ? { idempotency_key: request.idempotencyKey } : {}
|
|
263
341
|
} : {
|
|
@@ -394,7 +472,7 @@ async function findEmail() {
|
|
|
394
472
|
return;
|
|
395
473
|
}
|
|
396
474
|
const result2 = await createClient().findEmails(requests, batchOptions());
|
|
397
|
-
batchOutput(result2);
|
|
475
|
+
batchOutput(customerEmailBatch(result2));
|
|
398
476
|
return;
|
|
399
477
|
}
|
|
400
478
|
const companyDomain = flag("company-domain") || flag("domain");
|
|
@@ -421,12 +499,19 @@ async function findEmail() {
|
|
|
421
499
|
return;
|
|
422
500
|
}
|
|
423
501
|
const result = await createClient().findEmail(request);
|
|
424
|
-
|
|
502
|
+
const publicResult = customerEmailResult(result);
|
|
503
|
+
output(publicResult, () => {
|
|
425
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}
|
|
426
509
|
`);
|
|
427
510
|
process.stdout.write(`Confidence: ${result.confidence}
|
|
428
511
|
`);
|
|
429
512
|
process.stdout.write(`Provider: ${result.providerUsed}
|
|
513
|
+
`);
|
|
514
|
+
process.stdout.write(`Credits used: ${result.creditsUsed || 0}
|
|
430
515
|
`);
|
|
431
516
|
if (result.needsReverification) {
|
|
432
517
|
process.stdout.write("Send safety: stale verification; rerun with --skip-cache before sending\n");
|
|
@@ -450,7 +535,7 @@ async function verifyEmail(args) {
|
|
|
450
535
|
...batchOptions(),
|
|
451
536
|
skipCache: hasFlag("skip-cache")
|
|
452
537
|
});
|
|
453
|
-
batchOutput(result2);
|
|
538
|
+
batchOutput(customerEmailBatch(result2));
|
|
454
539
|
return;
|
|
455
540
|
}
|
|
456
541
|
const email = args[0] && !args[0].startsWith("--") ? args[0] : flag("email");
|
|
@@ -470,7 +555,8 @@ async function verifyEmail(args) {
|
|
|
470
555
|
return;
|
|
471
556
|
}
|
|
472
557
|
const result = await createClient().verifyEmail(email, options);
|
|
473
|
-
|
|
558
|
+
const publicResult = customerEmailResult(result);
|
|
559
|
+
output(publicResult, () => {
|
|
474
560
|
if (result.status === "processing") {
|
|
475
561
|
process.stdout.write(`Verification processing: ${result.verificationRunId}
|
|
476
562
|
`);
|
|
@@ -484,6 +570,9 @@ async function verifyEmail(args) {
|
|
|
484
570
|
Deliverable: ${result.isDeliverable}
|
|
485
571
|
Catch-all: ${result.isCatchAll}
|
|
486
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}
|
|
487
576
|
`);
|
|
488
577
|
});
|
|
489
578
|
}
|
|
@@ -519,7 +608,7 @@ async function companySignals() {
|
|
|
519
608
|
return;
|
|
520
609
|
}
|
|
521
610
|
const result2 = await createClient().enrichCompanies(requests, batchOptions());
|
|
522
|
-
batchOutput(result2);
|
|
611
|
+
batchOutput(customerSignalBatch(result2));
|
|
523
612
|
return;
|
|
524
613
|
}
|
|
525
614
|
const companyDomain = flag("domain") || flag("company-domain");
|
|
@@ -550,10 +639,13 @@ async function companySignals() {
|
|
|
550
639
|
dryRunOutput(result2);
|
|
551
640
|
return;
|
|
552
641
|
}
|
|
553
|
-
const result = await createClient().enrichCompanySignals(request);
|
|
642
|
+
const result = customerSignalResult(await createClient().enrichCompanySignals(request));
|
|
554
643
|
output(result, () => {
|
|
555
644
|
process.stdout.write(`Company: ${result.company.name || result.company.domain}
|
|
556
645
|
Signals: ${result.signalCount}
|
|
646
|
+
`);
|
|
647
|
+
process.stdout.write(`Result source: ${result.resultReturnedFrom || "unknown"}
|
|
648
|
+
Credits used: ${result.creditsUsed || 0}
|
|
557
649
|
`);
|
|
558
650
|
for (const signal of result.signals.slice(0, 5)) {
|
|
559
651
|
process.stdout.write(`- ${signal.title} [${signal.type}]
|
|
@@ -617,7 +709,10 @@ async function signals(args) {
|
|
|
617
709
|
const startedAt = Date.now();
|
|
618
710
|
while (signalDiscoveryIsPending(result.status) && result.signalSearchRunId && Date.now() - startedAt < maxWaitMs) {
|
|
619
711
|
await sleep(Math.max(250, pollIntervalMs ?? (result.nextPollAfterSeconds || 5) * 1e3));
|
|
620
|
-
result = await discoverSignalsEverything({
|
|
712
|
+
result = await discoverSignalsEverything({
|
|
713
|
+
signalSearchRunId: result.signalSearchRunId,
|
|
714
|
+
limit: request.limit
|
|
715
|
+
});
|
|
621
716
|
}
|
|
622
717
|
}
|
|
623
718
|
output(result, () => {
|
|
@@ -638,8 +733,15 @@ async function signals(args) {
|
|
|
638
733
|
`);
|
|
639
734
|
return;
|
|
640
735
|
}
|
|
641
|
-
|
|
736
|
+
const available = result.availableCompanySignalCount ?? result.signalCount;
|
|
737
|
+
process.stdout.write(`Qualified companies returned: ${result.signalCount}
|
|
642
738
|
`);
|
|
739
|
+
if (available > result.signalCount) {
|
|
740
|
+
process.stdout.write(
|
|
741
|
+
`Retained cohort: ${available}. Expand without new acquisition: signaliz signals --signal-search-run-id ${result.signalSearchRunId} --limit ${available}
|
|
742
|
+
`
|
|
743
|
+
);
|
|
744
|
+
}
|
|
643
745
|
const guardrail = result.costGuardrail;
|
|
644
746
|
if (guardrail) {
|
|
645
747
|
process.stdout.write(
|
|
@@ -648,8 +750,8 @@ async function signals(args) {
|
|
|
648
750
|
);
|
|
649
751
|
}
|
|
650
752
|
for (const signal of result.signals.slice(0, 20)) {
|
|
651
|
-
process.stdout.write(`- ${signal.company.name} (${signal.company.domain}) \u2014 ${signal.title}
|
|
652
|
-
${signal.sourceUrl
|
|
753
|
+
process.stdout.write(`- ${signal.company.name} (${signal.company.domain}) \u2014 ${signal.eventDate} \u2014 ${signal.title}
|
|
754
|
+
${signal.sourceUrl}
|
|
653
755
|
`);
|
|
654
756
|
}
|
|
655
757
|
if (result.signalCount > 20) process.stdout.write(`Showing 20 of ${result.signalCount}; use --json for the full result.
|
|
@@ -682,7 +784,7 @@ async function signalToCopy() {
|
|
|
682
784
|
return;
|
|
683
785
|
}
|
|
684
786
|
const result2 = await createClient().createSignalCopyBatch(requests, batchOptions());
|
|
685
|
-
batchOutput(result2);
|
|
787
|
+
batchOutput(customerSignalBatch(result2));
|
|
686
788
|
return;
|
|
687
789
|
}
|
|
688
790
|
const companyDomain = flag("company-domain") || flag("domain");
|
|
@@ -710,7 +812,7 @@ async function signalToCopy() {
|
|
|
710
812
|
dryRunOutput(result2);
|
|
711
813
|
return;
|
|
712
814
|
}
|
|
713
|
-
const result = await createClient().signalToCopy(request);
|
|
815
|
+
const result = customerSignalResult(await createClient().signalToCopy(request));
|
|
714
816
|
output(result, () => {
|
|
715
817
|
if (result.variations.length === 0) {
|
|
716
818
|
process.stdout.write(`${String(result.raw.message || "Signal research completed without supported evidence.")}
|
|
@@ -720,6 +822,9 @@ async function signalToCopy() {
|
|
|
720
822
|
process.stdout.write(`Strongest signal: ${result.strongestSignal}
|
|
721
823
|
Confidence: ${result.confidence}
|
|
722
824
|
Evidence: ${result.evidenceUrl}
|
|
825
|
+
`);
|
|
826
|
+
process.stdout.write(`Result source: ${result.resultReturnedFrom || "unknown"}
|
|
827
|
+
Credits used: ${result.creditsUsed || 0}
|
|
723
828
|
`);
|
|
724
829
|
for (const variation of result.variations) {
|
|
725
830
|
process.stdout.write(`
|
package/package.json
CHANGED