@fluentcommerce/fluent-mcp-extn 0.2.1 → 0.3.1

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/tools.js CHANGED
@@ -6,8 +6,8 @@ import { buildEventPayload } from "./event-payload.js";
6
6
  import { ToolError, toToolFailure } from "./errors.js";
7
7
  // New tool modules
8
8
  import { ENTITY_TOOL_DEFINITIONS, handleEntityCreate, handleEntityUpdate, handleEntityGet, } from "./entity-tools.js";
9
- import { WORKFLOW_TOOL_DEFINITIONS, handleWorkflowUpload, handleWorkflowDiff, handleWorkflowSimulate, } from "./workflow-tools.js";
10
- import { SETTING_TOOL_DEFINITIONS, handleSettingUpsert, handleSettingBulkUpsert, } from "./settings-tools.js";
9
+ import { WORKFLOW_TOOL_DEFINITIONS, handleWorkflowGet, handleWorkflowList, handleWorkflowUpload, handleWorkflowDiff, handleWorkflowSimulate, } from "./workflow-tools.js";
10
+ import { SETTING_TOOL_DEFINITIONS, handleSettingGet, handleSettingUpsert, handleSettingBulkUpsert, } from "./settings-tools.js";
11
11
  import { ENVIRONMENT_TOOL_DEFINITIONS, handleEnvironmentDiscover, handleEnvironmentValidate, } from "./environment-tools.js";
12
12
  import { TEST_TOOL_DEFINITIONS, handleTestAssert, } from "./test-tools.js";
13
13
  import { shapeResponse, summarizeConnection, analyzeEvents, } from "./response-shaper.js";
@@ -128,6 +128,8 @@ const TransitionTriggerInputSchema = z.object({
128
128
  module: z.string().min(1).optional(),
129
129
  flexType: z.string().min(1).optional(),
130
130
  flexVersion: z.union([z.string().min(1), z.number().int()]).optional(),
131
+ entityId: z.string().min(1).optional(),
132
+ entityRef: z.string().min(1).optional(),
131
133
  });
132
134
  const TransitionActionsInputSchema = z.object({
133
135
  triggers: z.array(TransitionTriggerInputSchema).min(1),
@@ -599,8 +601,16 @@ const TOOL_DEFINITIONS = [
599
601
  "INTEGRATION: The eventName from each userAction maps directly to event.send's \"name\" parameter.",
600
602
  "The attributes[] tell you what to include in event.send's \"attributes\" parameter.",
601
603
  "",
604
+ "CRITICAL: The Transition API requires `flexType` (e.g. ORDER::HD) to return results.",
605
+ "Without it the API silently returns empty `{response:[]}`. For some entity types",
606
+ "(e.g. CREDIT_MEMO) `flexVersion` is also required. When `type` and `subtype` are",
607
+ "provided but `flexType` is not, the tool auto-derives it as `TYPE::SUBTYPE`.",
608
+ "",
609
+ "BEST PRACTICE: Always provide `flexType` and `flexVersion` for reliable results.",
610
+ "Get these from the entity's `workflowRef` and `workflowVersion` fields via GraphQL.",
611
+ "",
602
612
  "EXAMPLE: Find available actions for an ORDER in CREATED status:",
603
- "{ triggers: [{ type: \"ORDER\", subtype: \"HD\", status: \"CREATED\", retailerId: \"5\", flexType: \"ORDER::HD\" }] }",
613
+ "{ triggers: [{ type: \"ORDER\", subtype: \"HD\", status: \"CREATED\", retailerId: \"5\", flexType: \"ORDER::HD\", flexVersion: 4 }] }",
604
614
  ].join("\n"),
605
615
  inputSchema: {
606
616
  type: "object",
@@ -623,17 +633,19 @@ const TOOL_DEFINITIONS = [
623
633
  },
624
634
  module: {
625
635
  type: "string",
626
- description: "Filter by module (e.g. servicepoint, adminconsole). Case-sensitive.",
636
+ description: "REQUIRED for results. App module name (e.g. adminconsole, oms, store, servicepoint). Without this, API silently returns empty userActions. Case-sensitive.",
627
637
  },
628
638
  flexType: {
629
639
  type: "string",
630
- description: "Workflow type (e.g. ORDER::HD, FULFILMENT::HD_WH).",
640
+ description: "Workflow type (e.g. ORDER::HD, FULFILMENT::HD_WH). REQUIRED for API to return results. Auto-derived from type::subtype when omitted.",
631
641
  },
632
642
  flexVersion: {
633
643
  oneOf: [{ type: "integer" }, { type: "string" }],
634
- description: "Workflow version. Omit for latest.",
644
+ description: "Workflow version. Strongly recommended — required for some entity types (e.g. CREDIT_MEMO). Get from entity's workflowVersion field.",
635
645
  },
636
646
  name: { type: "string", description: "Event name filter" },
647
+ entityId: { type: "string", description: "Entity ID (strongly recommended — API may return empty without it)" },
648
+ entityRef: { type: "string", description: "Entity ref (strongly recommended — API may return empty without it)" },
637
649
  },
638
650
  required: ["retailerId"],
639
651
  additionalProperties: false,
@@ -1258,7 +1270,14 @@ export function toEventQueryParams(input) {
1258
1270
  return params;
1259
1271
  }
1260
1272
  /**
1261
- * Fill missing trigger.retailerId from runtime config and validate readiness.
1273
+ * Fill missing trigger fields from runtime config and validate readiness.
1274
+ *
1275
+ * The Transition API requires `flexType` (e.g. "ORDER::HD") to return results.
1276
+ * Without it the API silently returns `{"response":[]}`. For some entity
1277
+ * types (e.g. CREDIT_MEMO) `flexVersion` is also required.
1278
+ *
1279
+ * This function auto-derives `flexType` from `type`+`subtype` when both are
1280
+ * present and `flexType` is not explicitly set.
1262
1281
  */
1263
1282
  export function resolveTransitionRequest(input, fallbackRetailerId) {
1264
1283
  const triggers = input.triggers.map((trigger, index) => {
@@ -1266,9 +1285,16 @@ export function resolveTransitionRequest(input, fallbackRetailerId) {
1266
1285
  if (!retailerId) {
1267
1286
  throw new ToolError("VALIDATION_ERROR", `triggers[${index}].retailerId is required. Set FLUENT_RETAILER_ID or pass retailerId per trigger.`);
1268
1287
  }
1288
+ // Auto-derive flexType from type+subtype when not explicitly provided.
1289
+ // The Transition API requires flexType to return user actions.
1290
+ let flexType = trigger.flexType;
1291
+ if (!flexType && trigger.type && trigger.subtype) {
1292
+ flexType = `${trigger.type}::${trigger.subtype}`;
1293
+ }
1269
1294
  return {
1270
1295
  ...trigger,
1271
1296
  retailerId,
1297
+ ...(flexType ? { flexType } : {}),
1272
1298
  };
1273
1299
  });
1274
1300
  return { triggers };
@@ -3212,6 +3238,16 @@ export function registerToolHandlers(server, ctx) {
3212
3238
  const result = await handleEntityGet(args, ctx);
3213
3239
  return json(result, false, ctx.responseBudget);
3214
3240
  }
3241
+ // ------- workflow.get ---------------------------------------------------
3242
+ if (toolName === "workflow.get") {
3243
+ const result = await handleWorkflowGet(args, ctx);
3244
+ return json(result, false, ctx.responseBudget);
3245
+ }
3246
+ // ------- workflow.list --------------------------------------------------
3247
+ if (toolName === "workflow.list") {
3248
+ const result = await handleWorkflowList(args, ctx);
3249
+ return json(result, false, ctx.responseBudget);
3250
+ }
3215
3251
  // ------- workflow.upload -----------------------------------------------
3216
3252
  if (toolName === "workflow.upload") {
3217
3253
  const result = await handleWorkflowUpload(args, ctx);
@@ -3227,6 +3263,11 @@ export function registerToolHandlers(server, ctx) {
3227
3263
  const result = await handleWorkflowSimulate(args, ctx);
3228
3264
  return json(result, false, ctx.responseBudget);
3229
3265
  }
3266
+ // ------- setting.get ---------------------------------------------------
3267
+ if (toolName === "setting.get") {
3268
+ const result = await handleSettingGet(args, ctx);
3269
+ return json(result, false, ctx.responseBudget);
3270
+ }
3230
3271
  // ------- setting.upsert ------------------------------------------------
3231
3272
  if (toolName === "setting.upsert") {
3232
3273
  const result = await handleSettingUpsert(args, ctx);
@@ -7,6 +7,8 @@
7
7
  * event outcomes without live execution.
8
8
  */
9
9
  import { z } from "zod";
10
+ import * as fs from "node:fs";
11
+ import * as path from "node:path";
10
12
  import { ToolError } from "./errors.js";
11
13
  // ---------------------------------------------------------------------------
12
14
  // Input schemas
@@ -40,6 +42,42 @@ export const WorkflowDiffInputSchema = z.object({
40
42
  .default("summary")
41
43
  .describe("Output format: summary (default), detailed, or mermaid"),
42
44
  });
45
+ export const WorkflowGetInputSchema = z.object({
46
+ entityType: z
47
+ .string()
48
+ .describe("Workflow entity type (e.g., ORDER, FULFILMENT, INVENTORY_CATALOGUE, RETURN_ORDER, BILLING_ACCOUNT, VIRTUAL_CATALOGUE, PRODUCT_CATALOGUE, CONTROL_GROUP, PAYMENT, WAVE, CONSIGNMENT, ARTICLE)."),
49
+ entitySubtype: z
50
+ .string()
51
+ .describe("Workflow entity subtype (e.g., HD, DEFAULT, MASTER, BASE, CC, CUSTOMER, REFUND, PAYMENT)."),
52
+ retailerId: z
53
+ .string()
54
+ .optional()
55
+ .describe("Target retailer ID. Falls back to FLUENT_RETAILER_ID."),
56
+ version: z
57
+ .string()
58
+ .optional()
59
+ .describe("Specific workflow version to fetch. Omit for latest."),
60
+ outputFile: z
61
+ .string()
62
+ .optional()
63
+ .describe("Optional file path to save the full workflow JSON. " +
64
+ "When provided, writes workflow to file and returns only summary " +
65
+ "(name, version, status/ruleset counts) — keeps large workflow JSON out of the LLM context. " +
66
+ "Parent directories are created automatically."),
67
+ });
68
+ export const WorkflowListInputSchema = z.object({
69
+ retailerId: z
70
+ .string()
71
+ .optional()
72
+ .describe("Target retailer ID. Falls back to FLUENT_RETAILER_ID."),
73
+ outputDir: z
74
+ .string()
75
+ .optional()
76
+ .describe("Optional directory path to download ALL workflows (latest version each) as individual JSON files. " +
77
+ "Each file is named <ENTITY_TYPE>-<ENTITY_SUBTYPE>.json (e.g., ORDER-HD.json). " +
78
+ "Returns only summary metadata — full workflow JSON is NOT included in the response. " +
79
+ "Reads from live server (NOT workflowlog cache). Parent directories are created automatically."),
80
+ });
43
81
  export const WorkflowSimulateInputSchema = z.object({
44
82
  workflow: z
45
83
  .union([z.string(), z.record(z.string(), z.unknown())])
@@ -64,6 +102,91 @@ export const WorkflowSimulateInputSchema = z.object({
64
102
  // Tool definitions (JSON Schema for MCP)
65
103
  // ---------------------------------------------------------------------------
66
104
  export const WORKFLOW_TOOL_DEFINITIONS = [
105
+ {
106
+ name: "workflow.get",
107
+ description: [
108
+ "Fetch a workflow definition by entity type and subtype from the Fluent REST API.",
109
+ "",
110
+ "Calls GET /api/v4.1/workflow/{retailerId}/{entityType}::{entitySubtype}/",
111
+ "Returns the full workflow JSON including statuses, rulesets, rules, and triggers.",
112
+ "",
113
+ "NOTE: This fetches a specific workflow by name, which works even when the list",
114
+ "endpoint returns 401 (insufficient permissions for listing).",
115
+ "",
116
+ "KNOWN ENTITY TYPES:",
117
+ "ORDER, FULFILMENT, INVENTORY_CATALOGUE, RETURN_ORDER, BILLING_ACCOUNT,",
118
+ "VIRTUAL_CATALOGUE, PRODUCT_CATALOGUE, CONTROL_GROUP, PAYMENT, WAVE,",
119
+ "CONSIGNMENT, ARTICLE, LOCATION, NETWORK, CUSTOMER, CREDIT_MEMO",
120
+ "",
121
+ "COMMON SUBTYPES:",
122
+ "HD, CC, DEFAULT, MASTER, BASE, CUSTOMER, REFUND, PAYMENT, HD_WH, HD_MP",
123
+ "",
124
+ "RESPONSE includes: name, version, entityType, entitySubtype, statuses, rulesets,",
125
+ "and a summary with status/ruleset/rule counts.",
126
+ "",
127
+ "Use outputFile to save large workflow JSON to disk instead of returning inline.",
128
+ "Returns only summary (name, version, counts) when outputFile is set.",
129
+ ].join("\n"),
130
+ inputSchema: {
131
+ type: "object",
132
+ properties: {
133
+ entityType: {
134
+ type: "string",
135
+ description: "Workflow entity type (e.g., ORDER, FULFILMENT, INVENTORY_CATALOGUE)",
136
+ },
137
+ entitySubtype: {
138
+ type: "string",
139
+ description: "Workflow entity subtype (e.g., HD, DEFAULT, MASTER)",
140
+ },
141
+ retailerId: {
142
+ type: "string",
143
+ description: "Target retailer ID.",
144
+ },
145
+ version: {
146
+ type: "string",
147
+ description: "Specific workflow version. Omit for latest.",
148
+ },
149
+ outputFile: {
150
+ type: "string",
151
+ description: "File path to save workflow JSON. Returns summary only (not full JSON) when set.",
152
+ },
153
+ },
154
+ required: ["entityType", "entitySubtype"],
155
+ additionalProperties: false,
156
+ },
157
+ },
158
+ {
159
+ name: "workflow.list",
160
+ description: [
161
+ "List all workflows for a retailer from the Fluent REST API.",
162
+ "",
163
+ "Calls GET /api/v4.1/workflow?retailerId={retailerId}",
164
+ "Returns a list of workflow summaries (name, version, entityType, entitySubtype, status).",
165
+ "",
166
+ "When outputDir is provided, downloads ALL workflows (latest version each) as individual",
167
+ "JSON files to the directory. Each file is named <TYPE>-<SUBTYPE>.json (e.g., ORDER-HD.json).",
168
+ "Returns only summary metadata — full JSON stays on disk, not in the response.",
169
+ "Reads from LIVE server, not the workflowlog cache.",
170
+ "",
171
+ "NOTE: This endpoint may return 401 on some accounts where the user lacks listing",
172
+ "permissions. In that case, use workflow.get to fetch a specific workflow by name.",
173
+ ].join("\n"),
174
+ inputSchema: {
175
+ type: "object",
176
+ properties: {
177
+ retailerId: {
178
+ type: "string",
179
+ description: "Target retailer ID.",
180
+ },
181
+ outputDir: {
182
+ type: "string",
183
+ description: "Directory to save all workflows as individual JSON files. Returns summary only when set.",
184
+ },
185
+ },
186
+ required: [],
187
+ additionalProperties: false,
188
+ },
189
+ },
67
190
  {
68
191
  name: "workflow.upload",
69
192
  description: [
@@ -750,3 +873,166 @@ export async function handleWorkflowSimulate(args, _ctx) {
750
873
  limitations,
751
874
  };
752
875
  }
876
+ /**
877
+ * Handle workflow.get tool call.
878
+ * Fetches a specific workflow by entityType::entitySubtype via REST API.
879
+ */
880
+ export async function handleWorkflowGet(args, ctx) {
881
+ const parsed = WorkflowGetInputSchema.parse(args);
882
+ const retailerId = parsed.retailerId ?? ctx.config.retailerId;
883
+ if (!retailerId) {
884
+ throw new ToolError("VALIDATION_ERROR", "retailerId is required. Set FLUENT_RETAILER_ID or pass retailerId.");
885
+ }
886
+ const client = requireWorkflowClient(ctx);
887
+ const workflowName = `${parsed.entityType}::${parsed.entitySubtype}`;
888
+ const response = await client.getWorkflow(retailerId, parsed.entityType, parsed.entitySubtype, parsed.version);
889
+ // Extract summary info from the workflow
890
+ const wf = response;
891
+ if (!wf || typeof wf !== "object") {
892
+ throw new ToolError("VALIDATION_ERROR", `No workflow found for ${workflowName} on retailer ${retailerId}.`);
893
+ }
894
+ const statuses = (wf.statuses ?? wf.subStatuses);
895
+ const rulesets = wf.rulesets;
896
+ const totalRules = (rulesets ?? []).reduce((sum, rs) => {
897
+ const rules = rs.rules;
898
+ return sum + (rules?.length ?? 0);
899
+ }, 0);
900
+ const summary = {
901
+ statuses: statuses?.length ?? 0,
902
+ rulesets: rulesets?.length ?? 0,
903
+ totalRules,
904
+ };
905
+ // If outputFile is provided, write workflow to file and return summary only
906
+ if (parsed.outputFile) {
907
+ const fileContent = JSON.stringify(wf, null, 2);
908
+ const dir = path.dirname(parsed.outputFile);
909
+ fs.mkdirSync(dir, { recursive: true });
910
+ fs.writeFileSync(parsed.outputFile, fileContent, "utf-8");
911
+ return {
912
+ ok: true,
913
+ workflowName: wf.name ?? workflowName,
914
+ version: wf.version,
915
+ entityType: wf.entityType ?? parsed.entityType,
916
+ entitySubtype: wf.entitySubtype ?? parsed.entitySubtype,
917
+ retailerId,
918
+ summary,
919
+ savedTo: parsed.outputFile,
920
+ sizeBytes: Buffer.byteLength(fileContent, "utf-8"),
921
+ message: `Workflow saved to ${parsed.outputFile} (${Buffer.byteLength(fileContent, "utf-8")} bytes). Full JSON NOT included in response.`,
922
+ };
923
+ }
924
+ return {
925
+ ok: true,
926
+ workflowName: wf.name ?? workflowName,
927
+ version: wf.version,
928
+ entityType: wf.entityType ?? parsed.entityType,
929
+ entitySubtype: wf.entitySubtype ?? parsed.entitySubtype,
930
+ retailerId,
931
+ summary,
932
+ workflow: wf,
933
+ };
934
+ }
935
+ /**
936
+ * Handle workflow.list tool call.
937
+ * Lists all workflows for a retailer via REST API.
938
+ */
939
+ export async function handleWorkflowList(args, ctx) {
940
+ const parsed = WorkflowListInputSchema.parse(args);
941
+ const retailerId = parsed.retailerId ?? ctx.config.retailerId;
942
+ if (!retailerId) {
943
+ throw new ToolError("VALIDATION_ERROR", "retailerId is required. Set FLUENT_RETAILER_ID or pass retailerId.");
944
+ }
945
+ const client = requireWorkflowClient(ctx);
946
+ const response = await client.listWorkflows(retailerId);
947
+ // Response can be: bare array, paginated { results: [...] }, or unwrapped from { data: ... }
948
+ let workflows;
949
+ if (Array.isArray(response)) {
950
+ workflows = response;
951
+ }
952
+ else if (response && typeof response === "object" && "results" in response) {
953
+ workflows = response.results;
954
+ }
955
+ else {
956
+ workflows = [];
957
+ }
958
+ // Deduplicate: group by name, keep only latest version
959
+ const latestByName = new Map();
960
+ for (const wf of workflows) {
961
+ const w = wf;
962
+ const name = w.name;
963
+ if (!name)
964
+ continue;
965
+ const existing = latestByName.get(name);
966
+ if (!existing || Number(w.version) > Number(existing.version)) {
967
+ latestByName.set(name, w);
968
+ }
969
+ }
970
+ const latest = [...latestByName.values()].map((w) => ({
971
+ name: w.name,
972
+ version: w.version,
973
+ entityType: w.entityType,
974
+ entitySubtype: w.entitySubtype,
975
+ status: w.status,
976
+ createdOn: w.createdOn,
977
+ }));
978
+ // If outputDir is provided, download each workflow's full JSON to individual files
979
+ if (parsed.outputDir && latest.length > 0) {
980
+ fs.mkdirSync(parsed.outputDir, { recursive: true });
981
+ const savedFiles = [];
982
+ const errors = [];
983
+ for (const wf of latest) {
984
+ const entityType = wf.entityType;
985
+ const entitySubtype = wf.entitySubtype;
986
+ if (!entityType || !entitySubtype)
987
+ continue;
988
+ try {
989
+ const fullWf = await client.getWorkflow(retailerId, entityType, entitySubtype);
990
+ if (fullWf && typeof fullWf === "object") {
991
+ const fileContent = JSON.stringify(fullWf, null, 2);
992
+ const fileName = `${entityType}-${entitySubtype}.json`;
993
+ const filePath = path.join(parsed.outputDir, fileName);
994
+ fs.writeFileSync(filePath, fileContent, "utf-8");
995
+ savedFiles.push({
996
+ name: wf.name,
997
+ file: filePath,
998
+ sizeBytes: Buffer.byteLength(fileContent, "utf-8"),
999
+ version: wf.version,
1000
+ });
1001
+ }
1002
+ }
1003
+ catch (err) {
1004
+ errors.push({
1005
+ name: `${entityType}::${entitySubtype}`,
1006
+ error: err instanceof Error ? err.message : String(err),
1007
+ });
1008
+ }
1009
+ }
1010
+ const totalBytes = savedFiles.reduce((s, f) => s + f.sizeBytes, 0);
1011
+ return {
1012
+ ok: true,
1013
+ retailerId,
1014
+ totalVersions: workflows.length,
1015
+ uniqueWorkflows: latest.length,
1016
+ savedTo: parsed.outputDir,
1017
+ filesWritten: savedFiles.length,
1018
+ totalSizeBytes: totalBytes,
1019
+ files: savedFiles,
1020
+ ...(errors.length > 0 ? { errors } : {}),
1021
+ message: `${savedFiles.length} workflow(s) saved to ${parsed.outputDir}/ (${(totalBytes / 1024).toFixed(1)} KB total). ` +
1022
+ `Full JSON NOT included in response.` +
1023
+ (errors.length > 0
1024
+ ? ` ${errors.length} workflow(s) failed to download.`
1025
+ : ""),
1026
+ };
1027
+ }
1028
+ return {
1029
+ ok: true,
1030
+ retailerId,
1031
+ totalVersions: workflows.length,
1032
+ uniqueWorkflows: latest.length,
1033
+ workflows: latest,
1034
+ note: workflows.length === 0
1035
+ ? "No workflows found. The list endpoint may return 401 on some accounts — try workflow.get with a specific entityType and entitySubtype instead."
1036
+ : undefined,
1037
+ };
1038
+ }
@@ -235,8 +235,8 @@ Discovery-first single order lifecycle test. Creates an order with
235
235
  **How to run:**
236
236
 
237
237
  ```bash
238
- npx tsx scripts/e2e-full-order.ts --profile SAGIRISH --retailer 2
239
- FLUENT_PROFILE=SAGIRISH FLUENT_RETAILER_ID=2 npx tsx scripts/e2e-full-order.ts
238
+ npx tsx scripts/e2e-full-order.ts --profile YOUR_PROFILE --retailer 2
239
+ FLUENT_PROFILE=YOUR_PROFILE FLUENT_RETAILER_ID=2 npx tsx scripts/e2e-full-order.ts
240
240
  ```
241
241
 
242
242
  **Environment:** requires `FLUENT_PROFILE` + `FLUENT_RETAILER_ID`, or `--profile`
@@ -269,7 +269,7 @@ MULTI order type workflow and includes workflow transition discovery.
269
269
  npx tsx scripts/e2e-full-multi.ts
270
270
  ```
271
271
 
272
- **Environment:** defaults to `FLUENT_BASE_URL=https://sagirish.test.api.fluentretail.com`
272
+ **Environment:** defaults to `FLUENT_BASE_URL=https://<account>.test.api.fluentretail.com`
273
273
  and `FLUENT_RETAILER_ID=2`. Override with env vars. Requires OAuth or profile
274
274
  credentials.
275
275
 
@@ -296,7 +296,7 @@ Comprehensive smoke test for all 11 agentic tools against a live environment.
296
296
  **How to run:**
297
297
 
298
298
  ```bash
299
- npx tsx scripts/e2e-agentic.ts --profile SAGIRISH
299
+ npx tsx scripts/e2e-agentic.ts --profile YOUR_PROFILE
300
300
  ```
301
301
 
302
302
  **Environment:** requires `FLUENT_PROFILE` or `--profile` flag. Defaults to
@@ -322,7 +322,7 @@ responses.
322
322
  **How to run:**
323
323
 
324
324
  ```bash
325
- npx tsx scripts/e2e-response-shaping.ts --profile SAGIRISH
325
+ npx tsx scripts/e2e-response-shaping.ts --profile YOUR_PROFILE
326
326
  ```
327
327
 
328
328
  **Environment:** requires `FLUENT_PROFILE` or `--profile`. Uses default budget
@@ -347,7 +347,7 @@ per-event drilldowns via `event.get`.
347
347
  **How to run:**
348
348
 
349
349
  ```bash
350
- npx tsx scripts/run-flow-inspect.ts <ROOT_ENTITY_REF> --profile SAGIRISH
350
+ npx tsx scripts/run-flow-inspect.ts <ROOT_ENTITY_REF> --profile YOUR_PROFILE
351
351
  npx tsx scripts/run-flow-inspect.ts HD-001 --root-type ORDER --profile HMDEV
352
352
  npx tsx scripts/run-flow-inspect.ts HD-001 --root-id 12345 --light --no-drilldown
353
353
  npx tsx scripts/run-flow-inspect.ts HD-001 --drilldown-classes webhook,mutation --drilldown-limit 20
@@ -357,7 +357,7 @@ npx tsx scripts/run-flow-inspect.ts HD-001 --drilldown-classes webhook,mutation
357
357
 
358
358
  | Flag | Default | Description |
359
359
  |------|---------|-------------|
360
- | `--profile <name>` | `SAGIRISH` | Fluent CLI profile |
360
+ | `--profile <name>` | - | Fluent CLI profile |
361
361
  | `--root-type <type>` | any | Root entity type (ORDER, FULFILMENT, etc.) |
362
362
  | `--root-id <id>` | - | Root entity ID for disambiguation |
363
363
  | `--out <path>` | `accounts/<profile>/analysis/EVENT_FLOW_INSPECT_<ref>.json` | Raw output path |
@@ -394,7 +394,7 @@ mutations, sendEvent actions, scheduled actions, and ruleset durations.
394
394
  **How to run:**
395
395
 
396
396
  ```bash
397
- npx tsx scripts/order-event-inspect.ts <ORDER_REF> --profile SAGIRISH
397
+ npx tsx scripts/order-event-inspect.ts <ORDER_REF> --profile YOUR_PROFILE
398
398
  npx tsx scripts/order-event-inspect.ts HD-001 --profile HMDEV --out /tmp/inspect.json
399
399
  ```
400
400
 
@@ -411,16 +411,16 @@ and entity ref.
411
411
 
412
412
  ```bash
413
413
  # Fetch specific events by ID
414
- npx tsx scripts/check-event-status.ts --event-id <uuid> --profile SAGIRISH
414
+ npx tsx scripts/check-event-status.ts --event-id <uuid> --profile YOUR_PROFILE
415
415
 
416
416
  # List events by name
417
- npx tsx scripts/check-event-status.ts --event-name ConfirmValidation --profile SAGIRISH
417
+ npx tsx scripts/check-event-status.ts --event-name ConfirmValidation --profile YOUR_PROFILE
418
418
 
419
419
  # List events by entity ref
420
- npx tsx scripts/check-event-status.ts --entity-ref HD-001 --profile SAGIRISH
420
+ npx tsx scripts/check-event-status.ts --entity-ref HD-001 --profile YOUR_PROFILE
421
421
 
422
422
  # Combine filters
423
- npx tsx scripts/check-event-status.ts --event-name ConfirmValidation --entity-ref HD-001 --count 20 --profile SAGIRISH
423
+ npx tsx scripts/check-event-status.ts --event-name ConfirmValidation --entity-ref HD-001 --count 20 --profile YOUR_PROFILE
424
424
  ```
425
425
 
426
426
  **Options:**
package/docs/RUNBOOK.md CHANGED
@@ -92,8 +92,11 @@ Run tools in this order:
92
92
  7. `event.get` using ID returned by send
93
93
  8. `graphql.query` simple read
94
94
  9. `entity.get` — verify entity lookup works (e.g., look up a known order by ref)
95
- 10. `workflow.transitions` (optional) — verify User Action API access for a known trigger
96
- 11. `graphql.queryAll` — verify auto-pagination and run-level timeout
95
+ 10. `setting.get` with `name: "fc.mystique.manifest.%"` — verify settings read access and wildcard support
96
+ 11. `workflow.list` — verify REST workflow API access (list all workflows for a retailer)
97
+ 12. `workflow.get` with `entityType: "ORDER", entitySubtype: "HD"` — verify specific workflow fetch
98
+ 13. `workflow.transitions` (optional) — verify User Action API access for a known trigger
99
+ 14. `graphql.queryAll` — verify auto-pagination and run-level timeout
97
100
  12. `graphql.introspect` with `listMutations: true` — verify schema access
98
101
  13. `environment.discover` with `include: ["retailer", "locations"]` — verify environment snapshot
99
102
  14. `environment.validate` with `checks: ["auth", "retailer", "locations"]` — verify pre-flight checks