@signaliz/cli 1.0.11 → 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/bin.js +164 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -1077,6 +1077,8 @@ Campaign Builder:
|
|
|
1077
1077
|
campaign-agent dry-run Execute build_campaign with dry_run=true
|
|
1078
1078
|
campaign-agent build-approved
|
|
1079
1079
|
Launch only after explicit approval metadata
|
|
1080
|
+
campaign-agent review <id>
|
|
1081
|
+
Review rows, artifacts, and delivery gates
|
|
1080
1082
|
campaign-agent status <id>
|
|
1081
1083
|
Inspect a campaign-agent build
|
|
1082
1084
|
campaign-agent rows <id>
|
|
@@ -2793,6 +2795,7 @@ Strategy-template campaign builder:
|
|
|
2793
2795
|
commit-plan Dry-run or write a reviewed GTM campaign object
|
|
2794
2796
|
dry-run Execute build_campaign with dry_run=true
|
|
2795
2797
|
build-approved Launch only after explicit approval metadata
|
|
2798
|
+
review Review status, rows, artifacts, and delivery gates
|
|
2796
2799
|
status Inspect a campaign-agent build
|
|
2797
2800
|
rows Retrieve reviewable campaign-agent rows
|
|
2798
2801
|
artifacts List generated artifacts
|
|
@@ -2806,6 +2809,7 @@ Examples:
|
|
|
2806
2809
|
signaliz campaign-agent dry-run --goal "Build a local services campaign" --target-count 250 --use-local-leads --json
|
|
2807
2810
|
signaliz campaign-agent build-approved --goal "Build a strategy-template campaign" --confirm-launch --approve-all --approved-by operator@example.com --spend-limit 500
|
|
2808
2811
|
signaliz campaign-agent build-approved --request-file campaign-builder-agent-request.json --confirm-launch --approve-all --approved-by operator@example.com --spend-limit 500 --wait --approve-delivery --delivery-destination-type json
|
|
2812
|
+
signaliz campaign-agent review <campaign_build_id> --limit 100 --json
|
|
2809
2813
|
signaliz campaign-agent status <campaign_build_id> --json
|
|
2810
2814
|
signaliz campaign-agent rows <campaign_build_id> --limit 100 --json
|
|
2811
2815
|
|
|
@@ -2860,7 +2864,7 @@ async function campaignAgent(sub, rest) {
|
|
|
2860
2864
|
process.stdout.write(CAMPAIGN_AGENT_HELP);
|
|
2861
2865
|
return;
|
|
2862
2866
|
}
|
|
2863
|
-
if (["status", "rows", "artifacts", "approve", "approve-delivery"].includes(sub)) {
|
|
2867
|
+
if (["review", "status", "rows", "artifacts", "approve", "approve-delivery"].includes(sub)) {
|
|
2864
2868
|
await campaignAgentReview(sub, rest);
|
|
2865
2869
|
return;
|
|
2866
2870
|
}
|
|
@@ -2974,6 +2978,24 @@ async function campaignAgentReview(sub, rest) {
|
|
|
2974
2978
|
const sdk = getSdk();
|
|
2975
2979
|
const agent = sdk.campaignBuilderAgent;
|
|
2976
2980
|
const campaigns = sdk.campaigns || {};
|
|
2981
|
+
if (sub === "review") {
|
|
2982
|
+
const rowOptions = {
|
|
2983
|
+
limit: commandNumberFlag(flags, "limit") ?? 100,
|
|
2984
|
+
cursor: commandStringFlag(flags, "cursor"),
|
|
2985
|
+
segment: commandStringFlag(flags, "segment"),
|
|
2986
|
+
rowStatus: commandStringFlag(flags, "row-status"),
|
|
2987
|
+
qualified: commandBooleanFlag(flags, "qualified") ? true : commandBooleanFlag(flags, "disqualified") ? false : void 0
|
|
2988
|
+
};
|
|
2989
|
+
const review = await agent.reviewBuild?.(buildId, rowOptions) || await campaignAgentBuildReviewFromCampaignApis(agent, campaigns, buildId, rowOptions);
|
|
2990
|
+
const operatorReview = {
|
|
2991
|
+
...review,
|
|
2992
|
+
rows: {
|
|
2993
|
+
...review.rows,
|
|
2994
|
+
rows: formatCampaignRowsForOperator(review.rows?.rows || [])
|
|
2995
|
+
}
|
|
2996
|
+
};
|
|
2997
|
+
return output(operatorReview, () => printCampaignAgentBuildReview(operatorReview));
|
|
2998
|
+
}
|
|
2977
2999
|
if (sub === "status") {
|
|
2978
3000
|
const status = await (agent.getBuildStatus?.bind(agent) || campaigns.status?.bind(campaigns) || campaigns.getCampaignBuildStatus?.bind(campaigns))?.(buildId);
|
|
2979
3001
|
if (!status) die("campaign-agent status requires a compatible @signaliz/sdk campaign status API");
|
|
@@ -3025,6 +3047,13 @@ async function campaignAgentReview(sub, rest) {
|
|
|
3025
3047
|
if (result.message) console.log(result.message);
|
|
3026
3048
|
});
|
|
3027
3049
|
}
|
|
3050
|
+
async function campaignAgentBuildReviewFromCampaignApis(agent, campaigns, buildId, rowOptions) {
|
|
3051
|
+
const status = await (agent.getBuildStatus?.bind(agent) || campaigns.status?.bind(campaigns) || campaigns.getCampaignBuildStatus?.bind(campaigns))?.(buildId);
|
|
3052
|
+
const rows = await (agent.getBuildRows?.bind(agent) || campaigns.rows?.bind(campaigns) || campaigns.getCampaignBuildRows?.bind(campaigns))?.(buildId, rowOptions);
|
|
3053
|
+
const artifacts = await (agent.listBuildArtifacts?.bind(agent) || campaigns.artifacts?.bind(campaigns) || campaigns.listCampaignBuildArtifacts?.bind(campaigns))?.(buildId);
|
|
3054
|
+
if (!status || !rows || !artifacts) die("campaign-agent review requires compatible @signaliz/sdk build status, rows, and artifacts APIs");
|
|
3055
|
+
return createCampaignAgentBuildReview(status, rows, artifacts);
|
|
3056
|
+
}
|
|
3028
3057
|
function campaignAgentRequestTemplateFromFlags(flags, rest) {
|
|
3029
3058
|
const goal = commandStringFlag(flags, "goal", "brief") || promptArg(rest) || "Build a strategy-template campaign for mature operators in the target ICP.";
|
|
3030
3059
|
const request = campaignAgentRequestFromFlags(goal, flags, { includeDefaults: true });
|
|
@@ -3357,6 +3386,140 @@ function printCampaignAgentBuildStatus(status) {
|
|
|
3357
3386
|
hint(`signaliz ops run-status ${status.triggerRunId} --watch`);
|
|
3358
3387
|
}
|
|
3359
3388
|
}
|
|
3389
|
+
function printCampaignAgentBuildReview(review) {
|
|
3390
|
+
const summary = record(review.summary);
|
|
3391
|
+
const status = record(review.status);
|
|
3392
|
+
console.log(`Campaign: ${status.name || review.campaignBuildId}`);
|
|
3393
|
+
console.log(`Status: ${summary.status || status.status}`);
|
|
3394
|
+
console.log(`Phase: ${summary.phase || status.currentPhase || "N/A"}`);
|
|
3395
|
+
console.log(`Rows: ${summary.sampledRows || 0} sampled, ${summary.availableRows || 0} available`);
|
|
3396
|
+
console.log(`Qualified: ${summary.qualifiedRows || 0}`);
|
|
3397
|
+
console.log(`Emails: ${summary.rowsWithEmail || 0}`);
|
|
3398
|
+
console.log(`Copy ready: ${summary.copyReadyRows || 0}`);
|
|
3399
|
+
console.log(`Artifacts: ${summary.artifactCount || 0}`);
|
|
3400
|
+
console.log(`Delivery approval ready: ${summary.readyForDeliveryApproval === true ? "yes" : "no"}`);
|
|
3401
|
+
const gates = Array.isArray(review.gates) ? review.gates : [];
|
|
3402
|
+
if (gates.length) {
|
|
3403
|
+
console.log("\nGates:");
|
|
3404
|
+
for (const gate of gates) {
|
|
3405
|
+
console.log(`- ${gate.passed ? "PASS" : "BLOCKED"} ${gate.label}: ${gate.detail}`);
|
|
3406
|
+
}
|
|
3407
|
+
}
|
|
3408
|
+
const warnings = Array.isArray(summary.warnings) ? summary.warnings : [];
|
|
3409
|
+
if (warnings.length) {
|
|
3410
|
+
console.log("\nWarnings:");
|
|
3411
|
+
for (const warning of warnings.slice(0, 5)) console.log(`- ${warning}`);
|
|
3412
|
+
}
|
|
3413
|
+
const nextActions = Array.isArray(review.nextActions) ? review.nextActions : [];
|
|
3414
|
+
if (nextActions.length) {
|
|
3415
|
+
console.log("\nNext:");
|
|
3416
|
+
for (const action of nextActions) console.log(`- ${action}`);
|
|
3417
|
+
}
|
|
3418
|
+
}
|
|
3419
|
+
function createCampaignAgentBuildReview(status, rows, artifacts) {
|
|
3420
|
+
const rowList = Array.isArray(rows?.rows) ? rows.rows : [];
|
|
3421
|
+
const sampledRows = rowList.length;
|
|
3422
|
+
const availableRows = Number(rows?.count || sampledRows);
|
|
3423
|
+
const qualifiedRows = rowList.filter((row) => row?.qualified !== false).length;
|
|
3424
|
+
const operatorRows = formatCampaignRowsForOperator(rowList);
|
|
3425
|
+
const rowsWithEmail = operatorRows.filter((row) => Boolean(row.email)).length;
|
|
3426
|
+
const copyReadyRows = operatorRows.filter((row) => Boolean(row.has_copy || row.status === "copy_ready")).length;
|
|
3427
|
+
const artifactCount = artifacts.length || Number(status?.artifactCount || status?.artifact_count || 0);
|
|
3428
|
+
const buildStatus = String(status?.status || "unknown");
|
|
3429
|
+
const gates = [
|
|
3430
|
+
{
|
|
3431
|
+
id: "build_completed",
|
|
3432
|
+
label: "Build completed",
|
|
3433
|
+
passed: buildStatus === "completed",
|
|
3434
|
+
detail: buildStatus === "completed" ? "The campaign build is completed." : `The campaign build is ${buildStatus}; review again after completion.`
|
|
3435
|
+
},
|
|
3436
|
+
{
|
|
3437
|
+
id: "rows_available",
|
|
3438
|
+
label: "Rows available",
|
|
3439
|
+
passed: sampledRows > 0,
|
|
3440
|
+
detail: sampledRows > 0 ? `${sampledRows} sampled row(s) are available for review.` : "No rows were returned for review."
|
|
3441
|
+
},
|
|
3442
|
+
{
|
|
3443
|
+
id: "qualified_sample",
|
|
3444
|
+
label: "Sample rows qualified",
|
|
3445
|
+
passed: sampledRows > 0 && qualifiedRows === sampledRows,
|
|
3446
|
+
detail: sampledRows > 0 ? `${qualifiedRows}/${sampledRows} sampled row(s) are marked qualified.` : "Qualification could not be checked without sampled rows."
|
|
3447
|
+
},
|
|
3448
|
+
{
|
|
3449
|
+
id: "email_coverage",
|
|
3450
|
+
label: "Email coverage",
|
|
3451
|
+
passed: sampledRows > 0 && rowsWithEmail === sampledRows,
|
|
3452
|
+
detail: sampledRows > 0 ? `${rowsWithEmail}/${sampledRows} sampled row(s) include an email.` : "Email coverage could not be checked without sampled rows."
|
|
3453
|
+
},
|
|
3454
|
+
{
|
|
3455
|
+
id: "artifact_available",
|
|
3456
|
+
label: "Artifact available",
|
|
3457
|
+
passed: artifactCount > 0,
|
|
3458
|
+
detail: artifactCount > 0 ? `${artifactCount} artifact(s) are available.` : "No delivery artifact is available yet."
|
|
3459
|
+
},
|
|
3460
|
+
{
|
|
3461
|
+
id: "no_failed_rows",
|
|
3462
|
+
label: "No failed rows",
|
|
3463
|
+
passed: Number(status?.recordsFailed || status?.records_failed || 0) === 0,
|
|
3464
|
+
detail: Number(status?.recordsFailed || status?.records_failed || 0) === 0 ? "The build reports zero failed rows." : `${status.recordsFailed || status.records_failed} row(s) failed during the build.`
|
|
3465
|
+
}
|
|
3466
|
+
];
|
|
3467
|
+
const blockedReasons = gates.filter((gate) => !gate.passed).map((gate) => gate.detail);
|
|
3468
|
+
const warnings = [
|
|
3469
|
+
rows?.hasMore || rows?.has_more ? "This review is based on a row sample; page through remaining rows before final approval." : void 0,
|
|
3470
|
+
sampledRows > 0 && copyReadyRows < sampledRows ? `${copyReadyRows}/${sampledRows} sampled row(s) include generated copy.` : void 0,
|
|
3471
|
+
...Array.isArray(status?.warnings) ? status.warnings : []
|
|
3472
|
+
].filter(Boolean);
|
|
3473
|
+
const readyForDeliveryApproval = blockedReasons.length === 0;
|
|
3474
|
+
return {
|
|
3475
|
+
campaignBuildId: status.campaignBuildId || status.campaign_build_id || rows.campaignBuildId || rows.campaign_build_id || "",
|
|
3476
|
+
status,
|
|
3477
|
+
rows,
|
|
3478
|
+
artifacts,
|
|
3479
|
+
gates,
|
|
3480
|
+
summary: {
|
|
3481
|
+
status: buildStatus,
|
|
3482
|
+
phase: status.currentPhase || status.current_phase || null,
|
|
3483
|
+
sampledRows,
|
|
3484
|
+
availableRows,
|
|
3485
|
+
qualifiedRows,
|
|
3486
|
+
rowsWithEmail,
|
|
3487
|
+
copyReadyRows,
|
|
3488
|
+
artifactCount,
|
|
3489
|
+
readyForDeliveryApproval,
|
|
3490
|
+
blockedReasons,
|
|
3491
|
+
warnings
|
|
3492
|
+
},
|
|
3493
|
+
nextActions: campaignAgentReviewNextActions(status, readyForDeliveryApproval)
|
|
3494
|
+
};
|
|
3495
|
+
}
|
|
3496
|
+
function campaignAgentReviewNextActions(status, readyForDeliveryApproval) {
|
|
3497
|
+
const buildId = status.campaignBuildId || status.campaign_build_id;
|
|
3498
|
+
const buildStatus = String(status.status || "unknown");
|
|
3499
|
+
if (!buildId) return [];
|
|
3500
|
+
if (buildStatus === "completed" && readyForDeliveryApproval) {
|
|
3501
|
+
return [
|
|
3502
|
+
`signaliz campaign-agent approve ${buildId} --destination-type json`,
|
|
3503
|
+
`signaliz campaign-agent artifacts ${buildId}`
|
|
3504
|
+
];
|
|
3505
|
+
}
|
|
3506
|
+
if (buildStatus === "completed") {
|
|
3507
|
+
return [
|
|
3508
|
+
`signaliz campaign-agent rows ${buildId} --limit 100`,
|
|
3509
|
+
`signaliz campaign-agent artifacts ${buildId}`
|
|
3510
|
+
];
|
|
3511
|
+
}
|
|
3512
|
+
if (buildStatus === "pending_approval") {
|
|
3513
|
+
return [
|
|
3514
|
+
`signaliz campaign-agent rows ${buildId} --limit 100`,
|
|
3515
|
+
`signaliz campaign-agent approve ${buildId} --destination-type json`
|
|
3516
|
+
];
|
|
3517
|
+
}
|
|
3518
|
+
if ((buildStatus === "queued" || buildStatus === "running") && status.triggerRunId) {
|
|
3519
|
+
return [`signaliz ops run-status ${status.triggerRunId} --watch`];
|
|
3520
|
+
}
|
|
3521
|
+
return [`signaliz campaign-agent status ${buildId}`];
|
|
3522
|
+
}
|
|
3360
3523
|
function printCampaignAgentRows(result) {
|
|
3361
3524
|
if (!Array.isArray(result.rows) || result.rows.length === 0) {
|
|
3362
3525
|
console.log("No rows found.");
|