postgresai 0.14.0-dev.83 → 0.14.0-dev.85

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.
@@ -1643,9 +1643,9 @@ program
1643
1643
  });
1644
1644
 
1645
1645
  program
1646
- .command("checkup [conn]")
1646
+ .command("checkup [checkIdOrConn] [conn]")
1647
1647
  .description("generate health check reports directly from PostgreSQL (express mode)")
1648
- .option("--check-id <id>", `specific check to run (see list below), or ALL`, "ALL")
1648
+ .option("--check-id <id>", `specific check to run (see list below), or ALL`)
1649
1649
  .option("--node-name <name>", "node name for reports", "node-01")
1650
1650
  .option("--output <path>", "output directory for JSON files")
1651
1651
  .option("--upload", "upload JSON results to PostgresAI (requires API key)")
@@ -1664,13 +1664,43 @@ program
1664
1664
  "",
1665
1665
  "Examples:",
1666
1666
  " postgresai checkup postgresql://user:pass@host:5432/db",
1667
- " postgresai checkup postgresql://user:pass@host:5432/db --check-id D001",
1667
+ " postgresai checkup H002 postgresql://user:pass@host:5432/db",
1668
+ " postgresai checkup postgresql://user:pass@host:5432/db --check-id H002",
1668
1669
  " postgresai checkup postgresql://user:pass@host:5432/db --output ./reports",
1669
- " postgresai checkup postgresql://user:pass@host:5432/db --project my_project",
1670
1670
  " postgresai checkup postgresql://user:pass@host:5432/db --no-upload --json",
1671
1671
  ].join("\n")
1672
1672
  )
1673
- .action(async (conn: string | undefined, opts: CheckupOptions, cmd: Command) => {
1673
+ .action(async (checkIdOrConn: string | undefined, connArg: string | undefined, opts: CheckupOptions, cmd: Command) => {
1674
+ // Support both syntaxes:
1675
+ // pgai checkup postgresql://... -> run ALL checks
1676
+ // pgai checkup H002 postgresql://... -> run specific check (positional)
1677
+ // pgai checkup --check-id H002 postgresql:// -> run specific check (option)
1678
+ const checkIdPattern = /^[A-Z]\d{3}$/i;
1679
+ let conn: string | undefined;
1680
+ let checkId: string;
1681
+
1682
+ if (!checkIdOrConn) {
1683
+ cmd.outputHelp();
1684
+ process.exitCode = 1;
1685
+ return;
1686
+ }
1687
+
1688
+ if (checkIdPattern.test(checkIdOrConn)) {
1689
+ // First arg is a check ID
1690
+ checkId = checkIdOrConn.toUpperCase();
1691
+ conn = connArg;
1692
+ if (!conn) {
1693
+ console.error(`Error: Connection string required when specifying check ID "${checkId}"`);
1694
+ console.error(`\nUsage: postgresai checkup ${checkId} postgresql://user@host:5432/dbname\n`);
1695
+ process.exitCode = 1;
1696
+ return;
1697
+ }
1698
+ } else {
1699
+ // First arg is the connection string
1700
+ conn = checkIdOrConn;
1701
+ checkId = opts.checkId?.toUpperCase() || "ALL";
1702
+ }
1703
+
1674
1704
  if (!conn) {
1675
1705
  cmd.outputHelp();
1676
1706
  process.exitCode = 1;
@@ -1718,12 +1748,11 @@ program
1718
1748
 
1719
1749
  // Generate reports
1720
1750
  let reports: Record<string, any>;
1721
- if (opts.checkId === "ALL") {
1751
+ if (checkId === "ALL") {
1722
1752
  reports = await generateAllReports(client, opts.nodeName, (p) => {
1723
1753
  spinner.update(`Running ${p.checkId}: ${p.checkTitle} (${p.index}/${p.total})`);
1724
1754
  });
1725
1755
  } else {
1726
- const checkId = opts.checkId.toUpperCase();
1727
1756
  const generator = REPORT_GENERATORS[checkId];
1728
1757
  if (!generator) {
1729
1758
  spinner.stop();
@@ -1733,7 +1762,7 @@ program
1733
1762
  console.error(`Check ${checkId} (${dictEntry.title}) is not yet available in express mode.`);
1734
1763
  console.error(`Express-mode checks: ${Object.keys(CHECK_INFO).join(", ")}`);
1735
1764
  } else {
1736
- console.error(`Unknown check ID: ${opts.checkId}`);
1765
+ console.error(`Unknown check ID: ${checkId}`);
1737
1766
  console.error(`See 'postgresai checkup --help' for available checks.`);
1738
1767
  }
1739
1768
  process.exitCode = 1;
@@ -13064,7 +13064,7 @@ var {
13064
13064
  // package.json
13065
13065
  var package_default = {
13066
13066
  name: "postgresai",
13067
- version: "0.14.0-dev.83",
13067
+ version: "0.14.0-dev.85",
13068
13068
  description: "postgres_ai CLI",
13069
13069
  license: "Apache-2.0",
13070
13070
  private: false,
@@ -15889,7 +15889,7 @@ var Result = import_lib.default.Result;
15889
15889
  var TypeOverrides = import_lib.default.TypeOverrides;
15890
15890
  var defaults = import_lib.default.defaults;
15891
15891
  // package.json
15892
- var version = "0.14.0-dev.83";
15892
+ var version = "0.14.0-dev.85";
15893
15893
  var package_default2 = {
15894
15894
  name: "postgresai",
15895
15895
  version,
@@ -27116,7 +27116,7 @@ function buildCheckInfoMap() {
27116
27116
  }
27117
27117
 
27118
27118
  // lib/checkup.ts
27119
- var __dirname = "/builds/postgres-ai/postgres_ai/cli/lib";
27119
+ var __dirname = "/builds/postgres-ai/postgresai/cli/lib";
27120
27120
  var SECONDS_PER_DAY = 86400;
27121
27121
  var SECONDS_PER_HOUR = 3600;
27122
27122
  var SECONDS_PER_MINUTE = 60;
@@ -29487,19 +29487,42 @@ program2.command("unprepare-db [conn]").description("remove monitoring setup: dr
29487
29487
  closeReadline();
29488
29488
  }
29489
29489
  });
29490
- program2.command("checkup [conn]").description("generate health check reports directly from PostgreSQL (express mode)").option("--check-id <id>", `specific check to run (see list below), or ALL`, "ALL").option("--node-name <name>", "node name for reports", "node-01").option("--output <path>", "output directory for JSON files").option("--upload", "upload JSON results to PostgresAI (requires API key)").option("--no-upload", "disable upload to PostgresAI").option("--project <project>", "project name or ID for remote upload (used with --upload; defaults to config defaultProject; auto-generated on first run)").option("--json", "output JSON to stdout").addHelpText("after", [
29490
+ program2.command("checkup [checkIdOrConn] [conn]").description("generate health check reports directly from PostgreSQL (express mode)").option("--check-id <id>", `specific check to run (see list below), or ALL`).option("--node-name <name>", "node name for reports", "node-01").option("--output <path>", "output directory for JSON files").option("--upload", "upload JSON results to PostgresAI (requires API key)").option("--no-upload", "disable upload to PostgresAI").option("--project <project>", "project name or ID for remote upload (used with --upload; defaults to config defaultProject; auto-generated on first run)").option("--json", "output JSON to stdout").addHelpText("after", [
29491
29491
  "",
29492
29492
  "Available checks:",
29493
29493
  ...Object.entries(CHECK_INFO).map(([id, title]) => ` ${id}: ${title}`),
29494
29494
  "",
29495
29495
  "Examples:",
29496
29496
  " postgresai checkup postgresql://user:pass@host:5432/db",
29497
- " postgresai checkup postgresql://user:pass@host:5432/db --check-id D001",
29497
+ " postgresai checkup H002 postgresql://user:pass@host:5432/db",
29498
+ " postgresai checkup postgresql://user:pass@host:5432/db --check-id H002",
29498
29499
  " postgresai checkup postgresql://user:pass@host:5432/db --output ./reports",
29499
- " postgresai checkup postgresql://user:pass@host:5432/db --project my_project",
29500
29500
  " postgresai checkup postgresql://user:pass@host:5432/db --no-upload --json"
29501
29501
  ].join(`
29502
- `)).action(async (conn, opts, cmd) => {
29502
+ `)).action(async (checkIdOrConn, connArg, opts, cmd) => {
29503
+ const checkIdPattern = /^[A-Z]\d{3}$/i;
29504
+ let conn;
29505
+ let checkId;
29506
+ if (!checkIdOrConn) {
29507
+ cmd.outputHelp();
29508
+ process.exitCode = 1;
29509
+ return;
29510
+ }
29511
+ if (checkIdPattern.test(checkIdOrConn)) {
29512
+ checkId = checkIdOrConn.toUpperCase();
29513
+ conn = connArg;
29514
+ if (!conn) {
29515
+ console.error(`Error: Connection string required when specifying check ID "${checkId}"`);
29516
+ console.error(`
29517
+ Usage: postgresai checkup ${checkId} postgresql://user@host:5432/dbname
29518
+ `);
29519
+ process.exitCode = 1;
29520
+ return;
29521
+ }
29522
+ } else {
29523
+ conn = checkIdOrConn;
29524
+ checkId = opts.checkId?.toUpperCase() || "ALL";
29525
+ }
29503
29526
  if (!conn) {
29504
29527
  cmd.outputHelp();
29505
29528
  process.exitCode = 1;
@@ -29535,12 +29558,11 @@ program2.command("checkup [conn]").description("generate health check reports di
29535
29558
  const connResult = await connectWithSslFallback(Client, adminConn);
29536
29559
  client = connResult.client;
29537
29560
  let reports;
29538
- if (opts.checkId === "ALL") {
29561
+ if (checkId === "ALL") {
29539
29562
  reports = await generateAllReports(client, opts.nodeName, (p) => {
29540
29563
  spinner.update(`Running ${p.checkId}: ${p.checkTitle} (${p.index}/${p.total})`);
29541
29564
  });
29542
29565
  } else {
29543
- const checkId = opts.checkId.toUpperCase();
29544
29566
  const generator = REPORT_GENERATORS[checkId];
29545
29567
  if (!generator) {
29546
29568
  spinner.stop();
@@ -29549,7 +29571,7 @@ program2.command("checkup [conn]").description("generate health check reports di
29549
29571
  console.error(`Check ${checkId} (${dictEntry.title}) is not yet available in express mode.`);
29550
29572
  console.error(`Express-mode checks: ${Object.keys(CHECK_INFO).join(", ")}`);
29551
29573
  } else {
29552
- console.error(`Unknown check ID: ${opts.checkId}`);
29574
+ console.error(`Unknown check ID: ${checkId}`);
29553
29575
  console.error(`See 'postgresai checkup --help' for available checks.`);
29554
29576
  }
29555
29577
  process.exitCode = 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postgresai",
3
- "version": "0.14.0-dev.83",
3
+ "version": "0.14.0-dev.85",
4
4
  "description": "postgres_ai CLI",
5
5
  "license": "Apache-2.0",
6
6
  "private": false,
@@ -1008,6 +1008,47 @@ describe("CLI tests", () => {
1008
1008
  const r = runCli(["checkup", "postgresql://test:test@localhost:5432/test", "--no-upload"], env);
1009
1009
  expect(r.stderr).not.toMatch(/API key is required/i);
1010
1010
  });
1011
+
1012
+ // Argument parsing tests for check ID / connection string recognition
1013
+ test("checkup with check ID but no connection shows specific error", () => {
1014
+ const r = runCli(["checkup", "H002"]);
1015
+ expect(r.status).not.toBe(0);
1016
+ expect(r.stderr).toMatch(/connection string required/i);
1017
+ expect(r.stderr).toMatch(/H002/);
1018
+ });
1019
+
1020
+ test("checkup recognizes valid check ID patterns", () => {
1021
+ // Valid check IDs: A002, H002, F004, etc.
1022
+ for (const checkId of ["A002", "H002", "F004", "K003", "a002", "h002"]) {
1023
+ const r = runCli(["checkup", checkId]);
1024
+ expect(r.status).not.toBe(0);
1025
+ expect(r.stderr).toMatch(/connection string required/i);
1026
+ }
1027
+ });
1028
+
1029
+ test("checkup does not treat connection string as check ID", () => {
1030
+ // Connection strings should not be parsed as check IDs
1031
+ const r = runCli(["checkup", "postgresql://test:test@localhost:5432/test", "--no-upload"]);
1032
+ // Should not show "connection string required" error
1033
+ expect(r.stderr).not.toMatch(/connection string required/i);
1034
+ });
1035
+
1036
+ test("checkup with check ID and connection string works", () => {
1037
+ // pgai checkup H002 postgresql://...
1038
+ const r = runCli(["checkup", "H002", "postgresql://test:test@localhost:5432/test", "--no-upload"]);
1039
+ // Should not show "connection string required" error
1040
+ expect(r.stderr).not.toMatch(/connection string required/i);
1041
+ // Connection will fail but argument parsing should succeed
1042
+ expect(r.stderr).not.toMatch(/unknown option/i);
1043
+ });
1044
+
1045
+ test("checkup with --check-id option works", () => {
1046
+ // pgai checkup --check-id H002 postgresql://...
1047
+ const r = runCli(["checkup", "--check-id", "H002", "postgresql://test:test@localhost:5432/test", "--no-upload"]);
1048
+ // Should not show "connection string required" error
1049
+ expect(r.stderr).not.toMatch(/connection string required/i);
1050
+ expect(r.stderr).not.toMatch(/unknown option/i);
1051
+ });
1011
1052
  });
1012
1053
 
1013
1054
  // Tests for checkup-api module