@pixelml/agenticflow-cli 1.5.1 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/changelog.d.ts.map +1 -1
- package/dist/cli/changelog.js +19 -0
- package/dist/cli/changelog.js.map +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +123 -29
- package/dist/cli/main.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changelog.d.ts","sourceRoot":"","sources":["../../src/cli/changelog.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,eAAO,MAAM,SAAS,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"changelog.d.ts","sourceRoot":"","sources":["../../src/cli/changelog.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,eAAO,MAAM,SAAS,EAAE,cAAc,EAsIrC,CAAC;AAEF,wBAAgB,kBAAkB,IAAI,cAAc,CAEnD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,EAAE,CAInE"}
|
package/dist/cli/changelog.js
CHANGED
|
@@ -5,6 +5,25 @@
|
|
|
5
5
|
* and displayed after upgrade.
|
|
6
6
|
*/
|
|
7
7
|
export const CHANGELOG = [
|
|
8
|
+
{
|
|
9
|
+
version: "1.5.2",
|
|
10
|
+
date: "2026-04-14",
|
|
11
|
+
highlights: [
|
|
12
|
+
"`af workforce run --trigger-data '{...}'` now auto-wraps in the server's required `{trigger_data: ...}` envelope. Previously you had to pass `{\"trigger_data\":{\"topic\":\"AI\"}}` which felt like a CLI bug. Explicit wrapping still works (pass-through)",
|
|
13
|
+
"`af workforce delete` returns the consistent `agenticflow.delete.v1` envelope instead of bare `null`. Scripts now get the same shape as `af agent delete`",
|
|
14
|
+
"`af mcp-clients list --name-contains <substr> --fields id,name` — same filter + projection flags as `af agent list`. Essential for workspaces with dozens of MCP clients",
|
|
15
|
+
"`af mcp-clients inspect` surfaces the underlying `fetch_error` + `classification_reason` when tools can't be enumerated. Stops returning a misleading `pattern: unknown` that callers might treat as 'safe to attach'",
|
|
16
|
+
"`af schema <resource> --field <name>` now resolves against top-level schema keys too (not just create.optional). Lets you drill into `schema`, `update`, `stream` subtrees — e.g. `af schema workforce --field schema --json` returns the node_shape + edge_shape + agent_node_input docs",
|
|
17
|
+
"`af schema agent` clarifies that `project_id` is REQUIRED on create (server does NOT auto-inject for agents, unlike workforces). Separates the contract per resource",
|
|
18
|
+
],
|
|
19
|
+
for_ai: [
|
|
20
|
+
"When you hit a 422 `body.trigger_data missing` on `workforce run`, upgrade to 1.5.2 — the CLI now auto-wraps",
|
|
21
|
+
"If `mcp-clients inspect` returns `classification_reason: 'fetch_failed'` or `'unauthenticated'`, DO NOT attach that client to an agent — re-auth in the web UI first",
|
|
22
|
+
"Filter MCP clients with `af mcp-clients list --name-contains 'google docs' --fields id,name --json` — no more grep-piping",
|
|
23
|
+
"Drill into any schema subtree: `af schema workforce --field schema --json` returns graph shape; `af schema agent --field mcp_clients --json` returns attach shape",
|
|
24
|
+
"Consistent delete envelope: every `af <resource> delete` returns `{schema:'agenticflow.delete.v1', deleted:true, id, resource}` on success",
|
|
25
|
+
],
|
|
26
|
+
},
|
|
8
27
|
{
|
|
9
28
|
version: "1.5.1",
|
|
10
29
|
date: "2026-04-14",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changelog.js","sourceRoot":"","sources":["../../src/cli/changelog.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,CAAC,MAAM,SAAS,GAAqB;IACzC;QACE,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,YAAY;QAClB,UAAU,EAAE;YACV,gSAAgS;YAChS,0HAA0H;YAC1H,2KAA2K;YAC3K,sSAAsS;YACtS,wOAAwO;YACxO,yLAAyL;SAC1L;QACD,MAAM,EAAE;YACN,0UAA0U;YAC1U,+IAA+I;YAC/I,4IAA4I;YAC5I,mKAAmK;SACpK;KACF;IACD;QACE,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,YAAY;QAClB,UAAU,EAAE;YACV,iKAAiK;YACjK,mIAAmI;YACnI,4JAA4J;YAC5J,qJAAqJ;YACrJ,8GAA8G;YAC9G,yGAAyG;SAC1G;QACD,MAAM,EAAE;YACN,mMAAmM;YACnM,wLAAwL;YACxL,wGAAwG;YACxG,gGAAgG;YAChG,iIAAiI;YACjI,oIAAoI;SACrI;KACF;IACD;QACE,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,YAAY;QAClB,UAAU,EAAE;YACV,2GAA2G;YAC3G,+MAA+M;YAC/M,2LAA2L;YAC3L,kJAAkJ;YAClJ,2GAA2G;YAC3G,2GAA2G;YAC3G,iKAAiK;YACjK,kHAAkH;YAClH,uHAAuH;SACxH;QACD,MAAM,EAAE;YACN,6LAA6L;YAC7L,uLAAuL;YACvL,4PAA4P;YAC5P,+JAA+J;YAC/J,2GAA2G;SAC5G;KACF;IACD;QACE,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,YAAY;QAClB,UAAU,EAAE;YACV,uEAAuE;YACvE,mFAAmF;YACnF,yFAAyF;YACzF,gFAAgF;YAChF,kEAAkE;YAClE,uFAAuF;YACvF,iEAAiE;YACjE,uEAAuE;YACvE,yDAAyD;YACzD,wDAAwD;YACxD,6EAA6E;YAC7E,6GAA6G;SAC9G;QACD,MAAM,EAAE;YACN,6FAA6F;YAC7F,+GAA+G;YAC/G,qFAAqF;YACrF,6EAA6E;YAC7E,qEAAqE;YACrE,oHAAoH;YACpH,wGAAwG;YACxG,mGAAmG;SACpG;KACF;IACD;QACE,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,YAAY;QAClB,UAAU,EAAE;YACV,gEAAgE;YAChE,uEAAuE;YACvE,mDAAmD;YACnD,4CAA4C;SAC7C;QACD,MAAM,EAAE;YACN,6CAA6C;YAC7C,6DAA6D;SAC9D;KACF;IACD;QACE,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,YAAY;QAClB,UAAU,EAAE;YACV,kCAAkC;YAClC,6CAA6C;YAC7C,qCAAqC;SACtC;QACD,MAAM,EAAE;YACN,0CAA0C;SAC3C;KACF;CACF,CAAC;AAEF,MAAM,UAAU,kBAAkB;IAChC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,MAAM,GAAG,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC;IAC9D,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACjC,CAAC"}
|
|
1
|
+
{"version":3,"file":"changelog.js","sourceRoot":"","sources":["../../src/cli/changelog.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAy4BpC,wBAAgB,aAAa,IAAI,OAAO,
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAy4BpC,wBAAgB,aAAa,IAAI,OAAO,CA81KvC;AAED,wBAAsB,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB3D"}
|
package/dist/cli/main.js
CHANGED
|
@@ -758,6 +758,7 @@ export function createProgram() {
|
|
|
758
758
|
const SCHEMAS = {
|
|
759
759
|
agent: {
|
|
760
760
|
resource: "agent",
|
|
761
|
+
note: "`project_id` is REQUIRED in the body on agent create (server does NOT auto-inject from client config, unlike workforces). The CLI's local validator enforces this — grab the value from `af bootstrap --json > auth.project_id`. The `workspace_id` scoping is handled server-side via API key.",
|
|
761
762
|
create: {
|
|
762
763
|
required: ["name", "tools", "project_id"],
|
|
763
764
|
optional: {
|
|
@@ -1094,39 +1095,59 @@ export function createProgram() {
|
|
|
1094
1095
|
if (!schema) {
|
|
1095
1096
|
fail("schema_not_found", `Unknown resource: ${resource}`, `Available: ${Object.keys(SCHEMAS).join(", ")}`);
|
|
1096
1097
|
}
|
|
1097
|
-
// Field drilldown:
|
|
1098
|
+
// Field drilldown: resolve `--field X` against multiple schema locations.
|
|
1099
|
+
// We look in this order: top-level sibling key (e.g. `schema`, `update`,
|
|
1100
|
+
// `stream`), then create.required, then create.optional. This lets the
|
|
1101
|
+
// drilldown return rich subtree docs (like `schema` node/edge shapes on
|
|
1102
|
+
// the workforce resource) rather than "not found".
|
|
1098
1103
|
if (opts?.field) {
|
|
1099
1104
|
const fieldName = opts.field;
|
|
1100
1105
|
const s = schema;
|
|
1101
|
-
const create = s.create ?? {};
|
|
1102
|
-
const required = create.required ?? [];
|
|
1103
|
-
const optional = create.optional ?? {};
|
|
1104
1106
|
let doc = null;
|
|
1107
|
+
let location = null;
|
|
1105
1108
|
let isRequired = false;
|
|
1106
|
-
if (
|
|
1107
|
-
doc =
|
|
1108
|
-
|
|
1109
|
+
if (fieldName in s && fieldName !== "resource" && fieldName !== "fields") {
|
|
1110
|
+
doc = s[fieldName];
|
|
1111
|
+
location = "top_level";
|
|
1109
1112
|
}
|
|
1110
|
-
|
|
1111
|
-
|
|
1113
|
+
else {
|
|
1114
|
+
const create = s.create ?? {};
|
|
1115
|
+
const required = create.required ?? [];
|
|
1116
|
+
const optional = create.optional ?? {};
|
|
1117
|
+
if (required.includes(fieldName)) {
|
|
1118
|
+
doc = "required";
|
|
1119
|
+
isRequired = true;
|
|
1120
|
+
location = "create.required";
|
|
1121
|
+
}
|
|
1122
|
+
else if (fieldName in optional) {
|
|
1123
|
+
doc = optional[fieldName] ?? null;
|
|
1124
|
+
location = "create.optional";
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
const found = doc !== null && doc !== undefined;
|
|
1112
1128
|
const result = {
|
|
1113
1129
|
schema: "agenticflow.schema.field.v1",
|
|
1114
1130
|
resource: s.resource,
|
|
1115
1131
|
field: fieldName,
|
|
1116
1132
|
required: isRequired,
|
|
1133
|
+
location,
|
|
1117
1134
|
doc,
|
|
1118
|
-
found
|
|
1119
|
-
hint:
|
|
1120
|
-
? `Field '${fieldName}' has no documented shape in the static schema. For live introspection, fetch an existing instance via 'af ${s.resource} get --${s.resource}-id <id> --json' and inspect the returned value for that field.`
|
|
1135
|
+
found,
|
|
1136
|
+
hint: !found
|
|
1137
|
+
? `Field '${fieldName}' has no documented shape in the static schema. Candidates: top-level keys (${Object.keys(s).filter((k) => !["resource", "fields"].includes(k)).join(", ")}); create.required; create.optional. For live introspection, fetch an existing instance via 'af ${s.resource} get --${s.resource}-id <id> --json' and inspect the returned value for that field.`
|
|
1121
1138
|
: undefined,
|
|
1122
1139
|
};
|
|
1123
1140
|
if (isJsonFlagEnabled()) {
|
|
1124
1141
|
printResult(result);
|
|
1125
1142
|
}
|
|
1126
1143
|
else {
|
|
1127
|
-
console.log(`${s.resource}.${fieldName}${isRequired ? " (required)" : "
|
|
1128
|
-
if (doc)
|
|
1144
|
+
console.log(`${s.resource}.${fieldName}${isRequired ? " (required)" : ""}${location ? ` [${location}]` : ""}`);
|
|
1145
|
+
if (typeof doc === "string") {
|
|
1129
1146
|
console.log(` ${doc}`);
|
|
1147
|
+
}
|
|
1148
|
+
else if (doc !== null && doc !== undefined) {
|
|
1149
|
+
console.log(JSON.stringify(doc, null, 2).split("\n").map((l) => " " + l).join("\n"));
|
|
1150
|
+
}
|
|
1130
1151
|
if (result.hint)
|
|
1131
1152
|
console.log(` ${result.hint}`);
|
|
1132
1153
|
}
|
|
@@ -4040,28 +4061,54 @@ export function createProgram() {
|
|
|
4040
4061
|
.option("--project-id <id>", "Project ID")
|
|
4041
4062
|
.option("--limit <n>", "Limit")
|
|
4042
4063
|
.option("--offset <n>", "Offset")
|
|
4064
|
+
.option("--name-contains <substr>", "Client-side case-insensitive substring filter on client `name`. Essential in busy workspaces with dozens of MCP clients.")
|
|
4065
|
+
.option("--fields <fields>", "Comma-separated fields to return (e.g. id,name,is_authenticated). Applies after --name-contains filter.")
|
|
4043
4066
|
.option("--verify-auth", "Reconcile is_authenticated by calling `get` for each client — slower " +
|
|
4044
4067
|
"but catches the case where list() reports auth=true but get() reveals " +
|
|
4045
4068
|
"the underlying provider session is expired. N+1 call; use sparingly.")
|
|
4046
4069
|
.action(async (opts) => {
|
|
4047
4070
|
const client = buildClient(program.opts());
|
|
4071
|
+
// Helper: apply client-side name filter + fields projection to a list response
|
|
4072
|
+
const postFilter = (rows) => {
|
|
4073
|
+
let out = rows;
|
|
4074
|
+
const nameContains = opts.nameContains;
|
|
4075
|
+
if (nameContains && Array.isArray(out)) {
|
|
4076
|
+
const needle = nameContains.toLowerCase();
|
|
4077
|
+
out = out.filter((r) => {
|
|
4078
|
+
const n = r["name"];
|
|
4079
|
+
return typeof n === "string" && n.toLowerCase().includes(needle);
|
|
4080
|
+
});
|
|
4081
|
+
}
|
|
4082
|
+
return applyFieldsFilter(out, opts.fields);
|
|
4083
|
+
};
|
|
4048
4084
|
if (!opts.verifyAuth) {
|
|
4049
|
-
await run(() =>
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4085
|
+
await run(async () => {
|
|
4086
|
+
const rows = await client.mcpClients.list({
|
|
4087
|
+
workspaceId: opts.workspaceId,
|
|
4088
|
+
projectId: opts.projectId,
|
|
4089
|
+
limit: parseOptionalInteger(opts.limit, "--limit", 1),
|
|
4090
|
+
offset: parseOptionalInteger(opts.offset, "--offset", 0),
|
|
4091
|
+
});
|
|
4092
|
+
return postFilter(rows);
|
|
4093
|
+
});
|
|
4055
4094
|
return;
|
|
4056
4095
|
}
|
|
4057
|
-
// --verify-auth: list, then re-check each row's auth via get()
|
|
4096
|
+
// --verify-auth: list, filter, then re-check each remaining row's auth via get()
|
|
4058
4097
|
await run(async () => {
|
|
4059
|
-
|
|
4098
|
+
let rows = (await client.mcpClients.list({
|
|
4060
4099
|
workspaceId: opts.workspaceId,
|
|
4061
4100
|
projectId: opts.projectId,
|
|
4062
4101
|
limit: parseOptionalInteger(opts.limit, "--limit", 1),
|
|
4063
4102
|
offset: parseOptionalInteger(opts.offset, "--offset", 0),
|
|
4064
4103
|
}));
|
|
4104
|
+
const nameContains = opts.nameContains;
|
|
4105
|
+
if (nameContains) {
|
|
4106
|
+
const needle = nameContains.toLowerCase();
|
|
4107
|
+
rows = rows.filter((r) => {
|
|
4108
|
+
const n = r["name"];
|
|
4109
|
+
return typeof n === "string" && n.toLowerCase().includes(needle);
|
|
4110
|
+
});
|
|
4111
|
+
}
|
|
4065
4112
|
const verified = await Promise.all(rows.map(async (row) => {
|
|
4066
4113
|
const id = row["id"];
|
|
4067
4114
|
if (!id)
|
|
@@ -4079,7 +4126,7 @@ export function createProgram() {
|
|
|
4079
4126
|
return { ...row, verified_auth_error: err instanceof Error ? err.message : String(err) };
|
|
4080
4127
|
}
|
|
4081
4128
|
}));
|
|
4082
|
-
return verified;
|
|
4129
|
+
return applyFieldsFilter(verified, opts.fields);
|
|
4083
4130
|
});
|
|
4084
4131
|
});
|
|
4085
4132
|
mcpClientsCmd
|
|
@@ -4118,16 +4165,38 @@ export function createProgram() {
|
|
|
4118
4165
|
? (toolsBox.tools)
|
|
4119
4166
|
: [];
|
|
4120
4167
|
const report = inspectMcpToolsPattern(tools);
|
|
4168
|
+
// Surface the underlying fetch/auth error when the tools list couldn't
|
|
4169
|
+
// be enumerated — previously we silently returned pattern="unknown",
|
|
4170
|
+
// which callers mistook for "safe to attach." Now the `fetch_error`
|
|
4171
|
+
// + `classification_reason` make the failure explicit.
|
|
4172
|
+
const fetchError = raw["error"];
|
|
4173
|
+
const isAuth = raw["is_authenticated"];
|
|
4174
|
+
const classification_reason = tools.length > 0
|
|
4175
|
+
? "tools_enumerated"
|
|
4176
|
+
: fetchError
|
|
4177
|
+
? "fetch_failed"
|
|
4178
|
+
: isAuth === false
|
|
4179
|
+
? "unauthenticated"
|
|
4180
|
+
: "unknown";
|
|
4181
|
+
const additional_quirks = [...report.quirks];
|
|
4182
|
+
if (tools.length === 0 && (fetchError || isAuth === false)) {
|
|
4183
|
+
additional_quirks.unshift(`Cannot classify this MCP client's tools — ${classification_reason}. ` +
|
|
4184
|
+
(fetchError ? `Server reported: ${fetchError}. ` : "") +
|
|
4185
|
+
`Do NOT attach this client to an agent until the underlying issue is resolved. ` +
|
|
4186
|
+
`Re-auth via the AgenticFlow web UI (workspaces/<ws>/mcp/${clientId}).`);
|
|
4187
|
+
}
|
|
4121
4188
|
return {
|
|
4122
4189
|
schema: "agenticflow.mcp_client.inspect.v1",
|
|
4123
4190
|
client_id: clientId,
|
|
4124
4191
|
client_name: raw["name"] ?? null,
|
|
4125
|
-
is_authenticated:
|
|
4192
|
+
is_authenticated: isAuth ?? null,
|
|
4126
4193
|
tool_count: tools.length,
|
|
4127
4194
|
pattern: report.pattern, // "pipedream" | "composio" | "mixed" | "unknown"
|
|
4195
|
+
classification_reason,
|
|
4196
|
+
fetch_error: fetchError ?? null,
|
|
4128
4197
|
write_capable_tools: report.writeCapable,
|
|
4129
4198
|
pipedream_instruction_only_tools: report.pipedreamTools,
|
|
4130
|
-
known_quirks:
|
|
4199
|
+
known_quirks: additional_quirks,
|
|
4131
4200
|
playbook: "af playbook mcp-client-quirks",
|
|
4132
4201
|
};
|
|
4133
4202
|
});
|
|
@@ -4216,7 +4285,21 @@ export function createProgram() {
|
|
|
4216
4285
|
.option("--workspace-id <id>", "Workspace ID (overrides env)")
|
|
4217
4286
|
.action(async (opts) => {
|
|
4218
4287
|
const client = buildClient(program.opts());
|
|
4219
|
-
|
|
4288
|
+
try {
|
|
4289
|
+
await client.workforces.delete(opts.workforceId, { workspaceId: opts.workspaceId });
|
|
4290
|
+
// Server returns 204/null on success — wrap in the same delete envelope
|
|
4291
|
+
// that `af agent delete` uses so scripts get a consistent shape.
|
|
4292
|
+
printResult({
|
|
4293
|
+
schema: "agenticflow.delete.v1",
|
|
4294
|
+
deleted: true,
|
|
4295
|
+
id: opts.workforceId,
|
|
4296
|
+
resource: "workforce",
|
|
4297
|
+
});
|
|
4298
|
+
}
|
|
4299
|
+
catch (err) {
|
|
4300
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
4301
|
+
fail("request_failed", message);
|
|
4302
|
+
}
|
|
4220
4303
|
});
|
|
4221
4304
|
workforceCmd
|
|
4222
4305
|
.command("schema")
|
|
@@ -4275,13 +4358,24 @@ export function createProgram() {
|
|
|
4275
4358
|
.description("Execute a workforce. Streams SSE events — each event prints as one JSON line. " +
|
|
4276
4359
|
"Exits when the stream closes.")
|
|
4277
4360
|
.requiredOption("--workforce-id <id>", "Workforce ID")
|
|
4278
|
-
.option("--trigger-data <json>", "Trigger
|
|
4361
|
+
.option("--trigger-data <json>", "Trigger input as inline JSON or @file. Pass the data your trigger node expects " +
|
|
4362
|
+
"(e.g. `{\"topic\":\"AI\"}`) — the CLI automatically wraps it in the server's " +
|
|
4363
|
+
"required `{trigger_data: ...}` envelope. If you pass `{\"trigger_data\":{...}}` " +
|
|
4364
|
+
"explicitly, it's left as-is.", "{}")
|
|
4279
4365
|
.option("--workspace-id <id>", "Workspace ID (overrides env)")
|
|
4280
4366
|
.action(async (opts) => {
|
|
4281
4367
|
const client = buildClient(program.opts());
|
|
4282
|
-
const
|
|
4368
|
+
const raw = loadJsonPayload(opts.triggerData);
|
|
4369
|
+
// Server accepts `{trigger_data: {...}}`. If the caller already wrapped
|
|
4370
|
+
// it (explicitly nested under trigger_data), pass through. Otherwise,
|
|
4371
|
+
// wrap the user's payload. This is the ergonomics fix for friction S6 —
|
|
4372
|
+
// previously passing `{topic:"..."}` returned `422: body.trigger_data
|
|
4373
|
+
// missing` which looked like a CLI bug, not a payload shape bug.
|
|
4374
|
+
const triggerBody = "trigger_data" in raw && typeof raw["trigger_data"] === "object" && raw["trigger_data"] !== null
|
|
4375
|
+
? raw
|
|
4376
|
+
: { trigger_data: raw };
|
|
4283
4377
|
try {
|
|
4284
|
-
const response = await client.workforces.run(opts.workforceId,
|
|
4378
|
+
const response = await client.workforces.run(opts.workforceId, triggerBody, {
|
|
4285
4379
|
workspaceId: opts.workspaceId,
|
|
4286
4380
|
});
|
|
4287
4381
|
if (!response.ok) {
|