postgresai 0.14.0-beta.14 → 0.14.0-beta.15

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.
@@ -13064,7 +13064,7 @@ var {
13064
13064
  // package.json
13065
13065
  var package_default = {
13066
13066
  name: "postgresai",
13067
- version: "0.14.0-beta.14",
13067
+ version: "0.14.0-beta.15",
13068
13068
  description: "postgres_ai CLI",
13069
13069
  license: "Apache-2.0",
13070
13070
  private: false,
@@ -13090,15 +13090,17 @@ var package_default = {
13090
13090
  },
13091
13091
  scripts: {
13092
13092
  "embed-metrics": "bun run scripts/embed-metrics.ts",
13093
- build: `bun run embed-metrics && bun build ./bin/postgres-ai.ts --outdir ./dist/bin --target node && node -e "const fs=require('fs');const f='./dist/bin/postgres-ai.js';fs.writeFileSync(f,fs.readFileSync(f,'utf8').replace('#!/usr/bin/env bun','#!/usr/bin/env node'))" && cp -r ./sql ./dist/sql`,
13093
+ "embed-checkup-dictionary": "bun run scripts/embed-checkup-dictionary.ts",
13094
+ "embed-all": "bun run embed-metrics && bun run embed-checkup-dictionary",
13095
+ build: `bun run embed-all && bun build ./bin/postgres-ai.ts --outdir ./dist/bin --target node && node -e "const fs=require('fs');const f='./dist/bin/postgres-ai.js';fs.writeFileSync(f,fs.readFileSync(f,'utf8').replace('#!/usr/bin/env bun','#!/usr/bin/env node'))" && cp -r ./sql ./dist/sql`,
13094
13096
  prepublishOnly: "npm run build",
13095
13097
  start: "bun ./bin/postgres-ai.ts --help",
13096
13098
  "start:node": "node ./dist/bin/postgres-ai.js --help",
13097
- dev: "bun run embed-metrics && bun --watch ./bin/postgres-ai.ts",
13098
- test: "bun run embed-metrics && bun test",
13099
- "test:fast": "bun run embed-metrics && bun test --coverage=false",
13100
- "test:coverage": "bun run embed-metrics && bun test --coverage && echo 'Coverage report: cli/coverage/lcov-report/index.html'",
13101
- typecheck: "bun run embed-metrics && bunx tsc --noEmit"
13099
+ dev: "bun run embed-all && bun --watch ./bin/postgres-ai.ts",
13100
+ test: "bun run embed-all && bun test",
13101
+ "test:fast": "bun run embed-all && bun test --coverage=false",
13102
+ "test:coverage": "bun run embed-all && bun test --coverage && echo 'Coverage report: cli/coverage/lcov-report/index.html'",
13103
+ typecheck: "bun run embed-all && bunx tsc --noEmit"
13102
13104
  },
13103
13105
  dependencies: {
13104
13106
  "@modelcontextprotocol/sdk": "^1.20.2",
@@ -15887,7 +15889,7 @@ var Result = import_lib.default.Result;
15887
15889
  var TypeOverrides = import_lib.default.TypeOverrides;
15888
15890
  var defaults = import_lib.default.defaults;
15889
15891
  // package.json
15890
- var version = "0.14.0-beta.14";
15892
+ var version = "0.14.0-beta.15";
15891
15893
  var package_default2 = {
15892
15894
  name: "postgresai",
15893
15895
  version,
@@ -15916,15 +15918,17 @@ var package_default2 = {
15916
15918
  },
15917
15919
  scripts: {
15918
15920
  "embed-metrics": "bun run scripts/embed-metrics.ts",
15919
- build: `bun run embed-metrics && bun build ./bin/postgres-ai.ts --outdir ./dist/bin --target node && node -e "const fs=require('fs');const f='./dist/bin/postgres-ai.js';fs.writeFileSync(f,fs.readFileSync(f,'utf8').replace('#!/usr/bin/env bun','#!/usr/bin/env node'))" && cp -r ./sql ./dist/sql`,
15921
+ "embed-checkup-dictionary": "bun run scripts/embed-checkup-dictionary.ts",
15922
+ "embed-all": "bun run embed-metrics && bun run embed-checkup-dictionary",
15923
+ build: `bun run embed-all && bun build ./bin/postgres-ai.ts --outdir ./dist/bin --target node && node -e "const fs=require('fs');const f='./dist/bin/postgres-ai.js';fs.writeFileSync(f,fs.readFileSync(f,'utf8').replace('#!/usr/bin/env bun','#!/usr/bin/env node'))" && cp -r ./sql ./dist/sql`,
15920
15924
  prepublishOnly: "npm run build",
15921
15925
  start: "bun ./bin/postgres-ai.ts --help",
15922
15926
  "start:node": "node ./dist/bin/postgres-ai.js --help",
15923
- dev: "bun run embed-metrics && bun --watch ./bin/postgres-ai.ts",
15924
- test: "bun run embed-metrics && bun test",
15925
- "test:fast": "bun run embed-metrics && bun test --coverage=false",
15926
- "test:coverage": "bun run embed-metrics && bun test --coverage && echo 'Coverage report: cli/coverage/lcov-report/index.html'",
15927
- typecheck: "bun run embed-metrics && bunx tsc --noEmit"
15927
+ dev: "bun run embed-all && bun --watch ./bin/postgres-ai.ts",
15928
+ test: "bun run embed-all && bun test",
15929
+ "test:fast": "bun run embed-all && bun test --coverage=false",
15930
+ "test:coverage": "bun run embed-all && bun test --coverage && echo 'Coverage report: cli/coverage/lcov-report/index.html'",
15931
+ typecheck: "bun run embed-all && bunx tsc --noEmit"
15928
15932
  },
15929
15933
  dependencies: {
15930
15934
  "@modelcontextprotocol/sdk": "^1.20.2",
@@ -26542,6 +26546,572 @@ function transformMetricRow(row) {
26542
26546
  return result;
26543
26547
  }
26544
26548
 
26549
+ // lib/checkup-dictionary-embedded.ts
26550
+ var CHECKUP_DICTIONARY_DATA = [
26551
+ {
26552
+ code: "A001",
26553
+ title: "System information",
26554
+ description: "OS, kernel, hardware details",
26555
+ category: "system",
26556
+ sort_order: null,
26557
+ is_system_report: false
26558
+ },
26559
+ {
26560
+ code: "A002",
26561
+ title: "Postgres major version",
26562
+ description: "Major version and end-of-life status",
26563
+ category: "system",
26564
+ sort_order: null,
26565
+ is_system_report: false
26566
+ },
26567
+ {
26568
+ code: "A003",
26569
+ title: "Postgres settings",
26570
+ description: "Full list of current settings",
26571
+ category: "system",
26572
+ sort_order: null,
26573
+ is_system_report: false
26574
+ },
26575
+ {
26576
+ code: "A004",
26577
+ title: "Cluster information",
26578
+ description: "Data directory, cluster name, system identifier",
26579
+ category: "system",
26580
+ sort_order: null,
26581
+ is_system_report: false
26582
+ },
26583
+ {
26584
+ code: "A005",
26585
+ title: "Extensions",
26586
+ description: "Installed and available extensions",
26587
+ category: "system",
26588
+ sort_order: null,
26589
+ is_system_report: false
26590
+ },
26591
+ {
26592
+ code: "A006",
26593
+ title: "Postgres setting deviations",
26594
+ description: "Settings that differ from defaults",
26595
+ category: "system",
26596
+ sort_order: null,
26597
+ is_system_report: false
26598
+ },
26599
+ {
26600
+ code: "A007",
26601
+ title: "Altered settings",
26602
+ description: "Settings changed via ALTER SYSTEM or per-user/database",
26603
+ category: "system",
26604
+ sort_order: null,
26605
+ is_system_report: false
26606
+ },
26607
+ {
26608
+ code: "A008",
26609
+ title: "Disk usage and file system type",
26610
+ description: "Disk space, mount points, filesystem types",
26611
+ category: "system",
26612
+ sort_order: null,
26613
+ is_system_report: false
26614
+ },
26615
+ {
26616
+ code: "A009",
26617
+ title: "Tablespaces",
26618
+ description: "Tablespace locations and usage",
26619
+ category: "system",
26620
+ sort_order: null,
26621
+ is_system_report: false
26622
+ },
26623
+ {
26624
+ code: "A010",
26625
+ title: "Corruption control",
26626
+ description: "Checksums, wal_log_hints, backup safety",
26627
+ category: "system",
26628
+ sort_order: null,
26629
+ is_system_report: false
26630
+ },
26631
+ {
26632
+ code: "A011",
26633
+ title: "Connection management and pooling",
26634
+ description: "Connection limits and pooler detection",
26635
+ category: "system",
26636
+ sort_order: null,
26637
+ is_system_report: false
26638
+ },
26639
+ {
26640
+ code: "A012",
26641
+ title: "Anti-crash checks",
26642
+ description: "fsync, full_page_writes, synchronous_commit",
26643
+ category: "system",
26644
+ sort_order: null,
26645
+ is_system_report: false
26646
+ },
26647
+ {
26648
+ code: "A013",
26649
+ title: "Postgres minor version",
26650
+ description: "Minor version and available updates",
26651
+ category: "system",
26652
+ sort_order: null,
26653
+ is_system_report: false
26654
+ },
26655
+ {
26656
+ code: "B001",
26657
+ title: "SLO/SLA, RPO, RTO",
26658
+ description: "Recovery objectives and current capabilities",
26659
+ category: "backup",
26660
+ sort_order: null,
26661
+ is_system_report: false
26662
+ },
26663
+ {
26664
+ code: "B002",
26665
+ title: "File system and mount flags",
26666
+ description: "Mount options affecting durability",
26667
+ category: "backup",
26668
+ sort_order: null,
26669
+ is_system_report: false
26670
+ },
26671
+ {
26672
+ code: "B003",
26673
+ title: "Full and incremental backups",
26674
+ description: "Backup tooling and schedule",
26675
+ category: "backup",
26676
+ sort_order: null,
26677
+ is_system_report: false
26678
+ },
26679
+ {
26680
+ code: "B004",
26681
+ title: "WAL archiving",
26682
+ description: "Archive configuration and status",
26683
+ category: "backup",
26684
+ sort_order: null,
26685
+ is_system_report: false
26686
+ },
26687
+ {
26688
+ code: "B005",
26689
+ title: "Backup restore testing and monitoring",
26690
+ description: "Restore testing practices and alerting",
26691
+ category: "backup",
26692
+ sort_order: null,
26693
+ is_system_report: false
26694
+ },
26695
+ {
26696
+ code: "C001",
26697
+ title: "SLO/SLA",
26698
+ description: "Availability objectives",
26699
+ category: "replication",
26700
+ sort_order: null,
26701
+ is_system_report: false
26702
+ },
26703
+ {
26704
+ code: "C002",
26705
+ title: "Replication mode and method",
26706
+ description: "Sync/async, streaming/WAL shipping",
26707
+ category: "replication",
26708
+ sort_order: null,
26709
+ is_system_report: false
26710
+ },
26711
+ {
26712
+ code: "C003",
26713
+ title: "Single points of failure",
26714
+ description: "SPOF analysis",
26715
+ category: "replication",
26716
+ sort_order: null,
26717
+ is_system_report: false
26718
+ },
26719
+ {
26720
+ code: "C004",
26721
+ title: "Failover",
26722
+ description: "Failover mechanism and automation",
26723
+ category: "replication",
26724
+ sort_order: null,
26725
+ is_system_report: false
26726
+ },
26727
+ {
26728
+ code: "C005",
26729
+ title: "Switchover",
26730
+ description: "Planned switchover procedures",
26731
+ category: "replication",
26732
+ sort_order: null,
26733
+ is_system_report: false
26734
+ },
26735
+ {
26736
+ code: "C006",
26737
+ title: "Delayed replica",
26738
+ description: "Delayed standby configuration",
26739
+ category: "replication",
26740
+ sort_order: null,
26741
+ is_system_report: false
26742
+ },
26743
+ {
26744
+ code: "C007",
26745
+ title: "Replication slots and lag",
26746
+ description: "Slot status, lag, standby feedback",
26747
+ category: "replication",
26748
+ sort_order: null,
26749
+ is_system_report: false
26750
+ },
26751
+ {
26752
+ code: "D001",
26753
+ title: "Logging settings",
26754
+ description: "Log destination, verbosity, rotation",
26755
+ category: "monitoring",
26756
+ sort_order: null,
26757
+ is_system_report: false
26758
+ },
26759
+ {
26760
+ code: "D002",
26761
+ title: "Useful Linux tools",
26762
+ description: "Recommended OS-level tooling",
26763
+ category: "monitoring",
26764
+ sort_order: null,
26765
+ is_system_report: false
26766
+ },
26767
+ {
26768
+ code: "D003",
26769
+ title: "Monitoring metrics",
26770
+ description: "Key metrics to track",
26771
+ category: "monitoring",
26772
+ sort_order: null,
26773
+ is_system_report: false
26774
+ },
26775
+ {
26776
+ code: "D004",
26777
+ title: "pg_stat_statements and pg_stat_kcache",
26778
+ description: "Query stats extension settings",
26779
+ category: "monitoring",
26780
+ sort_order: null,
26781
+ is_system_report: false
26782
+ },
26783
+ {
26784
+ code: "D005",
26785
+ title: "track_io_timing and auto_explain",
26786
+ description: "I/O timing and plan logging",
26787
+ category: "monitoring",
26788
+ sort_order: null,
26789
+ is_system_report: false
26790
+ },
26791
+ {
26792
+ code: "D006",
26793
+ title: "Recommended DBA toolsets",
26794
+ description: "Useful third-party tools",
26795
+ category: "monitoring",
26796
+ sort_order: null,
26797
+ is_system_report: false
26798
+ },
26799
+ {
26800
+ code: "D007",
26801
+ title: "Postgres troubleshooting tools",
26802
+ description: "Built-in and ecosystem diagnostic tools",
26803
+ category: "monitoring",
26804
+ sort_order: null,
26805
+ is_system_report: false
26806
+ },
26807
+ {
26808
+ code: "E001",
26809
+ title: "WAL and checkpoint settings",
26810
+ description: "WAL size, checkpoint timing, I/O limits",
26811
+ category: "wal",
26812
+ sort_order: null,
26813
+ is_system_report: false
26814
+ },
26815
+ {
26816
+ code: "E002",
26817
+ title: "Checkpoint and bgwriter activity",
26818
+ description: "Checkpoint frequency, bgwriter stats",
26819
+ category: "wal",
26820
+ sort_order: null,
26821
+ is_system_report: false
26822
+ },
26823
+ {
26824
+ code: "F001",
26825
+ title: "Autovacuum: current settings",
26826
+ description: "Autovacuum configuration",
26827
+ category: "vacuum",
26828
+ sort_order: null,
26829
+ is_system_report: false
26830
+ },
26831
+ {
26832
+ code: "F002",
26833
+ title: "Autovacuum: transaction ID wraparound",
26834
+ description: "XID age and wraparound risk",
26835
+ category: "vacuum",
26836
+ sort_order: null,
26837
+ is_system_report: false
26838
+ },
26839
+ {
26840
+ code: "F003",
26841
+ title: "Autovacuum: dead tuples",
26842
+ description: "Dead tuple counts and cleanup status",
26843
+ category: "vacuum",
26844
+ sort_order: null,
26845
+ is_system_report: false
26846
+ },
26847
+ {
26848
+ code: "F004",
26849
+ title: "Autovacuum: heap bloat estimate",
26850
+ description: "Estimated table bloat",
26851
+ category: "vacuum",
26852
+ sort_order: null,
26853
+ is_system_report: false
26854
+ },
26855
+ {
26856
+ code: "F005",
26857
+ title: "Autovacuum: index bloat estimate",
26858
+ description: "Estimated index bloat",
26859
+ category: "vacuum",
26860
+ sort_order: null,
26861
+ is_system_report: false
26862
+ },
26863
+ {
26864
+ code: "F006",
26865
+ title: "Precise heap bloat analysis",
26866
+ description: "Detailed table bloat measurement",
26867
+ category: "vacuum",
26868
+ sort_order: null,
26869
+ is_system_report: false
26870
+ },
26871
+ {
26872
+ code: "F007",
26873
+ title: "Precise index bloat analysis",
26874
+ description: "Detailed index bloat measurement",
26875
+ category: "vacuum",
26876
+ sort_order: null,
26877
+ is_system_report: false
26878
+ },
26879
+ {
26880
+ code: "F008",
26881
+ title: "Autovacuum: resource usage",
26882
+ description: "Autovacuum I/O and CPU impact",
26883
+ category: "vacuum",
26884
+ sort_order: null,
26885
+ is_system_report: false
26886
+ },
26887
+ {
26888
+ code: "G001",
26889
+ title: "Memory-related settings",
26890
+ description: "shared_buffers, work_mem, maintenance_work_mem",
26891
+ category: "tuning",
26892
+ sort_order: null,
26893
+ is_system_report: false
26894
+ },
26895
+ {
26896
+ code: "G002",
26897
+ title: "Connections and current activity",
26898
+ description: "Connection usage and active sessions",
26899
+ category: "tuning",
26900
+ sort_order: null,
26901
+ is_system_report: false
26902
+ },
26903
+ {
26904
+ code: "G003",
26905
+ title: "Timeouts, locks, deadlocks",
26906
+ description: "Lock settings and deadlock stats",
26907
+ category: "tuning",
26908
+ sort_order: null,
26909
+ is_system_report: false
26910
+ },
26911
+ {
26912
+ code: "G004",
26913
+ title: "Query planner settings",
26914
+ description: "Planner cost and behavior settings",
26915
+ category: "tuning",
26916
+ sort_order: null,
26917
+ is_system_report: false
26918
+ },
26919
+ {
26920
+ code: "G005",
26921
+ title: "I/O settings",
26922
+ description: "effective_io_concurrency, random_page_cost",
26923
+ category: "tuning",
26924
+ sort_order: null,
26925
+ is_system_report: false
26926
+ },
26927
+ {
26928
+ code: "G006",
26929
+ title: "Statistics target settings",
26930
+ description: "default_statistics_target and per-column targets",
26931
+ category: "tuning",
26932
+ sort_order: null,
26933
+ is_system_report: false
26934
+ },
26935
+ {
26936
+ code: "H001",
26937
+ title: "Invalid indexes",
26938
+ description: "Indexes that failed to build",
26939
+ category: "indexes",
26940
+ sort_order: null,
26941
+ is_system_report: false
26942
+ },
26943
+ {
26944
+ code: "H002",
26945
+ title: "Unused indexes",
26946
+ description: "Indexes with no scans",
26947
+ category: "indexes",
26948
+ sort_order: null,
26949
+ is_system_report: false
26950
+ },
26951
+ {
26952
+ code: "H003",
26953
+ title: "Non-indexed foreign keys",
26954
+ description: "FKs missing supporting indexes",
26955
+ category: "indexes",
26956
+ sort_order: null,
26957
+ is_system_report: false
26958
+ },
26959
+ {
26960
+ code: "H004",
26961
+ title: "Redundant indexes",
26962
+ description: "Indexes covered by other indexes",
26963
+ category: "indexes",
26964
+ sort_order: null,
26965
+ is_system_report: false
26966
+ },
26967
+ {
26968
+ code: "J001",
26969
+ title: "Capacity planning",
26970
+ description: "Growth trends and resource projections",
26971
+ category: "capacity",
26972
+ sort_order: null,
26973
+ is_system_report: false
26974
+ },
26975
+ {
26976
+ code: "K001",
26977
+ title: "Globally aggregated query metrics",
26978
+ description: "Overall query stats summary",
26979
+ category: "queries",
26980
+ sort_order: null,
26981
+ is_system_report: false
26982
+ },
26983
+ {
26984
+ code: "K002",
26985
+ title: "Workload type",
26986
+ description: "Read/write/mixed workload classification",
26987
+ category: "queries",
26988
+ sort_order: null,
26989
+ is_system_report: false
26990
+ },
26991
+ {
26992
+ code: "K003",
26993
+ title: "Top queries by total time",
26994
+ description: "Highest total execution + planning time",
26995
+ category: "queries",
26996
+ sort_order: null,
26997
+ is_system_report: false
26998
+ },
26999
+ {
27000
+ code: "K004",
27001
+ title: "Top queries by temp bytes written",
27002
+ description: "Queries spilling to disk",
27003
+ category: "queries",
27004
+ sort_order: null,
27005
+ is_system_report: false
27006
+ },
27007
+ {
27008
+ code: "K005",
27009
+ title: "Top queries by WAL generation",
27010
+ description: "Queries generating most WAL",
27011
+ category: "queries",
27012
+ sort_order: null,
27013
+ is_system_report: false
27014
+ },
27015
+ {
27016
+ code: "K006",
27017
+ title: "Top queries by shared blocks read",
27018
+ description: "Queries with most disk reads",
27019
+ category: "queries",
27020
+ sort_order: null,
27021
+ is_system_report: false
27022
+ },
27023
+ {
27024
+ code: "K007",
27025
+ title: "Top queries by shared blocks hit",
27026
+ description: "Queries with most buffer hits",
27027
+ category: "queries",
27028
+ sort_order: null,
27029
+ is_system_report: false
27030
+ },
27031
+ {
27032
+ code: "K008",
27033
+ title: "Top queries by shared blocks accessed",
27034
+ description: "Queries touching most data",
27035
+ category: "queries",
27036
+ sort_order: null,
27037
+ is_system_report: false
27038
+ },
27039
+ {
27040
+ code: "L001",
27041
+ title: "Table sizes",
27042
+ description: "Table and toast sizes",
27043
+ category: "schema",
27044
+ sort_order: null,
27045
+ is_system_report: false
27046
+ },
27047
+ {
27048
+ code: "L002",
27049
+ title: "Data types being used",
27050
+ description: "Column type distribution",
27051
+ category: "schema",
27052
+ sort_order: null,
27053
+ is_system_report: false
27054
+ },
27055
+ {
27056
+ code: "L003",
27057
+ title: "Integer overflow risks in primary keys",
27058
+ description: "PKs approaching integer limits",
27059
+ category: "schema",
27060
+ sort_order: null,
27061
+ is_system_report: false
27062
+ },
27063
+ {
27064
+ code: "L004",
27065
+ title: "Tables without primary key",
27066
+ description: "Tables missing PK or unique constraint",
27067
+ category: "schema",
27068
+ sort_order: null,
27069
+ is_system_report: false
27070
+ },
27071
+ {
27072
+ code: "M001",
27073
+ title: "Top queries by mean execution time",
27074
+ description: "Slowest queries on average",
27075
+ category: "queries",
27076
+ sort_order: null,
27077
+ is_system_report: false
27078
+ },
27079
+ {
27080
+ code: "M002",
27081
+ title: "Top queries by rows processed",
27082
+ description: "Queries touching most rows",
27083
+ category: "queries",
27084
+ sort_order: null,
27085
+ is_system_report: false
27086
+ },
27087
+ {
27088
+ code: "M003",
27089
+ title: "Top queries by I/O time",
27090
+ description: "Queries with highest I/O wait",
27091
+ category: "queries",
27092
+ sort_order: null,
27093
+ is_system_report: false
27094
+ },
27095
+ {
27096
+ code: "N001",
27097
+ title: "Wait events by type and query",
27098
+ description: "Wait event analysis",
27099
+ category: "waits",
27100
+ sort_order: null,
27101
+ is_system_report: false
27102
+ }
27103
+ ];
27104
+
27105
+ // lib/checkup-dictionary.ts
27106
+ var dictionaryByCode = new Map(CHECKUP_DICTIONARY_DATA.map((entry) => [entry.code.toUpperCase(), entry]));
27107
+ function buildCheckInfoMap() {
27108
+ const result = {};
27109
+ for (const entry of CHECKUP_DICTIONARY_DATA) {
27110
+ result[entry.code] = entry.title;
27111
+ }
27112
+ return result;
27113
+ }
27114
+
26545
27115
  // lib/checkup.ts
26546
27116
  var __dirname = "/builds/postgres-ai/postgres_ai/cli/lib";
26547
27117
  var SECONDS_PER_DAY = 86400;
@@ -27185,6 +27755,23 @@ async function generateD004(client, nodeName) {
27185
27755
  };
27186
27756
  return report;
27187
27757
  }
27758
+ async function generateD001(client, nodeName) {
27759
+ const report = createBaseReport("D001", "Logging settings", nodeName);
27760
+ const postgresVersion = await getPostgresVersion(client);
27761
+ const pgMajorVersion = parseInt(postgresVersion.server_major_ver, 10) || 16;
27762
+ const allSettings = await getSettings(client, pgMajorVersion);
27763
+ const loggingSettings = {};
27764
+ for (const [name, setting] of Object.entries(allSettings)) {
27765
+ if (name.startsWith("log_") || name.startsWith("logging_")) {
27766
+ loggingSettings[name] = setting;
27767
+ }
27768
+ }
27769
+ report.results[nodeName] = {
27770
+ data: loggingSettings,
27771
+ postgres_version: postgresVersion
27772
+ };
27773
+ return report;
27774
+ }
27188
27775
  async function generateF001(client, nodeName) {
27189
27776
  const report = createBaseReport("F001", "Autovacuum: current settings", nodeName);
27190
27777
  const postgresVersion = await getPostgresVersion(client);
@@ -27285,32 +27872,88 @@ async function generateG001(client, nodeName) {
27285
27872
  };
27286
27873
  return report;
27287
27874
  }
27875
+ async function generateG003(client, nodeName) {
27876
+ const report = createBaseReport("G003", "Timeouts, locks, deadlocks", nodeName);
27877
+ const postgresVersion = await getPostgresVersion(client);
27878
+ const pgMajorVersion = parseInt(postgresVersion.server_major_ver, 10) || 16;
27879
+ const allSettings = await getSettings(client, pgMajorVersion);
27880
+ const lockTimeoutSettingNames = [
27881
+ "lock_timeout",
27882
+ "statement_timeout",
27883
+ "idle_in_transaction_session_timeout",
27884
+ "idle_session_timeout",
27885
+ "deadlock_timeout",
27886
+ "max_locks_per_transaction",
27887
+ "max_pred_locks_per_transaction",
27888
+ "max_pred_locks_per_relation",
27889
+ "max_pred_locks_per_page",
27890
+ "log_lock_waits",
27891
+ "transaction_timeout"
27892
+ ];
27893
+ const lockSettings = {};
27894
+ for (const name of lockTimeoutSettingNames) {
27895
+ if (allSettings[name]) {
27896
+ lockSettings[name] = allSettings[name];
27897
+ }
27898
+ }
27899
+ let deadlockStats = null;
27900
+ let deadlockError = null;
27901
+ try {
27902
+ const statsResult = await client.query(`
27903
+ select
27904
+ coalesce(sum(deadlocks), 0)::bigint as deadlocks,
27905
+ coalesce(sum(conflicts), 0)::bigint as conflicts,
27906
+ min(stats_reset)::text as stats_reset
27907
+ from pg_stat_database
27908
+ where datname = current_database()
27909
+ `);
27910
+ if (statsResult.rows.length > 0) {
27911
+ const row = statsResult.rows[0];
27912
+ deadlockStats = {
27913
+ deadlocks: parseInt(row.deadlocks, 10),
27914
+ conflicts: parseInt(row.conflicts, 10),
27915
+ stats_reset: row.stats_reset || null
27916
+ };
27917
+ }
27918
+ } catch (err) {
27919
+ const errorMsg = err instanceof Error ? err.message : String(err);
27920
+ console.log(`[G003] Error querying deadlock stats: ${errorMsg}`);
27921
+ deadlockError = errorMsg;
27922
+ }
27923
+ report.results[nodeName] = {
27924
+ data: {
27925
+ settings: lockSettings,
27926
+ deadlock_stats: deadlockStats,
27927
+ ...deadlockError && { deadlock_stats_error: deadlockError }
27928
+ },
27929
+ postgres_version: postgresVersion
27930
+ };
27931
+ return report;
27932
+ }
27288
27933
  var REPORT_GENERATORS = {
27289
27934
  A002: generateA002,
27290
27935
  A003: generateA003,
27291
27936
  A004: generateA004,
27292
27937
  A007: generateA007,
27293
27938
  A013: generateA013,
27939
+ D001: generateD001,
27294
27940
  D004: generateD004,
27295
27941
  F001: generateF001,
27296
27942
  G001: generateG001,
27943
+ G003: generateG003,
27297
27944
  H001: generateH001,
27298
27945
  H002: generateH002,
27299
27946
  H004: generateH004
27300
27947
  };
27301
- var CHECK_INFO = {
27302
- A002: "Postgres major version",
27303
- A003: "Postgres settings",
27304
- A004: "Cluster information",
27305
- A007: "Altered settings",
27306
- A013: "Postgres minor version",
27307
- D004: "pg_stat_statements and pg_stat_kcache settings",
27308
- F001: "Autovacuum: current settings",
27309
- G001: "Memory-related settings",
27310
- H001: "Invalid indexes",
27311
- H002: "Unused indexes",
27312
- H004: "Redundant indexes"
27313
- };
27948
+ var CHECK_INFO = (() => {
27949
+ const fullMap = buildCheckInfoMap();
27950
+ const expressCheckIds = Object.keys(REPORT_GENERATORS);
27951
+ const filtered = {};
27952
+ for (const checkId of expressCheckIds) {
27953
+ filtered[checkId] = fullMap[checkId] || checkId;
27954
+ }
27955
+ return filtered;
27956
+ })();
27314
27957
  async function generateAllReports(client, nodeName = "node-01", onProgress) {
27315
27958
  const reports = {};
27316
27959
  const entries = Object.entries(REPORT_GENERATORS);
@@ -27329,6 +27972,12 @@ async function generateAllReports(client, nodeName = "node-01", onProgress) {
27329
27972
  return reports;
27330
27973
  }
27331
27974
 
27975
+ // lib/checkup-dictionary.ts
27976
+ var dictionaryByCode2 = new Map(CHECKUP_DICTIONARY_DATA.map((entry) => [entry.code.toUpperCase(), entry]));
27977
+ function getCheckupEntry(code) {
27978
+ return dictionaryByCode2.get(code.toUpperCase()) ?? null;
27979
+ }
27980
+
27332
27981
  // lib/checkup-api.ts
27333
27982
  import * as https from "https";
27334
27983
  import { URL as URL3 } from "url";
@@ -28835,18 +29484,16 @@ program2.command("unprepare-db [conn]").description("remove monitoring setup: dr
28835
29484
  closeReadline();
28836
29485
  }
28837
29486
  });
28838
- program2.command("checkup [conn]").description("generate health check reports directly from PostgreSQL (express mode)").option("--check-id <id>", `specific check to run: ${Object.keys(CHECK_INFO).join(", ")}, or ALL`, "ALL").option("--node-name <name>", "node name for reports", "node-01").option("--output <path>", "output directory for JSON files").option("--[no-]upload", "upload JSON results to PostgresAI (default: enabled; requires API key)", undefined).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 (implies --no-upload)").addHelpText("after", [
29487
+ 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("--[no-]upload", "upload JSON results to PostgresAI (default: enabled; requires API key)", undefined).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 (implies --no-upload)").addHelpText("after", [
28839
29488
  "",
28840
29489
  "Available checks:",
28841
29490
  ...Object.entries(CHECK_INFO).map(([id, title]) => ` ${id}: ${title}`),
28842
29491
  "",
28843
29492
  "Examples:",
28844
29493
  " postgresai checkup postgresql://user:pass@host:5432/db",
28845
- " postgresai checkup postgresql://user:pass@host:5432/db --check-id A003",
29494
+ " postgresai checkup postgresql://user:pass@host:5432/db --check-id D001",
28846
29495
  " postgresai checkup postgresql://user:pass@host:5432/db --output ./reports",
28847
29496
  " postgresai checkup postgresql://user:pass@host:5432/db --project my_project",
28848
- " postgresai set-default-project my_project",
28849
- " postgresai checkup postgresql://user:pass@host:5432/db",
28850
29497
  " postgresai checkup postgresql://user:pass@host:5432/db --no-upload --json"
28851
29498
  ].join(`
28852
29499
  `)).action(async (conn, opts, cmd) => {
@@ -28894,8 +29541,14 @@ program2.command("checkup [conn]").description("generate health check reports di
28894
29541
  const generator = REPORT_GENERATORS[checkId];
28895
29542
  if (!generator) {
28896
29543
  spinner.stop();
28897
- console.error(`Unknown check ID: ${opts.checkId}`);
28898
- console.error(`Available: ${Object.keys(CHECK_INFO).join(", ")}, ALL`);
29544
+ const dictEntry = getCheckupEntry(checkId);
29545
+ if (dictEntry) {
29546
+ console.error(`Check ${checkId} (${dictEntry.title}) is not yet available in express mode.`);
29547
+ console.error(`Express-mode checks: ${Object.keys(CHECK_INFO).join(", ")}`);
29548
+ } else {
29549
+ console.error(`Unknown check ID: ${opts.checkId}`);
29550
+ console.error(`See 'postgresai checkup --help' for available checks.`);
29551
+ }
28899
29552
  process.exitCode = 1;
28900
29553
  return;
28901
29554
  }