@lexq/cli 0.1.34 → 0.1.36

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.
@@ -432,7 +432,7 @@ function registerFactTools(server, callApi) {
432
432
  "lexq_facts_list",
433
433
  {
434
434
  title: "List Fact Definitions",
435
- description: "List all fact definitions (input variable schema). Shows key, type, and required status. Always check this before creating rules.",
435
+ description: "List all fact definitions (input variable schema). Shows key, type, required, and PII status. Always check this before creating rules.",
436
436
  inputSchema: {
437
437
  page: z4.number().int().min(0).default(0).describe("Page number"),
438
438
  size: z4.number().int().min(1).max(100).default(20).describe("Page size"),
@@ -455,7 +455,10 @@ function registerFactTools(server, callApi) {
455
455
  name: z4.string().describe("Display name"),
456
456
  type: z4.enum(["STRING", "NUMBER", "BOOLEAN", "LIST_STRING", "LIST_NUMBER"]).describe("Value type"),
457
457
  description: z4.string().optional().describe("Description"),
458
- isRequired: z4.boolean().default(false).describe("Whether this fact is required for rule evaluation")
458
+ isRequired: z4.boolean().default(false).describe("Whether this fact is required for rule evaluation"),
459
+ isPii: z4.boolean().default(false).describe(
460
+ "Mark as PII \u2014 masked on every read surface, revealable only in the console (audited)"
461
+ )
459
462
  }
460
463
  },
461
464
  async (args) => callApi("POST", "schema/facts", { body: args })
@@ -464,12 +467,13 @@ function registerFactTools(server, callApi) {
464
467
  "lexq_facts_update",
465
468
  {
466
469
  title: "Update Fact Definition",
467
- description: "Update a fact definition. Key and type cannot be changed. Only provided fields are updated. System facts only allow name and description changes.",
470
+ description: "Update a fact definition. Key and type cannot be changed. Only provided fields are updated. System facts only allow name, description, and PII changes.",
468
471
  inputSchema: {
469
472
  factId: z4.string().uuid().describe("Fact definition ID"),
470
473
  name: z4.string().optional().describe("Display name"),
471
474
  description: z4.string().optional().describe("Description"),
472
- isRequired: z4.boolean().optional().describe("Required flag")
475
+ isRequired: z4.boolean().optional().describe("Required flag"),
476
+ isPii: z4.boolean().optional().describe("PII flag \u2014 enables/disables masking (changeable even on system facts)")
473
477
  }
474
478
  },
475
479
  async ({ factId, ...body }) => callApi("PUT", `schema/facts/${factId}`, { body })
@@ -714,21 +718,32 @@ function registerAnalyticsTools(server, callApi) {
714
718
  {
715
719
  title: "Start Simulation",
716
720
  description: dedent2`
717
- Start an Impact Simulation against historical or uploaded data.
721
+ Start an Impact Simulation against historical, uploaded, or inline data.
722
+
723
+ dataset.type and dataset.source are BOTH required, and must be paired:
724
+ HISTORICAL → source EXECUTION_LOGS, with dataset.from / dataset.to (yyyy-MM-dd)
725
+ UPLOADED → source S3_BUCKET, with dataset.path (the path returned by lexq_dataset_upload)
726
+ MANUAL → source REQUEST_BODY, with dataset.manualData (array of fact records)
718
727
 
719
- dataset.type: "HISTORICAL" or "UPLOADED"
720
- dataset.source (when HISTORICAL): "EXECUTION_LOGS"
721
- dataset.from / dataset.to: date range (yyyy-MM-dd, when HISTORICAL)
722
728
  options.maxRecords: number (max 100000, default 10000)
723
- options.baselinePolicyVersionId: uuid (optional, for comparison)
729
+ options.baselinePolicyVersionId: uuid (optional, for baseline comparison)
724
730
  options.includeRuleStats: boolean
731
+ options.metricConfig: optional — omit for plain execution count. To aggregate a fact, pass
732
+ { "targetVariable": "<fact>", "aggregationType": "COUNT" | "SUM" | "AVG" }
725
733
 
726
- Example body:
734
+ Example (uploaded dataset):
727
735
  {
728
736
  "policyVersionId": "<uuid>",
729
- "dataset": { "type": "HISTORICAL", "source": "EXECUTION_LOGS", "from": "2025-01-01", "to": "2025-01-31" },
737
+ "dataset": { "type": "UPLOADED", "source": "S3_BUCKET", "path": "<path from lexq_dataset_upload>" },
730
738
  "options": { "baselinePolicyVersionId": "<uuid>", "includeRuleStats": true, "maxRecords": 10000 }
731
739
  }
740
+
741
+ Example (historical):
742
+ {
743
+ "policyVersionId": "<uuid>",
744
+ "dataset": { "type": "HISTORICAL", "source": "EXECUTION_LOGS", "from": "2026-01-01", "to": "2026-01-31" },
745
+ "options": { "baselinePolicyVersionId": "<uuid>", "includeRuleStats": true }
746
+ }
732
747
  `,
733
748
  inputSchema: {
734
749
  body: z6.string().describe("JSON string of SimulationRequest")
@@ -802,8 +817,10 @@ function registerAnalyticsTools(server, callApi) {
802
817
  title: "Upload Dataset",
803
818
  description: dedent2`
804
819
  Upload inline CSV or JSON content as a simulation dataset.
805
- The content is uploaded to S3 and a path is returned.
806
- Use this path in simulation start with dataset type UPLOADED.
820
+ The content is uploaded to S3 and a path is returned in the "path" field.
821
+
822
+ To use the returned path in lexq_simulation_start, set:
823
+ dataset: { "type": "UPLOADED", "source": "S3_BUCKET", "path": "<returned path>" }
807
824
 
808
825
  CSV example:
809
826
  user_id,payment_amount
@@ -817,9 +834,25 @@ function registerAnalyticsTools(server, callApi) {
817
834
  filename: z6.string().default("dataset.csv").describe("Filename with extension (.csv or .json)")
818
835
  }
819
836
  },
820
- async ({ content, filename }) => callApi("POST", "analytics/datasets/upload", {
821
- upload: { content, filename, fieldName: "file" }
822
- })
837
+ async ({ content, filename }) => {
838
+ const result = await callApi("POST", "analytics/datasets/upload", {
839
+ upload: { content, filename, fieldName: "file" }
840
+ });
841
+ if (!result.isError) {
842
+ try {
843
+ const uploaded = JSON.parse(result.content[0]?.text ?? "{}");
844
+ if (uploaded.path) {
845
+ const dataset = { type: "UPLOADED", source: "S3_BUCKET", path: uploaded.path };
846
+ result.content.push({
847
+ type: "text",
848
+ text: "Ready-to-use dataset block for lexq_simulation_start:\n" + JSON.stringify({ dataset }, null, 2)
849
+ });
850
+ }
851
+ } catch {
852
+ }
853
+ }
854
+ return result;
855
+ }
823
856
  );
824
857
  server.registerTool(
825
858
  "lexq_dataset_template",
@@ -838,8 +871,73 @@ function registerAnalyticsTools(server, callApi) {
838
871
  );
839
872
  }
840
873
 
841
- // src/mcp/tools/history.ts
874
+ // src/mcp/tools/replay.ts
842
875
  import { z as z7 } from "zod";
876
+ function registerReplayTools(server, callApi) {
877
+ server.registerTool(
878
+ "lexq_replay_decision",
879
+ {
880
+ title: "Replay a Decision",
881
+ description: "Re-evaluate a past execution (traceId) against a candidate version and return the decision diff (decisionChanged, effect changes, fired rules) plus a determinism verdict. Synchronous and free of charge (TPS throttle only). External effects (webhooks, notifications) are always mocked \u2014 nothing fires.",
882
+ inputSchema: {
883
+ traceId: z7.string().describe("Trace ID of the past execution to replay"),
884
+ candidateVersionId: z7.string().uuid().describe("Version to re-evaluate against")
885
+ }
886
+ },
887
+ async ({ traceId, candidateVersionId }) => callApi("POST", "replay/decisions", { body: { traceId, candidateVersionId } })
888
+ );
889
+ server.registerTool(
890
+ "lexq_replay_start",
891
+ {
892
+ title: "Start Window Replay (Blast Radius)",
893
+ description: "Submit an async job that replays a date window of past executions against a candidate version and measures the blast radius (how many decisions change). Billed per replayed record (REPLAY metric); VIEWER role cannot submit. Poll with lexq_replay_status.",
894
+ inputSchema: {
895
+ candidateVersionId: z7.string().uuid().describe("Version to re-evaluate against"),
896
+ from: z7.string().describe("Window start date (yyyy-MM-dd)"),
897
+ to: z7.string().describe("Window end date (yyyy-MM-dd)"),
898
+ maxRecords: z7.number().int().min(1).optional().describe("Sample cap (server default applies; hard cap 50k)")
899
+ }
900
+ },
901
+ async ({ candidateVersionId, from, to, maxRecords }) => callApi("POST", "replay/jobs", { body: { candidateVersionId, from, to, maxRecords } })
902
+ );
903
+ server.registerTool(
904
+ "lexq_replay_status",
905
+ {
906
+ title: "Get Replay Job Status",
907
+ description: "Poll a window replay job. RUNNING shows progress 0\u2013100; COMPLETED fills summary and changedSamples; FAILED carries errorMessage. capped=true means the window exceeded the sample cap and only part was replayed.",
908
+ inputSchema: {
909
+ jobId: z7.string().describe("Replay job ID from lexq_replay_start")
910
+ }
911
+ },
912
+ async ({ jobId }) => callApi("GET", `replay/jobs/${jobId}`)
913
+ );
914
+ server.registerTool(
915
+ "lexq_replay_list",
916
+ {
917
+ title: "List Replay Jobs",
918
+ description: "List window replay job history (reverse-chronological). Lightweight items \u2014 use lexq_replay_status for summary and changed samples.",
919
+ inputSchema: {
920
+ page: z7.number().int().min(0).default(0).describe("Page number"),
921
+ size: z7.number().int().min(1).max(100).default(20).describe("Page size")
922
+ }
923
+ },
924
+ async ({ page, size }) => callApi("GET", "replay/jobs", { params: paginationParams(page, size) })
925
+ );
926
+ server.registerTool(
927
+ "lexq_replay_cancel",
928
+ {
929
+ title: "Cancel Replay Job",
930
+ description: "Cooperatively cancel a PENDING or RUNNING window replay job. Other states are rejected. VIEWER role cannot cancel.",
931
+ inputSchema: {
932
+ jobId: z7.string().describe("Replay job ID")
933
+ }
934
+ },
935
+ async ({ jobId }) => callApi("POST", `replay/jobs/${jobId}/cancel`)
936
+ );
937
+ }
938
+
939
+ // src/mcp/tools/history.ts
940
+ import { z as z8 } from "zod";
843
941
  function registerHistoryTools(server, callApi) {
844
942
  server.registerTool(
845
943
  "lexq_history_list",
@@ -847,14 +945,14 @@ function registerHistoryTools(server, callApi) {
847
945
  title: "List Execution History",
848
946
  description: "List policy execution history. Shows trace ID, group, version, status, match result, and latency.",
849
947
  inputSchema: {
850
- page: z7.number().int().min(0).default(0).describe("Page number"),
851
- size: z7.number().int().min(1).max(100).default(20).describe("Page size"),
852
- traceId: z7.string().optional().describe("Filter by trace ID"),
853
- groupId: z7.string().uuid().optional().describe("Filter by policy group"),
854
- versionId: z7.string().uuid().optional().describe("Filter by version"),
855
- status: z7.enum(["SUCCESS", "NO_MATCH", "ERROR", "TIMEOUT"]).optional().describe("Filter by execution status"),
856
- startDate: z7.string().optional().describe("Start date (yyyy-MM-dd)"),
857
- endDate: z7.string().optional().describe("End date (yyyy-MM-dd)")
948
+ page: z8.number().int().min(0).default(0).describe("Page number"),
949
+ size: z8.number().int().min(1).max(100).default(20).describe("Page size"),
950
+ traceId: z8.string().optional().describe("Filter by trace ID"),
951
+ groupId: z8.string().uuid().optional().describe("Filter by policy group"),
952
+ versionId: z8.string().uuid().optional().describe("Filter by version"),
953
+ status: z8.enum(["SUCCESS", "NO_MATCH", "ERROR", "TIMEOUT"]).optional().describe("Filter by execution status"),
954
+ startDate: z8.string().optional().describe("Start date (yyyy-MM-dd)"),
955
+ endDate: z8.string().optional().describe("End date (yyyy-MM-dd)")
858
956
  }
859
957
  },
860
958
  async ({ page, size, traceId, groupId, versionId, status, startDate, endDate }) => {
@@ -874,7 +972,7 @@ function registerHistoryTools(server, callApi) {
874
972
  title: "Get Execution Detail",
875
973
  description: "Get full execution detail including inputFacts, mutatedFacts, generatedVariables, executionTraces, and decisionTraces.",
876
974
  inputSchema: {
877
- traceId: z7.string().describe("Trace ID from execution history")
975
+ traceId: z8.string().describe("Trace ID from execution history")
878
976
  }
879
977
  },
880
978
  async ({ traceId }) => callApi("GET", `execution/history/${traceId}`)
@@ -885,9 +983,9 @@ function registerHistoryTools(server, callApi) {
885
983
  title: "Execution Statistics",
886
984
  description: "Get execution KPIs: total executions, success/failure counts, success rate, and average latency.",
887
985
  inputSchema: {
888
- groupId: z7.string().uuid().optional().describe("Filter by policy group"),
889
- startDate: z7.string().optional().describe("Start date (yyyy-MM-dd)"),
890
- endDate: z7.string().optional().describe("End date (yyyy-MM-dd)")
986
+ groupId: z8.string().uuid().optional().describe("Filter by policy group"),
987
+ startDate: z8.string().optional().describe("Start date (yyyy-MM-dd)"),
988
+ endDate: z8.string().optional().describe("End date (yyyy-MM-dd)")
891
989
  }
892
990
  },
893
991
  async ({ groupId, startDate, endDate }) => {
@@ -900,8 +998,49 @@ function registerHistoryTools(server, callApi) {
900
998
  );
901
999
  }
902
1000
 
1001
+ // src/mcp/tools/provenance.ts
1002
+ import { z as z9 } from "zod";
1003
+ function registerProvenanceTools(server, callApi) {
1004
+ server.registerTool(
1005
+ "lexq_provenance_get",
1006
+ {
1007
+ title: "Get Decision Provenance",
1008
+ description: "Get the lineage of a single decision: what was decided, deterministic why per rule, input facts (PII facts are masked as \u2022\u2022\u2022\u2022\u2022\u2022 with maskedKeys listing them \u2014 values are revealable only in the console, audited), the authored/published/deployed responsibility chain, and the rule snapshot fingerprint.",
1009
+ inputSchema: {
1010
+ traceId: z9.string().describe("Trace ID of the execution")
1011
+ }
1012
+ },
1013
+ async ({ traceId }) => callApi("GET", `provenance/${traceId}`)
1014
+ );
1015
+ server.registerTool(
1016
+ "lexq_pii_reveals_list",
1017
+ {
1018
+ title: "List PII Reveal Audits",
1019
+ description: "List the PII reveal audit ledger \u2014 who revealed which fact of which trace, and when. Metadata only; revealed values are never stored or returned. Use for monthly access-log inspection and SIEM collection.",
1020
+ inputSchema: {
1021
+ page: z9.number().int().min(0).default(0).describe("Page number"),
1022
+ size: z9.number().int().min(1).max(100).default(20).describe("Page size"),
1023
+ traceId: z9.string().optional().describe("Filter by trace ID (exact match)"),
1024
+ revealedBy: z9.string().optional().describe("Filter by operator ID (exact match)"),
1025
+ factKey: z9.string().optional().describe("Filter by fact key (partial match, case-insensitive)"),
1026
+ startDate: z9.string().optional().describe("Start date (yyyy-MM-dd)"),
1027
+ endDate: z9.string().optional().describe("End date (yyyy-MM-dd)")
1028
+ }
1029
+ },
1030
+ async ({ page, size, traceId, revealedBy, factKey, startDate, endDate }) => {
1031
+ const params = paginationParams(page, size);
1032
+ if (traceId) params.traceId = traceId;
1033
+ if (revealedBy) params.revealedBy = revealedBy;
1034
+ if (factKey) params.factKey = factKey;
1035
+ if (startDate) params.startDate = startDate;
1036
+ if (endDate) params.endDate = endDate;
1037
+ return callApi("GET", "provenance/reveal-audits", { params });
1038
+ }
1039
+ );
1040
+ }
1041
+
903
1042
  // src/mcp/tools/integrations.ts
904
- import { z as z8 } from "zod";
1043
+ import { z as z10 } from "zod";
905
1044
  function registerIntegrationTools(server, callApi) {
906
1045
  server.registerTool(
907
1046
  "lexq_integrations_list",
@@ -909,9 +1048,9 @@ function registerIntegrationTools(server, callApi) {
909
1048
  title: "List Integrations",
910
1049
  description: "List all external integrations (webhooks, CRM, notification, etc.).",
911
1050
  inputSchema: {
912
- page: z8.number().int().min(0).default(0).describe("Page number"),
913
- size: z8.number().int().min(1).max(100).default(20).describe("Page size"),
914
- type: z8.enum(["COUPON", "POINT", "NOTIFICATION", "CRM", "MESSENGER", "WEBHOOK"]).optional().describe("Filter by integration type")
1051
+ page: z10.number().int().min(0).default(0).describe("Page number"),
1052
+ size: z10.number().int().min(1).max(100).default(20).describe("Page size"),
1053
+ type: z10.enum(["COUPON", "POINT", "NOTIFICATION", "CRM", "MESSENGER", "WEBHOOK"]).optional().describe("Filter by integration type")
915
1054
  }
916
1055
  },
917
1056
  async ({ page, size, type }) => {
@@ -926,7 +1065,7 @@ function registerIntegrationTools(server, callApi) {
926
1065
  title: "Get Integration",
927
1066
  description: "Get integration detail by ID.",
928
1067
  inputSchema: {
929
- integrationId: z8.string().uuid().describe("Integration ID")
1068
+ integrationId: z10.string().uuid().describe("Integration ID")
930
1069
  }
931
1070
  },
932
1071
  async ({ integrationId }) => callApi("GET", `integrations/${integrationId}`)
@@ -937,13 +1076,13 @@ function registerIntegrationTools(server, callApi) {
937
1076
  title: "Save Integration",
938
1077
  description: "Create or update an integration. Provide id to update an existing one; omit id to create new. Types: COUPON, POINT, NOTIFICATION, CRM, MESSENGER, WEBHOOK.",
939
1078
  inputSchema: {
940
- id: z8.string().uuid().optional().describe("Integration ID (omit to create, provide to update)"),
941
- type: z8.enum(["COUPON", "POINT", "NOTIFICATION", "CRM", "MESSENGER", "WEBHOOK"]).describe("Integration type"),
942
- name: z8.string().describe("Integration name"),
943
- baseUrl: z8.string().describe("Base URL of the external service"),
944
- credential: z8.string().optional().describe("API key or token for the service"),
945
- additionalConfig: z8.string().optional().describe("JSON string of additional config key-value pairs"),
946
- isActive: z8.boolean().default(true).describe("Whether the integration is active")
1079
+ id: z10.string().uuid().optional().describe("Integration ID (omit to create, provide to update)"),
1080
+ type: z10.enum(["COUPON", "POINT", "NOTIFICATION", "CRM", "MESSENGER", "WEBHOOK"]).describe("Integration type"),
1081
+ name: z10.string().describe("Integration name"),
1082
+ baseUrl: z10.string().describe("Base URL of the external service"),
1083
+ credential: z10.string().optional().describe("API key or token for the service"),
1084
+ additionalConfig: z10.string().optional().describe("JSON string of additional config key-value pairs"),
1085
+ isActive: z10.boolean().default(true).describe("Whether the integration is active")
947
1086
  }
948
1087
  },
949
1088
  async ({ additionalConfig, ...rest }) => {
@@ -958,7 +1097,7 @@ function registerIntegrationTools(server, callApi) {
958
1097
  title: "Delete Integration",
959
1098
  description: "Delete an integration by ID.",
960
1099
  inputSchema: {
961
- integrationId: z8.string().uuid().describe("Integration ID")
1100
+ integrationId: z10.string().uuid().describe("Integration ID")
962
1101
  }
963
1102
  },
964
1103
  async ({ integrationId }) => callApi("DELETE", `integrations/${integrationId}`)
@@ -975,7 +1114,7 @@ function registerIntegrationTools(server, callApi) {
975
1114
  }
976
1115
 
977
1116
  // src/mcp/tools/logs.ts
978
- import { z as z9 } from "zod";
1117
+ import { z as z11 } from "zod";
979
1118
 
980
1119
  // src/types/enums.ts
981
1120
  var FailureStatus = ["PENDING", "RESOLVED", "IGNORED"];
@@ -1013,14 +1152,14 @@ function registerLogTools(server, callApi) {
1013
1152
  title: "List Failure Logs",
1014
1153
  description: "List system failure logs from background tasks (webhook calls, coupon issuance, etc.).",
1015
1154
  inputSchema: {
1016
- page: z9.number().int().min(0).default(0).describe("Page number"),
1017
- size: z9.number().int().min(1).max(100).default(20).describe("Page size"),
1018
- category: z9.enum(TaskCategory).optional().describe("Task category"),
1019
- taskType: z9.enum(TaskType).optional().describe("Task type"),
1020
- status: z9.enum(FailureStatus).optional().describe("Log status"),
1021
- keyword: z9.string().optional().describe("Search in refId, refSubId, errorMessage"),
1022
- startDate: z9.string().optional().describe("Start date (yyyy-MM-dd)"),
1023
- endDate: z9.string().optional().describe("End date (yyyy-MM-dd)")
1155
+ page: z11.number().int().min(0).default(0).describe("Page number"),
1156
+ size: z11.number().int().min(1).max(100).default(20).describe("Page size"),
1157
+ category: z11.enum(TaskCategory).optional().describe("Task category"),
1158
+ taskType: z11.enum(TaskType).optional().describe("Task type"),
1159
+ status: z11.enum(FailureStatus).optional().describe("Log status"),
1160
+ keyword: z11.string().optional().describe("Search in refId, refSubId, errorMessage"),
1161
+ startDate: z11.string().optional().describe("Start date (yyyy-MM-dd)"),
1162
+ endDate: z11.string().optional().describe("End date (yyyy-MM-dd)")
1024
1163
  }
1025
1164
  },
1026
1165
  async ({ page, size, category, taskType, status, keyword, startDate, endDate }) => {
@@ -1040,7 +1179,7 @@ function registerLogTools(server, callApi) {
1040
1179
  title: "Get Failure Log",
1041
1180
  description: "Get failure log detail by ID.",
1042
1181
  inputSchema: {
1043
- logId: z9.string().uuid().describe("Failure log ID")
1182
+ logId: z11.string().uuid().describe("Failure log ID")
1044
1183
  }
1045
1184
  },
1046
1185
  async ({ logId }) => callApi("GET", `failure-logs/${logId}`)
@@ -1051,8 +1190,8 @@ function registerLogTools(server, callApi) {
1051
1190
  title: "Process Failure Log",
1052
1191
  description: "Process a single failure log: RETRY (re-execute with original payload), RESOLVE (mark as manually fixed), or IGNORE (skip intentionally).",
1053
1192
  inputSchema: {
1054
- logId: z9.string().uuid().describe("Failure log ID"),
1055
- action: z9.enum(FailureAction).describe("Action to take")
1193
+ logId: z11.string().uuid().describe("Failure log ID"),
1194
+ action: z11.enum(FailureAction).describe("Action to take")
1056
1195
  }
1057
1196
  },
1058
1197
  async ({ logId, action }) => callApi("POST", `failure-logs/${logId}/actions`, {
@@ -1065,8 +1204,8 @@ function registerLogTools(server, callApi) {
1065
1204
  title: "Bulk Process Failure Logs",
1066
1205
  description: "Process multiple failure logs at once. Provide an array of log IDs and the action.",
1067
1206
  inputSchema: {
1068
- logIds: z9.array(z9.string().uuid()).describe("Array of failure log IDs"),
1069
- action: z9.enum(FailureAction).describe("Action to apply to all logs")
1207
+ logIds: z11.array(z11.string().uuid()).describe("Array of failure log IDs"),
1208
+ action: z11.enum(FailureAction).describe("Action to apply to all logs")
1070
1209
  }
1071
1210
  },
1072
1211
  async ({ logIds, action }) => callApi("POST", "failure-logs/bulk-actions", {
@@ -1076,7 +1215,7 @@ function registerLogTools(server, callApi) {
1076
1215
  }
1077
1216
 
1078
1217
  // src/mcp/tools/webhook-subscriptions.ts
1079
- import { z as z10 } from "zod";
1218
+ import { z as z12 } from "zod";
1080
1219
  function registerWebhookSubscriptionTools(server, callApi) {
1081
1220
  server.registerTool(
1082
1221
  "lexq_webhook_subscriptions_list",
@@ -1084,8 +1223,8 @@ function registerWebhookSubscriptionTools(server, callApi) {
1084
1223
  title: "List Webhook Subscriptions",
1085
1224
  description: "List platform event webhook subscriptions. These receive deployment lifecycle notifications (publish, deploy, rollback, undeploy).",
1086
1225
  inputSchema: {
1087
- page: z10.number().int().min(0).default(0).describe("Page number"),
1088
- size: z10.number().int().min(1).max(100).default(20).describe("Page size")
1226
+ page: z12.number().int().min(0).default(0).describe("Page number"),
1227
+ size: z12.number().int().min(1).max(100).default(20).describe("Page size")
1089
1228
  }
1090
1229
  },
1091
1230
  async ({ page, size }) => {
@@ -1099,7 +1238,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
1099
1238
  title: "Get Webhook Subscription",
1100
1239
  description: "Get webhook subscription detail by ID.",
1101
1240
  inputSchema: {
1102
- id: z10.string().uuid().describe("Webhook subscription ID")
1241
+ id: z12.string().uuid().describe("Webhook subscription ID")
1103
1242
  }
1104
1243
  },
1105
1244
  async ({ id }) => callApi("GET", `webhook-subscriptions/${id}`)
@@ -1110,13 +1249,13 @@ function registerWebhookSubscriptionTools(server, callApi) {
1110
1249
  title: "Save Webhook Subscription",
1111
1250
  description: 'Create or update a webhook subscription. Omit id to create, provide id to update. Events: VERSION_PUBLISHED, DEPLOYED, ROLLED_BACK, UNDEPLOYED. Formats: GENERIC (full JSON), SLACK ({"text": "..."}).',
1112
1251
  inputSchema: {
1113
- id: z10.string().uuid().optional().describe("Subscription ID (omit to create, provide to update)"),
1114
- name: z10.string().min(1).describe("Subscription name (unique per tenant)"),
1115
- webhookUrl: z10.string().url().describe("Webhook endpoint URL"),
1116
- subscribedEvents: z10.array(z10.enum(PlatformEventType)).min(1).describe("Events to subscribe to"),
1117
- payloadFormat: z10.enum(WebhookPayloadFormat).optional().default("GENERIC").describe("Payload format"),
1118
- secret: z10.string().optional().describe("HMAC-SHA256 signing secret"),
1119
- isActive: z10.boolean().optional().default(true).describe("Whether the subscription is active")
1252
+ id: z12.string().uuid().optional().describe("Subscription ID (omit to create, provide to update)"),
1253
+ name: z12.string().min(1).describe("Subscription name (unique per tenant)"),
1254
+ webhookUrl: z12.string().url().describe("Webhook endpoint URL"),
1255
+ subscribedEvents: z12.array(z12.enum(PlatformEventType)).min(1).describe("Events to subscribe to"),
1256
+ payloadFormat: z12.enum(WebhookPayloadFormat).optional().default("GENERIC").describe("Payload format"),
1257
+ secret: z12.string().optional().describe("HMAC-SHA256 signing secret"),
1258
+ isActive: z12.boolean().optional().default(true).describe("Whether the subscription is active")
1120
1259
  }
1121
1260
  },
1122
1261
  async ({ ...body }) => callApi("POST", "webhook-subscriptions", { body })
@@ -1127,7 +1266,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
1127
1266
  title: "Delete Webhook Subscription",
1128
1267
  description: "Delete a webhook subscription by ID.",
1129
1268
  inputSchema: {
1130
- id: z10.string().uuid().describe("Webhook subscription ID")
1269
+ id: z12.string().uuid().describe("Webhook subscription ID")
1131
1270
  }
1132
1271
  },
1133
1272
  async ({ id }) => callApi("DELETE", `webhook-subscriptions/${id}`)
@@ -1138,7 +1277,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
1138
1277
  title: "Test Webhook Subscription",
1139
1278
  description: "Send a test event to verify webhook connectivity. Returns the HTTP status code and success/failure message.",
1140
1279
  inputSchema: {
1141
- id: z10.string().uuid().describe("Webhook subscription ID")
1280
+ id: z12.string().uuid().describe("Webhook subscription ID")
1142
1281
  }
1143
1282
  },
1144
1283
  async ({ id }) => callApi("POST", `webhook-subscriptions/${id}/test`)
@@ -1146,7 +1285,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
1146
1285
  }
1147
1286
 
1148
1287
  // src/mcp/tools/domain-templates.ts
1149
- import { z as z11 } from "zod";
1288
+ import { z as z13 } from "zod";
1150
1289
  function registerDomainTemplateTools(server, callApi) {
1151
1290
  server.registerTool(
1152
1291
  "lexq_domain_templates_list",
@@ -1163,7 +1302,7 @@ function registerDomainTemplateTools(server, callApi) {
1163
1302
  title: "Preview Domain Template",
1164
1303
  description: "Preview exactly what a domain template will provision before applying it: the fact definitions it registers, the sample rules it creates, and an apply plan. This is a read-only dry run \u2014 nothing is created. Only ACTIVE templates can be previewed.",
1165
1304
  inputSchema: {
1166
- template: z11.string().describe(
1305
+ template: z13.string().describe(
1167
1306
  "Domain template key (e.g. ECOMMERCE). Use lexq_domain_templates_list to see available keys \u2014 currently only ECOMMERCE is ACTIVE."
1168
1307
  )
1169
1308
  }
@@ -1176,8 +1315,8 @@ function registerDomainTemplateTools(server, callApi) {
1176
1315
  title: "Apply Domain Template",
1177
1316
  description: "Apply a domain template to the current tenant. Creates the template's fact definitions and a new policy group pre-populated with its sample rules as a DRAFT version. Existing facts are skipped \u2014 apply is additive and never overwrites existing schema. Run lexq_domain_templates_preview first to review what will be created. Only ACTIVE templates can be applied.",
1178
1317
  inputSchema: {
1179
- template: z11.string().describe("Domain template key to apply (e.g. ECOMMERCE)."),
1180
- customName: z11.string().optional().describe(
1318
+ template: z13.string().describe("Domain template key to apply (e.g. ECOMMERCE)."),
1319
+ customName: z13.string().optional().describe(
1181
1320
  "Optional custom name for the policy group that gets created. If omitted, the template's default name is used."
1182
1321
  )
1183
1322
  }
@@ -1199,7 +1338,9 @@ function registerAllTools(server, callApi) {
1199
1338
  registerFactTools(server, callApi);
1200
1339
  registerDeployTools(server, callApi);
1201
1340
  registerAnalyticsTools(server, callApi);
1341
+ registerReplayTools(server, callApi);
1202
1342
  registerHistoryTools(server, callApi);
1343
+ registerProvenanceTools(server, callApi);
1203
1344
  registerIntegrationTools(server, callApi);
1204
1345
  registerLogTools(server, callApi);
1205
1346
  registerDomainTemplateTools(server, callApi);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lexq/cli",
3
- "version": "0.1.34",
3
+ "version": "0.1.36",
4
4
  "description": "LexQ CLI — manage policies, simulate rules, and deploy from the terminal. Built for humans and AI agents.",
5
5
  "type": "module",
6
6
  "bin": {