@lexq/cli 0.3.1 → 1.0.0
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/README.md +58 -2
- package/dist/index.js +174 -5
- package/dist/mcp/register.js +96 -1
- package/package.json +4 -2
- package/skills/lexq-recipes/SKILL.md +5 -1
- package/skills/lexq-shared/SKILL.md +1 -0
- package/skills/lexq-simulation/SKILL.md +12 -6
package/dist/mcp/register.js
CHANGED
|
@@ -5,6 +5,7 @@ function registerStatusTools(server, callApi) {
|
|
|
5
5
|
"lexq_whoami",
|
|
6
6
|
{
|
|
7
7
|
title: "Who Am I",
|
|
8
|
+
annotations: { readOnlyHint: true },
|
|
8
9
|
description: "Show current authentication info (tenant ID, user ID, role).",
|
|
9
10
|
inputSchema: z.object({})
|
|
10
11
|
},
|
|
@@ -39,6 +40,7 @@ function registerGroupTools(server, callApi) {
|
|
|
39
40
|
"lexq_groups_list",
|
|
40
41
|
{
|
|
41
42
|
title: "List Policy Groups",
|
|
43
|
+
annotations: { readOnlyHint: true },
|
|
42
44
|
description: "List all policy groups (tenant-wide, priority ASC).",
|
|
43
45
|
inputSchema: z2.object({})
|
|
44
46
|
},
|
|
@@ -48,6 +50,7 @@ function registerGroupTools(server, callApi) {
|
|
|
48
50
|
"lexq_groups_get",
|
|
49
51
|
{
|
|
50
52
|
title: "Get Policy Group",
|
|
53
|
+
annotations: { readOnlyHint: true },
|
|
51
54
|
description: "Get a single policy group by ID.",
|
|
52
55
|
inputSchema: z2.object({
|
|
53
56
|
groupId: z2.string().uuid().describe("Policy group ID")
|
|
@@ -59,6 +62,7 @@ function registerGroupTools(server, callApi) {
|
|
|
59
62
|
"lexq_groups_create",
|
|
60
63
|
{
|
|
61
64
|
title: "Create Policy Group",
|
|
65
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
62
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.",
|
|
63
67
|
inputSchema: z2.object({
|
|
64
68
|
name: z2.string().describe("Group name (unique among non-ARCHIVED)"),
|
|
@@ -89,6 +93,7 @@ function registerGroupTools(server, callApi) {
|
|
|
89
93
|
"lexq_groups_update",
|
|
90
94
|
{
|
|
91
95
|
title: "Update Policy Group",
|
|
96
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
92
97
|
description: "Update a policy group. Only provided fields are updated; omitted fields remain unchanged.",
|
|
93
98
|
inputSchema: z2.object({
|
|
94
99
|
groupId: z2.string().uuid().describe("Policy group ID"),
|
|
@@ -111,6 +116,7 @@ function registerGroupTools(server, callApi) {
|
|
|
111
116
|
"lexq_groups_delete",
|
|
112
117
|
{
|
|
113
118
|
title: "Delete Policy Group",
|
|
119
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
114
120
|
description: "Archive a policy group. Only non-live groups can be deleted. This is irreversible.",
|
|
115
121
|
inputSchema: z2.object({
|
|
116
122
|
groupId: z2.string().uuid().describe("Policy group ID")
|
|
@@ -122,6 +128,7 @@ function registerGroupTools(server, callApi) {
|
|
|
122
128
|
"lexq_groups_reorder",
|
|
123
129
|
{
|
|
124
130
|
title: "Reorder Policy Groups",
|
|
131
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
125
132
|
description: "Reorder policy groups by priority. Priority is tenant-wide and flat (1...N continuous); array index 0 = priority 1 (highest precedence). activationGroup is not affected \u2014 this only changes priority.",
|
|
126
133
|
inputSchema: z2.object({
|
|
127
134
|
groupIds: z2.array(z2.string().uuid()).describe("Group IDs in desired priority order (index 0 = priority 1)")
|
|
@@ -139,6 +146,7 @@ function registerGroupTools(server, callApi) {
|
|
|
139
146
|
"lexq_ab_test_start",
|
|
140
147
|
{
|
|
141
148
|
title: "Start A/B Test",
|
|
149
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
142
150
|
description: "Start an A/B test on a policy group. Requires a challenger version ID and traffic rate. The split is computed from context.trafficKey on each execution request; requests that omit it never reach the challenger and the test stays at 0%.",
|
|
143
151
|
inputSchema: z2.object({
|
|
144
152
|
groupId: z2.string().uuid().describe("Policy group ID"),
|
|
@@ -152,6 +160,7 @@ function registerGroupTools(server, callApi) {
|
|
|
152
160
|
"lexq_ab_test_stop",
|
|
153
161
|
{
|
|
154
162
|
title: "Stop A/B Test",
|
|
163
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
155
164
|
description: "Stop a running A/B test. All traffic is restored to the control (current) version.",
|
|
156
165
|
inputSchema: z2.object({
|
|
157
166
|
groupId: z2.string().uuid().describe("Policy group ID")
|
|
@@ -163,6 +172,7 @@ function registerGroupTools(server, callApi) {
|
|
|
163
172
|
"lexq_ab_test_adjust",
|
|
164
173
|
{
|
|
165
174
|
title: "Adjust A/B Test",
|
|
175
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
166
176
|
description: "Adjust traffic rate of a running A/B test.",
|
|
167
177
|
inputSchema: z2.object({
|
|
168
178
|
groupId: z2.string().uuid().describe("Policy group ID"),
|
|
@@ -238,6 +248,7 @@ function registerVersionTools(server, callApi) {
|
|
|
238
248
|
"lexq_versions_list",
|
|
239
249
|
{
|
|
240
250
|
title: "List Policy Versions",
|
|
251
|
+
annotations: { readOnlyHint: true },
|
|
241
252
|
description: "List all versions of a policy group.",
|
|
242
253
|
inputSchema: z3.object({
|
|
243
254
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
@@ -253,6 +264,7 @@ function registerVersionTools(server, callApi) {
|
|
|
253
264
|
"lexq_versions_get",
|
|
254
265
|
{
|
|
255
266
|
title: "Get Policy Version",
|
|
267
|
+
annotations: { readOnlyHint: true },
|
|
256
268
|
description: "Get a single version by ID, including its rules and fact requirements.",
|
|
257
269
|
inputSchema: z3.object({
|
|
258
270
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
@@ -265,6 +277,7 @@ function registerVersionTools(server, callApi) {
|
|
|
265
277
|
"lexq_versions_create",
|
|
266
278
|
{
|
|
267
279
|
title: "Create Policy Version",
|
|
280
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
268
281
|
description: "Create a new DRAFT version in a policy group. Optionally provide a commit message and effective date range.",
|
|
269
282
|
inputSchema: z3.object({
|
|
270
283
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
@@ -279,6 +292,7 @@ function registerVersionTools(server, callApi) {
|
|
|
279
292
|
"lexq_versions_update",
|
|
280
293
|
{
|
|
281
294
|
title: "Update Policy Version",
|
|
295
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
282
296
|
description: "Update a DRAFT version. Only DRAFT versions can be modified. Only provided fields are changed.",
|
|
283
297
|
inputSchema: z3.object({
|
|
284
298
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
@@ -294,6 +308,7 @@ function registerVersionTools(server, callApi) {
|
|
|
294
308
|
"lexq_versions_delete",
|
|
295
309
|
{
|
|
296
310
|
title: "Delete Policy Version",
|
|
311
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
297
312
|
description: "Delete a DRAFT version. Only DRAFT versions can be deleted.",
|
|
298
313
|
inputSchema: z3.object({
|
|
299
314
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
@@ -306,6 +321,7 @@ function registerVersionTools(server, callApi) {
|
|
|
306
321
|
"lexq_versions_clone",
|
|
307
322
|
{
|
|
308
323
|
title: "Clone Policy Version",
|
|
324
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
309
325
|
description: "Clone an existing version to create a new DRAFT. Useful when the source version is already published.",
|
|
310
326
|
inputSchema: z3.object({
|
|
311
327
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
@@ -339,6 +355,7 @@ function registerRuleTools(server, callApi) {
|
|
|
339
355
|
"lexq_rules_list",
|
|
340
356
|
{
|
|
341
357
|
title: "List Rules",
|
|
358
|
+
annotations: { readOnlyHint: true },
|
|
342
359
|
description: "List all rules in a version (priority ASC). Returns summary with conditionSummary and actionSummary.",
|
|
343
360
|
inputSchema: z4.object({
|
|
344
361
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
@@ -351,6 +368,7 @@ function registerRuleTools(server, callApi) {
|
|
|
351
368
|
"lexq_rules_get",
|
|
352
369
|
{
|
|
353
370
|
title: "Get Rule Detail",
|
|
371
|
+
annotations: { readOnlyHint: true },
|
|
354
372
|
description: "Get full rule detail including condition tree and action definitions.",
|
|
355
373
|
inputSchema: z4.object({
|
|
356
374
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
@@ -364,6 +382,7 @@ function registerRuleTools(server, callApi) {
|
|
|
364
382
|
"lexq_rules_create",
|
|
365
383
|
{
|
|
366
384
|
title: "Create Rule",
|
|
385
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
367
386
|
description: dedent`
|
|
368
387
|
Create a rule in a DRAFT version. Requires name, condition tree, and actions array. priority is auto-assigned (appended last); use lexq_rules_reorder to change order.
|
|
369
388
|
|
|
@@ -442,6 +461,7 @@ function registerRuleTools(server, callApi) {
|
|
|
442
461
|
"lexq_rules_update",
|
|
443
462
|
{
|
|
444
463
|
title: "Update Rule",
|
|
464
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
445
465
|
description: "Update an existing rule in a DRAFT version. Only provided fields are changed.",
|
|
446
466
|
inputSchema: z4.object({
|
|
447
467
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
@@ -463,6 +483,7 @@ function registerRuleTools(server, callApi) {
|
|
|
463
483
|
"lexq_rules_delete",
|
|
464
484
|
{
|
|
465
485
|
title: "Delete Rule",
|
|
486
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
466
487
|
description: "Delete a rule from a DRAFT version.",
|
|
467
488
|
inputSchema: z4.object({
|
|
468
489
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
@@ -483,6 +504,7 @@ function registerRuleTools(server, callApi) {
|
|
|
483
504
|
"lexq_rules_reorder",
|
|
484
505
|
{
|
|
485
506
|
title: "Reorder Rules",
|
|
507
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
486
508
|
description: "Reorder rules by specifying rule IDs in desired order. Priorities are assigned 1...N (1-based, continuous); array index 0 = priority 1 (highest precedence).",
|
|
487
509
|
inputSchema: z4.object({
|
|
488
510
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
@@ -504,6 +526,7 @@ function registerRuleTools(server, callApi) {
|
|
|
504
526
|
"lexq_rules_toggle",
|
|
505
527
|
{
|
|
506
528
|
title: "Toggle Rule",
|
|
529
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
507
530
|
description: "Enable or disable a rule without deleting it.",
|
|
508
531
|
inputSchema: z4.object({
|
|
509
532
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
@@ -535,6 +558,7 @@ function registerFactTools(server, callApi) {
|
|
|
535
558
|
"lexq_facts_list",
|
|
536
559
|
{
|
|
537
560
|
title: "List Fact Definitions",
|
|
561
|
+
annotations: { readOnlyHint: true },
|
|
538
562
|
description: "List all fact definitions (input variable schema). Shows key, type, required, and PII status. Always check this before creating rules.",
|
|
539
563
|
inputSchema: z5.object({
|
|
540
564
|
page: z5.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -552,6 +576,7 @@ function registerFactTools(server, callApi) {
|
|
|
552
576
|
"lexq_facts_create",
|
|
553
577
|
{
|
|
554
578
|
title: "Create Fact Definition",
|
|
579
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
555
580
|
description: "Register a new input variable. Key starts with a letter, then letters, numbers, and underscores (e.g. paymentAmount). Casing is not enforced. Types: STRING, NUMBER, BOOLEAN, LIST_STRING, LIST_NUMBER.",
|
|
556
581
|
inputSchema: z5.object({
|
|
557
582
|
key: z5.string().regex(FACT_KEY_PATTERN).describe("Variable key. Any casing; must start with a letter."),
|
|
@@ -561,6 +586,15 @@ function registerFactTools(server, callApi) {
|
|
|
561
586
|
isRequired: z5.boolean().default(false).describe("Whether this fact is required for rule evaluation"),
|
|
562
587
|
isPii: z5.boolean().default(false).describe(
|
|
563
588
|
"Mark as PII \u2014 masked on every read surface, revealable only in the console (audited)"
|
|
589
|
+
),
|
|
590
|
+
valueDomain: z5.object({
|
|
591
|
+
allowedValues: z5.array(z5.union([z5.string(), z5.number()])).optional().describe(
|
|
592
|
+
"Accepted values. For list types the constraint applies to each element, not to the list as a whole."
|
|
593
|
+
),
|
|
594
|
+
min: z5.number().optional().describe("Lower bound, inclusive. Numeric types only."),
|
|
595
|
+
max: z5.number().optional().describe("Upper bound, inclusive. Numeric types only.")
|
|
596
|
+
}).optional().describe(
|
|
597
|
+
"Which values this fact accepts. Omit for no constraint. STRING and LIST_STRING take allowedValues only; NUMBER and LIST_NUMBER take all three; BOOLEAN takes none. Declaring it lets the rule editor offer a dropdown and rejects a rule literal that could never match."
|
|
564
598
|
)
|
|
565
599
|
})
|
|
566
600
|
},
|
|
@@ -570,6 +604,7 @@ function registerFactTools(server, callApi) {
|
|
|
570
604
|
"lexq_facts_update",
|
|
571
605
|
{
|
|
572
606
|
title: "Update Fact Definition",
|
|
607
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
573
608
|
description: "Update a fact definition. The key is immutable. The type can change only while no rule references the fact; if any does, the call fails with FD-007 and reports the count. Only the fields you send are changed. System facts accept name, description, and PII only.",
|
|
574
609
|
inputSchema: z5.object({
|
|
575
610
|
factId: z5.string().uuid().describe("Fact definition ID"),
|
|
@@ -579,7 +614,16 @@ function registerFactTools(server, callApi) {
|
|
|
579
614
|
"Value type. Omit to leave it unchanged. Changing it fails with FD-007 while any rule references the fact."
|
|
580
615
|
),
|
|
581
616
|
isRequired: z5.boolean().optional().describe("Required flag"),
|
|
582
|
-
isPii: z5.boolean().optional().describe("PII flag \u2014 enables/disables masking (changeable even on system facts)")
|
|
617
|
+
isPii: z5.boolean().optional().describe("PII flag \u2014 enables/disables masking (changeable even on system facts)"),
|
|
618
|
+
valueDomain: z5.object({
|
|
619
|
+
allowedValues: z5.array(z5.union([z5.string(), z5.number()])).optional().describe(
|
|
620
|
+
"Accepted values. For list types the constraint applies to each element, not to the list as a whole."
|
|
621
|
+
),
|
|
622
|
+
min: z5.number().optional().describe("Lower bound, inclusive. Numeric types only."),
|
|
623
|
+
max: z5.number().optional().describe("Upper bound, inclusive. Numeric types only.")
|
|
624
|
+
}).optional().describe(
|
|
625
|
+
"Which values this fact accepts. Three states: omit the field to leave the constraint alone, send {} to remove it, or send a populated object to replace it. Narrowing it does not rewrite rules that already reference this fact \u2014 they keep working, and the next save is judged against the new constraint."
|
|
626
|
+
)
|
|
583
627
|
})
|
|
584
628
|
},
|
|
585
629
|
async ({ factId, ...body }) => callApi("PUT", `schema/facts/${factId}`, { body })
|
|
@@ -588,6 +632,7 @@ function registerFactTools(server, callApi) {
|
|
|
588
632
|
"lexq_facts_delete",
|
|
589
633
|
{
|
|
590
634
|
title: "Delete Fact Definition",
|
|
635
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
591
636
|
description: "Delete a fact definition. System facts cannot be deleted. Neither can a fact that any rule references: that call fails with FD-006 and reports the count. Remove the references first.",
|
|
592
637
|
inputSchema: z5.object({
|
|
593
638
|
factId: z5.string().uuid().describe("Fact definition ID")
|
|
@@ -599,6 +644,7 @@ function registerFactTools(server, callApi) {
|
|
|
599
644
|
"lexq_facts_action_metadata",
|
|
600
645
|
{
|
|
601
646
|
title: "Get Action Runtime Fact Metadata",
|
|
647
|
+
annotations: { readOnlyHint: true },
|
|
602
648
|
description: "Retrieve runtime fact requirements per Action type. For each Action, shows which input facts must be present in the execution payload \u2014 e.g. MUTATE_FACT always requires its targetVar fact, plus refVar when one is specified. The factRequired flag describes the FACT, not the parameter: refVar is an optional parameter, but if you specify it the named fact must exist. A required fact absent at runtime throws \u2014 the engine never defaults to 0. Facts are supplied as input or written by a prior action in the same rule; only SET_FACT creates a fact from nothing. Static data, safe to cache in-session.",
|
|
603
649
|
inputSchema: z5.object({})
|
|
604
650
|
},
|
|
@@ -608,6 +654,7 @@ function registerFactTools(server, callApi) {
|
|
|
608
654
|
"lexq_facts_unregistered",
|
|
609
655
|
{
|
|
610
656
|
title: "List Unregistered Facts",
|
|
657
|
+
annotations: { readOnlyHint: true },
|
|
611
658
|
description: "List facts referenced by a version's rules but not yet defined (read-only \u2014 does not block publish/deploy, INV-4). Version-wide: covers every rule in the version. Each entry carries the inferred type, suggested name, and where it is referenced (condition/action). Register them with lexq_facts_create to enable type validation and the dry-run requirements analyzer.",
|
|
612
659
|
inputSchema: z5.object({
|
|
613
660
|
groupId: z5.string().uuid().describe("Policy group ID"),
|
|
@@ -620,6 +667,7 @@ function registerFactTools(server, callApi) {
|
|
|
620
667
|
"lexq_facts_export",
|
|
621
668
|
{
|
|
622
669
|
title: "Export Fact Catalog",
|
|
670
|
+
annotations: { readOnlyHint: true },
|
|
623
671
|
description: "Export the fact catalog. The two formats carry different things: CSV is the catalog as it stands, system facts included, for reading in a spreadsheet; JSON matches the shape that batch create accepts, so it can be fed straight back in, which is why it leaves out the fields that endpoint does not take. Returns the file contents as text.",
|
|
624
672
|
inputSchema: z5.object({
|
|
625
673
|
format: z5.enum(EXPORT_FORMATS).default("csv").describe("Export format"),
|
|
@@ -639,6 +687,7 @@ function registerDeployTools(server, callApi) {
|
|
|
639
687
|
"lexq_deploy_publish",
|
|
640
688
|
{
|
|
641
689
|
title: "Publish Version",
|
|
690
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
642
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.",
|
|
643
692
|
inputSchema: z6.object({
|
|
644
693
|
groupId: z6.string().uuid().describe("Policy group ID"),
|
|
@@ -652,6 +701,7 @@ function registerDeployTools(server, callApi) {
|
|
|
652
701
|
"lexq_deploy_live",
|
|
653
702
|
{
|
|
654
703
|
title: "Deploy to Live",
|
|
704
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
655
705
|
description: "Deploy an ACTIVE (published) version to live traffic. Takes effect immediately. Versions whose effective start date has not arrived are rejected (P-037) \u2014 use lexq_deploy_schedule for those. Undefined facts do not block deployment (INV-4); use lexq_facts_unregistered to review what the version references but has not defined.",
|
|
656
706
|
inputSchema: z6.object({
|
|
657
707
|
groupId: z6.string().uuid().describe("Policy group ID"),
|
|
@@ -667,6 +717,7 @@ function registerDeployTools(server, callApi) {
|
|
|
667
717
|
"lexq_deploy_rollback",
|
|
668
718
|
{
|
|
669
719
|
title: "Rollback Deployment",
|
|
720
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
670
721
|
description: "Rollback to the previous deployed version. Only available if there is a previous version.",
|
|
671
722
|
inputSchema: z6.object({
|
|
672
723
|
groupId: z6.string().uuid().describe("Policy group ID"),
|
|
@@ -681,6 +732,7 @@ function registerDeployTools(server, callApi) {
|
|
|
681
732
|
"lexq_deploy_undeploy",
|
|
682
733
|
{
|
|
683
734
|
title: "Undeploy",
|
|
735
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
684
736
|
description: "Remove the live version from traffic. The version stays ACTIVE but no longer serves requests.",
|
|
685
737
|
inputSchema: z6.object({
|
|
686
738
|
groupId: z6.string().uuid().describe("Policy group ID"),
|
|
@@ -695,6 +747,7 @@ function registerDeployTools(server, callApi) {
|
|
|
695
747
|
"lexq_deploy_schedule",
|
|
696
748
|
{
|
|
697
749
|
title: "Schedule Deployment",
|
|
750
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
698
751
|
description: "Schedule an ACTIVE version with a future effective start date to auto-deploy at that time (Scheduled Deployment). One pending schedule per group; manual deploy/rollback/undeploy, starting an A/B test, or archiving the group cancels it. The snapshot hash is sealed at scheduling and re-verified at execution (fail-closed).",
|
|
699
752
|
inputSchema: z6.object({
|
|
700
753
|
groupId: z6.string().uuid().describe("Policy group ID"),
|
|
@@ -710,6 +763,7 @@ function registerDeployTools(server, callApi) {
|
|
|
710
763
|
"lexq_deploy_unschedule",
|
|
711
764
|
{
|
|
712
765
|
title: "Cancel Scheduled Deployment",
|
|
766
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
713
767
|
description: "Cancel the pending scheduled deployment for a group. The version itself is not affected. Fails with P-039 if no pending schedule exists.",
|
|
714
768
|
inputSchema: z6.object({
|
|
715
769
|
groupId: z6.string().uuid().describe("Policy group ID")
|
|
@@ -721,6 +775,7 @@ function registerDeployTools(server, callApi) {
|
|
|
721
775
|
"lexq_deploy_schedules",
|
|
722
776
|
{
|
|
723
777
|
title: "List Scheduled Deployments",
|
|
778
|
+
annotations: { readOnlyHint: true },
|
|
724
779
|
description: "List scheduled deployments across all groups (all statuses: PENDING, EXECUTED, CANCELED, FAILED), newest first.",
|
|
725
780
|
inputSchema: z6.object({
|
|
726
781
|
page: z6.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -733,6 +788,7 @@ function registerDeployTools(server, callApi) {
|
|
|
733
788
|
"lexq_deploy_history",
|
|
734
789
|
{
|
|
735
790
|
title: "Deployment History",
|
|
791
|
+
annotations: { readOnlyHint: true },
|
|
736
792
|
description: "List deployment history across all groups.",
|
|
737
793
|
inputSchema: z6.object({
|
|
738
794
|
page: z6.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -756,6 +812,7 @@ function registerDeployTools(server, callApi) {
|
|
|
756
812
|
"lexq_deploy_detail",
|
|
757
813
|
{
|
|
758
814
|
title: "Deployment Detail",
|
|
815
|
+
annotations: { readOnlyHint: true },
|
|
759
816
|
description: "Get detailed info about a specific deployment including snapshot hash and integrity check.",
|
|
760
817
|
inputSchema: z6.object({
|
|
761
818
|
deploymentId: z6.string().uuid().describe("Deployment ID")
|
|
@@ -767,6 +824,7 @@ function registerDeployTools(server, callApi) {
|
|
|
767
824
|
"lexq_deploy_overview",
|
|
768
825
|
{
|
|
769
826
|
title: "Deployment Overview",
|
|
827
|
+
annotations: { readOnlyHint: true },
|
|
770
828
|
description: "Show current deployment status of all groups \u2014 which version is live, last deployment type, and deployer.",
|
|
771
829
|
inputSchema: z6.object({})
|
|
772
830
|
},
|
|
@@ -776,6 +834,7 @@ function registerDeployTools(server, callApi) {
|
|
|
776
834
|
"lexq_deploy_deployable",
|
|
777
835
|
{
|
|
778
836
|
title: "List Deployable Versions",
|
|
837
|
+
annotations: { readOnlyHint: true },
|
|
779
838
|
description: "List ACTIVE (published) versions that can be deployed for a group. Use this to find which versions are available before calling deploy live.",
|
|
780
839
|
inputSchema: z6.object({
|
|
781
840
|
groupId: z6.string().uuid().describe("Policy group ID")
|
|
@@ -787,6 +846,7 @@ function registerDeployTools(server, callApi) {
|
|
|
787
846
|
"lexq_deploy_diff",
|
|
788
847
|
{
|
|
789
848
|
title: "Deployment Diff",
|
|
849
|
+
annotations: { readOnlyHint: true },
|
|
790
850
|
description: "Compare rule snapshots between two versions. Shows added, removed, and modified rules. Useful for reviewing changes before deploying a new version.",
|
|
791
851
|
inputSchema: z6.object({
|
|
792
852
|
baseVersionId: z6.string().uuid().describe("Base version ID (typically the current live)"),
|
|
@@ -807,6 +867,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
807
867
|
"lexq_dry_run",
|
|
808
868
|
{
|
|
809
869
|
title: "Dry Run",
|
|
870
|
+
annotations: { readOnlyHint: true },
|
|
810
871
|
description: dedent2`
|
|
811
872
|
Execute a single dry run against a version. Tests how rules evaluate given input facts without side effects.
|
|
812
873
|
|
|
@@ -836,6 +897,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
836
897
|
"lexq_dry_run_compare",
|
|
837
898
|
{
|
|
838
899
|
title: "Dry Run Compare",
|
|
900
|
+
annotations: { readOnlyHint: true },
|
|
839
901
|
description: dedent2`
|
|
840
902
|
Compare dry run results between two versions using the same input facts. Useful for validating changes.
|
|
841
903
|
|
|
@@ -860,6 +922,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
860
922
|
"lexq_requirements",
|
|
861
923
|
{
|
|
862
924
|
title: "Analyze Requirements",
|
|
925
|
+
annotations: { readOnlyHint: true },
|
|
863
926
|
description: "Analyze which input facts a version requires. Returns required keys, types, and an example request body.",
|
|
864
927
|
inputSchema: z7.object({
|
|
865
928
|
groupId: z7.string().uuid().describe("Policy group ID"),
|
|
@@ -872,6 +935,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
872
935
|
"lexq_simulation_start",
|
|
873
936
|
{
|
|
874
937
|
title: "Start Simulation",
|
|
938
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
875
939
|
description: dedent2`
|
|
876
940
|
Start an Impact Simulation against historical, uploaded, or inline data.
|
|
877
941
|
|
|
@@ -913,6 +977,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
913
977
|
"lexq_simulation_status",
|
|
914
978
|
{
|
|
915
979
|
title: "Simulation Status",
|
|
980
|
+
annotations: { readOnlyHint: true },
|
|
916
981
|
description: "Get simulation status and results. Poll until status is COMPLETED or FAILED.",
|
|
917
982
|
inputSchema: z7.object({
|
|
918
983
|
simulationId: z7.string().uuid().describe("Simulation ID")
|
|
@@ -924,6 +989,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
924
989
|
"lexq_simulation_list",
|
|
925
990
|
{
|
|
926
991
|
title: "List Simulations",
|
|
992
|
+
annotations: { readOnlyHint: true },
|
|
927
993
|
description: "List simulation history with optional filters.",
|
|
928
994
|
inputSchema: z7.object({
|
|
929
995
|
page: z7.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -945,6 +1011,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
945
1011
|
"lexq_simulation_cancel",
|
|
946
1012
|
{
|
|
947
1013
|
title: "Cancel Simulation",
|
|
1014
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
948
1015
|
description: "Cancel a running or pending simulation.",
|
|
949
1016
|
inputSchema: z7.object({
|
|
950
1017
|
simulationId: z7.string().uuid().describe("Simulation ID")
|
|
@@ -956,6 +1023,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
956
1023
|
"lexq_simulation_export",
|
|
957
1024
|
{
|
|
958
1025
|
title: "Export Simulation",
|
|
1026
|
+
annotations: { readOnlyHint: true },
|
|
959
1027
|
description: "Export simulation results as JSON or CSV. Returns the raw data.",
|
|
960
1028
|
inputSchema: z7.object({
|
|
961
1029
|
simulationId: z7.string().uuid().describe("Simulation ID"),
|
|
@@ -970,6 +1038,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
970
1038
|
"lexq_dataset_upload",
|
|
971
1039
|
{
|
|
972
1040
|
title: "Upload Dataset",
|
|
1041
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
973
1042
|
description: dedent2`
|
|
974
1043
|
Upload inline CSV or JSON content as a simulation dataset.
|
|
975
1044
|
The content is uploaded to S3 and a path is returned in the "path" field.
|
|
@@ -1013,6 +1082,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
1013
1082
|
"lexq_dataset_template",
|
|
1014
1083
|
{
|
|
1015
1084
|
title: "Download Dataset Template",
|
|
1085
|
+
annotations: { readOnlyHint: true },
|
|
1016
1086
|
description: "Generate a sample CSV or JSON template based on the required facts of a version. Use this to understand the expected data format before uploading a dataset.",
|
|
1017
1087
|
inputSchema: z7.object({
|
|
1018
1088
|
groupId: z7.string().uuid().describe("Policy group ID"),
|
|
@@ -1042,6 +1112,7 @@ function registerProfileTools(server, callApi) {
|
|
|
1042
1112
|
"lexq_profile_overview",
|
|
1043
1113
|
{
|
|
1044
1114
|
title: "Group Latency Profile",
|
|
1115
|
+
annotations: { readOnlyHint: true },
|
|
1045
1116
|
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; a percentile is withheld (null) unless n\xD7(1\u2212q) \u2265 ${TAIL_MIN_OBS} (p50 needs n \u2265 6, p95 n \u2265 60, p99 n \u2265 300 \u2014 display gate, separate from the n \u2265 ${MIN_SAMPLES} judgment gate). Baselines report INSUFFICIENT_COHORT when fewer than ${MIN_COHORT_SIZE} rules qualify. Rule detail comes from a deterministic ${PROFILE_SAMPLE_PERMILLE / 10}% sample of calls; TOTAL is recorded for every call. Defaults: last ${PROFILE_DEFAULT_WINDOW_HOURS}h, live version, cacheState HIT.`,
|
|
1046
1117
|
inputSchema: z8.object({
|
|
1047
1118
|
groupId: z8.string().uuid().describe("Policy group ID"),
|
|
@@ -1061,6 +1132,7 @@ function registerProfileTools(server, callApi) {
|
|
|
1061
1132
|
"lexq_profile_rule",
|
|
1062
1133
|
{
|
|
1063
1134
|
title: "Rule Latency Detail",
|
|
1135
|
+
annotations: { readOnlyHint: true },
|
|
1064
1136
|
description: `Single-rule latency detail: merged phase \xD7 cacheState distributions plus a per-window time series (${LATENCY_WINDOW_MILLIS / 1e3}s windows). Missing windows are genuine gaps \u2014 never interpolated. Series points carry each window's own values; percentiles in merged distributions are withheld (null) unless n\xD7(1\u2212q) \u2265 ${TAIL_MIN_OBS} (p50 n \u2265 6, p95 n \u2265 60, p99 n \u2265 300). ` + RELATIVE_THRESHOLD,
|
|
1065
1137
|
inputSchema: z8.object({
|
|
1066
1138
|
groupId: z8.string().uuid().describe("Policy group ID"),
|
|
@@ -1085,6 +1157,7 @@ function registerReplayTools(server, callApi) {
|
|
|
1085
1157
|
"lexq_replay_decision",
|
|
1086
1158
|
{
|
|
1087
1159
|
title: "Replay a Decision",
|
|
1160
|
+
annotations: { readOnlyHint: true },
|
|
1088
1161
|
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). A replay sends no webhook, notification, or event: rule actions produce no outward effects.",
|
|
1089
1162
|
inputSchema: z9.object({
|
|
1090
1163
|
traceId: z9.string().describe("Trace ID of the past execution to replay"),
|
|
@@ -1097,6 +1170,7 @@ function registerReplayTools(server, callApi) {
|
|
|
1097
1170
|
"lexq_replay_start",
|
|
1098
1171
|
{
|
|
1099
1172
|
title: "Start Window Replay (Blast Radius)",
|
|
1173
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
1100
1174
|
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.",
|
|
1101
1175
|
inputSchema: z9.object({
|
|
1102
1176
|
candidateVersionId: z9.string().uuid().describe("Version to re-evaluate against"),
|
|
@@ -1113,6 +1187,7 @@ function registerReplayTools(server, callApi) {
|
|
|
1113
1187
|
"lexq_replay_status",
|
|
1114
1188
|
{
|
|
1115
1189
|
title: "Get Replay Job Status",
|
|
1190
|
+
annotations: { readOnlyHint: true },
|
|
1116
1191
|
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.",
|
|
1117
1192
|
inputSchema: z9.object({
|
|
1118
1193
|
jobId: z9.string().describe("Replay job ID from lexq_replay_start")
|
|
@@ -1124,6 +1199,7 @@ function registerReplayTools(server, callApi) {
|
|
|
1124
1199
|
"lexq_replay_list",
|
|
1125
1200
|
{
|
|
1126
1201
|
title: "List Replay Jobs",
|
|
1202
|
+
annotations: { readOnlyHint: true },
|
|
1127
1203
|
description: "List window replay job history (reverse-chronological). Lightweight items \u2014 use lexq_replay_status for summary and changed samples.",
|
|
1128
1204
|
inputSchema: z9.object({
|
|
1129
1205
|
page: z9.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -1136,6 +1212,7 @@ function registerReplayTools(server, callApi) {
|
|
|
1136
1212
|
"lexq_replay_cancel",
|
|
1137
1213
|
{
|
|
1138
1214
|
title: "Cancel Replay Job",
|
|
1215
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
1139
1216
|
description: "Cooperatively cancel a PENDING or RUNNING window replay job. Other states are rejected. VIEWER role cannot cancel.",
|
|
1140
1217
|
inputSchema: z9.object({
|
|
1141
1218
|
jobId: z9.string().describe("Replay job ID")
|
|
@@ -1147,6 +1224,7 @@ function registerReplayTools(server, callApi) {
|
|
|
1147
1224
|
"lexq_replay_export",
|
|
1148
1225
|
{
|
|
1149
1226
|
title: "Export Replay Result",
|
|
1227
|
+
annotations: { readOnlyHint: true },
|
|
1150
1228
|
description: "Export a COMPLETED window replay job. A running job is rejected \u2014 a partial result reads as the whole thing on the receiving end. The two formats carry different things: CSV holds the effect blast radius, whose columns are fixed; JSON holds the changed samples and action parameters, which nest and whose keys differ per tenant. JSON is not a superset of CSV. Returns the file contents as text.",
|
|
1151
1229
|
inputSchema: z9.object({
|
|
1152
1230
|
jobId: z9.string().describe("Replay job ID"),
|
|
@@ -1164,6 +1242,7 @@ function registerHistoryTools(server, callApi) {
|
|
|
1164
1242
|
"lexq_history_list",
|
|
1165
1243
|
{
|
|
1166
1244
|
title: "List Execution History",
|
|
1245
|
+
annotations: { readOnlyHint: true },
|
|
1167
1246
|
description: "List policy execution history. Shows trace ID, group, version, status, match result, and latency.",
|
|
1168
1247
|
inputSchema: z10.object({
|
|
1169
1248
|
page: z10.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -1191,6 +1270,7 @@ function registerHistoryTools(server, callApi) {
|
|
|
1191
1270
|
"lexq_history_get",
|
|
1192
1271
|
{
|
|
1193
1272
|
title: "Get Execution Detail",
|
|
1273
|
+
annotations: { readOnlyHint: true },
|
|
1194
1274
|
description: "Get full execution detail including inputFacts, mutatedFacts, generatedVariables, executionTraces, and decisionTraces.",
|
|
1195
1275
|
inputSchema: z10.object({
|
|
1196
1276
|
traceId: z10.string().describe("Trace ID from execution history")
|
|
@@ -1202,6 +1282,7 @@ function registerHistoryTools(server, callApi) {
|
|
|
1202
1282
|
"lexq_history_stats",
|
|
1203
1283
|
{
|
|
1204
1284
|
title: "Execution Statistics",
|
|
1285
|
+
annotations: { readOnlyHint: true },
|
|
1205
1286
|
description: "Get execution KPIs: total executions, success/failure counts, success rate, and average latency.",
|
|
1206
1287
|
inputSchema: z10.object({
|
|
1207
1288
|
groupId: z10.string().uuid().optional().describe("Filter by policy group"),
|
|
@@ -1226,6 +1307,7 @@ function registerProvenanceTools(server, callApi) {
|
|
|
1226
1307
|
"lexq_provenance_get",
|
|
1227
1308
|
{
|
|
1228
1309
|
title: "Get Decision Provenance",
|
|
1310
|
+
annotations: { readOnlyHint: true },
|
|
1229
1311
|
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.",
|
|
1230
1312
|
inputSchema: z11.object({
|
|
1231
1313
|
traceId: z11.string().describe("Trace ID of the execution")
|
|
@@ -1237,6 +1319,7 @@ function registerProvenanceTools(server, callApi) {
|
|
|
1237
1319
|
"lexq_pii_reveals_list",
|
|
1238
1320
|
{
|
|
1239
1321
|
title: "List PII Reveal Audits",
|
|
1322
|
+
annotations: { readOnlyHint: true },
|
|
1240
1323
|
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.",
|
|
1241
1324
|
inputSchema: z11.object({
|
|
1242
1325
|
page: z11.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -1267,6 +1350,7 @@ function registerLogTools(server, callApi) {
|
|
|
1267
1350
|
"lexq_logs_list",
|
|
1268
1351
|
{
|
|
1269
1352
|
title: "List Failure Logs",
|
|
1353
|
+
annotations: { readOnlyHint: true },
|
|
1270
1354
|
description: "List system failure logs from background tasks (platform event webhooks, scheduled deployments).",
|
|
1271
1355
|
inputSchema: z12.object({
|
|
1272
1356
|
page: z12.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -1292,6 +1376,7 @@ function registerLogTools(server, callApi) {
|
|
|
1292
1376
|
"lexq_logs_get",
|
|
1293
1377
|
{
|
|
1294
1378
|
title: "Get Failure Log",
|
|
1379
|
+
annotations: { readOnlyHint: true },
|
|
1295
1380
|
description: "Get failure log detail by ID.",
|
|
1296
1381
|
inputSchema: z12.object({
|
|
1297
1382
|
logId: z12.string().uuid().describe("Failure log ID")
|
|
@@ -1303,6 +1388,7 @@ function registerLogTools(server, callApi) {
|
|
|
1303
1388
|
"lexq_logs_action",
|
|
1304
1389
|
{
|
|
1305
1390
|
title: "Process Failure Log",
|
|
1391
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
1306
1392
|
description: "Process a single failure log: RESOLVE (mark as manually fixed) or IGNORE (skip intentionally).",
|
|
1307
1393
|
inputSchema: z12.object({
|
|
1308
1394
|
logId: z12.string().uuid().describe("Failure log ID"),
|
|
@@ -1317,6 +1403,7 @@ function registerLogTools(server, callApi) {
|
|
|
1317
1403
|
"lexq_logs_bulk_action",
|
|
1318
1404
|
{
|
|
1319
1405
|
title: "Bulk Process Failure Logs",
|
|
1406
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
1320
1407
|
description: "Process multiple failure logs at once. Provide an array of log IDs and the action.",
|
|
1321
1408
|
inputSchema: z12.object({
|
|
1322
1409
|
logIds: z12.array(z12.string().uuid()).describe("Array of failure log IDs"),
|
|
@@ -1336,6 +1423,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
|
|
|
1336
1423
|
"lexq_webhook_subscriptions_list",
|
|
1337
1424
|
{
|
|
1338
1425
|
title: "List Webhook Subscriptions",
|
|
1426
|
+
annotations: { readOnlyHint: true },
|
|
1339
1427
|
description: "List platform event webhook subscriptions. These receive deployment lifecycle notifications (publish, deploy, rollback, undeploy).",
|
|
1340
1428
|
inputSchema: z13.object({
|
|
1341
1429
|
page: z13.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -1351,6 +1439,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
|
|
|
1351
1439
|
"lexq_webhook_subscriptions_get",
|
|
1352
1440
|
{
|
|
1353
1441
|
title: "Get Webhook Subscription",
|
|
1442
|
+
annotations: { readOnlyHint: true },
|
|
1354
1443
|
description: "Get webhook subscription detail by ID.",
|
|
1355
1444
|
inputSchema: z13.object({
|
|
1356
1445
|
id: z13.string().uuid().describe("Webhook subscription ID")
|
|
@@ -1362,6 +1451,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
|
|
|
1362
1451
|
"lexq_webhook_subscriptions_save",
|
|
1363
1452
|
{
|
|
1364
1453
|
title: "Save Webhook Subscription",
|
|
1454
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
1365
1455
|
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": "..."}).',
|
|
1366
1456
|
inputSchema: z13.object({
|
|
1367
1457
|
id: z13.string().uuid().optional().describe("Subscription ID (omit to create, provide to update)"),
|
|
@@ -1379,6 +1469,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
|
|
|
1379
1469
|
"lexq_webhook_subscriptions_delete",
|
|
1380
1470
|
{
|
|
1381
1471
|
title: "Delete Webhook Subscription",
|
|
1472
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
1382
1473
|
description: "Delete a webhook subscription by ID.",
|
|
1383
1474
|
inputSchema: z13.object({
|
|
1384
1475
|
id: z13.string().uuid().describe("Webhook subscription ID")
|
|
@@ -1390,6 +1481,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
|
|
|
1390
1481
|
"lexq_webhook_subscriptions_test",
|
|
1391
1482
|
{
|
|
1392
1483
|
title: "Test Webhook Subscription",
|
|
1484
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
1393
1485
|
description: "Send a test event to verify webhook connectivity. Returns the HTTP status code and success/failure message.",
|
|
1394
1486
|
inputSchema: z13.object({
|
|
1395
1487
|
id: z13.string().uuid().describe("Webhook subscription ID")
|
|
@@ -1406,6 +1498,7 @@ function registerDomainTemplateTools(server, callApi) {
|
|
|
1406
1498
|
"lexq_domain_templates_list",
|
|
1407
1499
|
{
|
|
1408
1500
|
title: "List Domain Templates",
|
|
1501
|
+
annotations: { readOnlyHint: true },
|
|
1409
1502
|
description: "List all domain templates. A domain template is a curated, industry-specific starter pack of fact definitions and sample rules (e.g. ECOMMERCE). Each entry reports its key, status (ACTIVE or COMING_SOON), and a summary of what it provisions. Call this before preview or apply to discover which templates can currently be applied.",
|
|
1410
1503
|
inputSchema: z14.object({})
|
|
1411
1504
|
},
|
|
@@ -1415,6 +1508,7 @@ function registerDomainTemplateTools(server, callApi) {
|
|
|
1415
1508
|
"lexq_domain_templates_preview",
|
|
1416
1509
|
{
|
|
1417
1510
|
title: "Preview Domain Template",
|
|
1511
|
+
annotations: { readOnlyHint: true },
|
|
1418
1512
|
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.",
|
|
1419
1513
|
inputSchema: z14.object({
|
|
1420
1514
|
template: z14.string().describe(
|
|
@@ -1428,6 +1522,7 @@ function registerDomainTemplateTools(server, callApi) {
|
|
|
1428
1522
|
"lexq_domain_templates_apply",
|
|
1429
1523
|
{
|
|
1430
1524
|
title: "Apply Domain Template",
|
|
1525
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
1431
1526
|
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.",
|
|
1432
1527
|
inputSchema: z14.object({
|
|
1433
1528
|
template: z14.string().describe("Domain template key to apply (e.g. ECOMMERCE)."),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lexq/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
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",
|
|
@@ -30,16 +30,18 @@
|
|
|
30
30
|
"typecheck": "tsc --noEmit",
|
|
31
31
|
"enums": "node scripts/gen-enums.mjs",
|
|
32
32
|
"enums:check": "node scripts/gen-enums.mjs --check",
|
|
33
|
-
"
|
|
33
|
+
"prose:check": "node scripts/check-prose-mirrors.mjs",
|
|
34
34
|
"surface:check": "node scripts/check-public-surface.mjs",
|
|
35
35
|
"ab-key:check": "node scripts/check-ab-key.mjs",
|
|
36
36
|
"registry:check": "node scripts/check-registry-manifest.mjs",
|
|
37
|
+
"protocol:check": "node scripts/check-protocol-revisions.mjs",
|
|
37
38
|
"schemas:check": "node scripts/check-tool-schemas.mjs",
|
|
38
39
|
"schemas:update": "node scripts/check-tool-schemas.mjs --update",
|
|
39
40
|
"start": "node dist/index.js",
|
|
40
41
|
"test:decimals": "pnpm build && node tests/exact-decimals.mjs",
|
|
41
42
|
"test:fact-key": "node tests/fact-key.mjs",
|
|
42
43
|
"test:export-format": "node tests/export-format.mjs",
|
|
44
|
+
"test:value-domain": "pnpm build && node tests/value-domain.mjs",
|
|
43
45
|
"prepublishOnly": "pnpm build",
|
|
44
46
|
"knip": "knip",
|
|
45
47
|
"format": "prettier --write \"src/**/*.ts\"",
|