@signaliz/cli 1.0.84 → 1.0.86
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 +20 -1
- package/dist/bin.js +192 -4
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @signaliz/cli
|
|
2
2
|
|
|
3
|
-
The Signaliz CLI exposes
|
|
3
|
+
The Signaliz CLI exposes all five core products, Signal Awareness,
|
|
4
4
|
Signaliz Flow, and delivered managed builds through one public contract:
|
|
5
5
|
|
|
6
6
|
```bash
|
|
@@ -197,3 +197,22 @@ signaliz mcp install
|
|
|
197
197
|
Configuration is stored in `~/.signaliz/config.json` with file mode `0600`.
|
|
198
198
|
`SIGNALIZ_API_KEY`, `SIGNALIZ_API_URL`, and `SIGNALIZ_BASE_URL` override the
|
|
199
199
|
saved configuration.
|
|
200
|
+
|
|
201
|
+
## Campaign OS agent harness
|
|
202
|
+
|
|
203
|
+
Use the same commands from Codex, Claude Code, Cursor, Devin, Grok, or a shell
|
|
204
|
+
automation. All context is bounded and all provider actions remain gated:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
signaliz campaign-os clients --status active --json
|
|
208
|
+
signaliz campaign-os context --client-id <uuid> --json
|
|
209
|
+
signaliz campaign-os draft --client-id <uuid> --name "Launch intent" \
|
|
210
|
+
--lane realtime --agent codex --idempotency-key launch-draft-v1 --json
|
|
211
|
+
signaliz campaign-os request --client-id <uuid> --campaign-id <uuid> \
|
|
212
|
+
--agent devin --action provider_activation --instructions "Prepare for review" --json
|
|
213
|
+
signaliz campaign-os receipts --client-id <uuid> --json
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
`draft` creates only a locked Signaliz campaign object. `request` creates only
|
|
217
|
+
an auditable review request. Neither command loads leads, activates a provider
|
|
218
|
+
campaign, or sends email.
|
package/dist/bin.js
CHANGED
|
@@ -52,8 +52,15 @@ Product commands:
|
|
|
52
52
|
signaliz flow --run-id run_... Read a durable Flow checkpoint without dispatching new work
|
|
53
53
|
signaliz builds list
|
|
54
54
|
signaliz builds get --build-id BLD-...
|
|
55
|
-
signaliz builds
|
|
55
|
+
signaliz builds quote --build-id BLD-... [--input request.json]
|
|
56
|
+
signaliz builds run --build-id BLD-... [--input request.json] --confirm-spend --max-credits <number> [--idempotency-key <key>]
|
|
56
57
|
signaliz builds status --run-id <uuid> [--limit 100]
|
|
58
|
+
signaliz builds download --run-id <uuid> --out results.csv
|
|
59
|
+
signaliz campaign-os clients [--status active] [--query signaliz] [--limit 100]
|
|
60
|
+
signaliz campaign-os context --client-id <uuid> [--source-limit 50]
|
|
61
|
+
signaliz campaign-os draft --client-id <uuid> --name "Campaign" [--objective "..."] [--lane one_time|always_on|realtime] [--audience-binding-id <uuid>] [--agent codex]
|
|
62
|
+
signaliz campaign-os request --client-id <uuid> [--campaign-id <uuid>] --agent codex --action build_campaign --instructions "..." [--idempotency-key <key>]
|
|
63
|
+
signaliz campaign-os receipts [--client-id <uuid>] [--campaign-id <uuid>] [--limit 50]
|
|
57
64
|
|
|
58
65
|
Access and connection:
|
|
59
66
|
signaliz auth login
|
|
@@ -1986,18 +1993,44 @@ async function managedBuilds(args) {
|
|
|
1986
1993
|
output(result, () => {
|
|
1987
1994
|
process.stdout.write(`${result.build.build_id} \u2014 ${result.build.name}
|
|
1988
1995
|
`);
|
|
1989
|
-
process.stdout.write(`
|
|
1996
|
+
process.stdout.write(`Base price: ${result.build.fixed_credits_per_run} Signaliz credits for ${result.build.included_records_per_run} included record(s)
|
|
1997
|
+
`);
|
|
1998
|
+
process.stdout.write(`Additional records: ${result.build.additional_record_credits} Signaliz credits each \xB7 max ${result.build.max_records_per_run}
|
|
1999
|
+
`);
|
|
2000
|
+
process.stdout.write(`Estimated Clay use: ${result.build.clay_credits_budget_per_run} base + ${result.build.additional_clay_credits_per_record} per additional record
|
|
1990
2001
|
`);
|
|
1991
2002
|
if (result.build.delivery_notes) process.stdout.write(`${result.build.delivery_notes}
|
|
1992
2003
|
`);
|
|
1993
2004
|
});
|
|
1994
2005
|
return;
|
|
1995
2006
|
}
|
|
2007
|
+
if (action === "quote") {
|
|
2008
|
+
const buildId = flag("build-id");
|
|
2009
|
+
if (!buildId) throw new CliInputError("signaliz builds quote requires --build-id BLD-...");
|
|
2010
|
+
const result = await client.quoteManagedBuildRun(buildId, readManagedBuildInput());
|
|
2011
|
+
output(result, () => {
|
|
2012
|
+
process.stdout.write(`${result.quote.item_count} record(s): ${result.quote.total_signaliz_credits} Signaliz credits
|
|
2013
|
+
`);
|
|
2014
|
+
process.stdout.write(`Estimated Clay consumption: ${result.quote.estimated_clay_credits} credits
|
|
2015
|
+
`);
|
|
2016
|
+
process.stdout.write("No run created and no credits charged.\n");
|
|
2017
|
+
});
|
|
2018
|
+
return;
|
|
2019
|
+
}
|
|
1996
2020
|
if (action === "run") {
|
|
1997
2021
|
const buildId = flag("build-id");
|
|
1998
2022
|
if (!buildId) throw new CliInputError("signaliz builds run requires --build-id BLD-...");
|
|
1999
|
-
const
|
|
2023
|
+
const maxCredits = numberFlag("max-credits");
|
|
2024
|
+
if (!hasFlag("confirm-spend") || maxCredits === void 0) {
|
|
2025
|
+
throw new CliInputError("Live managed-build runs require --confirm-spend and --max-credits <number>. Use builds quote first.");
|
|
2026
|
+
}
|
|
2027
|
+
const result = await client.runManagedBuild(buildId, readManagedBuildInput(), {
|
|
2028
|
+
idempotencyKey: flag("idempotency-key"),
|
|
2029
|
+
confirmSpend: true,
|
|
2030
|
+
maxCredits
|
|
2031
|
+
});
|
|
2000
2032
|
output(result, () => {
|
|
2033
|
+
if (!result.run) throw new CliInputError(result.message || "Managed build was not queued.");
|
|
2001
2034
|
process.stdout.write(`Managed build queued: ${result.run.run_id}
|
|
2002
2035
|
`);
|
|
2003
2036
|
process.stdout.write(`Charged: ${result.run.fixed_credits_charged} Signaliz credits (${result.run.billing_status})
|
|
@@ -2017,13 +2050,166 @@ async function managedBuilds(args) {
|
|
|
2017
2050
|
process.stdout.write(`${result.run.build_id} run ${result.run.run_id}: ${result.run.status}
|
|
2018
2051
|
`);
|
|
2019
2052
|
process.stdout.write(`Results returned: ${result.returned || 0}
|
|
2053
|
+
`);
|
|
2054
|
+
const csv = result.artifacts?.csv?.download_url;
|
|
2055
|
+
if (csv) process.stdout.write(`CSV: ${csv}
|
|
2020
2056
|
`);
|
|
2021
2057
|
if (result.run.error) process.stdout.write(`Error: ${result.run.error}
|
|
2022
2058
|
`);
|
|
2023
2059
|
});
|
|
2024
2060
|
return;
|
|
2025
2061
|
}
|
|
2026
|
-
|
|
2062
|
+
if (action === "download") {
|
|
2063
|
+
const runId = flag("run-id");
|
|
2064
|
+
const out = flag("out");
|
|
2065
|
+
if (!runId || !out) throw new CliInputError("signaliz builds download requires --run-id <uuid> --out results.csv");
|
|
2066
|
+
const result = await client.getManagedBuildRun(runId, 1);
|
|
2067
|
+
const url = result.artifacts?.csv?.download_url;
|
|
2068
|
+
if (!url) throw new CliInputError("This run does not have a CSV artifact yet. Check builds status first.");
|
|
2069
|
+
const response = await fetch(url);
|
|
2070
|
+
if (!response.ok) throw new Error(`CSV download failed (HTTP ${response.status}).`);
|
|
2071
|
+
(0, import_node_fs.writeFileSync)(out, Buffer.from(await response.arrayBuffer()));
|
|
2072
|
+
output({ success: true, run_id: runId, path: out }, () => process.stdout.write(`Saved ${out}
|
|
2073
|
+
`));
|
|
2074
|
+
return;
|
|
2075
|
+
}
|
|
2076
|
+
throw new CliInputError("Usage: signaliz builds list|get|quote|run|status|download");
|
|
2077
|
+
}
|
|
2078
|
+
var CAMPAIGN_OS_AGENTS = /* @__PURE__ */ new Set([
|
|
2079
|
+
"codex",
|
|
2080
|
+
"claude_code",
|
|
2081
|
+
"cursor",
|
|
2082
|
+
"devin",
|
|
2083
|
+
"grok",
|
|
2084
|
+
"other"
|
|
2085
|
+
]);
|
|
2086
|
+
var CAMPAIGN_OS_ACTIONS = /* @__PURE__ */ new Set([
|
|
2087
|
+
"build_campaign",
|
|
2088
|
+
"refresh_brain",
|
|
2089
|
+
"sync_audience",
|
|
2090
|
+
"prepare_realtime_policy",
|
|
2091
|
+
"provider_load",
|
|
2092
|
+
"provider_activation",
|
|
2093
|
+
"provider_send"
|
|
2094
|
+
]);
|
|
2095
|
+
function campaignOsAgentFlag() {
|
|
2096
|
+
const value = flag("agent")?.trim().toLowerCase().replace(/[\s-]+/g, "_");
|
|
2097
|
+
if (!value) return void 0;
|
|
2098
|
+
if (!CAMPAIGN_OS_AGENTS.has(value)) {
|
|
2099
|
+
throw new CliInputError("--agent must be codex, claude_code, cursor, devin, grok, or other");
|
|
2100
|
+
}
|
|
2101
|
+
return value;
|
|
2102
|
+
}
|
|
2103
|
+
async function campaignOs(args) {
|
|
2104
|
+
const action = args[0];
|
|
2105
|
+
const client = createClient();
|
|
2106
|
+
if (action === "clients") {
|
|
2107
|
+
const limit = numberFlag("limit") ?? 100;
|
|
2108
|
+
requireIntegerInRange(limit, "--limit", 1, 200);
|
|
2109
|
+
const status = flag("status");
|
|
2110
|
+
if (status && !["onboarding", "active", "paused", "archived"].includes(status)) {
|
|
2111
|
+
throw new CliInputError("--status must be onboarding, active, paused, or archived");
|
|
2112
|
+
}
|
|
2113
|
+
const result = await client.listCampaignOsClients({ query: flag("query"), status, limit });
|
|
2114
|
+
output(result, () => {
|
|
2115
|
+
process.stdout.write(`Campaign OS clients: ${result.total_returned}
|
|
2116
|
+
`);
|
|
2117
|
+
for (const item of result.clients) {
|
|
2118
|
+
process.stdout.write(`- ${item.name} (${item.status}) \xB7 Brain v${item.brain_version} \xB7 ${item.counts.sources} sources \xB7 ${item.counts.audiences} audiences \xB7 ${item.counts.campaigns} campaigns
|
|
2119
|
+
`);
|
|
2120
|
+
}
|
|
2121
|
+
});
|
|
2122
|
+
return;
|
|
2123
|
+
}
|
|
2124
|
+
if (action === "context") {
|
|
2125
|
+
const clientId = flag("client-id");
|
|
2126
|
+
if (!clientId) throw new CliInputError("signaliz campaign-os context requires --client-id <uuid>");
|
|
2127
|
+
const sourceLimit = numberFlag("source-limit") ?? 50;
|
|
2128
|
+
requireIntegerInRange(sourceLimit, "--source-limit", 1, 100);
|
|
2129
|
+
const result = await client.getCampaignOsClientContext(clientId, sourceLimit);
|
|
2130
|
+
output(result, () => {
|
|
2131
|
+
const selected = result.client;
|
|
2132
|
+
process.stdout.write(`${String(selected.name || clientId)} \xB7 Brain v${String(selected.brain_version || "?")}
|
|
2133
|
+
`);
|
|
2134
|
+
process.stdout.write(`${result.brain_sources.length} bounded sources \xB7 ${result.audiences.length} audiences \xB7 ${result.campaigns.length} campaigns \xB7 ${result.realtime_policies.length} realtime policies
|
|
2135
|
+
`);
|
|
2136
|
+
process.stdout.write("Raw source bodies and provider secrets were not returned.\n");
|
|
2137
|
+
});
|
|
2138
|
+
return;
|
|
2139
|
+
}
|
|
2140
|
+
if (action === "draft") {
|
|
2141
|
+
const clientId = flag("client-id");
|
|
2142
|
+
const name = flag("name");
|
|
2143
|
+
if (!clientId || !name) throw new CliInputError('signaliz campaign-os draft requires --client-id <uuid> --name "Campaign"');
|
|
2144
|
+
const lane = flag("lane") || "one_time";
|
|
2145
|
+
if (!["one_time", "always_on", "realtime"].includes(lane)) {
|
|
2146
|
+
throw new CliInputError("--lane must be one_time, always_on, or realtime");
|
|
2147
|
+
}
|
|
2148
|
+
const targetCount = numberFlag("target-count");
|
|
2149
|
+
requireIntegerInRange(targetCount, "--target-count", 0, 1e7);
|
|
2150
|
+
const result = await client.createCampaignOsDraft({
|
|
2151
|
+
clientId,
|
|
2152
|
+
name,
|
|
2153
|
+
objective: flag("objective"),
|
|
2154
|
+
lane,
|
|
2155
|
+
targetCount,
|
|
2156
|
+
audienceBindingId: flag("audience-binding-id"),
|
|
2157
|
+
agentVendor: campaignOsAgentFlag(),
|
|
2158
|
+
idempotencyKey: flag("idempotency-key")
|
|
2159
|
+
});
|
|
2160
|
+
output(result, () => {
|
|
2161
|
+
const campaign = record(result.campaign);
|
|
2162
|
+
process.stdout.write(`Review-held draft created: ${String(campaign.name || name)} (${String(campaign.id || "")})
|
|
2163
|
+
`);
|
|
2164
|
+
process.stdout.write("Provider load: locked \xB7 activation: locked \xB7 send: locked\n");
|
|
2165
|
+
process.stdout.write("No Clay or Instantly mutation was performed.\n");
|
|
2166
|
+
});
|
|
2167
|
+
return;
|
|
2168
|
+
}
|
|
2169
|
+
if (action === "request") {
|
|
2170
|
+
const clientId = flag("client-id");
|
|
2171
|
+
const actionType = flag("action");
|
|
2172
|
+
const instructions = flag("instructions");
|
|
2173
|
+
if (!clientId || !actionType || !instructions) {
|
|
2174
|
+
throw new CliInputError('signaliz campaign-os request requires --client-id <uuid> --action <type> --instructions "..."');
|
|
2175
|
+
}
|
|
2176
|
+
if (!CAMPAIGN_OS_ACTIONS.has(actionType)) {
|
|
2177
|
+
throw new CliInputError(`--action must be one of: ${Array.from(CAMPAIGN_OS_ACTIONS).join(", ")}`);
|
|
2178
|
+
}
|
|
2179
|
+
const result = await client.submitCampaignOsActionRequest({
|
|
2180
|
+
clientId,
|
|
2181
|
+
campaignId: flag("campaign-id"),
|
|
2182
|
+
agentVendor: campaignOsAgentFlag(),
|
|
2183
|
+
actionType,
|
|
2184
|
+
instructions,
|
|
2185
|
+
idempotencyKey: flag("idempotency-key")
|
|
2186
|
+
});
|
|
2187
|
+
output(result, () => {
|
|
2188
|
+
const request = record(result.request);
|
|
2189
|
+
process.stdout.write(`Action request recorded: ${String(request.id || "")} \xB7 ${String(request.status || "review_required")}
|
|
2190
|
+
`);
|
|
2191
|
+
process.stdout.write("Execution did not start. Provider mutations require a separate Signaliz admin approval.\n");
|
|
2192
|
+
});
|
|
2193
|
+
return;
|
|
2194
|
+
}
|
|
2195
|
+
if (action === "receipts") {
|
|
2196
|
+
const limit = numberFlag("limit") ?? 50;
|
|
2197
|
+
requireIntegerInRange(limit, "--limit", 1, 200);
|
|
2198
|
+
const result = await client.listCampaignOsReceipts({
|
|
2199
|
+
clientId: flag("client-id"),
|
|
2200
|
+
campaignId: flag("campaign-id"),
|
|
2201
|
+
limit
|
|
2202
|
+
});
|
|
2203
|
+
output(result, () => {
|
|
2204
|
+
const requests = Array.isArray(result.action_requests) ? result.action_requests : [];
|
|
2205
|
+
const deliveries = Array.isArray(result.delivery_receipts) ? result.delivery_receipts : [];
|
|
2206
|
+
process.stdout.write(`${requests.length} agent request receipt(s) \xB7 ${deliveries.length} provider delivery receipt(s)
|
|
2207
|
+
`);
|
|
2208
|
+
process.stdout.write("Provider accepted and mailbox sent remain distinct states.\n");
|
|
2209
|
+
});
|
|
2210
|
+
return;
|
|
2211
|
+
}
|
|
2212
|
+
throw new CliInputError("Usage: signaliz campaign-os clients|context|draft|request|receipts");
|
|
2027
2213
|
}
|
|
2028
2214
|
async function main() {
|
|
2029
2215
|
const [, , command, ...args] = process.argv;
|
|
@@ -2050,6 +2236,8 @@ async function main() {
|
|
|
2050
2236
|
return flow();
|
|
2051
2237
|
case "builds":
|
|
2052
2238
|
return managedBuilds(args);
|
|
2239
|
+
case "campaign-os":
|
|
2240
|
+
return campaignOs(args);
|
|
2053
2241
|
case "signal-to-copy":
|
|
2054
2242
|
return signalToCopy();
|
|
2055
2243
|
case "health":
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signaliz/cli",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Signaliz CLI for core products, Signal Awareness, Signaliz Flow, and reusable managed builds.",
|
|
3
|
+
"version": "1.0.86",
|
|
4
|
+
"description": "Signaliz CLI for Campaign OS, core products, Signal Awareness, Signaliz Flow, and reusable managed builds.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"signaliz": "dist/bin.js"
|
|
7
7
|
},
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"company-signals",
|
|
22
22
|
"signal-to-copy",
|
|
23
23
|
"signals-first",
|
|
24
|
+
"campaign-os",
|
|
24
25
|
"signal-awareness",
|
|
25
26
|
"signaliz-flow"
|
|
26
27
|
],
|
|
@@ -29,7 +30,7 @@
|
|
|
29
30
|
"node": ">=18"
|
|
30
31
|
},
|
|
31
32
|
"dependencies": {
|
|
32
|
-
"@signaliz/sdk": "^1.0.
|
|
33
|
+
"@signaliz/sdk": "^1.0.90"
|
|
33
34
|
},
|
|
34
35
|
"devDependencies": {
|
|
35
36
|
"tsup": "^8.0.0",
|