@signaliz/cli 1.0.62 → 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 +707 -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,10 @@ 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,
526
+ billing_replayed: typeof raw.billing_replayed === "boolean" ? raw.billing_replayed : result.billingReplayed === true,
527
+ ...typeof raw.idempotency_replayed === "boolean" || typeof result.idempotencyReplayed === "boolean" ? {
528
+ idempotency_replayed: typeof raw.idempotency_replayed === "boolean" ? raw.idempotency_replayed : result.idempotencyReplayed === true
529
+ } : {},
300
530
  billing_metadata: normalizedBillingMetadata,
301
531
  ...Object.keys(historicalBillingMetadata2).length > 0 ? { historical_billing_metadata: historicalBillingMetadata2 } : {},
302
532
  ...estimatedExternalCostUsd2 !== null ? { estimated_external_cost_usd: estimatedExternalCostUsd2 } : {},
@@ -305,11 +535,6 @@ function customerEmailResult(value, kind) {
305
535
  recovery_mode: raw.recovery_mode,
306
536
  recovery_status: raw.recovery_status ?? "completed"
307
537
  } : {},
308
- ...raw.cache_publication_status ? {
309
- cache_publication_status: raw.cache_publication_status,
310
- cache_publication_retry_eligible: raw.cache_publication_retry_eligible === true,
311
- ...raw.suggested_action ? { suggested_action: raw.suggested_action } : {}
312
- } : {},
313
538
  ...terminalErrorCode ? {
314
539
  email: null,
315
540
  success: false,
@@ -344,11 +569,6 @@ function customerEmailResult(value, kind) {
344
569
  const isMalformed = typeof result.isMalformed === "boolean" ? result.isMalformed : raw.is_malformed === true;
345
570
  const quality = typeof result.quality === "string" ? result.quality : typeof raw.quality === "string" ? raw.quality : null;
346
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";
347
- const cacheHit = typeof raw.cache_hit === "boolean" ? raw.cache_hit : result.cacheHit === true;
348
- const negativeCacheHit = typeof raw.negative_cache_hit === "boolean" ? raw.negative_cache_hit : result.negativeCacheHit === true;
349
- const negativeCacheTtlSeconds = safeNonNegativeNumber(
350
- result.negativeCacheTtlSeconds ?? raw.negative_cache_ttl_seconds
351
- );
352
572
  const billingMetadata = customerEmailBillingMetadata(
353
573
  Object.keys(record(result.billingMetadata)).length > 0 ? result.billingMetadata : raw.billing_metadata
354
574
  );
@@ -378,24 +598,15 @@ function customerEmailResult(value, kind) {
378
598
  verification_source: result.verificationSource ?? raw.verification_source ?? "email_verification",
379
599
  ...result.verificationObservedAt ?? raw.verification_observed_at ? { verification_observed_at: result.verificationObservedAt ?? raw.verification_observed_at } : {},
380
600
  failure_reason: result.failureReason ?? raw.failure_reason ?? (verifiedForSending ? "none" : isCatchAll ? "catch_all_domain_not_send_safe" : "verification_not_send_safe"),
381
- cache_hit: cacheHit,
382
- negative_cache_hit: negativeCacheHit,
383
- negative_cache_ttl_seconds: negativeCacheTtlSeconds,
384
- cache_tier: result.cacheTier ?? raw.cache_tier ?? null,
385
- result_returned_from: result.resultReturnedFrom ?? raw.result_returned_from ?? null,
386
- fresh_enrichment_used: typeof raw.fresh_enrichment_used === "boolean" ? raw.fresh_enrichment_used : result.freshEnrichmentUsed === true,
387
- live_provider_called: typeof raw.live_provider_called === "boolean" ? raw.live_provider_called : result.liveProviderCalled === true,
388
601
  billing_replayed: typeof raw.billing_replayed === "boolean" ? raw.billing_replayed : result.billingReplayed === true,
602
+ ...typeof raw.idempotency_replayed === "boolean" || typeof result.idempotencyReplayed === "boolean" ? {
603
+ idempotency_replayed: typeof raw.idempotency_replayed === "boolean" ? raw.idempotency_replayed : result.idempotencyReplayed === true
604
+ } : {},
389
605
  billing_metadata: billingMetadata,
390
606
  ...Object.keys(historicalBillingMetadata).length > 0 ? { historical_billing_metadata: historicalBillingMetadata } : {},
391
607
  ...estimatedExternalCostUsd !== null ? { estimated_external_cost_usd: estimatedExternalCostUsd } : {},
392
608
  ...verificationRunId ? { verification_run_id: verificationRunId } : {},
393
- ...runId ? { run_id: runId } : {},
394
- ...raw.cache_publication_status ? {
395
- cache_publication_status: raw.cache_publication_status,
396
- cache_publication_retry_eligible: raw.cache_publication_retry_eligible === true,
397
- ...raw.suggested_action ? { suggested_action: raw.suggested_action } : {}
398
- } : {}
609
+ ...runId ? { run_id: runId } : {}
399
610
  };
400
611
  }
401
612
  function customerEmailBatch(value, kind) {
@@ -423,15 +634,39 @@ function customerSignalResult(value) {
423
634
  return {
424
635
  ...result,
425
636
  ...Object.keys(billingMetadata).length > 0 ? { billingMetadata } : {},
426
- resultReturnedFrom: result.resultReturnedFrom ?? raw.result_returned_from,
427
- cacheHit: result.cacheHit ?? raw.cache_hit,
428
- freshEnrichmentUsed: result.freshEnrichmentUsed ?? raw.fresh_enrichment_used,
429
637
  creditsUsed: result.creditsUsed ?? raw.credits_used,
430
- liveProviderCalled: result.liveProviderCalled ?? raw.live_provider_called,
431
638
  aiProviderCalled: result.aiProviderCalled ?? raw.ai_provider_called,
432
639
  byoAiUsed: result.byoAiUsed ?? raw.byo_ai_used
433
640
  };
434
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
+ }
435
670
  function customerSignalBatch(value) {
436
671
  return {
437
672
  ...value,
@@ -441,6 +676,31 @@ function customerSignalBatch(value) {
441
676
  })
442
677
  };
443
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
+ }
444
704
  function batchOptions() {
445
705
  return {
446
706
  concurrency: numberFlag("concurrency"),
@@ -546,12 +806,40 @@ function numberValue(value) {
546
806
  const number = Number(value);
547
807
  return Number.isFinite(number) ? number : void 0;
548
808
  }
549
- function nullableNumberValue(value) {
550
- return value === null ? null : numberValue(value);
551
- }
552
809
  function stringValue(value) {
553
810
  return typeof value === "string" ? value.trim() : "";
554
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
+ }
555
843
  function hasFindEmailLinkedInIdentity(value) {
556
844
  const linkedinUrl = stringValue(value);
557
845
  if (!linkedinUrl) return false;
@@ -575,35 +863,11 @@ function signalsEverythingErrorType(status) {
575
863
  }
576
864
  function normalizeSignalsEverythingResult(request, value) {
577
865
  const rawSignals = Array.isArray(value.signals) ? value.signals : [];
578
- const signals2 = rawSignals.map((rawSignal) => {
579
- const signal = record(rawSignal);
580
- const company = record(signal.company);
581
- const name = stringValue(company.name || signal.company_name);
582
- const domain = stringValue(company.domain || signal.company_domain);
583
- if (!name || !domain) {
584
- throw new Error("Signals Everything response violated the company attribution contract.");
585
- }
586
- const evidence = Array.isArray(signal.evidence) ? signal.evidence.map((rawEvidence) => {
587
- const item = record(rawEvidence);
588
- return {
589
- url: stringValue(item.url),
590
- publishedAt: stringValue(item.published_at || item.publishedAt),
591
- source: stringValue(item.source)
592
- };
593
- }).filter((item) => Boolean(item.url)) : [];
594
- const eventDate = stringValue(signal.event_date || signal.date);
595
- const sourceUrl = stringValue(signal.source_url || signal.url);
596
- if (!eventDate || !sourceUrl || !evidence.some((item) => item.url === sourceUrl && item.publishedAt === eventDate)) {
597
- throw new Error("Signals Everything response violated the dated-evidence and source-URL contract.");
598
- }
599
- return {
600
- company: { name, domain },
601
- title: stringValue(signal.title || signal.summary || signal.content),
602
- eventDate,
603
- sourceUrl,
604
- evidence
605
- };
606
- });
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
+ );
607
871
  const statusValue = stringValue(value.status).toLowerCase();
608
872
  const statuses = /* @__PURE__ */ new Set([
609
873
  "planned",
@@ -614,52 +878,24 @@ function normalizeSignalsEverythingResult(request, value) {
614
878
  "failed"
615
879
  ]);
616
880
  const status = statuses.has(statusValue) ? statusValue : signals2.length > 0 ? "completed" : "failed";
617
- const guardrail = record(value.cost_guardrail);
618
- const maxCost = numberValue(guardrail.max_cost_per_qualified_signal_usd);
619
- const costSource = stringValue(guardrail.cost_source);
620
- const identityCostSource = stringValue(guardrail.identity_cost_source);
621
- 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;
622
884
  return {
623
885
  success: value.success !== false,
624
886
  status,
625
887
  signalSearchRunId: stringValue(value.signal_search_run_id || request.signalSearchRunId),
626
888
  query: stringValue(value.query || request.query),
627
- requestedCount: numberValue(value.requested_count) ?? request.limit ?? 100,
889
+ ...requestedCount === void 0 ? {} : { requestedCount },
628
890
  nextPollAfterSeconds: numberValue(value.next_poll_after_seconds),
629
891
  signals: signals2,
630
892
  signalCount: signals2.length,
631
- ...numberValue(value.available_company_signal_count) === void 0 ? {} : {
632
- availableCompanySignalCount: numberValue(value.available_company_signal_count)
633
- },
634
- ...maxCost === void 0 ? {} : {
635
- costGuardrail: {
636
- maxCostPerQualifiedSignalUsd: maxCost,
637
- projectedSourceCostUsd: nullableNumberValue(guardrail.projected_source_cost_usd),
638
- maxSourceCostUsd: nullableNumberValue(guardrail.max_source_cost_usd),
639
- projectedCostPerRequestedCompanySignalUsd: nullableNumberValue(
640
- guardrail.projected_cost_per_requested_company_signal_usd
641
- ),
642
- sourceCostUsd: nullableNumberValue(guardrail.source_cost_usd),
643
- costSource: ["observed", "catalog_preflight", "catalog_bounded", "mixed", "unavailable"].includes(costSource) ? costSource : void 0,
644
- costPerQualifiedSignalUsd: nullableNumberValue(guardrail.cost_per_qualified_signal_usd),
645
- identityResolutionCostUsd: nullableNumberValue(guardrail.identity_resolution_cost_usd),
646
- identityCostSource: [
647
- "observed_zero_credit_receipts",
648
- "contractual_zero_cost",
649
- "not_used",
650
- "unavailable"
651
- ].includes(identityCostSource) ? identityCostSource : void 0,
652
- identityProviderRequests: numberValue(guardrail.identity_provider_requests),
653
- qualifiedCompanySignalCount: numberValue(guardrail.qualified_company_signal_count),
654
- returnedCompanySignalCount: numberValue(guardrail.returned_company_signal_count),
655
- availableCompanySignalCount: numberValue(guardrail.available_company_signal_count),
656
- acquisitionCandidateLimit: numberValue(guardrail.acquisition_candidate_limit),
657
- minimumQualifiedCompanySignals: numberValue(guardrail.minimum_qualified_company_signals),
658
- withinLimit: guardrail.within_limit === true
659
- }
660
- },
661
- ...warnings?.length ? { warnings } : {},
662
- 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 } : {}
663
899
  };
664
900
  }
665
901
  async function discoverSignalsEverything(request) {
@@ -674,6 +910,8 @@ async function discoverSignalsEverything(request) {
674
910
  limit: request.limit ?? 100,
675
911
  ...request.sources ? { sources: request.sources } : {},
676
912
  ...request.lookbackDays === void 0 ? {} : { lookback_days: request.lookbackDays },
913
+ ...request.afterDate ? { after_date: request.afterDate } : {},
914
+ ...request.beforeDate ? { before_date: request.beforeDate } : {},
677
915
  ...request.dryRun === void 0 ? {} : { dry_run: request.dryRun },
678
916
  ...request.idempotencyKey ? { idempotency_key: request.idempotencyKey } : {}
679
917
  };
@@ -690,14 +928,19 @@ async function discoverSignalsEverything(request) {
690
928
  const responseBody = record(responseValue);
691
929
  if (!response.ok) {
692
930
  const error = record(responseBody.error);
693
- const code = stringValue(error.code || responseBody.error_code) || `HTTP_${response.status}`;
694
- 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
+ );
695
934
  throw new import_sdk.SignalizError({
696
- code,
697
- message,
935
+ code: publicFailure.errorCode,
936
+ message: publicFailure.error,
698
937
  errorType: signalsEverythingErrorType(response.status),
699
938
  retryAfter: numberValue(responseBody.retry_after_seconds || responseBody.retry_after),
700
- details: responseBody
939
+ details: normalizeSignalsEverythingResult(request, {
940
+ ...responseBody,
941
+ success: false,
942
+ error_code: publicFailure.errorCode
943
+ })
701
944
  });
702
945
  }
703
946
  return normalizeSignalsEverythingResult(request, responseBody);
@@ -709,10 +952,39 @@ function output(value, human) {
709
952
  } else if (human) {
710
953
  human();
711
954
  } else {
712
- process.stdout.write(`${JSON.stringify(value, null, 2)}
955
+ process.stdout.write(`${JSON.stringify(publicCliValue(value), null, 2)}
713
956
  `);
714
957
  }
715
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
+ }
716
988
  function outputFailedCoreProduct(value, fallbackMessage) {
717
989
  const result = record(value);
718
990
  if (result.success !== false) return false;
@@ -726,7 +998,7 @@ function outputFailedCoreProduct(value, fallbackMessage) {
726
998
  }
727
999
  function stringifyMachineJson(value, space) {
728
1000
  const omitRaw = hasFlag("omit-raw");
729
- 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);
730
1002
  }
731
1003
  function fail(message) {
732
1004
  process.stderr.write(`${message}
@@ -807,7 +1079,7 @@ async function findEmail() {
807
1079
  "linkedin-url",
808
1080
  "company-name",
809
1081
  "run-id",
810
- "skip-cache"
1082
+ "no-wait"
811
1083
  ].filter(hasFlag);
812
1084
  if (conflicts.length > 0) {
813
1085
  throw new CliInputError(
@@ -826,6 +1098,9 @@ async function findEmail() {
826
1098
  }
827
1099
  const rows = readBatchInput();
828
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
+ }
829
1104
  const requests = rows.map((value) => {
830
1105
  const row = record(value);
831
1106
  const runId2 = row.runId || row.run_id;
@@ -838,7 +1113,6 @@ async function findEmail() {
838
1113
  lastName: row.lastName || row.last_name,
839
1114
  linkedinUrl: row.linkedinUrl || row.linkedin_url || row.linkedin,
840
1115
  companyName: row.companyName || row.company_name,
841
- skipCache: row.skipCache ?? row.skip_cache ?? hasFlag("skip-cache"),
842
1116
  idempotencyKey
843
1117
  };
844
1118
  });
@@ -877,7 +1151,7 @@ async function findEmail() {
877
1151
  lastName,
878
1152
  linkedinUrl,
879
1153
  companyName: flag("company-name"),
880
- skipCache: hasFlag("skip-cache"),
1154
+ waitForResult: hasFlag("no-wait") ? false : void 0,
881
1155
  idempotencyKey: flag("idempotency-key")
882
1156
  };
883
1157
  if (hasFlag("dry-run")) {
@@ -917,7 +1191,6 @@ async function verifyEmail(args) {
917
1191
  "dry-run",
918
1192
  "email",
919
1193
  "verification-run-id",
920
- "skip-cache",
921
1194
  "no-wait"
922
1195
  ].filter(hasFlag);
923
1196
  if (positionalEmail || conflicts.length > 0) {
@@ -944,22 +1217,19 @@ async function verifyEmail(args) {
944
1217
  const row = record(value);
945
1218
  return {
946
1219
  email: String(row.email || ""),
947
- skipCache: row.skipCache ?? row.skip_cache ?? hasFlag("skip-cache"),
948
1220
  idempotencyKey: row.idempotencyKey || row.idempotency_key
949
1221
  };
950
1222
  });
951
1223
  if (hasFlag("dry-run")) {
952
1224
  const result3 = await createClient().verifyEmails(emails, {
953
1225
  ...batchOptions(),
954
- skipCache: hasFlag("skip-cache"),
955
1226
  dryRun: true
956
1227
  });
957
1228
  dryRunOutput(result3);
958
1229
  return;
959
1230
  }
960
1231
  const result2 = await createClient().verifyEmails(emails, {
961
- ...batchOptions(),
962
- skipCache: hasFlag("skip-cache")
1232
+ ...batchOptions()
963
1233
  });
964
1234
  batchOutput(customerEmailBatch(result2, "verify"));
965
1235
  return;
@@ -970,7 +1240,6 @@ async function verifyEmail(args) {
970
1240
  throw new CliInputError("Usage: signaliz verify-email [jane@example.com] [--verification-run-id run_...]");
971
1241
  }
972
1242
  const options = {
973
- skipCache: hasFlag("skip-cache"),
974
1243
  verificationRunId,
975
1244
  waitForResult: !hasFlag("no-wait"),
976
1245
  maxWaitMs: numberFlag("max-wait-ms"),
@@ -1005,7 +1274,7 @@ async function verifyEmail(args) {
1005
1274
  `);
1006
1275
  process.stdout.write(`Recommendation: ${publicResult.recommendation}
1007
1276
  `);
1008
- 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}
1009
1278
  `);
1010
1279
  if (publicResult.run_id) process.stdout.write(`Run ID: ${publicResult.run_id}
1011
1280
  `);
@@ -1015,6 +1284,39 @@ async function verifyEmail(args) {
1015
1284
  }
1016
1285
  async function companySignals() {
1017
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
+ }
1018
1320
  if (jobId) {
1019
1321
  const conflicts = [
1020
1322
  "input",
@@ -1024,18 +1326,7 @@ async function companySignals() {
1024
1326
  "company-name",
1025
1327
  "signal-run-id",
1026
1328
  "research-prompt",
1027
- "prompt",
1028
- "signal-types",
1029
- "target-signal-count",
1030
1329
  "lookback-days",
1031
- "offline",
1032
- "shallow",
1033
- "search-mode",
1034
- "no-summary",
1035
- "outreach-intelligence",
1036
- "predictive-intelligence",
1037
- "skip-cache",
1038
- "include-candidate-evidence",
1039
1330
  "no-wait",
1040
1331
  "concurrency"
1041
1332
  ].filter(hasFlag);
@@ -1051,7 +1342,7 @@ async function companySignals() {
1051
1342
  idempotencyKey: flag("idempotency-key"),
1052
1343
  compactDuplicates: !hasFlag("expand-duplicates")
1053
1344
  });
1054
- batchOutput(customerSignalBatch(result2));
1345
+ batchOutput(customerCompanySignalBatch(result2));
1055
1346
  return;
1056
1347
  }
1057
1348
  rejectDurableNoWaitPollingFlags("Company Signals");
@@ -1060,59 +1351,20 @@ async function companySignals() {
1060
1351
  const durableBatch = rows.length > 25;
1061
1352
  const requests = rows.map((value) => {
1062
1353
  const row = record(value);
1063
- const online = row.online ?? !hasFlag("offline");
1064
1354
  return {
1065
1355
  signalRunId: row.signalRunId || row.signal_run_id,
1066
1356
  companyDomain: row.companyDomain || row.company_domain || row.domain,
1067
- companyName: row.companyName || row.company_name || row.name,
1068
- researchPrompt: row.researchPrompt || row.research_prompt || flag("research-prompt") || flag("prompt"),
1069
- signalTypes: row.signalTypes || row.signal_types || csvFlag("signal-types"),
1070
- targetSignalCount: row.targetSignalCount ?? row.target_signal_count ?? numberFlag("target-signal-count"),
1071
- lookbackDays: row.lookbackDays ?? row.lookback_days ?? numberFlag("lookback-days"),
1072
- online,
1073
- enableDeepSearch: row.enableDeepSearch ?? row.enable_deep_search ?? (online && !hasFlag("shallow")),
1074
- searchMode: companySignalSearchMode(row.searchMode ?? row.search_mode ?? flag("search-mode")),
1075
- includeSummary: row.includeSummary ?? row.include_summary ?? !hasFlag("no-summary"),
1076
- enableOutreachIntelligence: row.enableOutreachIntelligence ?? row.enable_outreach_intelligence,
1077
- enablePredictiveIntelligence: row.enablePredictiveIntelligence ?? row.enable_predictive_intelligence,
1078
- skipCache: row.skipCache ?? row.skip_cache ?? hasFlag("skip-cache"),
1079
- includeCandidateEvidence: row.includeCandidateEvidence ?? row.include_candidate_evidence ?? hasFlag("include-candidate-evidence"),
1080
- maxWaitMs: row.maxWaitMs ?? row.max_wait_ms ?? (durableBatch ? void 0 : numberFlag("max-wait-ms")),
1357
+ domain: row.domain || row.companyDomain || row.company_domain,
1081
1358
  idempotencyKey: row.idempotencyKey || row.idempotency_key
1082
1359
  };
1083
1360
  });
1084
- for (const request2 of requests) {
1085
- requireIntegerInRange(request2.targetSignalCount, "targetSignalCount", 1, 15);
1086
- requireIntegerInRange(request2.lookbackDays, "lookbackDays", 1, 365);
1087
- requireIntegerInRange(request2.maxWaitMs, "maxWaitMs", 1e4, 12e4);
1088
- }
1089
- if (durableBatch && requests.some((request2) => request2.includeCandidateEvidence === true)) {
1090
- throw new CliInputError(
1091
- "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."
1092
- );
1093
- }
1094
1361
  if (durableBatch) {
1095
- const controlKey = (request2) => JSON.stringify({
1096
- researchPrompt: request2.researchPrompt,
1097
- signalTypes: request2.signalTypes,
1098
- targetSignalCount: request2.targetSignalCount,
1099
- lookbackDays: request2.lookbackDays,
1100
- online: request2.online,
1101
- enableDeepSearch: request2.enableDeepSearch,
1102
- searchMode: request2.searchMode ?? "balanced",
1103
- includeSummary: request2.includeSummary,
1104
- enableOutreachIntelligence: request2.enableOutreachIntelligence,
1105
- enablePredictiveIntelligence: request2.enablePredictiveIntelligence,
1106
- skipCache: request2.skipCache,
1107
- includeCandidateEvidence: request2.includeCandidateEvidence
1108
- });
1109
- const firstControlKey = controlKey(requests[0]);
1110
1362
  const incompatible = requests.some(
1111
- (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)
1112
1364
  );
1113
1365
  if (incompatible) {
1114
1366
  throw new CliInputError(
1115
- "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."
1116
1368
  );
1117
1369
  }
1118
1370
  } else if (hasFlag("no-wait") && !hasFlag("dry-run")) {
@@ -1137,7 +1389,7 @@ async function companySignals() {
1137
1389
  return;
1138
1390
  }
1139
1391
  const result2 = await createClient().enrichCompanies(requests, batchOptions());
1140
- batchOutput(customerSignalBatch(result2));
1392
+ batchOutput(customerCompanySignalBatch(result2));
1141
1393
  return;
1142
1394
  }
1143
1395
  if (hasFlag("no-wait")) {
@@ -1147,49 +1399,30 @@ async function companySignals() {
1147
1399
  throw new CliInputError("Company Signals --poll-interval-ms requires --input or --job-id.");
1148
1400
  }
1149
1401
  const companyDomain = flag("domain") || flag("company-domain");
1150
- const companyName = flag("company-name");
1151
1402
  const signalRunId = flag("signal-run-id");
1152
- if (!companyDomain && !companyName && !signalRunId) {
1403
+ if (!companyDomain && !signalRunId) {
1153
1404
  throw new CliInputError("Usage: signaliz company-signals --domain example.com");
1154
1405
  }
1155
1406
  const request = {
1156
1407
  signalRunId,
1157
- companyDomain,
1158
- companyName,
1159
- researchPrompt: flag("research-prompt") || flag("prompt"),
1160
- signalTypes: csvFlag("signal-types"),
1161
- targetSignalCount: numberFlag("target-signal-count"),
1162
- lookbackDays: numberFlag("lookback-days"),
1163
- online: !hasFlag("offline"),
1164
- enableDeepSearch: !hasFlag("offline") && !hasFlag("shallow"),
1165
- searchMode: companySignalSearchMode(flag("search-mode")),
1166
- includeSummary: !hasFlag("no-summary"),
1167
- enableOutreachIntelligence: hasFlag("outreach-intelligence") || void 0,
1168
- enablePredictiveIntelligence: hasFlag("predictive-intelligence") || void 0,
1169
- skipCache: hasFlag("skip-cache"),
1170
- includeCandidateEvidence: hasFlag("include-candidate-evidence"),
1171
- maxWaitMs: numberFlag("max-wait-ms"),
1408
+ domain: companyDomain,
1172
1409
  idempotencyKey: flag("idempotency-key")
1173
1410
  };
1174
- requireIntegerInRange(request.targetSignalCount, "targetSignalCount", 1, 15);
1175
- requireIntegerInRange(request.lookbackDays, "lookbackDays", 1, 365);
1176
- requireIntegerInRange(request.maxWaitMs, "maxWaitMs", 1e4, 12e4);
1177
1411
  if (hasFlag("dry-run")) {
1178
1412
  const result2 = await createClient().enrichCompanySignals({ ...request, dryRun: true });
1179
1413
  dryRunOutput(result2);
1180
1414
  return;
1181
1415
  }
1182
- const result = customerSignalResult(await createClient().enrichCompanySignals(request));
1416
+ const result = customerCompanySignalResult(await createClient().enrichCompanySignals(request));
1183
1417
  if (outputFailedCoreProduct(result, "Company Signal enrichment failed")) return;
1184
1418
  output(result, () => {
1185
1419
  process.stdout.write(`Company: ${result.company.name || result.company.domain}
1186
1420
  Signals: ${result.signalCount}
1187
1421
  `);
1188
- process.stdout.write(`Result source: ${result.resultReturnedFrom || "unknown"}
1189
- Credits used: ${result.creditsUsed || 0}
1422
+ process.stdout.write(`Credits used: ${result.creditsUsed || 0}
1190
1423
  `);
1191
- for (const signal of result.signals.slice(0, 5)) {
1192
- 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}
1193
1426
  `);
1194
1427
  }
1195
1428
  });
@@ -1201,6 +1434,8 @@ function signalQueryFromArgs(args) {
1201
1434
  "--limit",
1202
1435
  "--sources",
1203
1436
  "--lookback-days",
1437
+ "--after-date",
1438
+ "--before-date",
1204
1439
  "--icp-context",
1205
1440
  "--signal-search-run-id",
1206
1441
  "--idempotency-key",
@@ -1246,9 +1481,12 @@ async function signals(args) {
1246
1481
  limit: numberFlag("limit"),
1247
1482
  sources: sourceValues,
1248
1483
  lookbackDays: numberFlag("lookback-days"),
1484
+ afterDate: flag("after-date"),
1485
+ beforeDate: flag("before-date"),
1249
1486
  idempotencyKey: flag("idempotency-key"),
1250
1487
  dryRun: hasFlag("dry-run")
1251
1488
  };
1489
+ validateSignalDateWindow(request.afterDate, request.beforeDate, request.lookbackDays);
1252
1490
  let result = await discoverSignalsEverything(request);
1253
1491
  if (hasFlag("wait") && !request.dryRun) {
1254
1492
  const maxWaitMs = numberFlag("max-wait-ms") ?? 15 * 6e4;
@@ -1264,57 +1502,135 @@ async function signals(args) {
1264
1502
  }
1265
1503
  output(result, () => {
1266
1504
  if (result.status === "planned") {
1267
- 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.
1268
1506
  `);
1269
1507
  return;
1270
1508
  }
1271
1509
  if (signalDiscoveryIsPending(result.status)) {
1272
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.
1273
1513
  `);
1274
1514
  process.stdout.write(`Resume with --signal-search-run-id ${result.signalSearchRunId}${hasFlag("wait") ? " after the current wait window" : ""}.
1275
1515
  `);
1276
1516
  return;
1277
1517
  }
1278
1518
  if (!result.success || result.status === "failed") {
1279
- process.stdout.write(`${String(result.raw.error || result.raw.message || "Signals Everything failed.")}
1519
+ process.stdout.write(`${result.error || "Signals Everything failed."}
1280
1520
  `);
1281
1521
  return;
1282
1522
  }
1283
- const available = result.availableCompanySignalCount ?? result.signalCount;
1284
1523
  process.stdout.write(`Qualified companies returned: ${result.signalCount}
1285
1524
  `);
1286
- if (available > result.signalCount) {
1287
- process.stdout.write(
1288
- `Retained cohort: ${available}. Expand without new acquisition: signaliz signals --signal-search-run-id ${result.signalSearchRunId} --limit ${available}
1289
- `
1290
- );
1291
- }
1292
- const guardrail = result.costGuardrail;
1293
- if (guardrail) {
1294
- process.stdout.write(
1295
- `Source cost per qualified company: ${guardrail.costPerQualifiedSignalUsd ?? "n/a"} (must be < $${guardrail.maxCostPerQualifiedSignalUsd})
1296
- `
1297
- );
1298
- if (guardrail.identityResolutionCostUsd !== void 0) {
1299
- const identityCost = guardrail.identityResolutionCostUsd === null ? "unavailable" : `$${guardrail.identityResolutionCostUsd}`;
1300
- const identityRequests = guardrail.identityProviderRequests;
1301
- process.stdout.write(
1302
- `Identity resolution cost: ${identityCost}${identityRequests === void 0 ? "" : ` across ${identityRequests} identity lookup request${identityRequests === 1 ? "" : "s"}`}${guardrail.identityCostSource ? ` (${guardrail.identityCostSource})` : ""}.
1303
- `
1304
- );
1305
- }
1306
- }
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");
1307
1528
  for (const signal of result.signals.slice(0, 20)) {
1308
- process.stdout.write(`- ${signal.company.name} (${signal.company.domain}) \u2014 ${signal.eventDate} \u2014 ${signal.title}
1309
- ${signal.sourceUrl}
1529
+ process.stdout.write(`- ${signal.company_name} (${signal.domain}) \u2014 ${signal.date} \u2014 ${signal.signal_type}
1530
+ ${signal.source}
1310
1531
  `);
1311
1532
  }
1312
1533
  if (result.signalCount > 20) process.stdout.write(`Showing 20 of ${result.signalCount}; use --json for the full result.
1313
- `);
1314
- for (const warning of result.warnings || []) process.stdout.write(`Warning: ${warning}
1315
1534
  `);
1316
1535
  });
1317
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
+ }
1318
1634
  async function signalToCopy() {
1319
1635
  const jobId = flag("job-id");
1320
1636
  if (jobId) {
@@ -1330,8 +1646,12 @@ async function signalToCopy() {
1330
1646
  "research-prompt",
1331
1647
  "prompt",
1332
1648
  "lookback-days",
1649
+ "copy-evidence-mode",
1650
+ "without-signals",
1333
1651
  "signal-run-id",
1334
- "skip-cache",
1652
+ "signal-search-run-id",
1653
+ "fact-id",
1654
+ "event-id",
1335
1655
  "deep-search",
1336
1656
  "no-wait",
1337
1657
  "concurrency"
@@ -1362,27 +1682,28 @@ async function signalToCopy() {
1362
1682
  personName: row.personName || row.person_name,
1363
1683
  title: row.title,
1364
1684
  campaignOffer: row.campaignOffer || row.campaign_offer || row.offer,
1365
- researchPrompt: row.researchPrompt || row.research_prompt || flag("research-prompt") || flag("prompt"),
1366
- 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,
1367
1687
  signalRunId: row.signalRunId || row.signal_run_id,
1368
- 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,
1369
1691
  enableDeepSearch: row.enableDeepSearch ?? row.enable_deep_search ?? hasFlag("deep-search"),
1370
1692
  maxWaitMs: row.maxWaitMs ?? row.max_wait_ms ?? (durableBatch ? void 0 : numberFlag("max-wait-ms")),
1371
1693
  idempotencyKey: row.idempotencyKey || row.idempotency_key
1372
1694
  };
1373
1695
  });
1374
1696
  for (const request2 of requests) {
1375
- requireIntegerInRange(request2.lookbackDays, "lookbackDays", 1, 365);
1376
1697
  requireIntegerInRange(request2.maxWaitMs, "maxWaitMs", 1e4, 12e4);
1377
1698
  requireSignalToCopyIdentity(request2);
1378
1699
  }
1379
1700
  if (durableBatch) {
1380
1701
  const invalidIndex = requests.findIndex(
1381
- (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)
1382
1703
  );
1383
1704
  if (invalidIndex >= 0) {
1384
1705
  throw new CliInputError(
1385
- `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.`
1386
1707
  );
1387
1708
  }
1388
1709
  } else if (hasFlag("no-wait") && !hasFlag("dry-run")) {
@@ -1409,7 +1730,7 @@ async function signalToCopy() {
1409
1730
  return;
1410
1731
  }
1411
1732
  if (hasFlag("no-wait")) {
1412
- 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.");
1413
1734
  }
1414
1735
  if (hasFlag("poll-interval-ms")) {
1415
1736
  throw new CliInputError("Signal to Copy --poll-interval-ms requires --input or --job-id.");
@@ -1424,15 +1745,16 @@ async function signalToCopy() {
1424
1745
  personName,
1425
1746
  title,
1426
1747
  campaignOffer,
1427
- researchPrompt: flag("research-prompt") || flag("prompt"),
1428
- lookbackDays: numberFlag("lookback-days"),
1748
+ copyEvidenceMode: flag("copy-evidence-mode") || (hasFlag("without-signals") ? "firmographic" : void 0),
1749
+ lookbackDays: 365,
1429
1750
  signalRunId,
1430
- skipCache: hasFlag("skip-cache"),
1751
+ signalSearchRunId: flag("signal-search-run-id"),
1752
+ factId: flag("fact-id"),
1753
+ eventId: flag("event-id"),
1431
1754
  enableDeepSearch: hasFlag("deep-search"),
1432
1755
  maxWaitMs: numberFlag("max-wait-ms"),
1433
1756
  idempotencyKey: flag("idempotency-key")
1434
1757
  };
1435
- requireIntegerInRange(request.lookbackDays, "lookbackDays", 1, 365);
1436
1758
  requireIntegerInRange(request.maxWaitMs, "maxWaitMs", 1e4, 12e4);
1437
1759
  requireSignalToCopyIdentity(request);
1438
1760
  if (hasFlag("dry-run")) {
@@ -1452,8 +1774,16 @@ async function signalToCopy() {
1452
1774
  Confidence: ${result.confidence}
1453
1775
  Evidence: ${result.evidenceUrl}
1454
1776
  `);
1455
- process.stdout.write(`Result source: ${result.resultReturnedFrom || "unknown"}
1456
- 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}
1457
1787
  `);
1458
1788
  for (const variation of result.variations) {
1459
1789
  process.stdout.write(`
@@ -1503,6 +1833,108 @@ Import this file into your MCP client.
1503
1833
  `);
1504
1834
  });
1505
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
+ }
1506
1938
  async function main() {
1507
1939
  const [, , command, ...args] = process.argv;
1508
1940
  if (!command || ["help", "--help", "-h"].includes(command)) {
@@ -1520,6 +1952,12 @@ async function main() {
1520
1952
  return companySignals();
1521
1953
  case "signals":
1522
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();
1523
1961
  case "signal-to-copy":
1524
1962
  return signalToCopy();
1525
1963
  case "health":