@lexq/cli 0.1.35 → 0.1.37

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 })
@@ -867,8 +871,56 @@ function registerAnalyticsTools(server, callApi) {
867
871
  );
868
872
  }
869
873
 
870
- // src/mcp/tools/replay.ts
874
+ // src/mcp/tools/profile.ts
871
875
  import { z as z7 } from "zod";
876
+ var RELATIVE_THRESHOLD = "flagged = p50 \u2265 10\xD7 median of per-rule p50s within the group; absolute thresholds are intentionally not supported.";
877
+ function profileParams(opts) {
878
+ const params = {};
879
+ if (opts.versionId) params.versionId = opts.versionId;
880
+ if (opts.from) params.from = opts.from;
881
+ if (opts.to) params.to = opts.to;
882
+ if (opts.cacheState) params.cacheState = opts.cacheState;
883
+ return params;
884
+ }
885
+ function registerProfileTools(server, callApi) {
886
+ server.registerTool(
887
+ "lexq_profile_overview",
888
+ {
889
+ title: "Group Latency Profile",
890
+ description: "Per-rule latency profile of a policy group over a time window: group TOTAL distribution split by cache state (HIT = compiled ruleset cache hit, MISS = deep-load + compile), a per-rule CONDITION/ACTION percentile table, and slow-rule flags. " + RELATIVE_THRESHOLD + " Every percentile is accompanied by its sample count n; percentiles are withheld (null) when n < 100, and baselines report INSUFFICIENT_COHORT when fewer than 3 rules qualify. Rule detail comes from a deterministic 1% sample of calls; TOTAL is recorded for every call. Defaults: last 24h, live version, cacheState HIT.",
891
+ inputSchema: {
892
+ groupId: z7.string().uuid().describe("Policy group ID"),
893
+ versionId: z7.string().uuid().optional().describe("Version to inspect (default: live version)"),
894
+ from: z7.string().optional().describe("Window start, ISO-8601 instant (e.g. 2026-07-01T00:00:00Z). Default: 24h ago"),
895
+ to: z7.string().optional().describe("Window end, ISO-8601 instant. Default: now"),
896
+ cacheState: z7.enum(["HIT", "MISS"]).optional().describe("Cache dimension for the rule table and judgment (default: HIT)")
897
+ }
898
+ },
899
+ async ({ groupId, versionId, from, to, cacheState }) => callApi("GET", `policy-groups/${groupId}/profile`, {
900
+ params: profileParams({ versionId, from, to, cacheState })
901
+ })
902
+ );
903
+ server.registerTool(
904
+ "lexq_profile_rule",
905
+ {
906
+ title: "Rule Latency Detail",
907
+ description: "Single-rule latency detail: merged phase \xD7 cacheState distributions plus a per-window time series (60s windows). Missing windows are genuine gaps \u2014 never interpolated. Series points carry each window's own values; percentiles in merged distributions are withheld (null) when n < 100. " + RELATIVE_THRESHOLD,
908
+ inputSchema: {
909
+ groupId: z7.string().uuid().describe("Policy group ID"),
910
+ ruleId: z7.string().uuid().describe("Rule ID (from lexq_profile_overview)"),
911
+ versionId: z7.string().uuid().optional().describe("Version to inspect (default: live version)"),
912
+ from: z7.string().optional().describe("Window start, ISO-8601 instant. Default: 24h ago"),
913
+ to: z7.string().optional().describe("Window end, ISO-8601 instant. Default: now")
914
+ }
915
+ },
916
+ async ({ groupId, ruleId, versionId, from, to }) => callApi("GET", `policy-groups/${groupId}/profile/rules/${ruleId}`, {
917
+ params: profileParams({ versionId, from, to })
918
+ })
919
+ );
920
+ }
921
+
922
+ // src/mcp/tools/replay.ts
923
+ import { z as z8 } from "zod";
872
924
  function registerReplayTools(server, callApi) {
873
925
  server.registerTool(
874
926
  "lexq_replay_decision",
@@ -876,8 +928,8 @@ function registerReplayTools(server, callApi) {
876
928
  title: "Replay a Decision",
877
929
  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.",
878
930
  inputSchema: {
879
- traceId: z7.string().describe("Trace ID of the past execution to replay"),
880
- candidateVersionId: z7.string().uuid().describe("Version to re-evaluate against")
931
+ traceId: z8.string().describe("Trace ID of the past execution to replay"),
932
+ candidateVersionId: z8.string().uuid().describe("Version to re-evaluate against")
881
933
  }
882
934
  },
883
935
  async ({ traceId, candidateVersionId }) => callApi("POST", "replay/decisions", { body: { traceId, candidateVersionId } })
@@ -888,10 +940,10 @@ function registerReplayTools(server, callApi) {
888
940
  title: "Start Window Replay (Blast Radius)",
889
941
  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.",
890
942
  inputSchema: {
891
- candidateVersionId: z7.string().uuid().describe("Version to re-evaluate against"),
892
- from: z7.string().describe("Window start date (yyyy-MM-dd)"),
893
- to: z7.string().describe("Window end date (yyyy-MM-dd)"),
894
- maxRecords: z7.number().int().min(1).optional().describe("Sample cap (server default applies; hard cap 50k)")
943
+ candidateVersionId: z8.string().uuid().describe("Version to re-evaluate against"),
944
+ from: z8.string().describe("Window start date (yyyy-MM-dd)"),
945
+ to: z8.string().describe("Window end date (yyyy-MM-dd)"),
946
+ maxRecords: z8.number().int().min(1).optional().describe("Sample cap (server default applies; hard cap 50k)")
895
947
  }
896
948
  },
897
949
  async ({ candidateVersionId, from, to, maxRecords }) => callApi("POST", "replay/jobs", { body: { candidateVersionId, from, to, maxRecords } })
@@ -902,7 +954,7 @@ function registerReplayTools(server, callApi) {
902
954
  title: "Get Replay Job Status",
903
955
  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.",
904
956
  inputSchema: {
905
- jobId: z7.string().describe("Replay job ID from lexq_replay_start")
957
+ jobId: z8.string().describe("Replay job ID from lexq_replay_start")
906
958
  }
907
959
  },
908
960
  async ({ jobId }) => callApi("GET", `replay/jobs/${jobId}`)
@@ -913,8 +965,8 @@ function registerReplayTools(server, callApi) {
913
965
  title: "List Replay Jobs",
914
966
  description: "List window replay job history (reverse-chronological). Lightweight items \u2014 use lexq_replay_status for summary and changed samples.",
915
967
  inputSchema: {
916
- page: z7.number().int().min(0).default(0).describe("Page number"),
917
- size: z7.number().int().min(1).max(100).default(20).describe("Page size")
968
+ page: z8.number().int().min(0).default(0).describe("Page number"),
969
+ size: z8.number().int().min(1).max(100).default(20).describe("Page size")
918
970
  }
919
971
  },
920
972
  async ({ page, size }) => callApi("GET", "replay/jobs", { params: paginationParams(page, size) })
@@ -925,7 +977,7 @@ function registerReplayTools(server, callApi) {
925
977
  title: "Cancel Replay Job",
926
978
  description: "Cooperatively cancel a PENDING or RUNNING window replay job. Other states are rejected. VIEWER role cannot cancel.",
927
979
  inputSchema: {
928
- jobId: z7.string().describe("Replay job ID")
980
+ jobId: z8.string().describe("Replay job ID")
929
981
  }
930
982
  },
931
983
  async ({ jobId }) => callApi("POST", `replay/jobs/${jobId}/cancel`)
@@ -933,7 +985,7 @@ function registerReplayTools(server, callApi) {
933
985
  }
934
986
 
935
987
  // src/mcp/tools/history.ts
936
- import { z as z8 } from "zod";
988
+ import { z as z9 } from "zod";
937
989
  function registerHistoryTools(server, callApi) {
938
990
  server.registerTool(
939
991
  "lexq_history_list",
@@ -941,14 +993,14 @@ function registerHistoryTools(server, callApi) {
941
993
  title: "List Execution History",
942
994
  description: "List policy execution history. Shows trace ID, group, version, status, match result, and latency.",
943
995
  inputSchema: {
944
- page: z8.number().int().min(0).default(0).describe("Page number"),
945
- size: z8.number().int().min(1).max(100).default(20).describe("Page size"),
946
- traceId: z8.string().optional().describe("Filter by trace ID"),
947
- groupId: z8.string().uuid().optional().describe("Filter by policy group"),
948
- versionId: z8.string().uuid().optional().describe("Filter by version"),
949
- status: z8.enum(["SUCCESS", "NO_MATCH", "ERROR", "TIMEOUT"]).optional().describe("Filter by execution status"),
950
- startDate: z8.string().optional().describe("Start date (yyyy-MM-dd)"),
951
- endDate: z8.string().optional().describe("End date (yyyy-MM-dd)")
996
+ page: z9.number().int().min(0).default(0).describe("Page number"),
997
+ size: z9.number().int().min(1).max(100).default(20).describe("Page size"),
998
+ traceId: z9.string().optional().describe("Filter by trace ID"),
999
+ groupId: z9.string().uuid().optional().describe("Filter by policy group"),
1000
+ versionId: z9.string().uuid().optional().describe("Filter by version"),
1001
+ status: z9.enum(["SUCCESS", "NO_MATCH", "ERROR", "TIMEOUT"]).optional().describe("Filter by execution status"),
1002
+ startDate: z9.string().optional().describe("Start date (yyyy-MM-dd)"),
1003
+ endDate: z9.string().optional().describe("End date (yyyy-MM-dd)")
952
1004
  }
953
1005
  },
954
1006
  async ({ page, size, traceId, groupId, versionId, status, startDate, endDate }) => {
@@ -968,7 +1020,7 @@ function registerHistoryTools(server, callApi) {
968
1020
  title: "Get Execution Detail",
969
1021
  description: "Get full execution detail including inputFacts, mutatedFacts, generatedVariables, executionTraces, and decisionTraces.",
970
1022
  inputSchema: {
971
- traceId: z8.string().describe("Trace ID from execution history")
1023
+ traceId: z9.string().describe("Trace ID from execution history")
972
1024
  }
973
1025
  },
974
1026
  async ({ traceId }) => callApi("GET", `execution/history/${traceId}`)
@@ -979,9 +1031,9 @@ function registerHistoryTools(server, callApi) {
979
1031
  title: "Execution Statistics",
980
1032
  description: "Get execution KPIs: total executions, success/failure counts, success rate, and average latency.",
981
1033
  inputSchema: {
982
- groupId: z8.string().uuid().optional().describe("Filter by policy group"),
983
- startDate: z8.string().optional().describe("Start date (yyyy-MM-dd)"),
984
- endDate: z8.string().optional().describe("End date (yyyy-MM-dd)")
1034
+ groupId: z9.string().uuid().optional().describe("Filter by policy group"),
1035
+ startDate: z9.string().optional().describe("Start date (yyyy-MM-dd)"),
1036
+ endDate: z9.string().optional().describe("End date (yyyy-MM-dd)")
985
1037
  }
986
1038
  },
987
1039
  async ({ groupId, startDate, endDate }) => {
@@ -995,7 +1047,7 @@ function registerHistoryTools(server, callApi) {
995
1047
  }
996
1048
 
997
1049
  // src/mcp/tools/provenance.ts
998
- import { z as z9 } from "zod";
1050
+ import { z as z10 } from "zod";
999
1051
  function registerProvenanceTools(server, callApi) {
1000
1052
  server.registerTool(
1001
1053
  "lexq_provenance_get",
@@ -1003,7 +1055,7 @@ function registerProvenanceTools(server, callApi) {
1003
1055
  title: "Get Decision Provenance",
1004
1056
  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.",
1005
1057
  inputSchema: {
1006
- traceId: z9.string().describe("Trace ID of the execution")
1058
+ traceId: z10.string().describe("Trace ID of the execution")
1007
1059
  }
1008
1060
  },
1009
1061
  async ({ traceId }) => callApi("GET", `provenance/${traceId}`)
@@ -1014,13 +1066,13 @@ function registerProvenanceTools(server, callApi) {
1014
1066
  title: "List PII Reveal Audits",
1015
1067
  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.",
1016
1068
  inputSchema: {
1017
- page: z9.number().int().min(0).default(0).describe("Page number"),
1018
- size: z9.number().int().min(1).max(100).default(20).describe("Page size"),
1019
- traceId: z9.string().optional().describe("Filter by trace ID (exact match)"),
1020
- revealedBy: z9.string().optional().describe("Filter by operator ID (exact match)"),
1021
- factKey: z9.string().optional().describe("Filter by fact key (partial match, case-insensitive)"),
1022
- startDate: z9.string().optional().describe("Start date (yyyy-MM-dd)"),
1023
- endDate: z9.string().optional().describe("End date (yyyy-MM-dd)")
1069
+ page: z10.number().int().min(0).default(0).describe("Page number"),
1070
+ size: z10.number().int().min(1).max(100).default(20).describe("Page size"),
1071
+ traceId: z10.string().optional().describe("Filter by trace ID (exact match)"),
1072
+ revealedBy: z10.string().optional().describe("Filter by operator ID (exact match)"),
1073
+ factKey: z10.string().optional().describe("Filter by fact key (partial match, case-insensitive)"),
1074
+ startDate: z10.string().optional().describe("Start date (yyyy-MM-dd)"),
1075
+ endDate: z10.string().optional().describe("End date (yyyy-MM-dd)")
1024
1076
  }
1025
1077
  },
1026
1078
  async ({ page, size, traceId, revealedBy, factKey, startDate, endDate }) => {
@@ -1036,7 +1088,7 @@ function registerProvenanceTools(server, callApi) {
1036
1088
  }
1037
1089
 
1038
1090
  // src/mcp/tools/integrations.ts
1039
- import { z as z10 } from "zod";
1091
+ import { z as z11 } from "zod";
1040
1092
  function registerIntegrationTools(server, callApi) {
1041
1093
  server.registerTool(
1042
1094
  "lexq_integrations_list",
@@ -1044,9 +1096,9 @@ function registerIntegrationTools(server, callApi) {
1044
1096
  title: "List Integrations",
1045
1097
  description: "List all external integrations (webhooks, CRM, notification, etc.).",
1046
1098
  inputSchema: {
1047
- page: z10.number().int().min(0).default(0).describe("Page number"),
1048
- size: z10.number().int().min(1).max(100).default(20).describe("Page size"),
1049
- type: z10.enum(["COUPON", "POINT", "NOTIFICATION", "CRM", "MESSENGER", "WEBHOOK"]).optional().describe("Filter by integration type")
1099
+ page: z11.number().int().min(0).default(0).describe("Page number"),
1100
+ size: z11.number().int().min(1).max(100).default(20).describe("Page size"),
1101
+ type: z11.enum(["COUPON", "POINT", "NOTIFICATION", "CRM", "MESSENGER", "WEBHOOK"]).optional().describe("Filter by integration type")
1050
1102
  }
1051
1103
  },
1052
1104
  async ({ page, size, type }) => {
@@ -1061,7 +1113,7 @@ function registerIntegrationTools(server, callApi) {
1061
1113
  title: "Get Integration",
1062
1114
  description: "Get integration detail by ID.",
1063
1115
  inputSchema: {
1064
- integrationId: z10.string().uuid().describe("Integration ID")
1116
+ integrationId: z11.string().uuid().describe("Integration ID")
1065
1117
  }
1066
1118
  },
1067
1119
  async ({ integrationId }) => callApi("GET", `integrations/${integrationId}`)
@@ -1072,13 +1124,13 @@ function registerIntegrationTools(server, callApi) {
1072
1124
  title: "Save Integration",
1073
1125
  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.",
1074
1126
  inputSchema: {
1075
- id: z10.string().uuid().optional().describe("Integration ID (omit to create, provide to update)"),
1076
- type: z10.enum(["COUPON", "POINT", "NOTIFICATION", "CRM", "MESSENGER", "WEBHOOK"]).describe("Integration type"),
1077
- name: z10.string().describe("Integration name"),
1078
- baseUrl: z10.string().describe("Base URL of the external service"),
1079
- credential: z10.string().optional().describe("API key or token for the service"),
1080
- additionalConfig: z10.string().optional().describe("JSON string of additional config key-value pairs"),
1081
- isActive: z10.boolean().default(true).describe("Whether the integration is active")
1127
+ id: z11.string().uuid().optional().describe("Integration ID (omit to create, provide to update)"),
1128
+ type: z11.enum(["COUPON", "POINT", "NOTIFICATION", "CRM", "MESSENGER", "WEBHOOK"]).describe("Integration type"),
1129
+ name: z11.string().describe("Integration name"),
1130
+ baseUrl: z11.string().describe("Base URL of the external service"),
1131
+ credential: z11.string().optional().describe("API key or token for the service"),
1132
+ additionalConfig: z11.string().optional().describe("JSON string of additional config key-value pairs"),
1133
+ isActive: z11.boolean().default(true).describe("Whether the integration is active")
1082
1134
  }
1083
1135
  },
1084
1136
  async ({ additionalConfig, ...rest }) => {
@@ -1093,7 +1145,7 @@ function registerIntegrationTools(server, callApi) {
1093
1145
  title: "Delete Integration",
1094
1146
  description: "Delete an integration by ID.",
1095
1147
  inputSchema: {
1096
- integrationId: z10.string().uuid().describe("Integration ID")
1148
+ integrationId: z11.string().uuid().describe("Integration ID")
1097
1149
  }
1098
1150
  },
1099
1151
  async ({ integrationId }) => callApi("DELETE", `integrations/${integrationId}`)
@@ -1110,7 +1162,7 @@ function registerIntegrationTools(server, callApi) {
1110
1162
  }
1111
1163
 
1112
1164
  // src/mcp/tools/logs.ts
1113
- import { z as z11 } from "zod";
1165
+ import { z as z12 } from "zod";
1114
1166
 
1115
1167
  // src/types/enums.ts
1116
1168
  var FailureStatus = ["PENDING", "RESOLVED", "IGNORED"];
@@ -1148,14 +1200,14 @@ function registerLogTools(server, callApi) {
1148
1200
  title: "List Failure Logs",
1149
1201
  description: "List system failure logs from background tasks (webhook calls, coupon issuance, etc.).",
1150
1202
  inputSchema: {
1151
- page: z11.number().int().min(0).default(0).describe("Page number"),
1152
- size: z11.number().int().min(1).max(100).default(20).describe("Page size"),
1153
- category: z11.enum(TaskCategory).optional().describe("Task category"),
1154
- taskType: z11.enum(TaskType).optional().describe("Task type"),
1155
- status: z11.enum(FailureStatus).optional().describe("Log status"),
1156
- keyword: z11.string().optional().describe("Search in refId, refSubId, errorMessage"),
1157
- startDate: z11.string().optional().describe("Start date (yyyy-MM-dd)"),
1158
- endDate: z11.string().optional().describe("End date (yyyy-MM-dd)")
1203
+ page: z12.number().int().min(0).default(0).describe("Page number"),
1204
+ size: z12.number().int().min(1).max(100).default(20).describe("Page size"),
1205
+ category: z12.enum(TaskCategory).optional().describe("Task category"),
1206
+ taskType: z12.enum(TaskType).optional().describe("Task type"),
1207
+ status: z12.enum(FailureStatus).optional().describe("Log status"),
1208
+ keyword: z12.string().optional().describe("Search in refId, refSubId, errorMessage"),
1209
+ startDate: z12.string().optional().describe("Start date (yyyy-MM-dd)"),
1210
+ endDate: z12.string().optional().describe("End date (yyyy-MM-dd)")
1159
1211
  }
1160
1212
  },
1161
1213
  async ({ page, size, category, taskType, status, keyword, startDate, endDate }) => {
@@ -1175,7 +1227,7 @@ function registerLogTools(server, callApi) {
1175
1227
  title: "Get Failure Log",
1176
1228
  description: "Get failure log detail by ID.",
1177
1229
  inputSchema: {
1178
- logId: z11.string().uuid().describe("Failure log ID")
1230
+ logId: z12.string().uuid().describe("Failure log ID")
1179
1231
  }
1180
1232
  },
1181
1233
  async ({ logId }) => callApi("GET", `failure-logs/${logId}`)
@@ -1186,8 +1238,8 @@ function registerLogTools(server, callApi) {
1186
1238
  title: "Process Failure Log",
1187
1239
  description: "Process a single failure log: RETRY (re-execute with original payload), RESOLVE (mark as manually fixed), or IGNORE (skip intentionally).",
1188
1240
  inputSchema: {
1189
- logId: z11.string().uuid().describe("Failure log ID"),
1190
- action: z11.enum(FailureAction).describe("Action to take")
1241
+ logId: z12.string().uuid().describe("Failure log ID"),
1242
+ action: z12.enum(FailureAction).describe("Action to take")
1191
1243
  }
1192
1244
  },
1193
1245
  async ({ logId, action }) => callApi("POST", `failure-logs/${logId}/actions`, {
@@ -1200,8 +1252,8 @@ function registerLogTools(server, callApi) {
1200
1252
  title: "Bulk Process Failure Logs",
1201
1253
  description: "Process multiple failure logs at once. Provide an array of log IDs and the action.",
1202
1254
  inputSchema: {
1203
- logIds: z11.array(z11.string().uuid()).describe("Array of failure log IDs"),
1204
- action: z11.enum(FailureAction).describe("Action to apply to all logs")
1255
+ logIds: z12.array(z12.string().uuid()).describe("Array of failure log IDs"),
1256
+ action: z12.enum(FailureAction).describe("Action to apply to all logs")
1205
1257
  }
1206
1258
  },
1207
1259
  async ({ logIds, action }) => callApi("POST", "failure-logs/bulk-actions", {
@@ -1211,7 +1263,7 @@ function registerLogTools(server, callApi) {
1211
1263
  }
1212
1264
 
1213
1265
  // src/mcp/tools/webhook-subscriptions.ts
1214
- import { z as z12 } from "zod";
1266
+ import { z as z13 } from "zod";
1215
1267
  function registerWebhookSubscriptionTools(server, callApi) {
1216
1268
  server.registerTool(
1217
1269
  "lexq_webhook_subscriptions_list",
@@ -1219,8 +1271,8 @@ function registerWebhookSubscriptionTools(server, callApi) {
1219
1271
  title: "List Webhook Subscriptions",
1220
1272
  description: "List platform event webhook subscriptions. These receive deployment lifecycle notifications (publish, deploy, rollback, undeploy).",
1221
1273
  inputSchema: {
1222
- page: z12.number().int().min(0).default(0).describe("Page number"),
1223
- size: z12.number().int().min(1).max(100).default(20).describe("Page size")
1274
+ page: z13.number().int().min(0).default(0).describe("Page number"),
1275
+ size: z13.number().int().min(1).max(100).default(20).describe("Page size")
1224
1276
  }
1225
1277
  },
1226
1278
  async ({ page, size }) => {
@@ -1234,7 +1286,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
1234
1286
  title: "Get Webhook Subscription",
1235
1287
  description: "Get webhook subscription detail by ID.",
1236
1288
  inputSchema: {
1237
- id: z12.string().uuid().describe("Webhook subscription ID")
1289
+ id: z13.string().uuid().describe("Webhook subscription ID")
1238
1290
  }
1239
1291
  },
1240
1292
  async ({ id }) => callApi("GET", `webhook-subscriptions/${id}`)
@@ -1245,13 +1297,13 @@ function registerWebhookSubscriptionTools(server, callApi) {
1245
1297
  title: "Save Webhook Subscription",
1246
1298
  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": "..."}).',
1247
1299
  inputSchema: {
1248
- id: z12.string().uuid().optional().describe("Subscription ID (omit to create, provide to update)"),
1249
- name: z12.string().min(1).describe("Subscription name (unique per tenant)"),
1250
- webhookUrl: z12.string().url().describe("Webhook endpoint URL"),
1251
- subscribedEvents: z12.array(z12.enum(PlatformEventType)).min(1).describe("Events to subscribe to"),
1252
- payloadFormat: z12.enum(WebhookPayloadFormat).optional().default("GENERIC").describe("Payload format"),
1253
- secret: z12.string().optional().describe("HMAC-SHA256 signing secret"),
1254
- isActive: z12.boolean().optional().default(true).describe("Whether the subscription is active")
1300
+ id: z13.string().uuid().optional().describe("Subscription ID (omit to create, provide to update)"),
1301
+ name: z13.string().min(1).describe("Subscription name (unique per tenant)"),
1302
+ webhookUrl: z13.string().url().describe("Webhook endpoint URL"),
1303
+ subscribedEvents: z13.array(z13.enum(PlatformEventType)).min(1).describe("Events to subscribe to"),
1304
+ payloadFormat: z13.enum(WebhookPayloadFormat).optional().default("GENERIC").describe("Payload format"),
1305
+ secret: z13.string().optional().describe("HMAC-SHA256 signing secret"),
1306
+ isActive: z13.boolean().optional().default(true).describe("Whether the subscription is active")
1255
1307
  }
1256
1308
  },
1257
1309
  async ({ ...body }) => callApi("POST", "webhook-subscriptions", { body })
@@ -1262,7 +1314,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
1262
1314
  title: "Delete Webhook Subscription",
1263
1315
  description: "Delete a webhook subscription by ID.",
1264
1316
  inputSchema: {
1265
- id: z12.string().uuid().describe("Webhook subscription ID")
1317
+ id: z13.string().uuid().describe("Webhook subscription ID")
1266
1318
  }
1267
1319
  },
1268
1320
  async ({ id }) => callApi("DELETE", `webhook-subscriptions/${id}`)
@@ -1273,7 +1325,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
1273
1325
  title: "Test Webhook Subscription",
1274
1326
  description: "Send a test event to verify webhook connectivity. Returns the HTTP status code and success/failure message.",
1275
1327
  inputSchema: {
1276
- id: z12.string().uuid().describe("Webhook subscription ID")
1328
+ id: z13.string().uuid().describe("Webhook subscription ID")
1277
1329
  }
1278
1330
  },
1279
1331
  async ({ id }) => callApi("POST", `webhook-subscriptions/${id}/test`)
@@ -1281,7 +1333,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
1281
1333
  }
1282
1334
 
1283
1335
  // src/mcp/tools/domain-templates.ts
1284
- import { z as z13 } from "zod";
1336
+ import { z as z14 } from "zod";
1285
1337
  function registerDomainTemplateTools(server, callApi) {
1286
1338
  server.registerTool(
1287
1339
  "lexq_domain_templates_list",
@@ -1298,7 +1350,7 @@ function registerDomainTemplateTools(server, callApi) {
1298
1350
  title: "Preview Domain Template",
1299
1351
  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.",
1300
1352
  inputSchema: {
1301
- template: z13.string().describe(
1353
+ template: z14.string().describe(
1302
1354
  "Domain template key (e.g. ECOMMERCE). Use lexq_domain_templates_list to see available keys \u2014 currently only ECOMMERCE is ACTIVE."
1303
1355
  )
1304
1356
  }
@@ -1311,8 +1363,8 @@ function registerDomainTemplateTools(server, callApi) {
1311
1363
  title: "Apply Domain Template",
1312
1364
  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.",
1313
1365
  inputSchema: {
1314
- template: z13.string().describe("Domain template key to apply (e.g. ECOMMERCE)."),
1315
- customName: z13.string().optional().describe(
1366
+ template: z14.string().describe("Domain template key to apply (e.g. ECOMMERCE)."),
1367
+ customName: z14.string().optional().describe(
1316
1368
  "Optional custom name for the policy group that gets created. If omitted, the template's default name is used."
1317
1369
  )
1318
1370
  }
@@ -1334,6 +1386,7 @@ function registerAllTools(server, callApi) {
1334
1386
  registerFactTools(server, callApi);
1335
1387
  registerDeployTools(server, callApi);
1336
1388
  registerAnalyticsTools(server, callApi);
1389
+ registerProfileTools(server, callApi);
1337
1390
  registerReplayTools(server, callApi);
1338
1391
  registerHistoryTools(server, callApi);
1339
1392
  registerProvenanceTools(server, callApi);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lexq/cli",
3
- "version": "0.1.35",
3
+ "version": "0.1.37",
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": {