@signaliz/cli 1.0.68 → 1.0.69
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 +55 -237
- 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,24 @@ 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 "Why would this company use Signaliz?"
|
|
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 update --monitor-id <uuid> [--company-name "Acme"] [--schedule weekly] [--webhook-url https://...]
|
|
46
|
-
signaliz awareness schedule --monitor-id <uuid> --schedule monthly
|
|
47
|
-
signaliz awareness run --monitor-id <uuid> --idempotency-key <key>
|
|
48
|
-
signaliz awareness signals [--monitor-id <uuid>]
|
|
49
|
-
signaliz awareness pause|resume|delete --monitor-id <uuid>
|
|
50
|
-
signaliz awareness settings
|
|
51
|
-
signaliz awareness set-output --mode csv|webhook [--webhook-url https://...]
|
|
52
|
-
signaliz awareness test-webhook --webhook-url https://...
|
|
53
|
-
signaliz awareness export [--monitor-id <uuid>] --json
|
|
54
|
-
signaliz awareness send-export --input signals.jsonl
|
|
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 signals --domain acme.com
|
|
43
|
+
signaliz awareness delete --domain acme.com
|
|
44
|
+
signaliz awareness schedule --domain acme.com --schedule daily|weekly|monthly
|
|
55
45
|
signaliz flow --signal-query "companies with recent hiring" --campaign-offer "..." [--limit 5] [--lookback-days 90] [--people-titles "CEO,VP Sales"]
|
|
56
46
|
signaliz flow --run-id run_... Read a durable Flow checkpoint without dispatching new work
|
|
57
47
|
|
|
@@ -75,16 +65,14 @@ Common flags:
|
|
|
75
65
|
--concurrency <1-50> Simultaneous API requests for batch input (default: 10)
|
|
76
66
|
--idempotency-key <key> Reuse after an ambiguous response to recover the same request or job
|
|
77
67
|
--no-wait Return the durable Find Email run ID immediately; resume with --run-id
|
|
78
|
-
--
|
|
68
|
+
--run-without-signal yes|no Draft from the offer without researching or claiming a company signal
|
|
79
69
|
--run-id <run_...> Resume one existing Find Email run without dispatching new work
|
|
80
70
|
--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
71
|
--fact-id <sha256> Pin one active canonical signal fact in Signal to Copy
|
|
84
72
|
--event-id <sha256> Pin one canonical signal event in Signal to Copy
|
|
85
73
|
--dry-run Return a no-spend plan without provider calls, jobs, or writes
|
|
86
74
|
|
|
87
|
-
Company Signals
|
|
75
|
+
Company Signals requires --domain and --research-prompt. 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 and research_prompt. Signal to Copy accepts --run-without-signal yes|no. Signals First accepts only a query and --limit up to 100. Signal Awareness management uses only a company domain and, for schedule changes, daily, weekly, or monthly.
|
|
88
76
|
`;
|
|
89
77
|
function loadConfig() {
|
|
90
78
|
if (!(0, import_node_fs.existsSync)(CONFIG_FILE)) return {};
|
|
@@ -131,25 +119,6 @@ function requireIntegerInRange(value, name, minimum, maximum) {
|
|
|
131
119
|
throw new CliInputError(`${name} must be an integer between ${minimum} and ${maximum}`);
|
|
132
120
|
}
|
|
133
121
|
}
|
|
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
122
|
function requireSignalToCopyIdentity(request) {
|
|
154
123
|
if (stringValue(request.signalRunId)) return;
|
|
155
124
|
const missing = [
|
|
@@ -935,26 +904,16 @@ function normalizeSignalsEverythingResult(request, value) {
|
|
|
935
904
|
async function discoverSignalsEverything(request) {
|
|
936
905
|
const body = request.signalSearchRunId ? {
|
|
937
906
|
signal_search_run_id: request.signalSearchRunId,
|
|
938
|
-
...request.limit === void 0 ? {} : { limit: request.limit }
|
|
939
|
-
...request.dryRun === void 0 ? {} : { dry_run: request.dryRun },
|
|
940
|
-
...request.idempotencyKey ? { idempotency_key: request.idempotencyKey } : {}
|
|
907
|
+
...request.limit === void 0 ? {} : { limit: request.limit }
|
|
941
908
|
} : {
|
|
942
909
|
query: request.query,
|
|
943
|
-
|
|
944
|
-
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
|
-
...request.dryRun === void 0 ? {} : { dry_run: request.dryRun },
|
|
950
|
-
...request.idempotencyKey ? { idempotency_key: request.idempotencyKey } : {}
|
|
910
|
+
limit: request.limit ?? 100
|
|
951
911
|
};
|
|
952
912
|
const response = await fetch(`${resolveBaseUrl()}/api/v1/signals`, {
|
|
953
913
|
method: "POST",
|
|
954
914
|
headers: {
|
|
955
915
|
"Content-Type": "application/json",
|
|
956
|
-
Authorization: `Bearer ${resolveApiKey()}
|
|
957
|
-
...request.idempotencyKey ? { "Idempotency-Key": request.idempotencyKey } : {}
|
|
916
|
+
Authorization: `Bearer ${resolveApiKey()}`
|
|
958
917
|
},
|
|
959
918
|
body: JSON.stringify(body)
|
|
960
919
|
});
|
|
@@ -1340,7 +1299,7 @@ async function companySignals() {
|
|
|
1340
1299
|
].filter(hasFlag);
|
|
1341
1300
|
if (removedControlFlags.length > 0) {
|
|
1342
1301
|
throw new CliInputError(
|
|
1343
|
-
`Company Signals manages provider routing, coverage, and classifications internally; ${removedControlFlags.map((name) => `--${name}`).join(", ")} is no longer supported. Use --domain
|
|
1302
|
+
`Company Signals manages provider routing, coverage, and classifications internally; ${removedControlFlags.map((name) => `--${name}`).join(", ")} is no longer supported. Use --domain and --research-prompt.`
|
|
1344
1303
|
);
|
|
1345
1304
|
}
|
|
1346
1305
|
if (jobId) {
|
|
@@ -1381,16 +1340,17 @@ async function companySignals() {
|
|
|
1381
1340
|
signalRunId: row.signalRunId || row.signal_run_id,
|
|
1382
1341
|
companyDomain: row.companyDomain || row.company_domain || row.domain,
|
|
1383
1342
|
domain: row.domain || row.companyDomain || row.company_domain,
|
|
1343
|
+
researchPrompt: row.researchPrompt || row.research_prompt,
|
|
1384
1344
|
idempotencyKey: row.idempotencyKey || row.idempotency_key
|
|
1385
1345
|
};
|
|
1386
1346
|
});
|
|
1387
1347
|
if (durableBatch) {
|
|
1388
1348
|
const incompatible = requests.some(
|
|
1389
|
-
(request2) => Boolean(stringValue(request2.signalRunId)) || Boolean(stringValue(request2.idempotencyKey)) || !stringValue(request2.domain)
|
|
1349
|
+
(request2) => Boolean(stringValue(request2.signalRunId)) || Boolean(stringValue(request2.idempotencyKey)) || !stringValue(request2.domain) || !stringValue(request2.researchPrompt)
|
|
1390
1350
|
);
|
|
1391
1351
|
if (incompatible) {
|
|
1392
1352
|
throw new CliInputError(
|
|
1393
|
-
"Company Signals batches larger than 25 require domain
|
|
1353
|
+
"Company Signals batches larger than 25 require domain and research_prompt rows without per-row controls or recovery IDs."
|
|
1394
1354
|
);
|
|
1395
1355
|
}
|
|
1396
1356
|
} else if (hasFlag("no-wait") && !hasFlag("dry-run")) {
|
|
@@ -1425,14 +1385,15 @@ async function companySignals() {
|
|
|
1425
1385
|
throw new CliInputError("Company Signals --poll-interval-ms requires --input or --job-id.");
|
|
1426
1386
|
}
|
|
1427
1387
|
const companyDomain = flag("domain") || flag("company-domain");
|
|
1388
|
+
const researchPrompt = flag("research-prompt");
|
|
1428
1389
|
const signalRunId = flag("signal-run-id");
|
|
1429
|
-
if (!companyDomain && !signalRunId) {
|
|
1430
|
-
throw new CliInputError(
|
|
1390
|
+
if ((!companyDomain || !researchPrompt) && !signalRunId) {
|
|
1391
|
+
throw new CliInputError('Usage: signaliz company-signals --domain example.com --research-prompt "Why now?"');
|
|
1431
1392
|
}
|
|
1432
1393
|
const request = {
|
|
1433
1394
|
signalRunId,
|
|
1434
1395
|
domain: companyDomain,
|
|
1435
|
-
|
|
1396
|
+
researchPrompt
|
|
1436
1397
|
};
|
|
1437
1398
|
if (hasFlag("dry-run")) {
|
|
1438
1399
|
const result2 = await createClient().enrichCompanySignals({ ...request, dryRun: true });
|
|
@@ -1492,29 +1453,17 @@ async function signals(args) {
|
|
|
1492
1453
|
if (!query && !signalSearchRunId) {
|
|
1493
1454
|
fail('Usage: signaliz signals "companies that just got funded" [--limit 100] OR signaliz signals --signal-search-run-id run_...');
|
|
1494
1455
|
}
|
|
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");
|
|
1456
|
+
const removedControls = ["icp-context", "sources", "lookback-days", "after-date", "before-date"].filter(hasFlag);
|
|
1457
|
+
if (removedControls.length > 0) {
|
|
1458
|
+
fail(`Signals First accepts only query and --limit; ${removedControls.map((name) => `--${name}`).join(", ")} is no longer supported.`);
|
|
1502
1459
|
}
|
|
1503
1460
|
const request = {
|
|
1504
1461
|
query,
|
|
1505
|
-
icpContext: icpContext?.trim(),
|
|
1506
1462
|
signalSearchRunId,
|
|
1507
|
-
limit: numberFlag("limit")
|
|
1508
|
-
sources: sourceValues,
|
|
1509
|
-
lookbackDays: numberFlag("lookback-days"),
|
|
1510
|
-
afterDate: flag("after-date"),
|
|
1511
|
-
beforeDate: flag("before-date"),
|
|
1512
|
-
idempotencyKey: flag("idempotency-key"),
|
|
1513
|
-
dryRun: hasFlag("dry-run")
|
|
1463
|
+
limit: numberFlag("limit")
|
|
1514
1464
|
};
|
|
1515
|
-
validateSignalDateWindow(request.afterDate, request.beforeDate, request.lookbackDays);
|
|
1516
1465
|
let result = await discoverSignalsEverything(request);
|
|
1517
|
-
if (hasFlag("wait")
|
|
1466
|
+
if (hasFlag("wait")) {
|
|
1518
1467
|
const maxWaitMs = numberFlag("max-wait-ms") ?? 15 * 6e4;
|
|
1519
1468
|
const pollIntervalMs = numberFlag("poll-interval-ms");
|
|
1520
1469
|
const startedAt = Date.now();
|
|
@@ -1674,6 +1623,7 @@ async function signalToCopy() {
|
|
|
1674
1623
|
"lookback-days",
|
|
1675
1624
|
"copy-evidence-mode",
|
|
1676
1625
|
"without-signals",
|
|
1626
|
+
"run-without-signal",
|
|
1677
1627
|
"signal-run-id",
|
|
1678
1628
|
"signal-search-run-id",
|
|
1679
1629
|
"fact-id",
|
|
@@ -1708,10 +1658,9 @@ async function signalToCopy() {
|
|
|
1708
1658
|
personName: row.personName || row.person_name,
|
|
1709
1659
|
title: row.title,
|
|
1710
1660
|
campaignOffer: row.campaignOffer || row.campaign_offer || row.offer,
|
|
1711
|
-
|
|
1661
|
+
runWithoutSignal: row.runWithoutSignal ?? row.run_without_signal ?? yesNoFlag("run-without-signal"),
|
|
1712
1662
|
lookbackDays: 365,
|
|
1713
1663
|
signalRunId: row.signalRunId || row.signal_run_id,
|
|
1714
|
-
signalSearchRunId: row.signalSearchRunId || row.signal_search_run_id,
|
|
1715
1664
|
factId: row.factId || row.fact_id,
|
|
1716
1665
|
eventId: row.eventId || row.event_id,
|
|
1717
1666
|
enableDeepSearch: row.enableDeepSearch ?? row.enable_deep_search ?? hasFlag("deep-search"),
|
|
@@ -1725,7 +1674,7 @@ async function signalToCopy() {
|
|
|
1725
1674
|
}
|
|
1726
1675
|
if (durableBatch) {
|
|
1727
1676
|
const invalidIndex = requests.findIndex(
|
|
1728
|
-
(request2) => Boolean(stringValue(request2.idempotencyKey)) || request2.maxWaitMs !== void 0 || Boolean(stringValue(request2.
|
|
1677
|
+
(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
1678
|
);
|
|
1730
1679
|
if (invalidIndex >= 0) {
|
|
1731
1680
|
throw new CliInputError(
|
|
@@ -1771,10 +1720,9 @@ async function signalToCopy() {
|
|
|
1771
1720
|
personName,
|
|
1772
1721
|
title,
|
|
1773
1722
|
campaignOffer,
|
|
1774
|
-
|
|
1723
|
+
runWithoutSignal: yesNoFlag("run-without-signal"),
|
|
1775
1724
|
lookbackDays: 365,
|
|
1776
1725
|
signalRunId,
|
|
1777
|
-
signalSearchRunId: flag("signal-search-run-id"),
|
|
1778
1726
|
factId: flag("fact-id"),
|
|
1779
1727
|
eventId: flag("event-id"),
|
|
1780
1728
|
enableDeepSearch: hasFlag("deep-search"),
|
|
@@ -1860,102 +1808,31 @@ Import this file into your MCP client.
|
|
|
1860
1808
|
});
|
|
1861
1809
|
}
|
|
1862
1810
|
function awarenessSchedule() {
|
|
1863
|
-
const direct = flag("schedule-cron");
|
|
1864
|
-
if (direct) return direct;
|
|
1865
1811
|
const schedule = flag("schedule");
|
|
1866
1812
|
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");
|
|
1813
|
+
if (!["daily", "weekly", "monthly"].includes(schedule)) {
|
|
1814
|
+
throw new CliInputError("--schedule must be daily, weekly, or monthly");
|
|
1876
1815
|
}
|
|
1877
|
-
return
|
|
1816
|
+
return schedule;
|
|
1817
|
+
}
|
|
1818
|
+
function yesNoFlag(name) {
|
|
1819
|
+
const value = flag(name);
|
|
1820
|
+
if (value === void 0) return void 0;
|
|
1821
|
+
if (value === "yes") return true;
|
|
1822
|
+
if (value === "no") return false;
|
|
1823
|
+
throw new CliInputError(`--${name} must be yes or no`);
|
|
1878
1824
|
}
|
|
1879
1825
|
async function awareness(args) {
|
|
1880
1826
|
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
|
-
];
|
|
1827
|
+
const actions = ["add", "signals", "delete", "schedule"];
|
|
1899
1828
|
if (!action || !actions.includes(action)) {
|
|
1900
1829
|
throw new CliInputError(`Usage: signaliz awareness <${actions.join("|")}>`);
|
|
1901
1830
|
}
|
|
1831
|
+
const domain = flag("domain");
|
|
1832
|
+
if (!domain) throw new CliInputError(`signaliz awareness ${action} requires --domain <company-domain>`);
|
|
1902
1833
|
const client = createClient();
|
|
1903
|
-
if (action === "create") {
|
|
1904
|
-
const companyName = flag("company-name");
|
|
1905
|
-
const domain = flag("domain");
|
|
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
|
-
`));
|
|
1917
|
-
return;
|
|
1918
|
-
}
|
|
1919
|
-
if (action === "import") {
|
|
1920
|
-
const rows = readBatchInput();
|
|
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
|
-
`));
|
|
1937
|
-
return;
|
|
1938
|
-
}
|
|
1939
|
-
if (action === "list") {
|
|
1940
|
-
const offset = numberFlag("offset");
|
|
1941
|
-
const limit = numberFlag("limit");
|
|
1942
|
-
if (limit !== void 0) requireIntegerInRange(limit, "--limit", 1, 500);
|
|
1943
|
-
if (offset !== void 0) requireIntegerInRange(offset, "--offset", 0, 1e4);
|
|
1944
|
-
const result2 = await client.listSignalMonitors(limit, offset);
|
|
1945
|
-
output(result2, () => {
|
|
1946
|
-
for (const monitor of result2.monitors || []) {
|
|
1947
|
-
process.stdout.write(`${String(monitor.company_name)} ${String(monitor.status)} ${String(monitor.next_run_at || "not scheduled")} ${String(monitor.id)}
|
|
1948
|
-
`);
|
|
1949
|
-
}
|
|
1950
|
-
});
|
|
1951
|
-
return;
|
|
1952
|
-
}
|
|
1953
1834
|
if (action === "signals") {
|
|
1954
|
-
const
|
|
1955
|
-
const limit = numberFlag("limit");
|
|
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));
|
|
1835
|
+
const result2 = customerSignalAwarenessResult(await client.listAllSignalAwarenessSignals(domain));
|
|
1959
1836
|
output(result2, () => {
|
|
1960
1837
|
for (const signal of result2.signals || []) {
|
|
1961
1838
|
process.stdout.write(`${signal.signal_type} ${signal.signal_title} ${signal.signal_summary} ${signal.source} ${signal.date} ${signal.company_name} ${signal.domain}
|
|
@@ -1964,81 +1841,22 @@ Skipped: ${result2.skipped || 0}
|
|
|
1964
1841
|
});
|
|
1965
1842
|
return;
|
|
1966
1843
|
}
|
|
1967
|
-
if (action === "
|
|
1968
|
-
const result2 = await client.
|
|
1969
|
-
output(result2, () => process.stdout.write(`
|
|
1970
|
-
Webhook: ${result2.webhookUrl || "not configured"}
|
|
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}
|
|
1844
|
+
if (action === "add") {
|
|
1845
|
+
const result2 = await client.addSignalAwarenessCompany(domain, awarenessSchedule() ?? "daily");
|
|
1846
|
+
output(result2, () => process.stdout.write(`Company added: ${domain}
|
|
1996
1847
|
`));
|
|
1997
1848
|
return;
|
|
1998
1849
|
}
|
|
1999
|
-
if (action === "
|
|
2000
|
-
const
|
|
2001
|
-
if (!
|
|
2002
|
-
|
|
2003
|
-
|
|
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"}
|
|
1850
|
+
if (action === "schedule") {
|
|
1851
|
+
const schedule = awarenessSchedule();
|
|
1852
|
+
if (!schedule) throw new CliInputError("signaliz awareness schedule requires --schedule daily|weekly|monthly");
|
|
1853
|
+
const result2 = await client.changeSignalAwarenessSchedule(domain, schedule);
|
|
1854
|
+
output(result2, () => process.stdout.write(`Schedule updated: ${domain} (${schedule})
|
|
2008
1855
|
`));
|
|
2009
1856
|
return;
|
|
2010
1857
|
}
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
const scheduleCron = awarenessSchedule();
|
|
2014
|
-
const companyName = flag("company-name");
|
|
2015
|
-
const webhookUrl = hasFlag("clear-webhook") ? null : flag("webhook-url");
|
|
2016
|
-
if (action === "schedule" && !scheduleCron) throw new CliInputError("signaliz awareness schedule requires --schedule or --schedule-cron");
|
|
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}
|
|
2022
|
-
`));
|
|
2023
|
-
return;
|
|
2024
|
-
}
|
|
2025
|
-
if (action === "run") {
|
|
2026
|
-
if (hasFlag("dry-run")) {
|
|
2027
|
-
const result3 = await client.signalAwareness({ action: "manual_run", monitorId, idempotencyKey: flag("idempotency-key"), dryRun: true });
|
|
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}
|
|
1858
|
+
const result = await client.deleteSignalAwarenessCompany(domain);
|
|
1859
|
+
output(result, () => process.stdout.write(`Company deleted: ${domain}
|
|
2042
1860
|
`));
|
|
2043
1861
|
}
|
|
2044
1862
|
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.69",
|
|
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.74"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"tsup": "^8.0.0",
|