@automagik/omni 2.260524.1 → 2.260525.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
@@ -4663,40 +4663,157 @@ var require_cli_spinners = __commonJS((exports, module) => {
4663
4663
  // src/lib/embedded-canonical-migration.ts
4664
4664
  var exports_embedded_canonical_migration = {};
4665
4665
  __export(exports_embedded_canonical_migration, {
4666
+ readDataDirMajor: () => readDataDirMajor,
4666
4667
  migrateUnmountedEmbeddedToCanonical: () => migrateUnmountedEmbeddedToCanonical,
4668
+ embeddedPostgresPackage: () => embeddedPostgresPackage,
4669
+ compareVersionDesc: () => compareVersionDesc,
4667
4670
  compareEmbeddedVsCanonicalCounts: () => compareEmbeddedVsCanonicalCounts,
4671
+ MIGRATION_SKIP_TABLES: () => MIGRATION_SKIP_TABLES,
4668
4672
  EMBEDDED_PGSERVE_DATA_DIR: () => EMBEDDED_PGSERVE_DATA_DIR
4669
4673
  });
4670
- import { spawn, spawnSync as spawnSync2 } from "child_process";
4671
- import { existsSync as existsSync9, mkdtempSync } from "fs";
4674
+ import { execFileSync as execFileSync3, spawn, spawnSync as spawnSync2 } from "child_process";
4675
+ import { existsSync as existsSync9, mkdirSync as mkdirSync6, mkdtempSync, readFileSync as readFileSync6, readdirSync as readdirSync2, symlinkSync } from "fs";
4672
4676
  import { createServer } from "net";
4673
- import { homedir as homedir7, tmpdir } from "os";
4674
- import { join as join11 } from "path";
4677
+ import { arch, homedir as homedir7, platform, tmpdir } from "os";
4678
+ import { dirname as dirname2, join as join11 } from "path";
4675
4679
  import { setTimeout as sleep2 } from "timers/promises";
4676
4680
  function defaultLog(line) {
4677
4681
  process.stdout.write(`${line}
4678
4682
  `);
4679
4683
  }
4680
- function findAutopgPostgresBinary() {
4684
+ function readDataDirMajor(dataDir) {
4685
+ try {
4686
+ const major = Number.parseInt(readFileSync6(join11(dataDir, "PG_VERSION"), "utf8").trim(), 10);
4687
+ return Number.isFinite(major) ? major : null;
4688
+ } catch {
4689
+ return null;
4690
+ }
4691
+ }
4692
+ function binaryMajor(binary) {
4693
+ try {
4694
+ const out = execFileSync3(binary, ["--version"], { encoding: "utf8", timeout: 5000 });
4695
+ const m = out.match(/(\d+)(?:[.\s]|$)/);
4696
+ return m ? Number.parseInt(m[1], 10) : null;
4697
+ } catch {
4698
+ return null;
4699
+ }
4700
+ }
4701
+ function findAutopgPostgresBinary(wantMajor) {
4681
4702
  const autopgRoot = join11(homedir7(), ".local", "share", "autopg");
4682
4703
  if (!existsSync9(autopgRoot))
4683
4704
  return null;
4684
- let bestPath = null;
4685
- for (const entry of safeReaddir(autopgRoot)) {
4686
- const candidate = join11(autopgRoot, entry, "postgres", "bin", "postgres");
4687
- if (existsSync9(candidate))
4688
- bestPath = candidate;
4705
+ const candidates = safeReaddir(autopgRoot).sort((a, b) => compareVersionDesc(a, b)).map((entry) => join11(autopgRoot, entry, "postgres", "bin", "postgres")).filter((candidate) => existsSync9(candidate));
4706
+ if (candidates.length === 0)
4707
+ return null;
4708
+ if (wantMajor === null)
4709
+ return candidates[0];
4710
+ for (const candidate of candidates) {
4711
+ if (binaryMajor(candidate) === wantMajor)
4712
+ return candidate;
4713
+ }
4714
+ return null;
4715
+ }
4716
+ function compareVersionDesc(a, b) {
4717
+ const parse = (s) => (s.match(/\d+/g) ?? []).map(Number);
4718
+ const pa = parse(a);
4719
+ const pb = parse(b);
4720
+ for (let i = 0;i < Math.max(pa.length, pb.length); i++) {
4721
+ const diff = (pb[i] ?? 0) - (pa[i] ?? 0);
4722
+ if (diff !== 0)
4723
+ return diff;
4689
4724
  }
4690
- return bestPath;
4725
+ return b.localeCompare(a);
4691
4726
  }
4692
4727
  function safeReaddir(path) {
4693
4728
  try {
4694
- const { readdirSync: readdirSync2 } = __require("fs");
4695
4729
  return readdirSync2(path);
4696
4730
  } catch {
4697
4731
  return [];
4698
4732
  }
4699
4733
  }
4734
+ function embeddedPostgresPackage() {
4735
+ const a = arch() === "arm64" ? "arm64" : arch() === "x64" ? "x64" : null;
4736
+ if (!a)
4737
+ return null;
4738
+ if (platform() === "linux")
4739
+ return `@embedded-postgres/linux-${a}`;
4740
+ if (platform() === "darwin")
4741
+ return `@embedded-postgres/darwin-${a}`;
4742
+ if (platform() === "win32" && a === "x64")
4743
+ return "@embedded-postgres/windows-x64";
4744
+ return null;
4745
+ }
4746
+ function latestReaderVersion(pkg, major) {
4747
+ try {
4748
+ const raw2 = execFileSync3("npm", ["view", pkg, "versions", "--json"], { encoding: "utf8", timeout: 30000 });
4749
+ const versions = JSON.parse(raw2);
4750
+ const list2 = Array.isArray(versions) ? versions : [versions];
4751
+ const matching = list2.filter((v) => v.startsWith(`${major}.`)).sort(compareVersionDesc);
4752
+ return matching.length ? matching[0] : null;
4753
+ } catch {
4754
+ return null;
4755
+ }
4756
+ }
4757
+ function materializeReaderLibs(nativeDir) {
4758
+ const libDir = join11(nativeDir, "lib");
4759
+ try {
4760
+ const pkgRoot = dirname2(nativeDir);
4761
+ const pairs = JSON.parse(readFileSync6(join11(nativeDir, "pg-symlinks.json"), "utf8"));
4762
+ for (const { source, target } of pairs) {
4763
+ const tgt = join11(pkgRoot, target);
4764
+ if (!existsSync9(tgt)) {
4765
+ try {
4766
+ symlinkSync(join11(pkgRoot, source), tgt);
4767
+ } catch {}
4768
+ }
4769
+ }
4770
+ } catch {}
4771
+ for (const f of safeReaddir(libDir)) {
4772
+ const m = f.match(/^(.*\.so\.\d+)\.\d+/);
4773
+ if (!m)
4774
+ continue;
4775
+ const base = join11(libDir, m[1]);
4776
+ if (!existsSync9(base)) {
4777
+ try {
4778
+ symlinkSync(join11(libDir, f), base);
4779
+ } catch {}
4780
+ }
4781
+ }
4782
+ }
4783
+ function fetchEmbeddedReader(major, log) {
4784
+ const pkg = embeddedPostgresPackage();
4785
+ if (!pkg)
4786
+ return null;
4787
+ const cacheDir = join11(homedir7(), ".omni", "cache", `pg-reader-${major}`);
4788
+ const nativeDir = join11(cacheDir, "node_modules", pkg, "native");
4789
+ const binary = join11(nativeDir, "bin", "postgres");
4790
+ if (existsSync9(binary) && binaryMajor(binary) === major) {
4791
+ materializeReaderLibs(nativeDir);
4792
+ return { binary, libDir: join11(nativeDir, "lib") };
4793
+ }
4794
+ const version = latestReaderVersion(pkg, major);
4795
+ if (!version)
4796
+ return null;
4797
+ log(` fetching PG ${major} reader (${pkg}@${version}) \u2014 one-time, cached at ${cacheDir}`);
4798
+ try {
4799
+ mkdirSync6(cacheDir, { recursive: true });
4800
+ const res = spawnSync2("bun", ["add", `${pkg}@${version}`], { cwd: cacheDir, encoding: "utf8", timeout: 180000 });
4801
+ if (res.status !== 0 || !existsSync9(binary))
4802
+ return null;
4803
+ materializeReaderLibs(nativeDir);
4804
+ return binaryMajor(binary) === major ? { binary, libDir: join11(nativeDir, "lib") } : null;
4805
+ } catch {
4806
+ return null;
4807
+ }
4808
+ }
4809
+ function resolveReaderForMajor(wantMajor, log) {
4810
+ const installed = findAutopgPostgresBinary(wantMajor);
4811
+ if (installed)
4812
+ return { binary: installed };
4813
+ if (wantMajor === null)
4814
+ return null;
4815
+ return fetchEmbeddedReader(wantMajor, log);
4816
+ }
4700
4817
  async function findFreePort() {
4701
4818
  return new Promise((resolve, reject) => {
4702
4819
  const server = createServer();
@@ -4714,10 +4831,17 @@ async function findFreePort() {
4714
4831
  });
4715
4832
  });
4716
4833
  }
4717
- async function spawnTempPostmaster(binary, dataDir, port, log) {
4834
+ async function spawnTempPostmaster(reader, dataDir, port, log) {
4718
4835
  const socketDir = mkdtempSync(join11(tmpdir(), "omni-migrate-pg-"));
4719
4836
  log(` spawning temp postmaster: pid=\u2026 port=${port} socket=${socketDir}`);
4720
- const child = spawn(binary, [
4837
+ let env2 = process.env;
4838
+ if (reader.libDir) {
4839
+ const loaderVar = platform() === "darwin" ? "DYLD_LIBRARY_PATH" : platform() === "win32" ? "PATH" : "LD_LIBRARY_PATH";
4840
+ const sep = platform() === "win32" ? ";" : ":";
4841
+ const prev = process.env[loaderVar];
4842
+ env2 = { ...process.env, [loaderVar]: prev ? `${reader.libDir}${sep}${prev}` : reader.libDir };
4843
+ }
4844
+ const child = spawn(reader.binary, [
4721
4845
  "-D",
4722
4846
  dataDir,
4723
4847
  "-p",
@@ -4728,7 +4852,8 @@ async function spawnTempPostmaster(binary, dataDir, port, log) {
4728
4852
  `unix_socket_directories=${socketDir}`
4729
4853
  ], {
4730
4854
  stdio: ["ignore", "pipe", "pipe"],
4731
- detached: false
4855
+ detached: false,
4856
+ env: env2
4732
4857
  });
4733
4858
  let started = false;
4734
4859
  let crashed = null;
@@ -4771,6 +4896,19 @@ async function spawnTempPostmaster(binary, dataDir, port, log) {
4771
4896
  }
4772
4897
  };
4773
4898
  }
4899
+ function listTables(args) {
4900
+ return psqlCapture([...args, "-tAc", `SELECT tablename FROM pg_tables WHERE schemaname='public' ORDER BY tablename`]).split(`
4901
+ `).map((s) => s.trim()).filter(Boolean);
4902
+ }
4903
+ function listColumns(args, table, insertableOnly = false) {
4904
+ const filter = insertableOnly ? `AND is_generated <> 'ALWAYS'` : "";
4905
+ return psqlCapture([
4906
+ ...args,
4907
+ "-tAc",
4908
+ `SELECT column_name FROM information_schema.columns WHERE table_schema='public' AND table_name='${table}' ${filter} ORDER BY ordinal_position`
4909
+ ]).split(`
4910
+ `).map((s) => s.trim()).filter(Boolean);
4911
+ }
4774
4912
  function psqlCapture(args) {
4775
4913
  const result = spawnSync2("psql", args, {
4776
4914
  encoding: "utf-8",
@@ -4782,10 +4920,15 @@ function psqlCapture(args) {
4782
4920
  }
4783
4921
  return result.stdout ?? "";
4784
4922
  }
4785
- async function copyTable(table, srcArgs, dstArgs, log) {
4923
+ async function copyTable(table, columns, srcArgs, dstArgs, log) {
4924
+ if (columns.length === 0) {
4925
+ log(` skip ${table} (no shared columns)`);
4926
+ return;
4927
+ }
4928
+ const colList = columns.map((c2) => `"${c2}"`).join(", ");
4786
4929
  const tmpFile = join11(tmpdir(), `omni-migrate-${table}-${process.pid}.copy`);
4787
4930
  try {
4788
- const srcResult = spawnSync2("psql", [...srcArgs, "-c", `\\copy public.${table} TO '${tmpFile}' WITH (FORMAT binary)`], {
4931
+ const srcResult = spawnSync2("psql", [...srcArgs, "-c", `\\copy public."${table}" (${colList}) TO '${tmpFile}' WITH (FORMAT text)`], {
4789
4932
  stdio: ["ignore", "pipe", "pipe"],
4790
4933
  env: { ...process.env, PGPASSWORD: "postgres" },
4791
4934
  timeout: 600000,
@@ -4799,7 +4942,7 @@ async function copyTable(table, srcArgs, dstArgs, log) {
4799
4942
  "-c",
4800
4943
  `SET session_replication_role='replica';`,
4801
4944
  "-c",
4802
- `\\copy public.${table} FROM '${tmpFile}' WITH (FORMAT binary)`
4945
+ `\\copy public."${table}" (${colList}) FROM '${tmpFile}' WITH (FORMAT text)`
4803
4946
  ], {
4804
4947
  stdio: ["ignore", "pipe", "pipe"],
4805
4948
  env: { ...process.env, PGPASSWORD: "postgres" },
@@ -4841,13 +4984,18 @@ async function compareEmbeddedVsCanonicalCounts(opts = {}) {
4841
4984
  if (!existsSync9(EMBEDDED_DIR) || !existsSync9(join11(EMBEDDED_DIR, "PG_VERSION"))) {
4842
4985
  return { kind: "skipped", reason: "embedded dir absent" };
4843
4986
  }
4844
- const binary = findAutopgPostgresBinary();
4845
- if (!binary)
4846
- return { kind: "skipped", reason: "autopg postgres binary not found" };
4987
+ const wantMajor = readDataDirMajor(EMBEDDED_DIR);
4988
+ const reader = resolveReaderForMajor(wantMajor, () => {});
4989
+ if (!reader) {
4990
+ return {
4991
+ kind: "skipped",
4992
+ reason: wantMajor ? `no PostgreSQL ${wantMajor} reader available (autopg or fetchable embedded-postgres) for the PG ${wantMajor} embedded dir` : "autopg postgres binary not found"
4993
+ };
4994
+ }
4847
4995
  const tempPort = await findFreePort();
4848
4996
  let temp = null;
4849
4997
  try {
4850
- temp = await spawnTempPostmaster(binary, EMBEDDED_DIR, tempPort, () => {});
4998
+ temp = await spawnTempPostmaster(reader, EMBEDDED_DIR, tempPort, () => {});
4851
4999
  const srcArgs = ["-h", "127.0.0.1", "-p", String(tempPort), "-U", "postgres", "-d", "omni"];
4852
5000
  const dstArgs = ["-h", "127.0.0.1", "-p", String(canonicalPort), "-U", "postgres", "-d", "omni"];
4853
5001
  const tablesRaw = psqlCapture([
@@ -4863,8 +5011,8 @@ async function compareEmbeddedVsCanonicalCounts(opts = {}) {
4863
5011
  let totalExtra = 0;
4864
5012
  for (const t of tables) {
4865
5013
  try {
4866
- const em = Number.parseInt(psqlCapture([...srcArgs, "-tAc", `SELECT count(*) FROM public.${t}`]).trim(), 10);
4867
- const ca = Number.parseInt(psqlCapture([...dstArgs, "-tAc", `SELECT count(*) FROM public.${t}`]).trim(), 10);
5014
+ const em = Number.parseInt(psqlCapture([...srcArgs, "-tAc", `SELECT count(*) FROM public."${t}"`]).trim(), 10);
5015
+ const ca = Number.parseInt(psqlCapture([...dstArgs, "-tAc", `SELECT count(*) FROM public."${t}"`]).trim(), 10);
4868
5016
  if (Number.isFinite(em) && Number.isFinite(ca) && em > ca) {
4869
5017
  divergent.push(t);
4870
5018
  totalExtra += em - ca;
@@ -4892,37 +5040,43 @@ async function migrateUnmountedEmbeddedToCanonical(opts = {}) {
4892
5040
  if (!existsSync9(join11(EMBEDDED_DIR, "PG_VERSION"))) {
4893
5041
  return { status: "skipped", reason: "embedded dir missing PG_VERSION" };
4894
5042
  }
4895
- const binary = findAutopgPostgresBinary();
4896
- if (!binary) {
4897
- return { status: "skipped", reason: "autopg postgres binary not found \u2014 install autopg first" };
5043
+ const wantMajor = readDataDirMajor(EMBEDDED_DIR);
5044
+ const reader = resolveReaderForMajor(wantMajor, log);
5045
+ if (!reader) {
5046
+ return {
5047
+ status: "skipped",
5048
+ reason: wantMajor ? `could not obtain a PostgreSQL ${wantMajor} reader (no installed autopg match and embedded-postgres fetch unavailable \u2014 unsupported platform or offline)` : "autopg postgres binary not found \u2014 install autopg first"
5049
+ };
4898
5050
  }
4899
- log(` using postgres binary: ${binary}`);
5051
+ log(` using postgres binary: ${reader.binary} (matched PG ${wantMajor ?? "?"}${reader.libDir ? ", fetched reader" : ""})`);
4900
5052
  log(" stopping omni-api during data copy");
4901
5053
  spawnSync2("pm2", ["stop", "omni-api"], { stdio: "inherit" });
4902
5054
  const tempPort = await findFreePort();
4903
5055
  const t0 = Date.now();
4904
- const temp = await spawnTempPostmaster(binary, EMBEDDED_DIR, tempPort, log);
5056
+ const temp = await spawnTempPostmaster(reader, EMBEDDED_DIR, tempPort, log);
4905
5057
  let apiRestarted = false;
4906
5058
  try {
4907
5059
  const srcBaseArgs = ["-h", "127.0.0.1", "-p", String(tempPort), "-U", "postgres", "-d", "omni"];
4908
5060
  const dstBaseArgs = ["-h", "127.0.0.1", "-p", String(canonicalPort), "-U", "postgres", "-d", "omni"];
4909
- const tablesRaw = psqlCapture([
4910
- ...srcBaseArgs,
4911
- "-tAc",
4912
- `SELECT tablename FROM pg_tables WHERE schemaname='public' ORDER BY tablename`
4913
- ]);
4914
- const tables = tablesRaw.split(`
4915
- `).map((s) => s.trim()).filter(Boolean);
4916
- if (tables.length === 0) {
5061
+ const srcTables = new Set(listTables(srcBaseArgs));
5062
+ if (srcTables.size === 0) {
4917
5063
  return { status: "skipped", reason: "embedded omni has no public tables" };
4918
5064
  }
4919
- const SKIP_TABLES = new Set(["media_content"]);
4920
- const filteredTables = tables.filter((t) => !SKIP_TABLES.has(t));
4921
- const skipped = tables.filter((t) => SKIP_TABLES.has(t));
5065
+ const dstTables = listTables(dstBaseArgs);
5066
+ const tables = dstTables.filter((t) => srcTables.has(t));
5067
+ const onlyEmbedded = [...srcTables].filter((t) => !dstTables.includes(t));
5068
+ if (onlyEmbedded.length > 0) {
5069
+ log(` ${onlyEmbedded.length} obsolete embedded-only table(s) skipped: ${onlyEmbedded.join(", ")}`);
5070
+ }
5071
+ if (tables.length === 0) {
5072
+ return { status: "skipped", reason: "no tables shared between embedded and canonical schemas" };
5073
+ }
5074
+ const filteredTables = tables.filter((t) => !MIGRATION_SKIP_TABLES.has(t));
5075
+ const skipped = tables.filter((t) => MIGRATION_SKIP_TABLES.has(t));
4922
5076
  if (skipped.length > 0)
4923
5077
  log(` skipping ${skipped.length} table(s) (rebuilt at runtime): ${skipped.join(", ")}`);
4924
5078
  log(` ${filteredTables.length} tables to migrate`);
4925
- const truncateList = filteredTables.map((t) => `public.${t}`).join(",");
5079
+ const truncateList = filteredTables.map((t) => `public."${t}"`).join(",");
4926
5080
  psqlCapture([
4927
5081
  ...dstBaseArgs,
4928
5082
  "-c",
@@ -4930,7 +5084,9 @@ async function migrateUnmountedEmbeddedToCanonical(opts = {}) {
4930
5084
  ]);
4931
5085
  log(" truncated canonical (CASCADE)");
4932
5086
  for (const t of filteredTables) {
4933
- await copyTable(t, srcBaseArgs, dstBaseArgs, log);
5087
+ const srcCols = new Set(listColumns(srcBaseArgs, t));
5088
+ const sharedCols = listColumns(dstBaseArgs, t, true).filter((c2) => srcCols.has(c2));
5089
+ await copyTable(t, sharedCols, srcBaseArgs, dstBaseArgs, log);
4934
5090
  }
4935
5091
  resetSequences(dstBaseArgs, log);
4936
5092
  return { status: "migrated", tables: filteredTables.length, durationMs: Date.now() - t0 };
@@ -4941,9 +5097,10 @@ async function migrateUnmountedEmbeddedToCanonical(opts = {}) {
4941
5097
  apiRestarted = true;
4942
5098
  }
4943
5099
  }
4944
- var EMBEDDED_DIR, EMBEDDED_PGSERVE_DATA_DIR;
5100
+ var EMBEDDED_DIR, MIGRATION_SKIP_TABLES, EMBEDDED_PGSERVE_DATA_DIR;
4945
5101
  var init_embedded_canonical_migration = __esm(() => {
4946
5102
  EMBEDDED_DIR = join11(homedir7(), ".omni", "data", "pgserve");
5103
+ MIGRATION_SKIP_TABLES = new Set(["media_content", "api_keys", "api_key_audit_logs"]);
4947
5104
  EMBEDDED_PGSERVE_DATA_DIR = EMBEDDED_DIR;
4948
5105
  });
4949
5106
 
@@ -35933,10 +36090,10 @@ var init_agno_client = __esm(() => {
35933
36090
  // ../core/src/providers/claude-code-executable.ts
35934
36091
  import { existsSync as nodeExistsSync } from "fs";
35935
36092
  import { createRequire } from "module";
35936
- function archLinkerNames(arch) {
35937
- if (arch === "x64")
36093
+ function archLinkerNames(arch2) {
36094
+ if (arch2 === "x64")
35938
36095
  return { musl: "x86_64", glibc: "x86-64" };
35939
- if (arch === "arm64")
36096
+ if (arch2 === "arm64")
35940
36097
  return { musl: "aarch64", glibc: "aarch64" };
35941
36098
  return null;
35942
36099
  }
@@ -35949,41 +36106,41 @@ function glibcLinkerCandidates(glibcName, muslName, nodeArch) {
35949
36106
  return [`/lib64/${fileName}`, `/lib/${muslName}-linux-gnu/${fileName}`, `/lib/${fileName}`];
35950
36107
  }
35951
36108
  function detectLinuxLibc(options = {}) {
35952
- const platform = options.platform ?? process.platform;
35953
- if (platform !== "linux")
36109
+ const platform2 = options.platform ?? process.platform;
36110
+ if (platform2 !== "linux")
35954
36111
  return "unknown";
35955
- const arch = options.arch ?? process.arch;
35956
- const names = archLinkerNames(arch);
36112
+ const arch2 = options.arch ?? process.arch;
36113
+ const names = archLinkerNames(arch2);
35957
36114
  if (!names)
35958
36115
  return "unknown";
35959
36116
  const exists = options.existsSync ?? nodeExistsSync;
35960
36117
  if (exists(muslLinkerPath(names.musl)))
35961
36118
  return "musl";
35962
- if (glibcLinkerCandidates(names.glibc, names.musl, arch).some(exists))
36119
+ if (glibcLinkerCandidates(names.glibc, names.musl, arch2).some(exists))
35963
36120
  return "glibc";
35964
36121
  return "unknown";
35965
36122
  }
35966
36123
  function resolveClaudeCodeExecutable(options = {}) {
35967
- const platform = options.platform ?? process.platform;
35968
- if (platform !== "linux")
36124
+ const platform2 = options.platform ?? process.platform;
36125
+ if (platform2 !== "linux")
35969
36126
  return;
35970
- const libc = options.libc ?? detectLinuxLibc({ platform, arch: options.arch });
36127
+ const libc = options.libc ?? detectLinuxLibc({ platform: platform2, arch: options.arch });
35971
36128
  if (libc === "unknown")
35972
36129
  return;
35973
- const arch = options.arch ?? process.arch;
35974
- if (arch !== "x64" && arch !== "arm64")
36130
+ const arch2 = options.arch ?? process.arch;
36131
+ if (arch2 !== "x64" && arch2 !== "arm64")
35975
36132
  return;
35976
- const suffix = libc === "musl" ? `-${arch}-musl` : `-${arch}`;
36133
+ const suffix = libc === "musl" ? `-${arch2}-musl` : `-${arch2}`;
35977
36134
  const specifier = `@anthropic-ai/claude-agent-sdk-linux${suffix}/claude`;
35978
36135
  const resolve2 = options.resolve ?? createRequire(import.meta.url).resolve;
35979
36136
  try {
35980
36137
  const resolved = resolve2(specifier);
35981
- log6.debug("Resolved Claude Code executable for host libc", { libc, arch, resolved });
36138
+ log6.debug("Resolved Claude Code executable for host libc", { libc, arch: arch2, resolved });
35982
36139
  return resolved;
35983
36140
  } catch (error2) {
35984
36141
  log6.debug("Claude Code subpackage not installed; falling back to SDK default", {
35985
36142
  libc,
35986
- arch,
36143
+ arch: arch2,
35987
36144
  specifier,
35988
36145
  error: String(error2)
35989
36146
  });
@@ -35992,9 +36149,9 @@ function resolveClaudeCodeExecutable(options = {}) {
35992
36149
  }
35993
36150
  function describeClaudeCodeStartupError(error2, options = {}) {
35994
36151
  const raw2 = String(error2);
35995
- const platform = options.platform ?? process.platform;
36152
+ const platform2 = options.platform ?? process.platform;
35996
36153
  const isStartupCrash = /process exited with code 1/i.test(raw2);
35997
- if (!isStartupCrash || platform !== "linux")
36154
+ if (!isStartupCrash || platform2 !== "linux")
35998
36155
  return raw2;
35999
36156
  const configuredHint = options.explicitExecutablePath ? `Configured pathToClaudeCodeExecutable=${options.explicitExecutablePath} did not launch \u2014 verify the binary is executable on this host.` : "Set `pathToClaudeCodeExecutable` on the provider to the correct SDK binary for this host, " + "or remove the mismatched optional subpackage " + "(e.g. `bun remove @anthropic-ai/claude-agent-sdk-linux-x64-musl` on glibc).";
36000
36157
  return `${raw2} \u2014 Claude Code binary failed to start. This is typically a glibc/musl ABI mismatch: the SDK resolved an optional subpackage whose native binary cannot execute on this host's dynamic linker. ${configuredHint}`;
@@ -82813,7 +82970,7 @@ var require_path = __commonJS((exports) => {
82813
82970
  function join21(...args) {
82814
82971
  return normalizePath(args.join("/"));
82815
82972
  }
82816
- function dirname6(path) {
82973
+ function dirname7(path) {
82817
82974
  const result = splitPath(path);
82818
82975
  const root = result[0] || "";
82819
82976
  let dir = result[1];
@@ -82833,7 +82990,7 @@ var require_path = __commonJS((exports) => {
82833
82990
  return f10;
82834
82991
  }
82835
82992
  exports.basename = basename6;
82836
- exports.dirname = dirname6;
82993
+ exports.dirname = dirname7;
82837
82994
  exports.isAbsolute = isAbsolute;
82838
82995
  exports.join = join21;
82839
82996
  exports.normalizePath = normalizePath;
@@ -124460,7 +124617,7 @@ import { fileURLToPath } from "url";
124460
124617
  // package.json
124461
124618
  var package_default = {
124462
124619
  name: "@automagik/omni",
124463
- version: "2.260524.1",
124620
+ version: "2.260525.2",
124464
124621
  description: "LLM-optimized CLI for Omni",
124465
124622
  type: "module",
124466
124623
  bin: {
@@ -125965,7 +126122,7 @@ function resolveOmniScopedCredentials() {
125965
126122
  // src/runtime-env.ts
125966
126123
  var LEGACY_DEFAULT_DATABASE_URL = "postgresql://postgres:postgres@localhost:5432/omni";
125967
126124
  var LEGACY_PHASE2_DATABASE_URL = "postgresql://postgres:postgres@localhost:8432/omni";
125968
- var DEFAULT_PGSERVE_PORT = 8432;
126125
+ var DEFAULT_PGSERVE_PORT = CANONICAL_PG_PORT;
125969
126126
  function buildEmbeddedDatabaseUrl(pgservePort = DEFAULT_PGSERVE_PORT) {
125970
126127
  return `postgresql://postgres:postgres@localhost:${pgservePort}/omni`;
125971
126128
  }
@@ -128331,7 +128488,7 @@ function createDeadLettersCommand() {
128331
128488
  }
128332
128489
 
128333
128490
  // src/commands/doctor.ts
128334
- import { existsSync as existsSync10, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
128491
+ import { existsSync as existsSync10, readdirSync as readdirSync3, statSync as statSync2 } from "fs";
128335
128492
  import { homedir as homedir8 } from "os";
128336
128493
  import { join as join13, resolve } from "path";
128337
128494
  init_config();
@@ -129734,12 +129891,12 @@ init_output();
129734
129891
 
129735
129892
  // src/server-bundle.ts
129736
129893
  init_output();
129737
- import { dirname as dirname2, join as join12 } from "path";
129894
+ import { dirname as dirname3, join as join12 } from "path";
129738
129895
  import { fileURLToPath as fileURLToPath2 } from "url";
129739
129896
  function getServerBundlePath() {
129740
129897
  try {
129741
129898
  const thisFile = fileURLToPath2(import.meta.url);
129742
- const distDir = dirname2(thisFile);
129899
+ const distDir = dirname3(thisFile);
129743
129900
  return join12(distDir, "server", "index.js");
129744
129901
  } catch {
129745
129902
  return join12(process.cwd(), "dist", "server", "index.js");
@@ -129748,7 +129905,7 @@ function getServerBundlePath() {
129748
129905
  function getServerLauncherPath() {
129749
129906
  try {
129750
129907
  const thisFile = fileURLToPath2(import.meta.url);
129751
- const distDir = dirname2(thisFile);
129908
+ const distDir = dirname3(thisFile);
129752
129909
  return join12(distDir, "..", "bin", "omni-server");
129753
129910
  } catch {
129754
129911
  return join12(process.cwd(), "bin", "omni-server");
@@ -129920,7 +130077,7 @@ function scanForOrphans(dir, acc, depth, maxDepth = 4) {
129920
130077
  return;
129921
130078
  let entries;
129922
130079
  try {
129923
- entries = readdirSync2(dir);
130080
+ entries = readdirSync3(dir);
129924
130081
  } catch {
129925
130082
  return;
129926
130083
  }
@@ -130607,7 +130764,7 @@ Safety:
130607
130764
  }
130608
130765
 
130609
130766
  // src/commands/done.ts
130610
- import { existsSync as existsSync11, readFileSync as readFileSync6 } from "fs";
130767
+ import { existsSync as existsSync11, readFileSync as readFileSync7 } from "fs";
130611
130768
  import { basename, extname } from "path";
130612
130769
 
130613
130770
  // src/context.ts
@@ -130721,7 +130878,7 @@ async function handleMedia(client, ctx, mediaPath, caption) {
130721
130878
  }
130722
130879
  try {
130723
130880
  const mediaType = getMediaType(mediaPath);
130724
- const buffer = readFileSync6(mediaPath);
130881
+ const buffer = readFileSync7(mediaPath);
130725
130882
  const base64 = buffer.toString("base64");
130726
130883
  const filename = basename(mediaPath);
130727
130884
  await client.messages.sendMedia({
@@ -131241,7 +131398,7 @@ function createFilmCommand() {
131241
131398
  }
131242
131399
 
131243
131400
  // src/commands/follow-up.ts
131244
- import { readFileSync as readFileSync7 } from "fs";
131401
+ import { readFileSync as readFileSync8 } from "fs";
131245
131402
  init_output();
131246
131403
  var VALID_SCOPES = ["agents", "instances", "chats"];
131247
131404
  function assertScope(scope) {
@@ -131259,9 +131416,9 @@ async function resolveScopedId(scope, id) {
131259
131416
  function readJsonArg(raw2) {
131260
131417
  let body = raw2;
131261
131418
  if (body === "-") {
131262
- body = readFileSync7(0, "utf8");
131419
+ body = readFileSync8(0, "utf8");
131263
131420
  } else if (body.startsWith("@")) {
131264
- body = readFileSync7(body.slice(1), "utf8");
131421
+ body = readFileSync8(body.slice(1), "utf8");
131265
131422
  }
131266
131423
  try {
131267
131424
  return JSON.parse(body);
@@ -131414,7 +131571,7 @@ function createHistoryCommand() {
131414
131571
 
131415
131572
  // src/commands/imagine.ts
131416
131573
  import { writeFileSync as writeFileSync8 } from "fs";
131417
- import { basename as basename2, dirname as dirname3, extname as extname2, join as join14 } from "path";
131574
+ import { basename as basename2, dirname as dirname4, extname as extname2, join as join14 } from "path";
131418
131575
  init_output();
131419
131576
  var ALLOWED_ASPECT_RATIOS = ["1:1", "4:3", "3:4", "16:9", "9:16", "3:2", "2:3"];
131420
131577
  function extensionForMime(mimeType) {
@@ -131425,7 +131582,7 @@ function extensionForMime(mimeType) {
131425
131582
  return ".png";
131426
131583
  }
131427
131584
  function buildOutputPath(outputBase, index, total, mimeType) {
131428
- const dir = dirname3(outputBase);
131585
+ const dir = dirname4(outputBase);
131429
131586
  const ext = extname2(outputBase) || extensionForMime(mimeType);
131430
131587
  const stem = basename2(outputBase, extname2(outputBase));
131431
131588
  if (total <= 1) {
@@ -131549,7 +131706,7 @@ function createImagineCommand() {
131549
131706
  }
131550
131707
 
131551
131708
  // src/commands/install.ts
131552
- import { existsSync as existsSync12, mkdirSync as mkdirSync6 } from "fs";
131709
+ import { existsSync as existsSync12, mkdirSync as mkdirSync7 } from "fs";
131553
131710
  import { homedir as homedir9 } from "os";
131554
131711
  import { join as join15 } from "path";
131555
131712
  init_config();
@@ -131659,7 +131816,7 @@ async function startServices(cfg, forceCleanup, forceSystemd, useCanonicalPgserv
131659
131816
  Or build locally: make cli-build-full`);
131660
131817
  return false;
131661
131818
  }
131662
- mkdirSync6(getPm2LogDir(), { recursive: true });
131819
+ mkdirSync7(getPm2LogDir(), { recursive: true });
131663
131820
  await installPm2Logrotate();
131664
131821
  const runtimeEnv = buildInstallRuntimeEnv(cfg, forceCleanup, useCanonicalPgserve);
131665
131822
  await runPm2(["delete", PM2_PROCESSES.api]);
@@ -131680,7 +131837,7 @@ async function startServices(cfg, forceCleanup, forceSystemd, useCanonicalPgserv
131680
131837
  if (existsSync12(NATS_BINARY_PATH)) {
131681
131838
  const natsSpinner = ora(`Starting ${PM2_PROCESSES.nats}...`).start();
131682
131839
  const natsDataDir = join15(cfg.dataDir, "nats");
131683
- mkdirSync6(natsDataDir, { recursive: true });
131840
+ mkdirSync7(natsDataDir, { recursive: true });
131684
131841
  const natsArgs = buildPm2StartArgs({
131685
131842
  kind: "nats",
131686
131843
  script: NATS_BINARY_PATH,
@@ -133357,8 +133514,8 @@ function createLogsCommand() {
133357
133514
  }
133358
133515
 
133359
133516
  // src/commands/media.ts
133360
- import { createWriteStream as createWriteStream2, existsSync as existsSync14, mkdirSync as mkdirSync8, statSync as statSync4 } from "fs";
133361
- import { basename as basename4, dirname as dirname4, resolve as resolve2 } from "path";
133517
+ import { createWriteStream as createWriteStream2, existsSync as existsSync14, mkdirSync as mkdirSync9, statSync as statSync4 } from "fs";
133518
+ import { basename as basename4, dirname as dirname5, resolve as resolve2 } from "path";
133362
133519
  import { Readable } from "stream";
133363
133520
  import { pipeline } from "stream/promises";
133364
133521
  init_config();
@@ -133425,9 +133582,9 @@ function resolveOutputPath(outputPath, result) {
133425
133582
  return resolved;
133426
133583
  }
133427
133584
  async function downloadToFile(url, apiKey, destinationPath) {
133428
- const destDir = dirname4(destinationPath);
133585
+ const destDir = dirname5(destinationPath);
133429
133586
  if (!existsSync14(destDir))
133430
- mkdirSync8(destDir, { recursive: true });
133587
+ mkdirSync9(destDir, { recursive: true });
133431
133588
  const resp = await fetch(url, {
133432
133589
  method: "GET",
133433
133590
  headers: apiKey ? { "x-api-key": apiKey } : undefined
@@ -134378,11 +134535,11 @@ init_output();
134378
134535
 
134379
134536
  // src/commands/providers-setup.ts
134380
134537
  init_src();
134381
- import { execFileSync as execFileSync3, execSync } from "child_process";
134538
+ import { execFileSync as execFileSync4, execSync } from "child_process";
134382
134539
  import * as nodeCrypto2 from "crypto";
134383
- import { existsSync as existsSync15, mkdirSync as mkdirSync9, readFileSync as readFileSync9, writeFileSync as writeFileSync9 } from "fs";
134540
+ import { existsSync as existsSync15, mkdirSync as mkdirSync10, readFileSync as readFileSync10, writeFileSync as writeFileSync9 } from "fs";
134384
134541
  import { homedir as homedir11 } from "os";
134385
- import { dirname as dirname5, resolve as resolve3 } from "path";
134542
+ import { dirname as dirname6, resolve as resolve3 } from "path";
134386
134543
  import { createInterface as createInterface2 } from "readline";
134387
134544
  init_config();
134388
134545
  init_output();
@@ -134613,13 +134770,13 @@ var PLUGIN_MARKER = "plugin-openclaw/omni.ts";
134613
134770
  function readOpenClawConfig(configPath) {
134614
134771
  if (!existsSync15(configPath))
134615
134772
  return {};
134616
- const raw2 = readFileSync9(configPath, "utf-8").trim();
134773
+ const raw2 = readFileSync10(configPath, "utf-8").trim();
134617
134774
  if (!raw2)
134618
134775
  return {};
134619
134776
  return JSON.parse(raw2);
134620
134777
  }
134621
134778
  function writeOpenClawConfig(configPath, config2) {
134622
- mkdirSync9(dirname5(configPath), { recursive: true, mode: 448 });
134779
+ mkdirSync10(dirname6(configPath), { recursive: true, mode: 448 });
134623
134780
  writeFileSync9(configPath, `${JSON.stringify(config2, null, 2)}
134624
134781
  `, { mode: 384 });
134625
134782
  }
@@ -134660,7 +134817,7 @@ function resolvePluginPath(explicit) {
134660
134817
  function registerPlugin(config2, pluginPath, configPath) {
134661
134818
  if (hasOpenClawCli()) {
134662
134819
  try {
134663
- execFileSync3("openclaw", ["plugins", "install", "--link", pluginPath], { stdio: "ignore" });
134820
+ execFileSync4("openclaw", ["plugins", "install", "--link", pluginPath], { stdio: "ignore" });
134664
134821
  try {
134665
134822
  return { config: readOpenClawConfig(configPath), registered: true };
134666
134823
  } catch {
@@ -135705,7 +135862,7 @@ function createSayCommand() {
135705
135862
  }
135706
135863
 
135707
135864
  // src/commands/see.ts
135708
- import { existsSync as existsSync16, readFileSync as readFileSync10, statSync as statSync5 } from "fs";
135865
+ import { existsSync as existsSync16, readFileSync as readFileSync11, statSync as statSync5 } from "fs";
135709
135866
  import { extname as extname4 } from "path";
135710
135867
  init_output();
135711
135868
  var MIME_BY_EXT = {
@@ -135748,7 +135905,7 @@ function loadMedia(file) {
135748
135905
  error(`File is empty: ${file}`);
135749
135906
  }
135750
135907
  try {
135751
- return { buffer: readFileSync10(file), mimeType: guessMimeType(file) };
135908
+ return { buffer: readFileSync11(file), mimeType: guessMimeType(file) };
135752
135909
  } catch (err2) {
135753
135910
  const message2 = err2 instanceof Error ? err2.message : "Unknown error";
135754
135911
  return error(`Failed to read ${file}: ${message2}`);
@@ -135823,7 +135980,7 @@ function createSeeCommand() {
135823
135980
  }
135824
135981
 
135825
135982
  // src/commands/send.ts
135826
- import { existsSync as existsSync17, readFileSync as readFileSync11 } from "fs";
135983
+ import { existsSync as existsSync17, readFileSync as readFileSync12 } from "fs";
135827
135984
  import { basename as basename5, extname as extname5 } from "path";
135828
135985
  init_source();
135829
135986
  init_config();
@@ -135843,7 +136000,7 @@ function getMediaType2(path) {
135843
136000
  return "document";
135844
136001
  }
135845
136002
  function readFileAsBase64(path) {
135846
- const buffer3 = readFileSync11(path);
136003
+ const buffer3 = readFileSync12(path);
135847
136004
  return buffer3.toString("base64");
135848
136005
  }
135849
136006
  var messageSenders = {
@@ -136396,7 +136553,7 @@ function pickFilename(mimeType, provider) {
136396
136553
  }
136397
136554
 
136398
136555
  // src/commands/start.ts
136399
- import { existsSync as existsSync18, mkdirSync as mkdirSync10 } from "fs";
136556
+ import { existsSync as existsSync18, mkdirSync as mkdirSync11 } from "fs";
136400
136557
  import { homedir as homedir12 } from "os";
136401
136558
  import { join as join17 } from "path";
136402
136559
  init_config();
@@ -136412,7 +136569,7 @@ async function runStart() {
136412
136569
  }
136413
136570
  const serverConfig = loadServerConfig();
136414
136571
  const apiPort = serverConfig.port;
136415
- mkdirSync10(getPm2LogDir(), { recursive: true });
136572
+ mkdirSync11(getPm2LogDir(), { recursive: true });
136416
136573
  info(`Starting ${PM2_PROCESSES.api} (port ${apiPort})...`);
136417
136574
  const cliConfig = loadConfig();
136418
136575
  const env2 = buildRuntimeEnv(serverConfig, cliConfig);
@@ -136432,7 +136589,7 @@ async function runStart() {
136432
136589
  if (existsSync18(natsPath)) {
136433
136590
  info(`Starting ${PM2_PROCESSES.nats}...`);
136434
136591
  const natsDataDir = join17(serverConfig.dataDir, "nats");
136435
- mkdirSync10(natsDataDir, { recursive: true });
136592
+ mkdirSync11(natsDataDir, { recursive: true });
136436
136593
  const natsArgs = buildPm2StartArgs({
136437
136594
  kind: "nats",
136438
136595
  script: natsPath,
@@ -137135,7 +137292,7 @@ async function cleanupLegacyArtifacts(skipList) {
137135
137292
  init_output();
137136
137293
 
137137
137294
  // src/update-diagnostics.ts
137138
- import { existsSync as existsSync19, mkdirSync as mkdirSync11, readFileSync as readFileSync12, writeFileSync as writeFileSync10 } from "fs";
137295
+ import { existsSync as existsSync19, mkdirSync as mkdirSync12, readFileSync as readFileSync13, writeFileSync as writeFileSync10 } from "fs";
137139
137296
  import { homedir as homedir13 } from "os";
137140
137297
  import { join as join18 } from "path";
137141
137298
  var UPDATE_DIAGNOSTICS_SCHEMA_VERSION = 1;
@@ -137170,7 +137327,7 @@ function tailFileLines(path, maxLines) {
137170
137327
  if (!existsSync19(path))
137171
137328
  return [];
137172
137329
  try {
137173
- const raw2 = readFileSync12(path, "utf8");
137330
+ const raw2 = readFileSync13(path, "utf8");
137174
137331
  const lines = raw2.split(/\r?\n/);
137175
137332
  if (lines.length > 0 && lines[lines.length - 1] === "")
137176
137333
  lines.pop();
@@ -137204,7 +137361,7 @@ function writeDiagnostics(state, exitCode) {
137204
137361
  const path = getDiagnosticsPath(state.startedAt);
137205
137362
  try {
137206
137363
  if (!existsSync19(dir)) {
137207
- mkdirSync11(dir, { recursive: true, mode: 448 });
137364
+ mkdirSync12(dir, { recursive: true, mode: 448 });
137208
137365
  }
137209
137366
  writeFileSync10(path, `${JSON.stringify(state, null, 2)}
137210
137367
  `, { mode: 384 });
@@ -137784,9 +137941,9 @@ function createVoiceCommand() {
137784
137941
  const startTime = Date.now();
137785
137942
  let saveDir = "";
137786
137943
  if (opts.save) {
137787
- const { mkdirSync: mkdirSync12 } = await import("fs");
137944
+ const { mkdirSync: mkdirSync13 } = await import("fs");
137788
137945
  saveDir = opts.save;
137789
- mkdirSync12(saveDir, { recursive: true });
137946
+ mkdirSync13(saveDir, { recursive: true });
137790
137947
  info(`Saving audio to: ${saveDir}`);
137791
137948
  }
137792
137949
  ws.onopen = () => {
@@ -138010,7 +138167,7 @@ init_config();
138010
138167
  init_output();
138011
138168
 
138012
138169
  // src/manifest-pin.ts
138013
- import { existsSync as existsSync21, readFileSync as readFileSync13, renameSync as renameSync3, writeFileSync as writeFileSync11 } from "fs";
138170
+ import { existsSync as existsSync21, readFileSync as readFileSync14, renameSync as renameSync3, writeFileSync as writeFileSync11 } from "fs";
138014
138171
  import { homedir as homedir14 } from "os";
138015
138172
  import { join as join20 } from "path";
138016
138173
  var PACKAGE_NAME2 = "@automagik/omni";
@@ -138020,7 +138177,7 @@ function pinManifestEntry(manifestPath, exactVersion) {
138020
138177
  return false;
138021
138178
  let manifest;
138022
138179
  try {
138023
- manifest = JSON.parse(readFileSync13(manifestPath, "utf-8"));
138180
+ manifest = JSON.parse(readFileSync14(manifestPath, "utf-8"));
138024
138181
  } catch {
138025
138182
  return false;
138026
138183
  }
@@ -138095,7 +138252,7 @@ function getConfigSummary() {
138095
138252
 
138096
138253
  // src/telemetry.ts
138097
138254
  init_config();
138098
- import { arch, platform, release } from "os";
138255
+ import { arch as arch2, platform as platform2, release } from "os";
138099
138256
  var OMNI_SENTRY_DSN = "https://2b2ca6f407e3d13409aa7dd8d12483f2@o4509714066571264.ingest.us.sentry.io/4510982636371968";
138100
138257
  var SENSITIVE_FLAGS = new Set([
138101
138258
  "--api-key",
@@ -138177,8 +138334,8 @@ function ensureSentry() {
138177
138334
  }
138178
138335
  });
138179
138336
  Sentry.setTag("cli.version", VERSION);
138180
- Sentry.setTag("os.platform", platform());
138181
- Sentry.setTag("os.arch", arch());
138337
+ Sentry.setTag("os.platform", platform2());
138338
+ Sentry.setTag("os.arch", arch2());
138182
138339
  Sentry.setTag("os.release", release());
138183
138340
  Sentry.setTag("runtime", `bun/${process.versions.bun ?? "unknown"}`);
138184
138341
  sentryModule = Sentry;
@@ -24,13 +24,20 @@
24
24
  *
25
25
  * Solution
26
26
  * --------
27
- * Spawn autopg's bundled `postgres` binary against the unmounted embedded
28
- * data dir on a free TCP port, copy every public-schema table over to
29
- * canonical via psql `COPY ... TO STDOUT | COPY ... FROM STDIN` pipes
30
- * (psql 17 happily connects to a PG18 server — only pg_dump is strict),
31
- * then shut the temp postmaster down. Postgres version compatibility is
32
- * sidestepped: both embedded and canonical use the same autopg-bundled
33
- * postgres binary on this host.
27
+ * Spawn a matching-major `postgres` reader against the unmounted embedded
28
+ * data dir on a free TCP port, copy the shared public-schema tables over to
29
+ * canonical via psql `\copy`, then shut the temp postmaster down.
30
+ *
31
+ * Cross-major + cross-schema seamless: a PostgreSQL server can only open a
32
+ * data dir of its OWN major, so the reader major MUST match the embedded
33
+ * cluster (e.g. legacy PG17 data → reader PG17 even though canonical is PG18).
34
+ * {@link resolveReaderForMajor} finds an installed autopg binary of that major
35
+ * or AUTO-FETCHES one (`@embedded-postgres/<platform>@<major>`, cached under
36
+ * `~/.omni/cache/`) — the operator never deals with PG versions. The copy is
37
+ * TEXT format over the INTERSECTION of each table's columns, so it survives
38
+ * both the major-version wire gap and schema drift between an old embedded
39
+ * schema and the current canonical one. Install-local auth tables are
40
+ * preserved (see SKIP_TABLES) so the live CLI key keeps working.
34
41
  *
35
42
  * Idempotency: caller is expected to gate on `canonical omni DB is
36
43
  * empty + embedded dir has data` so re-running this isn't destructive.
@@ -61,6 +68,22 @@ export interface MigrateOptions {
61
68
  /** Logger sink — defaults to writing prefixed lines to process.stdout. */
62
69
  log?: (line: string) => void;
63
70
  }
71
+ /** Read the catalog major (e.g. 17, 18) recorded in a data dir's PG_VERSION. */
72
+ export declare function readDataDirMajor(dataDir: string): number | null;
73
+ /** Compare two `vX.Y.Z`-ish dir names numerically, newest first. */
74
+ export declare function compareVersionDesc(a: string, b: string): number;
75
+ /**
76
+ * Tables NOT copied embedded→canonical.
77
+ * - media_content: large blobs that overflow the COPY pipe; omni-api re-syncs
78
+ * media from the source channel on next message.
79
+ * - api_keys / api_key_audit_logs: INSTALL-LOCAL auth state the canonical
80
+ * install created fresh (the operator's live CLI key). Overwriting them with
81
+ * the stale embedded `__primary__` key breaks `omni` CLI auth immediately,
82
+ * and copying the audit logs would violate their FK to the preserved keys.
83
+ */
84
+ export declare const MIGRATION_SKIP_TABLES: Set<string>;
85
+ /** Map the host to its `@embedded-postgres/<platform>` package name. */
86
+ export declare function embeddedPostgresPackage(): string | null;
64
87
  /**
65
88
  * Public entry point — call this from `omni doctor --fix` when the
66
89
  * `embedded-data-orphaned` check FAILs (canonical omni DB empty AND
@@ -1 +1 @@
1
- {"version":3,"file":"embedded-canonical-migration.d.ts","sourceRoot":"","sources":["../../src/lib/embedded-canonical-migration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAWH,MAAM,MAAM,eAAe,GACvB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC1D;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1C,MAAM,WAAW,cAAc;IAC7B,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0EAA0E;IAC1E,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAmPD;;;;;;;;GAQG;AACH;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,eAAe,EAAE,MAAM,EAAE,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC9E;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC,MAAM,WAAW,cAAc;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAsB,gCAAgC,CAAC,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CAiDxG;AAED,wBAAsB,mCAAmC,CAAC,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,eAAe,CAAC,CAuF7G;AAED,yEAAyE;AACzE,eAAO,MAAM,yBAAyB,QAAe,CAAC"}
1
+ {"version":3,"file":"embedded-canonical-migration.d.ts","sourceRoot":"","sources":["../../src/lib/embedded-canonical-migration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAWH,MAAM,MAAM,eAAe,GACvB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC1D;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1C,MAAM,WAAW,cAAc;IAC7B,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0EAA0E;IAC1E,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAMD,gFAAgF;AAChF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAO/D;AAoDD,oEAAoE;AACpE,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAS/D;AAUD;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,aAA+D,CAAC;AASlG,wEAAwE;AACxE,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,IAAI,CAOvD;AA6WD;;;;;;;;GAQG;AACH;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,eAAe,EAAE,MAAM,EAAE,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC9E;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC,MAAM,WAAW,cAAc;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAsB,gCAAgC,CAAC,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CAyDxG;AAED,wBAAsB,mCAAmC,CAAC,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,eAAe,CAAC,CAwG7G;AAED,yEAAyE;AACzE,eAAO,MAAM,yBAAyB,QAAe,CAAC"}
@@ -46,20 +46,20 @@ export type RuntimeEnv = {
46
46
  LOG_LEVEL: string;
47
47
  };
48
48
  /**
49
- * Default pgserve port when none is set explicitly.
49
+ * Default pgserve port when none is set explicitly — the CANONICAL port.
50
50
  *
51
51
  * Phase 2 of the canonical-pgserve cutover (omni#595/#596/#597) used the
52
52
  * bun-bridge port `8432`. Phase 3 (`pgserve-singleton-no-proxy`) lands the
53
- * postmaster directly on **5432** (canonical postgres port) and listens
54
- * on the canonical UDS at `$XDG_RUNTIME_DIR/pgserve/.s.PGSQL.5432`.
55
- *
56
- * Kept as the module-level default for backwards compatibility with the
57
- * stored `~/.omni/config.json` entries that still record `8432`. Use
58
- * {@link resolveDatabaseUrl} as the entry point it prefers the canonical
59
- * UDS when available and falls back to the legacy port only when the
60
- * socket is missing AND the operator hasn't migrated their config.
53
+ * postmaster directly on **5432** (the canonical postgres port) and listens
54
+ * on the canonical UDS at `$XDG_RUNTIME_DIR/pgserve/.s.PGSQL.5432`. There is
55
+ * no embedded 8432 listener anymore, so the default MUST be canonical — a
56
+ * hardcoded 8432 here leaked into `resolvePgservePort` (→ the `PGSERVE_PORT`
57
+ * env that `omni doctor`'s `pgserve-reachable` check probes), making doctor
58
+ * false-FAIL "cannot connect to pgserve on :8432" on every healthy host.
59
+ * Stored `8432` entries in `~/.omni/config.json` are treated as a stale
60
+ * default and re-resolved by {@link resolveDatabaseUrl} (UDS-first).
61
61
  */
62
- export declare const DEFAULT_PGSERVE_PORT = 8432;
62
+ export declare const DEFAULT_PGSERVE_PORT = 5432;
63
63
  /** Canonical postgres TCP port the postmaster binds in singleton mode. */
64
64
  export { CANONICAL_PG_PORT } from './lib/pgserve-transport.js';
65
65
  /**
@@ -77,9 +77,13 @@ export declare function buildEmbeddedDatabaseUrl(pgservePort?: number): string;
77
77
  export declare function buildCanonicalSocketDatabaseUrl(): string;
78
78
  /**
79
79
  * Extract the effective pgserve port. Honors an explicit override on the
80
- * server config first (`server.pgservePort`, if ever added), then the
81
- * hard-coded default. This function intentionally does NOT read
82
- * `process.env.PGSERVE_PORT` env pollution is the bug we're fixing.
80
+ * server config first (`server.pgservePort`), then falls back to
81
+ * {@link DEFAULT_PGSERVE_PORT} which is now the CANONICAL port (5432), not
82
+ * the legacy 8432. This value feeds the runtime `PGSERVE_PORT` env that
83
+ * `omni doctor`'s `pgserve-reachable` check probes.
84
+ *
85
+ * This function intentionally does NOT read `process.env.PGSERVE_PORT` —
86
+ * env pollution is the bug we're fixing.
83
87
  */
84
88
  export declare function resolvePgservePort(serverConfig: ServerConfig): number;
85
89
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-env.d.ts","sourceRoot":"","sources":["../src/runtime-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AASxD;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IAQrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAQF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAEzC,0EAA0E;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAE/D;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,GAAE,MAA6B,GAAG,MAAM,CAE3F;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,IAAI,MAAM,CAKxD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,CAMrE;AAgBD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,CAiBrE;AAoBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,UAAU,CAqCzF"}
1
+ {"version":3,"file":"runtime-env.d.ts","sourceRoot":"","sources":["../src/runtime-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AASxD;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IAQrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAQF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB,OAAoB,CAAC;AAEtD,0EAA0E;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAE/D;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,GAAE,MAA6B,GAAG,MAAM,CAE3F;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,IAAI,MAAM,CAKxD;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,CAMrE;AAgBD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,CAiBrE;AAoBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,UAAU,CAqCzF"}
@@ -230186,7 +230186,7 @@ var init_sentry_scrub = __esm(() => {
230186
230186
  var require_package8 = __commonJS((exports, module) => {
230187
230187
  module.exports = {
230188
230188
  name: "@omni/api",
230189
- version: "2.260524.1",
230189
+ version: "2.260525.2",
230190
230190
  type: "module",
230191
230191
  exports: {
230192
230192
  ".": {
@@ -330333,6 +330333,7 @@ class MessageService {
330333
330333
  status,
330334
330334
  hasMedia,
330335
330335
  senderPersonId,
330336
+ externalId,
330336
330337
  since,
330337
330338
  until,
330338
330339
  search,
@@ -330357,6 +330358,8 @@ class MessageService {
330357
330358
  conditions3.push(eq(messages2.hasMedia, hasMedia));
330358
330359
  if (senderPersonId)
330359
330360
  conditions3.push(eq(messages2.senderPersonId, senderPersonId));
330361
+ if (externalId)
330362
+ conditions3.push(eq(messages2.externalId, externalId));
330360
330363
  if (since)
330361
330364
  conditions3.push(gte(messages2.platformTimestamp, since));
330362
330365
  if (until)
@@ -349864,6 +349867,7 @@ var init_messages5 = __esm(() => {
349864
349867
  status: exports_external.string().optional().transform((v2) => v2?.split(",")),
349865
349868
  hasMedia: exports_external.coerce.boolean().optional(),
349866
349869
  senderPersonId: exports_external.string().uuid().optional(),
349870
+ externalId: exports_external.string().min(1).optional(),
349867
349871
  since: optionalDateParam("since"),
349868
349872
  until: optionalDateParam("until"),
349869
349873
  search: exports_external.string().optional(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/omni",
3
- "version": "2.260524.1",
3
+ "version": "2.260525.2",
4
4
  "description": "LLM-optimized CLI for Omni",
5
5
  "type": "module",
6
6
  "bin": {