@signaliz/cli 1.0.63 → 1.0.64

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 +45 -24
  2. package/dist/bin.js +700 -269
  3. package/package.json +6 -6
package/dist/bin.js CHANGED
@@ -17,25 +17,35 @@ var CONFIG_DIR = (0, import_node_path.join)((0, import_node_os.homedir)(), ".sig
17
17
  var CONFIG_FILE = (0, import_node_path.join)(CONFIG_DIR, "config.json");
18
18
  var HELP = `Signaliz CLI
19
19
 
20
- Five product commands:
21
- signaliz find-email --linkedin-url https://www.linkedin.com/in/jane-doe [--skip-cache]
22
- signaliz find-email --company-domain example.com --full-name "Jane Doe" [--skip-cache]
20
+ Six product commands:
21
+ signaliz find-email --linkedin-url https://www.linkedin.com/in/jane-doe [--no-wait]
22
+ signaliz find-email --company-domain example.com --full-name "Jane Doe" [--no-wait]
23
23
  signaliz find-email --run-id run_... Resume an existing Find Email run without duplicate spend
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 [--research-prompt "..."] [--search-mode fast|balanced|coverage] [--include-candidate-evidence] [--no-summary] [--max-wait-ms 120000]
27
+ signaliz company-signals --domain example.com
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
- [--lookback-days 90] [--skip-cache] [--deep-search] [--max-wait-ms 120000]
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]
34
35
  signaliz signal-to-copy --signal-run-id copy_... Reuse a completed signal run
35
- signaliz signal-to-copy --input recipients.json --no-wait Submit an available-data-only >25-row batch
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
+ signaliz signal-to-copy --input recipients.json --no-wait Submit a durable >25-row batch
36
38
  signaliz signal-to-copy --job-id job_... Resume an existing Signal to Copy batch without redispatch
37
- signaliz signals "companies that just got funded" [--icp-context "..."] [--limit 100] [--sources web,news] [--wait]
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]
38
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] [--monthly-credit-cap 100]
43
+ signaliz awareness list [--limit 100] [--offset 0]
44
+ signaliz awareness run --monitor-id <uuid> --idempotency-key <key>
45
+ signaliz awareness signals [--monitor-id <uuid>]
46
+ signaliz awareness pause|resume|delete --monitor-id <uuid>
47
+ signaliz flow --signal-query "companies with recent hiring" --campaign-offer "..." [--limit 5] [--lookback-days 90] [--people-titles "CEO,VP Sales"]
48
+ signaliz flow --run-id run_... Read a durable Flow checkpoint without dispatching new work
39
49
 
40
50
  Access and connection:
41
51
  signaliz auth login
@@ -56,12 +66,17 @@ Common flags:
56
66
  --input - Read a JSON array or JSONL batch from stdin
57
67
  --concurrency <1-50> Simultaneous API requests for batch input (default: 10)
58
68
  --idempotency-key <key> Reuse after an ambiguous response to recover the same request or job
69
+ --no-wait Return the durable Find Email run ID immediately; resume with --run-id
70
+ --copy-evidence-mode <mode> Use signals, or draft from offer and research context without signal claims
59
71
  --run-id <run_...> Resume one existing Find Email run without dispatching new work
60
72
  --job-id <job_...> Resume an existing core-product batch without dispatching new work
61
73
  --icp-context <text> Optional ICP, product, or pain context that returned signals must support
74
+ --signal-search-run-id <id> Resume Signals First, or pin its immutable snapshot in Signal to Copy
75
+ --fact-id <sha256> Pin one active canonical signal fact in Signal to Copy
76
+ --event-id <sha256> Pin one canonical signal event in Signal to Copy
62
77
  --dry-run Return a no-spend plan without provider calls, jobs, or writes
63
78
 
64
- Company Signals and Signal to Copy wait by default. For a durable batch larger than 25 rows, use --no-wait to return job_id + idempotency_key immediately, then resume with --job-id. Large Company Signal batches exclude candidate-evidence diagnostics; split --include-candidate-evidence requests into batches of at most 25. Large Signal to Copy batches are available-data-only. Signals Everything is asynchronous by default; use --wait to poll until it completes.
79
+ 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 Everything is asynchronous by default; use --wait to poll until it completes.
65
80
  `;
66
81
  function loadConfig() {
67
82
  if (!(0, import_node_fs.existsSync)(CONFIG_FILE)) return {};
@@ -108,6 +123,25 @@ function requireIntegerInRange(value, name, minimum, maximum) {
108
123
  throw new CliInputError(`${name} must be an integer between ${minimum} and ${maximum}`);
109
124
  }
110
125
  }
126
+ function validateSignalDateWindow(afterDate, beforeDate, lookbackDays, flagPrefix = "--") {
127
+ if ((afterDate || beforeDate) && lookbackDays !== void 0) {
128
+ throw new CliInputError(`${flagPrefix}after-date/--before-date cannot be combined with --lookback-days`);
129
+ }
130
+ const parseDate = (value, name) => {
131
+ if (value === void 0) return void 0;
132
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) throw new CliInputError(`${name} must use YYYY-MM-DD format`);
133
+ const timestamp = Date.parse(`${value}T00:00:00Z`);
134
+ if (!Number.isFinite(timestamp) || new Date(timestamp).toISOString().slice(0, 10) !== value) {
135
+ throw new CliInputError(`${name} must be a valid calendar date`);
136
+ }
137
+ return timestamp;
138
+ };
139
+ const afterTimestamp = parseDate(afterDate, `${flagPrefix}after-date`);
140
+ const beforeTimestamp = parseDate(beforeDate, `${flagPrefix}before-date`);
141
+ if (afterTimestamp !== void 0 && beforeTimestamp !== void 0 && beforeTimestamp < afterTimestamp) {
142
+ throw new CliInputError(`${flagPrefix}before-date must be on or after ${flagPrefix}after-date`);
143
+ }
144
+ }
111
145
  function requireSignalToCopyIdentity(request) {
112
146
  if (stringValue(request.signalRunId)) return;
113
147
  const missing = [
@@ -124,11 +158,6 @@ function csvFlag(name) {
124
158
  const value = flag(name);
125
159
  return value?.split(",").map((item) => item.trim()).filter(Boolean);
126
160
  }
127
- function companySignalSearchMode(value) {
128
- if (value === void 0 || value === null || value === "") return void 0;
129
- if (value === "fast" || value === "balanced" || value === "coverage") return value;
130
- throw new CliInputError("--search-mode must be fast, balanced, or coverage");
131
- }
132
161
  function readBatchInput() {
133
162
  const path = flag("input");
134
163
  if (!path) return null;
@@ -164,6 +193,221 @@ function readBatchInput() {
164
193
  function record(value) {
165
194
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
166
195
  }
196
+ function signalText(value) {
197
+ return typeof value === "string" ? value.trim() : "";
198
+ }
199
+ function signalDate(value) {
200
+ const match = signalText(value).match(/^\d{4}-\d{2}-\d{2}/);
201
+ if (!match) return "";
202
+ const parsed = /* @__PURE__ */ new Date(`${match[0]}T00:00:00.000Z`);
203
+ return Number.isFinite(parsed.getTime()) && parsed.toISOString().slice(0, 10) === match[0] ? match[0] : "";
204
+ }
205
+ function signalClassification(value) {
206
+ const direct = signalText(value);
207
+ if (direct) return direct;
208
+ const classification = record(value);
209
+ return signalText(classification.slug || classification.type || classification.name);
210
+ }
211
+ function publicSignalType(signal) {
212
+ const raw = record(signal.raw_data);
213
+ const generic = /* @__PURE__ */ new Set(["unclassified", "unknown", "other", "news", "signal"]);
214
+ for (const value of [
215
+ signal.signal_type,
216
+ signal.signalType,
217
+ signalClassification(signal.signal_classification || signal.signalClassification),
218
+ signalClassification(signal.classification),
219
+ raw.signal_type,
220
+ raw.signalType,
221
+ signalClassification(raw.signal_classification || raw.signalClassification),
222
+ signalClassification(raw.classification),
223
+ signal.type,
224
+ signal.category,
225
+ signal.event_type,
226
+ raw.type,
227
+ raw.category,
228
+ raw.event_type
229
+ ]) {
230
+ const candidate = signalText(value);
231
+ if (candidate && !generic.has(candidate.toLowerCase())) return candidate;
232
+ }
233
+ return "";
234
+ }
235
+ function verifiedHttpsSource(value) {
236
+ const source = signalText(value);
237
+ if (!source || /\s/.test(source)) return "";
238
+ try {
239
+ const url = new URL(source);
240
+ return url.protocol === "https:" && Boolean(url.hostname) && !url.username && !url.password ? source : "";
241
+ } catch {
242
+ return "";
243
+ }
244
+ }
245
+ function normalizedSignalDomain(value) {
246
+ const normalized = signalText(value).toLowerCase().replace(/^https?:\/\//, "").replace(/^www\./, "").split(/[/?#]/)[0].replace(/\.$/, "");
247
+ return /^(?=.{3,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$/i.test(normalized) ? normalized : "";
248
+ }
249
+ function firstValidSignalValue(values, normalize) {
250
+ for (const value of values) {
251
+ const normalized = normalize(value);
252
+ if (normalized) return normalized;
253
+ }
254
+ return "";
255
+ }
256
+ function publicSignalRow(value, fallbackCompany) {
257
+ const signal = record(value);
258
+ const raw = record(signal.raw_data);
259
+ const company = record(signal.company);
260
+ const rawCompany = record(raw.company);
261
+ const fallback = record(fallbackCompany);
262
+ const row = {
263
+ signal_type: publicSignalType(signal),
264
+ signal_title: firstValidSignalValue([
265
+ signal.signal_title,
266
+ signal.signalTitle,
267
+ raw.signal_title,
268
+ raw.signalTitle,
269
+ signal.title,
270
+ raw.title,
271
+ signal.headline,
272
+ raw.headline,
273
+ signal.name,
274
+ raw.name
275
+ ], signalText),
276
+ signal_summary: firstValidSignalValue([
277
+ signal.signal_summary,
278
+ signal.signalSummary,
279
+ raw.signal_summary,
280
+ raw.signalSummary,
281
+ signal.summary,
282
+ raw.summary,
283
+ signal.signal_content,
284
+ signal.signalContent,
285
+ raw.signal_content,
286
+ raw.signalContent,
287
+ signal.content,
288
+ raw.content,
289
+ signal.description,
290
+ raw.description
291
+ ], signalText),
292
+ source: firstValidSignalValue([
293
+ signal.canonical_source_url,
294
+ signal.canonicalSourceUrl,
295
+ signal.source_url,
296
+ signal.sourceUrl,
297
+ signal.verified_source_url,
298
+ signal.verifiedSourceUrl,
299
+ signal.signal_source,
300
+ signal.signalSource,
301
+ signal.source,
302
+ signal.url,
303
+ raw.canonical_source_url,
304
+ raw.canonicalSourceUrl,
305
+ raw.source_url,
306
+ raw.sourceUrl,
307
+ raw.verified_source_url,
308
+ raw.verifiedSourceUrl,
309
+ raw.signal_source,
310
+ raw.signalSource,
311
+ raw.source,
312
+ raw.url
313
+ ], verifiedHttpsSource),
314
+ date: firstValidSignalValue([
315
+ signal.date,
316
+ signal.event_date,
317
+ signal.eventDate,
318
+ signal.signal_date,
319
+ signal.signalDate,
320
+ signal.published_date,
321
+ signal.publishedDate,
322
+ signal.published_at,
323
+ signal.publishedAt,
324
+ signal.detected_at,
325
+ signal.detectedAt,
326
+ signal.observed_at,
327
+ signal.observedAt,
328
+ raw.date,
329
+ raw.event_date,
330
+ raw.eventDate,
331
+ raw.signal_date,
332
+ raw.signalDate,
333
+ raw.published_date,
334
+ raw.publishedDate,
335
+ raw.published_at,
336
+ raw.publishedAt,
337
+ raw.detected_at,
338
+ raw.detectedAt,
339
+ raw.observed_at,
340
+ raw.observedAt
341
+ ], signalDate),
342
+ company_name: signalText(
343
+ signal.company_name || signal.companyName || company.name || company.company_name || raw.company_name || raw.companyName || rawCompany.name || rawCompany.company_name || fallback.company_name || fallback.companyName || fallback.name
344
+ ),
345
+ domain: firstValidSignalValue([
346
+ signal.company_domain,
347
+ signal.companyDomain,
348
+ signal.domain,
349
+ company.domain,
350
+ company.company_domain,
351
+ raw.company_domain,
352
+ raw.companyDomain,
353
+ raw.domain,
354
+ rawCompany.domain,
355
+ rawCompany.company_domain,
356
+ fallback.company_domain,
357
+ fallback.companyDomain,
358
+ fallback.domain
359
+ ], normalizedSignalDomain)
360
+ };
361
+ return row.signal_type && row.source && row.date && row.company_name && row.domain ? row : null;
362
+ }
363
+ function publicSignalRows(value, fallbackCompany) {
364
+ if (!Array.isArray(value)) return [];
365
+ return value.flatMap((item) => {
366
+ const row = publicSignalRow(item, fallbackCompany);
367
+ return row ? [row] : [];
368
+ });
369
+ }
370
+ function oneSignalPerCompany(rows) {
371
+ const seen = /* @__PURE__ */ new Set();
372
+ return rows.filter((row) => {
373
+ if (seen.has(row.domain)) return false;
374
+ seen.add(row.domain);
375
+ return true;
376
+ });
377
+ }
378
+ var PUBLIC_COMPANY_SIGNAL_MAX_COVERAGE_COUNT = 10;
379
+ function publicCompanySignalRows(value, fallbackCompany) {
380
+ const candidates = Array.isArray(value) ? value : [];
381
+ const seenEvents = /* @__PURE__ */ new Set();
382
+ const rows = [];
383
+ for (const candidate of candidates) {
384
+ const row = publicSignalRow(candidate, fallbackCompany);
385
+ if (!row) continue;
386
+ const signal = record(candidate);
387
+ const raw = record(signal.raw_data);
388
+ const eventId = signalText(
389
+ signal.event_id || signal.eventId || signal.fact_id || signal.factId || raw.event_id || raw.eventId || raw.fact_id || raw.factId
390
+ ).toLowerCase();
391
+ const identities = [
392
+ ...eventId ? [`event:${eventId}`] : [],
393
+ `source:${row.source.toLowerCase()}`
394
+ ];
395
+ if (identities.some((identity) => seenEvents.has(identity))) continue;
396
+ identities.forEach((identity) => seenEvents.add(identity));
397
+ rows.push(row);
398
+ if (rows.length >= PUBLIC_COMPANY_SIGNAL_MAX_COVERAGE_COUNT) break;
399
+ }
400
+ return rows;
401
+ }
402
+ function companySignalOutputRow(signal) {
403
+ return {
404
+ date: signal.date,
405
+ signal_type: signal.signal_type,
406
+ signal_title: signal.signal_title,
407
+ signal_summary: signal.signal_summary,
408
+ source: signal.source
409
+ };
410
+ }
167
411
  function safeNonNegativeNumber(value) {
168
412
  if (value === null || value === void 0 || value === "") return null;
169
413
  const numeric = Number(value);
@@ -173,7 +417,7 @@ function customerEmailBillingMetadata(value) {
173
417
  const source = record(value);
174
418
  const safe = {};
175
419
  if (typeof source.result_returned_from === "string") safe.result_returned_from = source.result_returned_from;
176
- for (const field of ["cache_hit", "fresh_enrichment_used", "live_provider_called", "openrouter_called", "byo_openrouter_used"]) {
420
+ for (const field of ["openrouter_called", "byo_openrouter_used"]) {
177
421
  if (typeof source[field] === "boolean") safe[field] = source[field];
178
422
  }
179
423
  for (const field of ["credits_used", "credits_charged", "estimated_external_cost_usd"]) {
@@ -241,19 +485,10 @@ function customerEmailResult(value, kind) {
241
485
  const historicalBillingMetadata2 = customerEmailBillingMetadata(
242
486
  Object.keys(record(result.historicalBillingMetadata)).length > 0 ? result.historicalBillingMetadata : raw.historical_billing_metadata
243
487
  );
244
- const cacheHit2 = typeof raw.cache_hit === "boolean" ? raw.cache_hit : result.cacheHit === true;
245
- const negativeCacheHit2 = typeof raw.negative_cache_hit === "boolean" ? raw.negative_cache_hit : result.negativeCacheHit === true;
246
- const resultReturnedFrom = result.resultReturnedFrom ?? raw.result_returned_from ?? null;
247
- const freshEnrichmentUsed = typeof raw.fresh_enrichment_used === "boolean" ? raw.fresh_enrichment_used : result.freshEnrichmentUsed === true;
248
- const liveProviderCalled = typeof raw.live_provider_called === "boolean" ? raw.live_provider_called : result.liveProviderCalled === true;
249
488
  const normalizedBillingMetadata = {
250
489
  ...billingMetadata2,
251
- ...resultReturnedFrom ? { result_returned_from: resultReturnedFrom } : {},
252
- cache_hit: cacheHit2,
253
- fresh_enrichment_used: freshEnrichmentUsed,
254
490
  credits_used: base.credits_used,
255
- credits_charged: base.credits_charged,
256
- live_provider_called: liveProviderCalled
491
+ credits_charged: base.credits_charged
257
492
  };
258
493
  const estimatedExternalCostUsd2 = safeNonNegativeNumber(
259
494
  result.estimatedExternalCostUsd ?? raw.estimated_external_cost_usd
@@ -288,15 +523,6 @@ function customerEmailResult(value, kind) {
288
523
  verification_source: result.verificationSource ?? raw.verification_source ?? result.providerUsed ?? "email_finder",
289
524
  ...result.verificationObservedAt ?? raw.verification_observed_at ? { verification_observed_at: result.verificationObservedAt ?? raw.verification_observed_at } : {},
290
525
  failure_reason: result.failureReason ?? raw.failure_reason ?? (verifiedForSending2 ? "none" : "no_verified_email_found"),
291
- cache_hit: cacheHit2,
292
- negative_cache_hit: negativeCacheHit2,
293
- negative_cache_ttl_seconds: safeNonNegativeNumber(
294
- result.negativeCacheTtlSeconds ?? raw.negative_cache_ttl_seconds
295
- ),
296
- cache_tier: result.cacheTier ?? raw.cache_tier ?? null,
297
- result_returned_from: resultReturnedFrom,
298
- fresh_enrichment_used: freshEnrichmentUsed,
299
- live_provider_called: liveProviderCalled,
300
526
  billing_replayed: typeof raw.billing_replayed === "boolean" ? raw.billing_replayed : result.billingReplayed === true,
301
527
  ...typeof raw.idempotency_replayed === "boolean" || typeof result.idempotencyReplayed === "boolean" ? {
302
528
  idempotency_replayed: typeof raw.idempotency_replayed === "boolean" ? raw.idempotency_replayed : result.idempotencyReplayed === true
@@ -309,11 +535,6 @@ function customerEmailResult(value, kind) {
309
535
  recovery_mode: raw.recovery_mode,
310
536
  recovery_status: raw.recovery_status ?? "completed"
311
537
  } : {},
312
- ...raw.cache_publication_status ? {
313
- cache_publication_status: raw.cache_publication_status,
314
- cache_publication_retry_eligible: raw.cache_publication_retry_eligible === true,
315
- ...raw.suggested_action ? { suggested_action: raw.suggested_action } : {}
316
- } : {},
317
538
  ...terminalErrorCode ? {
318
539
  email: null,
319
540
  success: false,
@@ -348,11 +569,6 @@ function customerEmailResult(value, kind) {
348
569
  const isMalformed = typeof result.isMalformed === "boolean" ? result.isMalformed : raw.is_malformed === true;
349
570
  const quality = typeof result.quality === "string" ? result.quality : typeof raw.quality === "string" ? raw.quality : null;
350
571
  const recommendation = typeof result.recommendation === "string" ? result.recommendation : typeof raw.recommendation === "string" ? raw.recommendation : verifiedForSending ? "send" : ["unknown", "verifier_error"].includes(verificationStatus) ? "manual_review" : "do_not_send";
351
- const cacheHit = typeof raw.cache_hit === "boolean" ? raw.cache_hit : result.cacheHit === true;
352
- const negativeCacheHit = typeof raw.negative_cache_hit === "boolean" ? raw.negative_cache_hit : result.negativeCacheHit === true;
353
- const negativeCacheTtlSeconds = safeNonNegativeNumber(
354
- result.negativeCacheTtlSeconds ?? raw.negative_cache_ttl_seconds
355
- );
356
572
  const billingMetadata = customerEmailBillingMetadata(
357
573
  Object.keys(record(result.billingMetadata)).length > 0 ? result.billingMetadata : raw.billing_metadata
358
574
  );
@@ -382,13 +598,6 @@ function customerEmailResult(value, kind) {
382
598
  verification_source: result.verificationSource ?? raw.verification_source ?? "email_verification",
383
599
  ...result.verificationObservedAt ?? raw.verification_observed_at ? { verification_observed_at: result.verificationObservedAt ?? raw.verification_observed_at } : {},
384
600
  failure_reason: result.failureReason ?? raw.failure_reason ?? (verifiedForSending ? "none" : isCatchAll ? "catch_all_domain_not_send_safe" : "verification_not_send_safe"),
385
- cache_hit: cacheHit,
386
- negative_cache_hit: negativeCacheHit,
387
- negative_cache_ttl_seconds: negativeCacheTtlSeconds,
388
- cache_tier: result.cacheTier ?? raw.cache_tier ?? null,
389
- result_returned_from: result.resultReturnedFrom ?? raw.result_returned_from ?? null,
390
- fresh_enrichment_used: typeof raw.fresh_enrichment_used === "boolean" ? raw.fresh_enrichment_used : result.freshEnrichmentUsed === true,
391
- live_provider_called: typeof raw.live_provider_called === "boolean" ? raw.live_provider_called : result.liveProviderCalled === true,
392
601
  billing_replayed: typeof raw.billing_replayed === "boolean" ? raw.billing_replayed : result.billingReplayed === true,
393
602
  ...typeof raw.idempotency_replayed === "boolean" || typeof result.idempotencyReplayed === "boolean" ? {
394
603
  idempotency_replayed: typeof raw.idempotency_replayed === "boolean" ? raw.idempotency_replayed : result.idempotencyReplayed === true
@@ -397,12 +606,7 @@ function customerEmailResult(value, kind) {
397
606
  ...Object.keys(historicalBillingMetadata).length > 0 ? { historical_billing_metadata: historicalBillingMetadata } : {},
398
607
  ...estimatedExternalCostUsd !== null ? { estimated_external_cost_usd: estimatedExternalCostUsd } : {},
399
608
  ...verificationRunId ? { verification_run_id: verificationRunId } : {},
400
- ...runId ? { run_id: runId } : {},
401
- ...raw.cache_publication_status ? {
402
- cache_publication_status: raw.cache_publication_status,
403
- cache_publication_retry_eligible: raw.cache_publication_retry_eligible === true,
404
- ...raw.suggested_action ? { suggested_action: raw.suggested_action } : {}
405
- } : {}
609
+ ...runId ? { run_id: runId } : {}
406
610
  };
407
611
  }
408
612
  function customerEmailBatch(value, kind) {
@@ -430,15 +634,39 @@ function customerSignalResult(value) {
430
634
  return {
431
635
  ...result,
432
636
  ...Object.keys(billingMetadata).length > 0 ? { billingMetadata } : {},
433
- resultReturnedFrom: result.resultReturnedFrom ?? raw.result_returned_from,
434
- cacheHit: result.cacheHit ?? raw.cache_hit,
435
- freshEnrichmentUsed: result.freshEnrichmentUsed ?? raw.fresh_enrichment_used,
436
637
  creditsUsed: result.creditsUsed ?? raw.credits_used,
437
- liveProviderCalled: result.liveProviderCalled ?? raw.live_provider_called,
438
638
  aiProviderCalled: result.aiProviderCalled ?? raw.ai_provider_called,
439
639
  byoAiUsed: result.byoAiUsed ?? raw.byo_ai_used
440
640
  };
441
641
  }
642
+ function customerCompanySignalResult(value) {
643
+ const result = record(value);
644
+ const raw = record(result.raw);
645
+ const company = record(result.company);
646
+ const rawCompany = record(raw.company);
647
+ const normalizedCompany = {
648
+ name: signalText(result.companyName || result.company_name || company.name || raw.company_name || rawCompany.name) || null,
649
+ domain: normalizedSignalDomain(
650
+ result.companyDomain || result.company_domain || result.domain || company.domain || raw.company_domain || raw.domain || rawCompany.domain
651
+ ) || null
652
+ };
653
+ const rawSignals = Array.isArray(raw.signals) ? raw.signals : Array.isArray(raw.signal_feed) ? raw.signal_feed : result.signals;
654
+ const signals2 = publicCompanySignalRows(rawSignals, normalizedCompany).map(companySignalOutputRow);
655
+ const {
656
+ raw: _raw,
657
+ signals: _signals,
658
+ signalCount: _signalCount,
659
+ company: _company,
660
+ ...publicResult
661
+ } = result;
662
+ return {
663
+ ...publicResult,
664
+ company: normalizedCompany,
665
+ signals: signals2,
666
+ signalCount: signals2.length,
667
+ creditsUsed: result.creditsUsed ?? raw.credits_used
668
+ };
669
+ }
442
670
  function customerSignalBatch(value) {
443
671
  return {
444
672
  ...value,
@@ -448,6 +676,31 @@ function customerSignalBatch(value) {
448
676
  })
449
677
  };
450
678
  }
679
+ function customerCompanySignalBatch(value) {
680
+ const batch = record(value);
681
+ const { raw: _raw, results: _results, ...publicBatch } = batch;
682
+ const results = Array.isArray(batch.results) ? batch.results.map((item) => {
683
+ const row = record(item);
684
+ const { raw: _rowRaw, ...publicRow } = row;
685
+ if (row.data) {
686
+ return promoteBatchRecoveryMetadata({ ...publicRow, data: customerCompanySignalResult(row.data) });
687
+ }
688
+ if (Array.isArray(row.signals) || row.company) {
689
+ return promoteBatchRecoveryMetadata(customerCompanySignalResult(publicRow));
690
+ }
691
+ return promoteBatchRecoveryMetadata(publicRow);
692
+ }) : [];
693
+ return { ...publicBatch, results };
694
+ }
695
+ function customerSignalAwarenessResult(value) {
696
+ const result = record(value);
697
+ const { raw: _raw, signals: _signals, ...publicResult } = result;
698
+ const signals2 = Array.isArray(result.signals) ? oneSignalPerCompany(publicSignalRows(result.signals)) : void 0;
699
+ return {
700
+ ...publicResult,
701
+ ...signals2 ? { signals: signals2 } : {}
702
+ };
703
+ }
451
704
  function batchOptions() {
452
705
  return {
453
706
  concurrency: numberFlag("concurrency"),
@@ -553,12 +806,40 @@ function numberValue(value) {
553
806
  const number = Number(value);
554
807
  return Number.isFinite(number) ? number : void 0;
555
808
  }
556
- function nullableNumberValue(value) {
557
- return value === null ? null : numberValue(value);
558
- }
559
809
  function stringValue(value) {
560
810
  return typeof value === "string" ? value.trim() : "";
561
811
  }
812
+ function publicSignalDiscoveryFailure(value) {
813
+ const requestedCode = stringValue(value).toUpperCase();
814
+ if (requestedCode === "NO_QUALIFIED_SIGNALS") {
815
+ return {
816
+ errorCode: requestedCode,
817
+ error: "No company signal met the dated-evidence, company-identity, and query requirements."
818
+ };
819
+ }
820
+ if (requestedCode === "SOURCE_EMPTY") {
821
+ return {
822
+ errorCode: requestedCode,
823
+ error: "The selected source lanes returned no candidates for this query and time window."
824
+ };
825
+ }
826
+ if (requestedCode === "IDEMPOTENCY_CONFLICT") {
827
+ return {
828
+ errorCode: requestedCode,
829
+ error: "This recovery key belongs to a different Signals Everything request."
830
+ };
831
+ }
832
+ if (requestedCode === "PERSISTENCE_UNAVAILABLE") {
833
+ return {
834
+ errorCode: requestedCode,
835
+ error: "The result is still being finalized. Retry with the same signal search run ID."
836
+ };
837
+ }
838
+ return {
839
+ errorCode: "SOURCE_UNAVAILABLE",
840
+ error: "Signals Everything could not complete this search."
841
+ };
842
+ }
562
843
  function hasFindEmailLinkedInIdentity(value) {
563
844
  const linkedinUrl = stringValue(value);
564
845
  if (!linkedinUrl) return false;
@@ -582,35 +863,11 @@ function signalsEverythingErrorType(status) {
582
863
  }
583
864
  function normalizeSignalsEverythingResult(request, value) {
584
865
  const rawSignals = Array.isArray(value.signals) ? value.signals : [];
585
- const signals2 = rawSignals.map((rawSignal) => {
586
- const signal = record(rawSignal);
587
- const company = record(signal.company);
588
- const name = stringValue(company.name || signal.company_name);
589
- const domain = stringValue(company.domain || signal.company_domain);
590
- if (!name || !domain) {
591
- throw new Error("Signals Everything response violated the company attribution contract.");
592
- }
593
- const evidence = Array.isArray(signal.evidence) ? signal.evidence.map((rawEvidence) => {
594
- const item = record(rawEvidence);
595
- return {
596
- url: stringValue(item.url),
597
- publishedAt: stringValue(item.published_at || item.publishedAt),
598
- source: stringValue(item.source)
599
- };
600
- }).filter((item) => Boolean(item.url)) : [];
601
- const eventDate = stringValue(signal.event_date || signal.date);
602
- const sourceUrl = stringValue(signal.source_url || signal.url);
603
- if (!eventDate || !sourceUrl || !evidence.some((item) => item.url === sourceUrl && item.publishedAt === eventDate)) {
604
- throw new Error("Signals Everything response violated the dated-evidence and source-URL contract.");
605
- }
606
- return {
607
- company: { name, domain },
608
- title: stringValue(signal.title || signal.summary || signal.content),
609
- eventDate,
610
- sourceUrl,
611
- evidence
612
- };
613
- });
866
+ const requestedCount = numberValue(value.requested_count) ?? request.limit;
867
+ const signals2 = oneSignalPerCompany(publicSignalRows(rawSignals)).slice(
868
+ 0,
869
+ requestedCount !== void 0 && requestedCount > 0 ? requestedCount : void 0
870
+ );
614
871
  const statusValue = stringValue(value.status).toLowerCase();
615
872
  const statuses = /* @__PURE__ */ new Set([
616
873
  "planned",
@@ -621,52 +878,24 @@ function normalizeSignalsEverythingResult(request, value) {
621
878
  "failed"
622
879
  ]);
623
880
  const status = statuses.has(statusValue) ? statusValue : signals2.length > 0 ? "completed" : "failed";
624
- const guardrail = record(value.cost_guardrail);
625
- const maxCost = numberValue(guardrail.max_cost_per_qualified_signal_usd);
626
- const costSource = stringValue(guardrail.cost_source);
627
- const identityCostSource = stringValue(guardrail.identity_cost_source);
628
- const warnings = Array.isArray(value.warnings) ? value.warnings.filter((warning) => typeof warning === "string") : void 0;
881
+ const error = record(value.error);
882
+ const hasFailure = value.success === false || Boolean(stringValue(value.error_code || error.code));
883
+ const publicFailure = hasFailure ? publicSignalDiscoveryFailure(value.error_code || error.code) : void 0;
629
884
  return {
630
885
  success: value.success !== false,
631
886
  status,
632
887
  signalSearchRunId: stringValue(value.signal_search_run_id || request.signalSearchRunId),
633
888
  query: stringValue(value.query || request.query),
634
- requestedCount: numberValue(value.requested_count) ?? request.limit ?? 100,
889
+ ...requestedCount === void 0 ? {} : { requestedCount },
635
890
  nextPollAfterSeconds: numberValue(value.next_poll_after_seconds),
636
891
  signals: signals2,
637
892
  signalCount: signals2.length,
638
- ...numberValue(value.available_company_signal_count) === void 0 ? {} : {
639
- availableCompanySignalCount: numberValue(value.available_company_signal_count)
640
- },
641
- ...maxCost === void 0 ? {} : {
642
- costGuardrail: {
643
- maxCostPerQualifiedSignalUsd: maxCost,
644
- projectedSourceCostUsd: nullableNumberValue(guardrail.projected_source_cost_usd),
645
- maxSourceCostUsd: nullableNumberValue(guardrail.max_source_cost_usd),
646
- projectedCostPerRequestedCompanySignalUsd: nullableNumberValue(
647
- guardrail.projected_cost_per_requested_company_signal_usd
648
- ),
649
- sourceCostUsd: nullableNumberValue(guardrail.source_cost_usd),
650
- costSource: ["observed", "catalog_preflight", "catalog_bounded", "mixed", "unavailable"].includes(costSource) ? costSource : void 0,
651
- costPerQualifiedSignalUsd: nullableNumberValue(guardrail.cost_per_qualified_signal_usd),
652
- identityResolutionCostUsd: nullableNumberValue(guardrail.identity_resolution_cost_usd),
653
- identityCostSource: [
654
- "observed_zero_credit_receipts",
655
- "contractual_zero_cost",
656
- "not_used",
657
- "unavailable"
658
- ].includes(identityCostSource) ? identityCostSource : void 0,
659
- identityProviderRequests: numberValue(guardrail.identity_provider_requests),
660
- qualifiedCompanySignalCount: numberValue(guardrail.qualified_company_signal_count),
661
- returnedCompanySignalCount: numberValue(guardrail.returned_company_signal_count),
662
- availableCompanySignalCount: numberValue(guardrail.available_company_signal_count),
663
- acquisitionCandidateLimit: numberValue(guardrail.acquisition_candidate_limit),
664
- minimumQualifiedCompanySignals: numberValue(guardrail.minimum_qualified_company_signals),
665
- withinLimit: guardrail.within_limit === true
666
- }
667
- },
668
- ...warnings?.length ? { warnings } : {},
669
- raw: value
893
+ creditsUsed: numberValue(value.credits_used) ?? 0,
894
+ creditsCharged: numberValue(value.credits_charged) ?? 0,
895
+ ...value.billing_status === "included" ? { billingStatus: "included" } : {},
896
+ ...typeof value.idempotency_replayed === "boolean" ? { idempotencyReplayed: value.idempotency_replayed } : {},
897
+ ...publicFailure ? publicFailure : {},
898
+ ...typeof value.retry_eligible === "boolean" ? { retryEligible: value.retry_eligible } : {}
670
899
  };
671
900
  }
672
901
  async function discoverSignalsEverything(request) {
@@ -681,6 +910,8 @@ async function discoverSignalsEverything(request) {
681
910
  limit: request.limit ?? 100,
682
911
  ...request.sources ? { sources: request.sources } : {},
683
912
  ...request.lookbackDays === void 0 ? {} : { lookback_days: request.lookbackDays },
913
+ ...request.afterDate ? { after_date: request.afterDate } : {},
914
+ ...request.beforeDate ? { before_date: request.beforeDate } : {},
684
915
  ...request.dryRun === void 0 ? {} : { dry_run: request.dryRun },
685
916
  ...request.idempotencyKey ? { idempotency_key: request.idempotencyKey } : {}
686
917
  };
@@ -697,14 +928,19 @@ async function discoverSignalsEverything(request) {
697
928
  const responseBody = record(responseValue);
698
929
  if (!response.ok) {
699
930
  const error = record(responseBody.error);
700
- const code = stringValue(error.code || responseBody.error_code) || `HTTP_${response.status}`;
701
- const message = stringValue(error.message || responseBody.message || responseBody.error) || `Signals Everything request failed with status ${response.status}`;
931
+ const publicFailure = publicSignalDiscoveryFailure(
932
+ error.code || responseBody.error_code || `HTTP_${response.status}`
933
+ );
702
934
  throw new import_sdk.SignalizError({
703
- code,
704
- message,
935
+ code: publicFailure.errorCode,
936
+ message: publicFailure.error,
705
937
  errorType: signalsEverythingErrorType(response.status),
706
938
  retryAfter: numberValue(responseBody.retry_after_seconds || responseBody.retry_after),
707
- details: responseBody
939
+ details: normalizeSignalsEverythingResult(request, {
940
+ ...responseBody,
941
+ success: false,
942
+ error_code: publicFailure.errorCode
943
+ })
708
944
  });
709
945
  }
710
946
  return normalizeSignalsEverythingResult(request, responseBody);
@@ -716,10 +952,39 @@ function output(value, human) {
716
952
  } else if (human) {
717
953
  human();
718
954
  } else {
719
- process.stdout.write(`${JSON.stringify(value, null, 2)}
955
+ process.stdout.write(`${JSON.stringify(publicCliValue(value), null, 2)}
720
956
  `);
721
957
  }
722
958
  }
959
+ var INTERNAL_PRODUCT_OUTPUT_KEYS = /* @__PURE__ */ new Set([
960
+ "billingmetadata",
961
+ "historicalbillingmetadata",
962
+ "resultreturnedfrom",
963
+ "freshenrichmentused",
964
+ "liveprovidercalled",
965
+ "openroutercalled",
966
+ "byoopenrouterused",
967
+ "aiprovidercalled",
968
+ "byoaiused",
969
+ "estimatedexternalcostusd"
970
+ ]);
971
+ function publicCliValue(value) {
972
+ if (Array.isArray(value)) return value.map(publicCliValue);
973
+ if (!value || typeof value !== "object") return value;
974
+ const output2 = {};
975
+ for (const [key, raw] of Object.entries(value)) {
976
+ const normalizedKey = key.toLowerCase().replace(/_/g, "");
977
+ if (normalizedKey.includes("cache") || INTERNAL_PRODUCT_OUTPUT_KEYS.has(normalizedKey)) continue;
978
+ if (typeof raw === "string" && (raw.toLowerCase().includes("cache") || raw === "available_data")) {
979
+ if (["source", "emailsource", "emailsourcelabel", "verificationsource", "providerstatus"].includes(normalizedKey)) {
980
+ output2[key] = normalizedKey === "verificationsource" ? "email_verification" : "email_finder";
981
+ }
982
+ continue;
983
+ }
984
+ output2[key] = publicCliValue(raw);
985
+ }
986
+ return output2;
987
+ }
723
988
  function outputFailedCoreProduct(value, fallbackMessage) {
724
989
  const result = record(value);
725
990
  if (result.success !== false) return false;
@@ -733,7 +998,7 @@ function outputFailedCoreProduct(value, fallbackMessage) {
733
998
  }
734
999
  function stringifyMachineJson(value, space) {
735
1000
  const omitRaw = hasFlag("omit-raw");
736
- return JSON.stringify(value, omitRaw ? (key, item) => key === "raw" ? void 0 : item : void 0, space);
1001
+ return JSON.stringify(publicCliValue(value), omitRaw ? (key, item) => key === "raw" ? void 0 : item : void 0, space);
737
1002
  }
738
1003
  function fail(message) {
739
1004
  process.stderr.write(`${message}
@@ -814,7 +1079,7 @@ async function findEmail() {
814
1079
  "linkedin-url",
815
1080
  "company-name",
816
1081
  "run-id",
817
- "skip-cache"
1082
+ "no-wait"
818
1083
  ].filter(hasFlag);
819
1084
  if (conflicts.length > 0) {
820
1085
  throw new CliInputError(
@@ -833,6 +1098,9 @@ async function findEmail() {
833
1098
  }
834
1099
  const rows = readBatchInput();
835
1100
  if (rows) {
1101
+ if (hasFlag("no-wait")) {
1102
+ throw new CliInputError("Find Email --no-wait supports one contact. Batch submissions are already durable and return a recoverable job.");
1103
+ }
836
1104
  const requests = rows.map((value) => {
837
1105
  const row = record(value);
838
1106
  const runId2 = row.runId || row.run_id;
@@ -845,7 +1113,6 @@ async function findEmail() {
845
1113
  lastName: row.lastName || row.last_name,
846
1114
  linkedinUrl: row.linkedinUrl || row.linkedin_url || row.linkedin,
847
1115
  companyName: row.companyName || row.company_name,
848
- skipCache: row.skipCache ?? row.skip_cache ?? hasFlag("skip-cache"),
849
1116
  idempotencyKey
850
1117
  };
851
1118
  });
@@ -884,7 +1151,7 @@ async function findEmail() {
884
1151
  lastName,
885
1152
  linkedinUrl,
886
1153
  companyName: flag("company-name"),
887
- skipCache: hasFlag("skip-cache"),
1154
+ waitForResult: hasFlag("no-wait") ? false : void 0,
888
1155
  idempotencyKey: flag("idempotency-key")
889
1156
  };
890
1157
  if (hasFlag("dry-run")) {
@@ -924,7 +1191,6 @@ async function verifyEmail(args) {
924
1191
  "dry-run",
925
1192
  "email",
926
1193
  "verification-run-id",
927
- "skip-cache",
928
1194
  "no-wait"
929
1195
  ].filter(hasFlag);
930
1196
  if (positionalEmail || conflicts.length > 0) {
@@ -951,22 +1217,19 @@ async function verifyEmail(args) {
951
1217
  const row = record(value);
952
1218
  return {
953
1219
  email: String(row.email || ""),
954
- skipCache: row.skipCache ?? row.skip_cache ?? hasFlag("skip-cache"),
955
1220
  idempotencyKey: row.idempotencyKey || row.idempotency_key
956
1221
  };
957
1222
  });
958
1223
  if (hasFlag("dry-run")) {
959
1224
  const result3 = await createClient().verifyEmails(emails, {
960
1225
  ...batchOptions(),
961
- skipCache: hasFlag("skip-cache"),
962
1226
  dryRun: true
963
1227
  });
964
1228
  dryRunOutput(result3);
965
1229
  return;
966
1230
  }
967
1231
  const result2 = await createClient().verifyEmails(emails, {
968
- ...batchOptions(),
969
- skipCache: hasFlag("skip-cache")
1232
+ ...batchOptions()
970
1233
  });
971
1234
  batchOutput(customerEmailBatch(result2, "verify"));
972
1235
  return;
@@ -977,7 +1240,6 @@ async function verifyEmail(args) {
977
1240
  throw new CliInputError("Usage: signaliz verify-email [jane@example.com] [--verification-run-id run_...]");
978
1241
  }
979
1242
  const options = {
980
- skipCache: hasFlag("skip-cache"),
981
1243
  verificationRunId,
982
1244
  waitForResult: !hasFlag("no-wait"),
983
1245
  maxWaitMs: numberFlag("max-wait-ms"),
@@ -1012,7 +1274,7 @@ async function verifyEmail(args) {
1012
1274
  `);
1013
1275
  process.stdout.write(`Recommendation: ${publicResult.recommendation}
1014
1276
  `);
1015
- process.stdout.write(`Source: ${publicResult.verification_source}${publicResult.cache_hit === true ? " (cache)" : ""}
1277
+ process.stdout.write(`Source: ${String(publicResult.verification_source || "email_verification").toLowerCase().includes("cache") ? "email_verification" : publicResult.verification_source}
1016
1278
  `);
1017
1279
  if (publicResult.run_id) process.stdout.write(`Run ID: ${publicResult.run_id}
1018
1280
  `);
@@ -1022,6 +1284,39 @@ async function verifyEmail(args) {
1022
1284
  }
1023
1285
  async function companySignals() {
1024
1286
  const jobId = flag("job-id");
1287
+ const removedControlFlags = [
1288
+ "prompt",
1289
+ "signal-types",
1290
+ "after-date",
1291
+ "before-date",
1292
+ "include-candidate-evidence",
1293
+ "search-mode",
1294
+ "model",
1295
+ "online",
1296
+ "offline",
1297
+ "shallow",
1298
+ "deep-search",
1299
+ "enable-deep-search",
1300
+ "no-summary",
1301
+ "outreach-intelligence",
1302
+ "predictive-intelligence",
1303
+ "credit-free-grounding-only",
1304
+ "skip-cache",
1305
+ "bypass-cache",
1306
+ "fresh-only",
1307
+ "cache-ttl-hours",
1308
+ "cache-ttl-seconds",
1309
+ "cache-enabled",
1310
+ "cache-policy",
1311
+ "target-signal-count",
1312
+ "provider-target-signal-count",
1313
+ ...jobId ? [] : ["max-wait-ms"]
1314
+ ].filter(hasFlag);
1315
+ if (removedControlFlags.length > 0) {
1316
+ throw new CliInputError(
1317
+ `Company Signals manages provider routing, coverage, and classifications internally; ${removedControlFlags.map((name) => `--${name}`).join(", ")} is no longer supported. Use --domain only.`
1318
+ );
1319
+ }
1025
1320
  if (jobId) {
1026
1321
  const conflicts = [
1027
1322
  "input",
@@ -1031,18 +1326,7 @@ async function companySignals() {
1031
1326
  "company-name",
1032
1327
  "signal-run-id",
1033
1328
  "research-prompt",
1034
- "prompt",
1035
- "signal-types",
1036
- "target-signal-count",
1037
1329
  "lookback-days",
1038
- "offline",
1039
- "shallow",
1040
- "search-mode",
1041
- "no-summary",
1042
- "outreach-intelligence",
1043
- "predictive-intelligence",
1044
- "skip-cache",
1045
- "include-candidate-evidence",
1046
1330
  "no-wait",
1047
1331
  "concurrency"
1048
1332
  ].filter(hasFlag);
@@ -1058,7 +1342,7 @@ async function companySignals() {
1058
1342
  idempotencyKey: flag("idempotency-key"),
1059
1343
  compactDuplicates: !hasFlag("expand-duplicates")
1060
1344
  });
1061
- batchOutput(customerSignalBatch(result2));
1345
+ batchOutput(customerCompanySignalBatch(result2));
1062
1346
  return;
1063
1347
  }
1064
1348
  rejectDurableNoWaitPollingFlags("Company Signals");
@@ -1067,59 +1351,20 @@ async function companySignals() {
1067
1351
  const durableBatch = rows.length > 25;
1068
1352
  const requests = rows.map((value) => {
1069
1353
  const row = record(value);
1070
- const online = row.online ?? !hasFlag("offline");
1071
1354
  return {
1072
1355
  signalRunId: row.signalRunId || row.signal_run_id,
1073
1356
  companyDomain: row.companyDomain || row.company_domain || row.domain,
1074
- companyName: row.companyName || row.company_name || row.name,
1075
- researchPrompt: row.researchPrompt || row.research_prompt || flag("research-prompt") || flag("prompt"),
1076
- signalTypes: row.signalTypes || row.signal_types || csvFlag("signal-types"),
1077
- targetSignalCount: row.targetSignalCount ?? row.target_signal_count ?? numberFlag("target-signal-count"),
1078
- lookbackDays: row.lookbackDays ?? row.lookback_days ?? numberFlag("lookback-days"),
1079
- online,
1080
- enableDeepSearch: row.enableDeepSearch ?? row.enable_deep_search ?? (online && !hasFlag("shallow")),
1081
- searchMode: companySignalSearchMode(row.searchMode ?? row.search_mode ?? flag("search-mode")),
1082
- includeSummary: row.includeSummary ?? row.include_summary ?? !hasFlag("no-summary"),
1083
- enableOutreachIntelligence: row.enableOutreachIntelligence ?? row.enable_outreach_intelligence,
1084
- enablePredictiveIntelligence: row.enablePredictiveIntelligence ?? row.enable_predictive_intelligence,
1085
- skipCache: row.skipCache ?? row.skip_cache ?? hasFlag("skip-cache"),
1086
- includeCandidateEvidence: row.includeCandidateEvidence ?? row.include_candidate_evidence ?? hasFlag("include-candidate-evidence"),
1087
- maxWaitMs: row.maxWaitMs ?? row.max_wait_ms ?? (durableBatch ? void 0 : numberFlag("max-wait-ms")),
1357
+ domain: row.domain || row.companyDomain || row.company_domain,
1088
1358
  idempotencyKey: row.idempotencyKey || row.idempotency_key
1089
1359
  };
1090
1360
  });
1091
- for (const request2 of requests) {
1092
- requireIntegerInRange(request2.targetSignalCount, "targetSignalCount", 1, 15);
1093
- requireIntegerInRange(request2.lookbackDays, "lookbackDays", 1, 365);
1094
- requireIntegerInRange(request2.maxWaitMs, "maxWaitMs", 1e4, 12e4);
1095
- }
1096
- if (durableBatch && requests.some((request2) => request2.includeCandidateEvidence === true)) {
1097
- throw new CliInputError(
1098
- "includeCandidateEvidence is not supported in Company Signals batches larger than 25 because rejected evidence diagnostics are intentionally excluded from durable scale storage; split diagnostic requests into batches of at most 25."
1099
- );
1100
- }
1101
1361
  if (durableBatch) {
1102
- const controlKey = (request2) => JSON.stringify({
1103
- researchPrompt: request2.researchPrompt,
1104
- signalTypes: request2.signalTypes,
1105
- targetSignalCount: request2.targetSignalCount,
1106
- lookbackDays: request2.lookbackDays,
1107
- online: request2.online,
1108
- enableDeepSearch: request2.enableDeepSearch,
1109
- searchMode: request2.searchMode ?? "balanced",
1110
- includeSummary: request2.includeSummary,
1111
- enableOutreachIntelligence: request2.enableOutreachIntelligence,
1112
- enablePredictiveIntelligence: request2.enablePredictiveIntelligence,
1113
- skipCache: request2.skipCache,
1114
- includeCandidateEvidence: request2.includeCandidateEvidence
1115
- });
1116
- const firstControlKey = controlKey(requests[0]);
1117
1362
  const incompatible = requests.some(
1118
- (request2) => Boolean(stringValue(request2.signalRunId)) || Boolean(stringValue(request2.idempotencyKey)) || !stringValue(request2.companyDomain) && !stringValue(request2.companyName) || controlKey(request2) !== firstControlKey
1363
+ (request2) => Boolean(stringValue(request2.signalRunId)) || Boolean(stringValue(request2.idempotencyKey)) || !stringValue(request2.domain)
1119
1364
  );
1120
1365
  if (incompatible) {
1121
1366
  throw new CliInputError(
1122
- "Company Signals batches larger than 25 require homogeneous new-enrichment rows with company identity only and uniform controls; split recovery or mixed-control rows into batches of at most 25."
1367
+ "Company Signals batches larger than 25 require domain-only rows without per-row controls or recovery IDs."
1123
1368
  );
1124
1369
  }
1125
1370
  } else if (hasFlag("no-wait") && !hasFlag("dry-run")) {
@@ -1144,7 +1389,7 @@ async function companySignals() {
1144
1389
  return;
1145
1390
  }
1146
1391
  const result2 = await createClient().enrichCompanies(requests, batchOptions());
1147
- batchOutput(customerSignalBatch(result2));
1392
+ batchOutput(customerCompanySignalBatch(result2));
1148
1393
  return;
1149
1394
  }
1150
1395
  if (hasFlag("no-wait")) {
@@ -1154,49 +1399,30 @@ async function companySignals() {
1154
1399
  throw new CliInputError("Company Signals --poll-interval-ms requires --input or --job-id.");
1155
1400
  }
1156
1401
  const companyDomain = flag("domain") || flag("company-domain");
1157
- const companyName = flag("company-name");
1158
1402
  const signalRunId = flag("signal-run-id");
1159
- if (!companyDomain && !companyName && !signalRunId) {
1403
+ if (!companyDomain && !signalRunId) {
1160
1404
  throw new CliInputError("Usage: signaliz company-signals --domain example.com");
1161
1405
  }
1162
1406
  const request = {
1163
1407
  signalRunId,
1164
- companyDomain,
1165
- companyName,
1166
- researchPrompt: flag("research-prompt") || flag("prompt"),
1167
- signalTypes: csvFlag("signal-types"),
1168
- targetSignalCount: numberFlag("target-signal-count"),
1169
- lookbackDays: numberFlag("lookback-days"),
1170
- online: !hasFlag("offline"),
1171
- enableDeepSearch: !hasFlag("offline") && !hasFlag("shallow"),
1172
- searchMode: companySignalSearchMode(flag("search-mode")),
1173
- includeSummary: !hasFlag("no-summary"),
1174
- enableOutreachIntelligence: hasFlag("outreach-intelligence") || void 0,
1175
- enablePredictiveIntelligence: hasFlag("predictive-intelligence") || void 0,
1176
- skipCache: hasFlag("skip-cache"),
1177
- includeCandidateEvidence: hasFlag("include-candidate-evidence"),
1178
- maxWaitMs: numberFlag("max-wait-ms"),
1408
+ domain: companyDomain,
1179
1409
  idempotencyKey: flag("idempotency-key")
1180
1410
  };
1181
- requireIntegerInRange(request.targetSignalCount, "targetSignalCount", 1, 15);
1182
- requireIntegerInRange(request.lookbackDays, "lookbackDays", 1, 365);
1183
- requireIntegerInRange(request.maxWaitMs, "maxWaitMs", 1e4, 12e4);
1184
1411
  if (hasFlag("dry-run")) {
1185
1412
  const result2 = await createClient().enrichCompanySignals({ ...request, dryRun: true });
1186
1413
  dryRunOutput(result2);
1187
1414
  return;
1188
1415
  }
1189
- const result = customerSignalResult(await createClient().enrichCompanySignals(request));
1416
+ const result = customerCompanySignalResult(await createClient().enrichCompanySignals(request));
1190
1417
  if (outputFailedCoreProduct(result, "Company Signal enrichment failed")) return;
1191
1418
  output(result, () => {
1192
1419
  process.stdout.write(`Company: ${result.company.name || result.company.domain}
1193
1420
  Signals: ${result.signalCount}
1194
1421
  `);
1195
- process.stdout.write(`Result source: ${result.resultReturnedFrom || "unknown"}
1196
- Credits used: ${result.creditsUsed || 0}
1422
+ process.stdout.write(`Credits used: ${result.creditsUsed || 0}
1197
1423
  `);
1198
- for (const signal of result.signals.slice(0, 5)) {
1199
- process.stdout.write(`- ${signal.title} [${signal.type}]
1424
+ for (const signal of result.signals.slice(0, PUBLIC_COMPANY_SIGNAL_MAX_COVERAGE_COUNT)) {
1425
+ process.stdout.write(`${signal.date} ${signal.signal_type} ${signal.signal_title} ${signal.signal_summary} ${signal.source}
1200
1426
  `);
1201
1427
  }
1202
1428
  });
@@ -1208,6 +1434,8 @@ function signalQueryFromArgs(args) {
1208
1434
  "--limit",
1209
1435
  "--sources",
1210
1436
  "--lookback-days",
1437
+ "--after-date",
1438
+ "--before-date",
1211
1439
  "--icp-context",
1212
1440
  "--signal-search-run-id",
1213
1441
  "--idempotency-key",
@@ -1253,9 +1481,12 @@ async function signals(args) {
1253
1481
  limit: numberFlag("limit"),
1254
1482
  sources: sourceValues,
1255
1483
  lookbackDays: numberFlag("lookback-days"),
1484
+ afterDate: flag("after-date"),
1485
+ beforeDate: flag("before-date"),
1256
1486
  idempotencyKey: flag("idempotency-key"),
1257
1487
  dryRun: hasFlag("dry-run")
1258
1488
  };
1489
+ validateSignalDateWindow(request.afterDate, request.beforeDate, request.lookbackDays);
1259
1490
  let result = await discoverSignalsEverything(request);
1260
1491
  if (hasFlag("wait") && !request.dryRun) {
1261
1492
  const maxWaitMs = numberFlag("max-wait-ms") ?? 15 * 6e4;
@@ -1271,57 +1502,135 @@ async function signals(args) {
1271
1502
  }
1272
1503
  output(result, () => {
1273
1504
  if (result.status === "planned") {
1274
- process.stdout.write(`Signals Everything plan: ${result.requestedCount} distinct companies. No source acquisition was launched.
1505
+ process.stdout.write(`Signals Everything plan: ${result.requestedCount} distinct companies. No source acquisition was launched. Included on plan; 0 Signaliz credits charged.
1275
1506
  `);
1276
1507
  return;
1277
1508
  }
1278
1509
  if (signalDiscoveryIsPending(result.status)) {
1279
1510
  process.stdout.write(`Signals Everything ${result.status}: ${result.signalSearchRunId}
1511
+ `);
1512
+ process.stdout.write(`Billing: included on plan \xB7 ${result.creditsCharged} Signaliz credits charged.
1280
1513
  `);
1281
1514
  process.stdout.write(`Resume with --signal-search-run-id ${result.signalSearchRunId}${hasFlag("wait") ? " after the current wait window" : ""}.
1282
1515
  `);
1283
1516
  return;
1284
1517
  }
1285
1518
  if (!result.success || result.status === "failed") {
1286
- process.stdout.write(`${String(result.raw.error || result.raw.message || "Signals Everything failed.")}
1519
+ process.stdout.write(`${result.error || "Signals Everything failed."}
1287
1520
  `);
1288
1521
  return;
1289
1522
  }
1290
- const available = result.availableCompanySignalCount ?? result.signalCount;
1291
1523
  process.stdout.write(`Qualified companies returned: ${result.signalCount}
1292
1524
  `);
1293
- if (available > result.signalCount) {
1294
- process.stdout.write(
1295
- `Retained cohort: ${available}. Expand without new acquisition: signaliz signals --signal-search-run-id ${result.signalSearchRunId} --limit ${available}
1296
- `
1297
- );
1298
- }
1299
- const guardrail = result.costGuardrail;
1300
- if (guardrail) {
1301
- process.stdout.write(
1302
- `Source cost per qualified company: ${guardrail.costPerQualifiedSignalUsd ?? "n/a"} (must be < $${guardrail.maxCostPerQualifiedSignalUsd})
1303
- `
1304
- );
1305
- if (guardrail.identityResolutionCostUsd !== void 0) {
1306
- const identityCost = guardrail.identityResolutionCostUsd === null ? "unavailable" : `$${guardrail.identityResolutionCostUsd}`;
1307
- const identityRequests = guardrail.identityProviderRequests;
1308
- process.stdout.write(
1309
- `Identity resolution cost: ${identityCost}${identityRequests === void 0 ? "" : ` across ${identityRequests} identity lookup request${identityRequests === 1 ? "" : "s"}`}${guardrail.identityCostSource ? ` (${guardrail.identityCostSource})` : ""}.
1310
- `
1311
- );
1312
- }
1313
- }
1525
+ process.stdout.write(`Billing: ${result.billingStatus === "included" ? "included on plan" : "receipt unavailable"} \xB7 ${result.creditsCharged} Signaliz credits charged.
1526
+ `);
1527
+ if (result.idempotencyReplayed) process.stdout.write("Retained result reused; no new source acquisition.\n");
1314
1528
  for (const signal of result.signals.slice(0, 20)) {
1315
- process.stdout.write(`- ${signal.company.name} (${signal.company.domain}) \u2014 ${signal.eventDate} \u2014 ${signal.title}
1316
- ${signal.sourceUrl}
1529
+ process.stdout.write(`- ${signal.company_name} (${signal.domain}) \u2014 ${signal.date} \u2014 ${signal.signal_type}
1530
+ ${signal.source}
1317
1531
  `);
1318
1532
  }
1319
1533
  if (result.signalCount > 20) process.stdout.write(`Showing 20 of ${result.signalCount}; use --json for the full result.
1320
- `);
1321
- for (const warning of result.warnings || []) process.stdout.write(`Warning: ${warning}
1322
1534
  `);
1323
1535
  });
1324
1536
  }
1537
+ async function flow() {
1538
+ const runId = flag("run-id");
1539
+ if (runId) {
1540
+ const conflicts = [
1541
+ "signal-query",
1542
+ "query",
1543
+ "campaign-offer",
1544
+ "offer",
1545
+ "limit",
1546
+ "lookback-days",
1547
+ "after-date",
1548
+ "before-date",
1549
+ "people-titles",
1550
+ "people-per-company",
1551
+ "copy-research-prompt",
1552
+ "icp-context",
1553
+ "dry-run",
1554
+ "idempotency-key",
1555
+ "deep-search"
1556
+ ].filter(hasFlag);
1557
+ if (conflicts.length > 0) {
1558
+ throw new CliInputError(`Flow --run-id cannot be combined with ${conflicts.map((name) => `--${name}`).join(", ")}.`);
1559
+ }
1560
+ const result2 = await createClient().getFlow(runId);
1561
+ output(result2, () => {
1562
+ const outcome = record(result2.result);
1563
+ process.stdout.write(`Signaliz Flow ${result2.status}: ${result2.runId}
1564
+ `);
1565
+ process.stdout.write(`Verified leads: ${Number(outcome.emails_verified || 0)} \xB7 Copy drafts: ${Number(outcome.copies_ready || 0)}
1566
+ `);
1567
+ const billing = record(outcome.billing);
1568
+ if (billing.creditsCharged !== void 0) process.stdout.write(`Credits charged: ${Number(billing.creditsCharged || 0)}
1569
+ `);
1570
+ });
1571
+ return;
1572
+ }
1573
+ const signalQuery = flag("signal-query") || flag("query");
1574
+ const campaignOffer = flag("campaign-offer") || flag("offer");
1575
+ if (!signalQuery || !campaignOffer) {
1576
+ fail('Usage: signaliz flow --signal-query "companies with recent hiring" --campaign-offer "your offer" [--limit 5]');
1577
+ }
1578
+ const removedFlowControls = [
1579
+ "after-date",
1580
+ "before-date",
1581
+ "deep-search",
1582
+ "enable-deep-search",
1583
+ "signal-types",
1584
+ "search-mode",
1585
+ "model",
1586
+ "online",
1587
+ "offline",
1588
+ "shallow",
1589
+ "skip-cache",
1590
+ "bypass-cache",
1591
+ "fresh-only",
1592
+ "cache-ttl-hours",
1593
+ "cache-ttl-seconds",
1594
+ "cache-enabled",
1595
+ "cache-policy",
1596
+ "target-signal-count",
1597
+ "provider-target-signal-count"
1598
+ ].filter(hasFlag);
1599
+ if (removedFlowControls.length > 0) {
1600
+ throw new CliInputError(
1601
+ `Flow selects signal acquisition internally; ${removedFlowControls.map((name) => `--${name}`).join(", ")} is no longer supported. Use --lookback-days to set the maximum evidence age.`
1602
+ );
1603
+ }
1604
+ const request = {
1605
+ signalQuery,
1606
+ campaignOffer,
1607
+ signalLimit: numberFlag("limit"),
1608
+ lookbackDays: numberFlag("lookback-days"),
1609
+ icpContext: flag("icp-context"),
1610
+ peopleTitles: csvFlag("people-titles"),
1611
+ peoplePerCompany: numberFlag("people-per-company"),
1612
+ copyResearchPrompt: flag("copy-research-prompt") || flag("research-prompt"),
1613
+ approvalRequired: true,
1614
+ idempotencyKey: flag("idempotency-key")
1615
+ };
1616
+ requireIntegerInRange(request.signalLimit, "limit", 1, 25);
1617
+ requireIntegerInRange(request.lookbackDays, "lookbackDays", 1, 365);
1618
+ requireIntegerInRange(request.peoplePerCompany, "peoplePerCompany", 1, 5);
1619
+ if (hasFlag("dry-run")) {
1620
+ const result2 = await createClient().startFlow({ ...request, dryRun: true });
1621
+ output(result2, () => {
1622
+ process.stdout.write(`Signaliz Flow plan: up to ${result2.plan.maximumReviewCandidates} review candidates. No work was dispatched.
1623
+ `);
1624
+ for (const safeguard of result2.plan.safeguards) process.stdout.write(`- ${safeguard}
1625
+ `);
1626
+ });
1627
+ return;
1628
+ }
1629
+ const result = await createClient().startFlow(request);
1630
+ output(result, () => process.stdout.write(`Signaliz Flow started: ${result.runId}
1631
+ Check status: signaliz flow --run-id ${result.runId}
1632
+ `));
1633
+ }
1325
1634
  async function signalToCopy() {
1326
1635
  const jobId = flag("job-id");
1327
1636
  if (jobId) {
@@ -1337,8 +1646,12 @@ async function signalToCopy() {
1337
1646
  "research-prompt",
1338
1647
  "prompt",
1339
1648
  "lookback-days",
1649
+ "copy-evidence-mode",
1650
+ "without-signals",
1340
1651
  "signal-run-id",
1341
- "skip-cache",
1652
+ "signal-search-run-id",
1653
+ "fact-id",
1654
+ "event-id",
1342
1655
  "deep-search",
1343
1656
  "no-wait",
1344
1657
  "concurrency"
@@ -1369,27 +1682,28 @@ async function signalToCopy() {
1369
1682
  personName: row.personName || row.person_name,
1370
1683
  title: row.title,
1371
1684
  campaignOffer: row.campaignOffer || row.campaign_offer || row.offer,
1372
- researchPrompt: row.researchPrompt || row.research_prompt || flag("research-prompt") || flag("prompt"),
1373
- lookbackDays: row.lookbackDays ?? row.lookback_days ?? numberFlag("lookback-days"),
1685
+ copyEvidenceMode: row.copyEvidenceMode || row.copy_evidence_mode || flag("copy-evidence-mode") || (hasFlag("without-signals") ? "firmographic" : void 0),
1686
+ lookbackDays: 365,
1374
1687
  signalRunId: row.signalRunId || row.signal_run_id,
1375
- skipCache: row.skipCache ?? row.skip_cache ?? hasFlag("skip-cache"),
1688
+ signalSearchRunId: row.signalSearchRunId || row.signal_search_run_id,
1689
+ factId: row.factId || row.fact_id,
1690
+ eventId: row.eventId || row.event_id,
1376
1691
  enableDeepSearch: row.enableDeepSearch ?? row.enable_deep_search ?? hasFlag("deep-search"),
1377
1692
  maxWaitMs: row.maxWaitMs ?? row.max_wait_ms ?? (durableBatch ? void 0 : numberFlag("max-wait-ms")),
1378
1693
  idempotencyKey: row.idempotencyKey || row.idempotency_key
1379
1694
  };
1380
1695
  });
1381
1696
  for (const request2 of requests) {
1382
- requireIntegerInRange(request2.lookbackDays, "lookbackDays", 1, 365);
1383
1697
  requireIntegerInRange(request2.maxWaitMs, "maxWaitMs", 1e4, 12e4);
1384
1698
  requireSignalToCopyIdentity(request2);
1385
1699
  }
1386
1700
  if (durableBatch) {
1387
1701
  const invalidIndex = requests.findIndex(
1388
- (request2) => request2.skipCache === true || request2.enableDeepSearch === true || Boolean(stringValue(request2.idempotencyKey)) || request2.maxWaitMs !== void 0 || !stringValue(request2.companyDomain) || !stringValue(request2.personName) || !stringValue(request2.title) || !stringValue(request2.campaignOffer)
1702
+ (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)
1389
1703
  );
1390
1704
  if (invalidIndex >= 0) {
1391
1705
  throw new CliInputError(
1392
- `Signal to Copy batches larger than 25 are available-data-only; row ${invalidIndex} requests fresh/deep/synchronous controls or lacks required recipient fields. Split fresh requests into batches of at most 25.`
1706
+ `Signal to Copy batch row ${invalidIndex} uses canonical references (supported only in batches of 25 or fewer), uses unsupported row-level execution controls, or lacks required recipient fields. Put wait and idempotency controls on the batch command.`
1393
1707
  );
1394
1708
  }
1395
1709
  } else if (hasFlag("no-wait") && !hasFlag("dry-run")) {
@@ -1416,7 +1730,7 @@ async function signalToCopy() {
1416
1730
  return;
1417
1731
  }
1418
1732
  if (hasFlag("no-wait")) {
1419
- throw new CliInputError("Signal to Copy --no-wait requires --input with more than 25 available-data-only rows.");
1733
+ throw new CliInputError("Signal to Copy --no-wait requires --input with more than 25 rows.");
1420
1734
  }
1421
1735
  if (hasFlag("poll-interval-ms")) {
1422
1736
  throw new CliInputError("Signal to Copy --poll-interval-ms requires --input or --job-id.");
@@ -1431,15 +1745,16 @@ async function signalToCopy() {
1431
1745
  personName,
1432
1746
  title,
1433
1747
  campaignOffer,
1434
- researchPrompt: flag("research-prompt") || flag("prompt"),
1435
- lookbackDays: numberFlag("lookback-days"),
1748
+ copyEvidenceMode: flag("copy-evidence-mode") || (hasFlag("without-signals") ? "firmographic" : void 0),
1749
+ lookbackDays: 365,
1436
1750
  signalRunId,
1437
- skipCache: hasFlag("skip-cache"),
1751
+ signalSearchRunId: flag("signal-search-run-id"),
1752
+ factId: flag("fact-id"),
1753
+ eventId: flag("event-id"),
1438
1754
  enableDeepSearch: hasFlag("deep-search"),
1439
1755
  maxWaitMs: numberFlag("max-wait-ms"),
1440
1756
  idempotencyKey: flag("idempotency-key")
1441
1757
  };
1442
- requireIntegerInRange(request.lookbackDays, "lookbackDays", 1, 365);
1443
1758
  requireIntegerInRange(request.maxWaitMs, "maxWaitMs", 1e4, 12e4);
1444
1759
  requireSignalToCopyIdentity(request);
1445
1760
  if (hasFlag("dry-run")) {
@@ -1459,8 +1774,16 @@ async function signalToCopy() {
1459
1774
  Confidence: ${result.confidence}
1460
1775
  Evidence: ${result.evidenceUrl}
1461
1776
  `);
1462
- process.stdout.write(`Result source: ${result.resultReturnedFrom || "unknown"}
1463
- Credits used: ${result.creditsUsed || 0}
1777
+ const canonicalPointers = [
1778
+ result.signalSearchRunId ? `snapshot=${result.signalSearchRunId}` : "",
1779
+ result.factId ? `fact=${result.factId}` : "",
1780
+ result.eventId ? `event=${result.eventId}` : ""
1781
+ ].filter(Boolean);
1782
+ if (canonicalPointers.length > 0) {
1783
+ process.stdout.write(`Canonical evidence: ${canonicalPointers.join(" ")}
1784
+ `);
1785
+ }
1786
+ process.stdout.write(`Credits used: ${result.creditsUsed || 0}
1464
1787
  `);
1465
1788
  for (const variation of result.variations) {
1466
1789
  process.stdout.write(`
@@ -1510,6 +1833,108 @@ Import this file into your MCP client.
1510
1833
  `);
1511
1834
  });
1512
1835
  }
1836
+ function awarenessSchedule() {
1837
+ const direct = flag("schedule-cron");
1838
+ if (direct) return direct;
1839
+ const schedule = flag("schedule");
1840
+ if (!schedule) return void 0;
1841
+ const schedules = {
1842
+ every_6_hours: "0 */6 * * *",
1843
+ daily: "0 8 * * *",
1844
+ every_2_days: "0 8 */2 * *",
1845
+ weekly: "0 8 * * 1"
1846
+ };
1847
+ if (!schedules[schedule]) {
1848
+ throw new CliInputError("--schedule must be every_6_hours, daily, every_2_days, or weekly");
1849
+ }
1850
+ return schedules[schedule];
1851
+ }
1852
+ async function awareness(args) {
1853
+ const action = args[0];
1854
+ const monitorId = flag("monitor-id");
1855
+ if (!action || !["create", "list", "run", "signals", "pause", "resume", "delete"].includes(action)) {
1856
+ throw new CliInputError("Usage: signaliz awareness <create|list|run|signals|pause|resume|delete>");
1857
+ }
1858
+ const client = createClient();
1859
+ if (action === "create") {
1860
+ const companyName = flag("company-name");
1861
+ const domain = flag("domain");
1862
+ if (!companyName || !domain) {
1863
+ throw new CliInputError('Usage: signaliz awareness create --company-name "Acme" --domain acme.com');
1864
+ }
1865
+ const monthlyCreditCap = numberFlag("monthly-credit-cap");
1866
+ if (monthlyCreditCap !== void 0) requireIntegerInRange(monthlyCreditCap, "--monthly-credit-cap", 1, 1e4);
1867
+ const lookbackDays = numberFlag("lookback-days");
1868
+ if (lookbackDays !== void 0) requireIntegerInRange(lookbackDays, "--lookback-days", 1, 365);
1869
+ const signalTypes = csvFlag("signal-types");
1870
+ const result2 = await client.createSignalMonitor({
1871
+ companyName,
1872
+ domain,
1873
+ template: flag("template") === "basic" ? "basic" : "full_intelligence",
1874
+ scheduleCron: awarenessSchedule(),
1875
+ monthlyCreditCap,
1876
+ webhookUrl: flag("webhook-url"),
1877
+ signalConfig: {
1878
+ ...lookbackDays !== void 0 ? { lookback_days: lookbackDays } : {},
1879
+ ...signalTypes ? { signal_types: signalTypes } : {},
1880
+ ...flag("research-prompt") ? { research_prompt: flag("research-prompt") } : {}
1881
+ }
1882
+ });
1883
+ output(result2, () => process.stdout.write(`Monitor created: ${String(result2.monitor?.id || "pending")}
1884
+ `));
1885
+ return;
1886
+ }
1887
+ if (action === "list") {
1888
+ const offset = numberFlag("offset");
1889
+ if (offset !== void 0) requireIntegerInRange(offset, "--offset", 0, 1e4);
1890
+ const result2 = await client.listSignalMonitors(numberFlag("limit"), offset);
1891
+ output(result2, () => {
1892
+ for (const monitor of result2.monitors || []) {
1893
+ process.stdout.write(`${String(monitor.company_name)} ${String(monitor.status)} ${String(monitor.next_run_at || "not scheduled")} ${String(monitor.id)}
1894
+ `);
1895
+ }
1896
+ });
1897
+ return;
1898
+ }
1899
+ if (action === "signals") {
1900
+ const offset = numberFlag("offset");
1901
+ if (offset !== void 0) requireIntegerInRange(offset, "--offset", 0, 1e4);
1902
+ const result2 = customerSignalAwarenessResult(await client.signalAwareness({
1903
+ action: "list_signals",
1904
+ monitorId,
1905
+ limit: numberFlag("limit"),
1906
+ offset
1907
+ }));
1908
+ output(result2, () => {
1909
+ for (const signal of result2.signals || []) {
1910
+ process.stdout.write(`${signal.signal_type} ${signal.signal_title} ${signal.signal_summary} ${signal.source} ${signal.date} ${signal.company_name} ${signal.domain}
1911
+ `);
1912
+ }
1913
+ });
1914
+ return;
1915
+ }
1916
+ if (!monitorId) throw new CliInputError(`signaliz awareness ${action} requires --monitor-id <uuid>`);
1917
+ if (action === "run") {
1918
+ if (hasFlag("dry-run")) {
1919
+ const result3 = await client.signalAwareness({ action: "manual_run", monitorId, idempotencyKey: flag("idempotency-key"), dryRun: true });
1920
+ output(result3);
1921
+ return;
1922
+ }
1923
+ const result2 = await client.runSignalMonitor(monitorId, flag("idempotency-key"));
1924
+ output(result2, () => {
1925
+ process.stdout.write(`Run: ${String(result2.run?.id || result2.runId || "pending")}
1926
+ Signals: ${String(result2.run?.signals_found || 0)}
1927
+ Credits used: ${result2.creditsUsed || 0}
1928
+ `);
1929
+ });
1930
+ return;
1931
+ }
1932
+ const result = await client.signalAwareness(
1933
+ action === "delete" ? { action: "delete", monitorId } : { action: "update", monitorId, updates: { status: action === "resume" ? "active" : "paused", ...action === "resume" ? { auto_paused: false, auto_pause_reason: null } : {} } }
1934
+ );
1935
+ output(result, () => process.stdout.write(`Monitor ${action === "delete" ? "deleted" : action === "resume" ? "resumed" : "paused"}: ${monitorId}
1936
+ `));
1937
+ }
1513
1938
  async function main() {
1514
1939
  const [, , command, ...args] = process.argv;
1515
1940
  if (!command || ["help", "--help", "-h"].includes(command)) {
@@ -1527,6 +1952,12 @@ async function main() {
1527
1952
  return companySignals();
1528
1953
  case "signals":
1529
1954
  return signals(args);
1955
+ case "signals-first":
1956
+ return signals(args);
1957
+ case "awareness":
1958
+ return awareness(args);
1959
+ case "flow":
1960
+ return flow();
1530
1961
  case "signal-to-copy":
1531
1962
  return signalToCopy();
1532
1963
  case "health":