@lexq/cli 0.1.12 → 0.1.14
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 +318 -443
- package/dist/mcp/register.js +54 -83
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -75,7 +75,7 @@ async function apiRequest(method, path, options = {}) {
|
|
|
75
75
|
}
|
|
76
76
|
const headers = {
|
|
77
77
|
"X-API-KEY": apiKey,
|
|
78
|
-
|
|
78
|
+
Accept: "application/json"
|
|
79
79
|
};
|
|
80
80
|
if (options.body) {
|
|
81
81
|
headers["Content-Type"] = "application/json";
|
|
@@ -194,11 +194,10 @@ function registerAuthCommands(program) {
|
|
|
194
194
|
console.error('Not authenticated. Run "lexq auth login" first.');
|
|
195
195
|
process.exit(1);
|
|
196
196
|
}
|
|
197
|
-
const info = await apiRequest(
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
);
|
|
197
|
+
const info = await apiRequest("GET", "whoami", {
|
|
198
|
+
apiKey: config.apiKey,
|
|
199
|
+
baseUrl: config.baseUrl
|
|
200
|
+
});
|
|
202
201
|
const masked = config.apiKey.length > 8 ? config.apiKey.substring(0, 4) + "****" + config.apiKey.substring(config.apiKey.length - 4) : "****";
|
|
203
202
|
printJson({
|
|
204
203
|
...info,
|
|
@@ -244,17 +243,13 @@ function registerGroupCommands(program) {
|
|
|
244
243
|
try {
|
|
245
244
|
const globalOpts = program.opts();
|
|
246
245
|
const format = globalOpts.format ?? "json";
|
|
247
|
-
const data = await apiRequest(
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
verbose: globalOpts.verbose,
|
|
255
|
-
params: { page: opts.page, size: opts.size }
|
|
256
|
-
}
|
|
257
|
-
);
|
|
246
|
+
const data = await apiRequest("GET", "policy-groups", {
|
|
247
|
+
apiKey: globalOpts.apiKey,
|
|
248
|
+
baseUrl: globalOpts.baseUrl,
|
|
249
|
+
dryRun: globalOpts.dryRun,
|
|
250
|
+
verbose: globalOpts.verbose,
|
|
251
|
+
params: { page: opts.page, size: opts.size }
|
|
252
|
+
});
|
|
258
253
|
if (format === "table") {
|
|
259
254
|
printTable(
|
|
260
255
|
["ID", "Name", "Status", "Priority", "Version", "Updated"],
|
|
@@ -281,16 +276,12 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
281
276
|
groups.command("get").description("Get a policy group by ID").requiredOption("--id <groupId>", "Policy group ID").action(async (opts) => {
|
|
282
277
|
try {
|
|
283
278
|
const globalOpts = program.opts();
|
|
284
|
-
const data = await apiRequest(
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
dryRun: globalOpts.dryRun,
|
|
291
|
-
verbose: globalOpts.verbose
|
|
292
|
-
}
|
|
293
|
-
);
|
|
279
|
+
const data = await apiRequest("GET", `policy-groups/${opts.id}`, {
|
|
280
|
+
apiKey: globalOpts.apiKey,
|
|
281
|
+
baseUrl: globalOpts.baseUrl,
|
|
282
|
+
dryRun: globalOpts.dryRun,
|
|
283
|
+
verbose: globalOpts.verbose
|
|
284
|
+
});
|
|
294
285
|
printJson(data);
|
|
295
286
|
} catch (error) {
|
|
296
287
|
printError(error);
|
|
@@ -301,17 +292,13 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
301
292
|
try {
|
|
302
293
|
const globalOpts = program.opts();
|
|
303
294
|
const body = JSON.parse(opts.json);
|
|
304
|
-
const data = await apiRequest(
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
verbose: globalOpts.verbose,
|
|
312
|
-
body
|
|
313
|
-
}
|
|
314
|
-
);
|
|
295
|
+
const data = await apiRequest("POST", "policy-groups", {
|
|
296
|
+
apiKey: globalOpts.apiKey,
|
|
297
|
+
baseUrl: globalOpts.baseUrl,
|
|
298
|
+
dryRun: globalOpts.dryRun,
|
|
299
|
+
verbose: globalOpts.verbose,
|
|
300
|
+
body
|
|
301
|
+
});
|
|
315
302
|
printJson(data);
|
|
316
303
|
} catch (error) {
|
|
317
304
|
printError(error);
|
|
@@ -322,17 +309,13 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
322
309
|
try {
|
|
323
310
|
const globalOpts = program.opts();
|
|
324
311
|
const body = JSON.parse(opts.json);
|
|
325
|
-
const data = await apiRequest(
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
verbose: globalOpts.verbose,
|
|
333
|
-
body
|
|
334
|
-
}
|
|
335
|
-
);
|
|
312
|
+
const data = await apiRequest("PUT", `policy-groups/${opts.id}`, {
|
|
313
|
+
apiKey: globalOpts.apiKey,
|
|
314
|
+
baseUrl: globalOpts.baseUrl,
|
|
315
|
+
dryRun: globalOpts.dryRun,
|
|
316
|
+
verbose: globalOpts.verbose,
|
|
317
|
+
body
|
|
318
|
+
});
|
|
336
319
|
printJson(data);
|
|
337
320
|
} catch (error) {
|
|
338
321
|
printError(error);
|
|
@@ -352,16 +335,12 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
352
335
|
return;
|
|
353
336
|
}
|
|
354
337
|
}
|
|
355
|
-
await apiRequest(
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
dryRun: globalOpts.dryRun,
|
|
362
|
-
verbose: globalOpts.verbose
|
|
363
|
-
}
|
|
364
|
-
);
|
|
338
|
+
await apiRequest("DELETE", `policy-groups/${opts.id}`, {
|
|
339
|
+
apiKey: globalOpts.apiKey,
|
|
340
|
+
baseUrl: globalOpts.baseUrl,
|
|
341
|
+
dryRun: globalOpts.dryRun,
|
|
342
|
+
verbose: globalOpts.verbose
|
|
343
|
+
});
|
|
365
344
|
console.log(`\u2713 Group ${opts.id} deleted.`);
|
|
366
345
|
} catch (error) {
|
|
367
346
|
printError(error);
|
|
@@ -406,16 +385,12 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
406
385
|
return;
|
|
407
386
|
}
|
|
408
387
|
}
|
|
409
|
-
const data = await apiRequest(
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
dryRun: globalOpts.dryRun,
|
|
416
|
-
verbose: globalOpts.verbose
|
|
417
|
-
}
|
|
418
|
-
);
|
|
388
|
+
const data = await apiRequest("DELETE", `policy-groups/${opts.groupId}/ab-test`, {
|
|
389
|
+
apiKey: globalOpts.apiKey,
|
|
390
|
+
baseUrl: globalOpts.baseUrl,
|
|
391
|
+
dryRun: globalOpts.dryRun,
|
|
392
|
+
verbose: globalOpts.verbose
|
|
393
|
+
});
|
|
419
394
|
printJson(data);
|
|
420
395
|
} catch (error) {
|
|
421
396
|
printError(error);
|
|
@@ -563,16 +538,12 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
563
538
|
return;
|
|
564
539
|
}
|
|
565
540
|
}
|
|
566
|
-
await apiRequest(
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
dryRun: globalOpts.dryRun,
|
|
573
|
-
verbose: globalOpts.verbose
|
|
574
|
-
}
|
|
575
|
-
);
|
|
541
|
+
await apiRequest("DELETE", `policy-groups/${opts.groupId}/versions/${opts.id}`, {
|
|
542
|
+
apiKey: globalOpts.apiKey,
|
|
543
|
+
baseUrl: globalOpts.baseUrl,
|
|
544
|
+
dryRun: globalOpts.dryRun,
|
|
545
|
+
verbose: globalOpts.verbose
|
|
546
|
+
});
|
|
576
547
|
console.log(`\u2713 Version ${opts.id} deleted.`);
|
|
577
548
|
} catch (error) {
|
|
578
549
|
printError(error);
|
|
@@ -809,17 +780,13 @@ function registerFactCommands(program) {
|
|
|
809
780
|
size: opts.size
|
|
810
781
|
};
|
|
811
782
|
if (opts.keyword) params.keyword = opts.keyword;
|
|
812
|
-
const data = await apiRequest(
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
verbose: globalOpts.verbose,
|
|
820
|
-
params
|
|
821
|
-
}
|
|
822
|
-
);
|
|
783
|
+
const data = await apiRequest("GET", "schema/facts", {
|
|
784
|
+
apiKey: globalOpts.apiKey,
|
|
785
|
+
baseUrl: globalOpts.baseUrl,
|
|
786
|
+
dryRun: globalOpts.dryRun,
|
|
787
|
+
verbose: globalOpts.verbose,
|
|
788
|
+
params
|
|
789
|
+
});
|
|
823
790
|
if (format === "table") {
|
|
824
791
|
printTable(
|
|
825
792
|
["ID", "Key", "Name", "Type", "System", "Required"],
|
|
@@ -847,17 +814,13 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
847
814
|
try {
|
|
848
815
|
const globalOpts = program.opts();
|
|
849
816
|
const body = opts.json ? JSON.parse(opts.json) : buildCreateBody2(opts);
|
|
850
|
-
const data = await apiRequest(
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
verbose: globalOpts.verbose,
|
|
858
|
-
body
|
|
859
|
-
}
|
|
860
|
-
);
|
|
817
|
+
const data = await apiRequest("POST", "schema/facts", {
|
|
818
|
+
apiKey: globalOpts.apiKey,
|
|
819
|
+
baseUrl: globalOpts.baseUrl,
|
|
820
|
+
dryRun: globalOpts.dryRun,
|
|
821
|
+
verbose: globalOpts.verbose,
|
|
822
|
+
body
|
|
823
|
+
});
|
|
861
824
|
printJson(data);
|
|
862
825
|
} catch (error) {
|
|
863
826
|
printError(error);
|
|
@@ -868,17 +831,13 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
868
831
|
try {
|
|
869
832
|
const globalOpts = program.opts();
|
|
870
833
|
const body = opts.json ? JSON.parse(opts.json) : buildUpdateBody2(opts);
|
|
871
|
-
const data = await apiRequest(
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
verbose: globalOpts.verbose,
|
|
879
|
-
body
|
|
880
|
-
}
|
|
881
|
-
);
|
|
834
|
+
const data = await apiRequest("PUT", `schema/facts/${opts.id}`, {
|
|
835
|
+
apiKey: globalOpts.apiKey,
|
|
836
|
+
baseUrl: globalOpts.baseUrl,
|
|
837
|
+
dryRun: globalOpts.dryRun,
|
|
838
|
+
verbose: globalOpts.verbose,
|
|
839
|
+
body
|
|
840
|
+
});
|
|
882
841
|
printJson(data);
|
|
883
842
|
} catch (error) {
|
|
884
843
|
printError(error);
|
|
@@ -898,16 +857,12 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
898
857
|
return;
|
|
899
858
|
}
|
|
900
859
|
}
|
|
901
|
-
await apiRequest(
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
dryRun: globalOpts.dryRun,
|
|
908
|
-
verbose: globalOpts.verbose
|
|
909
|
-
}
|
|
910
|
-
);
|
|
860
|
+
await apiRequest("DELETE", `schema/facts/${opts.id}`, {
|
|
861
|
+
apiKey: globalOpts.apiKey,
|
|
862
|
+
baseUrl: globalOpts.baseUrl,
|
|
863
|
+
dryRun: globalOpts.dryRun,
|
|
864
|
+
verbose: globalOpts.verbose
|
|
865
|
+
});
|
|
911
866
|
console.log(`\u2713 Fact ${opts.id} deleted.`);
|
|
912
867
|
} catch (error) {
|
|
913
868
|
printError(error);
|
|
@@ -917,16 +872,12 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
917
872
|
facts.command("action-metadata").description("Get action runtime fact metadata").action(async () => {
|
|
918
873
|
try {
|
|
919
874
|
const globalOpts = program.opts();
|
|
920
|
-
const data = await apiRequest(
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
dryRun: globalOpts.dryRun,
|
|
927
|
-
verbose: globalOpts.verbose
|
|
928
|
-
}
|
|
929
|
-
);
|
|
875
|
+
const data = await apiRequest("GET", "schema/action-metadata", {
|
|
876
|
+
apiKey: globalOpts.apiKey,
|
|
877
|
+
baseUrl: globalOpts.baseUrl,
|
|
878
|
+
dryRun: globalOpts.dryRun,
|
|
879
|
+
verbose: globalOpts.verbose
|
|
880
|
+
});
|
|
930
881
|
printJson(data);
|
|
931
882
|
} catch (error) {
|
|
932
883
|
printError(error);
|
|
@@ -982,17 +933,13 @@ function registerDeployCommands(program) {
|
|
|
982
933
|
deploy.command("live").description("Deploy an ACTIVE version to live traffic").requiredOption("--group-id <groupId>", "Policy group ID").requiredOption("--version-id <versionId>", "Version ID to deploy").option("--memo <memo>", "Deployment memo").action(async (opts) => {
|
|
983
934
|
try {
|
|
984
935
|
const globalOpts = program.opts();
|
|
985
|
-
await apiRequest(
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
verbose: globalOpts.verbose,
|
|
993
|
-
body: { versionId: opts.versionId, memo: opts.memo ?? "" }
|
|
994
|
-
}
|
|
995
|
-
);
|
|
936
|
+
await apiRequest("POST", `policy-groups/${opts.groupId}/deploy`, {
|
|
937
|
+
apiKey: globalOpts.apiKey,
|
|
938
|
+
baseUrl: globalOpts.baseUrl,
|
|
939
|
+
dryRun: globalOpts.dryRun,
|
|
940
|
+
verbose: globalOpts.verbose,
|
|
941
|
+
body: { versionId: opts.versionId, memo: opts.memo ?? "" }
|
|
942
|
+
});
|
|
996
943
|
console.log(`\u2713 Version ${opts.versionId} deployed to live.`);
|
|
997
944
|
} catch (error) {
|
|
998
945
|
printError(error);
|
|
@@ -1012,17 +959,13 @@ function registerDeployCommands(program) {
|
|
|
1012
959
|
return;
|
|
1013
960
|
}
|
|
1014
961
|
}
|
|
1015
|
-
await apiRequest(
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
verbose: globalOpts.verbose,
|
|
1023
|
-
body: { memo: opts.memo ?? "" }
|
|
1024
|
-
}
|
|
1025
|
-
);
|
|
962
|
+
await apiRequest("POST", `policy-groups/${opts.groupId}/rollback`, {
|
|
963
|
+
apiKey: globalOpts.apiKey,
|
|
964
|
+
baseUrl: globalOpts.baseUrl,
|
|
965
|
+
dryRun: globalOpts.dryRun,
|
|
966
|
+
verbose: globalOpts.verbose,
|
|
967
|
+
body: { memo: opts.memo ?? "" }
|
|
968
|
+
});
|
|
1026
969
|
console.log(`\u2713 Group ${opts.groupId} rolled back.`);
|
|
1027
970
|
} catch (error) {
|
|
1028
971
|
printError(error);
|
|
@@ -1042,24 +985,23 @@ function registerDeployCommands(program) {
|
|
|
1042
985
|
return;
|
|
1043
986
|
}
|
|
1044
987
|
}
|
|
1045
|
-
await apiRequest(
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
verbose: globalOpts.verbose,
|
|
1053
|
-
body: { memo: opts.memo ?? "" }
|
|
1054
|
-
}
|
|
1055
|
-
);
|
|
988
|
+
await apiRequest("POST", `policy-groups/${opts.groupId}/undeploy`, {
|
|
989
|
+
apiKey: globalOpts.apiKey,
|
|
990
|
+
baseUrl: globalOpts.baseUrl,
|
|
991
|
+
dryRun: globalOpts.dryRun,
|
|
992
|
+
verbose: globalOpts.verbose,
|
|
993
|
+
body: { memo: opts.memo ?? "" }
|
|
994
|
+
});
|
|
1056
995
|
console.log(`\u2713 Group ${opts.groupId} undeployed.`);
|
|
1057
996
|
} catch (error) {
|
|
1058
997
|
printError(error);
|
|
1059
998
|
process.exit(1);
|
|
1060
999
|
}
|
|
1061
1000
|
});
|
|
1062
|
-
deploy.command("history").description("List deployment history").option("--group-id <groupId>", "Filter by policy group").option(
|
|
1001
|
+
deploy.command("history").description("List deployment history").option("--group-id <groupId>", "Filter by policy group").option(
|
|
1002
|
+
"--types <types>",
|
|
1003
|
+
"Filter by types (comma-separated: PUBLISH,DEPLOY,ROLLBACK,UNDEPLOY)"
|
|
1004
|
+
).option("--start-date <date>", "Start date (yyyy-MM-dd)").option("--end-date <date>", "End date (yyyy-MM-dd)").option("--page <number>", "Page number", "0").option("--size <number>", "Page size", "20").action(async (opts) => {
|
|
1063
1005
|
try {
|
|
1064
1006
|
const globalOpts = program.opts();
|
|
1065
1007
|
const format = globalOpts.format ?? "json";
|
|
@@ -1071,17 +1013,13 @@ function registerDeployCommands(program) {
|
|
|
1071
1013
|
if (opts.types) params.types = opts.types;
|
|
1072
1014
|
if (opts.startDate) params.startDate = opts.startDate;
|
|
1073
1015
|
if (opts.endDate) params.endDate = opts.endDate;
|
|
1074
|
-
const data = await apiRequest(
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
verbose: globalOpts.verbose,
|
|
1082
|
-
params
|
|
1083
|
-
}
|
|
1084
|
-
);
|
|
1016
|
+
const data = await apiRequest("GET", "deployments", {
|
|
1017
|
+
apiKey: globalOpts.apiKey,
|
|
1018
|
+
baseUrl: globalOpts.baseUrl,
|
|
1019
|
+
dryRun: globalOpts.dryRun,
|
|
1020
|
+
verbose: globalOpts.verbose,
|
|
1021
|
+
params
|
|
1022
|
+
});
|
|
1085
1023
|
if (format === "table") {
|
|
1086
1024
|
printTable(
|
|
1087
1025
|
["ID", "Type", "Group", "Version", "By", "At"],
|
|
@@ -1108,16 +1046,12 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
1108
1046
|
deploy.command("detail").description("Get deployment detail").requiredOption("--id <deploymentId>", "Deployment ID").action(async (opts) => {
|
|
1109
1047
|
try {
|
|
1110
1048
|
const globalOpts = program.opts();
|
|
1111
|
-
const data = await apiRequest(
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
dryRun: globalOpts.dryRun,
|
|
1118
|
-
verbose: globalOpts.verbose
|
|
1119
|
-
}
|
|
1120
|
-
);
|
|
1049
|
+
const data = await apiRequest("GET", `deployments/${opts.id}`, {
|
|
1050
|
+
apiKey: globalOpts.apiKey,
|
|
1051
|
+
baseUrl: globalOpts.baseUrl,
|
|
1052
|
+
dryRun: globalOpts.dryRun,
|
|
1053
|
+
verbose: globalOpts.verbose
|
|
1054
|
+
});
|
|
1121
1055
|
printJson(data);
|
|
1122
1056
|
} catch (error) {
|
|
1123
1057
|
printError(error);
|
|
@@ -1128,16 +1062,12 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
1128
1062
|
try {
|
|
1129
1063
|
const globalOpts = program.opts();
|
|
1130
1064
|
const format = globalOpts.format ?? "json";
|
|
1131
|
-
const data = await apiRequest(
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
dryRun: globalOpts.dryRun,
|
|
1138
|
-
verbose: globalOpts.verbose
|
|
1139
|
-
}
|
|
1140
|
-
);
|
|
1065
|
+
const data = await apiRequest("GET", "deployments/overview", {
|
|
1066
|
+
apiKey: globalOpts.apiKey,
|
|
1067
|
+
baseUrl: globalOpts.baseUrl,
|
|
1068
|
+
dryRun: globalOpts.dryRun,
|
|
1069
|
+
verbose: globalOpts.verbose
|
|
1070
|
+
});
|
|
1141
1071
|
if (format === "table") {
|
|
1142
1072
|
printTable(
|
|
1143
1073
|
["Group", "Name", "Status", "Current Version", "Last Deploy"],
|
|
@@ -1179,20 +1109,16 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
1179
1109
|
deploy.command("diff").description("Compare snapshot diff between two versions").requiredOption("--base <versionId>", "Base version ID").requiredOption("--target <versionId>", "Target version ID").action(async (opts) => {
|
|
1180
1110
|
try {
|
|
1181
1111
|
const globalOpts = program.opts();
|
|
1182
|
-
const data = await apiRequest(
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
params: {
|
|
1191
|
-
baseVersionId: opts.base,
|
|
1192
|
-
targetVersionId: opts.target
|
|
1193
|
-
}
|
|
1112
|
+
const data = await apiRequest("GET", "deployments/diff", {
|
|
1113
|
+
apiKey: globalOpts.apiKey,
|
|
1114
|
+
baseUrl: globalOpts.baseUrl,
|
|
1115
|
+
dryRun: globalOpts.dryRun,
|
|
1116
|
+
verbose: globalOpts.verbose,
|
|
1117
|
+
params: {
|
|
1118
|
+
baseVersionId: opts.base,
|
|
1119
|
+
targetVersionId: opts.target
|
|
1194
1120
|
}
|
|
1195
|
-
);
|
|
1121
|
+
});
|
|
1196
1122
|
printJson(data);
|
|
1197
1123
|
} catch (error) {
|
|
1198
1124
|
printError(error);
|
|
@@ -1237,19 +1163,17 @@ function registerAnalyticsCommands(program) {
|
|
|
1237
1163
|
const globalOpts = program.opts();
|
|
1238
1164
|
const body = resolveBody(opts);
|
|
1239
1165
|
if (!body.facts || !body.versionIdA || !body.versionIdB) {
|
|
1240
|
-
throw new Error(
|
|
1166
|
+
throw new Error(
|
|
1167
|
+
'Request body must include "facts", "versionIdA", "versionIdB". Use --json or --file.'
|
|
1168
|
+
);
|
|
1241
1169
|
}
|
|
1242
|
-
const data = await apiRequest(
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
verbose: globalOpts.verbose,
|
|
1250
|
-
body
|
|
1251
|
-
}
|
|
1252
|
-
);
|
|
1170
|
+
const data = await apiRequest("POST", "analytics/dry-run/compare", {
|
|
1171
|
+
apiKey: globalOpts.apiKey,
|
|
1172
|
+
baseUrl: globalOpts.baseUrl,
|
|
1173
|
+
dryRun: globalOpts.dryRun,
|
|
1174
|
+
verbose: globalOpts.verbose,
|
|
1175
|
+
body
|
|
1176
|
+
});
|
|
1253
1177
|
printJson(data);
|
|
1254
1178
|
} catch (error) {
|
|
1255
1179
|
printError(error);
|
|
@@ -1296,17 +1220,13 @@ function registerAnalyticsCommands(program) {
|
|
|
1296
1220
|
try {
|
|
1297
1221
|
const globalOpts = program.opts();
|
|
1298
1222
|
const body = resolveBody(opts);
|
|
1299
|
-
const data = await apiRequest(
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
verbose: globalOpts.verbose,
|
|
1307
|
-
body
|
|
1308
|
-
}
|
|
1309
|
-
);
|
|
1223
|
+
const data = await apiRequest("POST", "analytics/simulations", {
|
|
1224
|
+
apiKey: globalOpts.apiKey,
|
|
1225
|
+
baseUrl: globalOpts.baseUrl,
|
|
1226
|
+
dryRun: globalOpts.dryRun,
|
|
1227
|
+
verbose: globalOpts.verbose,
|
|
1228
|
+
body
|
|
1229
|
+
});
|
|
1310
1230
|
console.log(`\u2713 Simulation started: ${data.simulationId} (${data.status})`);
|
|
1311
1231
|
printJson(data);
|
|
1312
1232
|
} catch (error) {
|
|
@@ -1340,20 +1260,32 @@ function registerAnalyticsCommands(program) {
|
|
|
1340
1260
|
console.log(`Time: ${data.summary.executionTimeMs.toLocaleString()}ms`);
|
|
1341
1261
|
}
|
|
1342
1262
|
if (data.metricSummary) {
|
|
1343
|
-
console.log(
|
|
1344
|
-
|
|
1263
|
+
console.log(
|
|
1264
|
+
`
|
|
1265
|
+
\u2500\u2500 Metric: ${data.metricSummary.targetVariable} (${data.metricSummary.aggregationType}) \u2500\u2500`
|
|
1266
|
+
);
|
|
1345
1267
|
console.log(`Baseline: ${data.metricSummary.baselineValue.toLocaleString()}`);
|
|
1346
1268
|
console.log(`Simulated: ${data.metricSummary.simulatedValue.toLocaleString()}`);
|
|
1347
|
-
console.log(
|
|
1348
|
-
|
|
1269
|
+
console.log(
|
|
1270
|
+
`Delta: ${data.metricSummary.delta > 0 ? "+" : ""}${data.metricSummary.delta.toLocaleString()}`
|
|
1271
|
+
);
|
|
1272
|
+
console.log(
|
|
1273
|
+
`Change: ${data.metricSummary.deltaPercentage > 0 ? "+" : ""}${data.metricSummary.deltaPercentage.toFixed(1)}%`
|
|
1274
|
+
);
|
|
1349
1275
|
}
|
|
1350
1276
|
if (data.policyImpact?.comparison) {
|
|
1351
1277
|
const diff = data.policyImpact.comparison.difference;
|
|
1352
1278
|
console.log(`
|
|
1353
1279
|
\u2500\u2500 Impact \u2500\u2500`);
|
|
1354
|
-
console.log(
|
|
1355
|
-
|
|
1356
|
-
|
|
1280
|
+
console.log(
|
|
1281
|
+
`Matched \u0394: ${diff.matchedCountDelta > 0 ? "+" : ""}${diff.matchedCountDelta}`
|
|
1282
|
+
);
|
|
1283
|
+
console.log(
|
|
1284
|
+
`Rate \u0394: ${diff.matchedRateDelta > 0 ? "+" : ""}${diff.matchedRateDelta.toFixed(1)}%`
|
|
1285
|
+
);
|
|
1286
|
+
console.log(
|
|
1287
|
+
`Metric \u0394: ${diff.metricValueDelta > 0 ? "+" : ""}${diff.metricValueDelta.toLocaleString()}`
|
|
1288
|
+
);
|
|
1357
1289
|
}
|
|
1358
1290
|
if (data.ruleStats?.length) {
|
|
1359
1291
|
console.log("");
|
|
@@ -1375,7 +1307,10 @@ function registerAnalyticsCommands(program) {
|
|
|
1375
1307
|
process.exit(1);
|
|
1376
1308
|
}
|
|
1377
1309
|
});
|
|
1378
|
-
sim.command("list").description("List simulation history").option(
|
|
1310
|
+
sim.command("list").description("List simulation history").option(
|
|
1311
|
+
"--status <status>",
|
|
1312
|
+
"Filter by status (PENDING, RUNNING, COMPLETED, FAILED, CANCELLED)"
|
|
1313
|
+
).option("--from <date>", "Start date (yyyy-MM-dd)").option("--to <date>", "End date (yyyy-MM-dd)").option("--page <number>", "Page number", "0").option("--size <number>", "Page size", "20").action(async (opts) => {
|
|
1379
1314
|
try {
|
|
1380
1315
|
const globalOpts = program.opts();
|
|
1381
1316
|
const format = globalOpts.format ?? "json";
|
|
@@ -1434,16 +1369,12 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
1434
1369
|
return;
|
|
1435
1370
|
}
|
|
1436
1371
|
}
|
|
1437
|
-
await apiRequest(
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
dryRun: globalOpts.dryRun,
|
|
1444
|
-
verbose: globalOpts.verbose
|
|
1445
|
-
}
|
|
1446
|
-
);
|
|
1372
|
+
await apiRequest("DELETE", `analytics/simulations/${opts.id}`, {
|
|
1373
|
+
apiKey: globalOpts.apiKey,
|
|
1374
|
+
baseUrl: globalOpts.baseUrl,
|
|
1375
|
+
dryRun: globalOpts.dryRun,
|
|
1376
|
+
verbose: globalOpts.verbose
|
|
1377
|
+
});
|
|
1447
1378
|
console.log(`\u2713 Simulation ${opts.id} cancelled.`);
|
|
1448
1379
|
} catch (error) {
|
|
1449
1380
|
printError(error);
|
|
@@ -1497,7 +1428,10 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
1497
1428
|
const blob = new Blob([fileBuffer], { type: contentType });
|
|
1498
1429
|
const formData = new FormData();
|
|
1499
1430
|
formData.append("file", blob, fileName);
|
|
1500
|
-
const url = new URL(
|
|
1431
|
+
const url = new URL(
|
|
1432
|
+
"analytics/datasets/upload",
|
|
1433
|
+
baseUrl.endsWith("/") ? baseUrl : baseUrl + "/"
|
|
1434
|
+
);
|
|
1501
1435
|
if (globalOpts.verbose) {
|
|
1502
1436
|
console.error(`\u2192 POST ${url.toString()}`);
|
|
1503
1437
|
console.error(` File: ${filePath} (${fileBuffer.length} bytes)`);
|
|
@@ -1646,28 +1580,26 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
1646
1580
|
if (opts.groupId) params.policyGroupId = opts.groupId;
|
|
1647
1581
|
if (opts.startDate) params.startDate = opts.startDate;
|
|
1648
1582
|
if (opts.endDate) params.endDate = opts.endDate;
|
|
1649
|
-
const data = await apiRequest(
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
verbose: globalOpts.verbose,
|
|
1657
|
-
params
|
|
1658
|
-
}
|
|
1659
|
-
);
|
|
1583
|
+
const data = await apiRequest("GET", "execution/history/stats", {
|
|
1584
|
+
apiKey: globalOpts.apiKey,
|
|
1585
|
+
baseUrl: globalOpts.baseUrl,
|
|
1586
|
+
dryRun: globalOpts.dryRun,
|
|
1587
|
+
verbose: globalOpts.verbose,
|
|
1588
|
+
params
|
|
1589
|
+
});
|
|
1660
1590
|
if (format === "table") {
|
|
1661
1591
|
printTable(
|
|
1662
1592
|
["Total", "Success", "No Match", "Failures", "Success Rate", "Avg Latency"],
|
|
1663
|
-
[
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1593
|
+
[
|
|
1594
|
+
[
|
|
1595
|
+
String(data.totalExecutions),
|
|
1596
|
+
String(data.successCount),
|
|
1597
|
+
String(data.noMatchCount),
|
|
1598
|
+
String(data.failureCount),
|
|
1599
|
+
`${data.successRate}%`,
|
|
1600
|
+
`${data.avgLatencyMs}ms`
|
|
1601
|
+
]
|
|
1602
|
+
]
|
|
1671
1603
|
);
|
|
1672
1604
|
} else {
|
|
1673
1605
|
printJson(data);
|
|
@@ -1683,7 +1615,10 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
1683
1615
|
import "commander";
|
|
1684
1616
|
function registerIntegrationCommands(program) {
|
|
1685
1617
|
const integrations = program.command("integrations").description("Manage external integrations");
|
|
1686
|
-
integrations.command("list").description("List integrations").option(
|
|
1618
|
+
integrations.command("list").description("List integrations").option(
|
|
1619
|
+
"--type <type>",
|
|
1620
|
+
"Filter by type (COUPON, POINT, NOTIFICATION, CRM, MESSENGER, WEBHOOK)"
|
|
1621
|
+
).option("--page <number>", "Page number", "0").option("--size <number>", "Page size", "20").action(async (opts) => {
|
|
1687
1622
|
try {
|
|
1688
1623
|
const globalOpts = program.opts();
|
|
1689
1624
|
const format = globalOpts.format ?? "json";
|
|
@@ -1692,17 +1627,13 @@ function registerIntegrationCommands(program) {
|
|
|
1692
1627
|
size: opts.size
|
|
1693
1628
|
};
|
|
1694
1629
|
if (opts.type) params.type = opts.type;
|
|
1695
|
-
const data = await apiRequest(
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
verbose: globalOpts.verbose,
|
|
1703
|
-
params
|
|
1704
|
-
}
|
|
1705
|
-
);
|
|
1630
|
+
const data = await apiRequest("GET", "integrations", {
|
|
1631
|
+
apiKey: globalOpts.apiKey,
|
|
1632
|
+
baseUrl: globalOpts.baseUrl,
|
|
1633
|
+
dryRun: globalOpts.dryRun,
|
|
1634
|
+
verbose: globalOpts.verbose,
|
|
1635
|
+
params
|
|
1636
|
+
});
|
|
1706
1637
|
if (format === "table") {
|
|
1707
1638
|
printTable(
|
|
1708
1639
|
["ID", "Name", "Type", "URL", "Active"],
|
|
@@ -1728,16 +1659,12 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
1728
1659
|
integrations.command("get").description("Get integration detail").requiredOption("--id <integrationId>", "Integration ID").action(async (opts) => {
|
|
1729
1660
|
try {
|
|
1730
1661
|
const globalOpts = program.opts();
|
|
1731
|
-
const data = await apiRequest(
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
dryRun: globalOpts.dryRun,
|
|
1738
|
-
verbose: globalOpts.verbose
|
|
1739
|
-
}
|
|
1740
|
-
);
|
|
1662
|
+
const data = await apiRequest("GET", `integrations/${opts.id}`, {
|
|
1663
|
+
apiKey: globalOpts.apiKey,
|
|
1664
|
+
baseUrl: globalOpts.baseUrl,
|
|
1665
|
+
dryRun: globalOpts.dryRun,
|
|
1666
|
+
verbose: globalOpts.verbose
|
|
1667
|
+
});
|
|
1741
1668
|
printJson(data);
|
|
1742
1669
|
} catch (error) {
|
|
1743
1670
|
printError(error);
|
|
@@ -1748,17 +1675,13 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
1748
1675
|
try {
|
|
1749
1676
|
const globalOpts = program.opts();
|
|
1750
1677
|
const body = JSON.parse(opts.json);
|
|
1751
|
-
const data = await apiRequest(
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
verbose: globalOpts.verbose,
|
|
1759
|
-
body
|
|
1760
|
-
}
|
|
1761
|
-
);
|
|
1678
|
+
const data = await apiRequest("POST", "integrations", {
|
|
1679
|
+
apiKey: globalOpts.apiKey,
|
|
1680
|
+
baseUrl: globalOpts.baseUrl,
|
|
1681
|
+
dryRun: globalOpts.dryRun,
|
|
1682
|
+
verbose: globalOpts.verbose,
|
|
1683
|
+
body
|
|
1684
|
+
});
|
|
1762
1685
|
printJson(data);
|
|
1763
1686
|
} catch (error) {
|
|
1764
1687
|
printError(error);
|
|
@@ -1778,16 +1701,12 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
1778
1701
|
return;
|
|
1779
1702
|
}
|
|
1780
1703
|
}
|
|
1781
|
-
await apiRequest(
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
dryRun: globalOpts.dryRun,
|
|
1788
|
-
verbose: globalOpts.verbose
|
|
1789
|
-
}
|
|
1790
|
-
);
|
|
1704
|
+
await apiRequest("DELETE", `integrations/${opts.id}`, {
|
|
1705
|
+
apiKey: globalOpts.apiKey,
|
|
1706
|
+
baseUrl: globalOpts.baseUrl,
|
|
1707
|
+
dryRun: globalOpts.dryRun,
|
|
1708
|
+
verbose: globalOpts.verbose
|
|
1709
|
+
});
|
|
1791
1710
|
console.log(`\u2713 Integration ${opts.id} deleted.`);
|
|
1792
1711
|
} catch (error) {
|
|
1793
1712
|
printError(error);
|
|
@@ -1797,16 +1716,12 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
1797
1716
|
integrations.command("config-spec").description("Get integration configuration field specs").action(async () => {
|
|
1798
1717
|
try {
|
|
1799
1718
|
const globalOpts = program.opts();
|
|
1800
|
-
const data = await apiRequest(
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
dryRun: globalOpts.dryRun,
|
|
1807
|
-
verbose: globalOpts.verbose
|
|
1808
|
-
}
|
|
1809
|
-
);
|
|
1719
|
+
const data = await apiRequest("GET", "integrations/config-spec", {
|
|
1720
|
+
apiKey: globalOpts.apiKey,
|
|
1721
|
+
baseUrl: globalOpts.baseUrl,
|
|
1722
|
+
dryRun: globalOpts.dryRun,
|
|
1723
|
+
verbose: globalOpts.verbose
|
|
1724
|
+
});
|
|
1810
1725
|
printJson(data);
|
|
1811
1726
|
} catch (error) {
|
|
1812
1727
|
printError(error);
|
|
@@ -1855,17 +1770,13 @@ function registerLogCommands(program) {
|
|
|
1855
1770
|
if (opts.keyword) params.searchKeyword = opts.keyword;
|
|
1856
1771
|
if (opts.startDate) params.startDate = opts.startDate;
|
|
1857
1772
|
if (opts.endDate) params.endDate = opts.endDate;
|
|
1858
|
-
const data = await apiRequest(
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
verbose: globalOpts.verbose,
|
|
1866
|
-
params
|
|
1867
|
-
}
|
|
1868
|
-
);
|
|
1773
|
+
const data = await apiRequest("GET", "failure-logs", {
|
|
1774
|
+
apiKey: globalOpts.apiKey,
|
|
1775
|
+
baseUrl: globalOpts.baseUrl,
|
|
1776
|
+
dryRun: globalOpts.dryRun,
|
|
1777
|
+
verbose: globalOpts.verbose,
|
|
1778
|
+
params
|
|
1779
|
+
});
|
|
1869
1780
|
if (format === "table") {
|
|
1870
1781
|
printTable(
|
|
1871
1782
|
["ID", "Category", "Task", "Status", "Retries", "Error", "Created"],
|
|
@@ -1893,16 +1804,12 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
1893
1804
|
logs.command("get").description("Get failure log detail").requiredOption("--id <logId>", "Log ID").action(async (opts) => {
|
|
1894
1805
|
try {
|
|
1895
1806
|
const globalOpts = program.opts();
|
|
1896
|
-
const data = await apiRequest(
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
dryRun: globalOpts.dryRun,
|
|
1903
|
-
verbose: globalOpts.verbose
|
|
1904
|
-
}
|
|
1905
|
-
);
|
|
1807
|
+
const data = await apiRequest("GET", `failure-logs/${opts.id}`, {
|
|
1808
|
+
apiKey: globalOpts.apiKey,
|
|
1809
|
+
baseUrl: globalOpts.baseUrl,
|
|
1810
|
+
dryRun: globalOpts.dryRun,
|
|
1811
|
+
verbose: globalOpts.verbose
|
|
1812
|
+
});
|
|
1906
1813
|
printJson(data);
|
|
1907
1814
|
} catch (error) {
|
|
1908
1815
|
printError(error);
|
|
@@ -1933,17 +1840,13 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
1933
1840
|
try {
|
|
1934
1841
|
const globalOpts = program.opts();
|
|
1935
1842
|
const logIds = opts.ids.split(",").map((id) => id.trim());
|
|
1936
|
-
const data = await apiRequest(
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
verbose: globalOpts.verbose,
|
|
1944
|
-
body: { logIds, action: opts.action }
|
|
1945
|
-
}
|
|
1946
|
-
);
|
|
1843
|
+
const data = await apiRequest("POST", "failure-logs/bulk-actions", {
|
|
1844
|
+
apiKey: globalOpts.apiKey,
|
|
1845
|
+
baseUrl: globalOpts.baseUrl,
|
|
1846
|
+
dryRun: globalOpts.dryRun,
|
|
1847
|
+
verbose: globalOpts.verbose,
|
|
1848
|
+
body: { logIds, action: opts.action }
|
|
1849
|
+
});
|
|
1947
1850
|
printJson(data);
|
|
1948
1851
|
} catch (error) {
|
|
1949
1852
|
printError(error);
|
|
@@ -1968,7 +1871,10 @@ function createCallApiFromConfig() {
|
|
|
1968
1871
|
try {
|
|
1969
1872
|
const config = loadConfig();
|
|
1970
1873
|
if (opts?.upload) {
|
|
1971
|
-
const url = new URL(
|
|
1874
|
+
const url = new URL(
|
|
1875
|
+
path,
|
|
1876
|
+
config.baseUrl.endsWith("/") ? config.baseUrl : config.baseUrl + "/"
|
|
1877
|
+
);
|
|
1972
1878
|
if (opts.params) {
|
|
1973
1879
|
for (const [key, value] of Object.entries(opts.params)) {
|
|
1974
1880
|
if (value !== void 0) url.searchParams.set(key, value);
|
|
@@ -2036,18 +1942,14 @@ function registerGroupTools(server, callApi) {
|
|
|
2036
1942
|
"lexq_groups_list",
|
|
2037
1943
|
{
|
|
2038
1944
|
title: "List Policy Groups",
|
|
2039
|
-
description: "List all policy groups
|
|
1945
|
+
description: "List all policy groups with pagination.",
|
|
2040
1946
|
inputSchema: {
|
|
2041
1947
|
page: z.number().int().min(0).default(0).describe("Page number (0-indexed)"),
|
|
2042
|
-
size: z.number().int().min(1).max(100).default(20).describe("Page size")
|
|
2043
|
-
status: z.enum(["ACTIVE", "DISABLED", "ARCHIVED"]).optional().describe("Filter by status"),
|
|
2044
|
-
keyword: z.string().optional().describe("Search keyword")
|
|
1948
|
+
size: z.number().int().min(1).max(100).default(20).describe("Page size")
|
|
2045
1949
|
}
|
|
2046
1950
|
},
|
|
2047
|
-
async ({ page, size
|
|
1951
|
+
async ({ page, size }) => {
|
|
2048
1952
|
const params = paginationParams(page, size);
|
|
2049
|
-
if (status) params.status = status;
|
|
2050
|
-
if (keyword) params.keyword = keyword;
|
|
2051
1953
|
return callApi("GET", "policy-groups", { params });
|
|
2052
1954
|
}
|
|
2053
1955
|
);
|
|
@@ -2088,8 +1990,7 @@ function registerGroupTools(server, callApi) {
|
|
|
2088
1990
|
if (args.conflictResolutionStrategy !== void 0)
|
|
2089
1991
|
body.conflictResolutionStrategy = args.conflictResolutionStrategy;
|
|
2090
1992
|
if (args.maxSelections !== void 0) body.maxSelections = args.maxSelections;
|
|
2091
|
-
if (args.activationGroupId !== void 0)
|
|
2092
|
-
body.activationGroupId = args.activationGroupId;
|
|
1993
|
+
if (args.activationGroupId !== void 0) body.activationGroupId = args.activationGroupId;
|
|
2093
1994
|
return callApi("POST", "policy-groups", { body });
|
|
2094
1995
|
}
|
|
2095
1996
|
);
|
|
@@ -2109,7 +2010,7 @@ function registerGroupTools(server, callApi) {
|
|
|
2109
2010
|
maxSelections: z.number().int().min(1).optional().describe("Max selections")
|
|
2110
2011
|
}
|
|
2111
2012
|
},
|
|
2112
|
-
async ({ groupId, ...body }) => callApi("
|
|
2013
|
+
async ({ groupId, ...body }) => callApi("PUT", `policy-groups/${groupId}`, { body })
|
|
2113
2014
|
);
|
|
2114
2015
|
server.registerTool(
|
|
2115
2016
|
"lexq_groups_delete",
|
|
@@ -2126,41 +2027,37 @@ function registerGroupTools(server, callApi) {
|
|
|
2126
2027
|
"lexq_ab_test_start",
|
|
2127
2028
|
{
|
|
2128
2029
|
title: "Start A/B Test",
|
|
2129
|
-
description: "Start an A/B test on a policy group. Requires a challenger version ID and traffic
|
|
2030
|
+
description: "Start an A/B test on a policy group. Requires a challenger version ID and traffic rate.",
|
|
2130
2031
|
inputSchema: {
|
|
2131
2032
|
groupId: z.string().uuid().describe("Policy group ID"),
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
challengerWeight: z.number().int().min(1).max(99).describe("Challenger traffic weight (%)"),
|
|
2135
|
-
identityKey: z.string().optional().describe("Fact key for sticky assignment (e.g. customer_id)")
|
|
2033
|
+
testVersionId: z.string().uuid().describe("Challenger version ID to test"),
|
|
2034
|
+
trafficRate: z.number().int().min(1).max(99).describe("Traffic percentage routed to challenger (1-99)")
|
|
2136
2035
|
}
|
|
2137
2036
|
},
|
|
2138
|
-
async ({ groupId, ...body }) => callApi("POST", `policy-groups/${groupId}/ab-test
|
|
2037
|
+
async ({ groupId, ...body }) => callApi("POST", `policy-groups/${groupId}/ab-test`, { body })
|
|
2139
2038
|
);
|
|
2140
2039
|
server.registerTool(
|
|
2141
2040
|
"lexq_ab_test_stop",
|
|
2142
2041
|
{
|
|
2143
2042
|
title: "Stop A/B Test",
|
|
2144
|
-
description: "Stop a running A/B test.
|
|
2043
|
+
description: "Stop a running A/B test. All traffic is restored to the control (current) version.",
|
|
2145
2044
|
inputSchema: {
|
|
2146
|
-
groupId: z.string().uuid().describe("Policy group ID")
|
|
2147
|
-
winnerVersionId: z.string().uuid().describe("Version ID to keep as live")
|
|
2045
|
+
groupId: z.string().uuid().describe("Policy group ID")
|
|
2148
2046
|
}
|
|
2149
2047
|
},
|
|
2150
|
-
async ({ groupId
|
|
2048
|
+
async ({ groupId }) => callApi("DELETE", `policy-groups/${groupId}/ab-test`)
|
|
2151
2049
|
);
|
|
2152
2050
|
server.registerTool(
|
|
2153
2051
|
"lexq_ab_test_adjust",
|
|
2154
2052
|
{
|
|
2155
2053
|
title: "Adjust A/B Test",
|
|
2156
|
-
description: "Adjust traffic
|
|
2054
|
+
description: "Adjust traffic rate of a running A/B test.",
|
|
2157
2055
|
inputSchema: {
|
|
2158
2056
|
groupId: z.string().uuid().describe("Policy group ID"),
|
|
2159
|
-
|
|
2160
|
-
challengerWeight: z.number().int().min(1).max(99).describe("New challenger weight (%)")
|
|
2057
|
+
trafficRate: z.number().int().min(1).max(99).describe("New traffic percentage for challenger (1-99)")
|
|
2161
2058
|
}
|
|
2162
2059
|
},
|
|
2163
|
-
async ({ groupId, ...body }) => callApi("
|
|
2060
|
+
async ({ groupId, ...body }) => callApi("PATCH", `policy-groups/${groupId}/ab-test/traffic-rate`, { body })
|
|
2164
2061
|
);
|
|
2165
2062
|
}
|
|
2166
2063
|
|
|
@@ -2221,7 +2118,7 @@ function registerVersionTools(server, callApi) {
|
|
|
2221
2118
|
effectiveTo: z2.string().optional().describe("New effective end date")
|
|
2222
2119
|
}
|
|
2223
2120
|
},
|
|
2224
|
-
async ({ groupId, versionId, ...body }) => callApi("
|
|
2121
|
+
async ({ groupId, versionId, ...body }) => callApi("PUT", `policy-groups/${groupId}/versions/${versionId}`, { body })
|
|
2225
2122
|
);
|
|
2226
2123
|
server.registerTool(
|
|
2227
2124
|
"lexq_versions_delete",
|
|
@@ -2242,15 +2139,12 @@ function registerVersionTools(server, callApi) {
|
|
|
2242
2139
|
description: "Clone an existing version to create a new DRAFT. Useful when the source version is already published.",
|
|
2243
2140
|
inputSchema: {
|
|
2244
2141
|
groupId: z2.string().uuid().describe("Policy group ID"),
|
|
2245
|
-
versionId: z2.string().uuid().describe("Source version ID to clone")
|
|
2246
|
-
commitMessage: z2.string().optional().describe("Commit message for the cloned version")
|
|
2142
|
+
versionId: z2.string().uuid().describe("Source version ID to clone")
|
|
2247
2143
|
}
|
|
2248
2144
|
},
|
|
2249
|
-
async ({ groupId, versionId
|
|
2250
|
-
const body = {};
|
|
2251
|
-
if (commitMessage !== void 0) body.commitMessage = commitMessage;
|
|
2145
|
+
async ({ groupId, versionId }) => {
|
|
2252
2146
|
return callApi("POST", `policy-groups/${groupId}/versions/${versionId}/clone`, {
|
|
2253
|
-
body
|
|
2147
|
+
body: {}
|
|
2254
2148
|
});
|
|
2255
2149
|
}
|
|
2256
2150
|
);
|
|
@@ -2286,23 +2180,27 @@ function registerRuleTools(server, callApi) {
|
|
|
2286
2180
|
ruleId: z3.string().uuid().describe("Rule ID")
|
|
2287
2181
|
}
|
|
2288
2182
|
},
|
|
2289
|
-
async ({ groupId, versionId, ruleId }) => callApi(
|
|
2290
|
-
"GET",
|
|
2291
|
-
`policy-groups/${groupId}/versions/${versionId}/rules/${ruleId}`
|
|
2292
|
-
)
|
|
2183
|
+
async ({ groupId, versionId, ruleId }) => callApi("GET", `policy-groups/${groupId}/versions/${versionId}/rules/${ruleId}`)
|
|
2293
2184
|
);
|
|
2294
2185
|
server.registerTool(
|
|
2295
2186
|
"lexq_rules_create",
|
|
2296
2187
|
{
|
|
2297
2188
|
title: "Create Rule",
|
|
2298
|
-
description: `Create a rule in a DRAFT version. Requires name, priority, condition tree, and actions array.
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2189
|
+
description: `Create a rule in a DRAFT version. Requires name, priority, condition tree, and actions array.
|
|
2190
|
+
Condition: { type: "SINGLE", field, operator, value, valueType } or { type: "GROUP", operator: "AND"|"OR", children: [...] }
|
|
2191
|
+
Operators: EQUALS, NOT_EQUALS, GREATER_THAN, GREATER_THAN_OR_EQUAL, LESS_THAN, LESS_THAN_OR_EQUAL, CONTAINS, IN, NOT_IN
|
|
2192
|
+
Value types: STRING, NUMBER, BOOLEAN, LIST_STRING, LIST_NUMBER
|
|
2193
|
+
|
|
2194
|
+
Actions: [{ type, parameters }]
|
|
2195
|
+
|
|
2196
|
+
Action parameter schemas:
|
|
2197
|
+
- DISCOUNT: { refVar: string, method: "PERCENTAGE"|"AMOUNT", rate?: number (when PERCENTAGE), value?: number (when AMOUNT) }
|
|
2198
|
+
- POINT: { refVar: string, targetVar: string, method: "PERCENTAGE"|"AMOUNT", rate?: number (when PERCENTAGE), value?: number (when AMOUNT), integrationId: uuid }
|
|
2199
|
+
- COUPON_ISSUE: { couponId: string, integrationId: uuid }- BLOCK: { reason: string }
|
|
2200
|
+
- NOTIFICATION: { channel: "SMS"|"EMAIL"|"PUSH"|"KAKAO", targetVar: string, templateId: string, integrationId: uuid }
|
|
2201
|
+
- WEBHOOK: { url: string, method: "POST" }
|
|
2202
|
+
- SET_FACT: { key: string, value: string|number|boolean }
|
|
2203
|
+
- ADD_TAG: { tag: string, targetVar: string }`,
|
|
2306
2204
|
inputSchema: {
|
|
2307
2205
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
2308
2206
|
versionId: z3.string().uuid().describe("Version ID"),
|
|
@@ -2313,11 +2211,7 @@ Types: DISCOUNT, POINT, COUPON_ISSUE, BLOCK, NOTIFICATION, WEBHOOK, SET_FACT, AD
|
|
|
2313
2211
|
},
|
|
2314
2212
|
async ({ groupId, versionId, rule }) => {
|
|
2315
2213
|
const body = JSON.parse(rule);
|
|
2316
|
-
return callApi(
|
|
2317
|
-
"POST",
|
|
2318
|
-
`policy-groups/${groupId}/versions/${versionId}/rules`,
|
|
2319
|
-
{ body }
|
|
2320
|
-
);
|
|
2214
|
+
return callApi("POST", `policy-groups/${groupId}/versions/${versionId}/rules`, { body });
|
|
2321
2215
|
}
|
|
2322
2216
|
);
|
|
2323
2217
|
server.registerTool(
|
|
@@ -2336,11 +2230,9 @@ Types: DISCOUNT, POINT, COUPON_ISSUE, BLOCK, NOTIFICATION, WEBHOOK, SET_FACT, AD
|
|
|
2336
2230
|
},
|
|
2337
2231
|
async ({ groupId, versionId, ruleId, rule }) => {
|
|
2338
2232
|
const body = JSON.parse(rule);
|
|
2339
|
-
return callApi(
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
{ body }
|
|
2343
|
-
);
|
|
2233
|
+
return callApi("PUT", `policy-groups/${groupId}/versions/${versionId}/rules/${ruleId}`, {
|
|
2234
|
+
body
|
|
2235
|
+
});
|
|
2344
2236
|
}
|
|
2345
2237
|
);
|
|
2346
2238
|
server.registerTool(
|
|
@@ -2358,11 +2250,9 @@ Types: DISCOUNT, POINT, COUPON_ISSUE, BLOCK, NOTIFICATION, WEBHOOK, SET_FACT, AD
|
|
|
2358
2250
|
async ({ groupId, versionId, ruleId, force }) => {
|
|
2359
2251
|
const params = {};
|
|
2360
2252
|
if (force) params.force = "true";
|
|
2361
|
-
return callApi(
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
{ params }
|
|
2365
|
-
);
|
|
2253
|
+
return callApi("DELETE", `policy-groups/${groupId}/versions/${versionId}/rules/${ruleId}`, {
|
|
2254
|
+
params
|
|
2255
|
+
});
|
|
2366
2256
|
}
|
|
2367
2257
|
);
|
|
2368
2258
|
server.registerTool(
|
|
@@ -2381,11 +2271,9 @@ Types: DISCOUNT, POINT, COUPON_ISSUE, BLOCK, NOTIFICATION, WEBHOOK, SET_FACT, AD
|
|
|
2381
2271
|
ruleId,
|
|
2382
2272
|
priority: index
|
|
2383
2273
|
}));
|
|
2384
|
-
return callApi(
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
{ body: { rules } }
|
|
2388
|
-
);
|
|
2274
|
+
return callApi("PATCH", `policy-groups/${groupId}/versions/${versionId}/rules/reorder`, {
|
|
2275
|
+
body: { rules }
|
|
2276
|
+
});
|
|
2389
2277
|
}
|
|
2390
2278
|
);
|
|
2391
2279
|
server.registerTool(
|
|
@@ -2400,11 +2288,9 @@ Types: DISCOUNT, POINT, COUPON_ISSUE, BLOCK, NOTIFICATION, WEBHOOK, SET_FACT, AD
|
|
|
2400
2288
|
isEnabled: z3.boolean().describe("true to enable, false to disable")
|
|
2401
2289
|
}
|
|
2402
2290
|
},
|
|
2403
|
-
async ({ groupId, versionId, ruleId, isEnabled }) => callApi(
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
{ body: { isEnabled } }
|
|
2407
|
-
)
|
|
2291
|
+
async ({ groupId, versionId, ruleId, isEnabled }) => callApi("PATCH", `policy-groups/${groupId}/versions/${versionId}/rules/${ruleId}/enabled`, {
|
|
2292
|
+
body: { isEnabled }
|
|
2293
|
+
})
|
|
2408
2294
|
);
|
|
2409
2295
|
}
|
|
2410
2296
|
|
|
@@ -2455,7 +2341,7 @@ function registerFactTools(server, callApi) {
|
|
|
2455
2341
|
isRequired: z4.boolean().describe("Required flag")
|
|
2456
2342
|
}
|
|
2457
2343
|
},
|
|
2458
|
-
async ({ factId, ...body }) => callApi("
|
|
2344
|
+
async ({ factId, ...body }) => callApi("PUT", `schema/facts/${factId}`, { body })
|
|
2459
2345
|
);
|
|
2460
2346
|
server.registerTool(
|
|
2461
2347
|
"lexq_facts_delete",
|
|
@@ -2484,11 +2370,7 @@ function registerDeployTools(server, callApi) {
|
|
|
2484
2370
|
memo: z5.string().default("").describe("Deployment memo")
|
|
2485
2371
|
}
|
|
2486
2372
|
},
|
|
2487
|
-
async ({ groupId, versionId, memo }) => callApi(
|
|
2488
|
-
"POST",
|
|
2489
|
-
`policy-groups/${groupId}/versions/${versionId}/publish`,
|
|
2490
|
-
{ body: { memo } }
|
|
2491
|
-
)
|
|
2373
|
+
async ({ groupId, versionId, memo }) => callApi("POST", `policy-groups/${groupId}/versions/${versionId}/publish`, { body: { memo } })
|
|
2492
2374
|
);
|
|
2493
2375
|
server.registerTool(
|
|
2494
2376
|
"lexq_deploy_live",
|
|
@@ -2628,10 +2510,7 @@ Always dry-run before publishing to validate rule behavior.`,
|
|
|
2628
2510
|
versionId: z6.string().uuid().describe("Version ID")
|
|
2629
2511
|
}
|
|
2630
2512
|
},
|
|
2631
|
-
async ({ groupId, versionId }) => callApi(
|
|
2632
|
-
"GET",
|
|
2633
|
-
`analytics/groups/${groupId}/versions/${versionId}/requirements`
|
|
2634
|
-
)
|
|
2513
|
+
async ({ groupId, versionId }) => callApi("GET", `analytics/groups/${groupId}/versions/${versionId}/requirements`)
|
|
2635
2514
|
);
|
|
2636
2515
|
server.registerTool(
|
|
2637
2516
|
"lexq_simulation_start",
|
|
@@ -2746,11 +2625,9 @@ JSON example:
|
|
|
2746
2625
|
format: z6.enum(["csv", "json"]).default("csv").describe("Template format")
|
|
2747
2626
|
}
|
|
2748
2627
|
},
|
|
2749
|
-
async ({ groupId, versionId, format }) => callApi(
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
{ params: { format } }
|
|
2753
|
-
)
|
|
2628
|
+
async ({ groupId, versionId, format }) => callApi("GET", `analytics/groups/${groupId}/versions/${versionId}/dataset-template`, {
|
|
2629
|
+
params: { format }
|
|
2630
|
+
})
|
|
2754
2631
|
);
|
|
2755
2632
|
}
|
|
2756
2633
|
|
|
@@ -2978,9 +2855,7 @@ function registerAllTools(server, callApi) {
|
|
|
2978
2855
|
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
2979
2856
|
function getVersion() {
|
|
2980
2857
|
try {
|
|
2981
|
-
const pkg = JSON.parse(
|
|
2982
|
-
readFileSync3(join2(__dirname, "..", "package.json"), "utf-8")
|
|
2983
|
-
);
|
|
2858
|
+
const pkg = JSON.parse(readFileSync3(join2(__dirname, "..", "package.json"), "utf-8"));
|
|
2984
2859
|
return pkg.version;
|
|
2985
2860
|
} catch {
|
|
2986
2861
|
return "0.1.0";
|