@lexq/cli 2.0.0 → 2.1.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.
@@ -2,6 +2,12 @@ import { Implementation, McpServer } from '@modelcontextprotocol/server';
2
2
  import { LosslessNumber } from 'lossless-json';
3
3
  export { LosslessNumber } from 'lossless-json';
4
4
 
5
+ declare class ApiError extends Error {
6
+ readonly statusCode: number;
7
+ readonly errorCode: string | null;
8
+ constructor(statusCode: number, errorCode: string | null, message: string);
9
+ }
10
+
5
11
  interface McpToolResult {
6
12
  [key: string]: unknown;
7
13
  content: Array<{
@@ -61,12 +67,6 @@ declare function formatUnregisteredFactWarning(meta: unknown): string | null;
61
67
  */
62
68
  declare function formatValueDomainMismatchWarning(meta: unknown): string | null;
63
69
 
64
- declare class ApiError extends Error {
65
- readonly statusCode: number;
66
- readonly errorCode: string | null;
67
- constructor(statusCode: number, errorCode: string | null, message: string);
68
- }
69
-
70
70
  /** Parses JSON text without rounding numbers that a double cannot hold. */
71
71
  declare const parseJson: (text: string) => unknown;
72
72
  /**
@@ -966,6 +966,13 @@ function registerDeployTools(server, callApi) {
966
966
  // src/mcp/tools/analytics.ts
967
967
  import { z as z7 } from "zod";
968
968
  import dedent3 from "dedent";
969
+ function datasetBlock(path) {
970
+ const dataset = { type: "UPLOADED", source: "S3_BUCKET", path };
971
+ return {
972
+ type: "text",
973
+ text: "Ready-to-use dataset block for lexq_simulation_start:\n" + stringifyJson({ dataset }, 2)
974
+ };
975
+ }
969
976
  function registerAnalyticsTools(server, callApi) {
970
977
  server.registerTool(
971
978
  "lexq_dry_run",
@@ -1152,6 +1159,10 @@ function registerAnalyticsTools(server, callApi) {
1152
1159
  To use the returned path in lexq_simulation_start, set:
1153
1160
  dataset: { "type": "UPLOADED", "source": "S3_BUCKET", "path": "<returned path>" }
1154
1161
 
1162
+ The content travels inside the tool call, so this suits small datasets, and the hosted server at
1163
+ mcp.lexq.io limits the size of a request. For a larger file, use lexq_dataset_upload_file on the
1164
+ local server (lexq serve --mcp), or upload it with the CLI or the console and pass the returned path.
1165
+
1155
1166
  CSV example:
1156
1167
  userId,paymentAmount
1157
1168
  user_001,150000
@@ -1171,13 +1182,8 @@ function registerAnalyticsTools(server, callApi) {
1171
1182
  if (!result.isError) {
1172
1183
  try {
1173
1184
  const uploaded = parseJson(result.content[0]?.text ?? "{}");
1174
- if (uploaded.path) {
1175
- const dataset = { type: "UPLOADED", source: "S3_BUCKET", path: uploaded.path };
1176
- result.content.push({
1177
- type: "text",
1178
- text: "Ready-to-use dataset block for lexq_simulation_start:\n" + stringifyJson({ dataset }, 2)
1179
- });
1180
- }
1185
+ const path = uploaded.data?.path ?? uploaded.path;
1186
+ if (typeof path === "string" && path) result.content.push(datasetBlock(path));
1181
1187
  } catch {
1182
1188
  }
1183
1189
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lexq/cli",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "mcpName": "io.lexq/lexq",
5
5
  "description": "The Decision Operations Platform for engineering teams",
6
6
  "type": "module",
@@ -45,6 +45,7 @@
45
45
  "test:value-domain": "pnpm build && node tests/value-domain.mjs",
46
46
  "test:fact-update": "pnpm build && node tests/fact-update.mjs",
47
47
  "test:rollback": "pnpm build && node tests/rollback.mjs",
48
+ "test:dataset-upload": "pnpm build && node tests/dataset-upload.mjs",
48
49
  "prepublishOnly": "pnpm build",
49
50
  "knip": "knip",
50
51
  "format": "prettier --write \"src/**/*.ts\"",
@@ -76,16 +77,16 @@
76
77
  },
77
78
  "packageManager": "pnpm@10.28.0",
78
79
  "dependencies": {
79
- "@modelcontextprotocol/server": "^2.0.0",
80
+ "@modelcontextprotocol/server": "^2.3.1",
80
81
  "cli-table3": "^0.6.5",
81
82
  "commander": "^13.1.0",
82
83
  "dedent": "^1.7.2",
83
84
  "lossless-json": "4.3.1",
84
- "zod": "^4.5.4"
85
+ "zod": "^4.6.7"
85
86
  },
86
87
  "devDependencies": {
87
88
  "@eslint/js": "^9.20.0",
88
- "@modelcontextprotocol/client": "^2.0.0",
89
+ "@modelcontextprotocol/client": "^2.3.1",
89
90
  "@types/node": "^22.12.0",
90
91
  "eslint": "^10.2.0",
91
92
  "knip": "^6.29.0",
@@ -280,6 +280,11 @@ lexq analytics simulation start --json '{
280
280
  **CSV format:** Header row with fact keys, data rows with values. Types auto-detected.
281
281
  **JSON format:** Array of objects `[{"key": "value"}, ...]`
282
282
 
283
+ Dataset files can be up to 10 MB. Over MCP, the local server (`lexq serve --mcp`) has
284
+ `lexq_dataset_upload_file`, which takes the absolute path of a `.csv` or `.json` file and reads it from
285
+ disk. The hosted server has only `lexq_dataset_upload`, which takes the content inline and suits small
286
+ datasets. For a larger file there, upload it with the command above and pass the returned `path`.
287
+
283
288
  ### Check Status (Poll)
284
289
 
285
290
  ```bash