@lexq/cli 1.0.1 → 1.0.2
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
|
@@ -269,7 +269,7 @@ function registerAuthCommands(program) {
|
|
|
269
269
|
|
|
270
270
|
Example:
|
|
271
271
|
$ lexq auth whoami
|
|
272
|
-
{ "tenantId": "abc-123", "userId": "...", "role": "ADMIN", "apiKey": "lexq_us_****abcd" }
|
|
272
|
+
{ "tenantId": "abc-123", "userId": "...", "role": "ADMIN", "tenantTimezone": "Asia/Seoul", "apiKey": "lexq_us_****abcd" }
|
|
273
273
|
`
|
|
274
274
|
).action(async () => {
|
|
275
275
|
try {
|
|
@@ -310,9 +310,10 @@ function registerStatusCommand(program) {
|
|
|
310
310
|
|
|
311
311
|
Example:
|
|
312
312
|
$ lexq status
|
|
313
|
-
{ "status": "ok", "latencyMs": 142, "tenantId": "abc-123", "role": "ADMIN" }
|
|
313
|
+
{ "status": "ok", "latencyMs": 142, "tenantId": "abc-123", "role": "ADMIN", "tenantTimezone": "Asia/Seoul" }
|
|
314
314
|
|
|
315
315
|
Use this to verify your API key is valid and the LexQ API is reachable.
|
|
316
|
+
tenantTimezone is the zone every yyyy-MM-dd date option is read in.
|
|
316
317
|
`
|
|
317
318
|
).action(async () => {
|
|
318
319
|
const globalOpts = program.opts();
|
|
@@ -326,7 +327,8 @@ function registerStatusCommand(program) {
|
|
|
326
327
|
status: "ok",
|
|
327
328
|
latencyMs: Date.now() - startTime,
|
|
328
329
|
tenantId: info.tenantId,
|
|
329
|
-
role: info.role
|
|
330
|
+
role: info.role,
|
|
331
|
+
tenantTimezone: info.tenantTimezone
|
|
330
332
|
});
|
|
331
333
|
} catch (error) {
|
|
332
334
|
printError(error);
|
|
@@ -357,6 +359,22 @@ var MAX_SNAPSHOT_BYTES = 131072;
|
|
|
357
359
|
// src/commands/groups.ts
|
|
358
360
|
import "commander";
|
|
359
361
|
import dedent3 from "dedent";
|
|
362
|
+
|
|
363
|
+
// src/lib/dates.ts
|
|
364
|
+
var ORG_DAY = "yyyy-MM-dd, a whole calendar day in the organization time zone (tenantTimezone in whoami), not UTC";
|
|
365
|
+
var START_DAY = `Start date, ${ORG_DAY}. Inclusive.`;
|
|
366
|
+
var END_DAY = `End date, ${ORG_DAY}. Inclusive: the whole day counts.`;
|
|
367
|
+
var WINDOW_START_DAY = `Window start date, ${ORG_DAY}. Inclusive.`;
|
|
368
|
+
var WINDOW_END_DAY = `Window end date, ${ORG_DAY}. Inclusive: the whole day counts.`;
|
|
369
|
+
var INSTANT = "ISO-8601 instant with Z or an offset, e.g. 2026-10-01T00:00:00Z or 2026-10-01T09:00:00+09:00. A bare date or a time without an offset is rejected.";
|
|
370
|
+
var STATS_DEFAULT_WINDOW_DAYS = 30;
|
|
371
|
+
var STATS_MAX_WINDOW_DAYS = 31;
|
|
372
|
+
var FAILURE_LOG_LOOKBACK_DAYS = 7;
|
|
373
|
+
function utcMinute(instant) {
|
|
374
|
+
return instant ? `${new Date(instant).toISOString().substring(0, 16)}Z` : "\u2013";
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// src/commands/groups.ts
|
|
360
378
|
function registerGroupCommands(program) {
|
|
361
379
|
const groups = program.command("groups").description("Manage policy groups").addHelpText(
|
|
362
380
|
"after",
|
|
@@ -396,7 +414,7 @@ function registerGroupCommands(program) {
|
|
|
396
414
|
g.status,
|
|
397
415
|
String(g.priority),
|
|
398
416
|
g.currentVersionName ?? "\u2013",
|
|
399
|
-
g.updatedAt
|
|
417
|
+
utcMinute(g.updatedAt)
|
|
400
418
|
]),
|
|
401
419
|
{ truncate: 24 }
|
|
402
420
|
);
|
|
@@ -714,7 +732,7 @@ function registerVersionCommands(program) {
|
|
|
714
732
|
v.status,
|
|
715
733
|
v.commitMessage ?? "\u2013",
|
|
716
734
|
v.snapshotHash ? v.snapshotHash.substring(0, 8) : "\u2013",
|
|
717
|
-
v.createdAt
|
|
735
|
+
utcMinute(v.createdAt)
|
|
718
736
|
]),
|
|
719
737
|
{ truncate: 24 }
|
|
720
738
|
);
|
|
@@ -747,7 +765,7 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
747
765
|
process.exit(1);
|
|
748
766
|
}
|
|
749
767
|
});
|
|
750
|
-
versions.command("create").description("Create a new draft version").requiredOption("--group-id <groupId>", "Policy group ID").option("--commit-message <message>", "Commit message").option("--effective-from <
|
|
768
|
+
versions.command("create").description("Create a new draft version").requiredOption("--group-id <groupId>", "Policy group ID").option("--commit-message <message>", "Commit message").option("--effective-from <instant>", `Effective start, ${INSTANT}`).option("--effective-to <instant>", `Effective end, ${INSTANT}`).option("--json <body>", "Full request body as JSON (overrides other options)").addHelpText(
|
|
751
769
|
"after",
|
|
752
770
|
dedent4`
|
|
753
771
|
|
|
@@ -762,8 +780,8 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
762
780
|
|
|
763
781
|
Fields:
|
|
764
782
|
commitMessage string Version description (optional, max 255 chars)
|
|
765
|
-
effectiveFrom
|
|
766
|
-
effectiveTo
|
|
783
|
+
effectiveFrom instant Start of effective period (optional, with Z or an offset)
|
|
784
|
+
effectiveTo instant End of effective period (optional, auto-expires)
|
|
767
785
|
`
|
|
768
786
|
).action(async (opts) => {
|
|
769
787
|
try {
|
|
@@ -786,12 +804,16 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
786
804
|
process.exit(1);
|
|
787
805
|
}
|
|
788
806
|
});
|
|
789
|
-
versions.command("update").description("Update a draft version metadata").requiredOption("--group-id <groupId>", "Policy group ID").requiredOption("--id <versionId>", "Policy version ID").option("--commit-message <message>", "Commit message").option("--effective-from <
|
|
807
|
+
versions.command("update").description("Update a draft version metadata").requiredOption("--group-id <groupId>", "Policy group ID").requiredOption("--id <versionId>", "Policy version ID").option("--commit-message <message>", "Commit message").option("--effective-from <instant>", `Effective start, ${INSTANT}`).option("--effective-to <instant>", `Effective end, ${INSTANT}`).option("--json <body>", "Full request body as JSON (overrides other options)").addHelpText(
|
|
790
808
|
"after",
|
|
791
809
|
dedent4`
|
|
792
810
|
|
|
793
811
|
Only DRAFT versions can be updated. Published (ACTIVE) versions are immutable.
|
|
794
812
|
|
|
813
|
+
An omitted --commit-message keeps its value, but --effective-from and --effective-to
|
|
814
|
+
are replaced together: one you omit is cleared. To keep the effective window, pass
|
|
815
|
+
both current values (read them with lexq versions get).
|
|
816
|
+
|
|
795
817
|
Example:
|
|
796
818
|
$ lexq versions update --group-id <gid> --id <vid> --commit-message "Updated rules"
|
|
797
819
|
`
|
|
@@ -1742,7 +1764,7 @@ function registerDeployCommands(program) {
|
|
|
1742
1764
|
process.exit(1);
|
|
1743
1765
|
}
|
|
1744
1766
|
});
|
|
1745
|
-
deploy.command("history").description("List deployment history").option("--group-id <groupId>", "Filter by policy group").option("--types <types>", "Filter by types (comma-separated: DEPLOY,ROLLBACK,UNDEPLOY)").option("--start-date <date>",
|
|
1767
|
+
deploy.command("history").description("List deployment history").option("--group-id <groupId>", "Filter by policy group").option("--types <types>", "Filter by types (comma-separated: DEPLOY,ROLLBACK,UNDEPLOY)").option("--start-date <date>", START_DAY).option("--end-date <date>", END_DAY).option("--page <number>", "Page number", "0").option("--size <number>", "Page size", "20").addHelpText(
|
|
1746
1768
|
"after",
|
|
1747
1769
|
dedent7`
|
|
1748
1770
|
|
|
@@ -1774,7 +1796,7 @@ function registerDeployCommands(program) {
|
|
|
1774
1796
|
d.policyGroupName,
|
|
1775
1797
|
d.versionNo != null ? `v${d.versionNo}` : "\u2013",
|
|
1776
1798
|
d.deployedByName,
|
|
1777
|
-
d.deployedAt
|
|
1799
|
+
utcMinute(d.deployedAt)
|
|
1778
1800
|
]),
|
|
1779
1801
|
{ truncate: 20 }
|
|
1780
1802
|
);
|
|
@@ -1836,7 +1858,7 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
1836
1858
|
d.groupName,
|
|
1837
1859
|
d.groupStatus,
|
|
1838
1860
|
d.currentVersionName ?? "\u2013",
|
|
1839
|
-
d.lastDeployedAt
|
|
1861
|
+
utcMinute(d.lastDeployedAt)
|
|
1840
1862
|
])
|
|
1841
1863
|
);
|
|
1842
1864
|
} else {
|
|
@@ -1903,6 +1925,8 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
1903
1925
|
|
|
1904
1926
|
The version must be ACTIVE with a future effective start date; the system
|
|
1905
1927
|
deploys it automatically at that time (within one scheduler tick, ≤60s).
|
|
1928
|
+
That time is the version's effectiveFrom, set on the DRAFT before publishing;
|
|
1929
|
+
this command takes no time of its own.
|
|
1906
1930
|
One pending schedule per group. Manual deploy/rollback/undeploy, starting
|
|
1907
1931
|
an A/B test, or archiving the group cancels the pending schedule.
|
|
1908
1932
|
|
|
@@ -1994,9 +2018,9 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
1994
2018
|
s.status,
|
|
1995
2019
|
s.policyGroupName ?? s.policyGroupId.substring(0, 8),
|
|
1996
2020
|
s.versionNo != null ? `v${s.versionNo}` : "\u2013",
|
|
1997
|
-
s.scheduledFor
|
|
2021
|
+
utcMinute(s.scheduledFor),
|
|
1998
2022
|
s.scheduledByName,
|
|
1999
|
-
s.status === "EXECUTED" ? s.executedAt
|
|
2023
|
+
s.status === "EXECUTED" ? utcMinute(s.executedAt) : s.status === "CANCELED" ? s.canceledReason ?? "\u2013" : s.status === "FAILED" ? s.failedReason ?? "\u2013" : "\u2013"
|
|
2000
2024
|
]),
|
|
2001
2025
|
{ truncate: 20 }
|
|
2002
2026
|
);
|
|
@@ -2199,6 +2223,7 @@ function registerAnalyticsCommands(program) {
|
|
|
2199
2223
|
|
|
2200
2224
|
Dataset types: HISTORICAL, UPLOADED, MANUAL
|
|
2201
2225
|
Dataset sources: EXECUTION_LOGS, S3_BUCKET, REQUEST_BODY
|
|
2226
|
+
HISTORICAL from / to are yyyy-MM-dd, whole days in the organization time zone, both inclusive.
|
|
2202
2227
|
`
|
|
2203
2228
|
).action(async (opts) => {
|
|
2204
2229
|
try {
|
|
@@ -2315,7 +2340,7 @@ function registerAnalyticsCommands(program) {
|
|
|
2315
2340
|
process.exit(1);
|
|
2316
2341
|
}
|
|
2317
2342
|
});
|
|
2318
|
-
sim.command("list").description("List simulation history").option("--status <status>", "Filter by status (PENDING, RUNNING, COMPLETED, FAILED, CANCELED)").option("--from <date>",
|
|
2343
|
+
sim.command("list").description("List simulation history").option("--status <status>", "Filter by status (PENDING, RUNNING, COMPLETED, FAILED, CANCELED)").option("--from <date>", START_DAY).option("--to <date>", END_DAY).option("--page <number>", "Page number", "0").option("--size <number>", "Page size", "20").action(async (opts) => {
|
|
2319
2344
|
try {
|
|
2320
2345
|
const globalOpts = program.opts();
|
|
2321
2346
|
const format = globalOpts.format ?? "json";
|
|
@@ -2344,7 +2369,7 @@ function registerAnalyticsCommands(program) {
|
|
|
2344
2369
|
s.status,
|
|
2345
2370
|
`${s.matchRate.toFixed(1)}%`,
|
|
2346
2371
|
String(s.totalRecords),
|
|
2347
|
-
s.createdAt
|
|
2372
|
+
utcMinute(s.createdAt)
|
|
2348
2373
|
]),
|
|
2349
2374
|
{ truncate: 20 }
|
|
2350
2375
|
);
|
|
@@ -2665,7 +2690,7 @@ function registerHistoryCommands(program) {
|
|
|
2665
2690
|
Statuses: SUCCESS, NO_MATCH, ERROR, TIMEOUT
|
|
2666
2691
|
`
|
|
2667
2692
|
);
|
|
2668
|
-
history.command("list").description("List execution history").option("--trace-id <traceId>", "Filter by trace ID").option("--group-id <groupId>", "Filter by policy group").option("--version-id <versionId>", "Filter by version").option("--status <status>", "Filter by status (SUCCESS, NO_MATCH, ERROR, TIMEOUT)").option("--start-date <date>",
|
|
2693
|
+
history.command("list").description("List execution history").option("--trace-id <traceId>", "Filter by trace ID").option("--group-id <groupId>", "Filter by policy group").option("--version-id <versionId>", "Filter by version").option("--status <status>", "Filter by status (SUCCESS, NO_MATCH, ERROR, TIMEOUT)").option("--start-date <date>", START_DAY).option("--end-date <date>", END_DAY).option("--page <number>", "Page number", "0").option("--size <number>", "Page size", "20").addHelpText(
|
|
2669
2694
|
"after",
|
|
2670
2695
|
dedent10`
|
|
2671
2696
|
|
|
@@ -2705,7 +2730,7 @@ function registerHistoryCommands(program) {
|
|
|
2705
2730
|
h.status,
|
|
2706
2731
|
h.isMatched ? "\u2713" : "\u2717",
|
|
2707
2732
|
`${h.latencyMs}ms`,
|
|
2708
|
-
h.createdAt
|
|
2733
|
+
utcMinute(h.createdAt)
|
|
2709
2734
|
]),
|
|
2710
2735
|
{ truncate: 20 }
|
|
2711
2736
|
);
|
|
@@ -2745,15 +2770,19 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
2745
2770
|
process.exit(1);
|
|
2746
2771
|
}
|
|
2747
2772
|
});
|
|
2748
|
-
history.command("stats").description("Get execution statistics").option("--group-id <groupId>", "Filter by policy group").option("--start-date <date>",
|
|
2773
|
+
history.command("stats").description("Get execution statistics").option("--group-id <groupId>", "Filter by policy group").option("--start-date <date>", START_DAY).option("--end-date <date>", END_DAY).addHelpText(
|
|
2749
2774
|
"after",
|
|
2750
2775
|
dedent10`
|
|
2751
2776
|
|
|
2752
2777
|
Shows total executions, success/no-match/failure counts, success rate, and avg latency.
|
|
2753
2778
|
|
|
2779
|
+
Without dates the window is the last ${STATS_DEFAULT_WINDOW_DAYS} days through today, in the organization
|
|
2780
|
+
time zone. At most ${STATS_MAX_WINDOW_DAYS} days per call; a longer range is rejected with AN-039.
|
|
2781
|
+
--start-date alone runs through today.
|
|
2782
|
+
|
|
2754
2783
|
Example:
|
|
2755
2784
|
$ lexq history stats --format table
|
|
2756
|
-
$ lexq history stats --group-id <gid> --start-date 2026-04-01
|
|
2785
|
+
$ lexq history stats --group-id <gid> --start-date 2026-04-01 --end-date 2026-04-30
|
|
2757
2786
|
`
|
|
2758
2787
|
).action(async (opts) => {
|
|
2759
2788
|
try {
|
|
@@ -2840,7 +2869,7 @@ function registerReplayCommands(program) {
|
|
|
2840
2869
|
process.exit(1);
|
|
2841
2870
|
}
|
|
2842
2871
|
});
|
|
2843
|
-
replay.command("start").description("Submit a window replay job (blast radius)").requiredOption("--version-id <versionId>", "Candidate version to re-evaluate against").requiredOption("--from <date>",
|
|
2872
|
+
replay.command("start").description("Submit a window replay job (blast radius)").requiredOption("--version-id <versionId>", "Candidate version to re-evaluate against").requiredOption("--from <date>", WINDOW_START_DAY).requiredOption("--to <date>", WINDOW_END_DAY).option("--max-records <number>", `Sample cap (hard cap ${REPLAY_WINDOW_MAX_RECORDS / 1e3}k)`).addHelpText(
|
|
2844
2873
|
"after",
|
|
2845
2874
|
dedent11`
|
|
2846
2875
|
|
|
@@ -2884,7 +2913,7 @@ function registerReplayCommands(program) {
|
|
|
2884
2913
|
});
|
|
2885
2914
|
if (format === "table") {
|
|
2886
2915
|
printTable(
|
|
2887
|
-
["Job", "Version", "Window", "Status", "Progress", "Changed", "At"],
|
|
2916
|
+
["Job", "Version", "Window (org time zone)", "Status", "Progress", "Changed", "At"],
|
|
2888
2917
|
data.content.map((j) => [
|
|
2889
2918
|
j.jobId.substring(0, 12),
|
|
2890
2919
|
j.candidateVersionName ?? "\u2013",
|
|
@@ -2892,7 +2921,7 @@ function registerReplayCommands(program) {
|
|
|
2892
2921
|
j.status,
|
|
2893
2922
|
`${j.progress}%`,
|
|
2894
2923
|
`${j.changedCount}${j.capped ? " (capped)" : ""}`,
|
|
2895
|
-
j.createdAt
|
|
2924
|
+
utcMinute(j.createdAt)
|
|
2896
2925
|
]),
|
|
2897
2926
|
{ truncate: 24 }
|
|
2898
2927
|
);
|
|
@@ -2998,7 +3027,7 @@ function registerProvenanceCommands(program) {
|
|
|
2998
3027
|
process.exit(1);
|
|
2999
3028
|
}
|
|
3000
3029
|
});
|
|
3001
|
-
provenance.command("reveal-audits").description("List PII reveal audits (who revealed what, when)").option("--trace-id <traceId>", "Filter by trace ID (exact)").option("--fact-key <factKey>", "Filter by fact key (partial, case-insensitive)").option("--revealed-by <operatorId>", "Filter by operator ID (exact)").option("--start-date <date>",
|
|
3030
|
+
provenance.command("reveal-audits").description("List PII reveal audits (who revealed what, when)").option("--trace-id <traceId>", "Filter by trace ID (exact)").option("--fact-key <factKey>", "Filter by fact key (partial, case-insensitive)").option("--revealed-by <operatorId>", "Filter by operator ID (exact)").option("--start-date <date>", START_DAY).option("--end-date <date>", END_DAY).option("--page <number>", "Page number", "0").option("--size <number>", "Page size", "20").addHelpText(
|
|
3002
3031
|
"after",
|
|
3003
3032
|
dedent12`
|
|
3004
3033
|
|
|
@@ -3032,7 +3061,7 @@ function registerProvenanceCommands(program) {
|
|
|
3032
3061
|
printTable(
|
|
3033
3062
|
["Revealed At", "By", "Fact Key", "Trace"],
|
|
3034
3063
|
data.content.map((a) => [
|
|
3035
|
-
a.revealedAt
|
|
3064
|
+
utcMinute(a.revealedAt),
|
|
3036
3065
|
a.revealedByName,
|
|
3037
3066
|
a.factKey,
|
|
3038
3067
|
a.traceId.substring(0, 12)
|
|
@@ -3070,10 +3099,13 @@ function registerLogCommands(program) {
|
|
|
3070
3099
|
Statuses: PENDING (needs attention), RESOLVED, IGNORED
|
|
3071
3100
|
`
|
|
3072
3101
|
);
|
|
3073
|
-
logs.command("list").description("List failure logs").option("--task-type <taskType>", `Filter by task type (${TaskType.join(", ")})`).option("--status <status>", "Filter by status (PENDING, RESOLVED, IGNORED)").option("--keyword <keyword>", "Search keyword").option("--start-date <date>",
|
|
3102
|
+
logs.command("list").description("List failure logs").option("--task-type <taskType>", `Filter by task type (${TaskType.join(", ")})`).option("--status <status>", "Filter by status (PENDING, RESOLVED, IGNORED)").option("--keyword <keyword>", "Search keyword").option("--start-date <date>", START_DAY).option("--end-date <date>", END_DAY).option("--page <number>", "Page number", "0").option("--size <number>", "Page size", "20").addHelpText(
|
|
3074
3103
|
"after",
|
|
3075
3104
|
dedent13`
|
|
3076
3105
|
|
|
3106
|
+
Without dates the window is ${FAILURE_LOG_LOOKBACK_DAYS} days back through today, in the organization
|
|
3107
|
+
time zone. Pass --start-date to look further back.
|
|
3108
|
+
|
|
3077
3109
|
Examples:
|
|
3078
3110
|
$ lexq logs list --status PENDING --format table
|
|
3079
3111
|
$ lexq logs list --task-type PLATFORM_WEBHOOK
|
|
@@ -3104,7 +3136,7 @@ function registerLogCommands(program) {
|
|
|
3104
3136
|
l.taskType,
|
|
3105
3137
|
l.status,
|
|
3106
3138
|
l.errorMessage?.substring(0, 24) ?? "\u2013",
|
|
3107
|
-
l.createdAt
|
|
3139
|
+
utcMinute(l.createdAt)
|
|
3108
3140
|
]),
|
|
3109
3141
|
{ truncate: 24 }
|
|
3110
3142
|
);
|
|
@@ -3502,7 +3534,7 @@ function registerStatusTools(server, callApi) {
|
|
|
3502
3534
|
{
|
|
3503
3535
|
title: "Who Am I",
|
|
3504
3536
|
annotations: { readOnlyHint: true },
|
|
3505
|
-
description:
|
|
3537
|
+
description: 'Show current authentication info (tenant ID, user ID, role) and tenantTimezone, the organization time zone that every yyyy-MM-dd date filter uses. Work out "today" or "yesterday" in that zone, not in UTC.',
|
|
3506
3538
|
inputSchema: z.object({})
|
|
3507
3539
|
},
|
|
3508
3540
|
async () => callApi("GET", "whoami")
|
|
@@ -3700,8 +3732,8 @@ function registerVersionTools(server, callApi) {
|
|
|
3700
3732
|
inputSchema: z3.object({
|
|
3701
3733
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
3702
3734
|
commitMessage: z3.string().optional().describe("Commit message describing this version"),
|
|
3703
|
-
effectiveFrom: z3.string().optional().describe(
|
|
3704
|
-
effectiveTo: z3.string().optional().describe(
|
|
3735
|
+
effectiveFrom: z3.string().optional().describe(`Effective start, ${INSTANT}`),
|
|
3736
|
+
effectiveTo: z3.string().optional().describe(`Effective end, ${INSTANT}`)
|
|
3705
3737
|
})
|
|
3706
3738
|
},
|
|
3707
3739
|
async ({ groupId, ...body }) => callApi("POST", `policy-groups/${groupId}/versions`, { body })
|
|
@@ -3711,13 +3743,13 @@ function registerVersionTools(server, callApi) {
|
|
|
3711
3743
|
{
|
|
3712
3744
|
title: "Update Policy Version",
|
|
3713
3745
|
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
3714
|
-
description: "Update a DRAFT version. Only DRAFT versions can be modified.
|
|
3746
|
+
description: "Update a DRAFT version. Only DRAFT versions can be modified. An omitted commitMessage keeps its value, but effectiveFrom and effectiveTo are replaced together: one you omit is cleared. To keep the effective window, send both current values (read them with lexq_versions_get).",
|
|
3715
3747
|
inputSchema: z3.object({
|
|
3716
3748
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
3717
3749
|
versionId: z3.string().uuid().describe("Version ID"),
|
|
3718
3750
|
commitMessage: z3.string().optional().describe("New commit message"),
|
|
3719
|
-
effectiveFrom: z3.string().optional().describe(
|
|
3720
|
-
effectiveTo: z3.string().optional().describe(
|
|
3751
|
+
effectiveFrom: z3.string().optional().describe(`Effective start, ${INSTANT} Omit it and the start is cleared.`),
|
|
3752
|
+
effectiveTo: z3.string().optional().describe(`Effective end, ${INSTANT} Omit it and the end is cleared.`)
|
|
3721
3753
|
})
|
|
3722
3754
|
},
|
|
3723
3755
|
async ({ groupId, versionId, ...body }) => callApi("PUT", `policy-groups/${groupId}/versions/${versionId}`, { body })
|
|
@@ -4153,7 +4185,7 @@ function registerDeployTools(server, callApi) {
|
|
|
4153
4185
|
{
|
|
4154
4186
|
title: "Schedule Deployment",
|
|
4155
4187
|
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
4156
|
-
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).",
|
|
4188
|
+
description: "Schedule an ACTIVE version with a future effective start date to auto-deploy at that time (Scheduled Deployment). The time is the version's effectiveFrom, set on the DRAFT before publishing; this call takes no time of its own. 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).",
|
|
4157
4189
|
inputSchema: z6.object({
|
|
4158
4190
|
groupId: z6.string().uuid().describe("Policy group ID"),
|
|
4159
4191
|
versionId: z6.string().uuid().describe("ACTIVE version ID with a future effective start date"),
|
|
@@ -4200,8 +4232,8 @@ function registerDeployTools(server, callApi) {
|
|
|
4200
4232
|
size: z6.number().int().min(1).max(100).default(20).describe("Page size"),
|
|
4201
4233
|
groupId: z6.string().uuid().optional().describe("Filter by group ID"),
|
|
4202
4234
|
types: z6.string().optional().describe("Filter by deployment types (comma-separated: DEPLOY,ROLLBACK,UNDEPLOY)"),
|
|
4203
|
-
startDate: z6.string().optional().describe(
|
|
4204
|
-
endDate: z6.string().optional().describe(
|
|
4235
|
+
startDate: z6.string().optional().describe(START_DAY),
|
|
4236
|
+
endDate: z6.string().optional().describe(END_DAY)
|
|
4205
4237
|
})
|
|
4206
4238
|
},
|
|
4207
4239
|
async ({ page, size, groupId, types, startDate, endDate }) => {
|
|
@@ -4345,7 +4377,8 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
4345
4377
|
Start an Impact Simulation against historical, uploaded, or inline data.
|
|
4346
4378
|
|
|
4347
4379
|
dataset.type and dataset.source are BOTH required, and must be paired:
|
|
4348
|
-
HISTORICAL → source EXECUTION_LOGS, with dataset.from / dataset.to (yyyy-MM-dd
|
|
4380
|
+
HISTORICAL → source EXECUTION_LOGS, with dataset.from / dataset.to (yyyy-MM-dd, whole days
|
|
4381
|
+
in the organization time zone, both inclusive)
|
|
4349
4382
|
UPLOADED → source S3_BUCKET, with dataset.path (the path returned by lexq_dataset_upload)
|
|
4350
4383
|
MANUAL → source REQUEST_BODY, with dataset.manualData (array of fact records)
|
|
4351
4384
|
|
|
@@ -4400,8 +4433,8 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
4400
4433
|
page: z7.number().int().min(0).default(0).describe("Page number"),
|
|
4401
4434
|
size: z7.number().int().min(1).max(100).default(20).describe("Page size"),
|
|
4402
4435
|
status: z7.enum(["PENDING", "RUNNING", "COMPLETED", "FAILED", "CANCELED"]).optional().describe("Filter by status"),
|
|
4403
|
-
from: z7.string().optional().describe(
|
|
4404
|
-
to: z7.string().optional().describe(
|
|
4436
|
+
from: z7.string().optional().describe(START_DAY),
|
|
4437
|
+
to: z7.string().optional().describe(END_DAY)
|
|
4405
4438
|
})
|
|
4406
4439
|
},
|
|
4407
4440
|
async ({ page, size, status, from, to }) => {
|
|
@@ -4579,8 +4612,8 @@ function registerReplayTools(server, callApi) {
|
|
|
4579
4612
|
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.",
|
|
4580
4613
|
inputSchema: z9.object({
|
|
4581
4614
|
candidateVersionId: z9.string().uuid().describe("Version to re-evaluate against"),
|
|
4582
|
-
from: z9.string().describe(
|
|
4583
|
-
to: z9.string().describe(
|
|
4615
|
+
from: z9.string().describe(WINDOW_START_DAY),
|
|
4616
|
+
to: z9.string().describe(WINDOW_END_DAY),
|
|
4584
4617
|
maxRecords: z9.number().int().min(1).optional().describe(
|
|
4585
4618
|
`Sample cap (server default applies; hard cap ${REPLAY_WINDOW_MAX_RECORDS / 1e3}k)`
|
|
4586
4619
|
)
|
|
@@ -4656,8 +4689,8 @@ function registerHistoryTools(server, callApi) {
|
|
|
4656
4689
|
groupId: z10.string().uuid().optional().describe("Filter by policy group"),
|
|
4657
4690
|
versionId: z10.string().uuid().optional().describe("Filter by version"),
|
|
4658
4691
|
status: z10.enum(["SUCCESS", "NO_MATCH", "ERROR", "TIMEOUT"]).optional().describe("Filter by execution status"),
|
|
4659
|
-
startDate: z10.string().optional().describe(
|
|
4660
|
-
endDate: z10.string().optional().describe(
|
|
4692
|
+
startDate: z10.string().optional().describe(START_DAY),
|
|
4693
|
+
endDate: z10.string().optional().describe(END_DAY)
|
|
4661
4694
|
})
|
|
4662
4695
|
},
|
|
4663
4696
|
async ({ page, size, traceId, groupId, versionId, status, startDate, endDate }) => {
|
|
@@ -4688,11 +4721,11 @@ function registerHistoryTools(server, callApi) {
|
|
|
4688
4721
|
{
|
|
4689
4722
|
title: "Execution Statistics",
|
|
4690
4723
|
annotations: { readOnlyHint: true },
|
|
4691
|
-
description:
|
|
4724
|
+
description: `Get execution KPIs: total executions, success/failure counts, success rate, and average latency. Without dates the window is the last ${STATS_DEFAULT_WINDOW_DAYS} days through today, in the organization time zone. At most ${STATS_MAX_WINDOW_DAYS} days per call; a longer range is rejected with AN-039. startDate alone runs through today.`,
|
|
4692
4725
|
inputSchema: z10.object({
|
|
4693
4726
|
groupId: z10.string().uuid().optional().describe("Filter by policy group"),
|
|
4694
|
-
startDate: z10.string().optional().describe(
|
|
4695
|
-
endDate: z10.string().optional().describe(
|
|
4727
|
+
startDate: z10.string().optional().describe(START_DAY),
|
|
4728
|
+
endDate: z10.string().optional().describe(END_DAY)
|
|
4696
4729
|
})
|
|
4697
4730
|
},
|
|
4698
4731
|
async ({ groupId, startDate, endDate }) => {
|
|
@@ -4732,8 +4765,8 @@ function registerProvenanceTools(server, callApi) {
|
|
|
4732
4765
|
traceId: z11.string().optional().describe("Filter by trace ID (exact match)"),
|
|
4733
4766
|
revealedBy: z11.string().optional().describe("Filter by operator ID (exact match)"),
|
|
4734
4767
|
factKey: z11.string().optional().describe("Filter by fact key (partial match, case-insensitive)"),
|
|
4735
|
-
startDate: z11.string().optional().describe(
|
|
4736
|
-
endDate: z11.string().optional().describe(
|
|
4768
|
+
startDate: z11.string().optional().describe(START_DAY),
|
|
4769
|
+
endDate: z11.string().optional().describe(END_DAY)
|
|
4737
4770
|
})
|
|
4738
4771
|
},
|
|
4739
4772
|
async ({ page, size, traceId, revealedBy, factKey, startDate, endDate }) => {
|
|
@@ -4756,15 +4789,15 @@ function registerLogTools(server, callApi) {
|
|
|
4756
4789
|
{
|
|
4757
4790
|
title: "List Failure Logs",
|
|
4758
4791
|
annotations: { readOnlyHint: true },
|
|
4759
|
-
description:
|
|
4792
|
+
description: `List system failure logs from background tasks (platform event webhooks, scheduled deployments). Without dates the window is ${FAILURE_LOG_LOOKBACK_DAYS} days back through today, in the organization time zone; pass startDate to look further back.`,
|
|
4760
4793
|
inputSchema: z12.object({
|
|
4761
4794
|
page: z12.number().int().min(0).default(0).describe("Page number"),
|
|
4762
4795
|
size: z12.number().int().min(1).max(100).default(20).describe("Page size"),
|
|
4763
4796
|
taskType: z12.enum(TaskType).optional().describe("Task type"),
|
|
4764
4797
|
status: z12.enum(FailureStatus).optional().describe("Log status"),
|
|
4765
4798
|
keyword: z12.string().optional().describe("Search in refId, refSubId, errorMessage"),
|
|
4766
|
-
startDate: z12.string().optional().describe(
|
|
4767
|
-
endDate: z12.string().optional().describe(
|
|
4799
|
+
startDate: z12.string().optional().describe(START_DAY),
|
|
4800
|
+
endDate: z12.string().optional().describe(END_DAY)
|
|
4768
4801
|
})
|
|
4769
4802
|
},
|
|
4770
4803
|
async ({ page, size, taskType, status, keyword, startDate, endDate }) => {
|
package/dist/mcp/register.js
CHANGED
|
@@ -6,7 +6,7 @@ function registerStatusTools(server, callApi) {
|
|
|
6
6
|
{
|
|
7
7
|
title: "Who Am I",
|
|
8
8
|
annotations: { readOnlyHint: true },
|
|
9
|
-
description:
|
|
9
|
+
description: 'Show current authentication info (tenant ID, user ID, role) and tenantTimezone, the organization time zone that every yyyy-MM-dd date filter uses. Work out "today" or "yesterday" in that zone, not in UTC.',
|
|
10
10
|
inputSchema: z.object({})
|
|
11
11
|
},
|
|
12
12
|
async () => callApi("GET", "whoami")
|
|
@@ -259,6 +259,17 @@ function formatUnregisteredFactWarning(meta) {
|
|
|
259
259
|
].join("\n");
|
|
260
260
|
}
|
|
261
261
|
|
|
262
|
+
// src/lib/dates.ts
|
|
263
|
+
var ORG_DAY = "yyyy-MM-dd, a whole calendar day in the organization time zone (tenantTimezone in whoami), not UTC";
|
|
264
|
+
var START_DAY = `Start date, ${ORG_DAY}. Inclusive.`;
|
|
265
|
+
var END_DAY = `End date, ${ORG_DAY}. Inclusive: the whole day counts.`;
|
|
266
|
+
var WINDOW_START_DAY = `Window start date, ${ORG_DAY}. Inclusive.`;
|
|
267
|
+
var WINDOW_END_DAY = `Window end date, ${ORG_DAY}. Inclusive: the whole day counts.`;
|
|
268
|
+
var INSTANT = "ISO-8601 instant with Z or an offset, e.g. 2026-10-01T00:00:00Z or 2026-10-01T09:00:00+09:00. A bare date or a time without an offset is rejected.";
|
|
269
|
+
var STATS_DEFAULT_WINDOW_DAYS = 30;
|
|
270
|
+
var STATS_MAX_WINDOW_DAYS = 31;
|
|
271
|
+
var FAILURE_LOG_LOOKBACK_DAYS = 7;
|
|
272
|
+
|
|
262
273
|
// src/mcp/tools/versions.ts
|
|
263
274
|
function registerVersionTools(server, callApi) {
|
|
264
275
|
server.registerTool(
|
|
@@ -299,8 +310,8 @@ function registerVersionTools(server, callApi) {
|
|
|
299
310
|
inputSchema: z3.object({
|
|
300
311
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
301
312
|
commitMessage: z3.string().optional().describe("Commit message describing this version"),
|
|
302
|
-
effectiveFrom: z3.string().optional().describe(
|
|
303
|
-
effectiveTo: z3.string().optional().describe(
|
|
313
|
+
effectiveFrom: z3.string().optional().describe(`Effective start, ${INSTANT}`),
|
|
314
|
+
effectiveTo: z3.string().optional().describe(`Effective end, ${INSTANT}`)
|
|
304
315
|
})
|
|
305
316
|
},
|
|
306
317
|
async ({ groupId, ...body }) => callApi("POST", `policy-groups/${groupId}/versions`, { body })
|
|
@@ -310,13 +321,13 @@ function registerVersionTools(server, callApi) {
|
|
|
310
321
|
{
|
|
311
322
|
title: "Update Policy Version",
|
|
312
323
|
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
313
|
-
description: "Update a DRAFT version. Only DRAFT versions can be modified.
|
|
324
|
+
description: "Update a DRAFT version. Only DRAFT versions can be modified. An omitted commitMessage keeps its value, but effectiveFrom and effectiveTo are replaced together: one you omit is cleared. To keep the effective window, send both current values (read them with lexq_versions_get).",
|
|
314
325
|
inputSchema: z3.object({
|
|
315
326
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
316
327
|
versionId: z3.string().uuid().describe("Version ID"),
|
|
317
328
|
commitMessage: z3.string().optional().describe("New commit message"),
|
|
318
|
-
effectiveFrom: z3.string().optional().describe(
|
|
319
|
-
effectiveTo: z3.string().optional().describe(
|
|
329
|
+
effectiveFrom: z3.string().optional().describe(`Effective start, ${INSTANT} Omit it and the start is cleared.`),
|
|
330
|
+
effectiveTo: z3.string().optional().describe(`Effective end, ${INSTANT} Omit it and the end is cleared.`)
|
|
320
331
|
})
|
|
321
332
|
},
|
|
322
333
|
async ({ groupId, versionId, ...body }) => callApi("PUT", `policy-groups/${groupId}/versions/${versionId}`, { body })
|
|
@@ -756,7 +767,7 @@ function registerDeployTools(server, callApi) {
|
|
|
756
767
|
{
|
|
757
768
|
title: "Schedule Deployment",
|
|
758
769
|
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
759
|
-
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).",
|
|
770
|
+
description: "Schedule an ACTIVE version with a future effective start date to auto-deploy at that time (Scheduled Deployment). The time is the version's effectiveFrom, set on the DRAFT before publishing; this call takes no time of its own. 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).",
|
|
760
771
|
inputSchema: z6.object({
|
|
761
772
|
groupId: z6.string().uuid().describe("Policy group ID"),
|
|
762
773
|
versionId: z6.string().uuid().describe("ACTIVE version ID with a future effective start date"),
|
|
@@ -803,8 +814,8 @@ function registerDeployTools(server, callApi) {
|
|
|
803
814
|
size: z6.number().int().min(1).max(100).default(20).describe("Page size"),
|
|
804
815
|
groupId: z6.string().uuid().optional().describe("Filter by group ID"),
|
|
805
816
|
types: z6.string().optional().describe("Filter by deployment types (comma-separated: DEPLOY,ROLLBACK,UNDEPLOY)"),
|
|
806
|
-
startDate: z6.string().optional().describe(
|
|
807
|
-
endDate: z6.string().optional().describe(
|
|
817
|
+
startDate: z6.string().optional().describe(START_DAY),
|
|
818
|
+
endDate: z6.string().optional().describe(END_DAY)
|
|
808
819
|
})
|
|
809
820
|
},
|
|
810
821
|
async ({ page, size, groupId, types, startDate, endDate }) => {
|
|
@@ -948,7 +959,8 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
948
959
|
Start an Impact Simulation against historical, uploaded, or inline data.
|
|
949
960
|
|
|
950
961
|
dataset.type and dataset.source are BOTH required, and must be paired:
|
|
951
|
-
HISTORICAL → source EXECUTION_LOGS, with dataset.from / dataset.to (yyyy-MM-dd
|
|
962
|
+
HISTORICAL → source EXECUTION_LOGS, with dataset.from / dataset.to (yyyy-MM-dd, whole days
|
|
963
|
+
in the organization time zone, both inclusive)
|
|
952
964
|
UPLOADED → source S3_BUCKET, with dataset.path (the path returned by lexq_dataset_upload)
|
|
953
965
|
MANUAL → source REQUEST_BODY, with dataset.manualData (array of fact records)
|
|
954
966
|
|
|
@@ -1003,8 +1015,8 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
1003
1015
|
page: z7.number().int().min(0).default(0).describe("Page number"),
|
|
1004
1016
|
size: z7.number().int().min(1).max(100).default(20).describe("Page size"),
|
|
1005
1017
|
status: z7.enum(["PENDING", "RUNNING", "COMPLETED", "FAILED", "CANCELED"]).optional().describe("Filter by status"),
|
|
1006
|
-
from: z7.string().optional().describe(
|
|
1007
|
-
to: z7.string().optional().describe(
|
|
1018
|
+
from: z7.string().optional().describe(START_DAY),
|
|
1019
|
+
to: z7.string().optional().describe(END_DAY)
|
|
1008
1020
|
})
|
|
1009
1021
|
},
|
|
1010
1022
|
async ({ page, size, status, from, to }) => {
|
|
@@ -1182,8 +1194,8 @@ function registerReplayTools(server, callApi) {
|
|
|
1182
1194
|
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.",
|
|
1183
1195
|
inputSchema: z9.object({
|
|
1184
1196
|
candidateVersionId: z9.string().uuid().describe("Version to re-evaluate against"),
|
|
1185
|
-
from: z9.string().describe(
|
|
1186
|
-
to: z9.string().describe(
|
|
1197
|
+
from: z9.string().describe(WINDOW_START_DAY),
|
|
1198
|
+
to: z9.string().describe(WINDOW_END_DAY),
|
|
1187
1199
|
maxRecords: z9.number().int().min(1).optional().describe(
|
|
1188
1200
|
`Sample cap (server default applies; hard cap ${REPLAY_WINDOW_MAX_RECORDS / 1e3}k)`
|
|
1189
1201
|
)
|
|
@@ -1259,8 +1271,8 @@ function registerHistoryTools(server, callApi) {
|
|
|
1259
1271
|
groupId: z10.string().uuid().optional().describe("Filter by policy group"),
|
|
1260
1272
|
versionId: z10.string().uuid().optional().describe("Filter by version"),
|
|
1261
1273
|
status: z10.enum(["SUCCESS", "NO_MATCH", "ERROR", "TIMEOUT"]).optional().describe("Filter by execution status"),
|
|
1262
|
-
startDate: z10.string().optional().describe(
|
|
1263
|
-
endDate: z10.string().optional().describe(
|
|
1274
|
+
startDate: z10.string().optional().describe(START_DAY),
|
|
1275
|
+
endDate: z10.string().optional().describe(END_DAY)
|
|
1264
1276
|
})
|
|
1265
1277
|
},
|
|
1266
1278
|
async ({ page, size, traceId, groupId, versionId, status, startDate, endDate }) => {
|
|
@@ -1291,11 +1303,11 @@ function registerHistoryTools(server, callApi) {
|
|
|
1291
1303
|
{
|
|
1292
1304
|
title: "Execution Statistics",
|
|
1293
1305
|
annotations: { readOnlyHint: true },
|
|
1294
|
-
description:
|
|
1306
|
+
description: `Get execution KPIs: total executions, success/failure counts, success rate, and average latency. Without dates the window is the last ${STATS_DEFAULT_WINDOW_DAYS} days through today, in the organization time zone. At most ${STATS_MAX_WINDOW_DAYS} days per call; a longer range is rejected with AN-039. startDate alone runs through today.`,
|
|
1295
1307
|
inputSchema: z10.object({
|
|
1296
1308
|
groupId: z10.string().uuid().optional().describe("Filter by policy group"),
|
|
1297
|
-
startDate: z10.string().optional().describe(
|
|
1298
|
-
endDate: z10.string().optional().describe(
|
|
1309
|
+
startDate: z10.string().optional().describe(START_DAY),
|
|
1310
|
+
endDate: z10.string().optional().describe(END_DAY)
|
|
1299
1311
|
})
|
|
1300
1312
|
},
|
|
1301
1313
|
async ({ groupId, startDate, endDate }) => {
|
|
@@ -1335,8 +1347,8 @@ function registerProvenanceTools(server, callApi) {
|
|
|
1335
1347
|
traceId: z11.string().optional().describe("Filter by trace ID (exact match)"),
|
|
1336
1348
|
revealedBy: z11.string().optional().describe("Filter by operator ID (exact match)"),
|
|
1337
1349
|
factKey: z11.string().optional().describe("Filter by fact key (partial match, case-insensitive)"),
|
|
1338
|
-
startDate: z11.string().optional().describe(
|
|
1339
|
-
endDate: z11.string().optional().describe(
|
|
1350
|
+
startDate: z11.string().optional().describe(START_DAY),
|
|
1351
|
+
endDate: z11.string().optional().describe(END_DAY)
|
|
1340
1352
|
})
|
|
1341
1353
|
},
|
|
1342
1354
|
async ({ page, size, traceId, revealedBy, factKey, startDate, endDate }) => {
|
|
@@ -1359,15 +1371,15 @@ function registerLogTools(server, callApi) {
|
|
|
1359
1371
|
{
|
|
1360
1372
|
title: "List Failure Logs",
|
|
1361
1373
|
annotations: { readOnlyHint: true },
|
|
1362
|
-
description:
|
|
1374
|
+
description: `List system failure logs from background tasks (platform event webhooks, scheduled deployments). Without dates the window is ${FAILURE_LOG_LOOKBACK_DAYS} days back through today, in the organization time zone; pass startDate to look further back.`,
|
|
1363
1375
|
inputSchema: z12.object({
|
|
1364
1376
|
page: z12.number().int().min(0).default(0).describe("Page number"),
|
|
1365
1377
|
size: z12.number().int().min(1).max(100).default(20).describe("Page size"),
|
|
1366
1378
|
taskType: z12.enum(TaskType).optional().describe("Task type"),
|
|
1367
1379
|
status: z12.enum(FailureStatus).optional().describe("Log status"),
|
|
1368
1380
|
keyword: z12.string().optional().describe("Search in refId, refSubId, errorMessage"),
|
|
1369
|
-
startDate: z12.string().optional().describe(
|
|
1370
|
-
endDate: z12.string().optional().describe(
|
|
1381
|
+
startDate: z12.string().optional().describe(START_DAY),
|
|
1382
|
+
endDate: z12.string().optional().describe(END_DAY)
|
|
1371
1383
|
})
|
|
1372
1384
|
},
|
|
1373
1385
|
async ({ page, size, taskType, status, keyword, startDate, endDate }) => {
|
package/package.json
CHANGED
|
@@ -23,8 +23,11 @@ Filter options:
|
|
|
23
23
|
| `--group-id <id>` | Filter by policy group | `--group-id <gid>` |
|
|
24
24
|
| `--version-id <id>` | Filter by version | `--version-id <vid>` |
|
|
25
25
|
| `--status <status>` | Filter by status | `--status SUCCESS` |
|
|
26
|
-
| `--start-date <date>` |
|
|
27
|
-
| `--end-date <date>` |
|
|
26
|
+
| `--start-date <date>` | First day, inclusive | `--start-date 2025-01-01` |
|
|
27
|
+
| `--end-date <date>` | Last day, inclusive | `--end-date 2025-01-31` |
|
|
28
|
+
|
|
29
|
+
Dates are `yyyy-MM-dd`, whole days in the organization time zone (`tenantTimezone` in
|
|
30
|
+
`lexq auth whoami`), not UTC.
|
|
28
31
|
|
|
29
32
|
### Execution Statuses
|
|
30
33
|
|
|
@@ -53,6 +56,10 @@ Returns full detail including `inputFacts`, `executionTraces`, and `decisionTrac
|
|
|
53
56
|
lexq history stats
|
|
54
57
|
```
|
|
55
58
|
|
|
59
|
+
Without dates the window is the last 30 days through today, in the organization time zone. At most
|
|
60
|
+
31 days per call; a longer range is rejected with `AN-039`. `--start-date` alone runs through
|
|
61
|
+
today.
|
|
62
|
+
|
|
56
63
|
Returns KPI summary:
|
|
57
64
|
|
|
58
65
|
```json
|
|
@@ -98,8 +105,12 @@ Filter options:
|
|
|
98
105
|
| `--task-type <type>` | Task type | `PLATFORM_WEBHOOK`, `SCHEDULED_DEPLOYMENT` |
|
|
99
106
|
| `--status <status>` | Log status | `PENDING`, `RESOLVED`, `IGNORED` |
|
|
100
107
|
| `--keyword <kw>` | Search in refId, refSubId, errorMessage | any string |
|
|
101
|
-
| `--start-date <date>` |
|
|
102
|
-
| `--end-date <date>` |
|
|
108
|
+
| `--start-date <date>` | First day, inclusive | `2025-01-01` |
|
|
109
|
+
| `--end-date <date>` | Last day, inclusive | `2025-01-31` |
|
|
110
|
+
|
|
111
|
+
Without dates the list covers 7 days back through today, in the organization time zone. A failure
|
|
112
|
+
older than that is left out even while it is still `PENDING`. Pass an earlier `--start-date` to
|
|
113
|
+
see it.
|
|
103
114
|
|
|
104
115
|
### Get Failure Log Detail
|
|
105
116
|
|
|
@@ -247,7 +258,7 @@ lexq profile <groupId> --version <vid> --cache MISS \
|
|
|
247
258
|
```
|
|
248
259
|
|
|
249
260
|
`--from` / `--to` are ISO-8601 **instants** here (`2026-07-01T00:00:00Z`), unlike `replay start`
|
|
250
|
-
which takes `yyyy-MM-dd`
|
|
261
|
+
which takes `yyyy-MM-dd` days in the organization time zone.
|
|
251
262
|
|
|
252
263
|
`p50` / `p95` / `p99` are `null` when the sample is under 100 — the engine reports insufficient
|
|
253
264
|
data rather than inventing a number. `n` is always present.
|
|
@@ -264,7 +275,7 @@ lexq history list --status ERROR --page 0 --size 10
|
|
|
264
275
|
# 3. For a specific bad decision, get the deterministic why
|
|
265
276
|
lexq provenance get --trace-id <traceId>
|
|
266
277
|
|
|
267
|
-
# 4. Check for system failures
|
|
278
|
+
# 4. Check for system failures (covers 7 days back by default; add --start-date for older ones)
|
|
268
279
|
lexq logs list --status PENDING --page 0 --size 10
|
|
269
280
|
|
|
270
281
|
# 5. Inspect and mark
|
|
@@ -390,6 +390,10 @@ lexq logs bulk-action --ids "id4,id5" --action IGNORE
|
|
|
390
390
|
lexq logs list --status PENDING --page 0 --size 10
|
|
391
391
|
```
|
|
392
392
|
|
|
393
|
+
Without `--start-date`, `logs list` covers 7 days back through today, in the organization time
|
|
394
|
+
zone. An empty list in step 5 means there is no PENDING failure in that window, not that there is
|
|
395
|
+
none at all. Add an earlier `--start-date` to steps 1 and 5 to see older ones.
|
|
396
|
+
|
|
393
397
|
`RESOLVE` and `IGNORE` differ only in intent — both remove the log from PENDING. Use `RESOLVE`
|
|
394
398
|
when the underlying problem was fixed, `IGNORE` when it does not need fixing.
|
|
395
399
|
|
|
@@ -153,7 +153,12 @@ Prefixes you will encounter through the CLI:
|
|
|
153
153
|
1. **Fact keys start with a letter,** then letters, numbers, and underscores. Casing is yours to
|
|
154
154
|
choose and keys are case-sensitive. These docs use `camelCase`: `paymentAmount`, `customerTier`.
|
|
155
155
|
2. **IDs are UUIDs.** Always copy the full ID from list/create output — do not guess.
|
|
156
|
-
3. **Dates
|
|
156
|
+
3. **Dates come in two shapes.** A date filter (`--start-date`, `--end-date`, `--from` / `--to` on
|
|
157
|
+
`replay start` and `simulation list`) takes `yyyy-MM-dd` and means a whole calendar day in the
|
|
158
|
+
organization time zone, not UTC. `lexq auth whoami` shows that zone as `tenantTimezone`. An
|
|
159
|
+
instant (`--effective-from`, `--effective-to`, `--from` / `--to` on `profile`) takes ISO 8601
|
|
160
|
+
with `Z` or an offset: `2026-10-01T00:00:00Z` or `2026-10-01T09:00:00+09:00`. Tables print
|
|
161
|
+
times in UTC with a trailing `Z`.
|
|
157
162
|
4. **JSON bodies via `--json`.** Most create/update commands accept `--json '<body>'` for the request body.
|
|
158
163
|
5. **File input via `--file`.** `analytics dry-run`, `dry-run-compare`, `simulation start` accept
|
|
159
164
|
`--file path/to/body.json` as an alternative to `--json`. `analytics dataset upload` requires
|
|
@@ -251,6 +251,9 @@ lexq analytics simulation start --json '{
|
|
|
251
251
|
| `MANUAL` | `REQUEST_BODY` | Provide `manualData` array in the request |
|
|
252
252
|
| `UPLOADED` | `S3_BUCKET` | Reference an uploaded dataset by `path` |
|
|
253
253
|
|
|
254
|
+
`HISTORICAL` takes `from` / `to` as `yyyy-MM-dd`, whole days in the organization time zone, both
|
|
255
|
+
inclusive.
|
|
256
|
+
|
|
254
257
|
### File Upload Dataset
|
|
255
258
|
|
|
256
259
|
```bash
|