@signaliz/cli 1.0.5 → 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 +1359 -45
- package/package.json +14 -3
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
|
|
|
@@ -1497,14 +1850,14 @@ Run: signaliz ops help <command>
|
|
|
1497
1850
|
return OPS_COMMAND_HELP[sub] || opsHelpFor(void 0);
|
|
1498
1851
|
}
|
|
1499
1852
|
var CAMPAIGN_COMMAND_HELP = {
|
|
1500
|
-
scope: `signaliz campaign scope --prompt "
|
|
1853
|
+
scope: `signaliz campaign scope --prompt "campaign request" [options]
|
|
1501
1854
|
|
|
1502
|
-
Turn a
|
|
1855
|
+
Turn a campaign brief into a markdown scope, Brain preflight, and
|
|
1503
1856
|
ready-to-run build_campaign dry-run arguments.
|
|
1504
1857
|
|
|
1505
1858
|
Options:
|
|
1506
|
-
--
|
|
1507
|
-
--
|
|
1859
|
+
--account-label NAME Workspace/account label
|
|
1860
|
+
--account-context-file FILE
|
|
1508
1861
|
Markdown notes with ICP, exclusions, offer, proof, approvals
|
|
1509
1862
|
--target-count N Desired target count
|
|
1510
1863
|
--destinations a,b json,csv,webhook,instantly,slack,airbyte,nango
|
|
@@ -1747,6 +2100,16 @@ async function start() {
|
|
|
1747
2100
|
const bootstrap = bootstrapState.ok ? record(bootstrapState.data) : {};
|
|
1748
2101
|
const integrations = integrationsState.ok ? record(integrationsState.data) : {};
|
|
1749
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
|
+
}));
|
|
1750
2113
|
const gates = firstArray(bootstrap.gates);
|
|
1751
2114
|
const readyGates = gates.filter((gate) => gate.ready === true || gate.status === "ready").length;
|
|
1752
2115
|
const blockedLayers = Number(integrationSummary.blocked_layers || 0);
|
|
@@ -1792,7 +2155,8 @@ async function start() {
|
|
|
1792
2155
|
kernel_gates_total: gates.length,
|
|
1793
2156
|
provider_layers_ready: readyLayers,
|
|
1794
2157
|
provider_layers_total: totalLayers,
|
|
1795
|
-
provider_layers_blocked: blockedLayers
|
|
2158
|
+
provider_layers_blocked: blockedLayers,
|
|
2159
|
+
provider_blockers: providerBlockers
|
|
1796
2160
|
},
|
|
1797
2161
|
next_move: {
|
|
1798
2162
|
title: nextMove,
|
|
@@ -1800,13 +2164,15 @@ async function start() {
|
|
|
1800
2164
|
command: nextCommand
|
|
1801
2165
|
},
|
|
1802
2166
|
safe_commands: commands,
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
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
|
+
} : {}
|
|
1810
2176
|
};
|
|
1811
2177
|
return output(result, () => {
|
|
1812
2178
|
console.log("Signaliz start");
|
|
@@ -2098,17 +2464,24 @@ async function campaignBuild() {
|
|
|
2098
2464
|
if (hasFlag("wait")) {
|
|
2099
2465
|
if (!result.campaignBuildId) die("Campaign build did not return a campaign_build_id to poll");
|
|
2100
2466
|
info("\nPolling for completion...");
|
|
2467
|
+
let lastProgressLine = "";
|
|
2101
2468
|
const finalStatus = await sdk.campaigns.waitForCompletion(result.campaignBuildId, {
|
|
2102
2469
|
intervalMs: 5e3,
|
|
2103
2470
|
onStatus: (s) => {
|
|
2104
|
-
if (
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
)
|
|
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;
|
|
2108
2480
|
}
|
|
2481
|
+
process.stderr.write(`\r ${line} `);
|
|
2109
2482
|
}
|
|
2110
2483
|
});
|
|
2111
|
-
if (!jsonMode()) process.stderr.write("\n");
|
|
2484
|
+
if (!jsonMode() && !hasFlag("no-progress")) process.stderr.write("\n");
|
|
2112
2485
|
output(jsonMode() ? { initial: result, final: finalStatus } : finalStatus, () => {
|
|
2113
2486
|
console.log(`
|
|
2114
2487
|
\u2713 Build ${finalStatus.status}`);
|
|
@@ -2124,15 +2497,15 @@ async function campaignScope() {
|
|
|
2124
2497
|
const sdk = getSdk();
|
|
2125
2498
|
const promptText = flagArg("prompt") || positionalAfter("scope");
|
|
2126
2499
|
if (!promptText) {
|
|
2127
|
-
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"');
|
|
2128
2501
|
}
|
|
2129
|
-
const contextFile = flagArg("
|
|
2502
|
+
const contextFile = flagArg("account-context-file") || flagArg("workspace-context-file");
|
|
2130
2503
|
const targetCount = numberFlag("target-count");
|
|
2131
2504
|
const destinations = csvFlag("destinations")?.map((type) => ({ type }));
|
|
2132
2505
|
const result = await sdk.campaigns.scopeCampaign({
|
|
2133
2506
|
prompt: promptText,
|
|
2134
|
-
|
|
2135
|
-
|
|
2507
|
+
accountLabel: flagArg("account-label") || flagArg("workspace-label"),
|
|
2508
|
+
accountContext: contextFile ? (0, import_node_fs.readFileSync)(contextFile, "utf8") : flagArg("account-context") || flagArg("workspace-context"),
|
|
2136
2509
|
campaignGoal: flagArg("campaign-goal"),
|
|
2137
2510
|
targetCount,
|
|
2138
2511
|
destinations,
|
|
@@ -2169,6 +2542,11 @@ async function campaignStatus() {
|
|
|
2169
2542
|
console.log(`Phase: ${status.currentPhase || "N/A"}`);
|
|
2170
2543
|
console.log(`Rows: ${status.recordsSucceeded}/${status.recordsTotal} succeeded, ${status.recordsFailed} failed`);
|
|
2171
2544
|
console.log(`Artifacts: ${status.artifactCount}`);
|
|
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
|
+
}
|
|
2172
2550
|
if (status.warnings.length) {
|
|
2173
2551
|
console.log(`Warnings: ${status.warnings.length}`);
|
|
2174
2552
|
for (const warning of status.warnings.slice(0, 3)) console.log(` - ${warning}`);
|
|
@@ -2179,6 +2557,8 @@ async function campaignStatus() {
|
|
|
2179
2557
|
}
|
|
2180
2558
|
if (status.status === "completed") {
|
|
2181
2559
|
hint(`signaliz campaign rows ${buildId} --limit 100`);
|
|
2560
|
+
} else if (status.staleRunningPhase && status.triggerRunId) {
|
|
2561
|
+
hint(`signaliz ops run-status ${status.triggerRunId} --watch`);
|
|
2182
2562
|
} else if (status.status === "running" || status.status === "queued") {
|
|
2183
2563
|
hint(`signaliz campaign status ${buildId} (poll again in ~10s)`);
|
|
2184
2564
|
} else if (status.status === "pending_approval") {
|
|
@@ -2209,7 +2589,7 @@ async function campaignRows() {
|
|
|
2209
2589
|
if (hasFlag("qualified")) opts.qualified = true;
|
|
2210
2590
|
if (hasFlag("disqualified")) opts.qualified = false;
|
|
2211
2591
|
const result = await sdk.campaigns.getCampaignBuildRows(buildId, opts);
|
|
2212
|
-
allRows.push(...result.rows);
|
|
2592
|
+
allRows.push(...formatCampaignRowsForOperator(result.rows));
|
|
2213
2593
|
nextCursor = result.nextCursor;
|
|
2214
2594
|
page++;
|
|
2215
2595
|
info(` Fetched page ${page}: ${result.rows.length} rows (total: ${allRows.length})`);
|
|
@@ -2233,26 +2613,73 @@ async function campaignRows() {
|
|
|
2233
2613
|
if (hasFlag("qualified")) opts.qualified = true;
|
|
2234
2614
|
if (hasFlag("disqualified")) opts.qualified = false;
|
|
2235
2615
|
const result = await sdk.campaigns.getCampaignBuildRows(buildId, opts);
|
|
2236
|
-
|
|
2237
|
-
|
|
2616
|
+
const operatorResult = {
|
|
2617
|
+
...result,
|
|
2618
|
+
rows: formatCampaignRowsForOperator(result.rows)
|
|
2619
|
+
};
|
|
2620
|
+
output(operatorResult, () => {
|
|
2621
|
+
if (operatorResult.rows.length === 0) {
|
|
2238
2622
|
console.log("No rows found.");
|
|
2239
2623
|
return;
|
|
2240
2624
|
}
|
|
2241
|
-
console.table(
|
|
2242
|
-
email: r.
|
|
2243
|
-
name: r.
|
|
2244
|
-
|
|
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 || "",
|
|
2245
2630
|
segment: r.segment || "",
|
|
2246
|
-
status: r.status || ""
|
|
2631
|
+
status: r.status || "",
|
|
2632
|
+
score: r.score ?? ""
|
|
2247
2633
|
})));
|
|
2248
2634
|
console.log(`
|
|
2249
|
-
Showing ${
|
|
2250
|
-
if (
|
|
2251
|
-
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}`);
|
|
2252
2638
|
}
|
|
2253
2639
|
});
|
|
2254
2640
|
}
|
|
2255
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
|
+
}
|
|
2256
2683
|
async function campaignArtifacts() {
|
|
2257
2684
|
const buildId = positionalAfter("artifacts") || flagArg("campaign-build-id");
|
|
2258
2685
|
if (!buildId) die("Usage: signaliz campaign artifacts <campaign_build_id>");
|
|
@@ -2335,6 +2762,616 @@ async function campaign(sub) {
|
|
|
2335
2762
|
Available: scope, build, status, rows, artifacts, approve, cancel`);
|
|
2336
2763
|
}
|
|
2337
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
|
+
}
|
|
2338
3375
|
async function lead(sub, rest) {
|
|
2339
3376
|
const sdk = getSdk();
|
|
2340
3377
|
if (sub === "generate") {
|
|
@@ -2427,19 +3464,219 @@ async function gtm(sub, rest) {
|
|
|
2427
3464
|
return;
|
|
2428
3465
|
}
|
|
2429
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
|
+
}
|
|
2430
3661
|
if (sub === "plan" || sub === "build-plan" || sub === "campaign-plan") {
|
|
2431
3662
|
const campaignBrief = promptArg(rest) || flagArg("campaign-brief") || flagArg("brief");
|
|
2432
3663
|
if (!campaignBrief && !flagArg("campaign-id") && !flagArg("campaign-build-id") && !flagArg("build-id")) {
|
|
2433
|
-
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]');
|
|
2434
3665
|
}
|
|
2435
3666
|
const result = await sdk.gtm.campaignBuildPlan({
|
|
2436
3667
|
campaignId: flagArg("campaign-id"),
|
|
2437
3668
|
campaignBuildId: flagArg("campaign-build-id") || flagArg("build-id"),
|
|
2438
3669
|
campaignBrief,
|
|
3670
|
+
strategyTemplate: flagArg("strategy-template") || flagArg("template"),
|
|
2439
3671
|
targetIcp: readJsonObjectInput("target-icp-json", "target-icp-file"),
|
|
2440
3672
|
leadCount: numberFlag("lead-count") || numberFlag("target-count"),
|
|
2441
3673
|
layers: csvFlag("layers"),
|
|
2442
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"),
|
|
2443
3680
|
memoryDimensionFilters: readJsonObjectInput("memory-dimension-filters-json", "memory-dimension-filters-file"),
|
|
2444
3681
|
requireMemoryDimensionMatch: hasFlag("require-memory-dimension-match") || void 0,
|
|
2445
3682
|
includeMemory: !hasFlag("no-memory"),
|
|
@@ -2930,6 +4167,52 @@ async function gtm(sub, rest) {
|
|
|
2930
4167
|
hint("signaliz gtm activate-route --provider-id <provider> --layer <layer> --campaign-id <campaign_id>");
|
|
2931
4168
|
});
|
|
2932
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
|
+
}
|
|
2933
4216
|
if (sub === "activate-route" || sub === "route-activate") {
|
|
2934
4217
|
const providerId = flagArg("provider-id") || rest[0];
|
|
2935
4218
|
if (!providerId) die("Usage: signaliz gtm activate-route --provider-id <provider_id> --layer <layer> [--confirm]");
|
|
@@ -3026,7 +4309,7 @@ async function gtm(sub, rest) {
|
|
|
3026
4309
|
});
|
|
3027
4310
|
}
|
|
3028
4311
|
if (sub === "find") {
|
|
3029
|
-
const intent = rest
|
|
4312
|
+
const intent = promptArg(rest) || flagArg("intent") || "";
|
|
3030
4313
|
if (!intent) die('Usage: signaliz gtm find "<free-text intent>"');
|
|
3031
4314
|
const result = await sdk.leads.findGtmCapability(intent);
|
|
3032
4315
|
return output(result, () => {
|
|
@@ -3074,7 +4357,7 @@ ${i + 1}. ${m.capability_id} (score ${m.score}) \u2014 ${m.label}`);
|
|
|
3074
4357
|
const result = await sdk.leads.checkStatus(jobId);
|
|
3075
4358
|
return output(result);
|
|
3076
4359
|
}
|
|
3077
|
-
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>");
|
|
3078
4361
|
}
|
|
3079
4362
|
function nangoActionInput() {
|
|
3080
4363
|
const fromFile = readJsonFlag("input-file");
|
|
@@ -3091,11 +4374,40 @@ function nangoBaseOptions() {
|
|
|
3091
4374
|
nangoConnectionId: flagArg("nango-connection-id")
|
|
3092
4375
|
};
|
|
3093
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
|
+
}
|
|
3094
4390
|
function nangoStatusUrl(result) {
|
|
3095
4391
|
return result?.status_url || result?.statusUrl || result?.nango_result?.status_url || result?.nango_result?.statusUrl;
|
|
3096
4392
|
}
|
|
3097
4393
|
async function gtmNango(sub, rest) {
|
|
3098
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
|
+
}
|
|
3099
4411
|
if (!sub || sub === "tools" || sub === "list") {
|
|
3100
4412
|
const result = await sdk.gtm.listNangoTools({
|
|
3101
4413
|
...nangoBaseOptions(),
|
|
@@ -3148,7 +4460,7 @@ async function gtmNango(sub, rest) {
|
|
|
3148
4460
|
if (nextStatusUrl) console.log(` Status URL: ${nextStatusUrl}`);
|
|
3149
4461
|
});
|
|
3150
4462
|
}
|
|
3151
|
-
die("Usage: signaliz gtm nango <tools|call|result>");
|
|
4463
|
+
die("Usage: signaliz gtm nango <connect|tools|call|result>");
|
|
3152
4464
|
}
|
|
3153
4465
|
async function email(sub, rest) {
|
|
3154
4466
|
const sdk = getSdk();
|
|
@@ -4088,6 +5400,8 @@ async function main() {
|
|
|
4088
5400
|
case "email":
|
|
4089
5401
|
case "emails":
|
|
4090
5402
|
return email(rest[0], rest.slice(1));
|
|
5403
|
+
case "campaign-agent":
|
|
5404
|
+
return campaignAgent(rest[0], rest.slice(1));
|
|
4091
5405
|
case "campaign": {
|
|
4092
5406
|
const sub = rest[0];
|
|
4093
5407
|
if (!sub || sub === "--help" || sub === "-h") {
|