@signaliz/sdk 1.0.10 → 1.0.12

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
@@ -3,7 +3,7 @@ import {
3
3
  Signaliz,
4
4
  createCampaignBuilderAgentRequestTemplate,
5
5
  createCampaignBuilderApproval
6
- } from "./chunk-2EXN3RAX.mjs";
6
+ } from "./chunk-XJQ6KGNQ.mjs";
7
7
 
8
8
  // src/cli.ts
9
9
  import { readFileSync, writeFileSync } from "fs";
@@ -379,6 +379,10 @@ async function handleCampaignAgentCommand(signaliz, argv) {
379
379
  }
380
380
  return;
381
381
  }
382
+ if (["review", "status", "rows", "artifacts", "approve", "approve-delivery"].includes(subcommand)) {
383
+ await handleCampaignAgentReviewCommand(signaliz, subcommand, argv.slice(1));
384
+ return;
385
+ }
382
386
  if (!["plan", "proof", "smoke", "commit-plan", "dry-run", "build-approved", "launch-approved"].includes(subcommand)) {
383
387
  printCampaignAgentHelp();
384
388
  return;
@@ -478,6 +482,90 @@ async function handleCampaignAgentCommand(signaliz, argv) {
478
482
  printCampaignAgentPlan(plan);
479
483
  }
480
484
  }
485
+ async function handleCampaignAgentReviewCommand(signaliz, subcommand, argv) {
486
+ const flags = parseFlags(argv);
487
+ const buildId = argv[0] && !argv[0].startsWith("--") ? argv[0] : stringFlag(flags, "campaign-build-id", "build-id");
488
+ if (!buildId) throw new Error(`campaign-agent ${subcommand} requires <campaign_build_id> or --campaign-build-id`);
489
+ if (subcommand === "review") {
490
+ const review = await signaliz.campaignBuilderAgent.reviewBuild(buildId, {
491
+ limit: numberFlag(flags, "limit") ?? 100,
492
+ cursor: stringFlag(flags, "cursor"),
493
+ segment: stringFlag(flags, "segment"),
494
+ rowStatus: stringFlag(flags, "row-status"),
495
+ qualified: booleanFlag(flags, "qualified") ? true : booleanFlag(flags, "disqualified") ? false : void 0
496
+ });
497
+ const operatorReview = {
498
+ ...review,
499
+ rows: {
500
+ ...review.rows,
501
+ rows: formatCampaignAgentRows(review.rows.rows)
502
+ }
503
+ };
504
+ if (booleanFlag(flags, "json")) {
505
+ printJson(operatorReview);
506
+ } else {
507
+ printCampaignAgentBuildReview(operatorReview);
508
+ }
509
+ return;
510
+ }
511
+ if (subcommand === "status") {
512
+ const status = await signaliz.campaignBuilderAgent.getBuildStatus(buildId);
513
+ if (booleanFlag(flags, "json")) {
514
+ printJson(status);
515
+ } else {
516
+ printCampaignAgentBuildStatus(status);
517
+ }
518
+ return;
519
+ }
520
+ if (subcommand === "rows") {
521
+ const result2 = await signaliz.campaignBuilderAgent.getBuildRows(buildId, {
522
+ limit: numberFlag(flags, "limit"),
523
+ cursor: stringFlag(flags, "cursor"),
524
+ segment: stringFlag(flags, "segment"),
525
+ rowStatus: stringFlag(flags, "row-status"),
526
+ qualified: booleanFlag(flags, "qualified") ? true : booleanFlag(flags, "disqualified") ? false : void 0
527
+ });
528
+ const operatorResult = {
529
+ ...result2,
530
+ rows: formatCampaignAgentRows(result2.rows)
531
+ };
532
+ if (booleanFlag(flags, "json")) {
533
+ printJson(operatorResult);
534
+ } else {
535
+ printCampaignAgentRows(operatorResult);
536
+ }
537
+ return;
538
+ }
539
+ if (subcommand === "artifacts") {
540
+ const artifacts = await signaliz.campaignBuilderAgent.listBuildArtifacts(buildId);
541
+ if (booleanFlag(flags, "json")) {
542
+ printJson(artifacts);
543
+ } else if (artifacts.length === 0) {
544
+ console.log("No artifacts yet.");
545
+ console.log(`Next: signaliz campaign-agent status ${buildId}`);
546
+ } else {
547
+ for (const artifact of artifacts) {
548
+ console.log(`${artifact.artifactType || "artifact"}: ${artifact.rowCount} rows${artifact.signedUrl ? `
549
+ ${artifact.signedUrl}` : ""}`);
550
+ }
551
+ }
552
+ return;
553
+ }
554
+ const destinationType = stringFlag(flags, "destination-type", "delivery-destination-type", "type");
555
+ if (!destinationType || !["json", "csv", "webhook"].includes(destinationType)) {
556
+ throw new Error("campaign-agent approve requires --destination-type json|csv|webhook");
557
+ }
558
+ const result = await signaliz.campaignBuilderAgent.approveDelivery(buildId, destinationType, {
559
+ destinationId: stringFlag(flags, "destination-id", "delivery-destination-id"),
560
+ destinationConfig: jsonObjectFlag(flags, "destination-config", "delivery-config")
561
+ });
562
+ if (booleanFlag(flags, "json")) {
563
+ printJson(result);
564
+ } else {
565
+ console.log(`Delivery ${result.status}: ${result.destinationType}`);
566
+ if (result.message) console.log(result.message);
567
+ }
568
+ }
481
569
  function campaignAgentRequestTemplateFromFlags(flags) {
482
570
  const goal = stringFlag(flags, "goal", "brief") || "Build a strategy-template campaign for mature operators in the target ICP.";
483
571
  const request = campaignAgentRequestFromFlags(goal, flags, { includeDefaults: true });
@@ -814,6 +902,87 @@ function printCampaignAgentExecution(payload, flags) {
814
902
  console.log("\nResult:");
815
903
  printJson(payload.result);
816
904
  }
905
+ function printCampaignAgentBuildStatus(status) {
906
+ console.log(`Campaign: ${status.name || status.campaignBuildId}`);
907
+ if (status.campaignId) console.log(`Campaign ID: ${status.campaignId}`);
908
+ console.log(`Status: ${status.status}`);
909
+ console.log(`Phase: ${status.currentPhase || "N/A"}`);
910
+ console.log(`Rows: ${status.recordsSucceeded}/${status.recordsTotal} succeeded, ${status.recordsFailed} failed`);
911
+ console.log(`Artifacts: ${status.artifactCount}`);
912
+ if (status.triggerRunId) console.log(`Trigger: ${status.triggerRunId}`);
913
+ if (Array.isArray(status.warnings) && status.warnings.length > 0) {
914
+ console.log(`Warnings: ${status.warnings.slice(0, 3).join("; ")}`);
915
+ }
916
+ if (Array.isArray(status.errors) && status.errors.length > 0) {
917
+ console.log(`Errors: ${status.errors.slice(0, 3).join("; ")}`);
918
+ }
919
+ if (status.status === "completed") {
920
+ console.log(`Next: signaliz campaign-agent rows ${status.campaignBuildId} --limit 100`);
921
+ } else if (status.status === "pending_approval") {
922
+ console.log(`Next: signaliz campaign-agent approve ${status.campaignBuildId} --destination-type webhook`);
923
+ }
924
+ }
925
+ function printCampaignAgentBuildReview(review) {
926
+ const summary = asRecord(review.summary);
927
+ console.log(`Campaign: ${review.status?.name || review.campaignBuildId}`);
928
+ console.log(`Status: ${summary.status || review.status?.status}`);
929
+ console.log(`Phase: ${summary.phase || review.status?.currentPhase || "N/A"}`);
930
+ console.log(`Rows: ${summary.sampledRows || 0} sampled, ${summary.availableRows || 0} available`);
931
+ console.log(`Qualified: ${summary.qualifiedRows || 0}`);
932
+ console.log(`Emails: ${summary.rowsWithEmail || 0}`);
933
+ console.log(`Copy ready: ${summary.copyReadyRows || 0}`);
934
+ console.log(`Artifacts: ${summary.artifactCount || 0}`);
935
+ console.log(`Delivery approval ready: ${summary.readyForDeliveryApproval === true ? "yes" : "no"}`);
936
+ if (Array.isArray(review.gates) && review.gates.length > 0) {
937
+ console.log("\nGates:");
938
+ for (const gate of review.gates) {
939
+ console.log(`- ${gate.passed ? "PASS" : "BLOCKED"} ${gate.label}: ${gate.detail}`);
940
+ }
941
+ }
942
+ const warnings = Array.isArray(summary.warnings) ? summary.warnings : [];
943
+ if (warnings.length > 0) {
944
+ console.log("\nWarnings:");
945
+ for (const warning of warnings.slice(0, 5)) console.log(`- ${warning}`);
946
+ }
947
+ const nextActions = Array.isArray(review.nextActions) ? review.nextActions : [];
948
+ if (nextActions.length > 0) {
949
+ console.log("\nNext:");
950
+ for (const action of nextActions) console.log(`- ${action}`);
951
+ }
952
+ }
953
+ function formatCampaignAgentRows(rows) {
954
+ return rows.map((row) => {
955
+ const data = asRecord(row.data);
956
+ const fallbackName = `${data.first_name || ""} ${data.last_name || ""}`.trim() || null;
957
+ return {
958
+ ...row,
959
+ email: data.email ?? null,
960
+ name: data.full_name ?? fallbackName,
961
+ title: data.title ?? null,
962
+ company: data.company_name ?? null,
963
+ domain: data.company_domain ?? null,
964
+ score: data.overall_score ?? null,
965
+ has_copy: Boolean(data.subject || data.opener || data.body || data.cta || asRecord(data.raw_copy).subject)
966
+ };
967
+ });
968
+ }
969
+ function printCampaignAgentRows(result) {
970
+ if (!Array.isArray(result.rows) || result.rows.length === 0) {
971
+ console.log("No rows found.");
972
+ return;
973
+ }
974
+ console.table(result.rows.map((row) => ({
975
+ email: row.email || "",
976
+ name: row.name || "",
977
+ title: row.title || "",
978
+ company: row.company || row.domain || "",
979
+ status: row.status || "",
980
+ segment: row.segment || "",
981
+ score: row.score ?? ""
982
+ })));
983
+ console.log(`Showing ${result.rows.length} row(s)${result.hasMore ? " (more available)" : ""}`);
984
+ if (result.nextCursor) console.log(`Next: signaliz campaign-agent rows ${result.campaignBuildId} --cursor ${result.nextCursor}`);
985
+ }
817
986
  function asRecord(value) {
818
987
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
819
988
  }
@@ -990,6 +1159,9 @@ Usage:
990
1159
  signaliz campaign-agent dry-run --goal "Build a strategy-template campaign..." --target-count 500 --use-local-leads --json
991
1160
  signaliz campaign-agent build-approved --goal "Build a strategy-template campaign..." --confirm-launch --approve-all --approved-by you@example.com --spend-limit 500
992
1161
  signaliz campaign-agent build-approved --request-file campaign-request.json --confirm-launch --approve-all --approved-by you@example.com --spend-limit 500 --wait --approve-delivery --delivery-destination-type json
1162
+ signaliz campaign-agent review <campaign_build_id> --limit 100 --json
1163
+ signaliz campaign-agent status <campaign_build_id> --json
1164
+ signaliz campaign-agent rows <campaign_build_id> --limit 100 --json
993
1165
 
994
1166
  Environment:
995
1167
  SIGNALIZ_API_KEY Your API key (not required for campaign-agent init)
@@ -1021,8 +1193,13 @@ Signaliz campaign-agent commands:
1021
1193
  signaliz campaign-agent commit-plan (--goal TEXT | --request-file FILE) [--confirm-write --approved-by EMAIL] [--idempotency-key KEY] [--json]
1022
1194
  signaliz campaign-agent dry-run (--goal TEXT | --request-file FILE) [--gtm-campaign-id ID] [--delivery-risk JSON] [--idempotency-key KEY] [--json]
1023
1195
  signaliz campaign-agent build-approved (--goal TEXT | --request-file FILE) --confirm-launch --approved-by EMAIL (--approve-all | --approved-types a,b) [--commit-before-launch] [--spend-limit N] [--approved-route-ids a,b] [--wait] [--approve-delivery] [--delivery-destination-type json|csv|webhook] [--idempotency-key KEY] [--json]
1196
+ signaliz campaign-agent review <campaign_build_id> [--limit N] [--qualified|--disqualified] [--json]
1197
+ signaliz campaign-agent status <campaign_build_id> [--json]
1198
+ signaliz campaign-agent rows <campaign_build_id> [--limit N] [--cursor CURSOR] [--qualified|--disqualified] [--json]
1199
+ signaliz campaign-agent artifacts <campaign_build_id> [--json]
1200
+ signaliz campaign-agent approve <campaign_build_id> --destination-type json|csv|webhook [--destination-config JSON] [--json]
1024
1201
 
1025
- The init command emits a reusable JSON CampaignBuilderAgentRequest. The plan command composes an approval-gated strategy-template MCP flow. Proof runs the same plan path plus build_campaign dry_run=true and returns a no-spend receipt. Use --request-file to load a reusable request, then override fields such as --target-count or --strategy-template from the command line. Use --strategy-template to merge a private-safe strategy pattern into the plan without exposing private account labels, and --operating-playbooks to add reusable build-loop gates such as proof-first vertical qualification, net-new suppression, cache-first inventory, and signal-led copy approval. Built-ins map to Signaliz-native tools: lead_generation -> generate_leads, local_leads -> generate_local_leads, email_finding -> find_and_verify_emails, email_verification -> verify_emails, signals -> enrich_company_signals. Add BYO tools with --custom-tool provider:layer:tool[:mcp] or key=value pairs such as provider=apollo,layer=source,tool=apollo_search,mcp=apollo. Use --no-strategy-patterns or --no-workflow-patterns to disable default private strategy memory hints. Commit-plan dry-runs by default and writes only with --confirm-write plus approval identity. Dry-run executes build_campaign with dry_run=true. Approved build requires explicit launch confirmation and approval metadata; add --commit-before-launch to persist the reviewed plan as a GTM campaign before launch, --wait to poll until completion or pending approval, and --approve-delivery to approve reviewed JSON/CSV/webhook delivery after pending_approval.
1202
+ The init command emits a reusable JSON CampaignBuilderAgentRequest. The plan command composes an approval-gated strategy-template MCP flow. Proof runs the same plan path plus build_campaign dry_run=true and returns a no-spend receipt. Use --request-file to load a reusable request, then override fields such as --target-count or --strategy-template from the command line. Use --strategy-template to merge a private-safe strategy pattern into the plan without exposing private account labels, and --operating-playbooks to add reusable build-loop gates such as proof-first vertical qualification, net-new suppression, cache-first inventory, and signal-led copy approval. Built-ins map to Signaliz-native tools: lead_generation -> generate_leads, local_leads -> generate_local_leads, email_finding -> find_and_verify_emails, email_verification -> verify_emails, signals -> enrich_company_signals. Add BYO tools with --custom-tool provider:layer:tool[:mcp] or key=value pairs such as provider=apollo,layer=source,tool=apollo_search,mcp=apollo. Use --no-strategy-patterns or --no-workflow-patterns to disable default private strategy memory hints. Commit-plan dry-runs by default and writes only with --confirm-write plus approval identity. Dry-run executes build_campaign with dry_run=true. Approved build requires explicit launch confirmation and approval metadata; add --commit-before-launch to persist the reviewed plan as a GTM campaign before launch, --wait to poll until completion or pending approval, and --approve-delivery to approve reviewed webhook delivery after pending_approval. Use review to inspect status, sampled rows, artifacts, and delivery-readiness gates before approving delivery or routing rows to external tools.
1026
1203
  `);
1027
1204
  }
1028
1205
  main().catch((e) => {
package/dist/index.d.mts CHANGED
@@ -1094,6 +1094,38 @@ interface CampaignBuilderApprovedRunResult {
1094
1094
  finalStatus?: CampaignBuildStatus;
1095
1095
  deliveryApproval?: ApproveDeliveryResult;
1096
1096
  }
1097
+ interface CampaignBuilderBuildReviewOptions extends CampaignRowsOptions {
1098
+ /** Number of rows to sample for review. Defaults to 100. */
1099
+ limit?: number;
1100
+ }
1101
+ interface CampaignBuilderBuildReviewGate {
1102
+ id: string;
1103
+ label: string;
1104
+ passed: boolean;
1105
+ detail: string;
1106
+ }
1107
+ interface CampaignBuilderBuildReviewSummary {
1108
+ status: string;
1109
+ phase: string | null;
1110
+ sampledRows: number;
1111
+ availableRows: number;
1112
+ qualifiedRows: number;
1113
+ rowsWithEmail: number;
1114
+ copyReadyRows: number;
1115
+ artifactCount: number;
1116
+ readyForDeliveryApproval: boolean;
1117
+ blockedReasons: string[];
1118
+ warnings: string[];
1119
+ }
1120
+ interface CampaignBuilderBuildReview {
1121
+ campaignBuildId: string;
1122
+ status: CampaignBuildStatus;
1123
+ rows: CampaignRowsResult;
1124
+ artifacts: CampaignArtifact[];
1125
+ gates: CampaignBuilderBuildReviewGate[];
1126
+ summary: CampaignBuilderBuildReviewSummary;
1127
+ nextActions: string[];
1128
+ }
1097
1129
  declare const DEFAULT_SIGNALIZ_CAMPAIGN_BUILDER_DEFAULTS: Required<Pick<SignalizCampaignBuilderDefaults, 'requireVerifiedEmail' | 'dedupKeys' | 'allowDownscale'>> & SignalizCampaignBuilderDefaults;
1098
1130
  declare const DEFAULT_CAMPAIGN_BUILDER_BUILT_INS: CampaignBuilderBuiltInTool[];
1099
1131
  declare const DEFAULT_CAMPAIGN_BUILDER_APPROVAL_TYPES: CampaignBuilderApprovalType[];
@@ -1107,6 +1139,14 @@ declare class CampaignBuilderAgent {
1107
1139
  dryRunPlan(plan: CampaignBuilderAgentPlan, options?: BuildOptions): Promise<CampaignBuildResult>;
1108
1140
  buildApprovedPlan(plan: CampaignBuilderAgentPlan, approval: CampaignBuilderApproval, options?: CampaignBuilderBuildOptions): Promise<CampaignBuildResult>;
1109
1141
  runApprovedPlan(plan: CampaignBuilderAgentPlan, approval: CampaignBuilderApproval, options?: CampaignBuilderApprovedRunOptions): Promise<CampaignBuilderApprovedRunResult>;
1142
+ getBuildStatus(campaignBuildId: string): Promise<CampaignBuildStatus>;
1143
+ getBuildRows(campaignBuildId: string, options?: CampaignRowsOptions): Promise<CampaignRowsResult>;
1144
+ listBuildArtifacts(campaignBuildId: string): Promise<CampaignArtifact[]>;
1145
+ approveDelivery(campaignBuildId: string, destinationType: CampaignDeliveryMode, options?: {
1146
+ destinationId?: string;
1147
+ destinationConfig?: UnknownRecord$1;
1148
+ }): Promise<ApproveDeliveryResult>;
1149
+ reviewBuild(campaignBuildId: string, options?: CampaignBuilderBuildReviewOptions): Promise<CampaignBuilderBuildReview>;
1110
1150
  private getCampaignBuildStatus;
1111
1151
  private waitForCampaignBuildStatus;
1112
1152
  private approveCampaignDelivery;
package/dist/index.d.ts CHANGED
@@ -1094,6 +1094,38 @@ interface CampaignBuilderApprovedRunResult {
1094
1094
  finalStatus?: CampaignBuildStatus;
1095
1095
  deliveryApproval?: ApproveDeliveryResult;
1096
1096
  }
1097
+ interface CampaignBuilderBuildReviewOptions extends CampaignRowsOptions {
1098
+ /** Number of rows to sample for review. Defaults to 100. */
1099
+ limit?: number;
1100
+ }
1101
+ interface CampaignBuilderBuildReviewGate {
1102
+ id: string;
1103
+ label: string;
1104
+ passed: boolean;
1105
+ detail: string;
1106
+ }
1107
+ interface CampaignBuilderBuildReviewSummary {
1108
+ status: string;
1109
+ phase: string | null;
1110
+ sampledRows: number;
1111
+ availableRows: number;
1112
+ qualifiedRows: number;
1113
+ rowsWithEmail: number;
1114
+ copyReadyRows: number;
1115
+ artifactCount: number;
1116
+ readyForDeliveryApproval: boolean;
1117
+ blockedReasons: string[];
1118
+ warnings: string[];
1119
+ }
1120
+ interface CampaignBuilderBuildReview {
1121
+ campaignBuildId: string;
1122
+ status: CampaignBuildStatus;
1123
+ rows: CampaignRowsResult;
1124
+ artifacts: CampaignArtifact[];
1125
+ gates: CampaignBuilderBuildReviewGate[];
1126
+ summary: CampaignBuilderBuildReviewSummary;
1127
+ nextActions: string[];
1128
+ }
1097
1129
  declare const DEFAULT_SIGNALIZ_CAMPAIGN_BUILDER_DEFAULTS: Required<Pick<SignalizCampaignBuilderDefaults, 'requireVerifiedEmail' | 'dedupKeys' | 'allowDownscale'>> & SignalizCampaignBuilderDefaults;
1098
1130
  declare const DEFAULT_CAMPAIGN_BUILDER_BUILT_INS: CampaignBuilderBuiltInTool[];
1099
1131
  declare const DEFAULT_CAMPAIGN_BUILDER_APPROVAL_TYPES: CampaignBuilderApprovalType[];
@@ -1107,6 +1139,14 @@ declare class CampaignBuilderAgent {
1107
1139
  dryRunPlan(plan: CampaignBuilderAgentPlan, options?: BuildOptions): Promise<CampaignBuildResult>;
1108
1140
  buildApprovedPlan(plan: CampaignBuilderAgentPlan, approval: CampaignBuilderApproval, options?: CampaignBuilderBuildOptions): Promise<CampaignBuildResult>;
1109
1141
  runApprovedPlan(plan: CampaignBuilderAgentPlan, approval: CampaignBuilderApproval, options?: CampaignBuilderApprovedRunOptions): Promise<CampaignBuilderApprovedRunResult>;
1142
+ getBuildStatus(campaignBuildId: string): Promise<CampaignBuildStatus>;
1143
+ getBuildRows(campaignBuildId: string, options?: CampaignRowsOptions): Promise<CampaignRowsResult>;
1144
+ listBuildArtifacts(campaignBuildId: string): Promise<CampaignArtifact[]>;
1145
+ approveDelivery(campaignBuildId: string, destinationType: CampaignDeliveryMode, options?: {
1146
+ destinationId?: string;
1147
+ destinationConfig?: UnknownRecord$1;
1148
+ }): Promise<ApproveDeliveryResult>;
1149
+ reviewBuild(campaignBuildId: string, options?: CampaignBuilderBuildReviewOptions): Promise<CampaignBuilderBuildReview>;
1110
1150
  private getCampaignBuildStatus;
1111
1151
  private waitForCampaignBuildStatus;
1112
1152
  private approveCampaignDelivery;
package/dist/index.js CHANGED
@@ -1896,6 +1896,42 @@ var CampaignBuilderAgent = class {
1896
1896
  }
1897
1897
  return result;
1898
1898
  }
1899
+ async getBuildStatus(campaignBuildId) {
1900
+ return this.getCampaignBuildStatus(campaignBuildId);
1901
+ }
1902
+ async getBuildRows(campaignBuildId, options = {}) {
1903
+ const filters = compact({
1904
+ segment: options.segment,
1905
+ qualified: options.qualified,
1906
+ row_status: options.rowStatus
1907
+ });
1908
+ const args = compact({
1909
+ campaign_build_id: campaignBuildId,
1910
+ page_size: options.limit,
1911
+ cursor: options.cursor
1912
+ });
1913
+ if (Object.keys(filters).length > 0) args.filters = filters;
1914
+ const data = await this.callMcp("get_campaign_build_rows", args);
1915
+ return mapAgentCampaignRowsResult(data);
1916
+ }
1917
+ async listBuildArtifacts(campaignBuildId) {
1918
+ const data = await this.callMcp("list_campaign_build_artifacts", {
1919
+ campaign_build_id: campaignBuildId
1920
+ });
1921
+ return Array.isArray(data.artifacts) ? data.artifacts.map(mapAgentCampaignArtifact) : [];
1922
+ }
1923
+ async approveDelivery(campaignBuildId, destinationType, options) {
1924
+ return this.approveCampaignDelivery(campaignBuildId, destinationType, options);
1925
+ }
1926
+ async reviewBuild(campaignBuildId, options = {}) {
1927
+ const status = await this.getBuildStatus(campaignBuildId);
1928
+ const rows = await this.getBuildRows(campaignBuildId, {
1929
+ ...options,
1930
+ limit: options.limit ?? 100
1931
+ });
1932
+ const artifacts = await this.listBuildArtifacts(campaignBuildId);
1933
+ return createCampaignBuilderBuildReview(status, rows, artifacts);
1934
+ }
1899
1935
  async getCampaignBuildStatus(campaignBuildId) {
1900
1936
  const data = await this.callMcp("get_campaign_build_status", {
1901
1937
  campaign_build_id: campaignBuildId
@@ -3289,6 +3325,154 @@ function mapAgentCampaignBuildStatus(data) {
3289
3325
  completedAt: stringValue(data.completed_at) ?? null
3290
3326
  };
3291
3327
  }
3328
+ function mapAgentCampaignRowsResult(data) {
3329
+ const rows = Array.isArray(data.rows) ? data.rows : [];
3330
+ return {
3331
+ campaignBuildId: stringValue(data.campaign_build_id) ?? "",
3332
+ rows: rows.map((row, index) => {
3333
+ const record = asRecord(row);
3334
+ return {
3335
+ index: numberOrUndefined2(record.index) ?? index,
3336
+ status: stringValue(record.status) ?? stringValue(record.row_status) ?? "unknown",
3337
+ qualified: record.qualified !== false,
3338
+ segment: stringValue(record.segment) ?? null,
3339
+ data: nullableRecord(record.data) ?? record
3340
+ };
3341
+ }),
3342
+ count: numberOrUndefined2(data.count) ?? rows.length,
3343
+ pageSize: numberOrUndefined2(data.page_size) ?? rows.length,
3344
+ nextCursor: stringValue(data.next_cursor) ?? null,
3345
+ hasMore: data.has_more === true
3346
+ };
3347
+ }
3348
+ function mapAgentCampaignArtifact(data) {
3349
+ return {
3350
+ id: stringValue(data.id) ?? "",
3351
+ campaignBuildId: stringValue(data.campaign_build_id) ?? "",
3352
+ artifactType: stringValue(data.artifact_type) ?? "",
3353
+ destination: stringValue(data.destination) ?? "",
3354
+ storagePath: stringValue(data.storage_path) ?? "",
3355
+ signedUrl: stringValue(data.signed_url) ?? null,
3356
+ rowCount: numberOrUndefined2(data.row_count) ?? 0,
3357
+ checksum: stringValue(data.checksum) ?? null,
3358
+ metadata: nullableRecord(data.metadata) ?? {},
3359
+ createdAt: stringValue(data.created_at) ?? ""
3360
+ };
3361
+ }
3362
+ function createCampaignBuilderBuildReview(status, rows, artifacts) {
3363
+ const sampledRows = rows.rows.length;
3364
+ const availableRows = rows.count || sampledRows;
3365
+ const qualifiedRows = rows.rows.filter((row) => row.qualified !== false).length;
3366
+ const rowsWithEmail = rows.rows.filter(campaignReviewRowHasEmail).length;
3367
+ const copyReadyRows = rows.rows.filter(campaignReviewRowHasCopy).length;
3368
+ const artifactCount = artifacts.length || status.artifactCount || 0;
3369
+ const gates = [
3370
+ {
3371
+ id: "build_completed",
3372
+ label: "Build completed",
3373
+ passed: status.status === "completed",
3374
+ detail: status.status === "completed" ? "The campaign build is completed." : `The campaign build is ${status.status}; review again after completion.`
3375
+ },
3376
+ {
3377
+ id: "rows_available",
3378
+ label: "Rows available",
3379
+ passed: sampledRows > 0,
3380
+ detail: sampledRows > 0 ? `${sampledRows} sampled row(s) are available for review.` : "No rows were returned for review."
3381
+ },
3382
+ {
3383
+ id: "qualified_sample",
3384
+ label: "Sample rows qualified",
3385
+ passed: sampledRows > 0 && qualifiedRows === sampledRows,
3386
+ detail: sampledRows > 0 ? `${qualifiedRows}/${sampledRows} sampled row(s) are marked qualified.` : "Qualification could not be checked without sampled rows."
3387
+ },
3388
+ {
3389
+ id: "email_coverage",
3390
+ label: "Email coverage",
3391
+ passed: sampledRows > 0 && rowsWithEmail === sampledRows,
3392
+ detail: sampledRows > 0 ? `${rowsWithEmail}/${sampledRows} sampled row(s) include an email.` : "Email coverage could not be checked without sampled rows."
3393
+ },
3394
+ {
3395
+ id: "artifact_available",
3396
+ label: "Artifact available",
3397
+ passed: artifactCount > 0,
3398
+ detail: artifactCount > 0 ? `${artifactCount} artifact(s) are available.` : "No delivery artifact is available yet."
3399
+ },
3400
+ {
3401
+ id: "no_failed_rows",
3402
+ label: "No failed rows",
3403
+ passed: status.recordsFailed === 0,
3404
+ detail: status.recordsFailed === 0 ? "The build reports zero failed rows." : `${status.recordsFailed} row(s) failed during the build.`
3405
+ }
3406
+ ];
3407
+ const blockedReasons = gates.filter((gate) => !gate.passed).map((gate) => gate.detail);
3408
+ const warnings = [
3409
+ rows.hasMore ? "This review is based on a row sample; page through remaining rows before final approval." : void 0,
3410
+ sampledRows > 0 && copyReadyRows < sampledRows ? `${copyReadyRows}/${sampledRows} sampled row(s) include generated copy.` : void 0,
3411
+ ...status.warnings
3412
+ ].filter((item) => Boolean(item));
3413
+ const readyForDeliveryApproval = blockedReasons.length === 0;
3414
+ return {
3415
+ campaignBuildId: status.campaignBuildId || rows.campaignBuildId,
3416
+ status,
3417
+ rows,
3418
+ artifacts,
3419
+ gates,
3420
+ summary: {
3421
+ status: status.status,
3422
+ phase: status.currentPhase,
3423
+ sampledRows,
3424
+ availableRows,
3425
+ qualifiedRows,
3426
+ rowsWithEmail,
3427
+ copyReadyRows,
3428
+ artifactCount,
3429
+ readyForDeliveryApproval,
3430
+ blockedReasons,
3431
+ warnings
3432
+ },
3433
+ nextActions: campaignReviewNextActions(status, readyForDeliveryApproval)
3434
+ };
3435
+ }
3436
+ function campaignReviewNextActions(status, readyForDeliveryApproval) {
3437
+ const buildId = status.campaignBuildId;
3438
+ if (!buildId) return [];
3439
+ if (status.status === "completed" && readyForDeliveryApproval) {
3440
+ return [
3441
+ `signaliz campaign-agent approve ${buildId} --destination-type json`,
3442
+ `signaliz campaign-agent artifacts ${buildId}`
3443
+ ];
3444
+ }
3445
+ if (status.status === "completed") {
3446
+ return [
3447
+ `signaliz campaign-agent rows ${buildId} --limit 100`,
3448
+ `signaliz campaign-agent artifacts ${buildId}`
3449
+ ];
3450
+ }
3451
+ if (status.status === "pending_approval") {
3452
+ return [
3453
+ `signaliz campaign-agent rows ${buildId} --limit 100`,
3454
+ `signaliz campaign-agent approve ${buildId} --destination-type json`
3455
+ ];
3456
+ }
3457
+ if ((status.status === "queued" || status.status === "running") && status.triggerRunId) {
3458
+ return [`signaliz ops run-status ${status.triggerRunId} --watch`];
3459
+ }
3460
+ return [`signaliz campaign-agent status ${buildId}`];
3461
+ }
3462
+ function campaignReviewRowHasEmail(row) {
3463
+ const data = asRecord(row.data);
3464
+ return Boolean(
3465
+ stringValue(data.email) || stringValue(data.work_email) || stringValue(data.workEmail)
3466
+ );
3467
+ }
3468
+ function campaignReviewRowHasCopy(row) {
3469
+ const data = asRecord(row.data);
3470
+ const copy = asRecord(data.copy);
3471
+ const rawCopy = asRecord(data.raw_copy ?? data.rawCopy);
3472
+ return row.status === "copy_ready" || data.copy_ready === true || Boolean(
3473
+ stringValue(data.subject) || stringValue(data.subject_line) || stringValue(data.subjectLine) || stringValue(data.opener) || stringValue(data.body) || stringValue(data.cta) || stringValue(copy.subject) || stringValue(copy.body) || stringValue(rawCopy.subject) || stringValue(rawCopy.body)
3474
+ );
3475
+ }
3292
3476
  function diagnosticMessages2(value) {
3293
3477
  if (!Array.isArray(value)) return [];
3294
3478
  return value.map((item) => {
package/dist/index.mjs CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  getCampaignBuilderStrategyTemplate,
24
24
  getMissingCampaignBuilderApprovals,
25
25
  normalizeExecutionReference
26
- } from "./chunk-2EXN3RAX.mjs";
26
+ } from "./chunk-XJQ6KGNQ.mjs";
27
27
  export {
28
28
  Ai,
29
29
  CAMPAIGN_BUILDER_OPERATING_PLAYBOOKS,