@lexq/cli 1.0.0 → 1.0.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/index.js CHANGED
@@ -347,6 +347,12 @@ var SLOW_MULTIPLIER = 10;
347
347
  var MIN_SAMPLES = 100;
348
348
  var MIN_COHORT_SIZE = 3;
349
349
  var PROFILE_DEFAULT_WINDOW_HOURS = 24;
350
+ var MAX_GROUPS_PER_TENANT = 20;
351
+ var MAX_DRAFT_VERSIONS_PER_GROUP = 20;
352
+ var MAX_RULES_PER_VERSION = 100;
353
+ var MAX_CONDITIONS_PER_RULE = 25;
354
+ var MAX_CONDITION_DEPTH = 10;
355
+ var MAX_SNAPSHOT_BYTES = 131072;
350
356
 
351
357
  // src/commands/groups.ts
352
358
  import "commander";
@@ -3533,7 +3539,7 @@ function registerGroupTools(server, callApi) {
3533
3539
  {
3534
3540
  title: "Create Policy Group",
3535
3541
  annotations: { readOnlyHint: false, destructiveHint: false },
3536
- description: "Create a new policy group. Requires name. Priority is auto-assigned (appended last, tenant-wide); use lexq_groups_reorder to change order. Optionally set conflict resolution, activation group, and description. Policy groups that share an activationGroup form a cluster and must share the same activationMode / activationStrategy / executionLimit; executionLimit is how many of those groups run, not how many rules.",
3542
+ description: `Create a new policy group. Requires name. Priority is auto-assigned (appended last, tenant-wide); use lexq_groups_reorder to change order. Optionally set conflict resolution, activation group, and description. Policy groups that share an activationGroup form a cluster and must share the same activationMode / activationStrategy / executionLimit; executionLimit is how many of those groups run, not how many rules. A tenant can have at most ${MAX_GROUPS_PER_TENANT} groups that are not ARCHIVED; archive groups you no longer use to free a slot.`,
3537
3543
  inputSchema: z2.object({
3538
3544
  name: z2.string().describe("Group name (unique among non-ARCHIVED)"),
3539
3545
  description: z2.string().optional().describe("Group description"),
@@ -3690,7 +3696,7 @@ function registerVersionTools(server, callApi) {
3690
3696
  {
3691
3697
  title: "Create Policy Version",
3692
3698
  annotations: { readOnlyHint: false, destructiveHint: false },
3693
- description: "Create a new DRAFT version in a policy group. Optionally provide a commit message and effective date range.",
3699
+ description: `Create a new DRAFT version in a policy group. Optionally provide a commit message and effective date range. A group can hold at most ${MAX_DRAFT_VERSIONS_PER_GROUP} DRAFT versions at a time; published versions do not count. Publish or delete drafts to make room.`,
3694
3700
  inputSchema: z3.object({
3695
3701
  groupId: z3.string().uuid().describe("Policy group ID"),
3696
3702
  commitMessage: z3.string().optional().describe("Commit message describing this version"),
@@ -3734,7 +3740,7 @@ function registerVersionTools(server, callApi) {
3734
3740
  {
3735
3741
  title: "Clone Policy Version",
3736
3742
  annotations: { readOnlyHint: false, destructiveHint: false },
3737
- description: "Clone an existing version to create a new DRAFT. Useful when the source version is already published.",
3743
+ description: `Clone an existing version to create a new DRAFT. Useful when the source version is already published. The new DRAFT counts toward the limit of ${MAX_DRAFT_VERSIONS_PER_GROUP} DRAFT versions per group, and a source with more than ${MAX_RULES_PER_VERSION} rules cannot be cloned.`,
3738
3744
  inputSchema: z3.object({
3739
3745
  groupId: z3.string().uuid().describe("Policy group ID"),
3740
3746
  versionId: z3.string().uuid().describe("Source version ID to clone")
@@ -3797,7 +3803,9 @@ function registerRuleTools(server, callApi) {
3797
3803
 
3798
3804
  Condition: { type: "SINGLE", field, operator, value, valueType } or { type: "GROUP", operator: "AND"|"OR", children: [...] }
3799
3805
  Value types: STRING, NUMBER, BOOLEAN, LIST_STRING, LIST_NUMBER
3800
-
3806
+ Limits: a condition tree may hold at most ${MAX_CONDITIONS_PER_RULE} conditions (SINGLE nodes; GROUP nodes do not count)
3807
+ and nest at most ${MAX_CONDITION_DEPTH} levels below the root. A version holds at most ${MAX_RULES_PER_VERSION} rules.
3808
+
3801
3809
  Operators are constrained by the LEFT fact's type (from lexq_facts_list). Using one outside
3802
3810
  its type is rejected by the server — check the fact type before choosing an operator.
3803
3811
  - STRING fact: EQUALS, NOT_EQUALS, CONTAINS, IN, NOT_IN
@@ -3863,7 +3871,7 @@ function registerRuleTools(server, callApi) {
3863
3871
  {
3864
3872
  title: "Update Rule",
3865
3873
  annotations: { readOnlyHint: false, destructiveHint: true },
3866
- description: "Update an existing rule in a DRAFT version. Only provided fields are changed.",
3874
+ description: `Update an existing rule in a DRAFT version. Only provided fields are changed. A new condition tree must stay within ${MAX_CONDITIONS_PER_RULE} conditions (SINGLE nodes) and ${MAX_CONDITION_DEPTH} levels of nesting below the root.`,
3867
3875
  inputSchema: z4.object({
3868
3876
  groupId: z4.string().uuid().describe("Policy group ID"),
3869
3877
  versionId: z4.string().uuid().describe("Version ID"),
@@ -4085,7 +4093,7 @@ function registerDeployTools(server, callApi) {
4085
4093
  {
4086
4094
  title: "Publish Version",
4087
4095
  annotations: { readOnlyHint: false, destructiveHint: false },
4088
- description: "Publish a DRAFT version (DRAFT \u2192 ACTIVE). Locks the version from further edits. Must have at least one rule. Undefined facts referenced by rules do not block publishing (INV-4); call lexq_facts_unregistered first to review them.",
4096
+ description: `Publish a DRAFT version (DRAFT \u2192 ACTIVE). Locks the version from further edits. Must have at least one rule. Undefined facts referenced by rules do not block publishing (INV-4); call lexq_facts_unregistered first to review them. Publishing fails if the version's compiled rules exceed ${MAX_SNAPSHOT_BYTES / 1024} KB.`,
4089
4097
  inputSchema: z6.object({
4090
4098
  groupId: z6.string().uuid().describe("Policy group ID"),
4091
4099
  versionId: z6.string().uuid().describe("Version ID to publish"),
@@ -34,6 +34,23 @@ var PlatformEventType = [
34
34
  ];
35
35
  var WebhookPayloadFormat = ["GENERIC", "SLACK"];
36
36
 
37
+ // src/types/constants.ts
38
+ var MAX_ROUNDING_SCALE = 34;
39
+ var REPLAY_WINDOW_MAX_RECORDS = 5e4;
40
+ var PROFILE_SAMPLE_PERMILLE = 10;
41
+ var LATENCY_WINDOW_MILLIS = 6e4;
42
+ var TAIL_MIN_OBS = 3;
43
+ var SLOW_MULTIPLIER = 10;
44
+ var MIN_SAMPLES = 100;
45
+ var MIN_COHORT_SIZE = 3;
46
+ var PROFILE_DEFAULT_WINDOW_HOURS = 24;
47
+ var MAX_GROUPS_PER_TENANT = 20;
48
+ var MAX_DRAFT_VERSIONS_PER_GROUP = 20;
49
+ var MAX_RULES_PER_VERSION = 100;
50
+ var MAX_CONDITIONS_PER_RULE = 25;
51
+ var MAX_CONDITION_DEPTH = 10;
52
+ var MAX_SNAPSHOT_BYTES = 131072;
53
+
37
54
  // src/mcp/tools/groups.ts
38
55
  function registerGroupTools(server, callApi) {
39
56
  server.registerTool(
@@ -63,7 +80,7 @@ function registerGroupTools(server, callApi) {
63
80
  {
64
81
  title: "Create Policy Group",
65
82
  annotations: { readOnlyHint: false, destructiveHint: false },
66
- description: "Create a new policy group. Requires name. Priority is auto-assigned (appended last, tenant-wide); use lexq_groups_reorder to change order. Optionally set conflict resolution, activation group, and description. Policy groups that share an activationGroup form a cluster and must share the same activationMode / activationStrategy / executionLimit; executionLimit is how many of those groups run, not how many rules.",
83
+ description: `Create a new policy group. Requires name. Priority is auto-assigned (appended last, tenant-wide); use lexq_groups_reorder to change order. Optionally set conflict resolution, activation group, and description. Policy groups that share an activationGroup form a cluster and must share the same activationMode / activationStrategy / executionLimit; executionLimit is how many of those groups run, not how many rules. A tenant can have at most ${MAX_GROUPS_PER_TENANT} groups that are not ARCHIVED; archive groups you no longer use to free a slot.`,
67
84
  inputSchema: z2.object({
68
85
  name: z2.string().describe("Group name (unique among non-ARCHIVED)"),
69
86
  description: z2.string().optional().describe("Group description"),
@@ -278,7 +295,7 @@ function registerVersionTools(server, callApi) {
278
295
  {
279
296
  title: "Create Policy Version",
280
297
  annotations: { readOnlyHint: false, destructiveHint: false },
281
- description: "Create a new DRAFT version in a policy group. Optionally provide a commit message and effective date range.",
298
+ description: `Create a new DRAFT version in a policy group. Optionally provide a commit message and effective date range. A group can hold at most ${MAX_DRAFT_VERSIONS_PER_GROUP} DRAFT versions at a time; published versions do not count. Publish or delete drafts to make room.`,
282
299
  inputSchema: z3.object({
283
300
  groupId: z3.string().uuid().describe("Policy group ID"),
284
301
  commitMessage: z3.string().optional().describe("Commit message describing this version"),
@@ -322,7 +339,7 @@ function registerVersionTools(server, callApi) {
322
339
  {
323
340
  title: "Clone Policy Version",
324
341
  annotations: { readOnlyHint: false, destructiveHint: false },
325
- description: "Clone an existing version to create a new DRAFT. Useful when the source version is already published.",
342
+ description: `Clone an existing version to create a new DRAFT. Useful when the source version is already published. The new DRAFT counts toward the limit of ${MAX_DRAFT_VERSIONS_PER_GROUP} DRAFT versions per group, and a source with more than ${MAX_RULES_PER_VERSION} rules cannot be cloned.`,
326
343
  inputSchema: z3.object({
327
344
  groupId: z3.string().uuid().describe("Policy group ID"),
328
345
  versionId: z3.string().uuid().describe("Source version ID to clone")
@@ -336,17 +353,6 @@ function registerVersionTools(server, callApi) {
336
353
  );
337
354
  }
338
355
 
339
- // src/types/constants.ts
340
- var MAX_ROUNDING_SCALE = 34;
341
- var REPLAY_WINDOW_MAX_RECORDS = 5e4;
342
- var PROFILE_SAMPLE_PERMILLE = 10;
343
- var LATENCY_WINDOW_MILLIS = 6e4;
344
- var TAIL_MIN_OBS = 3;
345
- var SLOW_MULTIPLIER = 10;
346
- var MIN_SAMPLES = 100;
347
- var MIN_COHORT_SIZE = 3;
348
- var PROFILE_DEFAULT_WINDOW_HOURS = 24;
349
-
350
356
  // src/mcp/tools/rules.ts
351
357
  import { z as z4 } from "zod";
352
358
  import dedent from "dedent";
@@ -396,7 +402,9 @@ function registerRuleTools(server, callApi) {
396
402
 
397
403
  Condition: { type: "SINGLE", field, operator, value, valueType } or { type: "GROUP", operator: "AND"|"OR", children: [...] }
398
404
  Value types: STRING, NUMBER, BOOLEAN, LIST_STRING, LIST_NUMBER
399
-
405
+ Limits: a condition tree may hold at most ${MAX_CONDITIONS_PER_RULE} conditions (SINGLE nodes; GROUP nodes do not count)
406
+ and nest at most ${MAX_CONDITION_DEPTH} levels below the root. A version holds at most ${MAX_RULES_PER_VERSION} rules.
407
+
400
408
  Operators are constrained by the LEFT fact's type (from lexq_facts_list). Using one outside
401
409
  its type is rejected by the server — check the fact type before choosing an operator.
402
410
  - STRING fact: EQUALS, NOT_EQUALS, CONTAINS, IN, NOT_IN
@@ -462,7 +470,7 @@ function registerRuleTools(server, callApi) {
462
470
  {
463
471
  title: "Update Rule",
464
472
  annotations: { readOnlyHint: false, destructiveHint: true },
465
- description: "Update an existing rule in a DRAFT version. Only provided fields are changed.",
473
+ description: `Update an existing rule in a DRAFT version. Only provided fields are changed. A new condition tree must stay within ${MAX_CONDITIONS_PER_RULE} conditions (SINGLE nodes) and ${MAX_CONDITION_DEPTH} levels of nesting below the root.`,
466
474
  inputSchema: z4.object({
467
475
  groupId: z4.string().uuid().describe("Policy group ID"),
468
476
  versionId: z4.string().uuid().describe("Version ID"),
@@ -688,7 +696,7 @@ function registerDeployTools(server, callApi) {
688
696
  {
689
697
  title: "Publish Version",
690
698
  annotations: { readOnlyHint: false, destructiveHint: false },
691
- description: "Publish a DRAFT version (DRAFT \u2192 ACTIVE). Locks the version from further edits. Must have at least one rule. Undefined facts referenced by rules do not block publishing (INV-4); call lexq_facts_unregistered first to review them.",
699
+ description: `Publish a DRAFT version (DRAFT \u2192 ACTIVE). Locks the version from further edits. Must have at least one rule. Undefined facts referenced by rules do not block publishing (INV-4); call lexq_facts_unregistered first to review them. Publishing fails if the version's compiled rules exceed ${MAX_SNAPSHOT_BYTES / 1024} KB.`,
692
700
  inputSchema: z6.object({
693
701
  groupId: z6.string().uuid().describe("Policy group ID"),
694
702
  versionId: z6.string().uuid().describe("Version ID to publish"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lexq/cli",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "mcpName": "io.lexq/lexq",
5
5
  "description": "LexQ CLI — manage policies, simulate rules, and deploy from the terminal. Built for humans and AI agents.",
6
6
  "type": "module",