@signaliz/cli 1.0.68 → 1.0.70
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 +16 -18
- package/dist/bin.js +86 -224
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -10,10 +10,13 @@ signaliz auth login
|
|
|
10
10
|
# Production REST gateway:
|
|
11
11
|
# https://api.signaliz.com/functions/v1/api/v1/find-email
|
|
12
12
|
# https://api.signaliz.com/functions/v1/api/v1/verify-email
|
|
13
|
-
# https://api.signaliz.com/functions/v1/
|
|
13
|
+
# https://api.signaliz.com/functions/v1/company-signal-enrichment-v2
|
|
14
14
|
# https://api.signaliz.com/functions/v1/api/v1/signal-to-copy
|
|
15
15
|
# https://api.signaliz.com/functions/v1/api/v1/signals
|
|
16
|
-
# https://api.signaliz.com/functions/v1/api/v1/signal-awareness
|
|
16
|
+
# https://api.signaliz.com/functions/v1/api/v1/signal-awareness/signals
|
|
17
|
+
# https://api.signaliz.com/functions/v1/api/v1/signal-awareness/companies/add
|
|
18
|
+
# https://api.signaliz.com/functions/v1/api/v1/signal-awareness/companies/delete
|
|
19
|
+
# https://api.signaliz.com/functions/v1/api/v1/signal-awareness/companies/schedule
|
|
17
20
|
# https://api.signaliz.com/functions/v1/api/v1/flow
|
|
18
21
|
# The same contracts are available under /api/v2/.
|
|
19
22
|
|
|
@@ -26,12 +29,14 @@ signaliz verify-email jane@example.com --dry-run --json
|
|
|
26
29
|
# Return early when a provider check runs long, then resume the exact run
|
|
27
30
|
signaliz verify-email jane@example.com --no-wait --json
|
|
28
31
|
signaliz verify-email --verification-run-id run_... --json
|
|
29
|
-
signaliz company-signals --domain example.com
|
|
32
|
+
signaliz company-signals --domain example.com \
|
|
33
|
+
--research-prompt "Find recent signals that explain why this company would use Signaliz."
|
|
30
34
|
signaliz signal-to-copy \
|
|
31
35
|
--company-domain example.com \
|
|
32
36
|
--person-name "Jane Doe" \
|
|
33
37
|
--title "VP Sales" \
|
|
34
|
-
--campaign-offer "pipeline intelligence"
|
|
38
|
+
--campaign-offer "pipeline intelligence" \
|
|
39
|
+
--run-without-signal no
|
|
35
40
|
|
|
36
41
|
# Reuse the exact Signals First snapshot, fact, or event instead of rediscovering it.
|
|
37
42
|
# Keep company/recipient/offer fields so Signaliz can validate identity and write the copy.
|
|
@@ -47,20 +52,14 @@ signaliz signal-to-copy --company-domain example.com --person-name "Jane Doe" \
|
|
|
47
52
|
|
|
48
53
|
# Signals First returns distinct companies with a source-backed signal.
|
|
49
54
|
# It is asynchronous by default; add --wait or resume the returned run ID.
|
|
50
|
-
signaliz signals "companies that just got funded" --limit 100
|
|
51
|
-
signaliz signals "companies showing signals they need account-signal automation" \
|
|
52
|
-
--icp-context "B2B SaaS with outbound teams and manual account research" \
|
|
53
|
-
--limit 100 --sources web,news
|
|
55
|
+
signaliz signals "companies that just got funded" --limit 100
|
|
54
56
|
signaliz signals --signal-search-run-id run_... --wait --json
|
|
55
57
|
|
|
56
58
|
# Monitor companies with the fixed Company Signal evidence engine.
|
|
57
|
-
signaliz awareness
|
|
58
|
-
signaliz awareness
|
|
59
|
-
signaliz awareness
|
|
60
|
-
signaliz awareness
|
|
61
|
-
signaliz awareness signals --monitor-id <uuid> --limit 100 --offset 0 --json
|
|
62
|
-
signaliz awareness set-output --mode webhook --webhook-url https://hooks.example.com/signaliz
|
|
63
|
-
signaliz awareness export --monitor-id <uuid> --json
|
|
59
|
+
signaliz awareness add --domain acme.com --schedule daily
|
|
60
|
+
signaliz awareness signals --domain acme.com --json
|
|
61
|
+
signaliz awareness schedule --domain acme.com --schedule monthly
|
|
62
|
+
signaliz awareness delete --domain acme.com
|
|
64
63
|
|
|
65
64
|
# Flow starts and resumes through the versioned REST contract.
|
|
66
65
|
signaliz flow --signal-query "companies with recent hiring" \
|
|
@@ -86,9 +85,8 @@ signaliz signal-to-copy --input copy-requests.jsonl --no-wait --json
|
|
|
86
85
|
signaliz signal-to-copy --job-id job_... --idempotency-key key_... --json
|
|
87
86
|
```
|
|
88
87
|
|
|
89
|
-
Signal to Copy accepts `
|
|
90
|
-
|
|
91
|
-
`--event-id` flags for one request. These references reuse canonical evidence
|
|
88
|
+
Signal to Copy accepts `fact_id` or `event_id` in JSON/JSONL rows, and the
|
|
89
|
+
equivalent `--fact-id` or `--event-id` flags for one request. These references reuse canonical evidence
|
|
92
90
|
in single calls and synchronous batches of at most 25. Durable batches of
|
|
93
91
|
26-5,000 reject canonical references instead of silently rediscovering them.
|
|
94
92
|
JSON output exposes the normalized customer-facing signal fields; human output
|
package/dist/bin.js
CHANGED
|
@@ -24,34 +24,30 @@ Six product commands:
|
|
|
24
24
|
signaliz find-email --job-id job_... Resume an existing Find Email batch without redispatch
|
|
25
25
|
signaliz verify-email [jane@example.com] [--verification-run-id run_...] [--no-wait] [--max-wait-ms 600000]
|
|
26
26
|
signaliz verify-email --job-id job_... Resume an existing Verify Email batch without redispatch
|
|
27
|
-
signaliz company-signals --domain example.com
|
|
27
|
+
signaliz company-signals --domain example.com [--research-prompt "Optional research lens"] [--lookback-days 365]
|
|
28
28
|
signaliz company-signals --input companies.json --no-wait Submit a durable >25-row batch and return its job
|
|
29
29
|
signaliz company-signals --job-id job_... Resume an existing Company Signals batch without redispatch
|
|
30
30
|
signaliz company-signals --signal-run-id run_... Read a completed run without duplicate spend
|
|
31
31
|
signaliz signal-to-copy --company-domain example.com --person-name "Jane Doe" \\
|
|
32
32
|
--title "VP Sales" --campaign-offer "pipeline intelligence" [--signal-run-id run_...] \\
|
|
33
|
-
[--
|
|
34
|
-
[--
|
|
33
|
+
[--fact-id <sha256> | --event-id <sha256>] \\
|
|
34
|
+
[--run-without-signal yes|no] [--deep-search] [--max-wait-ms 120000]
|
|
35
35
|
signaliz signal-to-copy --signal-run-id copy_... Reuse a completed signal run
|
|
36
36
|
signaliz signal-to-copy --fact-id <sha256> --company-domain example.com --person-name "Jane Doe" --title "VP Sales" --campaign-offer "pipeline intelligence" Reuse one canonical signal without rediscovery
|
|
37
37
|
signaliz signal-to-copy --input recipients.json --no-wait Submit a durable >25-row batch
|
|
38
38
|
signaliz signal-to-copy --job-id job_... Resume an existing Signal to Copy batch without redispatch
|
|
39
|
-
signaliz signals "companies that just got funded" [--
|
|
40
|
-
signaliz signals-first "companies that just got funded" [--limit 100] [--
|
|
41
|
-
signaliz
|
|
42
|
-
signaliz awareness
|
|
43
|
-
signaliz awareness
|
|
44
|
-
signaliz awareness
|
|
45
|
-
signaliz awareness
|
|
46
|
-
signaliz awareness
|
|
47
|
-
signaliz awareness
|
|
48
|
-
signaliz awareness signals [--monitor-id <uuid>]
|
|
49
|
-
signaliz awareness pause|resume|delete --monitor-id <uuid>
|
|
39
|
+
signaliz signals "companies that just got funded" [--limit 100] [--wait]
|
|
40
|
+
signaliz signals-first "companies that just got funded" [--limit 100] [--wait]
|
|
41
|
+
signaliz awareness add --domain acme.com [--schedule daily|weekly|monthly]
|
|
42
|
+
signaliz awareness list
|
|
43
|
+
signaliz awareness run --monitor-id <uuid> [--idempotency-key <key>]
|
|
44
|
+
signaliz awareness pause|resume --monitor-id <uuid>
|
|
45
|
+
signaliz awareness signals --domain acme.com
|
|
46
|
+
signaliz awareness signals --monitor-id <uuid>
|
|
47
|
+
signaliz awareness export [--monitor-id <uuid>]
|
|
50
48
|
signaliz awareness settings
|
|
51
|
-
signaliz awareness
|
|
52
|
-
signaliz awareness
|
|
53
|
-
signaliz awareness export [--monitor-id <uuid>] --json
|
|
54
|
-
signaliz awareness send-export --input signals.jsonl
|
|
49
|
+
signaliz awareness delete --domain acme.com
|
|
50
|
+
signaliz awareness schedule --domain acme.com --schedule daily|weekly|monthly
|
|
55
51
|
signaliz flow --signal-query "companies with recent hiring" --campaign-offer "..." [--limit 5] [--lookback-days 90] [--people-titles "CEO,VP Sales"]
|
|
56
52
|
signaliz flow --run-id run_... Read a durable Flow checkpoint without dispatching new work
|
|
57
53
|
|
|
@@ -75,16 +71,14 @@ Common flags:
|
|
|
75
71
|
--concurrency <1-50> Simultaneous API requests for batch input (default: 10)
|
|
76
72
|
--idempotency-key <key> Reuse after an ambiguous response to recover the same request or job
|
|
77
73
|
--no-wait Return the durable Find Email run ID immediately; resume with --run-id
|
|
78
|
-
--
|
|
74
|
+
--run-without-signal yes|no Draft from the offer without researching or claiming a company signal
|
|
79
75
|
--run-id <run_...> Resume one existing Find Email run without dispatching new work
|
|
80
76
|
--job-id <job_...> Resume an existing core-product batch without dispatching new work
|
|
81
|
-
--icp-context <text> Optional ICP, product, or pain context that returned signals must support
|
|
82
|
-
--signal-search-run-id <id> Resume Signals First, or pin its immutable snapshot in Signal to Copy
|
|
83
77
|
--fact-id <sha256> Pin one active canonical signal fact in Signal to Copy
|
|
84
78
|
--event-id <sha256> Pin one canonical signal event in Signal to Copy
|
|
85
79
|
--dry-run Return a no-spend plan without provider calls, jobs, or writes
|
|
86
80
|
|
|
87
|
-
Company Signals
|
|
81
|
+
Company Signals requires only --domain; --research-prompt and --lookback-days are optional. Signaliz checks its cache and returns the newest distinct events that pass its deterministic date, source, company, evidence, and duplicate gates. Durable batch rows require domain. Signal to Copy accepts --run-without-signal yes|no. Signals First accepts a query and --limit up to 100, plus recovery, idempotency, and dry-run controls. Signal Awareness supports simple domain commands and the full monitor lifecycle.
|
|
88
82
|
`;
|
|
89
83
|
function loadConfig() {
|
|
90
84
|
if (!(0, import_node_fs.existsSync)(CONFIG_FILE)) return {};
|
|
@@ -131,25 +125,6 @@ function requireIntegerInRange(value, name, minimum, maximum) {
|
|
|
131
125
|
throw new CliInputError(`${name} must be an integer between ${minimum} and ${maximum}`);
|
|
132
126
|
}
|
|
133
127
|
}
|
|
134
|
-
function validateSignalDateWindow(afterDate, beforeDate, lookbackDays, flagPrefix = "--") {
|
|
135
|
-
if ((afterDate || beforeDate) && lookbackDays !== void 0) {
|
|
136
|
-
throw new CliInputError(`${flagPrefix}after-date/--before-date cannot be combined with --lookback-days`);
|
|
137
|
-
}
|
|
138
|
-
const parseDate = (value, name) => {
|
|
139
|
-
if (value === void 0) return void 0;
|
|
140
|
-
if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) throw new CliInputError(`${name} must use YYYY-MM-DD format`);
|
|
141
|
-
const timestamp = Date.parse(`${value}T00:00:00Z`);
|
|
142
|
-
if (!Number.isFinite(timestamp) || new Date(timestamp).toISOString().slice(0, 10) !== value) {
|
|
143
|
-
throw new CliInputError(`${name} must be a valid calendar date`);
|
|
144
|
-
}
|
|
145
|
-
return timestamp;
|
|
146
|
-
};
|
|
147
|
-
const afterTimestamp = parseDate(afterDate, `${flagPrefix}after-date`);
|
|
148
|
-
const beforeTimestamp = parseDate(beforeDate, `${flagPrefix}before-date`);
|
|
149
|
-
if (afterTimestamp !== void 0 && beforeTimestamp !== void 0 && beforeTimestamp < afterTimestamp) {
|
|
150
|
-
throw new CliInputError(`${flagPrefix}before-date must be on or after ${flagPrefix}after-date`);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
128
|
function requireSignalToCopyIdentity(request) {
|
|
154
129
|
if (stringValue(request.signalRunId)) return;
|
|
155
130
|
const missing = [
|
|
@@ -436,12 +411,19 @@ function customerEmailResult(value, kind) {
|
|
|
436
411
|
const result = record(value);
|
|
437
412
|
const raw = record(result.raw);
|
|
438
413
|
if (kind === "verify") {
|
|
414
|
+
const isCatchAll2 = result.isCatchAll === true || raw.is_catch_all === true || raw.email_is_catch_all === true;
|
|
415
|
+
const okToSend = result.okToSend === true || raw.ok_to_send === true;
|
|
416
|
+
const rawStatus = String(result.status || raw.status || "").trim().toLowerCase();
|
|
417
|
+
const legacyVerdict = String(
|
|
418
|
+
raw.verification_status || raw.verification_verdict || raw.deliverability_status || ""
|
|
419
|
+
).trim().toLowerCase();
|
|
420
|
+
const status = rawStatus && !["completed", "processing"].includes(rawStatus) ? rawStatus : rawStatus === "processing" ? "processing" : legacyVerdict ? legacyVerdict : okToSend ? "valid" : isCatchAll2 ? "catch_all" : "unknown";
|
|
439
421
|
return {
|
|
440
422
|
email: typeof result.email === "string" ? result.email : typeof raw.email === "string" ? raw.email : null,
|
|
441
|
-
status
|
|
442
|
-
is_catch_all:
|
|
423
|
+
status,
|
|
424
|
+
is_catch_all: isCatchAll2,
|
|
443
425
|
credits_charged: safeNonNegativeNumber(result.creditsCharged ?? raw.credits_charged) ?? 0,
|
|
444
|
-
ok_to_send:
|
|
426
|
+
ok_to_send: okToSend
|
|
445
427
|
};
|
|
446
428
|
}
|
|
447
429
|
if (String(result.status || "").toLowerCase() === "processing") {
|
|
@@ -936,16 +918,10 @@ async function discoverSignalsEverything(request) {
|
|
|
936
918
|
const body = request.signalSearchRunId ? {
|
|
937
919
|
signal_search_run_id: request.signalSearchRunId,
|
|
938
920
|
...request.limit === void 0 ? {} : { limit: request.limit },
|
|
939
|
-
...request.dryRun === void 0 ? {} : { dry_run: request.dryRun }
|
|
940
|
-
...request.idempotencyKey ? { idempotency_key: request.idempotencyKey } : {}
|
|
921
|
+
...request.dryRun === void 0 ? {} : { dry_run: request.dryRun }
|
|
941
922
|
} : {
|
|
942
923
|
query: request.query,
|
|
943
|
-
...request.icpContext ? { icp_context: request.icpContext } : {},
|
|
944
924
|
limit: request.limit ?? 100,
|
|
945
|
-
...request.sources ? { sources: request.sources } : {},
|
|
946
|
-
...request.lookbackDays === void 0 ? {} : { lookback_days: request.lookbackDays },
|
|
947
|
-
...request.afterDate ? { after_date: request.afterDate } : {},
|
|
948
|
-
...request.beforeDate ? { before_date: request.beforeDate } : {},
|
|
949
925
|
...request.dryRun === void 0 ? {} : { dry_run: request.dryRun },
|
|
950
926
|
...request.idempotencyKey ? { idempotency_key: request.idempotencyKey } : {}
|
|
951
927
|
};
|
|
@@ -1340,7 +1316,7 @@ async function companySignals() {
|
|
|
1340
1316
|
].filter(hasFlag);
|
|
1341
1317
|
if (removedControlFlags.length > 0) {
|
|
1342
1318
|
throw new CliInputError(
|
|
1343
|
-
`Company Signals manages provider routing, coverage, and classifications internally; ${removedControlFlags.map((name) => `--${name}`).join(", ")} is no longer supported. Use --domain
|
|
1319
|
+
`Company Signals manages provider routing, coverage, and classifications internally; ${removedControlFlags.map((name) => `--${name}`).join(", ")} is no longer supported. Use --domain and --research-prompt.`
|
|
1344
1320
|
);
|
|
1345
1321
|
}
|
|
1346
1322
|
if (jobId) {
|
|
@@ -1381,6 +1357,8 @@ async function companySignals() {
|
|
|
1381
1357
|
signalRunId: row.signalRunId || row.signal_run_id,
|
|
1382
1358
|
companyDomain: row.companyDomain || row.company_domain || row.domain,
|
|
1383
1359
|
domain: row.domain || row.companyDomain || row.company_domain,
|
|
1360
|
+
researchPrompt: row.researchPrompt || row.research_prompt,
|
|
1361
|
+
lookbackDays: row.lookbackDays || row.lookback_days,
|
|
1384
1362
|
idempotencyKey: row.idempotencyKey || row.idempotency_key
|
|
1385
1363
|
};
|
|
1386
1364
|
});
|
|
@@ -1390,7 +1368,7 @@ async function companySignals() {
|
|
|
1390
1368
|
);
|
|
1391
1369
|
if (incompatible) {
|
|
1392
1370
|
throw new CliInputError(
|
|
1393
|
-
"Company Signals batches larger than 25 require domain
|
|
1371
|
+
"Company Signals batches larger than 25 require domain rows without per-row controls or recovery IDs."
|
|
1394
1372
|
);
|
|
1395
1373
|
}
|
|
1396
1374
|
} else if (hasFlag("no-wait") && !hasFlag("dry-run")) {
|
|
@@ -1425,14 +1403,16 @@ async function companySignals() {
|
|
|
1425
1403
|
throw new CliInputError("Company Signals --poll-interval-ms requires --input or --job-id.");
|
|
1426
1404
|
}
|
|
1427
1405
|
const companyDomain = flag("domain") || flag("company-domain");
|
|
1406
|
+
const researchPrompt = flag("research-prompt");
|
|
1428
1407
|
const signalRunId = flag("signal-run-id");
|
|
1429
1408
|
if (!companyDomain && !signalRunId) {
|
|
1430
|
-
throw new CliInputError(
|
|
1409
|
+
throw new CliInputError('Usage: signaliz company-signals --domain example.com [--research-prompt "Why now?"]');
|
|
1431
1410
|
}
|
|
1432
1411
|
const request = {
|
|
1433
1412
|
signalRunId,
|
|
1434
1413
|
domain: companyDomain,
|
|
1435
|
-
|
|
1414
|
+
researchPrompt,
|
|
1415
|
+
lookbackDays: numberFlag("lookback-days")
|
|
1436
1416
|
};
|
|
1437
1417
|
if (hasFlag("dry-run")) {
|
|
1438
1418
|
const result2 = await createClient().enrichCompanySignals({ ...request, dryRun: true });
|
|
@@ -1492,29 +1472,19 @@ async function signals(args) {
|
|
|
1492
1472
|
if (!query && !signalSearchRunId) {
|
|
1493
1473
|
fail('Usage: signaliz signals "companies that just got funded" [--limit 100] OR signaliz signals --signal-search-run-id run_...');
|
|
1494
1474
|
}
|
|
1495
|
-
const
|
|
1496
|
-
if (
|
|
1497
|
-
fail(
|
|
1498
|
-
}
|
|
1499
|
-
const icpContext = flag("icp-context");
|
|
1500
|
-
if (hasFlag("icp-context") && (typeof icpContext !== "string" || icpContext.trim().length < 2 || icpContext.trim().length > 4e3)) {
|
|
1501
|
-
fail("--icp-context must contain between 2 and 4000 characters");
|
|
1475
|
+
const removedControls = ["icp-context", "sources", "lookback-days", "after-date", "before-date"].filter(hasFlag);
|
|
1476
|
+
if (removedControls.length > 0) {
|
|
1477
|
+
fail(`Signals First accepts only query and --limit; ${removedControls.map((name) => `--${name}`).join(", ")} is no longer supported.`);
|
|
1502
1478
|
}
|
|
1503
1479
|
const request = {
|
|
1504
1480
|
query,
|
|
1505
|
-
icpContext: icpContext?.trim(),
|
|
1506
1481
|
signalSearchRunId,
|
|
1507
1482
|
limit: numberFlag("limit"),
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
afterDate: flag("after-date"),
|
|
1511
|
-
beforeDate: flag("before-date"),
|
|
1512
|
-
idempotencyKey: flag("idempotency-key"),
|
|
1513
|
-
dryRun: hasFlag("dry-run")
|
|
1483
|
+
dryRun: hasFlag("dry-run") || void 0,
|
|
1484
|
+
idempotencyKey: flag("idempotency-key")
|
|
1514
1485
|
};
|
|
1515
|
-
validateSignalDateWindow(request.afterDate, request.beforeDate, request.lookbackDays);
|
|
1516
1486
|
let result = await discoverSignalsEverything(request);
|
|
1517
|
-
if (hasFlag("wait")
|
|
1487
|
+
if (hasFlag("wait")) {
|
|
1518
1488
|
const maxWaitMs = numberFlag("max-wait-ms") ?? 15 * 6e4;
|
|
1519
1489
|
const pollIntervalMs = numberFlag("poll-interval-ms");
|
|
1520
1490
|
const startedAt = Date.now();
|
|
@@ -1674,6 +1644,7 @@ async function signalToCopy() {
|
|
|
1674
1644
|
"lookback-days",
|
|
1675
1645
|
"copy-evidence-mode",
|
|
1676
1646
|
"without-signals",
|
|
1647
|
+
"run-without-signal",
|
|
1677
1648
|
"signal-run-id",
|
|
1678
1649
|
"signal-search-run-id",
|
|
1679
1650
|
"fact-id",
|
|
@@ -1708,10 +1679,9 @@ async function signalToCopy() {
|
|
|
1708
1679
|
personName: row.personName || row.person_name,
|
|
1709
1680
|
title: row.title,
|
|
1710
1681
|
campaignOffer: row.campaignOffer || row.campaign_offer || row.offer,
|
|
1711
|
-
|
|
1682
|
+
runWithoutSignal: row.runWithoutSignal ?? row.run_without_signal ?? yesNoFlag("run-without-signal"),
|
|
1712
1683
|
lookbackDays: 365,
|
|
1713
1684
|
signalRunId: row.signalRunId || row.signal_run_id,
|
|
1714
|
-
signalSearchRunId: row.signalSearchRunId || row.signal_search_run_id,
|
|
1715
1685
|
factId: row.factId || row.fact_id,
|
|
1716
1686
|
eventId: row.eventId || row.event_id,
|
|
1717
1687
|
enableDeepSearch: row.enableDeepSearch ?? row.enable_deep_search ?? hasFlag("deep-search"),
|
|
@@ -1725,7 +1695,7 @@ async function signalToCopy() {
|
|
|
1725
1695
|
}
|
|
1726
1696
|
if (durableBatch) {
|
|
1727
1697
|
const invalidIndex = requests.findIndex(
|
|
1728
|
-
(request2) => Boolean(stringValue(request2.idempotencyKey)) || request2.maxWaitMs !== void 0 || Boolean(stringValue(request2.
|
|
1698
|
+
(request2) => Boolean(stringValue(request2.idempotencyKey)) || request2.maxWaitMs !== void 0 || Boolean(stringValue(request2.factId)) || Boolean(stringValue(request2.eventId)) || !stringValue(request2.companyDomain) || !stringValue(request2.personName) || !stringValue(request2.title) || !stringValue(request2.campaignOffer)
|
|
1729
1699
|
);
|
|
1730
1700
|
if (invalidIndex >= 0) {
|
|
1731
1701
|
throw new CliInputError(
|
|
@@ -1771,10 +1741,9 @@ async function signalToCopy() {
|
|
|
1771
1741
|
personName,
|
|
1772
1742
|
title,
|
|
1773
1743
|
campaignOffer,
|
|
1774
|
-
|
|
1744
|
+
runWithoutSignal: yesNoFlag("run-without-signal"),
|
|
1775
1745
|
lookbackDays: 365,
|
|
1776
1746
|
signalRunId,
|
|
1777
|
-
signalSearchRunId: flag("signal-search-run-id"),
|
|
1778
1747
|
factId: flag("fact-id"),
|
|
1779
1748
|
eventId: flag("event-id"),
|
|
1780
1749
|
enableDeepSearch: hasFlag("deep-search"),
|
|
@@ -1860,102 +1829,51 @@ Import this file into your MCP client.
|
|
|
1860
1829
|
});
|
|
1861
1830
|
}
|
|
1862
1831
|
function awarenessSchedule() {
|
|
1863
|
-
const direct = flag("schedule-cron");
|
|
1864
|
-
if (direct) return direct;
|
|
1865
1832
|
const schedule = flag("schedule");
|
|
1866
1833
|
if (!schedule) return void 0;
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
daily: "0 8 * * *",
|
|
1870
|
-
every_2_days: "0 8 */2 * *",
|
|
1871
|
-
weekly: "0 8 * * 1",
|
|
1872
|
-
monthly: "0 8 1 * *"
|
|
1873
|
-
};
|
|
1874
|
-
if (!schedules[schedule]) {
|
|
1875
|
-
throw new CliInputError("--schedule must be every_6_hours, daily, every_2_days, weekly, or monthly");
|
|
1834
|
+
if (!["daily", "weekly", "monthly"].includes(schedule)) {
|
|
1835
|
+
throw new CliInputError("--schedule must be daily, weekly, or monthly");
|
|
1876
1836
|
}
|
|
1877
|
-
return
|
|
1837
|
+
return schedule;
|
|
1838
|
+
}
|
|
1839
|
+
function yesNoFlag(name) {
|
|
1840
|
+
const value = flag(name);
|
|
1841
|
+
if (value === void 0) return void 0;
|
|
1842
|
+
if (value === "yes") return true;
|
|
1843
|
+
if (value === "no") return false;
|
|
1844
|
+
throw new CliInputError(`--${name} must be yes or no`);
|
|
1878
1845
|
}
|
|
1879
1846
|
async function awareness(args) {
|
|
1880
1847
|
const action = args[0];
|
|
1881
|
-
const
|
|
1882
|
-
const actions = [
|
|
1883
|
-
"create",
|
|
1884
|
-
"import",
|
|
1885
|
-
"list",
|
|
1886
|
-
"update",
|
|
1887
|
-
"schedule",
|
|
1888
|
-
"run",
|
|
1889
|
-
"signals",
|
|
1890
|
-
"pause",
|
|
1891
|
-
"resume",
|
|
1892
|
-
"delete",
|
|
1893
|
-
"settings",
|
|
1894
|
-
"set-output",
|
|
1895
|
-
"test-webhook",
|
|
1896
|
-
"export",
|
|
1897
|
-
"send-export"
|
|
1898
|
-
];
|
|
1848
|
+
const actions = ["add", "list", "run", "pause", "resume", "signals", "export", "settings", "delete", "schedule"];
|
|
1899
1849
|
if (!action || !actions.includes(action)) {
|
|
1900
1850
|
throw new CliInputError(`Usage: signaliz awareness <${actions.join("|")}>`);
|
|
1901
1851
|
}
|
|
1852
|
+
const domain = flag("domain");
|
|
1853
|
+
const monitorId = flag("monitor-id");
|
|
1902
1854
|
const client = createClient();
|
|
1903
|
-
if (action === "
|
|
1904
|
-
const
|
|
1905
|
-
|
|
1906
|
-
if (!companyName || !domain) {
|
|
1907
|
-
throw new CliInputError('Usage: signaliz awareness create --company-name "Acme" --domain acme.com');
|
|
1908
|
-
}
|
|
1909
|
-
const result2 = await client.createSignalMonitor({
|
|
1910
|
-
companyName,
|
|
1911
|
-
domain,
|
|
1912
|
-
scheduleCron: awarenessSchedule(),
|
|
1913
|
-
webhookUrl: flag("webhook-url")
|
|
1914
|
-
});
|
|
1915
|
-
output(result2, () => process.stdout.write(`Monitor created: ${String(result2.monitor?.id || "pending")}
|
|
1916
|
-
`));
|
|
1855
|
+
if (action === "list") {
|
|
1856
|
+
const result2 = await client.listSignalMonitors(numberFlag("limit"), numberFlag("offset"));
|
|
1857
|
+
output(result2);
|
|
1917
1858
|
return;
|
|
1918
1859
|
}
|
|
1919
|
-
if (action === "
|
|
1920
|
-
|
|
1921
|
-
if (!rows) throw new CliInputError("signaliz awareness import requires --input <json-or-jsonl-file>");
|
|
1922
|
-
if (rows.length > 500) throw new CliInputError(`Signal Awareness imports at most 500 companies; received ${rows.length}`);
|
|
1923
|
-
const monitors = rows.map((value, index) => {
|
|
1924
|
-
const row = record(value);
|
|
1925
|
-
const companyName = stringValue(row.company_name ?? row.companyName ?? row.company ?? row.name);
|
|
1926
|
-
const domain = stringValue(row.domain ?? row.website);
|
|
1927
|
-
if (!companyName || !domain) throw new CliInputError(`Awareness import row ${index + 1} requires company_name and domain`);
|
|
1928
|
-
return { companyName, domain };
|
|
1929
|
-
});
|
|
1930
|
-
const result2 = await client.bulkCreateSignalMonitors(monitors, {
|
|
1931
|
-
scheduleCron: awarenessSchedule(),
|
|
1932
|
-
webhookUrl: flag("webhook-url")
|
|
1933
|
-
});
|
|
1934
|
-
output(result2, () => process.stdout.write(`Created: ${result2.created || 0}
|
|
1935
|
-
Skipped: ${result2.skipped || 0}
|
|
1936
|
-
`));
|
|
1860
|
+
if (action === "settings") {
|
|
1861
|
+
output(await client.getSignalAwarenessSettings());
|
|
1937
1862
|
return;
|
|
1938
1863
|
}
|
|
1939
|
-
if (action === "
|
|
1940
|
-
|
|
1941
|
-
const
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
process.stdout.write(`${String(monitor.company_name)} ${String(monitor.status)} ${String(monitor.next_run_at || "not scheduled")} ${String(monitor.id)}
|
|
1948
|
-
`);
|
|
1949
|
-
}
|
|
1950
|
-
});
|
|
1864
|
+
if (action === "run" || action === "pause" || action === "resume") {
|
|
1865
|
+
if (!monitorId) throw new CliInputError(`signaliz awareness ${action} requires --monitor-id <uuid>`);
|
|
1866
|
+
const result2 = action === "run" ? await client.runSignalMonitor(monitorId, flag("idempotency-key")) : action === "pause" ? await client.pauseSignalMonitor(monitorId) : await client.resumeSignalMonitor(monitorId);
|
|
1867
|
+
output(result2);
|
|
1868
|
+
return;
|
|
1869
|
+
}
|
|
1870
|
+
if (action === "export") {
|
|
1871
|
+
output(await client.exportSignalAwareness(monitorId));
|
|
1951
1872
|
return;
|
|
1952
1873
|
}
|
|
1953
1874
|
if (action === "signals") {
|
|
1954
|
-
|
|
1955
|
-
const
|
|
1956
|
-
if (limit !== void 0) requireIntegerInRange(limit, "--limit", 1, 500);
|
|
1957
|
-
if (offset !== void 0) requireIntegerInRange(offset, "--offset", 0, 1e4);
|
|
1958
|
-
const result2 = customerSignalAwarenessResult(await client.listSignalAwarenessSignals(monitorId, limit, offset));
|
|
1875
|
+
if (!domain && !monitorId) throw new CliInputError("signaliz awareness signals requires --domain or --monitor-id");
|
|
1876
|
+
const result2 = customerSignalAwarenessResult(monitorId ? await client.listSignalAwarenessSignals(monitorId, numberFlag("limit"), numberFlag("offset")) : await client.listAllSignalAwarenessSignals(domain));
|
|
1959
1877
|
output(result2, () => {
|
|
1960
1878
|
for (const signal of result2.signals || []) {
|
|
1961
1879
|
process.stdout.write(`${signal.signal_type} ${signal.signal_title} ${signal.signal_summary} ${signal.source} ${signal.date} ${signal.company_name} ${signal.domain}
|
|
@@ -1964,81 +1882,25 @@ Skipped: ${result2.skipped || 0}
|
|
|
1964
1882
|
});
|
|
1965
1883
|
return;
|
|
1966
1884
|
}
|
|
1967
|
-
if (action === "
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
`));
|
|
1972
|
-
return;
|
|
1973
|
-
}
|
|
1974
|
-
if (action === "set-output") {
|
|
1975
|
-
const mode = flag("mode");
|
|
1976
|
-
if (mode !== "csv" && mode !== "webhook") throw new CliInputError("signaliz awareness set-output requires --mode csv|webhook");
|
|
1977
|
-
const webhookUrl = flag("webhook-url");
|
|
1978
|
-
if (mode === "webhook" && !webhookUrl) throw new CliInputError("--webhook-url is required when --mode webhook");
|
|
1979
|
-
const result2 = await client.setSignalAwarenessOutput(mode, webhookUrl);
|
|
1980
|
-
output(result2, () => process.stdout.write(`Signal Awareness output set to ${mode}
|
|
1981
|
-
`));
|
|
1982
|
-
return;
|
|
1983
|
-
}
|
|
1984
|
-
if (action === "test-webhook") {
|
|
1985
|
-
const webhookUrl = flag("webhook-url");
|
|
1986
|
-
if (!webhookUrl) throw new CliInputError("signaliz awareness test-webhook requires --webhook-url https://...");
|
|
1987
|
-
const result2 = await client.testSignalAwarenessWebhook(webhookUrl);
|
|
1988
|
-
output(result2, () => process.stdout.write(`Webhook returned HTTP ${result2.webhookStatus || "unknown"}
|
|
1989
|
-
`));
|
|
1990
|
-
return;
|
|
1991
|
-
}
|
|
1992
|
-
if (action === "export") {
|
|
1993
|
-
const result2 = customerSignalAwarenessResult(await client.exportSignalAwareness(monitorId));
|
|
1994
|
-
output(result2, () => process.stdout.write(`Companies: ${result2.monitors?.length || 0}
|
|
1995
|
-
Signals: ${result2.signals?.length || 0}
|
|
1996
|
-
`));
|
|
1997
|
-
return;
|
|
1998
|
-
}
|
|
1999
|
-
if (action === "send-export") {
|
|
2000
|
-
const rows = readBatchInput();
|
|
2001
|
-
if (!rows) throw new CliInputError("signaliz awareness send-export requires --input <json-or-jsonl-file>");
|
|
2002
|
-
if (rows.length > 2e3) throw new CliInputError(`Signal Awareness sends at most 2,000 signals per call; received ${rows.length}`);
|
|
2003
|
-
const signals2 = publicSignalRows(rows);
|
|
2004
|
-
if (signals2.length !== rows.length) throw new CliInputError("Every send-export row must contain signal_type, source, date, company_name, and domain");
|
|
2005
|
-
const result2 = await client.sendSignalAwarenessExport(signals2);
|
|
2006
|
-
output(result2, () => process.stdout.write(`Delivered: ${result2.delivered || 0}
|
|
2007
|
-
Webhook: HTTP ${result2.webhookStatus || "unknown"}
|
|
1885
|
+
if (action === "add") {
|
|
1886
|
+
if (!domain) throw new CliInputError("signaliz awareness add requires --domain <company-domain>");
|
|
1887
|
+
const result2 = await client.addSignalAwarenessCompany(domain, awarenessSchedule() ?? "daily");
|
|
1888
|
+
output(result2, () => process.stdout.write(`Company added: ${domain}
|
|
2008
1889
|
`));
|
|
2009
1890
|
return;
|
|
2010
1891
|
}
|
|
2011
|
-
if (
|
|
2012
|
-
|
|
2013
|
-
const
|
|
2014
|
-
|
|
2015
|
-
const
|
|
2016
|
-
|
|
2017
|
-
if (!companyName && !scheduleCron && webhookUrl === void 0) {
|
|
2018
|
-
throw new CliInputError("signaliz awareness update requires --company-name, --schedule/--schedule-cron, --webhook-url, or --clear-webhook");
|
|
2019
|
-
}
|
|
2020
|
-
const result2 = await client.updateSignalMonitor(monitorId, { companyName, scheduleCron, webhookUrl });
|
|
2021
|
-
output(result2, () => process.stdout.write(`Monitor updated: ${monitorId}
|
|
1892
|
+
if (action === "schedule") {
|
|
1893
|
+
if (!domain) throw new CliInputError("signaliz awareness schedule requires --domain <company-domain>");
|
|
1894
|
+
const schedule = awarenessSchedule();
|
|
1895
|
+
if (!schedule) throw new CliInputError("signaliz awareness schedule requires --schedule daily|weekly|monthly");
|
|
1896
|
+
const result2 = await client.changeSignalAwarenessSchedule(domain, schedule);
|
|
1897
|
+
output(result2, () => process.stdout.write(`Schedule updated: ${domain} (${schedule})
|
|
2022
1898
|
`));
|
|
2023
1899
|
return;
|
|
2024
1900
|
}
|
|
2025
|
-
if (
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
output(result3);
|
|
2029
|
-
return;
|
|
2030
|
-
}
|
|
2031
|
-
const result2 = await client.runSignalMonitor(monitorId, flag("idempotency-key"));
|
|
2032
|
-
output(result2, () => {
|
|
2033
|
-
process.stdout.write(`Run: ${String(result2.run?.id || result2.runId || "pending")}
|
|
2034
|
-
Signals: ${String(result2.run?.signals_found || 0)}
|
|
2035
|
-
Credits used: ${result2.creditsUsed || 0}
|
|
2036
|
-
`);
|
|
2037
|
-
});
|
|
2038
|
-
return;
|
|
2039
|
-
}
|
|
2040
|
-
const result = action === "delete" ? await client.deleteSignalMonitor(monitorId) : action === "resume" ? await client.resumeSignalMonitor(monitorId) : await client.pauseSignalMonitor(monitorId);
|
|
2041
|
-
output(result, () => process.stdout.write(`Monitor ${action === "delete" ? "deleted" : action === "resume" ? "resumed" : "paused"}: ${monitorId}
|
|
1901
|
+
if (!domain && !monitorId) throw new CliInputError("signaliz awareness delete requires --domain or --monitor-id");
|
|
1902
|
+
const result = monitorId ? await client.deleteSignalMonitor(monitorId) : await client.deleteSignalAwarenessCompany(domain);
|
|
1903
|
+
output(result, () => process.stdout.write(`Monitor deleted: ${monitorId || domain}
|
|
2042
1904
|
`));
|
|
2043
1905
|
}
|
|
2044
1906
|
async function main() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signaliz/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.70",
|
|
4
4
|
"description": "Signaliz CLI for Company Signal Enrichment, Signals First, Signal Awareness, Signal to Copy AI, and Signaliz Flow.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"signaliz": "dist/bin.js"
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"node": ">=18"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@signaliz/sdk": "^1.0.
|
|
32
|
+
"@signaliz/sdk": "^1.0.75"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"tsup": "^8.0.0",
|