@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
|
|
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
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
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
|
|
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(
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
4845
|
-
|
|
4846
|
-
|
|
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(
|
|
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
|
|
4867
|
-
const ca = Number.parseInt(psqlCapture([...dstArgs, "-tAc", `SELECT count(*) FROM public
|
|
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
|
|
4896
|
-
|
|
4897
|
-
|
|
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(
|
|
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
|
|
4910
|
-
|
|
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
|
|
4920
|
-
const
|
|
4921
|
-
const
|
|
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
|
|
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
|
-
|
|
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(
|
|
35937
|
-
if (
|
|
36093
|
+
function archLinkerNames(arch2) {
|
|
36094
|
+
if (arch2 === "x64")
|
|
35938
36095
|
return { musl: "x86_64", glibc: "x86-64" };
|
|
35939
|
-
if (
|
|
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
|
|
35953
|
-
if (
|
|
36109
|
+
const platform2 = options.platform ?? process.platform;
|
|
36110
|
+
if (platform2 !== "linux")
|
|
35954
36111
|
return "unknown";
|
|
35955
|
-
const
|
|
35956
|
-
const names = archLinkerNames(
|
|
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,
|
|
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
|
|
35968
|
-
if (
|
|
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
|
|
35974
|
-
if (
|
|
36130
|
+
const arch2 = options.arch ?? process.arch;
|
|
36131
|
+
if (arch2 !== "x64" && arch2 !== "arm64")
|
|
35975
36132
|
return;
|
|
35976
|
-
const suffix = libc === "musl" ? `-${
|
|
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
|
|
36152
|
+
const platform2 = options.platform ?? process.platform;
|
|
35996
36153
|
const isStartupCrash = /process exited with code 1/i.test(raw2);
|
|
35997
|
-
if (!isStartupCrash ||
|
|
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
|
|
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 =
|
|
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.
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
131419
|
+
body = readFileSync8(0, "utf8");
|
|
131263
131420
|
} else if (body.startsWith("@")) {
|
|
131264
|
-
body =
|
|
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
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
133361
|
-
import { basename as basename4, dirname as
|
|
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 =
|
|
133585
|
+
const destDir = dirname5(destinationPath);
|
|
133429
133586
|
if (!existsSync14(destDir))
|
|
133430
|
-
|
|
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
|
|
134538
|
+
import { execFileSync as execFileSync4, execSync } from "child_process";
|
|
134382
134539
|
import * as nodeCrypto2 from "crypto";
|
|
134383
|
-
import { existsSync as existsSync15, mkdirSync as
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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:
|
|
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
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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:
|
|
137944
|
+
const { mkdirSync: mkdirSync13 } = await import("fs");
|
|
137788
137945
|
saveDir = opts.save;
|
|
137789
|
-
|
|
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
|
|
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(
|
|
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",
|
|
138181
|
-
Sentry.setTag("os.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
|
|
28
|
-
* data dir on a free TCP port, copy
|
|
29
|
-
* canonical via psql
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
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
|
|
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"}
|
package/dist/runtime-env.d.ts
CHANGED
|
@@ -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
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
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 =
|
|
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
|
|
81
|
-
*
|
|
82
|
-
*
|
|
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,
|
|
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"}
|
package/dist/server/index.js
CHANGED
|
@@ -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.
|
|
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(),
|