@lexq/cli 0.1.37 → 0.1.39

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
@@ -1358,13 +1358,16 @@ function registerDeployCommands(program) {
1358
1358
  "after",
1359
1359
  dedent7`
1360
1360
 
1361
- Lifecycle: Publish (DRAFT→ACTIVE) → Deploy (ACTIVE→LIVE) → Rollback / Undeploy
1361
+ Lifecycle: Publish (DRAFT→ACTIVE) → Deploy or Schedule (ACTIVE→LIVE) → Rollback / Undeploy
1362
1362
 
1363
1363
  Commands:
1364
1364
  publish Lock a DRAFT version (DRAFT → ACTIVE)
1365
1365
  live Push an ACTIVE version to production traffic
1366
1366
  rollback Revert to the previous deployed version
1367
1367
  undeploy Remove the live version (stops all traffic)
1368
+ schedule Schedule an ACTIVE version to auto-deploy at its effective start
1369
+ unschedule Cancel the pending scheduled deployment
1370
+ schedules List scheduled deployments (all statuses)
1368
1371
  history List deployment history with filters
1369
1372
  detail Get deployment detail with integrity check
1370
1373
  overview Show all groups' deployment status at a glance
@@ -1502,10 +1505,7 @@ function registerDeployCommands(program) {
1502
1505
  process.exit(1);
1503
1506
  }
1504
1507
  });
1505
- deploy.command("history").description("List deployment history").option("--group-id <groupId>", "Filter by policy group").option(
1506
- "--types <types>",
1507
- "Filter by types (comma-separated: PUBLISH,DEPLOY,ROLLBACK,UNDEPLOY)"
1508
- ).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").addHelpText(
1508
+ 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 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").addHelpText(
1509
1509
  "after",
1510
1510
  dedent7`
1511
1511
 
@@ -1660,6 +1660,119 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
1660
1660
  process.exit(1);
1661
1661
  }
1662
1662
  });
1663
+ deploy.command("schedule").description("Schedule an ACTIVE version to auto-deploy at its effective start").requiredOption("--group-id <groupId>", "Policy group ID").requiredOption("--version-id <versionId>", "Version ID to schedule").requiredOption("--memo <memo>", "Schedule memo").addHelpText(
1664
+ "after",
1665
+ dedent7`
1666
+
1667
+ The version must be ACTIVE with a future effective start date; the system
1668
+ deploys it automatically at that time (within one scheduler tick, ≤60s).
1669
+ One pending schedule per group. Manual deploy/rollback/undeploy, starting
1670
+ an A/B test, or archiving the group cancels the pending schedule.
1671
+
1672
+ Example:
1673
+ $ lexq deploy schedule --group-id <gid> --version-id <vid> --memo "Q4 pricing"
1674
+ `
1675
+ ).action(async (opts) => {
1676
+ try {
1677
+ const globalOpts = program.opts();
1678
+ const data = await apiRequest(
1679
+ "POST",
1680
+ `policy-groups/${opts.groupId}/schedule`,
1681
+ {
1682
+ apiKey: globalOpts.apiKey,
1683
+ baseUrl: globalOpts.baseUrl,
1684
+ dryRun: globalOpts.dryRun,
1685
+ verbose: globalOpts.verbose,
1686
+ body: { versionId: opts.versionId, memo: opts.memo }
1687
+ }
1688
+ );
1689
+ console.log(`\u2713 Scheduled v${data.versionNo ?? "?"} for ${data.scheduledFor}.`);
1690
+ } catch (error) {
1691
+ printError(error);
1692
+ process.exit(1);
1693
+ }
1694
+ });
1695
+ deploy.command("unschedule").description("Cancel the pending scheduled deployment for a group").requiredOption("--group-id <groupId>", "Policy group ID").option("--force", "Skip confirmation prompt").addHelpText(
1696
+ "after",
1697
+ dedent7`
1698
+
1699
+ Cancels the PENDING schedule only — the version itself is not affected.
1700
+
1701
+ Example:
1702
+ $ lexq deploy unschedule --group-id <gid> --force
1703
+ `
1704
+ ).action(async (opts) => {
1705
+ try {
1706
+ const globalOpts = program.opts();
1707
+ if (!opts.force) {
1708
+ const { createInterface: createInterface2 } = await import("readline/promises");
1709
+ const rl = createInterface2({ input: process.stdin, output: process.stdout });
1710
+ const answer = await rl.question(
1711
+ `Cancel the pending scheduled deployment for group ${opts.groupId}? [y/N] `
1712
+ );
1713
+ rl.close();
1714
+ if (answer.toLowerCase() !== "y") {
1715
+ console.log("Canceled.");
1716
+ return;
1717
+ }
1718
+ }
1719
+ await apiRequest("DELETE", `policy-groups/${opts.groupId}/schedule`, {
1720
+ apiKey: globalOpts.apiKey,
1721
+ baseUrl: globalOpts.baseUrl,
1722
+ dryRun: globalOpts.dryRun,
1723
+ verbose: globalOpts.verbose
1724
+ });
1725
+ console.log(`\u2713 Scheduled deployment canceled for group ${opts.groupId}.`);
1726
+ } catch (error) {
1727
+ printError(error);
1728
+ process.exit(1);
1729
+ }
1730
+ });
1731
+ deploy.command("schedules").description("List scheduled deployments (all statuses, newest first)").option("--page <number>", "Page number", "0").option("--size <number>", "Page size", "20").addHelpText(
1732
+ "after",
1733
+ dedent7`
1734
+
1735
+ Example:
1736
+ $ lexq deploy schedules --format table
1737
+ `
1738
+ ).action(async (opts) => {
1739
+ try {
1740
+ const globalOpts = program.opts();
1741
+ const format = globalOpts.format ?? "json";
1742
+ const data = await apiRequest(
1743
+ "GET",
1744
+ "policy-groups/schedules",
1745
+ {
1746
+ apiKey: globalOpts.apiKey,
1747
+ baseUrl: globalOpts.baseUrl,
1748
+ dryRun: globalOpts.dryRun,
1749
+ verbose: globalOpts.verbose,
1750
+ params: { page: opts.page, size: opts.size }
1751
+ }
1752
+ );
1753
+ if (format === "table") {
1754
+ printTable(
1755
+ ["Status", "Group", "Version", "Scheduled For", "By", "Result"],
1756
+ data.content.map((s) => [
1757
+ s.status,
1758
+ s.policyGroupName ?? s.policyGroupId.substring(0, 8),
1759
+ s.versionNo != null ? `v${s.versionNo}` : "\u2013",
1760
+ s.scheduledFor.substring(0, 16),
1761
+ s.scheduledByName,
1762
+ s.status === "EXECUTED" ? s.executedAt?.substring(0, 16) ?? "\u2013" : s.status === "CANCELED" ? s.canceledReason ?? "\u2013" : s.status === "FAILED" ? s.failedReason ?? "\u2013" : "\u2013"
1763
+ ]),
1764
+ { truncate: 20 }
1765
+ );
1766
+ console.log(`
1767
+ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
1768
+ } else {
1769
+ printJson(data);
1770
+ }
1771
+ } catch (error) {
1772
+ printError(error);
1773
+ process.exit(1);
1774
+ }
1775
+ });
1663
1776
  }
1664
1777
  async function warnUnregisteredFacts(globalOpts, groupId, versionId) {
1665
1778
  if (globalOpts.dryRun) return;
@@ -2206,13 +2319,16 @@ var TaskType = [
2206
2319
  // Internal
2207
2320
  "IMAGE_PROCESSING",
2208
2321
  "DAILY_SETTLEMENT",
2209
- "PLATFORM_WEBHOOK"
2322
+ "PLATFORM_WEBHOOK",
2323
+ "SCHEDULED_DEPLOYMENT"
2210
2324
  ];
2211
2325
  var PlatformEventType = [
2212
2326
  "VERSION_PUBLISHED",
2213
2327
  "DEPLOYED",
2214
2328
  "ROLLED_BACK",
2215
- "UNDEPLOYED"
2329
+ "UNDEPLOYED",
2330
+ "DEPLOY_SCHEDULED",
2331
+ "DEPLOY_SCHEDULE_CANCELED"
2216
2332
  ];
2217
2333
  var WebhookPayloadFormat = ["GENERIC", "SLACK"];
2218
2334
 
@@ -2226,8 +2342,9 @@ function registerProfileCommands(program) {
2226
2342
 
2227
2343
  Slow-rule judgment is relative only: flagged = p50 ≥ 10× the median of
2228
2344
  per-rule p50s within the group. Absolute ms thresholds are intentionally
2229
- not supported. Percentiles are withheld (–) when n < 100; TOTAL is
2230
- recorded for every call, rule detail from a deterministic 1% sample.
2345
+ not supported. Each percentile is withheld (–) unless n×(1−q) 3
2346
+ p50 from n ≥ 6, p95 from n ≥ 60, p99 from n 300. TOTAL is recorded
2347
+ on every call, rule detail from a deterministic 1% sample.
2231
2348
 
2232
2349
  Examples:
2233
2350
  $ lexq profile <groupId>
@@ -3816,7 +3933,7 @@ function registerDeployTools(server, callApi) {
3816
3933
  "lexq_deploy_live",
3817
3934
  {
3818
3935
  title: "Deploy to Live",
3819
- description: "Deploy an ACTIVE (published) version to live traffic. Takes effect immediately. Undefined facts do not block deployment (INV-4); use lexq_facts_unregistered to review what the version references but has not defined.",
3936
+ description: "Deploy an ACTIVE (published) version to live traffic. Takes effect immediately. Versions whose effective start date has not arrived are rejected (P-037) \u2014 use lexq_deploy_schedule for those. Undefined facts do not block deployment (INV-4); use lexq_facts_unregistered to review what the version references but has not defined.",
3820
3937
  inputSchema: {
3821
3938
  groupId: z5.string().uuid().describe("Policy group ID"),
3822
3939
  versionId: z5.string().uuid().describe("Version ID to deploy"),
@@ -3855,6 +3972,44 @@ function registerDeployTools(server, callApi) {
3855
3972
  body: { memo }
3856
3973
  })
3857
3974
  );
3975
+ server.registerTool(
3976
+ "lexq_deploy_schedule",
3977
+ {
3978
+ title: "Schedule Deployment",
3979
+ 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).",
3980
+ inputSchema: {
3981
+ groupId: z5.string().uuid().describe("Policy group ID"),
3982
+ versionId: z5.string().uuid().describe("ACTIVE version ID with a future effective start date"),
3983
+ memo: z5.string().min(1).describe("Schedule memo (required)")
3984
+ }
3985
+ },
3986
+ async ({ groupId, versionId, memo }) => callApi("POST", `policy-groups/${groupId}/schedule`, {
3987
+ body: { versionId, memo }
3988
+ })
3989
+ );
3990
+ server.registerTool(
3991
+ "lexq_deploy_unschedule",
3992
+ {
3993
+ title: "Cancel Scheduled Deployment",
3994
+ description: "Cancel the pending scheduled deployment for a group. The version itself is not affected. Fails with P-039 if no pending schedule exists.",
3995
+ inputSchema: {
3996
+ groupId: z5.string().uuid().describe("Policy group ID")
3997
+ }
3998
+ },
3999
+ async ({ groupId }) => callApi("DELETE", `policy-groups/${groupId}/schedule`)
4000
+ );
4001
+ server.registerTool(
4002
+ "lexq_deploy_schedules",
4003
+ {
4004
+ title: "List Scheduled Deployments",
4005
+ description: "List scheduled deployments across all groups (all statuses: PENDING, EXECUTED, CANCELED, FAILED), newest first.",
4006
+ inputSchema: {
4007
+ page: z5.number().int().min(0).default(0).describe("Page number"),
4008
+ size: z5.number().int().min(1).max(100).default(20).describe("Page size")
4009
+ }
4010
+ },
4011
+ async ({ page, size }) => callApi("GET", "policy-groups/schedules", { params: paginationParams(page, size) })
4012
+ );
3858
4013
  server.registerTool(
3859
4014
  "lexq_deploy_history",
3860
4015
  {
@@ -3864,9 +4019,7 @@ function registerDeployTools(server, callApi) {
3864
4019
  page: z5.number().int().min(0).default(0).describe("Page number"),
3865
4020
  size: z5.number().int().min(1).max(100).default(20).describe("Page size"),
3866
4021
  groupId: z5.string().uuid().optional().describe("Filter by group ID"),
3867
- types: z5.string().optional().describe(
3868
- "Filter by deployment types (comma-separated: PUBLISH,DEPLOY,ROLLBACK,UNDEPLOY)"
3869
- ),
4022
+ types: z5.string().optional().describe("Filter by deployment types (comma-separated: DEPLOY,ROLLBACK,UNDEPLOY)"),
3870
4023
  startDate: z5.string().optional().describe("Start date (yyyy-MM-dd)"),
3871
4024
  endDate: z5.string().optional().describe("End date (yyyy-MM-dd)")
3872
4025
  }
@@ -4171,7 +4324,7 @@ function registerProfileTools(server, callApi) {
4171
4324
  "lexq_profile_overview",
4172
4325
  {
4173
4326
  title: "Group Latency Profile",
4174
- description: "Per-rule latency profile of a policy group over a time window: group TOTAL distribution split by cache state (HIT = compiled ruleset cache hit, MISS = deep-load + compile), a per-rule CONDITION/ACTION percentile table, and slow-rule flags. " + RELATIVE_THRESHOLD + " Every percentile is accompanied by its sample count n; percentiles are withheld (null) when n < 100, and baselines report INSUFFICIENT_COHORT when fewer than 3 rules qualify. Rule detail comes from a deterministic 1% sample of calls; TOTAL is recorded for every call. Defaults: last 24h, live version, cacheState HIT.",
4327
+ description: "Per-rule latency profile of a policy group over a time window: group TOTAL distribution split by cache state (HIT = compiled ruleset cache hit, MISS = deep-load + compile), a per-rule CONDITION/ACTION percentile table, and slow-rule flags. " + RELATIVE_THRESHOLD + " Every percentile is accompanied by its sample count n; a percentile is withheld (null) unless n\xD7(1\u2212q) \u2265 3 (p50 needs n \u2265 6, p95 n \u2265 60, p99 n \u2265 300 \u2014 display gate, separate from the n \u2265 100 judgment gate). Baselines report INSUFFICIENT_COHORT when fewer than 3 rules qualify. Rule detail comes from a deterministic 1% sample of calls; TOTAL is recorded for every call. Defaults: last 24h, live version, cacheState HIT.",
4175
4328
  inputSchema: {
4176
4329
  groupId: z7.string().uuid().describe("Policy group ID"),
4177
4330
  versionId: z7.string().uuid().optional().describe("Version to inspect (default: live version)"),
@@ -4188,7 +4341,7 @@ function registerProfileTools(server, callApi) {
4188
4341
  "lexq_profile_rule",
4189
4342
  {
4190
4343
  title: "Rule Latency Detail",
4191
- description: "Single-rule latency detail: merged phase \xD7 cacheState distributions plus a per-window time series (60s windows). Missing windows are genuine gaps \u2014 never interpolated. Series points carry each window's own values; percentiles in merged distributions are withheld (null) when n < 100. " + RELATIVE_THRESHOLD,
4344
+ description: "Single-rule latency detail: merged phase \xD7 cacheState distributions plus a per-window time series (60s windows). Missing windows are genuine gaps \u2014 never interpolated. Series points carry each window's own values; percentiles in merged distributions are withheld (null) unless n\xD7(1\u2212q) \u2265 3 (p50 n \u2265 6, p95 n \u2265 60, p99 n \u2265 300). " + RELATIVE_THRESHOLD,
4192
4345
  inputSchema: {
4193
4346
  groupId: z7.string().uuid().describe("Policy group ID"),
4194
4347
  ruleId: z7.string().uuid().describe("Rule ID (from lexq_profile_overview)"),
@@ -35,6 +35,12 @@ declare function paginationParams(page?: number, size?: number): Record<string,
35
35
  */
36
36
  declare function formatUnregisteredFactWarning(meta: unknown): string | null;
37
37
 
38
+ declare class ApiError extends Error {
39
+ readonly statusCode: number;
40
+ readonly errorCode: string | null;
41
+ constructor(statusCode: number, errorCode: string | null, message: string);
42
+ }
43
+
38
44
  /**
39
45
  * Registers all MCP tools on the given server.
40
46
  *
@@ -43,4 +49,4 @@ declare function formatUnregisteredFactWarning(meta: unknown): string | null;
43
49
  */
44
50
  declare function registerAllTools(server: McpServer, callApi: CallApi): void;
45
51
 
46
- export { type CallApi, type McpToolResult, formatUnregisteredFactWarning, paginationParams, registerAllTools };
52
+ export { ApiError, type CallApi, type McpToolResult, formatUnregisteredFactWarning, paginationParams, registerAllTools };
@@ -154,6 +154,18 @@ import { join } from "path";
154
154
  var CONFIG_DIR = join(homedir(), ".lexq");
155
155
  var CONFIG_FILE = join(CONFIG_DIR, "config.json");
156
156
 
157
+ // src/lib/api-client.ts
158
+ var ApiError = class extends Error {
159
+ constructor(statusCode, errorCode, message) {
160
+ super(message);
161
+ this.statusCode = statusCode;
162
+ this.errorCode = errorCode;
163
+ this.name = "ApiError";
164
+ }
165
+ statusCode;
166
+ errorCode;
167
+ };
168
+
157
169
  // src/mcp/tools/_shared.ts
158
170
  function paginationParams(page, size) {
159
171
  const params = {};
@@ -532,7 +544,7 @@ function registerDeployTools(server, callApi) {
532
544
  "lexq_deploy_live",
533
545
  {
534
546
  title: "Deploy to Live",
535
- description: "Deploy an ACTIVE (published) version to live traffic. Takes effect immediately. Undefined facts do not block deployment (INV-4); use lexq_facts_unregistered to review what the version references but has not defined.",
547
+ description: "Deploy an ACTIVE (published) version to live traffic. Takes effect immediately. Versions whose effective start date has not arrived are rejected (P-037) \u2014 use lexq_deploy_schedule for those. Undefined facts do not block deployment (INV-4); use lexq_facts_unregistered to review what the version references but has not defined.",
536
548
  inputSchema: {
537
549
  groupId: z5.string().uuid().describe("Policy group ID"),
538
550
  versionId: z5.string().uuid().describe("Version ID to deploy"),
@@ -571,6 +583,44 @@ function registerDeployTools(server, callApi) {
571
583
  body: { memo }
572
584
  })
573
585
  );
586
+ server.registerTool(
587
+ "lexq_deploy_schedule",
588
+ {
589
+ title: "Schedule Deployment",
590
+ 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).",
591
+ inputSchema: {
592
+ groupId: z5.string().uuid().describe("Policy group ID"),
593
+ versionId: z5.string().uuid().describe("ACTIVE version ID with a future effective start date"),
594
+ memo: z5.string().min(1).describe("Schedule memo (required)")
595
+ }
596
+ },
597
+ async ({ groupId, versionId, memo }) => callApi("POST", `policy-groups/${groupId}/schedule`, {
598
+ body: { versionId, memo }
599
+ })
600
+ );
601
+ server.registerTool(
602
+ "lexq_deploy_unschedule",
603
+ {
604
+ title: "Cancel Scheduled Deployment",
605
+ description: "Cancel the pending scheduled deployment for a group. The version itself is not affected. Fails with P-039 if no pending schedule exists.",
606
+ inputSchema: {
607
+ groupId: z5.string().uuid().describe("Policy group ID")
608
+ }
609
+ },
610
+ async ({ groupId }) => callApi("DELETE", `policy-groups/${groupId}/schedule`)
611
+ );
612
+ server.registerTool(
613
+ "lexq_deploy_schedules",
614
+ {
615
+ title: "List Scheduled Deployments",
616
+ description: "List scheduled deployments across all groups (all statuses: PENDING, EXECUTED, CANCELED, FAILED), newest first.",
617
+ inputSchema: {
618
+ page: z5.number().int().min(0).default(0).describe("Page number"),
619
+ size: z5.number().int().min(1).max(100).default(20).describe("Page size")
620
+ }
621
+ },
622
+ async ({ page, size }) => callApi("GET", "policy-groups/schedules", { params: paginationParams(page, size) })
623
+ );
574
624
  server.registerTool(
575
625
  "lexq_deploy_history",
576
626
  {
@@ -580,9 +630,7 @@ function registerDeployTools(server, callApi) {
580
630
  page: z5.number().int().min(0).default(0).describe("Page number"),
581
631
  size: z5.number().int().min(1).max(100).default(20).describe("Page size"),
582
632
  groupId: z5.string().uuid().optional().describe("Filter by group ID"),
583
- types: z5.string().optional().describe(
584
- "Filter by deployment types (comma-separated: PUBLISH,DEPLOY,ROLLBACK,UNDEPLOY)"
585
- ),
633
+ types: z5.string().optional().describe("Filter by deployment types (comma-separated: DEPLOY,ROLLBACK,UNDEPLOY)"),
586
634
  startDate: z5.string().optional().describe("Start date (yyyy-MM-dd)"),
587
635
  endDate: z5.string().optional().describe("End date (yyyy-MM-dd)")
588
636
  }
@@ -887,7 +935,7 @@ function registerProfileTools(server, callApi) {
887
935
  "lexq_profile_overview",
888
936
  {
889
937
  title: "Group Latency Profile",
890
- description: "Per-rule latency profile of a policy group over a time window: group TOTAL distribution split by cache state (HIT = compiled ruleset cache hit, MISS = deep-load + compile), a per-rule CONDITION/ACTION percentile table, and slow-rule flags. " + RELATIVE_THRESHOLD + " Every percentile is accompanied by its sample count n; percentiles are withheld (null) when n < 100, and baselines report INSUFFICIENT_COHORT when fewer than 3 rules qualify. Rule detail comes from a deterministic 1% sample of calls; TOTAL is recorded for every call. Defaults: last 24h, live version, cacheState HIT.",
938
+ description: "Per-rule latency profile of a policy group over a time window: group TOTAL distribution split by cache state (HIT = compiled ruleset cache hit, MISS = deep-load + compile), a per-rule CONDITION/ACTION percentile table, and slow-rule flags. " + RELATIVE_THRESHOLD + " Every percentile is accompanied by its sample count n; a percentile is withheld (null) unless n\xD7(1\u2212q) \u2265 3 (p50 needs n \u2265 6, p95 n \u2265 60, p99 n \u2265 300 \u2014 display gate, separate from the n \u2265 100 judgment gate). Baselines report INSUFFICIENT_COHORT when fewer than 3 rules qualify. Rule detail comes from a deterministic 1% sample of calls; TOTAL is recorded for every call. Defaults: last 24h, live version, cacheState HIT.",
891
939
  inputSchema: {
892
940
  groupId: z7.string().uuid().describe("Policy group ID"),
893
941
  versionId: z7.string().uuid().optional().describe("Version to inspect (default: live version)"),
@@ -904,7 +952,7 @@ function registerProfileTools(server, callApi) {
904
952
  "lexq_profile_rule",
905
953
  {
906
954
  title: "Rule Latency Detail",
907
- description: "Single-rule latency detail: merged phase \xD7 cacheState distributions plus a per-window time series (60s windows). Missing windows are genuine gaps \u2014 never interpolated. Series points carry each window's own values; percentiles in merged distributions are withheld (null) when n < 100. " + RELATIVE_THRESHOLD,
955
+ description: "Single-rule latency detail: merged phase \xD7 cacheState distributions plus a per-window time series (60s windows). Missing windows are genuine gaps \u2014 never interpolated. Series points carry each window's own values; percentiles in merged distributions are withheld (null) unless n\xD7(1\u2212q) \u2265 3 (p50 n \u2265 6, p95 n \u2265 60, p99 n \u2265 300). " + RELATIVE_THRESHOLD,
908
956
  inputSchema: {
909
957
  groupId: z7.string().uuid().describe("Policy group ID"),
910
958
  ruleId: z7.string().uuid().describe("Rule ID (from lexq_profile_overview)"),
@@ -1182,13 +1230,16 @@ var TaskType = [
1182
1230
  // Internal
1183
1231
  "IMAGE_PROCESSING",
1184
1232
  "DAILY_SETTLEMENT",
1185
- "PLATFORM_WEBHOOK"
1233
+ "PLATFORM_WEBHOOK",
1234
+ "SCHEDULED_DEPLOYMENT"
1186
1235
  ];
1187
1236
  var PlatformEventType = [
1188
1237
  "VERSION_PUBLISHED",
1189
1238
  "DEPLOYED",
1190
1239
  "ROLLED_BACK",
1191
- "UNDEPLOYED"
1240
+ "UNDEPLOYED",
1241
+ "DEPLOY_SCHEDULED",
1242
+ "DEPLOY_SCHEDULE_CANCELED"
1192
1243
  ];
1193
1244
  var WebhookPayloadFormat = ["GENERIC", "SLACK"];
1194
1245
 
@@ -1396,6 +1447,7 @@ function registerAllTools(server, callApi) {
1396
1447
  registerWebhookSubscriptionTools(server, callApi);
1397
1448
  }
1398
1449
  export {
1450
+ ApiError,
1399
1451
  formatUnregisteredFactWarning,
1400
1452
  paginationParams,
1401
1453
  registerAllTools
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lexq/cli",
3
- "version": "0.1.37",
3
+ "version": "0.1.39",
4
4
  "description": "LexQ CLI — manage policies, simulate rules, and deploy from the terminal. Built for humans and AI agents.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -29,7 +29,10 @@
29
29
  "lint": "eslint src/",
30
30
  "typecheck": "tsc --noEmit",
31
31
  "start": "node dist/index.js",
32
- "prepublishOnly": "pnpm build"
32
+ "prepublishOnly": "pnpm build",
33
+ "knip": "knip",
34
+ "format": "prettier --write \"src/**/*.ts\"",
35
+ "format:check": "prettier --check \"src/**/*.ts\""
33
36
  },
34
37
  "keywords": [
35
38
  "lexq",
@@ -57,15 +60,14 @@
57
60
  "cli-table3": "^0.6.5",
58
61
  "commander": "^13.1.0",
59
62
  "dedent": "^1.7.2",
60
- "ora": "^8.2.0",
61
- "prettier": "^3.8.1",
62
63
  "zod": "^3.25.76"
63
64
  },
64
65
  "devDependencies": {
65
66
  "@eslint/js": "^9.20.0",
66
- "@types/dedent": "^0.7.2",
67
67
  "@types/node": "^22.12.0",
68
68
  "eslint": "^10.2.0",
69
+ "knip": "^6.29.0",
70
+ "prettier": "^3.9.6",
69
71
  "tsup": "^8.5.1",
70
72
  "typescript": "^5.7.0",
71
73
  "typescript-eslint": "^8.24.0"