@lexq/cli 0.1.19 → 0.1.20

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 CHANGED
@@ -1,13 +1,34 @@
1
1
  # LexQ CLI
2
2
 
3
- > CLI and MCP server for [LexQ](https://lexq.io) — a rule engine with built-in simulation.
4
- > Manage policies, simulate rules, and deploy from the terminal. Built for humans and AI agents.
3
+ > **The decision platform for engineering teams.**
4
+ > CLI and MCP server for [LexQ](https://lexq.io) move business rules out of
5
+ > your deploy pipeline, prove every change with simulation, and ship without
6
+ > a git push.
5
7
 
6
8
  **[Website](https://lexq.io)** · **[Docs](https://docs.lexq.io)** · **[Console](https://console.lexq.io)**
7
9
 
8
10
  [![npm](https://img.shields.io/npm/v/@lexq/cli)](https://www.npmjs.com/package/@lexq/cli)
9
11
  [![License](https://img.shields.io/github/license/lexq-io/lexq-cli)](LICENSE)
10
12
 
13
+ ---
14
+
15
+ ## Why LexQ?
16
+
17
+ Your business rules — pricing, promotions, fee logic, eligibility checks —
18
+ change often. But every change ships through the same PR → review → staging
19
+ → deploy cycle as your core application code. A one-line discount rule
20
+ takes two weeks.
21
+
22
+ This is an architectural problem, not a process problem. Business logic
23
+ that changes weekly shouldn't live in code that ships quarterly.
24
+
25
+ **LexQ separates the two.** Rules live outside your application. You change
26
+ them in a visual console or through this CLI. You prove every change with
27
+ batch simulation against real execution data. You deploy without touching
28
+ your codebase.
29
+
30
+ Every decision leaves a full audit trace.
31
+
11
32
  ## Install
12
33
 
13
34
  ```bash
@@ -55,7 +76,7 @@ lexq rules create --group-id <GROUP_ID> --version-id <VERSION_ID> --json '{
55
76
  }]
56
77
  }'
57
78
 
58
- # 6. Test
79
+ # 6. Test against your data before shipping
59
80
  lexq analytics dry-run --version-id <VERSION_ID> --debug --mock \
60
81
  --json '{"facts":{"customer_tier":"VIP","payment_amount":100000}}'
61
82
 
@@ -64,106 +85,16 @@ lexq deploy publish --group-id <GROUP_ID> --version-id <VERSION_ID> --memo "v1"
64
85
  lexq deploy live --group-id <GROUP_ID> --version-id <VERSION_ID> --memo "Initial deploy"
65
86
  ```
66
87
 
67
- ## Commands
68
-
69
- ```
70
- lexq auth login | logout | whoami
71
- lexq status API health check
72
- lexq serve Run as MCP stdio server (--mcp)
73
- lexq groups list | get | create | update | delete
74
- lexq groups ab-test start | stop | adjust
75
- lexq versions list | get | create | update | delete | clone
76
- lexq rules list | get | create | update | delete | reorder | toggle
77
- lexq facts list | create | update | delete | action-metadata
78
- lexq deploy publish | live | rollback | undeploy | history | detail | overview | deployable | diff
79
- lexq analytics dry-run | dry-run-compare | requirements
80
- lexq analytics simulation start | status | list | cancel | export
81
- lexq analytics dataset upload | template
82
- lexq history list | get | stats
83
- lexq integrations list | get | save | delete | config-spec
84
- lexq logs list | get | action | bulk-action
85
- lexq webhook-subscriptions list | get | save | delete | test
86
- ```
87
-
88
- ## Global Options
89
-
90
- | Flag | Description |
91
- |--------------------------|--------------------------------------------|
92
- | `--format <json\|table>` | Output format (default: `json`) |
93
- | `--api-key <key>` | Override stored API key |
94
- | `--base-url <url>` | Override API base URL |
95
- | `--dry-run` | Preview the HTTP request without executing |
96
- | `--verbose` | Show request/response details |
97
- | `--no-color` | Disable colored output |
98
-
99
- ## AI Agent Skills
100
-
101
- LexQ CLI ships with **AI Agent Skills** — structured documentation that AI coding agents can read to autonomously manage
102
- policies.
103
-
104
- ```
105
- skills/
106
- ├── lexq-shared/SKILL.md Core concepts, auth, workflow
107
- ├── lexq-groups/SKILL.md Policy groups, conflict resolution, A/B testing
108
- ├── lexq-rules/SKILL.md Condition syntax, action types, mutex
109
- ├── lexq-simulation/SKILL.md Dry run, batch simulation, compare
110
- ├── lexq-execution/SKILL.md Execution history, stats, failure logs,
111
- │ integrations, webhook subscriptions
112
- └── lexq-recipes/SKILL.md End-to-end recipes
113
-
114
- .claude/CLAUDE.md Claude Code project context
115
- AGENTS.md Universal agent guide (Cursor, Windsurf, Gemini CLI, Cline)
116
- CONTEXT.md Platform architecture & glossary
117
- ```
118
-
119
- ### For AI Agent Developers
120
-
121
- Skills are included in the npm package. After installing `@lexq/cli`, agents can read skills from:
122
-
123
- ```
124
- node_modules/@lexq/cli/skills/
125
- node_modules/@lexq/cli/AGENTS.md
126
- node_modules/@lexq/cli/CONTEXT.md
127
- ```
128
-
129
- Or reference them directly in your project by copying the `skills/` directory.
130
-
131
- ## Configuration
132
-
133
- Config is stored at `~/.lexq/config.json`:
134
-
135
- ```json
136
- {
137
- "apiKey": "sk_live_xxxxxxxxxxxxx",
138
- "baseUrl": "https://api.lexq.io/api/v1/partners",
139
- "format": "json"
140
- }
141
- ```
142
-
143
- ## Development
88
+ ## For AI Agents — 63 MCP Tools
144
89
 
145
- ```bash
146
- git clone https://github.com/lexq-io/lexq-cli.git
147
- cd lexq-cli
148
- pnpm install
149
- pnpm build
150
- pnpm start -- groups list
151
- ```
152
-
153
- ```bash
154
- pnpm typecheck # Type check
155
- pnpm lint # ESLint
156
- bash tests/e2e.sh # CLI E2E tests (requires API key)
157
- bash tests/test-engine-api.sh # Engine API integration tests
158
- ```
159
-
160
- ## MCP Server Mode
161
-
162
- LexQ exposes **63 policy engine tools** via MCP. Two connection methods:
90
+ LexQ is designed to be AI-native. The entire policy engine API — all 63 tools
91
+ is exposed via Model Context Protocol. Claude, Cursor, and other MCP-compatible
92
+ agents can create, simulate, and deploy rules autonomously, with human approval
93
+ before production.
163
94
 
164
95
  ### Claude.ai (Cloud — no install)
165
96
 
166
- 1. Go to **Settings → Connectors → Add Custom Integration**
97
+ 1. **Settings → Connectors → Add Custom Integration**
167
98
  2. Enter: `https://mcp.lexq.io`
168
99
  3. Sign in with your LexQ account and select an API key
169
100
  4. Done — 63 tools available in every conversation
@@ -182,7 +113,7 @@ For any MCP client that supports remote servers:
182
113
  }
183
114
  ```
184
115
 
185
- OAuth 2.1 authentication is required. Your AI client will handle authorization automatically.
116
+ OAuth 2.1 authentication is handled automatically by your client.
186
117
 
187
118
  ### Local (stdio)
188
119
 
@@ -192,9 +123,7 @@ Run LexQ CLI as a local MCP server:
192
123
  lexq serve --mcp
193
124
  ```
194
125
 
195
- This starts a stdio MCP server exposing 63 tools — the full LexQ API — to any MCP-compatible client.
196
-
197
- ### Claude Desktop
126
+ #### Claude Desktop
198
127
 
199
128
  Add to `claude_desktop_config.json`:
200
129
 
@@ -214,7 +143,7 @@ Add to `claude_desktop_config.json`:
214
143
  }
215
144
  ```
216
145
 
217
- ### VS Code / Cursor
146
+ #### VS Code / Cursor
218
147
 
219
148
  `.vscode/mcp.json`:
220
149
 
@@ -234,7 +163,96 @@ Add to `claude_desktop_config.json`:
234
163
  }
235
164
  ```
236
165
 
237
- > **Prerequisite:** `lexq auth login` must have been run once to store an API key in `~/.lexq/config.json`.
166
+ > **Prerequisite:** `lexq auth login` must have been run once to store an
167
+ > API key in `~/.lexq/config.json`.
168
+
169
+ ## AI Agent Skills
170
+
171
+ LexQ CLI ships with **AI Agent Skills** — structured documentation agents
172
+ read to understand *how* to use the tools, not just *what* they are.
173
+
174
+ ```
175
+ skills/
176
+ ├── lexq-shared/SKILL.md Core concepts, auth, workflow
177
+ ├── lexq-groups/SKILL.md Policy groups, conflict resolution, A/B testing
178
+ ├── lexq-rules/SKILL.md Condition syntax, action types, mutex
179
+ ├── lexq-simulation/SKILL.md Dry run, batch simulation, compare
180
+ ├── lexq-execution/SKILL.md Execution history, stats, failure logs
181
+ └── lexq-recipes/SKILL.md End-to-end recipes
182
+
183
+ .claude/CLAUDE.md Claude Code project context
184
+ AGENTS.md Universal agent guide (Cursor, Windsurf, Gemini CLI, Cline)
185
+ CONTEXT.md Platform architecture & glossary
186
+ ```
187
+
188
+ After installing `@lexq/cli`, agents can read skills from:
189
+
190
+ ```
191
+ node_modules/@lexq/cli/skills/
192
+ node_modules/@lexq/cli/AGENTS.md
193
+ node_modules/@lexq/cli/CONTEXT.md
194
+ ```
195
+
196
+ ## Commands
197
+
198
+ ```
199
+ lexq auth login | logout | whoami
200
+ lexq status API health check
201
+ lexq serve Run as MCP stdio server (--mcp)
202
+ lexq groups list | get | create | update | delete
203
+ lexq groups ab-test start | stop | adjust
204
+ lexq versions list | get | create | update | delete | clone
205
+ lexq rules list | get | create | update | delete | reorder | toggle
206
+ lexq facts list | create | update | delete | action-metadata
207
+ lexq deploy publish | live | rollback | undeploy | history | detail | overview | deployable | diff
208
+ lexq analytics dry-run | dry-run-compare | requirements
209
+ lexq analytics simulation start | status | list | cancel | export
210
+ lexq analytics dataset upload | template
211
+ lexq history list | get | stats
212
+ lexq integrations list | get | save | delete | config-spec
213
+ lexq logs list | get | action | bulk-action
214
+ lexq webhook-subscriptions list | get | save | delete | test
215
+ ```
216
+
217
+ ## Global Options
218
+
219
+ | Flag | Description |
220
+ |--------------------------|--------------------------------------------|
221
+ | `--format <json\|table>` | Output format (default: `json`) |
222
+ | `--api-key <key>` | Override stored API key |
223
+ | `--base-url <url>` | Override API base URL |
224
+ | `--dry-run` | Preview the HTTP request without executing |
225
+ | `--verbose` | Show request/response details |
226
+ | `--no-color` | Disable colored output |
227
+
228
+ ## Configuration
229
+
230
+ Config is stored at `~/.lexq/config.json`:
231
+
232
+ ```json
233
+ {
234
+ "apiKey": "YOUR_API_KEY",
235
+ "baseUrl": "https://api.lexq.io/api/v1/partners",
236
+ "format": "json"
237
+ }
238
+ ```
239
+
240
+ ## Development
241
+
242
+ ```bash
243
+ git clone https://github.com/lexq-io/lexq-cli.git
244
+ cd lexq-cli
245
+ pnpm install
246
+ pnpm build
247
+ pnpm start -- groups list
248
+ ```
249
+
250
+ ```bash
251
+ pnpm typecheck # Type check
252
+ pnpm lint # ESLint
253
+ bash tests/e2e.sh # CLI E2E tests (requires API key)
254
+ bash tests/test-engine-api.sh # Engine API integration tests
255
+ ```
238
256
 
239
257
  ## License
240
258
 
package/dist/index.js CHANGED
@@ -222,20 +222,25 @@ function registerAuthCommands(program) {
222
222
  `
223
223
  ).action(async () => {
224
224
  try {
225
+ const globalOpts = program.opts();
225
226
  const config = loadConfig();
226
- if (!config.apiKey) {
227
+ const apiKey = globalOpts.apiKey ?? config.apiKey;
228
+ const baseUrl = globalOpts.baseUrl ?? config.baseUrl;
229
+ if (!apiKey) {
227
230
  console.error('Not authenticated. Run "lexq auth login" first.');
228
231
  process.exit(1);
229
232
  }
230
233
  const info = await apiRequest("GET", "whoami", {
231
- apiKey: config.apiKey,
232
- baseUrl: config.baseUrl
234
+ apiKey,
235
+ baseUrl,
236
+ dryRun: globalOpts.dryRun,
237
+ verbose: globalOpts.verbose
233
238
  });
234
- const masked = config.apiKey.length > 8 ? config.apiKey.substring(0, 4) + "****" + config.apiKey.substring(config.apiKey.length - 4) : "****";
239
+ const masked = apiKey.length > 8 ? apiKey.substring(0, 4) + "****" + apiKey.substring(apiKey.length - 4) : "****";
235
240
  printJson({
236
241
  ...info,
237
242
  apiKey: masked,
238
- baseUrl: config.baseUrl
243
+ baseUrl
239
244
  });
240
245
  } catch (error) {
241
246
  printError(error);
@@ -3437,9 +3442,16 @@ function registerAnalyticsTools(server, callApi) {
3437
3442
  title: "Dry Run",
3438
3443
  description: dedent14`
3439
3444
  Execute a single dry run against a version. Tests how rules evaluate given input facts without side effects.
3445
+
3446
+ Returns:
3447
+ inputFacts — normalized input facts
3448
+ mutatedFacts — input facts changed by rule actions (e.g. DISCOUNT mutates payment_amount)
3449
+ generatedVariables — new variables created by rules (e.g. last_discount_amount)
3450
+ executionTraces — per-rule match status
3451
+ decisionTraces — per-rule decision (SELECTED / BLOCKED_MUTEX / etc.)
3452
+
3440
3453
  Example input: { "facts": { "payment_amount": 100000, "customer_tier": "VIP" } }
3441
- Always dry-run before publishing to validate rule behavior.
3442
- `,
3454
+ Always dry-run before publishing to validate rule behavior.`,
3443
3455
  inputSchema: {
3444
3456
  versionId: z6.string().uuid().describe("Policy version ID to test against"),
3445
3457
  facts: z6.string().describe('JSON string of facts object, e.g. {"payment_amount":100000}'),
@@ -3458,7 +3470,13 @@ function registerAnalyticsTools(server, callApi) {
3458
3470
  "lexq_dry_run_compare",
3459
3471
  {
3460
3472
  title: "Dry Run Compare",
3461
- description: "Compare dry run results between two versions using the same input facts. Useful for validating changes.",
3473
+ description: dedent14`
3474
+ Compare dry run results between two versions using the same input facts. Useful for validating changes.
3475
+
3476
+ Returns:
3477
+ resultA / resultB — full DryRunResponse for each version
3478
+ diff.mutatedDiff — changes in mutatedFacts between A and B (key → {before, after})
3479
+ diff.generatedDiff — changes in generatedVariables between A and B`,
3462
3480
  inputSchema: {
3463
3481
  versionIdA: z6.string().uuid().describe("Baseline version ID"),
3464
3482
  versionIdB: z6.string().uuid().describe("Candidate version ID"),
@@ -611,9 +611,16 @@ function registerAnalyticsTools(server, callApi) {
611
611
  title: "Dry Run",
612
612
  description: dedent2`
613
613
  Execute a single dry run against a version. Tests how rules evaluate given input facts without side effects.
614
+
615
+ Returns:
616
+ inputFacts — normalized input facts
617
+ mutatedFacts — input facts changed by rule actions (e.g. DISCOUNT mutates payment_amount)
618
+ generatedVariables — new variables created by rules (e.g. last_discount_amount)
619
+ executionTraces — per-rule match status
620
+ decisionTraces — per-rule decision (SELECTED / BLOCKED_MUTEX / etc.)
621
+
614
622
  Example input: { "facts": { "payment_amount": 100000, "customer_tier": "VIP" } }
615
- Always dry-run before publishing to validate rule behavior.
616
- `,
623
+ Always dry-run before publishing to validate rule behavior.`,
617
624
  inputSchema: {
618
625
  versionId: z6.string().uuid().describe("Policy version ID to test against"),
619
626
  facts: z6.string().describe('JSON string of facts object, e.g. {"payment_amount":100000}'),
@@ -632,7 +639,13 @@ function registerAnalyticsTools(server, callApi) {
632
639
  "lexq_dry_run_compare",
633
640
  {
634
641
  title: "Dry Run Compare",
635
- description: "Compare dry run results between two versions using the same input facts. Useful for validating changes.",
642
+ description: dedent2`
643
+ Compare dry run results between two versions using the same input facts. Useful for validating changes.
644
+
645
+ Returns:
646
+ resultA / resultB — full DryRunResponse for each version
647
+ diff.mutatedDiff — changes in mutatedFacts between A and B (key → {before, after})
648
+ diff.generatedDiff — changes in generatedVariables between A and B`,
636
649
  inputSchema: {
637
650
  versionIdA: z6.string().uuid().describe("Baseline version ID"),
638
651
  versionIdB: z6.string().uuid().describe("Candidate version ID"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lexq/cli",
3
- "version": "0.1.19",
3
+ "version": "0.1.20",
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": {