@signaliz/cli 1.0.43 → 1.0.45
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 +88 -19
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -18,6 +18,8 @@ signaliz find-email --company-domain example.com --full-name "Jane Doe" --skip-c
|
|
|
18
18
|
signaliz verify-email jane@example.com
|
|
19
19
|
# Force a fresh-provider verification instead of reusing cached proof
|
|
20
20
|
signaliz verify-email jane@example.com --skip-cache
|
|
21
|
+
# Preview any single or batch product request without provider calls or credits
|
|
22
|
+
signaliz verify-email jane@example.com --dry-run --json
|
|
21
23
|
# Return early when a provider check runs long, then resume the exact run
|
|
22
24
|
signaliz verify-email jane@example.com --skip-cache --no-wait --json
|
|
23
25
|
signaliz verify-email --verification-run-id run_... --json
|
|
@@ -67,9 +69,14 @@ generate-company-rows | signaliz company-signals --input - --jsonl --omit-raw
|
|
|
67
69
|
|
|
68
70
|
JSONL writes one `{ "type": "result", ... }` line per input followed by one
|
|
69
71
|
`{ "type": "summary", ... }` line. Input order and cardinality are preserved.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
Failed result lines preserve `errorCode`, `retryEligible`, and
|
|
73
|
+
`retryAfterSeconds` when the API supplies recovery guidance.
|
|
74
|
+
|
|
75
|
+
If a single request or batch submission response is lost, rerun the same
|
|
76
|
+
command with `--idempotency-key <key>` to recover the original request or job
|
|
77
|
+
without duplicate work. Add `--dry-run` to any product command, including one
|
|
78
|
+
using `--input`, to receive a conservative credit ceiling without provider
|
|
79
|
+
calls, jobs, writes, or spend.
|
|
73
80
|
|
|
74
81
|
Batch input is capped at 5,000 records, concurrency is bounded to `1-50`, input
|
|
75
82
|
order is preserved, and a failed item does not abort successful items.
|
package/dist/bin.js
CHANGED
|
@@ -39,7 +39,8 @@ Common flags:
|
|
|
39
39
|
--input <json-or-jsonl-file> Batch up to 5,000 records with any product command
|
|
40
40
|
--input - Read a JSON array or JSONL batch from stdin
|
|
41
41
|
--concurrency <1-50> Simultaneous API requests for batch input (default: 10)
|
|
42
|
-
--idempotency-key <key> Reuse after an ambiguous
|
|
42
|
+
--idempotency-key <key> Reuse after an ambiguous response to recover the same request or job
|
|
43
|
+
--dry-run Return a no-spend plan without provider calls, jobs, or writes
|
|
43
44
|
`;
|
|
44
45
|
function loadConfig() {
|
|
45
46
|
if (!(0, import_node_fs.existsSync)(CONFIG_FILE)) return {};
|
|
@@ -143,6 +144,15 @@ function batchOutput(value) {
|
|
|
143
144
|
if (value.failed > 0) process.stdout.write("Use --json to inspect per-record errors.\n");
|
|
144
145
|
});
|
|
145
146
|
}
|
|
147
|
+
function dryRunOutput(value) {
|
|
148
|
+
output(value, () => {
|
|
149
|
+
process.stdout.write(`Planned ${value.inputCount} ${value.capability} request(s).
|
|
150
|
+
`);
|
|
151
|
+
process.stdout.write(`Maximum estimated credits: ${value.estimatedCredits.max}
|
|
152
|
+
`);
|
|
153
|
+
process.stdout.write("No provider calls, jobs, writes, or credits were used.\n");
|
|
154
|
+
});
|
|
155
|
+
}
|
|
146
156
|
function resolveApiKey() {
|
|
147
157
|
const key = process.env.SIGNALIZ_API_KEY || loadConfig().apiKey;
|
|
148
158
|
if (!key) fail("No API key configured. Run: signaliz auth login");
|
|
@@ -238,7 +248,7 @@ async function auth(args) {
|
|
|
238
248
|
async function findEmail() {
|
|
239
249
|
const rows = readBatchInput();
|
|
240
250
|
if (rows) {
|
|
241
|
-
const
|
|
251
|
+
const requests = rows.map((value) => {
|
|
242
252
|
const row = record(value);
|
|
243
253
|
return {
|
|
244
254
|
companyDomain: row.companyDomain || row.company_domain || row.domain,
|
|
@@ -249,7 +259,13 @@ async function findEmail() {
|
|
|
249
259
|
companyName: row.companyName || row.company_name,
|
|
250
260
|
skipCache: row.skipCache ?? row.skip_cache ?? hasFlag("skip-cache")
|
|
251
261
|
};
|
|
252
|
-
})
|
|
262
|
+
});
|
|
263
|
+
if (hasFlag("dry-run")) {
|
|
264
|
+
const result3 = await createClient().findEmails(requests, { ...batchOptions(), dryRun: true });
|
|
265
|
+
dryRunOutput(result3);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const result2 = await createClient().findEmails(requests, batchOptions());
|
|
253
269
|
batchOutput(result2);
|
|
254
270
|
return;
|
|
255
271
|
}
|
|
@@ -261,15 +277,22 @@ async function findEmail() {
|
|
|
261
277
|
if (!companyDomain || !fullName && !(firstName && lastName)) {
|
|
262
278
|
fail('Usage: signaliz find-email --company-domain example.com --full-name "Jane Doe"');
|
|
263
279
|
}
|
|
264
|
-
const
|
|
280
|
+
const request = {
|
|
265
281
|
companyDomain,
|
|
266
282
|
fullName,
|
|
267
283
|
firstName,
|
|
268
284
|
lastName,
|
|
269
285
|
linkedinUrl,
|
|
270
286
|
companyName: flag("company-name"),
|
|
271
|
-
skipCache: hasFlag("skip-cache")
|
|
272
|
-
|
|
287
|
+
skipCache: hasFlag("skip-cache"),
|
|
288
|
+
idempotencyKey: flag("idempotency-key")
|
|
289
|
+
};
|
|
290
|
+
if (hasFlag("dry-run")) {
|
|
291
|
+
const result2 = await createClient().findEmail({ ...request, dryRun: true });
|
|
292
|
+
dryRunOutput(result2);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
const result = await createClient().findEmail(request);
|
|
273
296
|
output(result, () => {
|
|
274
297
|
process.stdout.write(`${result.email || "No email found"} (${result.verificationStatus})
|
|
275
298
|
`);
|
|
@@ -286,6 +309,15 @@ async function verifyEmail(args) {
|
|
|
286
309
|
const rows = readBatchInput();
|
|
287
310
|
if (rows) {
|
|
288
311
|
const emails = rows.map((value) => typeof value === "string" ? value : String(record(value).email || ""));
|
|
312
|
+
if (hasFlag("dry-run")) {
|
|
313
|
+
const result3 = await createClient().verifyEmails(emails, {
|
|
314
|
+
...batchOptions(),
|
|
315
|
+
skipCache: hasFlag("skip-cache"),
|
|
316
|
+
dryRun: true
|
|
317
|
+
});
|
|
318
|
+
dryRunOutput(result3);
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
289
321
|
const result2 = await createClient().verifyEmails(emails, {
|
|
290
322
|
...batchOptions(),
|
|
291
323
|
skipCache: hasFlag("skip-cache")
|
|
@@ -296,13 +328,20 @@ async function verifyEmail(args) {
|
|
|
296
328
|
const email = args[0] && !args[0].startsWith("--") ? args[0] : flag("email");
|
|
297
329
|
const verificationRunId = flag("verification-run-id");
|
|
298
330
|
if (!email && !verificationRunId) fail("Usage: signaliz verify-email [jane@example.com] [--verification-run-id run_...]");
|
|
299
|
-
const
|
|
331
|
+
const options = {
|
|
300
332
|
skipCache: hasFlag("skip-cache"),
|
|
301
333
|
verificationRunId,
|
|
302
334
|
waitForResult: !hasFlag("no-wait"),
|
|
303
335
|
maxWaitMs: numberFlag("max-wait-ms"),
|
|
304
|
-
pollIntervalMs: numberFlag("poll-interval-ms")
|
|
305
|
-
|
|
336
|
+
pollIntervalMs: numberFlag("poll-interval-ms"),
|
|
337
|
+
idempotencyKey: flag("idempotency-key")
|
|
338
|
+
};
|
|
339
|
+
if (hasFlag("dry-run")) {
|
|
340
|
+
const result2 = await createClient().verifyEmail(email, { ...options, dryRun: true });
|
|
341
|
+
dryRunOutput(result2);
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
const result = await createClient().verifyEmail(email, options);
|
|
306
345
|
output(result, () => {
|
|
307
346
|
if (result.status === "processing") {
|
|
308
347
|
process.stdout.write(`Verification processing: ${result.verificationRunId}
|
|
@@ -321,7 +360,7 @@ Catch-all: ${result.isCatchAll}
|
|
|
321
360
|
async function companySignals() {
|
|
322
361
|
const rows = readBatchInput();
|
|
323
362
|
if (rows) {
|
|
324
|
-
const
|
|
363
|
+
const requests = rows.map((value) => {
|
|
325
364
|
const row = record(value);
|
|
326
365
|
const online = row.online ?? !hasFlag("offline");
|
|
327
366
|
return {
|
|
@@ -342,7 +381,13 @@ async function companySignals() {
|
|
|
342
381
|
maxWaitMs: row.maxWaitMs || row.max_wait_ms || numberFlag("max-wait-ms"),
|
|
343
382
|
pollIntervalMs: row.pollIntervalMs || row.poll_interval_ms || numberFlag("poll-interval-ms")
|
|
344
383
|
};
|
|
345
|
-
})
|
|
384
|
+
});
|
|
385
|
+
if (hasFlag("dry-run")) {
|
|
386
|
+
const result3 = await createClient().enrichCompanies(requests, { ...batchOptions(), dryRun: true });
|
|
387
|
+
dryRunOutput(result3);
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
const result2 = await createClient().enrichCompanies(requests, batchOptions());
|
|
346
391
|
batchOutput(result2);
|
|
347
392
|
return;
|
|
348
393
|
}
|
|
@@ -350,7 +395,7 @@ async function companySignals() {
|
|
|
350
395
|
const companyName = flag("company-name");
|
|
351
396
|
const signalRunId = flag("signal-run-id");
|
|
352
397
|
if (!companyDomain && !companyName && !signalRunId) fail("Usage: signaliz company-signals --domain example.com");
|
|
353
|
-
const
|
|
398
|
+
const request = {
|
|
354
399
|
signalRunId,
|
|
355
400
|
companyDomain,
|
|
356
401
|
companyName,
|
|
@@ -366,8 +411,15 @@ async function companySignals() {
|
|
|
366
411
|
skipCache: hasFlag("skip-cache"),
|
|
367
412
|
waitForResult: !hasFlag("no-wait"),
|
|
368
413
|
maxWaitMs: numberFlag("max-wait-ms"),
|
|
369
|
-
pollIntervalMs: numberFlag("poll-interval-ms")
|
|
370
|
-
|
|
414
|
+
pollIntervalMs: numberFlag("poll-interval-ms"),
|
|
415
|
+
idempotencyKey: flag("idempotency-key")
|
|
416
|
+
};
|
|
417
|
+
if (hasFlag("dry-run")) {
|
|
418
|
+
const result2 = await createClient().enrichCompanySignals({ ...request, dryRun: true });
|
|
419
|
+
dryRunOutput(result2);
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
const result = await createClient().enrichCompanySignals(request);
|
|
371
423
|
output(result, () => {
|
|
372
424
|
process.stdout.write(`Company: ${result.company.name || result.company.domain}
|
|
373
425
|
Signals: ${result.signalCount}
|
|
@@ -381,7 +433,7 @@ Signals: ${result.signalCount}
|
|
|
381
433
|
async function signalToCopy() {
|
|
382
434
|
const rows = readBatchInput();
|
|
383
435
|
if (rows) {
|
|
384
|
-
const
|
|
436
|
+
const requests = rows.map((value) => {
|
|
385
437
|
const row = record(value);
|
|
386
438
|
return {
|
|
387
439
|
companyDomain: row.companyDomain || row.company_domain || row.domain,
|
|
@@ -396,7 +448,13 @@ async function signalToCopy() {
|
|
|
396
448
|
maxWaitMs: row.maxWaitMs || row.max_wait_ms || numberFlag("max-wait-ms"),
|
|
397
449
|
pollIntervalMs: row.pollIntervalMs || row.poll_interval_ms || numberFlag("poll-interval-ms")
|
|
398
450
|
};
|
|
399
|
-
})
|
|
451
|
+
});
|
|
452
|
+
if (hasFlag("dry-run")) {
|
|
453
|
+
const result3 = await createClient().createSignalCopyBatch(requests, { ...batchOptions(), dryRun: true });
|
|
454
|
+
dryRunOutput(result3);
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
const result2 = await createClient().createSignalCopyBatch(requests, batchOptions());
|
|
400
458
|
batchOutput(result2);
|
|
401
459
|
return;
|
|
402
460
|
}
|
|
@@ -408,7 +466,7 @@ async function signalToCopy() {
|
|
|
408
466
|
if (!signalRunId && (!companyDomain || !personName || !title || !campaignOffer)) {
|
|
409
467
|
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_...');
|
|
410
468
|
}
|
|
411
|
-
const
|
|
469
|
+
const request = {
|
|
412
470
|
companyDomain,
|
|
413
471
|
personName,
|
|
414
472
|
title,
|
|
@@ -418,8 +476,15 @@ async function signalToCopy() {
|
|
|
418
476
|
skipCache: hasFlag("skip-cache"),
|
|
419
477
|
enableDeepSearch: hasFlag("deep-search"),
|
|
420
478
|
maxWaitMs: numberFlag("max-wait-ms"),
|
|
421
|
-
pollIntervalMs: numberFlag("poll-interval-ms")
|
|
422
|
-
|
|
479
|
+
pollIntervalMs: numberFlag("poll-interval-ms"),
|
|
480
|
+
idempotencyKey: flag("idempotency-key")
|
|
481
|
+
};
|
|
482
|
+
if (hasFlag("dry-run")) {
|
|
483
|
+
const result2 = await createClient().signalToCopy({ ...request, dryRun: true });
|
|
484
|
+
dryRunOutput(result2);
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
const result = await createClient().signalToCopy(request);
|
|
423
488
|
output(result, () => {
|
|
424
489
|
if (result.variations.length === 0) {
|
|
425
490
|
process.stdout.write(`${String(result.raw.message || "Signal research completed without supported evidence.")}
|
|
@@ -517,6 +582,10 @@ main().catch((error) => {
|
|
|
517
582
|
error_code: signalizError?.code || "CLI_ERROR",
|
|
518
583
|
message,
|
|
519
584
|
retry_eligible: signalizError?.isRetryable ?? false,
|
|
585
|
+
...signalizError?.retryAfter !== void 0 ? {
|
|
586
|
+
retry_after: signalizError.retryAfter,
|
|
587
|
+
retry_after_seconds: signalizError.retryAfter
|
|
588
|
+
} : {},
|
|
520
589
|
...signalizError?.errorType ? { error_type: signalizError.errorType } : {},
|
|
521
590
|
...signalizError?.details ? { details: signalizError.details } : {}
|
|
522
591
|
}, hasFlag("json") ? 2 : void 0)}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signaliz/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.45",
|
|
4
4
|
"description": "Signaliz CLI for Find Email, Verify Email, Company Signal Enrichment, and Signal to Copy AI.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"signaliz": "dist/bin.js"
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"node": ">=18"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@signaliz/sdk": "^1.0.
|
|
31
|
+
"@signaliz/sdk": "^1.0.47"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"tsup": "^8.0.0",
|