@automagik/omni 2.260430.13 → 2.260430.14
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/commands/doctor.d.ts +13 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/index.js +152 -12
- package/dist/lib/canonical-pgserve.d.ts +50 -0
- package/dist/lib/canonical-pgserve.d.ts.map +1 -0
- package/dist/runtime-env.d.ts +6 -0
- package/dist/runtime-env.d.ts.map +1 -1
- package/dist/server/index.js +3687 -1324
- package/package.json +10 -10
|
@@ -41,7 +41,7 @@ import { type Config, type ServerConfig } from '../config.js';
|
|
|
41
41
|
/** Severity levels reported by each check. */
|
|
42
42
|
export type CheckLevel = 'OK' | 'WARN' | 'FAIL';
|
|
43
43
|
/** Identifier used in tests and --json output. */
|
|
44
|
-
export type CheckId = 'pm2-env-drift' | 'cli-key-valid' | 'pgserve-reachable' | 'omni-db-exists' | 'orphaned-data-dirs' | 'version-match' | 'pm2-status' | 'pm2-max-restarts' | 'pm2-logrotate-installed' | 'cli-signing-key-for-locked-instances';
|
|
44
|
+
export type CheckId = 'pm2-env-drift' | 'cli-key-valid' | 'pgserve-reachable' | 'omni-db-exists' | 'orphaned-data-dirs' | 'version-match' | 'pm2-status' | 'pm2-max-restarts' | 'pm2-logrotate-installed' | 'cli-signing-key-for-locked-instances' | 'pgserve-canonical';
|
|
45
45
|
export interface CheckResult {
|
|
46
46
|
id: CheckId;
|
|
47
47
|
level: CheckLevel;
|
|
@@ -135,6 +135,18 @@ export interface DoctorDeps {
|
|
|
135
135
|
* that as a WARN so it's caught before the operator hits the wall.
|
|
136
136
|
*/
|
|
137
137
|
cliHasSigningKey: () => boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Run canonical pgserve setup (probe binary → `pgserve install` →
|
|
140
|
+
* `pgserve url`). Returns the canonical URL on success or null on
|
|
141
|
+
* failure. Stubbed in tests.
|
|
142
|
+
*/
|
|
143
|
+
setupCanonicalPgserve: () => Promise<string | null>;
|
|
144
|
+
/**
|
|
145
|
+
* Persist a partial server config (merges with existing). Stubbed in
|
|
146
|
+
* tests so the canonical-pgserve fix can be validated without writing
|
|
147
|
+
* to ~/.omni/config.json.
|
|
148
|
+
*/
|
|
149
|
+
saveServerConfig: (partial: Partial<ServerConfig>) => void;
|
|
138
150
|
}
|
|
139
151
|
/**
|
|
140
152
|
* Run all checks and optionally apply fixes. Returns a structured
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAMH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyBpC;;;;GAIG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAED,8FAA8F;AAC9F,wBAAgB,yBAAyB,CAAC,OAAO,EAAE;IAAE,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAIvF;AAYD,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AA0MD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAmCzF;AAiED,wBAAgB,oBAAoB,IAAI,OAAO,CAU9C"}
|
package/dist/config.d.ts
CHANGED
|
@@ -12,6 +12,17 @@ export interface ServerConfig {
|
|
|
12
12
|
dataDir: string;
|
|
13
13
|
logLevel: string;
|
|
14
14
|
nodeEnv: string;
|
|
15
|
+
/**
|
|
16
|
+
* When true, omni-api connects to an externally-managed canonical pgserve
|
|
17
|
+
* (the one registered by `pgserve install` from pgserve@^2.1.0) and SKIPS
|
|
18
|
+
* its embedded pgserve startup path. Persisted by `omni install` (default
|
|
19
|
+
* true on fresh installs; preserved on reinstalls) and by
|
|
20
|
+
* `omni doctor --fix` when migrating an embedded install onto canonical.
|
|
21
|
+
*
|
|
22
|
+
* Default behavior on legacy configs (field absent): treated as false →
|
|
23
|
+
* embedded mode continues. Operators migrate via `omni doctor --fix`.
|
|
24
|
+
*/
|
|
25
|
+
useCanonicalPgserve?: boolean;
|
|
15
26
|
}
|
|
16
27
|
/** Valid config keys (top-level and dot-notation server.* keys) */
|
|
17
28
|
export type ConfigKey = 'apiUrl' | 'apiKey' | 'defaultInstance' | 'format' | 'showCommands' | 'telemetry' | 'updateChannel' | 'server.port' | 'server.databaseUrl' | 'server.dataDir' | 'server.logLevel' | 'server.nodeEnv';
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,oCAAoC;AACpC,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC;AAEzE,gCAAgC;AAChC,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,oCAAoC;AACpC,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC;AAEzE,gCAAgC;AAChC,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;;;;OASG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,mEAAmE;AACnE,MAAM,MAAM,SAAS,GACjB,QAAQ,GACR,QAAQ,GACR,iBAAiB,GACjB,QAAQ,GACR,cAAc,GACd,WAAW,GACX,eAAe,GACf,aAAa,GACb,oBAAoB,GACpB,gBAAgB,GAChB,iBAAiB,GACjB,gBAAgB,CAAC;AAErB,4BAA4B;AAC5B,MAAM,WAAW,MAAM;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAClC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;CAChC;AAQD,qDAAqD;AACrD,eAAO,MAAM,qBAAqB,EAAE,YAMnC,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,SAAS,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CA4BrF,CAAC;AAEF,gCAAgC;AAChC,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,2BAA2B;AAC3B,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAUD,4BAA4B;AAC5B,wBAAgB,UAAU,IAAI,MAAM,CAcnC;AAED,0BAA0B;AAC1B,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAI/C;AAED,gCAAgC;AAChC,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAcjE;AA6CD,gCAAgC;AAChC,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CASlE;AAED,4BAA4B;AAC5B,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAmBtD;AAED,mCAAmC;AACnC,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,IAAI,SAAS,CAE9D;AAED,2DAA2D;AAC3D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAE/D;AAED,8EAA8E;AAC9E,wBAAgB,eAAe,IAAI,OAAO,GAAG,MAAM,CAqBlD;AAED,yDAAyD;AACzD,wBAAgB,gBAAgB,IAAI,YAAY,CAG/C;AAED,4EAA4E;AAC5E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAIrE;AAED,kCAAkC;AAClC,wBAAgB,OAAO,IAAI,OAAO,CAGjC"}
|
package/dist/index.js
CHANGED
|
@@ -114079,7 +114079,7 @@ import { fileURLToPath } from "url";
|
|
|
114079
114079
|
// package.json
|
|
114080
114080
|
var package_default = {
|
|
114081
114081
|
name: "@automagik/omni",
|
|
114082
|
-
version: "2.260430.
|
|
114082
|
+
version: "2.260430.14",
|
|
114083
114083
|
description: "LLM-optimized CLI for Omni",
|
|
114084
114084
|
type: "module",
|
|
114085
114085
|
bin: {
|
|
@@ -115297,13 +115297,14 @@ function resolveDatabaseUrl(serverConfig) {
|
|
|
115297
115297
|
}
|
|
115298
115298
|
function buildRuntimeEnv(serverConfig, cliConfig) {
|
|
115299
115299
|
const pgservePort = resolvePgservePort(serverConfig);
|
|
115300
|
+
const useCanonical = serverConfig.useCanonicalPgserve === true;
|
|
115300
115301
|
return {
|
|
115301
115302
|
API_PORT: String(serverConfig.port),
|
|
115302
115303
|
DATABASE_URL: resolveDatabaseUrl(serverConfig),
|
|
115303
115304
|
OMNI_API_KEY: cliConfig.apiKey ?? "",
|
|
115304
115305
|
MEDIA_STORAGE_PATH: join5(serverConfig.dataDir, "media"),
|
|
115305
115306
|
OMNI_PACKAGES_DIR: join5(serverConfig.dataDir, "packages"),
|
|
115306
|
-
PGSERVE_EMBEDDED: "true",
|
|
115307
|
+
PGSERVE_EMBEDDED: useCanonical ? "false" : "true",
|
|
115307
115308
|
PGSERVE_DATA: join5(serverConfig.dataDir, "pgserve"),
|
|
115308
115309
|
PGSERVE_PORT: String(pgservePort),
|
|
115309
115310
|
NATS_URL: "nats://localhost:4222",
|
|
@@ -118728,6 +118729,96 @@ WantedBy=multi-user.target
|
|
|
118728
118729
|
}
|
|
118729
118730
|
}
|
|
118730
118731
|
|
|
118732
|
+
// src/lib/canonical-pgserve.ts
|
|
118733
|
+
init_config();
|
|
118734
|
+
init_output();
|
|
118735
|
+
var PGSERVE_REQUIRED_VERSION = "^2.1.0";
|
|
118736
|
+
async function isPgserveInstalled() {
|
|
118737
|
+
try {
|
|
118738
|
+
const code = await Bun.spawn({ cmd: ["pgserve", "--version"], stdout: "pipe", stderr: "pipe" }).exited;
|
|
118739
|
+
return code === 0;
|
|
118740
|
+
} catch {
|
|
118741
|
+
return false;
|
|
118742
|
+
}
|
|
118743
|
+
}
|
|
118744
|
+
async function ensurePgserveBinary() {
|
|
118745
|
+
if (await isPgserveInstalled())
|
|
118746
|
+
return true;
|
|
118747
|
+
raw(` Installing pgserve@${PGSERVE_REQUIRED_VERSION} globally (bun add -g)...`);
|
|
118748
|
+
const installCode = await Bun.spawn({
|
|
118749
|
+
cmd: ["bun", "add", "-g", `pgserve@${PGSERVE_REQUIRED_VERSION}`],
|
|
118750
|
+
stdout: "inherit",
|
|
118751
|
+
stderr: "inherit"
|
|
118752
|
+
}).exited;
|
|
118753
|
+
if (installCode !== 0) {
|
|
118754
|
+
warn(`bun add -g pgserve@${PGSERVE_REQUIRED_VERSION} exited with code ${installCode}`);
|
|
118755
|
+
return false;
|
|
118756
|
+
}
|
|
118757
|
+
return isPgserveInstalled();
|
|
118758
|
+
}
|
|
118759
|
+
async function runPgserveInstall() {
|
|
118760
|
+
raw(" Registering canonical pgserve under pm2 (idempotent)...");
|
|
118761
|
+
const installCode = await Bun.spawn({ cmd: ["pgserve", "install"], stdout: "inherit", stderr: "inherit" }).exited;
|
|
118762
|
+
if (installCode !== 0) {
|
|
118763
|
+
warn(`pgserve install exited with code ${installCode}`);
|
|
118764
|
+
return false;
|
|
118765
|
+
}
|
|
118766
|
+
return true;
|
|
118767
|
+
}
|
|
118768
|
+
async function readPgserveUrl() {
|
|
118769
|
+
const proc = Bun.spawn({ cmd: ["pgserve", "url"], stdout: "pipe", stderr: "inherit" });
|
|
118770
|
+
const stdout = await new Response(proc.stdout).text();
|
|
118771
|
+
const code = await proc.exited;
|
|
118772
|
+
if (code !== 0) {
|
|
118773
|
+
warn(`pgserve url exited with code ${code}`);
|
|
118774
|
+
return null;
|
|
118775
|
+
}
|
|
118776
|
+
const url = stdout.trim();
|
|
118777
|
+
if (!url.startsWith("postgres://") && !url.startsWith("postgresql://")) {
|
|
118778
|
+
warn(`pgserve url returned unexpected output ("${url}")`);
|
|
118779
|
+
return null;
|
|
118780
|
+
}
|
|
118781
|
+
return url;
|
|
118782
|
+
}
|
|
118783
|
+
async function setupCanonicalPgserve() {
|
|
118784
|
+
if (!await ensurePgserveBinary()) {
|
|
118785
|
+
warn("Canonical pgserve binary unavailable \u2014 install manually: bun add -g pgserve@^2.1.0");
|
|
118786
|
+
return null;
|
|
118787
|
+
}
|
|
118788
|
+
if (!await runPgserveInstall())
|
|
118789
|
+
return null;
|
|
118790
|
+
return readPgserveUrl();
|
|
118791
|
+
}
|
|
118792
|
+
async function resolveCanonicalPgservePreference(isReinstall, cfg) {
|
|
118793
|
+
if (isReinstall) {
|
|
118794
|
+
const existing = loadServerConfig().useCanonicalPgserve === true;
|
|
118795
|
+
if (!existing)
|
|
118796
|
+
return false;
|
|
118797
|
+
raw(" Canonical pgserve mode (preserved from previous install)");
|
|
118798
|
+
const url2 = await setupCanonicalPgserve();
|
|
118799
|
+
if (!url2) {
|
|
118800
|
+
warn("Canonical pgserve refresh failed \u2014 keeping previous databaseUrl.");
|
|
118801
|
+
return true;
|
|
118802
|
+
}
|
|
118803
|
+
cfg.databaseUrl = url2;
|
|
118804
|
+
raw(` \u2713 omni-api will connect to ${url2}`);
|
|
118805
|
+
raw("");
|
|
118806
|
+
return true;
|
|
118807
|
+
}
|
|
118808
|
+
raw(" Canonical pgserve mode (default for new installs)");
|
|
118809
|
+
const url = await setupCanonicalPgserve();
|
|
118810
|
+
if (!url) {
|
|
118811
|
+
warn("Canonical pgserve setup did not complete \u2014 falling back to embedded pgserve. Run `omni doctor --fix` later to migrate.");
|
|
118812
|
+
raw("");
|
|
118813
|
+
return false;
|
|
118814
|
+
}
|
|
118815
|
+
cfg.databaseUrl = url;
|
|
118816
|
+
raw(` \u2713 omni-api will connect to ${url}`);
|
|
118817
|
+
raw(" \u2713 embedded pgserve will be skipped (PGSERVE_EMBEDDED=false)");
|
|
118818
|
+
raw("");
|
|
118819
|
+
return true;
|
|
118820
|
+
}
|
|
118821
|
+
|
|
118731
118822
|
// src/commands/doctor.ts
|
|
118732
118823
|
init_output();
|
|
118733
118824
|
|
|
@@ -118882,7 +118973,9 @@ function productionDeps() {
|
|
|
118882
118973
|
return [];
|
|
118883
118974
|
}
|
|
118884
118975
|
},
|
|
118885
|
-
cliHasSigningKey: () => loadSigningContext() !== null
|
|
118976
|
+
cliHasSigningKey: () => loadSigningContext() !== null,
|
|
118977
|
+
setupCanonicalPgserve,
|
|
118978
|
+
saveServerConfig
|
|
118886
118979
|
};
|
|
118887
118980
|
}
|
|
118888
118981
|
function scanForOrphans(dir, acc, depth, maxDepth = 4) {
|
|
@@ -119151,6 +119244,27 @@ async function fixCliKeyValid(deps) {
|
|
|
119151
119244
|
deps.saveCliConfig(updated);
|
|
119152
119245
|
return "rotated CLI key and re-validated";
|
|
119153
119246
|
}
|
|
119247
|
+
async function fixPgserveCanonical(deps) {
|
|
119248
|
+
const { serverConfig, cliConfig } = deps.loadState();
|
|
119249
|
+
const url = await deps.setupCanonicalPgserve();
|
|
119250
|
+
if (!url) {
|
|
119251
|
+
throw new Error("canonical pgserve setup failed (pgserve binary unavailable or install failed) \u2014 install manually: bun add -g pgserve@^2.1.0");
|
|
119252
|
+
}
|
|
119253
|
+
deps.saveServerConfig({ databaseUrl: url, useCanonicalPgserve: true });
|
|
119254
|
+
const env2 = buildRuntimeEnv({ ...serverConfig, databaseUrl: url, useCanonicalPgserve: true }, cliConfig);
|
|
119255
|
+
await deps.runPm2(["delete", PM2_PROCESSES.api], env2);
|
|
119256
|
+
const startArgs = buildPm2StartArgs({
|
|
119257
|
+
kind: "api",
|
|
119258
|
+
script: getServerLauncherPath(),
|
|
119259
|
+
name: PM2_PROCESSES.api,
|
|
119260
|
+
interpreter: "bash"
|
|
119261
|
+
});
|
|
119262
|
+
const startCode = await deps.runPm2(startArgs, env2);
|
|
119263
|
+
if (startCode !== 0) {
|
|
119264
|
+
throw new Error(`pm2 start ${PM2_PROCESSES.api} exited ${startCode} after canonical migration`);
|
|
119265
|
+
}
|
|
119266
|
+
return `migrated to canonical pgserve@^2.1.0; omni-api now connects to ${url}`;
|
|
119267
|
+
}
|
|
119154
119268
|
function fixOrphanedDataDirs(deps) {
|
|
119155
119269
|
const found = deps.findOrphanedDataDirs();
|
|
119156
119270
|
if (found.length === 0) {
|
|
@@ -119189,6 +119303,21 @@ async function checkSigningKeyForLockedInstances(deps) {
|
|
|
119189
119303
|
detail: `${locked.length} instance(s) require signing (${names}${more}) but this CLI has no key in ~/.omni/keys/. Bearer-only admin against these instances will fail with 401 GENIE_SIGNATURE_REQUIRED. Run \`omni trust handshake\` to enable signed requests. (The unlock-only PATCH escape from omni#568 still works without a key.)`
|
|
119190
119304
|
};
|
|
119191
119305
|
}
|
|
119306
|
+
function checkPgserveCanonical(deps) {
|
|
119307
|
+
const { serverConfig } = deps.loadState();
|
|
119308
|
+
if (serverConfig.useCanonicalPgserve === true) {
|
|
119309
|
+
return {
|
|
119310
|
+
id: "pgserve-canonical",
|
|
119311
|
+
level: "OK",
|
|
119312
|
+
detail: "using canonical pgserve@^2.1.0 (single shared backbone with genie + others)"
|
|
119313
|
+
};
|
|
119314
|
+
}
|
|
119315
|
+
return {
|
|
119316
|
+
id: "pgserve-canonical",
|
|
119317
|
+
level: "WARN",
|
|
119318
|
+
detail: "using embedded pgserve \u2014 pgserve@^2.1.0 has grown up and is now the recommended shared backbone. Run `omni doctor --fix` to migrate (idempotent; preserves all data)."
|
|
119319
|
+
};
|
|
119320
|
+
}
|
|
119192
119321
|
async function runAllChecks(deps) {
|
|
119193
119322
|
return [
|
|
119194
119323
|
await checkPm2EnvDrift(deps),
|
|
@@ -119200,7 +119329,8 @@ async function runAllChecks(deps) {
|
|
|
119200
119329
|
await checkPm2Status(deps),
|
|
119201
119330
|
await checkPm2MaxRestarts(deps),
|
|
119202
119331
|
await checkPm2LogrotateInstalled(deps),
|
|
119203
|
-
await checkSigningKeyForLockedInstances(deps)
|
|
119332
|
+
await checkSigningKeyForLockedInstances(deps),
|
|
119333
|
+
checkPgserveCanonical(deps)
|
|
119204
119334
|
];
|
|
119205
119335
|
}
|
|
119206
119336
|
async function applyFix(deps, check) {
|
|
@@ -119215,6 +119345,8 @@ async function applyFix(deps, check) {
|
|
|
119215
119345
|
return await fixPm2MaxRestarts(deps);
|
|
119216
119346
|
if (check.id === "pm2-logrotate-installed")
|
|
119217
119347
|
return await fixPm2LogrotateInstalled(deps);
|
|
119348
|
+
if (check.id === "pgserve-canonical")
|
|
119349
|
+
return await fixPgserveCanonical(deps);
|
|
119218
119350
|
return null;
|
|
119219
119351
|
} catch (err) {
|
|
119220
119352
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -119281,6 +119413,7 @@ Checks:
|
|
|
119281
119413
|
pm2-status omni-api and omni-nats both online in pm2
|
|
119282
119414
|
pm2-max-restarts omni-api max_restarts is in the hardened range
|
|
119283
119415
|
pm2-logrotate-installed pm2-logrotate module installed with expected settings
|
|
119416
|
+
pgserve-canonical using canonical pgserve@^2.1.0 (shared backbone) vs. embedded
|
|
119284
119417
|
|
|
119285
119418
|
Safety:
|
|
119286
119419
|
--fix NEVER touches ~/.omni/data/pgserve \u2014 it only operates on the pm2
|
|
@@ -120324,19 +120457,20 @@ function resolveReinstallConfig(options) {
|
|
|
120324
120457
|
apiKey
|
|
120325
120458
|
};
|
|
120326
120459
|
}
|
|
120327
|
-
function buildInstallRuntimeEnv(cfg, forceCleanup) {
|
|
120460
|
+
function buildInstallRuntimeEnv(cfg, forceCleanup, useCanonicalPgserve) {
|
|
120328
120461
|
const serverConfig = {
|
|
120329
120462
|
...DEFAULT_SERVER_CONFIG,
|
|
120330
120463
|
port: cfg.port,
|
|
120331
120464
|
databaseUrl: cfg.databaseUrl,
|
|
120332
|
-
dataDir: cfg.dataDir
|
|
120465
|
+
dataDir: cfg.dataDir,
|
|
120466
|
+
useCanonicalPgserve
|
|
120333
120467
|
};
|
|
120334
120468
|
const env2 = buildRuntimeEnv(serverConfig, { apiKey: cfg.apiKey });
|
|
120335
120469
|
if (forceCleanup)
|
|
120336
120470
|
env2.OMNI_PGSERVE_FORCE_CLEANUP = "true";
|
|
120337
120471
|
return env2;
|
|
120338
120472
|
}
|
|
120339
|
-
async function startServices(cfg, forceCleanup, forceSystemd) {
|
|
120473
|
+
async function startServices(cfg, forceCleanup, forceSystemd, useCanonicalPgserve) {
|
|
120340
120474
|
if (forceSystemd) {
|
|
120341
120475
|
writeSystemdUnit(cfg.dataDir);
|
|
120342
120476
|
return false;
|
|
@@ -120356,7 +120490,7 @@ async function startServices(cfg, forceCleanup, forceSystemd) {
|
|
|
120356
120490
|
}
|
|
120357
120491
|
mkdirSync4(getPm2LogDir(), { recursive: true });
|
|
120358
120492
|
await installPm2Logrotate();
|
|
120359
|
-
const runtimeEnv = buildInstallRuntimeEnv(cfg, forceCleanup);
|
|
120493
|
+
const runtimeEnv = buildInstallRuntimeEnv(cfg, forceCleanup, useCanonicalPgserve);
|
|
120360
120494
|
await runPm2(["delete", PM2_PROCESSES.api]);
|
|
120361
120495
|
await runPm2(["delete", PM2_PROCESSES.nats]);
|
|
120362
120496
|
const apiSpinner = ora(`Starting ${PM2_PROCESSES.api} on port ${cfg.port}...`).start();
|
|
@@ -120392,7 +120526,7 @@ async function startServices(cfg, forceCleanup, forceSystemd) {
|
|
|
120392
120526
|
}
|
|
120393
120527
|
return true;
|
|
120394
120528
|
}
|
|
120395
|
-
function writeConfigFile(cfg) {
|
|
120529
|
+
function writeConfigFile(cfg, useCanonicalPgserve) {
|
|
120396
120530
|
const existing = loadConfig();
|
|
120397
120531
|
saveConfig({
|
|
120398
120532
|
...existing,
|
|
@@ -120400,7 +120534,12 @@ function writeConfigFile(cfg) {
|
|
|
120400
120534
|
apiKey: cfg.apiKey,
|
|
120401
120535
|
format: existing.format ?? "human"
|
|
120402
120536
|
});
|
|
120403
|
-
saveServerConfig({
|
|
120537
|
+
saveServerConfig({
|
|
120538
|
+
port: cfg.port,
|
|
120539
|
+
databaseUrl: cfg.databaseUrl,
|
|
120540
|
+
dataDir: cfg.dataDir,
|
|
120541
|
+
useCanonicalPgserve
|
|
120542
|
+
});
|
|
120404
120543
|
}
|
|
120405
120544
|
async function checkHealth(port) {
|
|
120406
120545
|
const spinner = ora(`Checking health at http://localhost:${port}/api/v2/health...`).start();
|
|
@@ -120485,9 +120624,10 @@ async function runInstall(options) {
|
|
|
120485
120624
|
raw("");
|
|
120486
120625
|
}
|
|
120487
120626
|
await runSystemChecks(cfg.port);
|
|
120627
|
+
const useCanonicalPgserve = await resolveCanonicalPgservePreference(signals2.isReinstall, cfg);
|
|
120488
120628
|
await ensureNats();
|
|
120489
|
-
const servicesStarted = await startServices(cfg, forceCleanup, forceSystemd);
|
|
120490
|
-
writeConfigFile(cfg);
|
|
120629
|
+
const servicesStarted = await startServices(cfg, forceCleanup, forceSystemd, useCanonicalPgserve);
|
|
120630
|
+
writeConfigFile(cfg, useCanonicalPgserve);
|
|
120491
120631
|
success(`Config written to ${getConfigPath()}`);
|
|
120492
120632
|
if (servicesStarted)
|
|
120493
120633
|
await checkHealth(cfg.port);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical pgserve helpers — single shared pgserve@^2.1.0 backbone.
|
|
3
|
+
*
|
|
4
|
+
* Background
|
|
5
|
+
* ----------
|
|
6
|
+
* Up through omni 2.260430, omni-api spawned its own embedded pgserve
|
|
7
|
+
* via `await import('pgserve')`. That worked, but every other service
|
|
8
|
+
* (genie-serve, future agents) that wanted Postgres span its own copy,
|
|
9
|
+
* so a single host could end up with 3+ pgserve instances on different
|
|
10
|
+
* ports with scattered data dirs. Canonical pgserve fixes this:
|
|
11
|
+
*
|
|
12
|
+
* - `pgserve install` (from pgserve@^2.1.0) registers ONE pm2-supervised
|
|
13
|
+
* pgserve instance on the canonical port (8432).
|
|
14
|
+
* - `pgserve url` returns its connection string — every downstream
|
|
15
|
+
* service (omni, genie, ...) reads this and connects there.
|
|
16
|
+
* - `omni install` calls `pgserve install` first, writes the URL into
|
|
17
|
+
* `~/.omni/config.json`, and starts omni-api with `PGSERVE_EMBEDDED=false`
|
|
18
|
+
* so the API skips its own embedded boot path.
|
|
19
|
+
*
|
|
20
|
+
* Embedded mode is NOT removed. It stays as the active path on existing
|
|
21
|
+
* installs (where `serverConfig.useCanonicalPgserve` is undefined or
|
|
22
|
+
* false) until the operator opts in via `omni doctor --fix`. Fresh
|
|
23
|
+
* installs default to canonical.
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Full canonical pgserve setup: ensure binary → `pgserve install` → read
|
|
27
|
+
* the canonical url. Returns the URL on success, null on any failure.
|
|
28
|
+
*
|
|
29
|
+
* The caller (omni install) writes this URL into serverConfig.databaseUrl
|
|
30
|
+
* so omni-api connects there with `PGSERVE_EMBEDDED=false`.
|
|
31
|
+
*/
|
|
32
|
+
export declare function setupCanonicalPgserve(): Promise<string | null>;
|
|
33
|
+
/**
|
|
34
|
+
* Decide whether an install run should use canonical pgserve and, when yes,
|
|
35
|
+
* mutate `cfg.databaseUrl` to the canonical url.
|
|
36
|
+
*
|
|
37
|
+
* Semantics:
|
|
38
|
+
* - Fresh install → ALWAYS canonical (auto-installs `pgserve` globally
|
|
39
|
+
* when missing, runs `pgserve install`, reads `pgserve url`). If
|
|
40
|
+
* canonical setup completely fails, falls back to embedded with a warn
|
|
41
|
+
* — the install still completes.
|
|
42
|
+
* - Reinstall → preserves the operator's existing
|
|
43
|
+
* `serverConfig.useCanonicalPgserve`. If `true`, re-runs setup
|
|
44
|
+
* (idempotent) to refresh the canonical url. If `false`/undefined,
|
|
45
|
+
* leaves embedded mode alone — operator migrates via `omni doctor --fix`.
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveCanonicalPgservePreference(isReinstall: boolean, cfg: {
|
|
48
|
+
databaseUrl: string;
|
|
49
|
+
}): Promise<boolean>;
|
|
50
|
+
//# sourceMappingURL=canonical-pgserve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical-pgserve.d.ts","sourceRoot":"","sources":["../../src/lib/canonical-pgserve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAsFH;;;;;;GAMG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOpE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iCAAiC,CACrD,WAAW,EAAE,OAAO,EACpB,GAAG,EAAE;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAC3B,OAAO,CAAC,OAAO,CAAC,CA6BlB"}
|
package/dist/runtime-env.d.ts
CHANGED
|
@@ -72,6 +72,12 @@ export declare function resolveDatabaseUrl(serverConfig: ServerConfig): string;
|
|
|
72
72
|
* Build the complete runtime env for the omni-api process.
|
|
73
73
|
*
|
|
74
74
|
* All values come from `serverConfig` / `cliConfig`. No shell env reads.
|
|
75
|
+
*
|
|
76
|
+
* `PGSERVE_EMBEDDED` is flipped off when `serverConfig.useCanonicalPgserve`
|
|
77
|
+
* is true — the omni-api code path in `packages/api/src/pgserve.ts` reads
|
|
78
|
+
* this and skips its embedded pgserve startup, connecting instead to
|
|
79
|
+
* whatever `DATABASE_URL` points at (typically the canonical pgserve
|
|
80
|
+
* registered by `pgserve install` from pgserve@^2.1.0).
|
|
75
81
|
*/
|
|
76
82
|
export declare function buildRuntimeEnv(serverConfig: ServerConfig, cliConfig: Config): RuntimeEnv;
|
|
77
83
|
//# sourceMappingURL=runtime-env.d.ts.map
|
|
@@ -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;AAExD;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,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;AAKF,wDAAwD;AACxD,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAEzC;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,GAAE,MAA6B,GAAG,MAAM,CAE3F;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,CAMrE;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,CAMrE;AAED
|
|
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;AAExD;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,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;AAKF,wDAAwD;AACxD,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAEzC;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,GAAE,MAA6B,GAAG,MAAM,CAE3F;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,CAMrE;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,CAMrE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,UAAU,CAgBzF"}
|