@xerg/cli 0.5.2 → 0.5.5

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
@@ -122,23 +122,6 @@ import { closeSync, openSync, readSync } from "fs";
122
122
  function sha1(input) {
123
123
  return createHash("sha1").update(input).digest("hex");
124
124
  }
125
- function sha1File(path) {
126
- const hash = createHash("sha1");
127
- const fd = openSync(path, "r");
128
- const buffer = Buffer.allocUnsafe(64 * 1024);
129
- try {
130
- let bytesRead = 0;
131
- do {
132
- bytesRead = readSync(fd, buffer, 0, buffer.length, null);
133
- if (bytesRead > 0) {
134
- hash.update(buffer.subarray(0, bytesRead));
135
- }
136
- } while (bytesRead > 0);
137
- } finally {
138
- closeSync(fd);
139
- }
140
- return hash.digest("hex");
141
- }
142
125
 
143
126
  // ../core/src/utils/time.ts
144
127
  function parseSince(value) {
@@ -736,354 +719,80 @@ async function inspectCursorUsageCsv(options) {
736
719
  }
737
720
 
738
721
  // ../core/src/db/client.ts
739
- import { mkdirSync } from "fs";
722
+ import { existsSync, mkdirSync, readFileSync as readFileSync2, renameSync, writeFileSync } from "fs";
740
723
  import { dirname } from "path";
741
- import Database from "better-sqlite3";
742
-
743
- // ../core/src/db/schema.ts
744
- var SCHEMA_VERSION = 1;
745
- var SCHEMA_SQL = `
746
- CREATE TABLE IF NOT EXISTS source_files (
747
- id TEXT PRIMARY KEY,
748
- path TEXT NOT NULL,
749
- kind TEXT NOT NULL,
750
- file_hash TEXT NOT NULL,
751
- mtime_ms INTEGER NOT NULL,
752
- size_bytes INTEGER NOT NULL,
753
- imported_at TEXT NOT NULL
754
- );
755
-
756
- CREATE TABLE IF NOT EXISTS runs (
757
- id TEXT PRIMARY KEY,
758
- source_path TEXT NOT NULL,
759
- source_kind TEXT NOT NULL,
760
- timestamp TEXT NOT NULL,
761
- workflow TEXT NOT NULL,
762
- environment TEXT NOT NULL,
763
- tags_json TEXT NOT NULL,
764
- total_cost_usd REAL NOT NULL,
765
- total_tokens INTEGER NOT NULL,
766
- observed_cost_usd REAL NOT NULL,
767
- estimated_cost_usd REAL NOT NULL
768
- );
769
-
770
- CREATE TABLE IF NOT EXISTS calls (
771
- id TEXT PRIMARY KEY,
772
- run_id TEXT NOT NULL,
773
- timestamp TEXT NOT NULL,
774
- provider TEXT NOT NULL,
775
- model TEXT NOT NULL,
776
- input_tokens INTEGER NOT NULL,
777
- output_tokens INTEGER NOT NULL,
778
- cost_usd REAL NOT NULL,
779
- cost_source TEXT NOT NULL,
780
- latency_ms INTEGER,
781
- tool_calls INTEGER NOT NULL,
782
- retries INTEGER NOT NULL,
783
- attempt INTEGER,
784
- iteration INTEGER,
785
- status TEXT,
786
- task_class TEXT,
787
- cache_hit INTEGER NOT NULL,
788
- cache_cost_usd REAL,
789
- metadata_json TEXT NOT NULL
790
- );
791
-
792
- CREATE TABLE IF NOT EXISTS findings (
793
- id TEXT PRIMARY KEY,
794
- audit_id TEXT NOT NULL,
795
- classification TEXT NOT NULL,
796
- confidence TEXT NOT NULL,
797
- kind TEXT NOT NULL,
798
- title TEXT NOT NULL,
799
- summary TEXT NOT NULL,
800
- scope TEXT NOT NULL,
801
- scope_id TEXT NOT NULL,
802
- cost_impact_usd REAL NOT NULL,
803
- details_json TEXT NOT NULL
804
- );
805
-
806
- CREATE TABLE IF NOT EXISTS pricing_catalog (
807
- id TEXT PRIMARY KEY,
808
- provider TEXT NOT NULL,
809
- model TEXT NOT NULL,
810
- effective_date TEXT NOT NULL,
811
- input_per_1m REAL NOT NULL,
812
- output_per_1m REAL NOT NULL,
813
- cached_input_per_1m REAL
814
- );
815
-
816
- CREATE TABLE IF NOT EXISTS audit_snapshots (
817
- id TEXT PRIMARY KEY,
818
- created_at TEXT NOT NULL,
819
- summary_json TEXT NOT NULL
820
- );
821
- `;
822
-
823
- // ../core/src/db/client.ts
824
- function createDb(path) {
825
- mkdirSync(dirname(path), { recursive: true });
826
- const sqlite = new Database(path);
827
- const currentVersion = sqlite.pragma("user_version", { simple: true });
828
- if (currentVersion > SCHEMA_VERSION) {
829
- sqlite.close();
830
- throw new Error(
831
- `Unsupported Xerg database schema version ${currentVersion}. This build supports up to ${SCHEMA_VERSION}.`
724
+ var SNAPSHOT_STORE_VERSION = 1;
725
+ function readStoredSnapshotRows(path) {
726
+ if (!existsSync(path)) {
727
+ return [];
728
+ }
729
+ try {
730
+ return normalizeStore(JSON.parse(readFileSync2(path, "utf8"))).auditSnapshots.sort(
731
+ (left, right) => right.createdAt.localeCompare(left.createdAt)
832
732
  );
733
+ } catch (error) {
734
+ const message = error instanceof Error ? error.message : "Unknown error";
735
+ process.stderr.write(`Warning: skipping unreadable local snapshot store ${path}: ${message}
736
+ `);
737
+ return [];
833
738
  }
834
- sqlite.exec(SCHEMA_SQL);
835
- if (currentVersion < SCHEMA_VERSION) {
836
- sqlite.pragma(`user_version = ${SCHEMA_VERSION}`);
739
+ }
740
+ function writeStoredSnapshotRows(path, rows) {
741
+ mkdirSync(dirname(path), { recursive: true });
742
+ const store = {
743
+ version: SNAPSHOT_STORE_VERSION,
744
+ auditSnapshots: rows.sort((left, right) => right.createdAt.localeCompare(left.createdAt))
745
+ };
746
+ const tempPath = `${path}.tmp-${process.pid}-${Date.now()}`;
747
+ writeFileSync(tempPath, `${JSON.stringify(store, null, 2)}
748
+ `, "utf8");
749
+ renameSync(tempPath, path);
750
+ }
751
+ function upsertStoredAuditSnapshot(path, row) {
752
+ const rows = readStoredSnapshotRows(path);
753
+ if (rows.some((existing) => existing.id === row.id)) {
754
+ return;
837
755
  }
838
- return { sqlite };
756
+ writeStoredSnapshotRows(path, [...rows, row]);
839
757
  }
840
-
841
- // ../core/src/db/persist.ts
842
- function persistAudit(audit, dbPath) {
843
- const { sqlite } = createDb(dbPath);
844
- const importedAt = isoNow();
845
- const pricingRows = audit.pricingCatalog.map((entry) => ({
846
- ...entry,
847
- cachedInputPer1m: entry.cachedInputPer1m ?? null
848
- }));
849
- const sourceFileRows = audit.summary.sourceFiles.map((file) => ({
850
- id: sha1(`${file.path}:${file.mtimeMs}:${file.sizeBytes}`),
851
- path: file.path,
852
- kind: file.kind,
853
- fileHash: sha1File(file.path),
854
- mtimeMs: Math.trunc(file.mtimeMs),
855
- sizeBytes: file.sizeBytes,
856
- importedAt
857
- }));
858
- const runRows = audit.runs.map((run2) => ({
859
- id: run2.id,
860
- sourcePath: run2.sourcePath,
861
- sourceKind: run2.sourceKind,
862
- timestamp: run2.timestamp,
863
- workflow: run2.workflow,
864
- environment: run2.environment,
865
- tagsJson: JSON.stringify(run2.tags),
866
- totalCostUsd: run2.totalCostUsd,
867
- totalTokens: run2.totalTokens,
868
- observedCostUsd: run2.observedCostUsd,
869
- estimatedCostUsd: run2.estimatedCostUsd
870
- }));
871
- const callRows = audit.runs.flatMap(
872
- (run2) => run2.calls.map((call) => ({
873
- id: call.id,
874
- runId: call.runId,
875
- timestamp: call.timestamp,
876
- provider: call.provider,
877
- model: call.model,
878
- inputTokens: call.inputTokens,
879
- outputTokens: call.outputTokens,
880
- costUsd: call.costUsd,
881
- costSource: call.costSource,
882
- latencyMs: call.latencyMs,
883
- toolCalls: call.toolCalls,
884
- retries: call.retries,
885
- attempt: call.attempt,
886
- iteration: call.iteration,
887
- status: call.status,
888
- taskClass: call.taskClass,
889
- cacheHit: call.cacheHit,
890
- cacheCostUsd: call.cacheCostUsd,
891
- metadataJson: JSON.stringify(call.metadata)
892
- }))
893
- );
894
- const findingRows = audit.summary.findings.map((finding) => ({
895
- id: finding.id,
896
- auditId: audit.summary.auditId,
897
- classification: finding.classification,
898
- confidence: finding.confidence,
899
- kind: finding.kind,
900
- title: finding.title,
901
- summary: finding.summary,
902
- scope: finding.scope,
903
- scopeId: finding.scopeId,
904
- costImpactUsd: finding.costImpactUsd,
905
- detailsJson: JSON.stringify(finding.details)
906
- }));
907
- const persistTransaction = sqlite.transaction(() => {
908
- insertMany(
909
- sqlite,
910
- `
911
- INSERT OR IGNORE INTO pricing_catalog (
912
- id,
913
- provider,
914
- model,
915
- effective_date,
916
- input_per_1m,
917
- output_per_1m,
918
- cached_input_per_1m
919
- ) VALUES (?, ?, ?, ?, ?, ?, ?)
920
- `,
921
- pricingRows.map((row) => [
922
- row.id,
923
- row.provider,
924
- row.model,
925
- row.effectiveDate,
926
- row.inputPer1m,
927
- row.outputPer1m,
928
- row.cachedInputPer1m
929
- ])
930
- );
931
- insertMany(
932
- sqlite,
933
- `
934
- INSERT OR IGNORE INTO source_files (
935
- id,
936
- path,
937
- kind,
938
- file_hash,
939
- mtime_ms,
940
- size_bytes,
941
- imported_at
942
- ) VALUES (?, ?, ?, ?, ?, ?, ?)
943
- `,
944
- sourceFileRows.map((row) => [
945
- row.id,
946
- row.path,
947
- row.kind,
948
- row.fileHash,
949
- row.mtimeMs,
950
- row.sizeBytes,
951
- row.importedAt
952
- ])
953
- );
954
- insertMany(
955
- sqlite,
956
- `
957
- INSERT OR IGNORE INTO runs (
958
- id,
959
- source_path,
960
- source_kind,
961
- timestamp,
962
- workflow,
963
- environment,
964
- tags_json,
965
- total_cost_usd,
966
- total_tokens,
967
- observed_cost_usd,
968
- estimated_cost_usd
969
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
970
- `,
971
- runRows.map((row) => [
972
- row.id,
973
- row.sourcePath,
974
- row.sourceKind,
975
- row.timestamp,
976
- row.workflow,
977
- row.environment,
978
- row.tagsJson,
979
- row.totalCostUsd,
980
- row.totalTokens,
981
- row.observedCostUsd,
982
- row.estimatedCostUsd
983
- ])
984
- );
985
- insertMany(
986
- sqlite,
987
- `
988
- INSERT OR IGNORE INTO calls (
989
- id,
990
- run_id,
991
- timestamp,
992
- provider,
993
- model,
994
- input_tokens,
995
- output_tokens,
996
- cost_usd,
997
- cost_source,
998
- latency_ms,
999
- tool_calls,
1000
- retries,
1001
- attempt,
1002
- iteration,
1003
- status,
1004
- task_class,
1005
- cache_hit,
1006
- cache_cost_usd,
1007
- metadata_json
1008
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1009
- `,
1010
- callRows.map((row) => [
1011
- row.id,
1012
- row.runId,
1013
- row.timestamp,
1014
- row.provider,
1015
- row.model,
1016
- row.inputTokens,
1017
- row.outputTokens,
1018
- row.costUsd,
1019
- row.costSource,
1020
- row.latencyMs ?? null,
1021
- row.toolCalls,
1022
- row.retries,
1023
- row.attempt ?? null,
1024
- row.iteration ?? null,
1025
- row.status ?? null,
1026
- row.taskClass ?? null,
1027
- row.cacheHit ? 1 : 0,
1028
- row.cacheCostUsd ?? null,
1029
- row.metadataJson
1030
- ])
1031
- );
1032
- insertMany(
1033
- sqlite,
1034
- `
1035
- INSERT OR IGNORE INTO findings (
1036
- id,
1037
- audit_id,
1038
- classification,
1039
- confidence,
1040
- kind,
1041
- title,
1042
- summary,
1043
- scope,
1044
- scope_id,
1045
- cost_impact_usd,
1046
- details_json
1047
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1048
- `,
1049
- findingRows.map((row) => [
1050
- row.id,
1051
- row.auditId,
1052
- row.classification,
1053
- row.confidence,
1054
- row.kind,
1055
- row.title,
1056
- row.summary,
1057
- row.scope,
1058
- row.scopeId,
1059
- row.costImpactUsd,
1060
- row.detailsJson
1061
- ])
1062
- );
1063
- sqlite.prepare(
1064
- `
1065
- INSERT OR IGNORE INTO audit_snapshots (
1066
- id,
1067
- created_at,
1068
- summary_json
1069
- ) VALUES (?, ?, ?)
1070
- `
1071
- ).run(audit.summary.auditId, audit.summary.generatedAt, JSON.stringify(audit.summary));
1072
- });
1073
- try {
1074
- persistTransaction();
1075
- } finally {
1076
- sqlite.close();
758
+ function normalizeStore(input) {
759
+ if (!input || typeof input !== "object") {
760
+ throw new Error("Snapshot store is not an object.");
761
+ }
762
+ const store = input;
763
+ if (store.version !== SNAPSHOT_STORE_VERSION) {
764
+ throw new Error(`Unsupported snapshot store version ${String(store.version)}.`);
765
+ }
766
+ if (!Array.isArray(store.auditSnapshots)) {
767
+ throw new Error("Snapshot store auditSnapshots field is missing or invalid.");
1077
768
  }
769
+ return {
770
+ version: SNAPSHOT_STORE_VERSION,
771
+ auditSnapshots: store.auditSnapshots.map(normalizeSnapshotRow)
772
+ };
1078
773
  }
1079
- function insertMany(sqlite, sql, rows) {
1080
- if (rows.length === 0) {
1081
- return;
774
+ function normalizeSnapshotRow(input) {
775
+ if (!input || typeof input !== "object") {
776
+ throw new Error("Snapshot row is not an object.");
1082
777
  }
1083
- const statement = sqlite.prepare(sql);
1084
- for (const row of rows) {
1085
- statement.run(...row);
778
+ const row = input;
779
+ if (typeof row.id !== "string" || typeof row.createdAt !== "string" || typeof row.summaryJson !== "string") {
780
+ throw new Error("Snapshot row is missing id, createdAt, or summaryJson.");
1086
781
  }
782
+ return {
783
+ id: row.id,
784
+ createdAt: row.createdAt,
785
+ summaryJson: row.summaryJson
786
+ };
787
+ }
788
+
789
+ // ../core/src/db/persist.ts
790
+ function persistAudit(audit, dbPath) {
791
+ upsertStoredAuditSnapshot(dbPath, {
792
+ id: audit.summary.auditId,
793
+ createdAt: audit.summary.generatedAt,
794
+ summaryJson: JSON.stringify(audit.summary)
795
+ });
1087
796
  }
1088
797
 
1089
798
  // ../core/src/report/comparison.ts
@@ -1358,19 +1067,7 @@ function parseAuditSummary(row) {
1358
1067
  }
1359
1068
  }
1360
1069
  function listStoredAuditSummaries(dbPath) {
1361
- const { sqlite } = createDb(dbPath);
1362
- try {
1363
- const rows = sqlite.prepare(
1364
- `
1365
- SELECT id, summary_json AS summaryJson
1366
- FROM audit_snapshots
1367
- ORDER BY created_at DESC
1368
- `
1369
- ).all();
1370
- return rows.map((row) => parseAuditSummary(row)).filter((summary) => summary !== null);
1371
- } finally {
1372
- sqlite.close();
1373
- }
1070
+ return readStoredSnapshotRows(dbPath).map((row) => parseAuditSummary(row)).filter((summary) => summary !== null);
1374
1071
  }
1375
1072
  function readLatestComparableAuditSummary(input) {
1376
1073
  return listStoredAuditSummaries(input.dbPath).find((summary) => {
@@ -2368,7 +2065,7 @@ import { homedir as homedir2 } from "os";
2368
2065
  import { basename as basename2, join as join3 } from "path";
2369
2066
 
2370
2067
  // ../core/src/normalize/hermes.ts
2371
- import { readFileSync as readFileSync2 } from "fs";
2068
+ import { readFileSync as readFileSync3 } from "fs";
2372
2069
  import { basename } from "path";
2373
2070
 
2374
2071
  // ../core/src/utils/records.ts
@@ -2454,7 +2151,7 @@ function parseJsonLine(line) {
2454
2151
  }
2455
2152
  }
2456
2153
  function parseJsonLines(path) {
2457
- const content = readFileSync2(path, "utf8");
2154
+ const content = readFileSync3(path, "utf8");
2458
2155
  const lines = content.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
2459
2156
  const records = [];
2460
2157
  for (const line of lines) {
@@ -2807,7 +2504,7 @@ function getAppPaths() {
2807
2504
  };
2808
2505
  }
2809
2506
  function getDefaultDbPath() {
2810
- return join(getAppPaths().data, "xerg.db");
2507
+ return join(getAppPaths().data, "xerg-snapshots.json");
2811
2508
  }
2812
2509
  function getDefaultOpenClawSessionsPattern() {
2813
2510
  return join(getUserHome(), ".openclaw", "agents", "*", "sessions", "*.jsonl");
@@ -2998,10 +2695,10 @@ async function detectOpenClawSources(options) {
2998
2695
  }
2999
2696
 
3000
2697
  // ../core/src/normalize/openclaw.ts
3001
- import { readFileSync as readFileSync3 } from "fs";
2698
+ import { readFileSync as readFileSync4 } from "fs";
3002
2699
  import { basename as basename3 } from "path";
3003
2700
  function parseJsonLines2(path) {
3004
- const content = readFileSync3(path, "utf8");
2701
+ const content = readFileSync4(path, "utf8");
3005
2702
  const lines = content.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
3006
2703
  const records = [];
3007
2704
  for (const line of lines) {
@@ -4226,12 +3923,12 @@ async function pushAudit(payload, config) {
4226
3923
  }
4227
3924
 
4228
3925
  // src/push/config.ts
4229
- import { readFileSync as readFileSync5 } from "fs";
3926
+ import { readFileSync as readFileSync6 } from "fs";
4230
3927
  import { homedir as homedir4 } from "os";
4231
3928
  import { join as join5 } from "path";
4232
3929
 
4233
3930
  // src/auth/credentials.ts
4234
- import { existsSync, mkdirSync as mkdirSync3, readFileSync as readFileSync4, rmSync, writeFileSync } from "fs";
3931
+ import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync5, rmSync, writeFileSync as writeFileSync2 } from "fs";
4235
3932
  import { homedir as homedir3 } from "os";
4236
3933
  import { dirname as dirname2, join as join4 } from "path";
4237
3934
  function getCredentialsPath() {
@@ -4243,13 +3940,13 @@ function storeCredentials(token) {
4243
3940
  const dir = dirname2(credPath);
4244
3941
  mkdirSync3(dir, { recursive: true });
4245
3942
  const data = { token, storedAt: (/* @__PURE__ */ new Date()).toISOString() };
4246
- writeFileSync(credPath, JSON.stringify(data, null, 2), { mode: 384 });
3943
+ writeFileSync2(credPath, JSON.stringify(data, null, 2), { mode: 384 });
4247
3944
  }
4248
3945
  function loadStoredCredentials() {
4249
3946
  const credPath = getCredentialsPath();
4250
3947
  try {
4251
- if (!existsSync(credPath)) return null;
4252
- const raw = readFileSync4(credPath, "utf8");
3948
+ if (!existsSync2(credPath)) return null;
3949
+ const raw = readFileSync5(credPath, "utf8");
4253
3950
  const parsed = JSON.parse(raw);
4254
3951
  return parsed.token || null;
4255
3952
  } catch {
@@ -4259,7 +3956,7 @@ function loadStoredCredentials() {
4259
3956
  function clearCredentials() {
4260
3957
  const credPath = getCredentialsPath();
4261
3958
  try {
4262
- if (!existsSync(credPath)) return false;
3959
+ if (!existsSync2(credPath)) return false;
4263
3960
  rmSync(credPath);
4264
3961
  return true;
4265
3962
  } catch {
@@ -4281,7 +3978,7 @@ function loadPushConfig() {
4281
3978
  };
4282
3979
  }
4283
3980
  try {
4284
- const raw = readFileSync5(CONFIG_PATH, "utf8");
3981
+ const raw = readFileSync6(CONFIG_PATH, "utf8");
4285
3982
  const parsed = JSON.parse(raw);
4286
3983
  if (parsed.apiKey) {
4287
3984
  return {
@@ -5100,13 +4797,13 @@ function formatBytes2(bytes) {
5100
4797
  }
5101
4798
 
5102
4799
  // src/transport/config.ts
5103
- import { readFileSync as readFileSync6 } from "fs";
4800
+ import { readFileSync as readFileSync7 } from "fs";
5104
4801
  import { resolve as resolve3 } from "path";
5105
4802
  function loadRemoteConfig(configPath) {
5106
4803
  const resolved = resolve3(configPath);
5107
4804
  let raw;
5108
4805
  try {
5109
- raw = readFileSync6(resolved, "utf8");
4806
+ raw = readFileSync7(resolved, "utf8");
5110
4807
  } catch {
5111
4808
  throw new Error(`Cannot read remote config at ${resolved}`);
5112
4809
  }
@@ -5253,11 +4950,11 @@ function resolveRemoteHost(target) {
5253
4950
  }
5254
4951
 
5255
4952
  // src/version.ts
5256
- import { readFileSync as readFileSync7 } from "fs";
4953
+ import { readFileSync as readFileSync8 } from "fs";
5257
4954
  function getCliVersion() {
5258
4955
  try {
5259
4956
  const packageJsonPath = new URL("../package.json", import.meta.url);
5260
- const packageJson = JSON.parse(readFileSync7(packageJsonPath, "utf8"));
4957
+ const packageJson = JSON.parse(readFileSync8(packageJsonPath, "utf8"));
5261
4958
  return packageJson.version ?? "0.0.0";
5262
4959
  } catch {
5263
4960
  return "0.0.0";
@@ -5793,7 +5490,8 @@ function renderMcpCredentialSourceMessage(config) {
5793
5490
  }
5794
5491
 
5795
5492
  // src/prompts.ts
5796
- import { confirm, select } from "@inquirer/prompts";
5493
+ import confirm from "@inquirer/confirm";
5494
+ import select from "@inquirer/select";
5797
5495
  function hasPromptTty() {
5798
5496
  return Boolean(process.stdin.isTTY && process.stdout.isTTY);
5799
5497
  }
@@ -5811,7 +5509,7 @@ async function promptSelect(message, choices) {
5811
5509
  }
5812
5510
 
5813
5511
  // src/commands/push.ts
5814
- import { readFileSync as readFileSync8 } from "fs";
5512
+ import { readFileSync as readFileSync9 } from "fs";
5815
5513
  async function runPushCommand(options) {
5816
5514
  const payload = options.file ? loadPayloadFromFile(options.file) : loadLatestCachedAuditPayload();
5817
5515
  if (options.dryRun) {
@@ -5835,7 +5533,7 @@ async function runPushCommand(options) {
5835
5533
  function loadPayloadFromFile(filePath) {
5836
5534
  let raw;
5837
5535
  try {
5838
- raw = readFileSync8(filePath, "utf8");
5536
+ raw = readFileSync9(filePath, "utf8");
5839
5537
  } catch {
5840
5538
  throw new Error(`Cannot read file: ${filePath}`);
5841
5539
  }
@@ -6206,7 +5904,7 @@ function renderRailwayDoctorReport(report) {
6206
5904
  }
6207
5905
 
6208
5906
  // src/commands/mcp-setup.ts
6209
- import { existsSync as existsSync2, mkdirSync as mkdirSync6, readFileSync as readFileSync9, writeFileSync as writeFileSync2 } from "fs";
5907
+ import { existsSync as existsSync3, mkdirSync as mkdirSync6, readFileSync as readFileSync10, writeFileSync as writeFileSync3 } from "fs";
6210
5908
  import { dirname as dirname3, join as join8 } from "path";
6211
5909
  var HOSTED_MCP_URL = "https://mcp.xerg.ai/mcp";
6212
5910
  var MCP_SERVER_NAME = "xerg";
@@ -6292,7 +5990,7 @@ async function runMcpSetupFlow() {
6292
5990
  async function handleCursorSetup(snippet, config) {
6293
5991
  const cursorDir = join8(process.cwd(), ".cursor");
6294
5992
  const cursorConfigPath = join8(cursorDir, "mcp.json");
6295
- if (existsSync2(cursorDir)) {
5993
+ if (existsSync3(cursorDir)) {
6296
5994
  const shouldWrite = await promptConfirm(
6297
5995
  "Write a project-scoped Cursor MCP config to .cursor/mcp.json?",
6298
5996
  true
@@ -6339,9 +6037,9 @@ function tomlString(value) {
6339
6037
  function writeCursorConfig(filePath, config) {
6340
6038
  mkdirSync6(dirname3(filePath), { recursive: true });
6341
6039
  let parsed = {};
6342
- if (existsSync2(filePath)) {
6040
+ if (existsSync3(filePath)) {
6343
6041
  try {
6344
- parsed = JSON.parse(readFileSync9(filePath, "utf8"));
6042
+ parsed = JSON.parse(readFileSync10(filePath, "utf8"));
6345
6043
  } catch {
6346
6044
  throw new Error(`Cursor config is not valid JSON: ${filePath}`);
6347
6045
  }
@@ -6354,7 +6052,7 @@ function writeCursorConfig(filePath, config) {
6354
6052
  ...existingServers ?? {},
6355
6053
  xerg: buildHostedMcpConfig(config).mcpServers.xerg
6356
6054
  };
6357
- writeFileSync2(filePath, `${JSON.stringify(parsed, null, 2)}
6055
+ writeFileSync3(filePath, `${JSON.stringify(parsed, null, 2)}
6358
6056
  `);
6359
6057
  }
6360
6058
 
@@ -6566,7 +6264,7 @@ Options:
6566
6264
  --compare Compare this audit to the newest compatible prior local snapshot
6567
6265
  --json Render the report as JSON
6568
6266
  --markdown Render the report as Markdown
6569
- --db <path> Custom SQLite database path
6267
+ --db <path> Custom JSON snapshot path
6570
6268
  --no-db Skip local persistence
6571
6269
 
6572
6270
  Remote options (SSH, OpenClaw only):