@lexq/cli 0.1.23 → 0.1.25

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
@@ -3910,6 +3910,51 @@ function registerWebhookSubscriptionTools(server, callApi) {
3910
3910
  );
3911
3911
  }
3912
3912
 
3913
+ // src/mcp/tools/domain-templates.ts
3914
+ import { z as z11 } from "zod";
3915
+ function registerDomainTemplateTools(server, callApi) {
3916
+ server.registerTool(
3917
+ "lexq_domain_templates_list",
3918
+ {
3919
+ title: "List Domain Templates",
3920
+ 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.",
3921
+ inputSchema: {}
3922
+ },
3923
+ async () => callApi("GET", "domain-templates")
3924
+ );
3925
+ server.registerTool(
3926
+ "lexq_domain_templates_preview",
3927
+ {
3928
+ title: "Preview Domain Template",
3929
+ 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.",
3930
+ inputSchema: {
3931
+ template: z11.string().describe(
3932
+ "Domain template key (e.g. ECOMMERCE). Use lexq_domain_templates_list to see available keys \u2014 currently only ECOMMERCE is ACTIVE."
3933
+ )
3934
+ }
3935
+ },
3936
+ async ({ template }) => callApi("GET", `domain-templates/${template}/preview`)
3937
+ );
3938
+ server.registerTool(
3939
+ "lexq_domain_templates_apply",
3940
+ {
3941
+ title: "Apply Domain Template",
3942
+ 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.",
3943
+ inputSchema: {
3944
+ template: z11.string().describe("Domain template key to apply (e.g. ECOMMERCE)."),
3945
+ customName: z11.string().optional().describe(
3946
+ "Optional custom name for the policy group that gets created. If omitted, the template's default name is used."
3947
+ )
3948
+ }
3949
+ },
3950
+ async ({ template, customName }) => {
3951
+ const body = {};
3952
+ if (customName !== void 0) body.customName = customName;
3953
+ return callApi("POST", `domain-templates/${template}/apply`, { body });
3954
+ }
3955
+ );
3956
+ }
3957
+
3913
3958
  // src/mcp/register.ts
3914
3959
  function registerAllTools(server, callApi) {
3915
3960
  registerStatusTools(server, callApi);
@@ -3922,6 +3967,7 @@ function registerAllTools(server, callApi) {
3922
3967
  registerHistoryTools(server, callApi);
3923
3968
  registerIntegrationTools(server, callApi);
3924
3969
  registerLogTools(server, callApi);
3970
+ registerDomainTemplateTools(server, callApi);
3925
3971
  registerWebhookSubscriptionTools(server, callApi);
3926
3972
  }
3927
3973
 
@@ -3979,6 +4025,137 @@ function registerServeCommand(program) {
3979
4025
  });
3980
4026
  }
3981
4027
 
4028
+ // src/commands/domain-templates.ts
4029
+ import "commander";
4030
+ import dedent16 from "dedent";
4031
+ function registerDomainTemplateCommands(program) {
4032
+ const templates = program.command("domain-templates").description("Browse and apply domain templates").addHelpText(
4033
+ "after",
4034
+ dedent16`
4035
+
4036
+ A domain template is an industry-specific starter pack of fact
4037
+ definitions and sample rules. Applying one provisions a ready-to-use
4038
+ policy group so you start from a working baseline instead of an
4039
+ empty schema.
4040
+
4041
+ Commands:
4042
+ list List available domain templates
4043
+ preview Preview the facts and rules a template provisions
4044
+ apply Apply a template to the current tenant
4045
+
4046
+ Workflow: list → preview → apply
4047
+ Currently available: ECOMMERCE (FINTECH, SAAS — coming soon)
4048
+ `
4049
+ );
4050
+ templates.command("list").description("List available domain templates").action(async () => {
4051
+ try {
4052
+ const globalOpts = program.opts();
4053
+ const format = globalOpts.format ?? "json";
4054
+ const data = await apiRequest("GET", "domain-templates", {
4055
+ apiKey: globalOpts.apiKey,
4056
+ baseUrl: globalOpts.baseUrl,
4057
+ dryRun: globalOpts.dryRun,
4058
+ verbose: globalOpts.verbose
4059
+ });
4060
+ if (format === "table") {
4061
+ printTable(
4062
+ ["Template", "Name", "Facts", "Rules", "Available"],
4063
+ data.map((t) => [
4064
+ t.template,
4065
+ t.displayName,
4066
+ String(t.factCount),
4067
+ String(t.ruleCount),
4068
+ t.isAvailable ? "\u2713" : "\u2013"
4069
+ ]),
4070
+ { truncate: 32 }
4071
+ );
4072
+ } else {
4073
+ printJson(data);
4074
+ }
4075
+ } catch (error) {
4076
+ printError(error);
4077
+ process.exit(1);
4078
+ }
4079
+ });
4080
+ templates.command("preview").description("Preview what a domain template provisions").requiredOption("--template <key>", "Domain template key (e.g. ECOMMERCE)").addHelpText(
4081
+ "after",
4082
+ dedent16`
4083
+
4084
+ Read-only dry run — shows the fact definitions and sample rules the
4085
+ template will create. Nothing is provisioned.
4086
+
4087
+ Example:
4088
+ $ lexq domain-templates preview --template ECOMMERCE
4089
+ `
4090
+ ).action(async (opts) => {
4091
+ try {
4092
+ const globalOpts = program.opts();
4093
+ const data = await apiRequest(
4094
+ "GET",
4095
+ `domain-templates/${opts.template}/preview`,
4096
+ {
4097
+ apiKey: globalOpts.apiKey,
4098
+ baseUrl: globalOpts.baseUrl,
4099
+ dryRun: globalOpts.dryRun,
4100
+ verbose: globalOpts.verbose
4101
+ }
4102
+ );
4103
+ printJson(data);
4104
+ } catch (error) {
4105
+ printError(error);
4106
+ process.exit(1);
4107
+ }
4108
+ });
4109
+ templates.command("apply").description("Apply a domain template to the current tenant").requiredOption("--template <key>", "Domain template key (e.g. ECOMMERCE)").option("--name <n>", "Custom name for the policy group that gets created").option("--force", "Skip confirmation prompt").addHelpText(
4110
+ "after",
4111
+ dedent16`
4112
+
4113
+ Creates the template's fact definitions and a new DRAFT policy group
4114
+ populated with its sample rules. Existing facts are skipped — apply is
4115
+ additive and never overwrites your schema.
4116
+
4117
+ Run "preview" first to review what will be created.
4118
+
4119
+ Example:
4120
+ $ lexq domain-templates apply --template ECOMMERCE
4121
+ $ lexq domain-templates apply --template ECOMMERCE --name "My Store Policy"
4122
+ `
4123
+ ).action(async (opts) => {
4124
+ try {
4125
+ const globalOpts = program.opts();
4126
+ if (!opts.force) {
4127
+ const { createInterface: createInterface2 } = await import("readline/promises");
4128
+ const rl = createInterface2({ input: process.stdin, output: process.stdout });
4129
+ const answer = await rl.question(
4130
+ `Apply domain template ${opts.template} to the current tenant? [y/N] `
4131
+ );
4132
+ rl.close();
4133
+ if (answer.toLowerCase() !== "y") {
4134
+ console.log("Cancelled.");
4135
+ return;
4136
+ }
4137
+ }
4138
+ const body = {};
4139
+ if (opts.name) body.customName = opts.name;
4140
+ const data = await apiRequest(
4141
+ "POST",
4142
+ `domain-templates/${opts.template}/apply`,
4143
+ {
4144
+ apiKey: globalOpts.apiKey,
4145
+ baseUrl: globalOpts.baseUrl,
4146
+ dryRun: globalOpts.dryRun,
4147
+ verbose: globalOpts.verbose,
4148
+ body
4149
+ }
4150
+ );
4151
+ printJson(data);
4152
+ } catch (error) {
4153
+ printError(error);
4154
+ process.exit(1);
4155
+ }
4156
+ });
4157
+ }
4158
+
3982
4159
  // src/cli.ts
3983
4160
  var __dirname2 = dirname2(fileURLToPath2(import.meta.url));
3984
4161
  function getVersion2() {
@@ -4000,6 +4177,7 @@ function createCli() {
4000
4177
  registerVersionCommands(program);
4001
4178
  registerRuleCommands(program);
4002
4179
  registerFactCommands(program);
4180
+ registerDomainTemplateCommands(program);
4003
4181
  registerDeployCommands(program);
4004
4182
  registerAnalyticsCommands(program);
4005
4183
  registerHistoryCommands(program);
@@ -27,7 +27,7 @@ type CallApi = (method: string, path: string, opts?: {
27
27
  declare function paginationParams(page?: number, size?: number): Record<string, string>;
28
28
 
29
29
  /**
30
- * Registers all 63 MCP tools on the given server.
30
+ * Registers all 66 MCP tools on the given server.
31
31
  *
32
32
  * @param server - McpServer instance
33
33
  * @param callApi - API caller function (config-based for CLI, Bearer-based for HTTP)
@@ -1109,6 +1109,51 @@ function registerWebhookSubscriptionTools(server, callApi) {
1109
1109
  );
1110
1110
  }
1111
1111
 
1112
+ // src/mcp/tools/domain-templates.ts
1113
+ import { z as z11 } from "zod";
1114
+ function registerDomainTemplateTools(server, callApi) {
1115
+ server.registerTool(
1116
+ "lexq_domain_templates_list",
1117
+ {
1118
+ title: "List Domain Templates",
1119
+ 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.",
1120
+ inputSchema: {}
1121
+ },
1122
+ async () => callApi("GET", "domain-templates")
1123
+ );
1124
+ server.registerTool(
1125
+ "lexq_domain_templates_preview",
1126
+ {
1127
+ title: "Preview Domain Template",
1128
+ 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.",
1129
+ inputSchema: {
1130
+ template: z11.string().describe(
1131
+ "Domain template key (e.g. ECOMMERCE). Use lexq_domain_templates_list to see available keys \u2014 currently only ECOMMERCE is ACTIVE."
1132
+ )
1133
+ }
1134
+ },
1135
+ async ({ template }) => callApi("GET", `domain-templates/${template}/preview`)
1136
+ );
1137
+ server.registerTool(
1138
+ "lexq_domain_templates_apply",
1139
+ {
1140
+ title: "Apply Domain Template",
1141
+ 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.",
1142
+ inputSchema: {
1143
+ template: z11.string().describe("Domain template key to apply (e.g. ECOMMERCE)."),
1144
+ customName: z11.string().optional().describe(
1145
+ "Optional custom name for the policy group that gets created. If omitted, the template's default name is used."
1146
+ )
1147
+ }
1148
+ },
1149
+ async ({ template, customName }) => {
1150
+ const body = {};
1151
+ if (customName !== void 0) body.customName = customName;
1152
+ return callApi("POST", `domain-templates/${template}/apply`, { body });
1153
+ }
1154
+ );
1155
+ }
1156
+
1112
1157
  // src/mcp/register.ts
1113
1158
  function registerAllTools(server, callApi) {
1114
1159
  registerStatusTools(server, callApi);
@@ -1121,6 +1166,7 @@ function registerAllTools(server, callApi) {
1121
1166
  registerHistoryTools(server, callApi);
1122
1167
  registerIntegrationTools(server, callApi);
1123
1168
  registerLogTools(server, callApi);
1169
+ registerDomainTemplateTools(server, callApi);
1124
1170
  registerWebhookSubscriptionTools(server, callApi);
1125
1171
  }
1126
1172
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lexq/cli",
3
- "version": "0.1.23",
3
+ "version": "0.1.25",
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": {
@@ -23,6 +23,14 @@
23
23
  "publishConfig": {
24
24
  "access": "public"
25
25
  },
26
+ "scripts": {
27
+ "dev": "tsup --watch",
28
+ "build": "tsup",
29
+ "lint": "eslint src/",
30
+ "typecheck": "tsc --noEmit",
31
+ "start": "node dist/index.js",
32
+ "prepublishOnly": "pnpm build"
33
+ },
26
34
  "keywords": [
27
35
  "lexq",
28
36
  "rule-engine",
@@ -43,6 +51,7 @@
43
51
  "engines": {
44
52
  "node": ">=18.0.0"
45
53
  },
54
+ "packageManager": "pnpm@10.28.0",
46
55
  "dependencies": {
47
56
  "@modelcontextprotocol/sdk": "^1.28.0",
48
57
  "cli-table3": "^0.6.5",
@@ -60,12 +69,5 @@
60
69
  "tsup": "^8.5.1",
61
70
  "typescript": "^5.7.0",
62
71
  "typescript-eslint": "^8.24.0"
63
- },
64
- "scripts": {
65
- "dev": "tsup --watch",
66
- "build": "tsup",
67
- "lint": "eslint src/",
68
- "typecheck": "tsc --noEmit",
69
- "start": "node dist/index.js"
70
72
  }
71
- }
73
+ }