@signaliz/sdk 1.0.17 → 1.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -62,6 +62,13 @@ async function main() {
62
62
  await handleGtmCommand(signaliz, process.argv.slice(3));
63
63
  break;
64
64
  }
65
+ case "public-data":
66
+ case "ground-truth":
67
+ case "public-ground-truth": {
68
+ const signaliz = await createSignalizClient();
69
+ await handlePublicGroundTruthCommand(signaliz, process.argv.slice(3));
70
+ break;
71
+ }
65
72
  case "campaign-agent":
66
73
  case "campaign-builder": {
67
74
  await handleCampaignAgentCommand(createSignalizClient, process.argv.slice(3));
@@ -71,6 +78,51 @@ async function main() {
71
78
  printHelp();
72
79
  }
73
80
  }
81
+ async function handlePublicGroundTruthCommand(signaliz, argv) {
82
+ const subcommand = argv[0] && !argv[0].startsWith("--") ? argv[0] : "search";
83
+ if (!subcommand || subcommand === "help" || subcommand === "--help" || subcommand === "-h") {
84
+ printPublicGroundTruthHelp();
85
+ return;
86
+ }
87
+ if (subcommand === "sources" || subcommand === "list-sources") {
88
+ const flags2 = parseFlags(argv.slice(subcommand === argv[0] ? 1 : 0));
89
+ const result2 = await signaliz.publicGroundTruth.listSources({
90
+ query: stringFlag(flags2, "query", "q", "search"),
91
+ status: stringFlag(flags2, "status"),
92
+ limit: numberFlag(flags2, "limit")
93
+ });
94
+ if (booleanFlag(flags2, "json")) {
95
+ printJson(result2);
96
+ } else {
97
+ printPublicGroundTruthSources(result2);
98
+ }
99
+ return;
100
+ }
101
+ if (subcommand !== "search") {
102
+ throw new Error(`Unknown public-data command: ${subcommand}`);
103
+ }
104
+ const flags = parseFlags(argv.slice(subcommand === argv[0] ? 1 : 0));
105
+ const query = stringFlag(flags, "query", "q", "search");
106
+ const sourceId = stringFlag(flags, "source-id", "sourceId");
107
+ const entityType = stringFlag(flags, "entity-type", "entityType");
108
+ const filters = publicGroundTruthFiltersFromFlags(flags);
109
+ if (!query && !sourceId && !entityType && Object.keys(filters).length === 0) {
110
+ throw new Error("public-data search requires --query or at least one filter");
111
+ }
112
+ const result = await signaliz.publicGroundTruth.search({
113
+ query,
114
+ sourceId,
115
+ entityType,
116
+ ...filters,
117
+ limit: numberFlag(flags, "limit"),
118
+ offset: numberFlag(flags, "offset")
119
+ });
120
+ if (booleanFlag(flags, "json")) {
121
+ printJson(result);
122
+ } else {
123
+ printPublicGroundTruthSearch(result);
124
+ }
125
+ }
74
126
  async function handleGtmCommand(signaliz, argv) {
75
127
  const subcommand = argv[0];
76
128
  if (!subcommand || subcommand === "help" || subcommand === "--help" || subcommand === "-h") {
@@ -1057,6 +1109,69 @@ function jsonObjectFromString(value, label) {
1057
1109
  }
1058
1110
  return parsed;
1059
1111
  }
1112
+ var PUBLIC_GROUND_TRUTH_CLI_FILTERS = [
1113
+ ["industry", "industry"],
1114
+ ["location", "location"],
1115
+ ["nativeId", "native-id", "nativeId"],
1116
+ ["entityName", "entity-name", "entityName"],
1117
+ ["domain", "domain"],
1118
+ ["websiteUrl", "website-url", "websiteUrl"],
1119
+ ["phone", "phone"],
1120
+ ["email", "email"],
1121
+ ["city", "city"],
1122
+ ["state", "state"],
1123
+ ["postalCode", "postal-code", "postalCode"],
1124
+ ["country", "country"],
1125
+ ["sourceUrl", "source-url", "sourceUrl"],
1126
+ ["naics", "naics"],
1127
+ ["industryCode", "industry-code", "industryCode"],
1128
+ ["industryType", "industry-type", "industryType"],
1129
+ ["year", "year"],
1130
+ ["quarter", "quarter"],
1131
+ ["areaFips", "area-fips", "areaFips"],
1132
+ ["geoId", "geo-id", "geoId"],
1133
+ ["ownCode", "own-code", "ownCode"],
1134
+ ["sourceUpdatedAfter", "source-updated-after", "sourceUpdatedAfter"],
1135
+ ["sourceUpdatedBefore", "source-updated-before", "sourceUpdatedBefore"],
1136
+ ["observedAfter", "observed-after", "observedAfter"],
1137
+ ["observedBefore", "observed-before", "observedBefore"]
1138
+ ];
1139
+ function objectFromKeyValueFlags(flags, keyValueNames, jsonNames) {
1140
+ const object = {};
1141
+ for (const jsonName of jsonNames) {
1142
+ const parsed = jsonObjectFlag(flags, jsonName);
1143
+ if (parsed) Object.assign(object, parsed);
1144
+ }
1145
+ for (const pair of repeatedStringFlag(flags, ...keyValueNames)) {
1146
+ const eq = pair.indexOf("=");
1147
+ if (eq <= 0) throw new Error(`Expected key=value for --${keyValueNames[0]}`);
1148
+ const key = pair.slice(0, eq).trim();
1149
+ const value = pair.slice(eq + 1).trim();
1150
+ if (!key) throw new Error(`Expected non-empty key for --${keyValueNames[0]}`);
1151
+ object[key] = value;
1152
+ }
1153
+ return Object.keys(object).length > 0 ? object : void 0;
1154
+ }
1155
+ function publicGroundTruthFiltersFromFlags(flags) {
1156
+ const filters = {};
1157
+ for (const [paramName, ...flagNames] of PUBLIC_GROUND_TRUTH_CLI_FILTERS) {
1158
+ const value = stringFlag(flags, ...flagNames);
1159
+ if (value) filters[paramName] = value;
1160
+ }
1161
+ const joinKeys = objectFromKeyValueFlags(
1162
+ flags,
1163
+ ["join-key", "joinKey"],
1164
+ ["join-keys-json", "joinKeysJson"]
1165
+ );
1166
+ const rowData = objectFromKeyValueFlags(
1167
+ flags,
1168
+ ["row-data", "rowData"],
1169
+ ["row-data-json", "rowDataJson"]
1170
+ );
1171
+ if (joinKeys) filters.joinKeys = joinKeys;
1172
+ if (rowData) filters.rowData = rowData;
1173
+ return filters;
1174
+ }
1060
1175
  function printResult(result, flags) {
1061
1176
  if (booleanFlag(flags, "json")) {
1062
1177
  printJson(result);
@@ -1133,10 +1248,59 @@ function printCampaignAgentExecution(payload, flags) {
1133
1248
  printJson(payload);
1134
1249
  return;
1135
1250
  }
1251
+ printCampaignAgentOperatorVerdict(payload);
1136
1252
  printCampaignAgentPlan(payload.plan);
1137
1253
  console.log("\nResult:");
1138
1254
  printJson(payload.result);
1139
1255
  }
1256
+ function printCampaignAgentOperatorVerdict(payload) {
1257
+ const result = asRecord(payload.result);
1258
+ const build = hasRecordKeys(asRecord(result.build)) ? asRecord(result.build) : result;
1259
+ const finalStatus = asRecord(result.finalStatus);
1260
+ const deliveryApproval = asRecord(result.deliveryApproval);
1261
+ const status = textFromRecord(finalStatus, "status") ?? textFromRecord(build, "status") ?? "unknown";
1262
+ const dryRun = build.dryRun === true || build.dry_run === true || status === "dry_run";
1263
+ const campaignBuildId = textFromRecord(build, "campaignBuildId", "campaign_build_id") ?? textFromRecord(finalStatus, "campaignBuildId", "campaign_build_id");
1264
+ const campaignId = textFromRecord(build, "campaignId", "campaign_id") ?? textFromRecord(finalStatus, "campaignId", "campaign_id");
1265
+ if (dryRun) {
1266
+ console.log("Operator verdict: dry run complete; nothing launched.");
1267
+ console.log("Safety: Dry-run only. No spend, provider write, sender load, delivery, or launch ran.");
1268
+ } else if (textFromRecord(finalStatus, "status") === "completed") {
1269
+ console.log("Operator verdict: approved campaign build completed.");
1270
+ console.log("Safety: Approved build path. Review rows and artifacts before any delivery expansion.");
1271
+ } else {
1272
+ console.log(`Operator verdict: approved campaign build ${status}.`);
1273
+ console.log("Safety: Approved build path. Spend and provider writes require the supplied approval packet; delivery remains separately gated.");
1274
+ }
1275
+ console.log(`Approval state: ${campaignAgentApprovalState(payload)}`);
1276
+ if (campaignId) console.log(`Campaign ID: ${campaignId}`);
1277
+ if (campaignBuildId) console.log(`Campaign build ID: ${campaignBuildId}`);
1278
+ if (hasRecordKeys(finalStatus)) console.log(`Final status: ${textFromRecord(finalStatus, "status") ?? "unknown"}`);
1279
+ if (hasRecordKeys(deliveryApproval)) console.log(`Delivery approval: ${textFromRecord(deliveryApproval, "status") ?? "unknown"}`);
1280
+ console.log(`Next safe command: ${campaignAgentNextSafeCommand(payload.plan, dryRun, campaignBuildId)}`);
1281
+ console.log("");
1282
+ }
1283
+ function campaignAgentApprovalState(payload) {
1284
+ if (payload.approval) return "approval packet supplied";
1285
+ const required = payload.plan.approvals.map((item) => item.type);
1286
+ return required.length ? `missing ${required.join(", ")}` : "no explicit approvals required";
1287
+ }
1288
+ function campaignAgentNextSafeCommand(plan, dryRun, campaignBuildId) {
1289
+ if (campaignBuildId) return `signaliz campaign-agent review ${campaignBuildId} --limit 100`;
1290
+ if (!dryRun) return "signaliz campaign-agent status <campaign-build-id>";
1291
+ return [
1292
+ "signaliz campaign-agent build-approved",
1293
+ "--goal",
1294
+ shellQuote(plan.campaignName),
1295
+ "--target-count",
1296
+ String(plan.targetCount),
1297
+ "--confirm-launch",
1298
+ "--approve-all",
1299
+ "--approved-by <operator-email>",
1300
+ "--spend-limit",
1301
+ String(plan.estimatedCredits)
1302
+ ].join(" ");
1303
+ }
1140
1304
  function printCampaignAgentReadiness(readiness) {
1141
1305
  const summary = asRecord(readiness.summary);
1142
1306
  const plan = readiness.plan;
@@ -1175,6 +1339,13 @@ function printCampaignAgentBuildStatus(status) {
1175
1339
  if (status.campaignId) console.log(`Campaign ID: ${status.campaignId}`);
1176
1340
  console.log(`Status: ${status.status}`);
1177
1341
  console.log(`Phase: ${status.currentPhase || "N/A"}`);
1342
+ const terminalState = asRecord(status.terminalState);
1343
+ if (terminalState.kind) {
1344
+ console.log(`Terminal state: ${terminalState.kind} (${terminalState.label || "no label"})`);
1345
+ if (terminalState.heartbeatAgeSeconds !== void 0 && terminalState.heartbeatAgeSeconds !== null) {
1346
+ console.log(`Heartbeat age: ${terminalState.heartbeatAgeSeconds}s`);
1347
+ }
1348
+ }
1178
1349
  console.log(`Rows: ${status.recordsSucceeded}/${status.recordsTotal} succeeded, ${status.recordsFailed} failed`);
1179
1350
  printCampaignCustomerRowCounts(status);
1180
1351
  console.log(`Artifacts: ${status.artifactCount}`);
@@ -1196,6 +1367,8 @@ function printCampaignAgentBuildStatus(status) {
1196
1367
  console.log(`Next: ${status.nextAction}`);
1197
1368
  } else if (status.status === "pending_approval") {
1198
1369
  console.log(`Next: signaliz campaign-agent approve ${status.campaignBuildId} --destination-type webhook`);
1370
+ } else if (terminalState.safeNextAction) {
1371
+ console.log(`Next: ${terminalState.safeNextAction}`);
1199
1372
  }
1200
1373
  }
1201
1374
  function printCampaignCustomerRowCounts(status) {
@@ -1203,7 +1376,10 @@ function printCampaignCustomerRowCounts(status) {
1203
1376
  if (!counts || typeof counts !== "object") return;
1204
1377
  const value = (camel, snake) => counts[camel] ?? counts[snake] ?? "n/a";
1205
1378
  const requested = value("requestedTarget", "requested_target");
1206
- console.log(`Customer rows: accepted ${value("acceptedRows", "accepted_rows")}/${requested}, copied ${value("copiedRows", "copied_rows")}, approval-ready ${value("approvalReadyRows", "approval_ready_rows")}, QA-ready ${value("qaReadyRows", "qa_ready_rows")}, delivered ${value("deliveredRows", "delivered_rows")}`);
1379
+ const copied = value("copiedRows", "copied_rows");
1380
+ const copySkipped = value("copySkippedRows", "copy_skipped_rows");
1381
+ const copyLabel = typeof copySkipped === "number" && copySkipped > 0 && (!copied || copied === "n/a") ? `copy-skipped ${copySkipped}` : `copied ${copied}`;
1382
+ console.log(`Customer rows: accepted ${value("acceptedRows", "accepted_rows")}/${requested}, ${copyLabel}, approval-ready ${value("approvalReadyRows", "approval_ready_rows")}, QA-ready ${value("qaReadyRows", "qa_ready_rows")}, delivered ${value("deliveredRows", "delivered_rows")}`);
1207
1383
  const shortfalls = [
1208
1384
  ["accepted", value("acceptedShortfall", "accepted_shortfall")],
1209
1385
  ["usable", value("usableShortfall", "usable_shortfall")],
@@ -1219,17 +1395,20 @@ function printCampaignAgentBuildReview(review) {
1219
1395
  console.log(`Campaign: ${review.status?.name || review.campaignBuildId}`);
1220
1396
  console.log(`Status: ${summary.status || review.status?.status}`);
1221
1397
  console.log(`Phase: ${summary.phase || review.status?.currentPhase || "N/A"}`);
1398
+ console.log(`Terminal state: ${summary.terminalState || review.status?.terminalState?.kind || "unknown"}`);
1222
1399
  console.log(`Rows: ${summary.sampledRows || 0} sampled, ${summary.availableRows || 0} available`);
1223
1400
  console.log(`Qualified: ${summary.qualifiedRows || 0}`);
1224
1401
  console.log(`Emails: ${summary.rowsWithEmail || 0}`);
1225
1402
  console.log(`Copy ready: ${summary.copyReadyRows || 0}`);
1226
1403
  console.log(`Artifacts: ${summary.artifactCount || 0}`);
1404
+ printCampaignAgentNorthStarScorecard(review.northStarScorecard);
1227
1405
  if (review.campaignBuildId) printCampaignArtifactDownload(review.status, review.campaignBuildId);
1228
1406
  console.log(`Delivery approval ready: ${summary.readyForDeliveryApproval === true ? "yes" : "no"}`);
1229
1407
  if (Array.isArray(review.gates) && review.gates.length > 0) {
1230
1408
  console.log("\nGates:");
1231
1409
  for (const gate of review.gates) {
1232
- console.log(`- ${gate.passed ? "PASS" : "BLOCKED"} ${gate.label}: ${gate.detail}`);
1410
+ const status = String(gate.status || (gate.passed ? "pass" : "blocked")).toUpperCase();
1411
+ console.log(`- ${status} ${gate.label}: ${gate.detail}`);
1233
1412
  }
1234
1413
  }
1235
1414
  const warnings = Array.isArray(summary.warnings) ? summary.warnings : [];
@@ -1243,6 +1422,21 @@ function printCampaignAgentBuildReview(review) {
1243
1422
  for (const action of nextActions) console.log(`- ${action}`);
1244
1423
  }
1245
1424
  }
1425
+ function printCampaignAgentNorthStarScorecard(scorecard) {
1426
+ const card = asRecord(scorecard);
1427
+ if (!card.version) return;
1428
+ const score = card.score === null || card.score === void 0 ? "pending" : `${card.score}%`;
1429
+ console.log(`North Star: ${String(card.status || "unknown")} (${score})`);
1430
+ if (card.moatState) console.log(`Moat state: ${card.moatState}`);
1431
+ const metrics = Array.isArray(card.metrics) ? card.metrics : [];
1432
+ if (metrics.length > 0) {
1433
+ console.log("\nNorth Star gates:");
1434
+ for (const metric of metrics.slice(0, 12)) {
1435
+ const item = asRecord(metric);
1436
+ console.log(`- ${String(item.status || "review").toUpperCase()} ${item.label || item.id}: ${item.detail || ""}`);
1437
+ }
1438
+ }
1439
+ }
1246
1440
  function formatCampaignAgentRows(rows) {
1247
1441
  return rows.map((row) => {
1248
1442
  const data = asRecord(row.data);
@@ -1320,6 +1514,20 @@ function printCampaignAgentCopySnippets(rows, limit = 5) {
1320
1514
  function asRecord(value) {
1321
1515
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
1322
1516
  }
1517
+ function hasRecordKeys(value) {
1518
+ return Object.keys(value).length > 0;
1519
+ }
1520
+ function textFromRecord(record, ...keys) {
1521
+ for (const key of keys) {
1522
+ const value = record[key];
1523
+ if (typeof value === "string" && value.trim()) return value.trim();
1524
+ if (typeof value === "number" && Number.isFinite(value)) return String(value);
1525
+ }
1526
+ return void 0;
1527
+ }
1528
+ function shellQuote(value) {
1529
+ return `'${String(value || "").replace(/'/g, `'\\''`)}'`;
1530
+ }
1323
1531
  function printCampaignAgentProof(proof) {
1324
1532
  console.log(`Campaign-agent proof: ${proof.success ? "passed" : "failed"}`);
1325
1533
  const campaign = asRecord(proof.campaign);
@@ -1337,6 +1545,51 @@ function printCampaignAgentProof(proof) {
1337
1545
  function printJson(value) {
1338
1546
  console.log(JSON.stringify(value, null, 2));
1339
1547
  }
1548
+ function truncateCell(value, width) {
1549
+ const text = String(value ?? "").replace(/\s+/g, " ").trim();
1550
+ return text.length > width ? `${text.slice(0, Math.max(width - 3, 0))}...` : text;
1551
+ }
1552
+ function printPublicGroundTruthSearch(result) {
1553
+ const records = Array.isArray(result.records) ? result.records : [];
1554
+ console.log(`Public data search: ${result.total_count ?? 0} matches (${records.length} returned)`);
1555
+ if (result.query) console.log(`Query: ${result.query}`);
1556
+ if (result.source_id) console.log(`Source: ${result.source_id}`);
1557
+ if (result.entity_type) console.log(`Entity type: ${result.entity_type}`);
1558
+ if (!records.length) {
1559
+ console.log("No records matched.");
1560
+ return;
1561
+ }
1562
+ console.log("");
1563
+ console.log("Source".padEnd(22) + "Native ID".padEnd(22) + "Name".padEnd(42) + "Industry".padEnd(28) + "Domain".padEnd(24) + "Loc".padEnd(12) + "Match");
1564
+ console.log("-".repeat(160));
1565
+ for (const record of records) {
1566
+ const loc = [record.city, record.state].filter(Boolean).join(", ");
1567
+ const industry = [record.industry_code, record.industry_name].filter(Boolean).join(" ");
1568
+ console.log(
1569
+ truncateCell(record.source_id, 21).padEnd(22) + truncateCell(record.native_id, 21).padEnd(22) + truncateCell(record.entity_name, 41).padEnd(42) + truncateCell(industry, 27).padEnd(28) + truncateCell(record.domain, 23).padEnd(24) + truncateCell(loc, 11).padEnd(12) + truncateCell(record.match_type, 16)
1570
+ );
1571
+ }
1572
+ if (result.next_offset !== null && result.next_offset !== void 0) {
1573
+ console.log(`
1574
+ Next page: --offset ${result.next_offset}`);
1575
+ }
1576
+ }
1577
+ function printPublicGroundTruthSources(result) {
1578
+ const sources = Array.isArray(result.sources) ? result.sources : [];
1579
+ console.log(`Public data sources: ${sources.length}/${result.total ?? sources.length}`);
1580
+ if (!sources.length) {
1581
+ console.log("No sources matched.");
1582
+ return;
1583
+ }
1584
+ console.log("");
1585
+ console.log("Source ID".padEnd(30) + "Status".padEnd(12) + "Rung".padEnd(7) + "Join key".padEnd(20) + "Cadence".padEnd(16) + "Name");
1586
+ console.log("-".repeat(120));
1587
+ for (const source of sources) {
1588
+ console.log(
1589
+ truncateCell(source.id, 29).padEnd(30) + truncateCell(source.ingestion_status, 11).padEnd(12) + String(source.ground_truth_rung ?? "").padEnd(7) + truncateCell(source.primary_join_key || source.join_key_quality, 19).padEnd(20) + truncateCell(source.update_cadence, 15).padEnd(16) + truncateCell(source.name, 40)
1590
+ );
1591
+ }
1592
+ }
1340
1593
  function printHelp() {
1341
1594
  console.log(`
1342
1595
  Signaliz CLI v1.0.0
@@ -1344,6 +1597,8 @@ Signaliz CLI v1.0.0
1344
1597
  Usage:
1345
1598
  signaliz test Verify API connectivity
1346
1599
  signaliz tools List all available MCP tools
1600
+ signaliz public-data search --query "swift transportation" --limit 10
1601
+ signaliz public-data sources --status ready
1347
1602
  signaliz gtm context --json Load GTM Kernel workspace context
1348
1603
  signaliz gtm bootstrap --json Inspect GTM Kernel readiness
1349
1604
  signaliz gtm templates --json List private-safe campaign strategy templates
@@ -1374,6 +1629,25 @@ Environment:
1374
1629
  SIGNALIZ_BASE_URL Optional API base URL override
1375
1630
  `);
1376
1631
  }
1632
+ function printPublicGroundTruthHelp() {
1633
+ console.log(`
1634
+ Signaliz public-data commands:
1635
+
1636
+ signaliz public-data search [--query TEXT] [--industry TEXT] [--location TEXT] [--source-id ID] [--domain DOMAIN] [--naics CODE] [--state ST] [--year YYYY] [--join-key k=v] [--row-data k=v] [--limit N] [--offset N] [--json]
1637
+ signaliz public-data sources [--query TEXT] [--status ready|partial|blocked|planned] [--limit N] [--json]
1638
+
1639
+ Aliases:
1640
+ signaliz ground-truth search ...
1641
+
1642
+ Examples:
1643
+ signaliz public-data search --query "swift transportation" --source-id fmcsa_company_census --limit 10
1644
+ signaliz public-data search --industry "software publishers" --location CA --limit 25 --json
1645
+ signaliz public-data search --source-id bls_qcew --naics 541511 --state CA --year 2025 --json
1646
+ signaliz public-data search --domain swifttrans.com --json
1647
+ signaliz public-data search --join-key ein=123456789 --json
1648
+ signaliz public-data sources --status ready --json
1649
+ `);
1650
+ }
1377
1651
  function printGtmHelp() {
1378
1652
  console.log(`
1379
1653
  Signaliz GTM commands: