@signaliz/cli 1.0.4 → 1.0.7
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/README.md +86 -0
- package/dist/bin.js +1572 -45
- package/package.json +15 -4
package/dist/bin.js
CHANGED
|
@@ -150,15 +150,28 @@ var promptValueFlags = /* @__PURE__ */ new Set([
|
|
|
150
150
|
"attachment-fields",
|
|
151
151
|
"attachment-file",
|
|
152
152
|
"attachment-url",
|
|
153
|
+
"account-context",
|
|
154
|
+
"account-context-file",
|
|
155
|
+
"account-label",
|
|
156
|
+
"approved-by",
|
|
157
|
+
"approved-route-ids",
|
|
158
|
+
"approved-types",
|
|
159
|
+
"approval-notes",
|
|
160
|
+
"allowed-integrations",
|
|
153
161
|
"blueprint",
|
|
154
162
|
"brain-config-file",
|
|
155
163
|
"brain-config-json",
|
|
164
|
+
"brain-defaults",
|
|
156
165
|
"build-id",
|
|
157
166
|
"cadence",
|
|
158
167
|
"campaign-build-id",
|
|
159
168
|
"campaign-id",
|
|
160
169
|
"campaign-brief",
|
|
170
|
+
"campaign-name",
|
|
161
171
|
"brief",
|
|
172
|
+
"builtins",
|
|
173
|
+
"builtin-tools",
|
|
174
|
+
"byo-tool",
|
|
162
175
|
"company-domains",
|
|
163
176
|
"company-domain",
|
|
164
177
|
"company-name",
|
|
@@ -166,12 +179,15 @@ var promptValueFlags = /* @__PURE__ */ new Set([
|
|
|
166
179
|
"context-json",
|
|
167
180
|
"copy-file",
|
|
168
181
|
"copy-json",
|
|
182
|
+
"custom-tool",
|
|
183
|
+
"customer-tool",
|
|
169
184
|
"destination",
|
|
170
185
|
"destinations",
|
|
171
186
|
"days",
|
|
172
187
|
"dedup-keys",
|
|
173
188
|
"delivery-file",
|
|
174
189
|
"delivery-json",
|
|
190
|
+
"delivery-risk",
|
|
175
191
|
"delivery-risk-file",
|
|
176
192
|
"delivery-risk-json",
|
|
177
193
|
"domains",
|
|
@@ -184,6 +200,9 @@ var promptValueFlags = /* @__PURE__ */ new Set([
|
|
|
184
200
|
"input-json",
|
|
185
201
|
"instantly-campaign-id",
|
|
186
202
|
"idempotency-key",
|
|
203
|
+
"icp",
|
|
204
|
+
"integration-display-name",
|
|
205
|
+
"integration-route",
|
|
187
206
|
"judge-model",
|
|
188
207
|
"layer",
|
|
189
208
|
"layers",
|
|
@@ -193,6 +212,8 @@ var promptValueFlags = /* @__PURE__ */ new Set([
|
|
|
193
212
|
"max-concurrency",
|
|
194
213
|
"max-retries",
|
|
195
214
|
"max-tokens",
|
|
215
|
+
"max-credits",
|
|
216
|
+
"max-credits-without-approval",
|
|
196
217
|
"memory-limit",
|
|
197
218
|
"memory-type",
|
|
198
219
|
"model",
|
|
@@ -202,17 +223,21 @@ var promptValueFlags = /* @__PURE__ */ new Set([
|
|
|
202
223
|
"nango-connection-id",
|
|
203
224
|
"network-days",
|
|
204
225
|
"output-format",
|
|
226
|
+
"output-file",
|
|
205
227
|
"output-fields",
|
|
206
228
|
"output-fields-file",
|
|
207
229
|
"outcome-type",
|
|
208
230
|
"pdf-engine",
|
|
209
231
|
"pdf-url",
|
|
210
232
|
"phases",
|
|
233
|
+
"privacy-mode",
|
|
211
234
|
"policy-file",
|
|
212
235
|
"policy-json",
|
|
236
|
+
"partners",
|
|
213
237
|
"provider",
|
|
214
238
|
"providers",
|
|
215
239
|
"preferred-providers",
|
|
240
|
+
"provider-display-name",
|
|
216
241
|
"provider-account-id",
|
|
217
242
|
"provider-campaign-id",
|
|
218
243
|
"provider-config-key",
|
|
@@ -222,8 +247,10 @@ var promptValueFlags = /* @__PURE__ */ new Set([
|
|
|
222
247
|
"provider-workspace-id",
|
|
223
248
|
"qualification-file",
|
|
224
249
|
"qualification-json",
|
|
250
|
+
"request-file",
|
|
225
251
|
"records-file",
|
|
226
252
|
"records-json",
|
|
253
|
+
"revenue-motion",
|
|
227
254
|
"readiness-json",
|
|
228
255
|
"rationale",
|
|
229
256
|
"route-config-json",
|
|
@@ -232,22 +259,36 @@ var promptValueFlags = /* @__PURE__ */ new Set([
|
|
|
232
259
|
"search",
|
|
233
260
|
"send-config-file",
|
|
234
261
|
"send-config-json",
|
|
262
|
+
"signaliz-tools",
|
|
235
263
|
"signals-file",
|
|
236
264
|
"signals-json",
|
|
265
|
+
"spend-limit",
|
|
266
|
+
"spend-limit-credits",
|
|
237
267
|
"status",
|
|
238
268
|
"status-url",
|
|
269
|
+
"source",
|
|
270
|
+
"strategy-model",
|
|
271
|
+
"strategy-template",
|
|
239
272
|
"system-prompt",
|
|
240
273
|
"target-count",
|
|
274
|
+
"target-icp",
|
|
241
275
|
"target-icp-file",
|
|
242
276
|
"target-icp-json",
|
|
243
277
|
"temperature",
|
|
244
278
|
"tool-name",
|
|
245
279
|
"url",
|
|
280
|
+
"user-display-name",
|
|
281
|
+
"user-email",
|
|
246
282
|
"video-url",
|
|
247
283
|
"write-mode",
|
|
248
284
|
"workspace-connection-id",
|
|
249
285
|
"workspace-integration-id",
|
|
286
|
+
"workspace-label",
|
|
250
287
|
"workspace-mcp-server-id",
|
|
288
|
+
"workspace-context",
|
|
289
|
+
"workspace-context-file",
|
|
290
|
+
"icp-file",
|
|
291
|
+
"brain-defaults-file",
|
|
251
292
|
"memory-dimension-filters-file",
|
|
252
293
|
"memory-dimension-filters-json",
|
|
253
294
|
"metadata-file",
|
|
@@ -272,6 +313,84 @@ function promptArg(rest) {
|
|
|
272
313
|
}
|
|
273
314
|
return parts.join(" ").trim() || void 0;
|
|
274
315
|
}
|
|
316
|
+
function parseCommandFlags(argv) {
|
|
317
|
+
const flags = {};
|
|
318
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
319
|
+
const token = argv[i];
|
|
320
|
+
if (!token.startsWith("--")) continue;
|
|
321
|
+
const eq = token.indexOf("=");
|
|
322
|
+
const name = normalizeCommandFlagName(eq >= 0 ? token.slice(2, eq) : token.slice(2));
|
|
323
|
+
const value = eq >= 0 ? token.slice(eq + 1) : argv[i + 1] && !argv[i + 1].startsWith("--") ? argv[++i] : true;
|
|
324
|
+
const current = flags[name];
|
|
325
|
+
if (current === void 0) {
|
|
326
|
+
flags[name] = value;
|
|
327
|
+
} else if (Array.isArray(current)) {
|
|
328
|
+
current.push(String(value));
|
|
329
|
+
} else {
|
|
330
|
+
flags[name] = [String(current), String(value)];
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return flags;
|
|
334
|
+
}
|
|
335
|
+
function normalizeCommandFlagName(name) {
|
|
336
|
+
return name.replace(/_/g, "-");
|
|
337
|
+
}
|
|
338
|
+
function commandFlagValue(flags, ...names) {
|
|
339
|
+
for (const name of names.map(normalizeCommandFlagName)) {
|
|
340
|
+
if (flags[name] !== void 0) return flags[name];
|
|
341
|
+
}
|
|
342
|
+
return void 0;
|
|
343
|
+
}
|
|
344
|
+
function commandStringFlag(flags, ...names) {
|
|
345
|
+
const value = commandFlagValue(flags, ...names);
|
|
346
|
+
if (Array.isArray(value)) return value.at(-1);
|
|
347
|
+
if (value === void 0 || typeof value === "boolean") return void 0;
|
|
348
|
+
const trimmed = String(value).trim();
|
|
349
|
+
return trimmed || void 0;
|
|
350
|
+
}
|
|
351
|
+
function commandNumberFlag(flags, ...names) {
|
|
352
|
+
const value = commandStringFlag(flags, ...names);
|
|
353
|
+
if (!value) return void 0;
|
|
354
|
+
const parsed = Number(value);
|
|
355
|
+
if (!Number.isFinite(parsed)) die(`Expected numeric value for --${names[0]}`);
|
|
356
|
+
return parsed;
|
|
357
|
+
}
|
|
358
|
+
function commandBooleanFlag(flags, name, defaultValue = false) {
|
|
359
|
+
const value = commandFlagValue(flags, name);
|
|
360
|
+
if (value === void 0) return defaultValue;
|
|
361
|
+
if (Array.isArray(value)) return value.length > 0 ? parseCommandBoolean(value.at(-1), defaultValue) : defaultValue;
|
|
362
|
+
return parseCommandBoolean(value, defaultValue);
|
|
363
|
+
}
|
|
364
|
+
function parseCommandBoolean(value, defaultValue) {
|
|
365
|
+
if (value === void 0) return defaultValue;
|
|
366
|
+
if (typeof value === "boolean") return value;
|
|
367
|
+
return !["0", "false", "no", "off"].includes(value.toLowerCase());
|
|
368
|
+
}
|
|
369
|
+
function commandCsvFlag(flags, ...names) {
|
|
370
|
+
const value = commandFlagValue(flags, ...names);
|
|
371
|
+
const values = Array.isArray(value) ? value : value === void 0 || typeof value === "boolean" ? [] : [value];
|
|
372
|
+
const parsed = values.flatMap((item) => String(item).split(",").map((part) => part.trim()).filter(Boolean));
|
|
373
|
+
return parsed.length > 0 ? parsed : void 0;
|
|
374
|
+
}
|
|
375
|
+
function repeatedCommandStringFlag(flags, ...names) {
|
|
376
|
+
const value = commandFlagValue(flags, ...names);
|
|
377
|
+
if (Array.isArray(value)) return value.map(String).map((item) => item.trim()).filter(Boolean);
|
|
378
|
+
if (value === void 0 || typeof value === "boolean") return [];
|
|
379
|
+
const trimmed = String(value).trim();
|
|
380
|
+
return trimmed ? [trimmed] : [];
|
|
381
|
+
}
|
|
382
|
+
function commandJsonObjectFlag(flags, ...names) {
|
|
383
|
+
const value = commandStringFlag(flags, ...names);
|
|
384
|
+
if (!value) return void 0;
|
|
385
|
+
return parseJsonObjectFromString(value, `--${names[0]}`);
|
|
386
|
+
}
|
|
387
|
+
function parseJsonObjectFromString(value, label) {
|
|
388
|
+
const parsed = JSON.parse(value);
|
|
389
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
390
|
+
die(`${label} must be a JSON object`);
|
|
391
|
+
}
|
|
392
|
+
return parsed;
|
|
393
|
+
}
|
|
275
394
|
function output(data, humanFn) {
|
|
276
395
|
if (jsonMode()) {
|
|
277
396
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -706,7 +825,7 @@ function getSdk() {
|
|
|
706
825
|
try {
|
|
707
826
|
const { Signaliz } = require("@signaliz/sdk");
|
|
708
827
|
const sdk = createSdk(Signaliz);
|
|
709
|
-
if (sdk.campaigns?.buildCampaign && sdk.ops?.listOutputSinks && sdk.leads?.generate && sdk.emails?.verify && sdk.ai?.multiModel && sdk.gtm?.campaignBuildPlan && sdk.gtm?.commitCampaignBuildPlan && sdk.gtm?.prepareCampaignBuildExecution && sdk.gtm?.listNangoTools && sdk.gtm?.callNangoTool && sdk.gtm?.getNangoActionResult && sdk.getPlatformHealth) return sdk;
|
|
828
|
+
if (sdk.campaigns?.buildCampaign && sdk.ops?.listOutputSinks && sdk.leads?.generate && sdk.emails?.verify && sdk.ai?.multiModel && sdk.gtm?.campaignBuildPlan && sdk.gtm?.campaignStrategyTemplates && sdk.gtm?.campaignStartContext && sdk.gtm?.campaignAgentPlan && sdk.gtm?.commitCampaignBuildPlan && sdk.gtm?.prepareCampaignBuildExecution && sdk.gtm?.prepareProviderRecipe && sdk.gtm?.activateProviderRoute && sdk.gtm?.createNangoConnectSession && sdk.gtm?.listNangoTools && sdk.gtm?.callNangoTool && sdk.gtm?.getNangoActionResult && sdk.campaignBuilderAgent?.createPlan && sdk.campaignBuilderAgent?.commitPlan && sdk.campaignBuilderAgent?.dryRunPlan && sdk.campaignBuilderAgent?.buildApprovedPlan && sdk.getPlatformHealth) return sdk;
|
|
710
829
|
primaryError = new Error("SDK missing required GTM workflow APIs");
|
|
711
830
|
} catch (err) {
|
|
712
831
|
primaryError = err;
|
|
@@ -732,19 +851,23 @@ var HELP = `signaliz <command> [options]
|
|
|
732
851
|
|
|
733
852
|
Quick Start:
|
|
734
853
|
signaliz auth login
|
|
854
|
+
|
|
855
|
+
No-spend agent path:
|
|
735
856
|
signaliz start
|
|
736
857
|
signaliz build "Build a campaign for industrial maintenance buyers"
|
|
737
858
|
signaliz connect
|
|
738
859
|
signaliz audit
|
|
739
860
|
signaliz improve <campaign_id>
|
|
740
|
-
signaliz prove
|
|
861
|
+
signaliz prove # alias: signaliz proof
|
|
741
862
|
signaliz health
|
|
742
863
|
signaliz tools
|
|
864
|
+
|
|
865
|
+
Spendful path after review:
|
|
743
866
|
signaliz ops plan "Monitor key accounts daily and alert Slack"
|
|
744
867
|
signaliz ops create "Build 100 verified VP Sales leads" --confirm-spend
|
|
745
868
|
signaliz autopilot
|
|
746
|
-
signaliz execute "Launch a
|
|
747
|
-
signaliz campaign build --prompt "VP Sales at B2B SaaS" --target-count 100
|
|
869
|
+
signaliz execute "Launch a strategy-template campaign for my ICP" --dry-run
|
|
870
|
+
signaliz campaign build --prompt "VP Sales at B2B SaaS" --target-count 100 --dry-run
|
|
748
871
|
signaliz campaign build --prompt "VP Sales at B2B SaaS" --confirm-spend
|
|
749
872
|
signaliz campaign status <campaign_build_id>
|
|
750
873
|
signaliz campaign rows <campaign_build_id> --limit 100
|
|
@@ -760,13 +883,14 @@ Auth:
|
|
|
760
883
|
start Recommend where to begin across Build, Connect, Audit, Improve, and Ops proof
|
|
761
884
|
--campaign-brief "..." Optional brief for the suggested campaign-plan command
|
|
762
885
|
--json Machine-readable onboarding state
|
|
886
|
+
--include-raw Include full raw MCP diagnostics in JSON output
|
|
763
887
|
|
|
764
888
|
Simple Jobs:
|
|
765
889
|
build "brief" Plan a campaign without spending credits
|
|
766
890
|
connect Inspect blocked provider/tool routes
|
|
767
891
|
audit Find previous campaigns to audit
|
|
768
892
|
improve <campaign_id> Plan Brain learning for a campaign
|
|
769
|
-
prove
|
|
893
|
+
prove/proof Prove Ops delivery readiness
|
|
770
894
|
|
|
771
895
|
Discovery:
|
|
772
896
|
tools List available MCP tools
|
|
@@ -825,6 +949,26 @@ GTM Kernel:
|
|
|
825
949
|
--campaign-id ID Optional campaign scope
|
|
826
950
|
--days N Lookback window, default server-side
|
|
827
951
|
--include-samples Include diagnostic samples when supported
|
|
952
|
+
gtm templates List private-safe campaign strategy templates
|
|
953
|
+
--query TEXT Optional text filter
|
|
954
|
+
--strategy-template ID
|
|
955
|
+
Inspect one template
|
|
956
|
+
gtm start-context Build read-only campaign-start MCP runbook
|
|
957
|
+
--strategy-template ID
|
|
958
|
+
Merge a private-safe strategy template
|
|
959
|
+
--target-count N Desired lead count
|
|
960
|
+
gtm strategy-memory Inspect strategy/workflow memory readiness
|
|
961
|
+
--strategy-template ID
|
|
962
|
+
Verify a private-safe strategy template
|
|
963
|
+
--include-samples Include sanitized memory sample metadata
|
|
964
|
+
gtm agent-template Build hosted reusable campaign request JSON
|
|
965
|
+
--strategy-template ID
|
|
966
|
+
Merge a private-safe strategy template
|
|
967
|
+
--with-byo-placeholder
|
|
968
|
+
Add an editable custom MCP route placeholder
|
|
969
|
+
gtm agent-plan Build one-call campaign-agent MCP runbook
|
|
970
|
+
--builtins a,b Native lanes: lead_generation, local_leads, email_finding, email_verification, signals
|
|
971
|
+
--custom-tool ROUTE BYO route: provider:layer:tool[:mcp]
|
|
828
972
|
gtm plan "brief" Compose a read-only GTM Kernel campaign build plan
|
|
829
973
|
--layers a,b Optional GTM layers to plan
|
|
830
974
|
--target-count N Desired lead count
|
|
@@ -872,6 +1016,10 @@ GTM Kernel:
|
|
|
872
1016
|
gtm route-preview Preview the effective provider route for a layer
|
|
873
1017
|
--campaign-id ID Optional campaign scope
|
|
874
1018
|
--layer LAYER Required campaign layer
|
|
1019
|
+
gtm provider-prepare Build read-only BYO provider setup plan
|
|
1020
|
+
--provider-id ID Required provider ID
|
|
1021
|
+
--layer LAYER Optional route preview layer
|
|
1022
|
+
--invocation-type T webhook|mcp_tool|api|airbyte|managed_integration|manual
|
|
875
1023
|
gtm activate-route Dry-run or confirm provider route setup
|
|
876
1024
|
--provider-id ID Required provider ID
|
|
877
1025
|
--layer LAYER Single layer, or use --layers a,b
|
|
@@ -887,6 +1035,9 @@ Native GTM Data Sources:
|
|
|
887
1035
|
gtm find "<intent>" Auto-route a free-text intent to the right capability
|
|
888
1036
|
gtm run --capability ID Run a GTM capability (use --query, --urls, --confirm-spend)
|
|
889
1037
|
gtm status <job_id> Check GTM job status
|
|
1038
|
+
gtm nango connect Start Nango Connect auth for a provider
|
|
1039
|
+
--provider-id ID Provider to authorize, e.g. apollo, hubspot
|
|
1040
|
+
--integration-id ID Optional Nango integration/provider-config key
|
|
890
1041
|
gtm nango tools List Nango action tools for a workspace connection
|
|
891
1042
|
--workspace-connection-id ID
|
|
892
1043
|
Signaliz workspace connection id
|
|
@@ -911,10 +1062,26 @@ Email:
|
|
|
911
1062
|
email status <job_id> Check async email job status
|
|
912
1063
|
|
|
913
1064
|
Campaign Builder:
|
|
914
|
-
campaign
|
|
1065
|
+
campaign-agent init Emit reusable CampaignBuilderAgentRequest JSON
|
|
1066
|
+
--output-file FILE Optional request file to write
|
|
1067
|
+
campaign-agent plan Compose an approval-gated strategy-template MCP flow
|
|
1068
|
+
--goal "..." Campaign goal or brief
|
|
1069
|
+
--request-file FILE Reusable JSON CampaignBuilderAgentRequest
|
|
1070
|
+
--strategy-template ID
|
|
1071
|
+
Merge a private-safe strategy template
|
|
1072
|
+
--builtins a,b lead_generation,local_leads,email_finding,email_verification,signals
|
|
1073
|
+
--custom-tool ROUTE BYO route: provider:layer:tool[:mcp]
|
|
1074
|
+
campaign-agent proof Prove memory, plan, approvals, and build dry-run without spend
|
|
1075
|
+
campaign-agent commit-plan
|
|
1076
|
+
Dry-run or write a reviewed GTM campaign object
|
|
1077
|
+
campaign-agent dry-run Execute build_campaign with dry_run=true
|
|
1078
|
+
campaign-agent build-approved
|
|
1079
|
+
Launch only after explicit approval metadata
|
|
1080
|
+
|
|
1081
|
+
campaign scope Scope a workspace/account campaign into a markdown brief + dry-run args
|
|
915
1082
|
--prompt "..." Campaign request or outcome (required)
|
|
916
|
-
--
|
|
917
|
-
--
|
|
1083
|
+
--account-label NAME Workspace/account label
|
|
1084
|
+
--account-context-file FILE
|
|
918
1085
|
Markdown/notes with ICP, exclusions, offer, proof, approvals
|
|
919
1086
|
--target-count N Desired target count
|
|
920
1087
|
--destinations csv,instantly,slack
|
|
@@ -928,6 +1095,7 @@ Campaign Builder:
|
|
|
928
1095
|
--dry-run Validate and plan without launching spendful work
|
|
929
1096
|
--allow-downscale Allow oversized target counts to be clamped
|
|
930
1097
|
--confirm-spend Acknowledge spendful generation after approval prompts
|
|
1098
|
+
--no-progress Hide wait-mode progress on stderr
|
|
931
1099
|
--webhook-url URL Webhook delivery endpoint
|
|
932
1100
|
--input-file FILE JSON config file (overrides flags)
|
|
933
1101
|
--wait Poll until completion
|
|
@@ -1068,17 +1236,41 @@ New-user path:
|
|
|
1068
1236
|
signaliz auth login
|
|
1069
1237
|
signaliz gtm context
|
|
1070
1238
|
signaliz gtm bootstrap --include-samples
|
|
1239
|
+
signaliz gtm templates
|
|
1240
|
+
signaliz gtm start-context --strategy-template non-medical-home-care --json
|
|
1241
|
+
signaliz gtm strategy-memory --strategy-template non-medical-home-care --include-samples --json
|
|
1242
|
+
signaliz gtm agent-template --strategy-template non-medical-home-care --target-count 250 --with-byo-placeholder --json
|
|
1243
|
+
signaliz gtm agent-plan --strategy-template non-medical-home-care --target-count 100 --json
|
|
1071
1244
|
signaliz gtm plan "Find CTOs at Series B fintech companies" --target-count 100 --json > plan.json
|
|
1072
1245
|
signaliz gtm commit-plan --plan-file plan.json
|
|
1073
1246
|
signaliz gtm commit-plan --plan-file plan.json --confirm
|
|
1074
1247
|
signaliz gtm integrations --include-planned
|
|
1248
|
+
signaliz gtm provider-prepare --provider-id customer_mcp --layer company_enrichment --invocation-type mcp_tool
|
|
1075
1249
|
signaliz gtm activate-route --provider-id instantly --layer sender
|
|
1076
1250
|
signaliz gtm prepare-build <campaign_id> --build-input --json > build-args.json
|
|
1077
1251
|
signaliz campaign build --input-file build-args.json --confirm-spend
|
|
1252
|
+
signaliz campaign-agent init --strategy-template non-medical-home-care --target-count 250 --use-local-leads --json > campaign-request.json
|
|
1253
|
+
signaliz campaign-agent plan --goal "Build a strategy-template campaign for my ICP" --strategy-template non-medical-home-care --json
|
|
1254
|
+
signaliz campaign-agent dry-run --goal "Build a strategy-template campaign for my ICP" --target-count 100 --json
|
|
1078
1255
|
|
|
1079
1256
|
Read-only planning:
|
|
1080
1257
|
context Inspect GTM Kernel workspace context
|
|
1081
1258
|
bootstrap Inspect Kernel + Brain readiness gates
|
|
1259
|
+
templates List private-safe campaign strategy templates
|
|
1260
|
+
start-context Build read-only Memory, Brain, risk, and route runbook
|
|
1261
|
+
strategy-memory Inspect strategy/workflow memory readiness
|
|
1262
|
+
agent-template Build hosted reusable campaign request JSON
|
|
1263
|
+
--goal TEXT Campaign goal or brief
|
|
1264
|
+
--strategy-template ID
|
|
1265
|
+
Strategy template to merge
|
|
1266
|
+
--with-byo-placeholder
|
|
1267
|
+
Add an editable custom MCP route placeholder
|
|
1268
|
+
agent-plan Build one-call campaign-agent MCP runbook
|
|
1269
|
+
--goal TEXT Campaign goal or brief
|
|
1270
|
+
--strategy-template ID
|
|
1271
|
+
Strategy template to merge
|
|
1272
|
+
--builtins a,b Native lanes to include
|
|
1273
|
+
--custom-tool ROUTE BYO route: provider:layer:tool[:mcp]
|
|
1082
1274
|
plan "brief" Compose Memory, Brain, failure, and provider-route plan
|
|
1083
1275
|
--campaign-id ID Optional existing campaign scope
|
|
1084
1276
|
--campaign-build-id ID
|
|
@@ -1113,6 +1305,7 @@ Status and repair:
|
|
|
1113
1305
|
execution <id> Inspect execution/provider readiness
|
|
1114
1306
|
integrations Inspect provider activation cards
|
|
1115
1307
|
route-preview Preview effective route for a layer
|
|
1308
|
+
provider-prepare Build read-only recipe, route, and preview arguments
|
|
1116
1309
|
activate-route Dry-run or confirm provider route setup
|
|
1117
1310
|
feedback-webhook Prepare feedback ingress
|
|
1118
1311
|
learning <id> Plan Brain learning
|
|
@@ -1153,6 +1346,132 @@ Options:
|
|
|
1153
1346
|
--include-samples Include safe sample rows/evidence where available
|
|
1154
1347
|
--min-sample-size N Minimum sample size for Brain/readiness checks
|
|
1155
1348
|
--json Machine-readable output
|
|
1349
|
+
`,
|
|
1350
|
+
templates: `signaliz gtm templates [options]
|
|
1351
|
+
|
|
1352
|
+
List private-safe campaign strategy templates that can be merged into
|
|
1353
|
+
gtm_campaign_build_plan with --strategy-template.
|
|
1354
|
+
|
|
1355
|
+
Options:
|
|
1356
|
+
--query TEXT Filter by ICP, motion, provider, or keyword
|
|
1357
|
+
--strategy-template ID Inspect one template
|
|
1358
|
+
--summary Return compact summaries instead of full ICP details
|
|
1359
|
+
--json Machine-readable output
|
|
1360
|
+
`,
|
|
1361
|
+
"strategy-templates": `signaliz gtm strategy-templates [options]
|
|
1362
|
+
|
|
1363
|
+
Alias for signaliz gtm templates.
|
|
1364
|
+
`,
|
|
1365
|
+
"start-context": `signaliz gtm start-context [options]
|
|
1366
|
+
|
|
1367
|
+
Build a read-only MCP runbook for the campaign start: ranked memory, Brain
|
|
1368
|
+
defaults, delivery risk, failure patterns, provider-route previews, and final
|
|
1369
|
+
gtm_campaign_build_plan arguments.
|
|
1370
|
+
|
|
1371
|
+
Options:
|
|
1372
|
+
--brief TEXT Campaign request or goal
|
|
1373
|
+
--campaign-id ID Optional existing campaign scope
|
|
1374
|
+
--campaign-build-id ID Optional Campaign Builder build scope
|
|
1375
|
+
--strategy-template ID Strategy template to merge
|
|
1376
|
+
--target-count N Desired lead count
|
|
1377
|
+
--layers a,b GTM layers to include
|
|
1378
|
+
--preferred-providers a,b
|
|
1379
|
+
Provider preferences for route planning
|
|
1380
|
+
--target-icp-json JSON Structured ICP object
|
|
1381
|
+
--target-icp-file FILE Structured ICP JSON file
|
|
1382
|
+
--no-memory Skip workspace memory call
|
|
1383
|
+
--no-brain Skip Brain defaults call
|
|
1384
|
+
--no-provider-routes Skip provider-route calls
|
|
1385
|
+
--no-failure-patterns Skip Brain failure-pattern call
|
|
1386
|
+
--no-delivery-risk Skip delivery-risk call
|
|
1387
|
+
--json Machine-readable output
|
|
1388
|
+
`,
|
|
1389
|
+
start: `signaliz gtm start [options]
|
|
1390
|
+
|
|
1391
|
+
Alias for signaliz gtm start-context.
|
|
1392
|
+
`,
|
|
1393
|
+
"strategy-memory": `signaliz gtm strategy-memory [options]
|
|
1394
|
+
|
|
1395
|
+
Inspect private-safe strategy/workflow memory readiness before campaign planning.
|
|
1396
|
+
|
|
1397
|
+
Options:
|
|
1398
|
+
--query TEXT Campaign goal or memory query
|
|
1399
|
+
--strategy-template ID Strategy template to verify
|
|
1400
|
+
--target-icp-json JSON Structured ICP object
|
|
1401
|
+
--target-icp-file FILE Structured ICP JSON file
|
|
1402
|
+
--memory-dimension-filters-json JSON
|
|
1403
|
+
Structured memory filters
|
|
1404
|
+
--include-samples Include sanitized memory sample metadata
|
|
1405
|
+
--no-sources Omit source-group details
|
|
1406
|
+
--json Machine-readable output
|
|
1407
|
+
`,
|
|
1408
|
+
"memory-status": `signaliz gtm memory-status [options]
|
|
1409
|
+
|
|
1410
|
+
Alias for signaliz gtm strategy-memory.
|
|
1411
|
+
`,
|
|
1412
|
+
"strategy-memory-status": `signaliz gtm strategy-memory-status [options]
|
|
1413
|
+
|
|
1414
|
+
Alias for signaliz gtm strategy-memory.
|
|
1415
|
+
`,
|
|
1416
|
+
"agent-template": `signaliz gtm agent-template [options]
|
|
1417
|
+
|
|
1418
|
+
Build hosted reusable CampaignBuilderAgentRequest JSON from a strategy template,
|
|
1419
|
+
Signaliz-native lanes, private memory settings, Nango catalog preference, and an
|
|
1420
|
+
optional editable BYO integration placeholder.
|
|
1421
|
+
|
|
1422
|
+
Options:
|
|
1423
|
+
--goal TEXT Campaign goal or brief
|
|
1424
|
+
--campaign-name NAME Optional private-safe campaign label
|
|
1425
|
+
--workspace-label NAME Optional private-safe workspace/account label
|
|
1426
|
+
--account-context TEXT Optional private-safe ICP, offer, or approval context
|
|
1427
|
+
--strategy-template ID Strategy template to merge
|
|
1428
|
+
--operating-playbooks a,b
|
|
1429
|
+
Optional playbook slugs to apply with the template
|
|
1430
|
+
--target-count N Desired lead/account count
|
|
1431
|
+
--target-icp-json JSON Structured ICP object
|
|
1432
|
+
--target-icp-file FILE Structured ICP JSON file
|
|
1433
|
+
--builtins a,b lead_generation,local_leads,email_finding,email_verification,signals
|
|
1434
|
+
--use-local-leads Add the local_leads native lane
|
|
1435
|
+
--with-byo-placeholder Add an editable custom MCP route placeholder
|
|
1436
|
+
--preferred-providers a,b
|
|
1437
|
+
Provider preferences or BYO provider ids
|
|
1438
|
+
--privacy-mode MODE workspace_only, anonymized_patterns, opt_in_network
|
|
1439
|
+
--destination TYPE json, csv, webhook
|
|
1440
|
+
--json Machine-readable output
|
|
1441
|
+
`,
|
|
1442
|
+
"campaign-agent-template": `signaliz gtm campaign-agent-template [options]
|
|
1443
|
+
|
|
1444
|
+
Alias for signaliz gtm agent-template.
|
|
1445
|
+
`,
|
|
1446
|
+
"request-template": `signaliz gtm request-template [options]
|
|
1447
|
+
|
|
1448
|
+
Alias for signaliz gtm agent-template.
|
|
1449
|
+
`,
|
|
1450
|
+
"agent-plan": `signaliz gtm agent-plan [options]
|
|
1451
|
+
|
|
1452
|
+
Build a one-call, read-only campaign-agent MCP runbook from a strategy template,
|
|
1453
|
+
Signaliz-native lanes, Memory, Brain, Nango discovery, and BYO integration routes.
|
|
1454
|
+
|
|
1455
|
+
Options:
|
|
1456
|
+
--goal TEXT Campaign goal or brief
|
|
1457
|
+
--campaign-name NAME Optional private-safe campaign label
|
|
1458
|
+
--campaign-id ID Optional existing campaign scope
|
|
1459
|
+
--campaign-build-id ID Optional Campaign Builder build scope
|
|
1460
|
+
--strategy-template ID Strategy template to merge
|
|
1461
|
+
--target-count N Desired lead/account count
|
|
1462
|
+
--target-icp-json JSON Structured ICP object
|
|
1463
|
+
--target-icp-file FILE Structured ICP JSON file
|
|
1464
|
+
--builtins a,b lead_generation,local_leads,email_finding,email_verification,signals
|
|
1465
|
+
--use-local-leads Add the local_leads native lane
|
|
1466
|
+
--custom-tool ROUTE BYO route: provider:layer:tool[:mcp] or key=value pairs
|
|
1467
|
+
--preferred-providers a,b
|
|
1468
|
+
Provider preferences or BYO provider ids
|
|
1469
|
+
--no-delivery-risk Skip delivery-risk preflight
|
|
1470
|
+
--json Machine-readable output
|
|
1471
|
+
`,
|
|
1472
|
+
"campaign-agent-plan": `signaliz gtm campaign-agent-plan [options]
|
|
1473
|
+
|
|
1474
|
+
Alias for signaliz gtm agent-plan.
|
|
1156
1475
|
`,
|
|
1157
1476
|
plan: `signaliz gtm plan "campaign brief" [options]
|
|
1158
1477
|
|
|
@@ -1162,10 +1481,16 @@ defaults, failure intelligence, provider routes, and approval boundaries.
|
|
|
1162
1481
|
Options:
|
|
1163
1482
|
--campaign-id ID Optional existing campaign scope
|
|
1164
1483
|
--campaign-build-id ID Optional Campaign Builder build scope
|
|
1484
|
+
--strategy-template ID Strategy template: industrial-ot-resilience, non-medical-home-care, agency-founder-led, cloud-infrastructure-displacement
|
|
1165
1485
|
--target-count N Desired lead count
|
|
1166
1486
|
--layers a,b GTM layers to include
|
|
1167
1487
|
--preferred-providers a,b
|
|
1168
1488
|
Provider preferences for route planning
|
|
1489
|
+
--strategy-model custom Optional custom strategy model override
|
|
1490
|
+
--partners a,b Partner/tool ecosystem hints
|
|
1491
|
+
--no-agency-patterns Disable default private strategy pattern hints
|
|
1492
|
+
--no-workflow-patterns Disable default workflow table pattern hints
|
|
1493
|
+
--no-nango-catalog Skip Nango tool catalog discovery
|
|
1169
1494
|
--target-icp-json JSON Structured ICP object
|
|
1170
1495
|
--target-icp-file FILE Structured ICP JSON file
|
|
1171
1496
|
--include-planned Include planned/needs-setup providers
|
|
@@ -1176,7 +1501,7 @@ Options:
|
|
|
1176
1501
|
--json Machine-readable output
|
|
1177
1502
|
|
|
1178
1503
|
Safe next step:
|
|
1179
|
-
signaliz gtm plan "Find CTOs at fintech startups" --target-count 100 --json > plan.json
|
|
1504
|
+
signaliz gtm plan "Find CTOs at fintech startups" --strategy-template cloud-infrastructure-displacement --target-count 100 --json > plan.json
|
|
1180
1505
|
signaliz gtm commit-plan --plan-file plan.json
|
|
1181
1506
|
`,
|
|
1182
1507
|
"build-plan": `signaliz gtm build-plan "campaign brief" [options]
|
|
@@ -1322,6 +1647,34 @@ Options:
|
|
|
1322
1647
|
"preview-route": `signaliz gtm preview-route --layer <layer> [options]
|
|
1323
1648
|
|
|
1324
1649
|
Alias for signaliz gtm route-preview.
|
|
1650
|
+
`,
|
|
1651
|
+
"provider-prepare": `signaliz gtm provider-prepare --provider-id <provider_id> [options]
|
|
1652
|
+
|
|
1653
|
+
Build a read-only BYO provider setup plan. Returns exact recipe, route,
|
|
1654
|
+
preview, and activation arguments without writing state or calling providers.
|
|
1655
|
+
|
|
1656
|
+
Options:
|
|
1657
|
+
--provider-id ID Provider id, for example customer_mcp
|
|
1658
|
+
--provider-name NAME Display name for the provider
|
|
1659
|
+
--layer NAME Layer to preview route setup for
|
|
1660
|
+
--layers a,b Recipe layer capabilities
|
|
1661
|
+
--invocation-type TYPE webhook|mcp_tool|api|airbyte|managed_integration|manual
|
|
1662
|
+
--auth-strategy TYPE none|integration_key|mcp_auth|webhook_secret|session_vault|byo_runtime
|
|
1663
|
+
--endpoint-url URL Webhook or API endpoint
|
|
1664
|
+
--workspace-mcp-server-id ID
|
|
1665
|
+
Existing workspace MCP server reference
|
|
1666
|
+
--workspace-connection-id ID
|
|
1667
|
+
Existing workspace connection reference
|
|
1668
|
+
--no-signaliz-fallback Disable Signaliz fallback for route preview
|
|
1669
|
+
--json Machine-readable output
|
|
1670
|
+
`,
|
|
1671
|
+
"prepare-provider": `signaliz gtm prepare-provider --provider-id <provider_id> [options]
|
|
1672
|
+
|
|
1673
|
+
Alias for signaliz gtm provider-prepare.
|
|
1674
|
+
`,
|
|
1675
|
+
"recipe-prepare": `signaliz gtm recipe-prepare --provider-id <provider_id> [options]
|
|
1676
|
+
|
|
1677
|
+
Alias for signaliz gtm provider-prepare.
|
|
1325
1678
|
`,
|
|
1326
1679
|
"activate-route": `signaliz gtm activate-route --provider-id <provider_id> --layer <layer> [options]
|
|
1327
1680
|
|
|
@@ -1397,6 +1750,185 @@ function gtmHelpFor(sub) {
|
|
|
1397
1750
|
if (!sub) return GTM_HELP;
|
|
1398
1751
|
return GTM_COMMAND_HELP[sub] || GTM_HELP;
|
|
1399
1752
|
}
|
|
1753
|
+
var OPS_COMMAND_HELP = {
|
|
1754
|
+
proof: `signaliz ops proof [options]
|
|
1755
|
+
|
|
1756
|
+
Show whether Ops delivery is proven before scaling a GTM motion.
|
|
1757
|
+
|
|
1758
|
+
Options:
|
|
1759
|
+
--window-hours N Delivery receipt lookback, default 720
|
|
1760
|
+
--json Machine-readable output
|
|
1761
|
+
`,
|
|
1762
|
+
autopilot: `signaliz ops autopilot [options]
|
|
1763
|
+
|
|
1764
|
+
Recommend the next best GTM motion from proof state.
|
|
1765
|
+
|
|
1766
|
+
Options:
|
|
1767
|
+
--window-hours N Delivery receipt lookback, default 720
|
|
1768
|
+
--json Machine-readable output
|
|
1769
|
+
`,
|
|
1770
|
+
plan: `signaliz ops plan "plain-English GTM goal" [options]
|
|
1771
|
+
|
|
1772
|
+
Preview a prompt-first Op plan without creating anything or spending credits.
|
|
1773
|
+
|
|
1774
|
+
Options:
|
|
1775
|
+
--blueprint NAME monitor_companies|build_leads|enrich_list|route_signals|launch_campaign
|
|
1776
|
+
--target-count N Target row count
|
|
1777
|
+
--cadence NAME manual|hourly|daily|weekly
|
|
1778
|
+
--destinations a,b Destinations such as json,csv,slack,airbyte,nango
|
|
1779
|
+
--company-domains a,b Explicit account/domain list
|
|
1780
|
+
--json Machine-readable output
|
|
1781
|
+
|
|
1782
|
+
Safe next step:
|
|
1783
|
+
signaliz ops create "same goal" --confirm-spend
|
|
1784
|
+
`,
|
|
1785
|
+
create: `signaliz ops create "plain-English GTM goal" [options]
|
|
1786
|
+
|
|
1787
|
+
Create a persistent Op from a prompt. Requires --confirm-spend for spendful
|
|
1788
|
+
work; otherwise the API returns an approval receipt and retry arguments.
|
|
1789
|
+
|
|
1790
|
+
Options:
|
|
1791
|
+
--confirm-spend Acknowledge estimated credits/external writes
|
|
1792
|
+
--activate Create as active instead of draft
|
|
1793
|
+
--target-count N Target row count
|
|
1794
|
+
--destinations a,b Destinations such as json,csv,slack,airbyte,nango
|
|
1795
|
+
--company-domains a,b Explicit account/domain list
|
|
1796
|
+
--json Machine-readable output
|
|
1797
|
+
|
|
1798
|
+
Safe next step:
|
|
1799
|
+
signaliz ops run <op_id>
|
|
1800
|
+
`,
|
|
1801
|
+
execute: `signaliz ops execute "plain-English GTM goal" [options]
|
|
1802
|
+
|
|
1803
|
+
One-call agent path: plan, create, and safely run an Op when approved.
|
|
1804
|
+
|
|
1805
|
+
Options:
|
|
1806
|
+
--dry-run Return the plan and next step without creating anything
|
|
1807
|
+
--confirm-spend Acknowledge estimated credits/external writes
|
|
1808
|
+
--auto-run Run immediately after create when safe
|
|
1809
|
+
--no-auto-run Create only
|
|
1810
|
+
--target-count N Target row count
|
|
1811
|
+
--destinations a,b Destinations such as json,csv,slack,airbyte,nango
|
|
1812
|
+
--json Machine-readable output
|
|
1813
|
+
`,
|
|
1814
|
+
run: `signaliz ops run <op_id> [options]
|
|
1815
|
+
|
|
1816
|
+
Run a created Op immediately.
|
|
1817
|
+
`,
|
|
1818
|
+
status: `signaliz ops status <op_id> [options]
|
|
1819
|
+
|
|
1820
|
+
Check simple Op status and next action.
|
|
1821
|
+
`,
|
|
1822
|
+
results: `signaliz ops results <op_id> [options]
|
|
1823
|
+
|
|
1824
|
+
Retrieve latest Op results.
|
|
1825
|
+
|
|
1826
|
+
Options:
|
|
1827
|
+
--limit N Page size, default 100, max 500
|
|
1828
|
+
--cursor ID Pagination cursor
|
|
1829
|
+
--include-failed-runs Include failed run output when supported
|
|
1830
|
+
--json Machine-readable output
|
|
1831
|
+
`
|
|
1832
|
+
};
|
|
1833
|
+
function opsHelpFor(sub) {
|
|
1834
|
+
if (!sub) {
|
|
1835
|
+
return `signaliz ops <command> [options]
|
|
1836
|
+
|
|
1837
|
+
Canonical path:
|
|
1838
|
+
signaliz ops plan "Build 100 verified VP Sales leads"
|
|
1839
|
+
signaliz ops create "Build 100 verified VP Sales leads" --confirm-spend
|
|
1840
|
+
signaliz ops run <op_id>
|
|
1841
|
+
signaliz ops status <op_id>
|
|
1842
|
+
signaliz ops results <op_id>
|
|
1843
|
+
|
|
1844
|
+
Common commands:
|
|
1845
|
+
proof, autopilot, plan, execute, create, run, status, results, doctor, connections
|
|
1846
|
+
|
|
1847
|
+
Run: signaliz ops help <command>
|
|
1848
|
+
`;
|
|
1849
|
+
}
|
|
1850
|
+
return OPS_COMMAND_HELP[sub] || opsHelpFor(void 0);
|
|
1851
|
+
}
|
|
1852
|
+
var CAMPAIGN_COMMAND_HELP = {
|
|
1853
|
+
scope: `signaliz campaign scope --prompt "campaign request" [options]
|
|
1854
|
+
|
|
1855
|
+
Turn a campaign brief into a markdown scope, Brain preflight, and
|
|
1856
|
+
ready-to-run build_campaign dry-run arguments.
|
|
1857
|
+
|
|
1858
|
+
Options:
|
|
1859
|
+
--account-label NAME Workspace/account label
|
|
1860
|
+
--account-context-file FILE
|
|
1861
|
+
Markdown notes with ICP, exclusions, offer, proof, approvals
|
|
1862
|
+
--target-count N Desired target count
|
|
1863
|
+
--destinations a,b json,csv,webhook,instantly,slack,airbyte,nango
|
|
1864
|
+
--json Machine-readable output
|
|
1865
|
+
`,
|
|
1866
|
+
build: `signaliz campaign build --prompt "lead search prompt" [options]
|
|
1867
|
+
|
|
1868
|
+
Start a campaign build. Use --dry-run first to validate; add --confirm-spend
|
|
1869
|
+
only after reviewing estimated credits and output risk.
|
|
1870
|
+
|
|
1871
|
+
Options:
|
|
1872
|
+
--target-count N Number of leads, default 50
|
|
1873
|
+
--outputs json,csv Delivery outputs, default json
|
|
1874
|
+
--dry-run Validate and plan without launching spendful work
|
|
1875
|
+
--allow-downscale Allow oversized target counts to be clamped
|
|
1876
|
+
--confirm-spend Acknowledge spendful generation
|
|
1877
|
+
--input-file FILE JSON config file from campaign scope or gtm prepare-build
|
|
1878
|
+
--wait Poll until completion
|
|
1879
|
+
--json Machine-readable output
|
|
1880
|
+
|
|
1881
|
+
Safe next step:
|
|
1882
|
+
signaliz campaign status <campaign_build_id>
|
|
1883
|
+
`,
|
|
1884
|
+
status: `signaliz campaign status <campaign_build_id> [options]
|
|
1885
|
+
|
|
1886
|
+
Check build status, phase progress, warnings, errors, and next action.
|
|
1887
|
+
`,
|
|
1888
|
+
rows: `signaliz campaign rows <campaign_build_id> [options]
|
|
1889
|
+
|
|
1890
|
+
Retrieve generated campaign rows.
|
|
1891
|
+
|
|
1892
|
+
Options:
|
|
1893
|
+
--limit N Page size, default 50, max 500
|
|
1894
|
+
--cursor ID Pagination cursor
|
|
1895
|
+
--qualified Only qualified rows
|
|
1896
|
+
--disqualified Only disqualified rows
|
|
1897
|
+
--all Dump all rows
|
|
1898
|
+
--json Machine-readable output
|
|
1899
|
+
`,
|
|
1900
|
+
artifacts: `signaliz campaign artifacts <campaign_build_id> [options]
|
|
1901
|
+
|
|
1902
|
+
List generated artifacts and signed download URLs.
|
|
1903
|
+
`,
|
|
1904
|
+
approve: `signaliz campaign approve <campaign_build_id> --destination-type <json|csv|webhook>
|
|
1905
|
+
|
|
1906
|
+
Approve pending delivery after human review.
|
|
1907
|
+
`,
|
|
1908
|
+
cancel: `signaliz campaign cancel <campaign_build_id> [options]
|
|
1909
|
+
|
|
1910
|
+
Cancel a running build.
|
|
1911
|
+
`
|
|
1912
|
+
};
|
|
1913
|
+
function campaignHelpFor(sub) {
|
|
1914
|
+
if (!sub) {
|
|
1915
|
+
return `signaliz campaign <command> [options]
|
|
1916
|
+
|
|
1917
|
+
Canonical path:
|
|
1918
|
+
signaliz campaign scope --prompt "Build a campaign for my ICP"
|
|
1919
|
+
signaliz campaign build --prompt "VP Sales at B2B SaaS" --dry-run
|
|
1920
|
+
signaliz campaign build --prompt "VP Sales at B2B SaaS" --confirm-spend --wait
|
|
1921
|
+
signaliz campaign rows <campaign_build_id> --limit 100
|
|
1922
|
+
signaliz campaign artifacts <campaign_build_id>
|
|
1923
|
+
|
|
1924
|
+
Commands:
|
|
1925
|
+
scope, build, status, rows, artifacts, approve, cancel
|
|
1926
|
+
|
|
1927
|
+
Run: signaliz campaign help <command>
|
|
1928
|
+
`;
|
|
1929
|
+
}
|
|
1930
|
+
return CAMPAIGN_COMMAND_HELP[sub] || campaignHelpFor(void 0);
|
|
1931
|
+
}
|
|
1400
1932
|
function isHelpRequest(args) {
|
|
1401
1933
|
return args[0] === "help" || args.includes("--help") || args.includes("-h");
|
|
1402
1934
|
}
|
|
@@ -1568,6 +2100,16 @@ async function start() {
|
|
|
1568
2100
|
const bootstrap = bootstrapState.ok ? record(bootstrapState.data) : {};
|
|
1569
2101
|
const integrations = integrationsState.ok ? record(integrationsState.data) : {};
|
|
1570
2102
|
const integrationSummary = record(integrations.summary);
|
|
2103
|
+
const integrationLayers = firstArray(
|
|
2104
|
+
integrations.layers || integrations.route_cards || integrations.items || integrations.routes
|
|
2105
|
+
);
|
|
2106
|
+
const providerBlockers = integrationLayers.filter((layer) => layer.ready === false || layer.status === "needs_route" || layer.status === "blocked").map((layer) => ({
|
|
2107
|
+
layer: layer.layer,
|
|
2108
|
+
label: layer.label || layer.layer,
|
|
2109
|
+
status: layer.status || (layer.ready === false ? "blocked" : "unknown"),
|
|
2110
|
+
blockers: firstArray(record(layer.readiness).blockers || layer.blockers),
|
|
2111
|
+
next_tools: firstArray(layer.next_tools || layer.nextTools)
|
|
2112
|
+
}));
|
|
1571
2113
|
const gates = firstArray(bootstrap.gates);
|
|
1572
2114
|
const readyGates = gates.filter((gate) => gate.ready === true || gate.status === "ready").length;
|
|
1573
2115
|
const blockedLayers = Number(integrationSummary.blocked_layers || 0);
|
|
@@ -1613,7 +2155,8 @@ async function start() {
|
|
|
1613
2155
|
kernel_gates_total: gates.length,
|
|
1614
2156
|
provider_layers_ready: readyLayers,
|
|
1615
2157
|
provider_layers_total: totalLayers,
|
|
1616
|
-
provider_layers_blocked: blockedLayers
|
|
2158
|
+
provider_layers_blocked: blockedLayers,
|
|
2159
|
+
provider_blockers: providerBlockers
|
|
1617
2160
|
},
|
|
1618
2161
|
next_move: {
|
|
1619
2162
|
title: nextMove,
|
|
@@ -1621,13 +2164,15 @@ async function start() {
|
|
|
1621
2164
|
command: nextCommand
|
|
1622
2165
|
},
|
|
1623
2166
|
safe_commands: commands,
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
2167
|
+
...hasFlag("include-raw") || hasFlag("verbose") ? {
|
|
2168
|
+
raw_status: {
|
|
2169
|
+
workspace: workspaceState,
|
|
2170
|
+
platform: platformState,
|
|
2171
|
+
ops_proof: proofState,
|
|
2172
|
+
gtm_bootstrap: bootstrapState,
|
|
2173
|
+
gtm_integrations: integrationsState
|
|
2174
|
+
}
|
|
2175
|
+
} : {}
|
|
1631
2176
|
};
|
|
1632
2177
|
return output(result, () => {
|
|
1633
2178
|
console.log("Signaliz start");
|
|
@@ -1835,6 +2380,10 @@ async function ai(sub, rest) {
|
|
|
1835
2380
|
});
|
|
1836
2381
|
}
|
|
1837
2382
|
async function campaignBuild() {
|
|
2383
|
+
if (isHelpRequest(process.argv.slice(4))) {
|
|
2384
|
+
process.stdout.write(campaignHelpFor("build"));
|
|
2385
|
+
return;
|
|
2386
|
+
}
|
|
1838
2387
|
const sdk = getSdk();
|
|
1839
2388
|
let config;
|
|
1840
2389
|
const inputFile = flagArg("input-file");
|
|
@@ -1915,17 +2464,24 @@ async function campaignBuild() {
|
|
|
1915
2464
|
if (hasFlag("wait")) {
|
|
1916
2465
|
if (!result.campaignBuildId) die("Campaign build did not return a campaign_build_id to poll");
|
|
1917
2466
|
info("\nPolling for completion...");
|
|
2467
|
+
let lastProgressLine = "";
|
|
1918
2468
|
const finalStatus = await sdk.campaigns.waitForCompletion(result.campaignBuildId, {
|
|
1919
2469
|
intervalMs: 5e3,
|
|
1920
2470
|
onStatus: (s) => {
|
|
1921
|
-
if (
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
)
|
|
2471
|
+
if (hasFlag("no-progress")) return;
|
|
2472
|
+
const line = `[${s.status}] phase=${s.currentPhase ?? "N/A"} rows=${s.recordsSucceeded}/${s.recordsTotal} artifacts=${s.artifactCount}`;
|
|
2473
|
+
if (jsonMode()) {
|
|
2474
|
+
if (line !== lastProgressLine) {
|
|
2475
|
+
process.stderr.write(`signaliz campaign build: ${line}
|
|
2476
|
+
`);
|
|
2477
|
+
lastProgressLine = line;
|
|
2478
|
+
}
|
|
2479
|
+
return;
|
|
1925
2480
|
}
|
|
2481
|
+
process.stderr.write(`\r ${line} `);
|
|
1926
2482
|
}
|
|
1927
2483
|
});
|
|
1928
|
-
if (!jsonMode()) process.stderr.write("\n");
|
|
2484
|
+
if (!jsonMode() && !hasFlag("no-progress")) process.stderr.write("\n");
|
|
1929
2485
|
output(jsonMode() ? { initial: result, final: finalStatus } : finalStatus, () => {
|
|
1930
2486
|
console.log(`
|
|
1931
2487
|
\u2713 Build ${finalStatus.status}`);
|
|
@@ -1941,15 +2497,15 @@ async function campaignScope() {
|
|
|
1941
2497
|
const sdk = getSdk();
|
|
1942
2498
|
const promptText = flagArg("prompt") || positionalAfter("scope");
|
|
1943
2499
|
if (!promptText) {
|
|
1944
|
-
die('--prompt is required. Example: signaliz campaign scope --prompt "Build a
|
|
2500
|
+
die('--prompt is required. Example: signaliz campaign scope --prompt "Build a home-care strategy home care campaign"');
|
|
1945
2501
|
}
|
|
1946
|
-
const contextFile = flagArg("
|
|
2502
|
+
const contextFile = flagArg("account-context-file") || flagArg("workspace-context-file");
|
|
1947
2503
|
const targetCount = numberFlag("target-count");
|
|
1948
2504
|
const destinations = csvFlag("destinations")?.map((type) => ({ type }));
|
|
1949
2505
|
const result = await sdk.campaigns.scopeCampaign({
|
|
1950
2506
|
prompt: promptText,
|
|
1951
|
-
|
|
1952
|
-
|
|
2507
|
+
accountLabel: flagArg("account-label") || flagArg("workspace-label"),
|
|
2508
|
+
accountContext: contextFile ? (0, import_node_fs.readFileSync)(contextFile, "utf8") : flagArg("account-context") || flagArg("workspace-context"),
|
|
1953
2509
|
campaignGoal: flagArg("campaign-goal"),
|
|
1954
2510
|
targetCount,
|
|
1955
2511
|
destinations,
|
|
@@ -1986,14 +2542,29 @@ async function campaignStatus() {
|
|
|
1986
2542
|
console.log(`Phase: ${status.currentPhase || "N/A"}`);
|
|
1987
2543
|
console.log(`Rows: ${status.recordsSucceeded}/${status.recordsTotal} succeeded, ${status.recordsFailed} failed`);
|
|
1988
2544
|
console.log(`Artifacts: ${status.artifactCount}`);
|
|
1989
|
-
if (status.
|
|
1990
|
-
if (status.
|
|
2545
|
+
if (status.triggerRunId) console.log(`Trigger: ${status.triggerRunId}`);
|
|
2546
|
+
if (status.staleRunningPhase) {
|
|
2547
|
+
const age = typeof status.phaseAgeSeconds === "number" ? `${status.phaseAgeSeconds}s` : "unknown age";
|
|
2548
|
+
console.log(`Stale: acquisition has reported no row progress for ${age}`);
|
|
2549
|
+
}
|
|
2550
|
+
if (status.warnings.length) {
|
|
2551
|
+
console.log(`Warnings: ${status.warnings.length}`);
|
|
2552
|
+
for (const warning of status.warnings.slice(0, 3)) console.log(` - ${warning}`);
|
|
2553
|
+
}
|
|
2554
|
+
if (status.errors.length) {
|
|
2555
|
+
console.log(`Errors: ${status.errors.length}`);
|
|
2556
|
+
for (const error of status.errors.slice(0, 3)) console.log(` - ${error}`);
|
|
2557
|
+
}
|
|
1991
2558
|
if (status.status === "completed") {
|
|
1992
2559
|
hint(`signaliz campaign rows ${buildId} --limit 100`);
|
|
2560
|
+
} else if (status.staleRunningPhase && status.triggerRunId) {
|
|
2561
|
+
hint(`signaliz ops run-status ${status.triggerRunId} --watch`);
|
|
1993
2562
|
} else if (status.status === "running" || status.status === "queued") {
|
|
1994
2563
|
hint(`signaliz campaign status ${buildId} (poll again in ~10s)`);
|
|
1995
2564
|
} else if (status.status === "pending_approval") {
|
|
1996
2565
|
hint(`signaliz campaign approve ${buildId} --destination-type webhook`);
|
|
2566
|
+
} else if (status.status === "failed" && status.nextAction) {
|
|
2567
|
+
hint(status.nextAction);
|
|
1997
2568
|
}
|
|
1998
2569
|
});
|
|
1999
2570
|
}
|
|
@@ -2018,7 +2589,7 @@ async function campaignRows() {
|
|
|
2018
2589
|
if (hasFlag("qualified")) opts.qualified = true;
|
|
2019
2590
|
if (hasFlag("disqualified")) opts.qualified = false;
|
|
2020
2591
|
const result = await sdk.campaigns.getCampaignBuildRows(buildId, opts);
|
|
2021
|
-
allRows.push(...result.rows);
|
|
2592
|
+
allRows.push(...formatCampaignRowsForOperator(result.rows));
|
|
2022
2593
|
nextCursor = result.nextCursor;
|
|
2023
2594
|
page++;
|
|
2024
2595
|
info(` Fetched page ${page}: ${result.rows.length} rows (total: ${allRows.length})`);
|
|
@@ -2042,26 +2613,73 @@ async function campaignRows() {
|
|
|
2042
2613
|
if (hasFlag("qualified")) opts.qualified = true;
|
|
2043
2614
|
if (hasFlag("disqualified")) opts.qualified = false;
|
|
2044
2615
|
const result = await sdk.campaigns.getCampaignBuildRows(buildId, opts);
|
|
2045
|
-
|
|
2046
|
-
|
|
2616
|
+
const operatorResult = {
|
|
2617
|
+
...result,
|
|
2618
|
+
rows: formatCampaignRowsForOperator(result.rows)
|
|
2619
|
+
};
|
|
2620
|
+
output(operatorResult, () => {
|
|
2621
|
+
if (operatorResult.rows.length === 0) {
|
|
2047
2622
|
console.log("No rows found.");
|
|
2048
2623
|
return;
|
|
2049
2624
|
}
|
|
2050
|
-
console.table(
|
|
2051
|
-
email: r.
|
|
2052
|
-
name: r.
|
|
2053
|
-
|
|
2625
|
+
console.table(operatorResult.rows.map((r) => ({
|
|
2626
|
+
email: r.email || "",
|
|
2627
|
+
name: r.name || "",
|
|
2628
|
+
title: r.title || "",
|
|
2629
|
+
company: r.company || r.domain || "",
|
|
2054
2630
|
segment: r.segment || "",
|
|
2055
|
-
status: r.status || ""
|
|
2631
|
+
status: r.status || "",
|
|
2632
|
+
score: r.score ?? ""
|
|
2056
2633
|
})));
|
|
2057
2634
|
console.log(`
|
|
2058
|
-
Showing ${
|
|
2059
|
-
if (
|
|
2060
|
-
hint(`signaliz campaign rows ${buildId} --limit ${limit} --cursor ${
|
|
2635
|
+
Showing ${operatorResult.rows.length} row(s)${operatorResult.hasMore ? " (more available)" : ""}`);
|
|
2636
|
+
if (operatorResult.nextCursor) {
|
|
2637
|
+
hint(`signaliz campaign rows ${buildId} --limit ${limit} --cursor ${operatorResult.nextCursor}`);
|
|
2061
2638
|
}
|
|
2062
2639
|
});
|
|
2063
2640
|
}
|
|
2064
2641
|
}
|
|
2642
|
+
function formatCampaignRowsForOperator(rows) {
|
|
2643
|
+
return rows.map((row) => {
|
|
2644
|
+
const rowRecord = record(row);
|
|
2645
|
+
const data = record(rowRecord.data);
|
|
2646
|
+
const rawCopy = record(data.raw_copy);
|
|
2647
|
+
const copy = {
|
|
2648
|
+
subject: data.subject || rawCopy.subject || null,
|
|
2649
|
+
opener: data.opener || rawCopy.opener || null,
|
|
2650
|
+
body: data.body || rawCopy.body || null,
|
|
2651
|
+
cta: data.cta || rawCopy.cta || null,
|
|
2652
|
+
engine: data.copy_engine || rawCopy.engine || null,
|
|
2653
|
+
model: data.copy_model || null
|
|
2654
|
+
};
|
|
2655
|
+
return {
|
|
2656
|
+
...rowRecord,
|
|
2657
|
+
email: data.email || null,
|
|
2658
|
+
name: data.full_name || `${data.first_name || ""} ${data.last_name || ""}`.trim() || null,
|
|
2659
|
+
title: data.title || null,
|
|
2660
|
+
company: data.company_name || null,
|
|
2661
|
+
domain: data.company_domain || null,
|
|
2662
|
+
industry: data.industry || null,
|
|
2663
|
+
linkedin_url: data.linkedin_url || null,
|
|
2664
|
+
score: data.overall_score ?? null,
|
|
2665
|
+
company_fit_score: data.company_fit_score ?? null,
|
|
2666
|
+
contact_fit_score: data.contact_fit_score ?? null,
|
|
2667
|
+
signal_relevance_score: data.signal_relevance_score ?? null,
|
|
2668
|
+
reason_codes: firstArray(data.reason_codes),
|
|
2669
|
+
disqualifiers: firstArray(data.disqualifiers),
|
|
2670
|
+
signal: data.signal_title ? {
|
|
2671
|
+
type: data.signal_type || null,
|
|
2672
|
+
title: data.signal_title,
|
|
2673
|
+
summary: data.signal_summary || null,
|
|
2674
|
+
date: data.signal_date || null,
|
|
2675
|
+
confidence: data.signal_confidence ?? null,
|
|
2676
|
+
source_url: data.signal_source_url || null
|
|
2677
|
+
} : null,
|
|
2678
|
+
copy,
|
|
2679
|
+
has_copy: Boolean(copy.subject || copy.opener || copy.body || copy.cta)
|
|
2680
|
+
};
|
|
2681
|
+
});
|
|
2682
|
+
}
|
|
2065
2683
|
async function campaignArtifacts() {
|
|
2066
2684
|
const buildId = positionalAfter("artifacts") || flagArg("campaign-build-id");
|
|
2067
2685
|
if (!buildId) die("Usage: signaliz campaign artifacts <campaign_build_id>");
|
|
@@ -2115,6 +2733,14 @@ async function campaignCancel() {
|
|
|
2115
2733
|
});
|
|
2116
2734
|
}
|
|
2117
2735
|
async function campaign(sub) {
|
|
2736
|
+
if (sub === "help") {
|
|
2737
|
+
process.stdout.write(campaignHelpFor(process.argv[4]));
|
|
2738
|
+
return;
|
|
2739
|
+
}
|
|
2740
|
+
if (isHelpRequest(process.argv.slice(4))) {
|
|
2741
|
+
process.stdout.write(campaignHelpFor(sub));
|
|
2742
|
+
return;
|
|
2743
|
+
}
|
|
2118
2744
|
switch (sub) {
|
|
2119
2745
|
case "scope":
|
|
2120
2746
|
return campaignScope();
|
|
@@ -2136,6 +2762,616 @@ async function campaign(sub) {
|
|
|
2136
2762
|
Available: scope, build, status, rows, artifacts, approve, cancel`);
|
|
2137
2763
|
}
|
|
2138
2764
|
}
|
|
2765
|
+
var CAMPAIGN_AGENT_APPROVAL_TYPES = [
|
|
2766
|
+
"memory_retrieval",
|
|
2767
|
+
"spend",
|
|
2768
|
+
"customer_tool",
|
|
2769
|
+
"external_write",
|
|
2770
|
+
"delivery",
|
|
2771
|
+
"launch"
|
|
2772
|
+
];
|
|
2773
|
+
var CAMPAIGN_AGENT_TEMPLATE_PLAYBOOKS = {
|
|
2774
|
+
"industrial-ot-resilience": ["net-new-suppressed-list", "proof-first-vertical-gate", "signal-led-copy-approval"],
|
|
2775
|
+
"non-medical-home-care": ["proof-first-vertical-gate", "domain-first-recovery", "table-workflow-handoff"],
|
|
2776
|
+
"agency-founder-led": ["net-new-suppressed-list", "signal-led-copy-approval", "table-workflow-handoff"],
|
|
2777
|
+
"cloud-infrastructure-displacement": ["proof-first-vertical-gate", "domain-first-recovery", "signal-led-copy-approval"]
|
|
2778
|
+
};
|
|
2779
|
+
var CAMPAIGN_AGENT_HELP = `signaliz campaign-agent <command> [options]
|
|
2780
|
+
|
|
2781
|
+
Strategy-template campaign builder:
|
|
2782
|
+
init Emit reusable CampaignBuilderAgentRequest JSON
|
|
2783
|
+
plan Compose an approval-gated strategy-template MCP flow
|
|
2784
|
+
proof Prove memory, plan, approvals, and build dry-run without spend
|
|
2785
|
+
commit-plan Dry-run or write a reviewed GTM campaign object
|
|
2786
|
+
dry-run Execute build_campaign with dry_run=true
|
|
2787
|
+
build-approved Launch only after explicit approval metadata
|
|
2788
|
+
|
|
2789
|
+
Examples:
|
|
2790
|
+
signaliz campaign-agent init --strategy-template non-medical-home-care --target-count 250 --use-local-leads --json > campaign-request.json
|
|
2791
|
+
signaliz campaign-agent plan --goal "Build a strategy-template campaign for my ICP" --strategy-template non-medical-home-care --target-count 500 --builtins lead_generation,email_finding,email_verification,signals
|
|
2792
|
+
signaliz campaign-agent proof --goal "Build a strategy-template campaign for my ICP" --strategy-template non-medical-home-care --target-count 100 --json
|
|
2793
|
+
signaliz campaign-agent plan --request-file campaign-builder-agent-request.json --target-count 250 --json
|
|
2794
|
+
signaliz campaign-agent dry-run --goal "Build a local services campaign" --target-count 250 --use-local-leads --json
|
|
2795
|
+
signaliz campaign-agent build-approved --goal "Build a strategy-template campaign" --confirm-launch --approve-all --approved-by operator@example.com --spend-limit 500
|
|
2796
|
+
|
|
2797
|
+
Plan options:
|
|
2798
|
+
--goal TEXT Campaign goal or brief
|
|
2799
|
+
--output-file FILE Write init output to a reusable request JSON file
|
|
2800
|
+
--request-file FILE Reusable JSON CampaignBuilderAgentRequest; flags override file fields
|
|
2801
|
+
--campaign-name NAME Optional campaign label
|
|
2802
|
+
--workspace-label NAME Optional workspace/account label
|
|
2803
|
+
--account-context TEXT Optional ICP, offer, exclusion, or approval context
|
|
2804
|
+
--strategy-template ID Strategy template to merge
|
|
2805
|
+
--target-count N Desired lead/account count
|
|
2806
|
+
--icp JSON Structured ICP object
|
|
2807
|
+
--builtins a,b lead_generation,local_leads,email_finding,email_verification,signals
|
|
2808
|
+
--use-local-leads Add the local_leads built-in lane
|
|
2809
|
+
--custom-tool ROUTE BYO route: provider:layer:tool[:mcp] or key=value pairs
|
|
2810
|
+
--with-byo-placeholder Add an editable custom MCP route placeholder during init
|
|
2811
|
+
--preferred-providers a,b
|
|
2812
|
+
Provider preferences or BYO provider ids
|
|
2813
|
+
--no-strategy-patterns Disable default private strategy memory hints
|
|
2814
|
+
--no-workflow-patterns Disable default workflow memory hints
|
|
2815
|
+
--no-strategy-memory Skip live strategy-memory readiness proof
|
|
2816
|
+
--no-kernel-plan Skip live gtm_campaign_build_plan evidence
|
|
2817
|
+
--no-delivery-risk Skip live delivery-risk evidence
|
|
2818
|
+
|
|
2819
|
+
Approval options:
|
|
2820
|
+
--confirm-write Required to write commit-plan
|
|
2821
|
+
--confirm-launch Required for build-approved
|
|
2822
|
+
--approved-by EMAIL Required approval identity for writes/launches
|
|
2823
|
+
--approve-all Approve every required approval type in the plan
|
|
2824
|
+
--approved-types a,b Approve selected types
|
|
2825
|
+
--spend-limit N Maximum approved credits
|
|
2826
|
+
--commit-before-launch Commit the reviewed plan before launch
|
|
2827
|
+
--idempotency-key KEY Idempotency key for write/launch calls
|
|
2828
|
+
--json Machine-readable output
|
|
2829
|
+
`;
|
|
2830
|
+
async function campaignAgent(sub, rest) {
|
|
2831
|
+
if (!sub || sub === "help" || sub === "--help" || sub === "-h") {
|
|
2832
|
+
process.stdout.write(CAMPAIGN_AGENT_HELP);
|
|
2833
|
+
return;
|
|
2834
|
+
}
|
|
2835
|
+
if (isHelpRequest(rest)) {
|
|
2836
|
+
process.stdout.write(CAMPAIGN_AGENT_HELP);
|
|
2837
|
+
return;
|
|
2838
|
+
}
|
|
2839
|
+
if (!["init", "template", "request-template", "new", "plan", "proof", "smoke", "commit-plan", "dry-run", "build-approved", "launch-approved"].includes(sub)) {
|
|
2840
|
+
process.stdout.write(CAMPAIGN_AGENT_HELP);
|
|
2841
|
+
return;
|
|
2842
|
+
}
|
|
2843
|
+
const flags = parseCommandFlags(rest);
|
|
2844
|
+
if (["init", "template", "request-template", "new"].includes(sub)) {
|
|
2845
|
+
const request2 = campaignAgentRequestTemplateFromFlags(flags, rest);
|
|
2846
|
+
const outputFile = commandStringFlag(flags, "output-file", "out");
|
|
2847
|
+
if (outputFile) {
|
|
2848
|
+
(0, import_node_fs.writeFileSync)(outputFile, `${JSON.stringify(request2, null, 2)}
|
|
2849
|
+
`, "utf8");
|
|
2850
|
+
}
|
|
2851
|
+
if (jsonMode() || !outputFile) return output(request2);
|
|
2852
|
+
console.log(`Campaign request template written: ${outputFile}`);
|
|
2853
|
+
console.log(`Next: signaliz campaign-agent plan --request-file ${outputFile} --json`);
|
|
2854
|
+
return;
|
|
2855
|
+
}
|
|
2856
|
+
const requestFromFile = campaignAgentRequestFileFromFlags(flags);
|
|
2857
|
+
const goal = commandStringFlag(flags, "goal", "brief") || promptArg(rest) || campaignAgentStringValue(requestFromFile?.goal);
|
|
2858
|
+
if (!goal) die(`campaign-agent ${sub} requires --goal or a request file with goal`);
|
|
2859
|
+
const isApprovedBuild = sub === "build-approved" || sub === "launch-approved";
|
|
2860
|
+
const isCommitPlan = sub === "commit-plan";
|
|
2861
|
+
const isConfirmedCommit = isCommitPlan && commandBooleanFlag(flags, "confirm-write");
|
|
2862
|
+
const approvedBy = commandStringFlag(flags, "approved-by");
|
|
2863
|
+
if (isApprovedBuild) {
|
|
2864
|
+
if (!commandBooleanFlag(flags, "confirm-launch")) die(`campaign-agent ${sub} requires --confirm-launch`);
|
|
2865
|
+
if (!approvedBy) die(`campaign-agent ${sub} requires --approved-by`);
|
|
2866
|
+
}
|
|
2867
|
+
if (isConfirmedCommit && !approvedBy) {
|
|
2868
|
+
die("campaign-agent commit-plan --confirm-write requires --approved-by");
|
|
2869
|
+
}
|
|
2870
|
+
const sdk = getSdk();
|
|
2871
|
+
const agent = sdk.campaignBuilderAgent;
|
|
2872
|
+
const request = mergeCampaignAgentRequests(
|
|
2873
|
+
requestFromFile,
|
|
2874
|
+
campaignAgentRequestFromFlags(goal, flags, { includeDefaults: !requestFromFile })
|
|
2875
|
+
);
|
|
2876
|
+
const plan = await agent.createPlan(request, {
|
|
2877
|
+
discoverCapabilities: !commandBooleanFlag(flags, "skip-discovery"),
|
|
2878
|
+
scopeCampaign: !commandBooleanFlag(flags, "skip-scope"),
|
|
2879
|
+
includeStrategyMemoryStatus: !commandBooleanFlag(flags, "no-strategy-memory"),
|
|
2880
|
+
includeKernelPlan: !commandBooleanFlag(flags, "no-kernel-plan"),
|
|
2881
|
+
includeDeliveryRisk: !commandBooleanFlag(flags, "no-delivery-risk")
|
|
2882
|
+
});
|
|
2883
|
+
if (sub === "proof" || sub === "smoke") {
|
|
2884
|
+
const result = await agent.dryRunPlan(plan, {
|
|
2885
|
+
idempotencyKey: commandStringFlag(flags, "idempotency-key")
|
|
2886
|
+
});
|
|
2887
|
+
const proof = createCampaignAgentProofReceipt(plan, result);
|
|
2888
|
+
if (!proof.success) process.exitCode = 1;
|
|
2889
|
+
return output(proof, () => printCampaignAgentProof(proof));
|
|
2890
|
+
}
|
|
2891
|
+
if (isCommitPlan) {
|
|
2892
|
+
const result = await agent.commitPlan(plan, {
|
|
2893
|
+
confirm: isConfirmedCommit,
|
|
2894
|
+
dryRun: !isConfirmedCommit,
|
|
2895
|
+
approvedBy,
|
|
2896
|
+
idempotencyKey: commandStringFlag(flags, "idempotency-key"),
|
|
2897
|
+
rationale: commandStringFlag(flags, "rationale")
|
|
2898
|
+
});
|
|
2899
|
+
return output({ plan, result }, () => printCampaignAgentExecution(plan, result));
|
|
2900
|
+
}
|
|
2901
|
+
if (sub === "dry-run") {
|
|
2902
|
+
const result = await agent.dryRunPlan(plan, {
|
|
2903
|
+
idempotencyKey: commandStringFlag(flags, "idempotency-key")
|
|
2904
|
+
});
|
|
2905
|
+
return output({ plan, result }, () => printCampaignAgentExecution(plan, result));
|
|
2906
|
+
}
|
|
2907
|
+
if (isApprovedBuild) {
|
|
2908
|
+
const approval = createCampaignAgentApproval(plan, {
|
|
2909
|
+
approvedBy,
|
|
2910
|
+
approvedTypes: campaignAgentApprovedTypesFromFlags(plan, flags),
|
|
2911
|
+
spendLimitCredits: commandNumberFlag(flags, "spend-limit", "spend-limit-credits", "max-credits"),
|
|
2912
|
+
approvedRouteIds: campaignAgentApprovedRouteIdsFromFlags(plan, flags),
|
|
2913
|
+
notes: commandStringFlag(flags, "approval-notes", "notes")
|
|
2914
|
+
});
|
|
2915
|
+
const result = await agent.buildApprovedPlan(plan, approval, {
|
|
2916
|
+
idempotencyKey: commandStringFlag(flags, "idempotency-key"),
|
|
2917
|
+
commitBeforeLaunch: commandBooleanFlag(flags, "commit-before-launch")
|
|
2918
|
+
});
|
|
2919
|
+
return output({ plan, approval, result }, () => printCampaignAgentExecution(plan, result));
|
|
2920
|
+
}
|
|
2921
|
+
return output(plan, () => printCampaignAgentPlan(plan));
|
|
2922
|
+
}
|
|
2923
|
+
function campaignAgentRequestTemplateFromFlags(flags, rest) {
|
|
2924
|
+
const goal = commandStringFlag(flags, "goal", "brief") || promptArg(rest) || "Build a strategy-template campaign for mature operators in the target ICP.";
|
|
2925
|
+
const request = campaignAgentRequestFromFlags(goal, flags, { includeDefaults: true });
|
|
2926
|
+
request.strategyTemplate = request.strategyTemplate || "non-medical-home-care";
|
|
2927
|
+
if (!Array.isArray(request.operatingPlaybooks)) {
|
|
2928
|
+
request.operatingPlaybooks = CAMPAIGN_AGENT_TEMPLATE_PLAYBOOKS[String(request.strategyTemplate)] || [];
|
|
2929
|
+
}
|
|
2930
|
+
request.campaignName = request.campaignName || "Strategy Template Campaign";
|
|
2931
|
+
request.accountLabel = request.accountLabel || "Workspace Campaign";
|
|
2932
|
+
request.accountContext = request.accountContext || "Use private workspace memory, current suppression rules, verified-email quality gates, and approval-gated provider routes.";
|
|
2933
|
+
request.targetCount = request.targetCount || 250;
|
|
2934
|
+
request.icp = request.icp || {
|
|
2935
|
+
personas: ["Operations leader", "Founder", "Revenue leader"],
|
|
2936
|
+
industries: ["B2B services", "Vertical software", "Local operators"],
|
|
2937
|
+
geographies: ["United States"],
|
|
2938
|
+
keywords: ["growth", "operations", "customer acquisition"],
|
|
2939
|
+
requireVerifiedEmail: true
|
|
2940
|
+
};
|
|
2941
|
+
const builtIns = new Set(campaignAgentStringArray(request.builtIns) || [
|
|
2942
|
+
"lead_generation",
|
|
2943
|
+
"email_finding",
|
|
2944
|
+
"email_verification",
|
|
2945
|
+
"signals"
|
|
2946
|
+
]);
|
|
2947
|
+
if (commandBooleanFlag(flags, "use-local-leads")) builtIns.add("local_leads");
|
|
2948
|
+
request.builtIns = [...builtIns];
|
|
2949
|
+
if (!Array.isArray(request.integrations) && (commandBooleanFlag(flags, "with-byo-placeholder") || commandBooleanFlag(flags, "include-byo-placeholder") || commandBooleanFlag(flags, "include-custom-tool-placeholder"))) {
|
|
2950
|
+
request.integrations = [{
|
|
2951
|
+
provider: "custom_mcp",
|
|
2952
|
+
layer: "enrichment",
|
|
2953
|
+
gtmLayers: ["company_enrichment"],
|
|
2954
|
+
mode: "if_available",
|
|
2955
|
+
toolName: "workspace_enrich",
|
|
2956
|
+
mcpServerName: "workspace-mcp",
|
|
2957
|
+
label: "Workspace enrichment MCP",
|
|
2958
|
+
approvalRequired: true,
|
|
2959
|
+
rationale: "Editable custom MCP route placeholder for workspace-owned enrichment."
|
|
2960
|
+
}];
|
|
2961
|
+
}
|
|
2962
|
+
const preferredProviders = new Set(campaignAgentStringArray(request.preferredProviders) || []);
|
|
2963
|
+
if (!commandBooleanFlag(flags, "no-nango-catalog")) preferredProviders.add("nango");
|
|
2964
|
+
request.preferredProviders = [...preferredProviders];
|
|
2965
|
+
request.memory = mergeCampaignAgentRecords({
|
|
2966
|
+
enabled: true,
|
|
2967
|
+
useWorkspaceHistory: true,
|
|
2968
|
+
useNetworkPatterns: false,
|
|
2969
|
+
privacyMode: "anonymized_patterns",
|
|
2970
|
+
queries: [{
|
|
2971
|
+
query: `${request.strategyTemplate} campaign reply patterns, objections, qualification gates, and verified-email QA`,
|
|
2972
|
+
scopes: ["workspace", "operator_notes"],
|
|
2973
|
+
topK: 10,
|
|
2974
|
+
required: true,
|
|
2975
|
+
rationale: "Load approved private strategy and workflow patterns before campaign planning."
|
|
2976
|
+
}]
|
|
2977
|
+
}, record(request.memory));
|
|
2978
|
+
request.agencyContext = mergeCampaignAgentRecords({
|
|
2979
|
+
strategyModel: "strategy_template",
|
|
2980
|
+
includeStrategyPatterns: true,
|
|
2981
|
+
includeWorkflowPatterns: true,
|
|
2982
|
+
includeNangoCatalog: !commandBooleanFlag(flags, "no-nango-catalog"),
|
|
2983
|
+
partnerEcosystem: commandBooleanFlag(flags, "no-nango-catalog") ? ["signaliz"] : ["signaliz", "nango"]
|
|
2984
|
+
}, record(request.agencyContext));
|
|
2985
|
+
request.signalizDefaults = mergeCampaignAgentRecords({
|
|
2986
|
+
delivery: {
|
|
2987
|
+
enabled: true,
|
|
2988
|
+
destinationType: "json",
|
|
2989
|
+
approvalRequired: true
|
|
2990
|
+
}
|
|
2991
|
+
}, record(request.signalizDefaults));
|
|
2992
|
+
request.approvalPolicy = mergeCampaignAgentRecords({
|
|
2993
|
+
requireHumanApproval: true,
|
|
2994
|
+
maxCreditsWithoutApproval: 0,
|
|
2995
|
+
requireApprovalFor: CAMPAIGN_AGENT_APPROVAL_TYPES
|
|
2996
|
+
}, record(request.approvalPolicy));
|
|
2997
|
+
return compactCampaignAgentRequest(request);
|
|
2998
|
+
}
|
|
2999
|
+
function campaignAgentRequestFileFromFlags(flags) {
|
|
3000
|
+
const file = commandStringFlag(flags, "request-file", "input-file", "campaign-file");
|
|
3001
|
+
if (!file) return void 0;
|
|
3002
|
+
const parsed = readJsonValue(file);
|
|
3003
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
3004
|
+
die("--request-file must point to a JSON object");
|
|
3005
|
+
}
|
|
3006
|
+
return parsed;
|
|
3007
|
+
}
|
|
3008
|
+
function campaignAgentRequestFromFlags(goal, flags, options = {}) {
|
|
3009
|
+
const includeDefaults = options.includeDefaults !== false;
|
|
3010
|
+
const request = {
|
|
3011
|
+
goal,
|
|
3012
|
+
campaignName: commandStringFlag(flags, "campaign-name", "name"),
|
|
3013
|
+
accountLabel: commandStringFlag(flags, "workspace-label", "account-label"),
|
|
3014
|
+
strategyTemplate: commandStringFlag(flags, "strategy-template", "template"),
|
|
3015
|
+
accountContext: commandStringFlag(flags, "account-context", "workspace-context"),
|
|
3016
|
+
targetCount: commandNumberFlag(flags, "target-count", "lead-count"),
|
|
3017
|
+
gtmCampaignId: commandStringFlag(flags, "gtm-campaign-id", "campaign-id"),
|
|
3018
|
+
icp: campaignAgentJsonObjectInput(flags, ["icp", "target-icp"], ["icp-file", "target-icp-file"]),
|
|
3019
|
+
brainDefaults: campaignAgentJsonObjectInput(flags, ["brain-defaults"], ["brain-defaults-file"]),
|
|
3020
|
+
deliveryRisk: campaignAgentJsonObjectInput(flags, ["delivery-risk"], ["delivery-risk-file"]),
|
|
3021
|
+
builtIns: campaignAgentBuiltInsFromFlags(flags),
|
|
3022
|
+
operatingPlaybooks: commandCsvFlag(flags, "operating-playbooks", "playbooks"),
|
|
3023
|
+
integrations: campaignAgentCustomToolRoutesFromFlags(flags),
|
|
3024
|
+
preferredProviders: commandCsvFlag(flags, "preferred-providers", "providers")
|
|
3025
|
+
};
|
|
3026
|
+
if (includeDefaults || commandFlagValue(flags, "strategy-model", "no-strategy-patterns", "no-agency-patterns", "no-workflow-patterns", "no-clay-patterns", "no-nango-catalog", "partners", "revenue-motion") !== void 0) {
|
|
3027
|
+
request.agencyContext = {
|
|
3028
|
+
strategyModel: commandStringFlag(flags, "strategy-model"),
|
|
3029
|
+
includeStrategyPatterns: !commandBooleanFlag(flags, "no-strategy-patterns") && !commandBooleanFlag(flags, "no-agency-patterns"),
|
|
3030
|
+
includeWorkflowPatterns: !commandBooleanFlag(flags, "no-workflow-patterns") && !commandBooleanFlag(flags, "no-clay-patterns"),
|
|
3031
|
+
includeNangoCatalog: !commandBooleanFlag(flags, "no-nango-catalog"),
|
|
3032
|
+
partnerEcosystem: commandCsvFlag(flags, "partners"),
|
|
3033
|
+
revenueMotion: commandStringFlag(flags, "revenue-motion")
|
|
3034
|
+
};
|
|
3035
|
+
}
|
|
3036
|
+
if (includeDefaults || commandFlagValue(flags, "no-memory", "no-workspace-history", "use-network-patterns", "privacy-mode") !== void 0) {
|
|
3037
|
+
request.memory = {
|
|
3038
|
+
enabled: !commandBooleanFlag(flags, "no-memory"),
|
|
3039
|
+
useWorkspaceHistory: !commandBooleanFlag(flags, "no-workspace-history"),
|
|
3040
|
+
useNetworkPatterns: commandBooleanFlag(flags, "use-network-patterns"),
|
|
3041
|
+
privacyMode: commandStringFlag(flags, "privacy-mode")
|
|
3042
|
+
};
|
|
3043
|
+
}
|
|
3044
|
+
if (includeDefaults || commandFlagValue(flags, "max-credits", "no-delivery", "destination") !== void 0) {
|
|
3045
|
+
request.signalizDefaults = {
|
|
3046
|
+
maxCredits: commandNumberFlag(flags, "max-credits"),
|
|
3047
|
+
delivery: {
|
|
3048
|
+
enabled: !commandBooleanFlag(flags, "no-delivery"),
|
|
3049
|
+
destinationType: commandStringFlag(flags, "destination"),
|
|
3050
|
+
approvalRequired: true
|
|
3051
|
+
}
|
|
3052
|
+
};
|
|
3053
|
+
}
|
|
3054
|
+
if (includeDefaults || commandFlagValue(flags, "no-human-approval", "max-credits-without-approval") !== void 0) {
|
|
3055
|
+
request.approvalPolicy = {
|
|
3056
|
+
requireHumanApproval: !commandBooleanFlag(flags, "no-human-approval"),
|
|
3057
|
+
maxCreditsWithoutApproval: commandNumberFlag(flags, "max-credits-without-approval"),
|
|
3058
|
+
requireApprovalFor: CAMPAIGN_AGENT_APPROVAL_TYPES
|
|
3059
|
+
};
|
|
3060
|
+
}
|
|
3061
|
+
return compactCampaignAgentRequest(request);
|
|
3062
|
+
}
|
|
3063
|
+
function mergeCampaignAgentRequests(base, override) {
|
|
3064
|
+
if (!base) return override;
|
|
3065
|
+
return compactCampaignAgentRequest({
|
|
3066
|
+
...base,
|
|
3067
|
+
...override,
|
|
3068
|
+
icp: mergeCampaignAgentRecords(record(base.icp), record(override.icp)),
|
|
3069
|
+
memory: mergeCampaignAgentRecords(record(base.memory), record(override.memory)),
|
|
3070
|
+
agencyContext: mergeCampaignAgentRecords(record(base.agencyContext), record(override.agencyContext)),
|
|
3071
|
+
signalizDefaults: mergeCampaignAgentRecords(record(base.signalizDefaults), record(override.signalizDefaults)),
|
|
3072
|
+
approvalPolicy: mergeCampaignAgentRecords(record(base.approvalPolicy), record(override.approvalPolicy)),
|
|
3073
|
+
constraints: mergeCampaignAgentRecords(record(base.constraints), record(override.constraints)),
|
|
3074
|
+
workspaceContext: mergeCampaignAgentRecords(record(base.workspaceContext), record(override.workspaceContext)),
|
|
3075
|
+
builtIns: override.builtIns ?? base.builtIns,
|
|
3076
|
+
operatingPlaybooks: override.operatingPlaybooks ?? base.operatingPlaybooks,
|
|
3077
|
+
integrations: override.integrations ?? base.integrations,
|
|
3078
|
+
customerTools: override.customerTools ?? base.customerTools,
|
|
3079
|
+
preferredProviders: override.preferredProviders ?? base.preferredProviders
|
|
3080
|
+
});
|
|
3081
|
+
}
|
|
3082
|
+
function mergeCampaignAgentRecords(base, override) {
|
|
3083
|
+
const merged = { ...base, ...override };
|
|
3084
|
+
return Object.keys(merged).length ? merged : void 0;
|
|
3085
|
+
}
|
|
3086
|
+
function compactCampaignAgentRequest(record2) {
|
|
3087
|
+
return Object.fromEntries(Object.entries(record2).filter(([, value]) => value !== void 0));
|
|
3088
|
+
}
|
|
3089
|
+
function campaignAgentJsonObjectInput(flags, inlineNames, fileNames) {
|
|
3090
|
+
const inline = commandJsonObjectFlag(flags, ...inlineNames);
|
|
3091
|
+
if (inline) return inline;
|
|
3092
|
+
const file = commandStringFlag(flags, ...fileNames);
|
|
3093
|
+
if (!file) return void 0;
|
|
3094
|
+
const parsed = readJsonValue(file);
|
|
3095
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
3096
|
+
die(`--${fileNames[0]} must point to a JSON object`);
|
|
3097
|
+
}
|
|
3098
|
+
return parsed;
|
|
3099
|
+
}
|
|
3100
|
+
function campaignAgentBuiltInsFromFlags(flags) {
|
|
3101
|
+
const explicit = commandCsvFlag(flags, "builtins", "builtin-tools", "signaliz-tools");
|
|
3102
|
+
const hasBuiltinFlag = Boolean(
|
|
3103
|
+
explicit?.length || commandFlagValue(flags, "use-local-leads") !== void 0 || commandFlagValue(flags, "no-lead-generation") !== void 0 || commandFlagValue(flags, "no-email-finding") !== void 0 || commandFlagValue(flags, "no-verification") !== void 0 || commandFlagValue(flags, "no-signals") !== void 0
|
|
3104
|
+
);
|
|
3105
|
+
if (!hasBuiltinFlag) return void 0;
|
|
3106
|
+
const builtIns = new Set(explicit?.length ? explicit : ["lead_generation", "email_finding", "email_verification", "signals"]);
|
|
3107
|
+
if (commandBooleanFlag(flags, "use-local-leads")) builtIns.add("local_leads");
|
|
3108
|
+
if (commandBooleanFlag(flags, "no-lead-generation")) builtIns.delete("lead_generation");
|
|
3109
|
+
if (commandBooleanFlag(flags, "no-email-finding")) builtIns.delete("email_finding");
|
|
3110
|
+
if (commandBooleanFlag(flags, "no-verification")) builtIns.delete("email_verification");
|
|
3111
|
+
if (commandBooleanFlag(flags, "no-signals")) builtIns.delete("signals");
|
|
3112
|
+
return [...builtIns];
|
|
3113
|
+
}
|
|
3114
|
+
function campaignAgentCustomToolRoutesFromFlags(flags) {
|
|
3115
|
+
const values = repeatedCommandStringFlag(flags, "custom-tool", "customer-tool", "byo-tool", "integration-route");
|
|
3116
|
+
const routes = values.map(parseCampaignAgentCustomToolRoute);
|
|
3117
|
+
return routes.length ? routes : void 0;
|
|
3118
|
+
}
|
|
3119
|
+
function parseCampaignAgentCustomToolRoute(raw) {
|
|
3120
|
+
const route = raw.trim().startsWith("{") ? parseJsonObjectFromString(raw, "--custom-tool") : raw.includes("=") ? campaignAgentKeyValueObject(raw) : campaignAgentColonRouteObject(raw);
|
|
3121
|
+
const provider = String(route.provider ?? route.provider_id ?? route.providerId ?? "custom_mcp");
|
|
3122
|
+
const layer = normalizeCampaignAgentLayer(String(route.layer ?? route.use_for_layer ?? route.useForLayer ?? "enrichment"));
|
|
3123
|
+
const label = campaignAgentStringValue(route.label ?? route.name) ?? provider;
|
|
3124
|
+
return {
|
|
3125
|
+
provider,
|
|
3126
|
+
layer,
|
|
3127
|
+
gtmLayers: campaignAgentStringArray(route.gtm_layers ?? route.gtmLayers ?? route.capabilities),
|
|
3128
|
+
mode: normalizeCampaignAgentRouteMode(String(route.mode ?? "required")),
|
|
3129
|
+
toolName: campaignAgentStringValue(route.tool ?? route.tool_name ?? route.toolName),
|
|
3130
|
+
mcpServerName: campaignAgentStringValue(route.mcp ?? route.server ?? route.mcp_server_name ?? route.mcpServerName),
|
|
3131
|
+
label,
|
|
3132
|
+
approvalRequired: campaignAgentOptionalBoolean(route.approval_required ?? route.approvalRequired, true),
|
|
3133
|
+
config: {
|
|
3134
|
+
provider_id: route.provider_id ?? route.providerId,
|
|
3135
|
+
available_tools: campaignAgentStringArray(route.available_tools ?? route.availableTools ?? route.tools),
|
|
3136
|
+
raw: raw.trim()
|
|
3137
|
+
},
|
|
3138
|
+
rationale: `${label} is a user-provided campaign-builder route declared from the CLI.`
|
|
3139
|
+
};
|
|
3140
|
+
}
|
|
3141
|
+
function campaignAgentColonRouteObject(raw) {
|
|
3142
|
+
const [provider, layer, tool, mcp] = raw.split(":").map((part) => part.trim()).filter(Boolean);
|
|
3143
|
+
if (!provider || !layer) die("Expected --custom-tool provider:layer:tool[:mcp] or key=value pairs");
|
|
3144
|
+
return { provider, layer, tool, mcp };
|
|
3145
|
+
}
|
|
3146
|
+
function campaignAgentKeyValueObject(raw) {
|
|
3147
|
+
const parsed = {};
|
|
3148
|
+
for (const segment of raw.split(",")) {
|
|
3149
|
+
const eq = segment.indexOf("=");
|
|
3150
|
+
if (eq < 0) continue;
|
|
3151
|
+
parsed[segment.slice(0, eq).trim().replace(/-/g, "_")] = segment.slice(eq + 1).trim();
|
|
3152
|
+
}
|
|
3153
|
+
return parsed;
|
|
3154
|
+
}
|
|
3155
|
+
function normalizeCampaignAgentLayer(value) {
|
|
3156
|
+
const normalized = value.trim().toLowerCase().replace(/-/g, "_");
|
|
3157
|
+
const allowed = ["workspace_context", "memory", "source", "enrichment", "qualification", "copy", "delivery", "feedback", "approval"];
|
|
3158
|
+
if (!allowed.includes(normalized)) {
|
|
3159
|
+
die(`Unknown campaign-builder layer "${value}". Use source, enrichment, qualification, copy, delivery, feedback, or approval.`);
|
|
3160
|
+
}
|
|
3161
|
+
return normalized;
|
|
3162
|
+
}
|
|
3163
|
+
function normalizeCampaignAgentRouteMode(value) {
|
|
3164
|
+
const normalized = value.trim().toLowerCase().replace(/-/g, "_");
|
|
3165
|
+
return ["required", "if_available", "fallback", "disabled"].includes(normalized) ? normalized : "required";
|
|
3166
|
+
}
|
|
3167
|
+
function campaignAgentStringArray(value) {
|
|
3168
|
+
const values = Array.isArray(value) ? value : value === void 0 ? [] : [value];
|
|
3169
|
+
const parsed = values.flatMap((item) => String(item).split(/[|,]/).map((part) => part.trim()).filter(Boolean));
|
|
3170
|
+
return parsed.length ? parsed : void 0;
|
|
3171
|
+
}
|
|
3172
|
+
function campaignAgentStringValue(value) {
|
|
3173
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
3174
|
+
}
|
|
3175
|
+
function campaignAgentOptionalBoolean(value, defaultValue) {
|
|
3176
|
+
if (value === void 0) return defaultValue;
|
|
3177
|
+
if (typeof value === "boolean") return value;
|
|
3178
|
+
return parseCommandBoolean(String(value), defaultValue);
|
|
3179
|
+
}
|
|
3180
|
+
function campaignAgentApprovedTypesFromFlags(plan, flags) {
|
|
3181
|
+
const requested = commandCsvFlag(flags, "approved-types", "approve-types");
|
|
3182
|
+
if (requested?.length) return requested;
|
|
3183
|
+
if (!commandBooleanFlag(flags, "approve-all")) {
|
|
3184
|
+
die("campaign-agent build-approved requires --approve-all or --approved-types");
|
|
3185
|
+
}
|
|
3186
|
+
const types = Array.isArray(plan?.approvals) ? plan.approvals.map((item) => item?.type).filter(Boolean) : [];
|
|
3187
|
+
return [...new Set(types.length ? types : CAMPAIGN_AGENT_APPROVAL_TYPES)];
|
|
3188
|
+
}
|
|
3189
|
+
function campaignAgentApprovedRouteIdsFromFlags(plan, flags) {
|
|
3190
|
+
const requested = commandCsvFlag(flags, "approved-route-ids", "route-ids");
|
|
3191
|
+
if (requested?.length) return requested;
|
|
3192
|
+
if (!commandBooleanFlag(flags, "approve-all")) return void 0;
|
|
3193
|
+
const routeIds = Array.isArray(plan?.approvals) ? plan.approvals.map((item) => item?.routeId).filter(Boolean) : [];
|
|
3194
|
+
return routeIds.length ? routeIds : void 0;
|
|
3195
|
+
}
|
|
3196
|
+
function createCampaignAgentApproval(plan, input) {
|
|
3197
|
+
return {
|
|
3198
|
+
...input,
|
|
3199
|
+
planId: plan?.planId,
|
|
3200
|
+
approvedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3201
|
+
};
|
|
3202
|
+
}
|
|
3203
|
+
function printCampaignAgentPlan(plan) {
|
|
3204
|
+
console.log(`Plan: ${plan.campaignName || plan.goal || plan.planId}`);
|
|
3205
|
+
if (plan.planId) console.log(`Plan ID: ${plan.planId}`);
|
|
3206
|
+
if (plan.targetCount !== void 0) console.log(`Target: ${plan.targetCount}`);
|
|
3207
|
+
if (plan.estimatedCredits !== void 0) console.log(`Estimated credits: ${plan.estimatedCredits}`);
|
|
3208
|
+
const memory = record(plan.memory);
|
|
3209
|
+
console.log(`Memory: ${memory.enabled === false ? "disabled" : memory.privacyMode || "workspace_only"}`);
|
|
3210
|
+
const playbooks = Array.isArray(plan.operatingPlaybooks) ? plan.operatingPlaybooks : [];
|
|
3211
|
+
console.log(`Playbooks: ${playbooks.map((item) => item.slug).filter(Boolean).join(", ") || "none"}`);
|
|
3212
|
+
console.log(`Strategy memory: ${plan.strategyMemoryStatus ? record(plan.strategyMemoryStatus).ready === false ? "needs seeding" : "ready" : "not loaded"}`);
|
|
3213
|
+
console.log(`Kernel plan: ${plan.kernelPlan ? "loaded" : "not loaded"}`);
|
|
3214
|
+
const approvals = Array.isArray(plan.approvals) ? plan.approvals : [];
|
|
3215
|
+
console.log(`Approvals: ${approvals.map((item) => item.type).filter(Boolean).join(", ") || "none"}`);
|
|
3216
|
+
const warnings = Array.isArray(plan.warnings) ? plan.warnings : [];
|
|
3217
|
+
if (warnings.length) console.log(`Warnings: ${warnings.join("; ")}`);
|
|
3218
|
+
const flow = Array.isArray(plan.mcpFlow) ? plan.mcpFlow : [];
|
|
3219
|
+
if (flow.length) {
|
|
3220
|
+
console.log("\nMCP flow:");
|
|
3221
|
+
for (const step of flow) {
|
|
3222
|
+
console.log(`- ${step.id || step.tool}: ${step.tool}${step.approvalRequired ? " (approval required)" : ""}`);
|
|
3223
|
+
}
|
|
3224
|
+
}
|
|
3225
|
+
}
|
|
3226
|
+
function printCampaignAgentExecution(plan, result) {
|
|
3227
|
+
printCampaignAgentPlan(plan);
|
|
3228
|
+
console.log("\nResult:");
|
|
3229
|
+
console.log(JSON.stringify(result, null, 2));
|
|
3230
|
+
}
|
|
3231
|
+
function createCampaignAgentProofReceipt(plan, result) {
|
|
3232
|
+
const strategyMemory = record(plan.strategyMemoryStatus);
|
|
3233
|
+
const dryRunResult = record(result);
|
|
3234
|
+
const approvals = firstArray(plan.approvals);
|
|
3235
|
+
const flow = firstArray(plan.mcpFlow);
|
|
3236
|
+
const memoryReady = plan.strategyMemoryStatus ? strategyMemory.ready !== false : false;
|
|
3237
|
+
const dryRunCompleted = dryRunResult.dryRun === true || dryRunResult.dry_run === true || dryRunResult.status === "dry_run";
|
|
3238
|
+
const noLaunch = dryRunCompleted && !dryRunResult.campaignBuildId && !dryRunResult.campaign_build_id;
|
|
3239
|
+
const gates = [
|
|
3240
|
+
{
|
|
3241
|
+
id: "strategy_memory_ready",
|
|
3242
|
+
passed: memoryReady,
|
|
3243
|
+
ready: strategyMemory.ready ?? null,
|
|
3244
|
+
blocker_count: firstArray(strategyMemory.blockers).length
|
|
3245
|
+
},
|
|
3246
|
+
{
|
|
3247
|
+
id: "campaign_plan_ready",
|
|
3248
|
+
passed: Boolean(plan.planId && flow.length > 0),
|
|
3249
|
+
plan_id: plan.planId ?? null,
|
|
3250
|
+
flow_steps: flow.length
|
|
3251
|
+
},
|
|
3252
|
+
{
|
|
3253
|
+
id: "approval_gates_present",
|
|
3254
|
+
passed: approvals.length > 0,
|
|
3255
|
+
approval_types: approvals.map((approval) => approval?.type).filter(Boolean)
|
|
3256
|
+
},
|
|
3257
|
+
{
|
|
3258
|
+
id: "dry_run_completed",
|
|
3259
|
+
passed: dryRunCompleted,
|
|
3260
|
+
status: dryRunResult.status ?? null,
|
|
3261
|
+
current_phase: dryRunResult.currentPhase ?? dryRunResult.current_phase ?? null
|
|
3262
|
+
},
|
|
3263
|
+
{
|
|
3264
|
+
id: "no_spendful_launch",
|
|
3265
|
+
passed: noLaunch,
|
|
3266
|
+
campaign_build_id: dryRunResult.campaignBuildId ?? dryRunResult.campaign_build_id ?? null
|
|
3267
|
+
}
|
|
3268
|
+
];
|
|
3269
|
+
return {
|
|
3270
|
+
receipt_version: "campaign-agent-proof.v1",
|
|
3271
|
+
source: "signaliz campaign-agent proof",
|
|
3272
|
+
success: gates.every((gate) => gate.passed),
|
|
3273
|
+
safety: {
|
|
3274
|
+
spendful_tools_called: false,
|
|
3275
|
+
external_writes_called: false,
|
|
3276
|
+
sender_loads_called: false,
|
|
3277
|
+
email_sends_called: false,
|
|
3278
|
+
dry_run_only: true
|
|
3279
|
+
},
|
|
3280
|
+
campaign: {
|
|
3281
|
+
plan_id: plan.planId,
|
|
3282
|
+
campaign_name: plan.campaignName,
|
|
3283
|
+
strategy_template: campaignAgentStrategyTemplate(plan),
|
|
3284
|
+
target_count: plan.targetCount,
|
|
3285
|
+
estimated_credits: plan.estimatedCredits,
|
|
3286
|
+
operating_playbooks: firstArray(plan.operatingPlaybooks).map((playbook) => playbook?.slug).filter(Boolean)
|
|
3287
|
+
},
|
|
3288
|
+
gates,
|
|
3289
|
+
strategy_memory_status: summarizeCampaignAgentStrategyMemory(strategyMemory),
|
|
3290
|
+
dry_run_result: summarizeCampaignAgentDryRun(dryRunResult),
|
|
3291
|
+
recommended_next_actions: [
|
|
3292
|
+
"Review the plan, approvals, and dry-run result.",
|
|
3293
|
+
"Use campaign-agent commit-plan --confirm-write only after review.",
|
|
3294
|
+
"Use campaign-agent build-approved only with --confirm-launch, approval identity, approval types, and spend limit."
|
|
3295
|
+
]
|
|
3296
|
+
};
|
|
3297
|
+
}
|
|
3298
|
+
function campaignAgentString(...values) {
|
|
3299
|
+
for (const value of values) {
|
|
3300
|
+
if (typeof value === "string" && value.trim()) return value;
|
|
3301
|
+
}
|
|
3302
|
+
return null;
|
|
3303
|
+
}
|
|
3304
|
+
function campaignAgentStrategyTemplate(plan) {
|
|
3305
|
+
const buildRequest = record(plan.buildRequest);
|
|
3306
|
+
const strategyMemory = record(plan.strategyMemoryStatus);
|
|
3307
|
+
const statusTemplate = strategyMemory.strategy_template ?? strategyMemory.strategyTemplate;
|
|
3308
|
+
const statusTemplateRecord = record(statusTemplate);
|
|
3309
|
+
const flowTemplate = firstArray(plan.mcpFlow).map((step) => record(record(step).arguments).strategy_template ?? record(record(step).arguments).strategyTemplate).find((value) => typeof value === "string" && value.trim());
|
|
3310
|
+
return campaignAgentString(
|
|
3311
|
+
buildRequest.strategyTemplate,
|
|
3312
|
+
buildRequest.strategy_template,
|
|
3313
|
+
statusTemplate,
|
|
3314
|
+
statusTemplateRecord.slug,
|
|
3315
|
+
statusTemplateRecord.id,
|
|
3316
|
+
flowTemplate
|
|
3317
|
+
);
|
|
3318
|
+
}
|
|
3319
|
+
function summarizeCampaignAgentStrategyMemory(strategyMemory) {
|
|
3320
|
+
if (Object.keys(strategyMemory).length === 0) return { ready: false };
|
|
3321
|
+
const template = strategyMemory.strategy_template ?? strategyMemory.strategyTemplate;
|
|
3322
|
+
const templateRecord = record(template);
|
|
3323
|
+
const coverage = record(strategyMemory.coverage);
|
|
3324
|
+
const sourceGroups = firstArray(strategyMemory.source_groups, strategyMemory.sourceGroups).map((group) => {
|
|
3325
|
+
const sourceGroup = record(group);
|
|
3326
|
+
return {
|
|
3327
|
+
id: sourceGroup.id ?? null,
|
|
3328
|
+
required: sourceGroup.required ?? null,
|
|
3329
|
+
ready: sourceGroup.ready ?? null,
|
|
3330
|
+
counts: record(sourceGroup.counts)
|
|
3331
|
+
};
|
|
3332
|
+
});
|
|
3333
|
+
return {
|
|
3334
|
+
ready: strategyMemory.ready ?? null,
|
|
3335
|
+
read_only: strategyMemory.read_only ?? strategyMemory.readOnly ?? null,
|
|
3336
|
+
source_tool: campaignAgentString(strategyMemory.source_tool, strategyMemory.sourceTool),
|
|
3337
|
+
strategy_template: {
|
|
3338
|
+
slug: campaignAgentString(template, templateRecord.slug, templateRecord.id),
|
|
3339
|
+
label: campaignAgentString(templateRecord.label)
|
|
3340
|
+
},
|
|
3341
|
+
coverage: {
|
|
3342
|
+
required_groups_ready: coverage.required_groups_ready ?? coverage.requiredGroupsReady ?? null,
|
|
3343
|
+
required_groups_total: coverage.required_groups_total ?? coverage.requiredGroupsTotal ?? null,
|
|
3344
|
+
source_groups_ready: coverage.source_groups_ready ?? coverage.sourceGroupsReady ?? null,
|
|
3345
|
+
source_groups_total: coverage.source_groups_total ?? coverage.sourceGroupsTotal ?? null,
|
|
3346
|
+
knowledge_docs: coverage.knowledge_docs ?? coverage.knowledgeDocs ?? null,
|
|
3347
|
+
memories: coverage.memories ?? null
|
|
3348
|
+
},
|
|
3349
|
+
source_groups: sourceGroups,
|
|
3350
|
+
blocker_count: firstArray(strategyMemory.blockers).length,
|
|
3351
|
+
warning_count: firstArray(strategyMemory.warnings).length
|
|
3352
|
+
};
|
|
3353
|
+
}
|
|
3354
|
+
function summarizeCampaignAgentDryRun(dryRunResult) {
|
|
3355
|
+
return {
|
|
3356
|
+
dryRun: dryRunResult.dryRun ?? dryRunResult.dry_run ?? null,
|
|
3357
|
+
status: dryRunResult.status ?? null,
|
|
3358
|
+
currentPhase: dryRunResult.currentPhase ?? dryRunResult.current_phase ?? null,
|
|
3359
|
+
campaignBuildId: dryRunResult.campaignBuildId ?? dryRunResult.campaign_build_id ?? null,
|
|
3360
|
+
plannedTargetCount: dryRunResult.plannedTargetCount ?? dryRunResult.planned_target_count ?? null
|
|
3361
|
+
};
|
|
3362
|
+
}
|
|
3363
|
+
function printCampaignAgentProof(proof) {
|
|
3364
|
+
console.log(`Campaign-agent proof: ${proof.success ? "passed" : "failed"}`);
|
|
3365
|
+
const campaign2 = record(proof.campaign);
|
|
3366
|
+
if (campaign2.plan_id) console.log(`Plan ID: ${campaign2.plan_id}`);
|
|
3367
|
+
if (campaign2.strategy_template) console.log(`Strategy template: ${campaign2.strategy_template}`);
|
|
3368
|
+
if (campaign2.target_count !== void 0) console.log(`Target: ${campaign2.target_count}`);
|
|
3369
|
+
console.log("\nGates:");
|
|
3370
|
+
for (const gate of firstArray(proof.gates)) {
|
|
3371
|
+
console.log(`- ${gate.id}: ${gate.passed ? "passed" : "failed"}`);
|
|
3372
|
+
}
|
|
3373
|
+
console.log("\nSafety: dry-run only; no spendful launch, external write, sender load, or email send.");
|
|
3374
|
+
}
|
|
2139
3375
|
async function lead(sub, rest) {
|
|
2140
3376
|
const sdk = getSdk();
|
|
2141
3377
|
if (sub === "generate") {
|
|
@@ -2228,19 +3464,219 @@ async function gtm(sub, rest) {
|
|
|
2228
3464
|
return;
|
|
2229
3465
|
}
|
|
2230
3466
|
const sdk = getSdk();
|
|
3467
|
+
if (sub === "start-context" || sub === "start") {
|
|
3468
|
+
const campaignBrief = promptArg(rest) || flagArg("campaign-brief") || flagArg("brief") || flagArg("goal");
|
|
3469
|
+
const strategyTemplate = flagArg("strategy-template") || flagArg("template");
|
|
3470
|
+
const targetIcp = readJsonObjectInput("target-icp-json", "target-icp-file");
|
|
3471
|
+
if (!campaignBrief && !flagArg("campaign-id") && !flagArg("campaign-build-id") && !flagArg("build-id") && !strategyTemplate && !targetIcp) {
|
|
3472
|
+
die('Usage: signaliz gtm start-context "campaign brief" [--strategy-template ID] [--target-count N] [--json]');
|
|
3473
|
+
}
|
|
3474
|
+
const result = await sdk.gtm.campaignStartContext({
|
|
3475
|
+
campaignId: flagArg("campaign-id"),
|
|
3476
|
+
campaignBuildId: flagArg("campaign-build-id") || flagArg("build-id"),
|
|
3477
|
+
campaignBrief,
|
|
3478
|
+
strategyTemplate,
|
|
3479
|
+
targetIcp,
|
|
3480
|
+
leadCount: numberFlag("lead-count") || numberFlag("target-count"),
|
|
3481
|
+
layers: csvFlag("layers"),
|
|
3482
|
+
preferredProviders: csvFlag("preferred-providers") || csvFlag("providers"),
|
|
3483
|
+
memoryDimensionFilters: readJsonObjectInput("memory-dimension-filters-json", "memory-dimension-filters-file"),
|
|
3484
|
+
requireMemoryDimensionMatch: hasFlag("require-memory-dimension-match") || void 0,
|
|
3485
|
+
includeMemory: !hasFlag("no-memory"),
|
|
3486
|
+
includeBrain: !hasFlag("no-brain"),
|
|
3487
|
+
includeProviderRoutes: !hasFlag("no-provider-routes"),
|
|
3488
|
+
includeFailurePatterns: !hasFlag("no-failure-patterns"),
|
|
3489
|
+
includeDeliveryRisk: !hasFlag("no-delivery-risk"),
|
|
3490
|
+
includeGlobalBrain: !hasFlag("no-global-brain"),
|
|
3491
|
+
includePlannedProviders: !hasFlag("no-planned-providers"),
|
|
3492
|
+
days: numberFlag("days"),
|
|
3493
|
+
minConfidence: numberFlag("min-confidence"),
|
|
3494
|
+
minSampleSize: numberFlag("min-sample-size"),
|
|
3495
|
+
limit: numberFlag("limit")
|
|
3496
|
+
});
|
|
3497
|
+
return output(result, () => {
|
|
3498
|
+
const runbook = Array.isArray(result.runbook) ? result.runbook : [];
|
|
3499
|
+
const blockers = Array.isArray(result.blockers) ? result.blockers : [];
|
|
3500
|
+
const warnings = Array.isArray(result.warnings) ? result.warnings : [];
|
|
3501
|
+
const readyCount = runbook.filter((step) => step.ready).length;
|
|
3502
|
+
console.log(blockers.length ? "GTM campaign start context: blocked" : "GTM campaign start context: ready");
|
|
3503
|
+
console.log(` Ready: ${readyCount}/${runbook.length} read-only calls`);
|
|
3504
|
+
console.log(` Safety: read-only; no credits spent, no provider writes, no send/export approval`);
|
|
3505
|
+
console.log(` Blockers: ${blockers.length}`);
|
|
3506
|
+
console.log(` Warnings: ${warnings.length}`);
|
|
3507
|
+
if (runbook.length) {
|
|
3508
|
+
console.log(" Runbook:");
|
|
3509
|
+
for (const step of runbook.slice(0, 6)) {
|
|
3510
|
+
console.log(` - ${step.tool || step.name || "unknown_tool"}${step.ready === false ? " [blocked]" : ""}`);
|
|
3511
|
+
}
|
|
3512
|
+
}
|
|
3513
|
+
if (blockers.length) {
|
|
3514
|
+
for (const blocker of blockers.slice(0, 5)) console.log(`- ${blocker}`);
|
|
3515
|
+
} else {
|
|
3516
|
+
hint("Review the read-only runbook, then run signaliz gtm plan with the same brief/template.");
|
|
3517
|
+
}
|
|
3518
|
+
});
|
|
3519
|
+
}
|
|
3520
|
+
if (sub === "templates" || sub === "strategy-templates") {
|
|
3521
|
+
const result = await sdk.gtm.campaignStrategyTemplates({
|
|
3522
|
+
strategyTemplate: flagArg("strategy-template") || flagArg("template"),
|
|
3523
|
+
query: flagArg("query") || flagArg("q"),
|
|
3524
|
+
includeDetails: !hasFlag("summary")
|
|
3525
|
+
});
|
|
3526
|
+
return output(result, () => {
|
|
3527
|
+
const templates = Array.isArray(result.templates) ? result.templates : [];
|
|
3528
|
+
console.log("GTM campaign strategy templates");
|
|
3529
|
+
for (const template of templates) {
|
|
3530
|
+
console.log(`- ${template.label || template.slug} (${template.slug})`);
|
|
3531
|
+
if (template.default_lead_count !== void 0) console.log(` Default lead count: ${template.default_lead_count}`);
|
|
3532
|
+
if (Array.isArray(template.preferred_providers)) console.log(` Providers: ${template.preferred_providers.join(", ")}`);
|
|
3533
|
+
if (template.usage?.cli) console.log(` CLI: ${template.usage.cli}`);
|
|
3534
|
+
}
|
|
3535
|
+
if (!templates.length) console.log("No strategy templates matched.");
|
|
3536
|
+
hint('Use one with: signaliz gtm plan "campaign brief" --strategy-template <slug> --json');
|
|
3537
|
+
});
|
|
3538
|
+
}
|
|
3539
|
+
if (sub === "strategy-memory" || sub === "memory-status" || sub === "strategy-memory-status") {
|
|
3540
|
+
const flags = parseCommandFlags(rest);
|
|
3541
|
+
const result = await sdk.gtm.campaignStrategyMemoryStatus({
|
|
3542
|
+
strategyTemplate: commandStringFlag(flags, "strategy-template", "template"),
|
|
3543
|
+
query: commandStringFlag(flags, "query", "goal", "q") || promptArg(rest),
|
|
3544
|
+
campaignBrief: commandStringFlag(flags, "brief", "campaign-brief"),
|
|
3545
|
+
targetIcp: readJsonObjectInput("target-icp-json", "target-icp-file") || campaignAgentJsonObjectInput(flags, ["icp", "target-icp"], ["icp-file", "target-icp-file"]),
|
|
3546
|
+
memoryDimensionFilters: readJsonObjectInput("memory-dimension-filters-json", "memory-dimension-filters-file"),
|
|
3547
|
+
requireMemoryDimensionMatch: commandBooleanFlag(flags, "require-memory-dimension-match") || void 0,
|
|
3548
|
+
includeSamples: commandBooleanFlag(flags, "include-samples") || void 0,
|
|
3549
|
+
includeSources: commandBooleanFlag(flags, "no-sources") ? false : void 0,
|
|
3550
|
+
days: commandNumberFlag(flags, "days"),
|
|
3551
|
+
limit: commandNumberFlag(flags, "limit")
|
|
3552
|
+
});
|
|
3553
|
+
return output(result, () => {
|
|
3554
|
+
const coverage = result.coverage || {};
|
|
3555
|
+
const blockers = Array.isArray(result.blockers) ? result.blockers : [];
|
|
3556
|
+
const groups = Array.isArray(result.source_groups) ? result.source_groups : [];
|
|
3557
|
+
console.log(result.ready ? "GTM strategy memory: ready" : "GTM strategy memory: needs seeding");
|
|
3558
|
+
console.log(` Knowledge docs: ${coverage.knowledge_docs ?? 0}`);
|
|
3559
|
+
console.log(` Memories: ${coverage.memories ?? 0}`);
|
|
3560
|
+
console.log(` Required: ${coverage.required_groups_ready ?? 0}/${coverage.required_groups_total ?? 0}`);
|
|
3561
|
+
console.log(` Blockers: ${blockers.length}`);
|
|
3562
|
+
if (groups.length) {
|
|
3563
|
+
console.log(" Source groups:");
|
|
3564
|
+
for (const group of groups.slice(0, 6)) {
|
|
3565
|
+
console.log(` - ${group.label || group.id}: ${group.ready ? "ready" : "missing"}`);
|
|
3566
|
+
}
|
|
3567
|
+
}
|
|
3568
|
+
hint("Use the returned memory_search_request before gtm agent-plan or gtm plan.");
|
|
3569
|
+
});
|
|
3570
|
+
}
|
|
3571
|
+
if (sub === "agent-template" || sub === "campaign-agent-template" || sub === "request-template") {
|
|
3572
|
+
const flags = parseCommandFlags(rest);
|
|
3573
|
+
const goal = commandStringFlag(flags, "goal", "brief", "campaign-brief") || promptArg(rest);
|
|
3574
|
+
const targetIcp = readJsonObjectInput("target-icp-json", "target-icp-file") || campaignAgentJsonObjectInput(flags, ["icp", "target-icp"], ["icp-file", "target-icp-file"]);
|
|
3575
|
+
const result = await sdk.gtm.campaignAgentRequestTemplate({
|
|
3576
|
+
goal,
|
|
3577
|
+
campaignName: commandStringFlag(flags, "campaign-name", "name"),
|
|
3578
|
+
accountLabel: commandStringFlag(flags, "workspace-label", "account-label"),
|
|
3579
|
+
accountContext: commandStringFlag(flags, "account-context", "workspace-context"),
|
|
3580
|
+
strategyTemplate: commandStringFlag(flags, "strategy-template", "template"),
|
|
3581
|
+
operatingPlaybooks: commandCsvFlag(flags, "operating-playbooks", "playbooks"),
|
|
3582
|
+
targetIcp,
|
|
3583
|
+
targetCount: commandNumberFlag(flags, "target-count", "lead-count"),
|
|
3584
|
+
builtIns: campaignAgentBuiltInsFromFlags(flags),
|
|
3585
|
+
includeLocalLeads: commandBooleanFlag(flags, "use-local-leads") || commandBooleanFlag(flags, "include-local-leads") || void 0,
|
|
3586
|
+
includeByoPlaceholder: commandBooleanFlag(flags, "with-byo-placeholder") || commandBooleanFlag(flags, "include-byo-placeholder") || void 0,
|
|
3587
|
+
includeNangoCatalog: !commandBooleanFlag(flags, "no-nango-catalog"),
|
|
3588
|
+
preferredProviders: commandCsvFlag(flags, "preferred-providers", "providers"),
|
|
3589
|
+
privacyMode: commandStringFlag(flags, "privacy-mode"),
|
|
3590
|
+
destinationType: commandStringFlag(flags, "destination", "destination-type")
|
|
3591
|
+
});
|
|
3592
|
+
return output(result, () => {
|
|
3593
|
+
const request = result.request || {};
|
|
3594
|
+
console.log("GTM campaign request template: ready");
|
|
3595
|
+
console.log(` Campaign: ${request.campaignName || commandStringFlag(flags, "campaign-name", "name") || "Strategy Template Campaign"}`);
|
|
3596
|
+
console.log(` Target: ${request.targetCount || commandNumberFlag(flags, "target-count", "lead-count") || "n/a"}`);
|
|
3597
|
+
console.log(` Safety: read-only; no credits spent, no provider calls, no writes`);
|
|
3598
|
+
if (result.next_mcp_call?.tool) console.log(` Next MCP: ${result.next_mcp_call.tool}`);
|
|
3599
|
+
hint("Save request_json, then run signaliz campaign-agent plan --request-file campaign-builder-agent-request.json --json.");
|
|
3600
|
+
});
|
|
3601
|
+
}
|
|
3602
|
+
if (sub === "agent-plan" || sub === "campaign-agent-plan") {
|
|
3603
|
+
const flags = parseCommandFlags(rest);
|
|
3604
|
+
const goal = commandStringFlag(flags, "goal", "brief", "campaign-brief") || promptArg(rest);
|
|
3605
|
+
const strategyTemplate = commandStringFlag(flags, "strategy-template", "template");
|
|
3606
|
+
const targetIcp = readJsonObjectInput("target-icp-json", "target-icp-file") || campaignAgentJsonObjectInput(flags, ["icp", "target-icp"], ["icp-file", "target-icp-file"]);
|
|
3607
|
+
if (!goal && !commandStringFlag(flags, "campaign-id") && !commandStringFlag(flags, "campaign-build-id", "build-id") && !strategyTemplate && !targetIcp) {
|
|
3608
|
+
die('Usage: signaliz gtm agent-plan --goal "campaign brief" [--strategy-template ID] [--target-count N] [--json]');
|
|
3609
|
+
}
|
|
3610
|
+
const result = await sdk.gtm.campaignAgentPlan({
|
|
3611
|
+
goal,
|
|
3612
|
+
campaignName: commandStringFlag(flags, "campaign-name", "name"),
|
|
3613
|
+
campaignId: commandStringFlag(flags, "campaign-id"),
|
|
3614
|
+
campaignBuildId: commandStringFlag(flags, "campaign-build-id", "build-id"),
|
|
3615
|
+
strategyTemplate,
|
|
3616
|
+
operatingPlaybooks: commandCsvFlag(flags, "operating-playbooks", "playbooks"),
|
|
3617
|
+
accountContext: commandStringFlag(flags, "account-context", "workspace-context"),
|
|
3618
|
+
targetIcp,
|
|
3619
|
+
targetCount: commandNumberFlag(flags, "target-count", "lead-count"),
|
|
3620
|
+
builtIns: campaignAgentBuiltInsFromFlags(flags),
|
|
3621
|
+
useLocalLeads: commandBooleanFlag(flags, "use-local-leads") || void 0,
|
|
3622
|
+
layers: commandCsvFlag(flags, "layers"),
|
|
3623
|
+
preferredProviders: commandCsvFlag(flags, "preferred-providers", "providers"),
|
|
3624
|
+
customTools: campaignAgentCustomToolRoutesFromFlags(flags),
|
|
3625
|
+
strategyModel: commandStringFlag(flags, "strategy-model"),
|
|
3626
|
+
includeStrategyPatterns: !commandBooleanFlag(flags, "no-strategy-patterns"),
|
|
3627
|
+
includeWorkflowPatterns: !commandBooleanFlag(flags, "no-workflow-patterns"),
|
|
3628
|
+
includeNangoCatalog: !commandBooleanFlag(flags, "no-nango-catalog"),
|
|
3629
|
+
partnerEcosystem: commandCsvFlag(flags, "partner-ecosystem", "partners"),
|
|
3630
|
+
memoryDimensionFilters: readJsonObjectInput("memory-dimension-filters-json", "memory-dimension-filters-file"),
|
|
3631
|
+
requireMemoryDimensionMatch: commandBooleanFlag(flags, "require-memory-dimension-match") || void 0,
|
|
3632
|
+
includeMemory: !commandBooleanFlag(flags, "no-memory"),
|
|
3633
|
+
includeBrain: !commandBooleanFlag(flags, "no-brain"),
|
|
3634
|
+
includeProviderRoutes: !commandBooleanFlag(flags, "no-provider-routes"),
|
|
3635
|
+
includeFailurePatterns: !commandBooleanFlag(flags, "no-failure-patterns"),
|
|
3636
|
+
includeDeliveryRisk: !commandBooleanFlag(flags, "no-delivery-risk"),
|
|
3637
|
+
includePlannedProviders: !commandBooleanFlag(flags, "no-planned-providers"),
|
|
3638
|
+
days: commandNumberFlag(flags, "days"),
|
|
3639
|
+
limit: commandNumberFlag(flags, "limit")
|
|
3640
|
+
});
|
|
3641
|
+
return output(result, () => {
|
|
3642
|
+
const flow = Array.isArray(result.mcp_flow) ? result.mcp_flow : [];
|
|
3643
|
+
const approvals = Array.isArray(result.required_approvals) ? result.required_approvals : [];
|
|
3644
|
+
const blockers = Array.isArray(result.blockers) ? result.blockers : [];
|
|
3645
|
+
const warnings = Array.isArray(result.warnings) ? result.warnings : [];
|
|
3646
|
+
console.log(blockers.length ? "GTM campaign agent plan: blocked" : "GTM campaign agent plan: ready for review");
|
|
3647
|
+
console.log(` Plan ID: ${result.plan_id || "n/a"}`);
|
|
3648
|
+
console.log(` Campaign: ${result.campaign?.name || goal || "strategy-template campaign"}`);
|
|
3649
|
+
console.log(` Safety: read-only; no credits spent, no provider writes, no send/export approval`);
|
|
3650
|
+
console.log(` Flow: ${flow.length} MCP steps`);
|
|
3651
|
+
console.log(` Approvals: ${approvals.length}`);
|
|
3652
|
+
console.log(` Blockers: ${blockers.length}`);
|
|
3653
|
+
console.log(` Warnings: ${warnings.length}`);
|
|
3654
|
+
if (flow.length) {
|
|
3655
|
+
console.log(" Next MCP flow:");
|
|
3656
|
+
for (const step of flow.slice(0, 6)) console.log(` - ${step.tool || step.name || "unknown_tool"}`);
|
|
3657
|
+
}
|
|
3658
|
+
hint("Review the runbook, then call gtm_campaign_build_plan and dry-run gtm_campaign_build_plan_commit.");
|
|
3659
|
+
});
|
|
3660
|
+
}
|
|
2231
3661
|
if (sub === "plan" || sub === "build-plan" || sub === "campaign-plan") {
|
|
2232
3662
|
const campaignBrief = promptArg(rest) || flagArg("campaign-brief") || flagArg("brief");
|
|
2233
3663
|
if (!campaignBrief && !flagArg("campaign-id") && !flagArg("campaign-build-id") && !flagArg("build-id")) {
|
|
2234
|
-
die('Usage: signaliz gtm plan "campaign brief" [--target-count N] [--layers a,b] [--preferred-providers a,b]');
|
|
3664
|
+
die('Usage: signaliz gtm plan "campaign brief" [--strategy-template ID] [--target-count N] [--layers a,b] [--preferred-providers a,b]');
|
|
2235
3665
|
}
|
|
2236
3666
|
const result = await sdk.gtm.campaignBuildPlan({
|
|
2237
3667
|
campaignId: flagArg("campaign-id"),
|
|
2238
3668
|
campaignBuildId: flagArg("campaign-build-id") || flagArg("build-id"),
|
|
2239
3669
|
campaignBrief,
|
|
3670
|
+
strategyTemplate: flagArg("strategy-template") || flagArg("template"),
|
|
2240
3671
|
targetIcp: readJsonObjectInput("target-icp-json", "target-icp-file"),
|
|
2241
3672
|
leadCount: numberFlag("lead-count") || numberFlag("target-count"),
|
|
2242
3673
|
layers: csvFlag("layers"),
|
|
2243
3674
|
preferredProviders: csvFlag("preferred-providers") || csvFlag("providers"),
|
|
3675
|
+
strategyModel: flagArg("strategy-model"),
|
|
3676
|
+
includeStrategyPatterns: !hasFlag("no-strategy-patterns") && !hasFlag("no-agency-patterns"),
|
|
3677
|
+
includeWorkflowPatterns: !hasFlag("no-workflow-patterns") && !hasFlag("no-clay-patterns"),
|
|
3678
|
+
includeNangoCatalog: !hasFlag("no-nango-catalog"),
|
|
3679
|
+
partnerEcosystem: csvFlag("partner-ecosystem") || csvFlag("partners"),
|
|
2244
3680
|
memoryDimensionFilters: readJsonObjectInput("memory-dimension-filters-json", "memory-dimension-filters-file"),
|
|
2245
3681
|
requireMemoryDimensionMatch: hasFlag("require-memory-dimension-match") || void 0,
|
|
2246
3682
|
includeMemory: !hasFlag("no-memory"),
|
|
@@ -2731,6 +4167,52 @@ async function gtm(sub, rest) {
|
|
|
2731
4167
|
hint("signaliz gtm activate-route --provider-id <provider> --layer <layer> --campaign-id <campaign_id>");
|
|
2732
4168
|
});
|
|
2733
4169
|
}
|
|
4170
|
+
if (sub === "provider-prepare" || sub === "prepare-provider" || sub === "recipe-prepare" || sub === "prepare-recipe") {
|
|
4171
|
+
const providerId = flagArg("provider-id") || flagArg("provider") || rest[0];
|
|
4172
|
+
if (!providerId) die("Usage: signaliz gtm provider-prepare --provider-id <provider_id> [--layer <layer>] [--json]");
|
|
4173
|
+
const result = await sdk.gtm.prepareProviderRecipe({
|
|
4174
|
+
providerId,
|
|
4175
|
+
providerName: flagArg("provider-name") || flagArg("name"),
|
|
4176
|
+
description: flagArg("description"),
|
|
4177
|
+
layerCapabilities: csvFlag("layer-capabilities") || csvFlag("layers"),
|
|
4178
|
+
invocationType: flagArg("invocation-type"),
|
|
4179
|
+
authStrategy: flagArg("auth-strategy"),
|
|
4180
|
+
endpointUrl: flagArg("endpoint-url"),
|
|
4181
|
+
httpMethod: flagArg("http-method"),
|
|
4182
|
+
secretRef: flagArg("secret-ref"),
|
|
4183
|
+
workspaceIntegrationId: flagArg("workspace-integration-id"),
|
|
4184
|
+
workspaceMcpServerId: flagArg("workspace-mcp-server-id"),
|
|
4185
|
+
workspaceConnectionId: flagArg("workspace-connection-id"),
|
|
4186
|
+
requestTemplate: readJsonObjectInput("request-template-json", "request-template-file"),
|
|
4187
|
+
responseMapping: readJsonObjectInput("response-mapping-json", "response-mapping-file"),
|
|
4188
|
+
inputSchema: readJsonObjectInput("input-schema-json", "input-schema-file"),
|
|
4189
|
+
outputSchema: readJsonObjectInput("output-schema-json", "output-schema-file"),
|
|
4190
|
+
readiness: readJsonObjectInput("readiness-json", "readiness-file"),
|
|
4191
|
+
metadata: readJsonObjectInput("metadata-json", "metadata-file"),
|
|
4192
|
+
layer: flagArg("layer"),
|
|
4193
|
+
campaignId: flagArg("campaign-id"),
|
|
4194
|
+
useSignalizFallback: !hasFlag("no-signaliz-fallback"),
|
|
4195
|
+
priority: numberFlag("priority"),
|
|
4196
|
+
status: flagArg("status"),
|
|
4197
|
+
sampleRecords: flagArg("records-file") ? readJsonValue(flagArg("records-file")) : void 0,
|
|
4198
|
+
context: readJsonObjectInput("context-json", "context-file")
|
|
4199
|
+
});
|
|
4200
|
+
return output(result, () => {
|
|
4201
|
+
const recipeArgs = result.recipe_arguments || result.recipeArgs || {};
|
|
4202
|
+
const routeArgs = result.route_arguments || result.routeArgs || {};
|
|
4203
|
+
const blockers = Array.isArray(result.blockers) ? result.blockers : [];
|
|
4204
|
+
const warnings = Array.isArray(result.warnings) ? result.warnings : [];
|
|
4205
|
+
console.log("GTM provider setup plan");
|
|
4206
|
+
console.log(` Provider: ${providerId}`);
|
|
4207
|
+
console.log(` Layer: ${flagArg("layer") || (Array.isArray(recipeArgs.layer_capabilities) ? recipeArgs.layer_capabilities[0] : "not specified")}`);
|
|
4208
|
+
console.log(" Safety: read-only; no recipe, route, provider call, or external write");
|
|
4209
|
+
if (recipeArgs.provider_id) console.log(` Recipe: ${recipeArgs.provider_id}`);
|
|
4210
|
+
if (routeArgs.layer) console.log(` Route: ${routeArgs.layer}`);
|
|
4211
|
+
if (blockers.length) console.log(` Blockers: ${blockers.join("; ")}`);
|
|
4212
|
+
if (warnings.length) console.log(` Warnings: ${warnings.join("; ")}`);
|
|
4213
|
+
hint("Review the recipe and route arguments, then run signaliz gtm activate-route as a dry-run.");
|
|
4214
|
+
});
|
|
4215
|
+
}
|
|
2734
4216
|
if (sub === "activate-route" || sub === "route-activate") {
|
|
2735
4217
|
const providerId = flagArg("provider-id") || rest[0];
|
|
2736
4218
|
if (!providerId) die("Usage: signaliz gtm activate-route --provider-id <provider_id> --layer <layer> [--confirm]");
|
|
@@ -2827,7 +4309,7 @@ async function gtm(sub, rest) {
|
|
|
2827
4309
|
});
|
|
2828
4310
|
}
|
|
2829
4311
|
if (sub === "find") {
|
|
2830
|
-
const intent = rest
|
|
4312
|
+
const intent = promptArg(rest) || flagArg("intent") || "";
|
|
2831
4313
|
if (!intent) die('Usage: signaliz gtm find "<free-text intent>"');
|
|
2832
4314
|
const result = await sdk.leads.findGtmCapability(intent);
|
|
2833
4315
|
return output(result, () => {
|
|
@@ -2875,7 +4357,7 @@ ${i + 1}. ${m.capability_id} (score ${m.score}) \u2014 ${m.label}`);
|
|
|
2875
4357
|
const result = await sdk.leads.checkStatus(jobId);
|
|
2876
4358
|
return output(result);
|
|
2877
4359
|
}
|
|
2878
|
-
die("Usage: signaliz gtm <context|bootstrap|plan|commit-plan|prepare-build|campaigns|campaign|existing-campaigns|audit-existing|memory|learning|execution|integrations|activate-route|list|find|run|status|nango>");
|
|
4360
|
+
die("Usage: signaliz gtm <context|bootstrap|strategy-memory|agent-template|agent-plan|plan|commit-plan|prepare-build|campaigns|campaign|existing-campaigns|audit-existing|memory|learning|execution|integrations|provider-prepare|activate-route|list|find|run|status|nango>");
|
|
2879
4361
|
}
|
|
2880
4362
|
function nangoActionInput() {
|
|
2881
4363
|
const fromFile = readJsonFlag("input-file");
|
|
@@ -2892,11 +4374,40 @@ function nangoBaseOptions() {
|
|
|
2892
4374
|
nangoConnectionId: flagArg("nango-connection-id")
|
|
2893
4375
|
};
|
|
2894
4376
|
}
|
|
4377
|
+
function nangoConnectOptions() {
|
|
4378
|
+
return {
|
|
4379
|
+
providerId: flagArg("provider-id") || flagArg("provider"),
|
|
4380
|
+
integrationId: flagArg("integration-id") || flagArg("provider-config-key"),
|
|
4381
|
+
providerDisplayName: flagArg("provider-display-name") || flagArg("provider-name"),
|
|
4382
|
+
integrationDisplayName: flagArg("integration-display-name"),
|
|
4383
|
+
allowedIntegrations: csvFlag("allowed-integrations"),
|
|
4384
|
+
surface: flagArg("surface") || "gtm_kernel",
|
|
4385
|
+
source: flagArg("source") || "signaliz_cli",
|
|
4386
|
+
userEmail: flagArg("user-email"),
|
|
4387
|
+
userDisplayName: flagArg("user-display-name")
|
|
4388
|
+
};
|
|
4389
|
+
}
|
|
2895
4390
|
function nangoStatusUrl(result) {
|
|
2896
4391
|
return result?.status_url || result?.statusUrl || result?.nango_result?.status_url || result?.nango_result?.statusUrl;
|
|
2897
4392
|
}
|
|
2898
4393
|
async function gtmNango(sub, rest) {
|
|
2899
4394
|
const sdk = getSdk();
|
|
4395
|
+
if (sub === "connect" || sub === "auth" || sub === "authorize") {
|
|
4396
|
+
const options = nangoConnectOptions();
|
|
4397
|
+
if (!options.providerId && !options.integrationId && (!options.allowedIntegrations || options.allowedIntegrations.length === 0)) {
|
|
4398
|
+
die("Usage: signaliz gtm nango connect --provider-id <provider> [--integration-id <key>] [--allowed-integrations a,b]");
|
|
4399
|
+
}
|
|
4400
|
+
const result = await sdk.gtm.createNangoConnectSession(options);
|
|
4401
|
+
return output(result, () => {
|
|
4402
|
+
console.log(`Nango connect session: ${result?.status || "created"}`);
|
|
4403
|
+
if (result?.provider_id || options.providerId) console.log(` Provider: ${result?.provider_id || options.providerId}`);
|
|
4404
|
+
if (result?.integration_id || options.integrationId) console.log(` Integration: ${result?.integration_id || options.integrationId}`);
|
|
4405
|
+
if (result?.connect_link || result?.auth_window_url) console.log(` Auth link: ${result.connect_link || result.auth_window_url}`);
|
|
4406
|
+
if (result?.expires_at) console.log(` Expires: ${result.expires_at}`);
|
|
4407
|
+
if (result?.next_action) console.log(` Next: ${result.next_action}`);
|
|
4408
|
+
hint("After authorization finishes, run signaliz gtm nango tools --workspace-connection-id <id> --provider-config-key <key>");
|
|
4409
|
+
});
|
|
4410
|
+
}
|
|
2900
4411
|
if (!sub || sub === "tools" || sub === "list") {
|
|
2901
4412
|
const result = await sdk.gtm.listNangoTools({
|
|
2902
4413
|
...nangoBaseOptions(),
|
|
@@ -2949,7 +4460,7 @@ async function gtmNango(sub, rest) {
|
|
|
2949
4460
|
if (nextStatusUrl) console.log(` Status URL: ${nextStatusUrl}`);
|
|
2950
4461
|
});
|
|
2951
4462
|
}
|
|
2952
|
-
die("Usage: signaliz gtm nango <tools|call|result>");
|
|
4463
|
+
die("Usage: signaliz gtm nango <connect|tools|call|result>");
|
|
2953
4464
|
}
|
|
2954
4465
|
async function email(sub, rest) {
|
|
2955
4466
|
const sdk = getSdk();
|
|
@@ -3141,6 +4652,14 @@ async function keys(sub, rest) {
|
|
|
3141
4652
|
if (!res.ok) process.exit(1);
|
|
3142
4653
|
}
|
|
3143
4654
|
async function ops(sub, rest) {
|
|
4655
|
+
if (sub === "help") {
|
|
4656
|
+
process.stdout.write(opsHelpFor(rest[0]));
|
|
4657
|
+
return;
|
|
4658
|
+
}
|
|
4659
|
+
if (isHelpRequest(rest)) {
|
|
4660
|
+
process.stdout.write(opsHelpFor(sub));
|
|
4661
|
+
return;
|
|
4662
|
+
}
|
|
3144
4663
|
if (sub === "saved" || sub === "save") {
|
|
3145
4664
|
const savedSub = sub === "save" ? "save" : rest[0];
|
|
3146
4665
|
const savedRest = sub === "save" ? rest : rest.slice(1);
|
|
@@ -3881,14 +5400,22 @@ async function main() {
|
|
|
3881
5400
|
case "email":
|
|
3882
5401
|
case "emails":
|
|
3883
5402
|
return email(rest[0], rest.slice(1));
|
|
5403
|
+
case "campaign-agent":
|
|
5404
|
+
return campaignAgent(rest[0], rest.slice(1));
|
|
3884
5405
|
case "campaign": {
|
|
3885
5406
|
const sub = rest[0];
|
|
3886
|
-
if (!sub
|
|
5407
|
+
if (!sub || sub === "--help" || sub === "-h") {
|
|
5408
|
+
process.stdout.write(campaignHelpFor(void 0));
|
|
5409
|
+
return;
|
|
5410
|
+
}
|
|
3887
5411
|
return campaign(sub);
|
|
3888
5412
|
}
|
|
3889
5413
|
case "ops": {
|
|
3890
5414
|
const sub = rest[0];
|
|
3891
|
-
if (!sub
|
|
5415
|
+
if (!sub || sub === "--help" || sub === "-h") {
|
|
5416
|
+
process.stdout.write(opsHelpFor(void 0));
|
|
5417
|
+
return;
|
|
5418
|
+
}
|
|
3892
5419
|
if (sub === "logs" || sub === "log-stream") {
|
|
3893
5420
|
const runId = rest[1] || flagArg("run-id");
|
|
3894
5421
|
if (!runId) die("Usage: signaliz ops logs <run_id>");
|