@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.
Files changed (3) hide show
  1. package/README.md +16 -18
  2. package/dist/bin.js +55 -237
  3. 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/api/v1/company-signals
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 --sources web,news
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 create --company-name "Acme" --domain acme.com --schedule daily
58
- signaliz awareness schedule --monitor-id <uuid> --schedule monthly
59
- signaliz awareness import --input companies.json --schedule weekly
60
- signaliz awareness list --limit 100 --offset 0 --json
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 `signal_search_run_id`, `fact_id`, or `event_id` in
90
- JSON/JSONL rows, and the equivalent `--signal-search-run-id`, `--fact-id`, or
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
- [--signal-search-run-id run_... | --fact-id <sha256> | --event-id <sha256>] \\
34
- [--copy-evidence-mode signal_led|firmographic] [--deep-search] [--max-wait-ms 120000]
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" [--icp-context "..."] [--limit 100] [--sources web,news] [--after-date YYYY-MM-DD --before-date YYYY-MM-DD] [--wait]
40
- signaliz signals-first "companies that just got funded" [--limit 100] [--lookback-days 30] [--wait]
41
- signaliz signals --signal-search-run-id run_... Resume an existing company-attributed signal search
42
- signaliz awareness create --company-name "Acme" --domain acme.com [--schedule daily|weekly|monthly | --schedule-cron "0 8 * * *"]
43
- signaliz awareness import --input companies.json [--schedule daily]
44
- signaliz awareness list [--limit 100] [--offset 0]
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
- --copy-evidence-mode <mode> Use signals, or draft from offer and research context without signal claims
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 accepts only --domain. Signaliz checks its cache, runs one type-agnostic Parallel Advanced search plus at most one first-party hub Extract, and returns the newest distinct events that pass its deterministic date, source, company, evidence, and duplicate gates. For a durable batch larger than 25 rows, provide domain-only rows with --no-wait and resume with --job-id. Signal to Copy canonical references remain separate. Signals First is asynchronous by default; use --wait to poll until it completes.
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
- ...request.icpContext ? { icp_context: request.icpContext } : {},
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 only.`
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-only rows without per-row controls or recovery IDs."
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("Usage: signaliz company-signals --domain example.com");
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
- idempotencyKey: flag("idempotency-key")
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 sourceValues = csvFlag("sources");
1496
- if (sourceValues?.some((source) => !["web", "news"].includes(source))) {
1497
- fail("--sources must contain only web or news");
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") && !request.dryRun) {
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
- copyEvidenceMode: row.copyEvidenceMode || row.copy_evidence_mode || flag("copy-evidence-mode") || (hasFlag("without-signals") ? "firmographic" : void 0),
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.signalSearchRunId)) || Boolean(stringValue(request2.factId)) || Boolean(stringValue(request2.eventId)) || !stringValue(request2.companyDomain) || !stringValue(request2.personName) || !stringValue(request2.title) || !stringValue(request2.campaignOffer)
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
- copyEvidenceMode: flag("copy-evidence-mode") || (hasFlag("without-signals") ? "firmographic" : void 0),
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
- const schedules = {
1868
- every_6_hours: "0 */6 * * *",
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 schedules[schedule];
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 monitorId = flag("monitor-id");
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 offset = numberFlag("offset");
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 === "settings") {
1968
- const result2 = await client.getSignalAwarenessSettings();
1969
- output(result2, () => process.stdout.write(`Output: ${result2.outputMode || "csv"}
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 === "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"}
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
- if (!monitorId) throw new CliInputError(`signaliz awareness ${action} requires --monitor-id <uuid>`);
2012
- if (action === "update" || action === "schedule") {
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.68",
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.72"
32
+ "@signaliz/sdk": "^1.0.74"
33
33
  },
34
34
  "devDependencies": {
35
35
  "tsup": "^8.0.0",