@automagik/omni 2.260430.13 → 2.260430.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +171 -14
- 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.15",
|
|
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,103 @@ 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", "port"], 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
|
+
var OMNI_DATABASE_NAME = "omni";
|
|
118769
|
+
async function readPgservePort() {
|
|
118770
|
+
const proc = Bun.spawn({ cmd: ["pgserve", "port"], stdout: "pipe", stderr: "inherit" });
|
|
118771
|
+
const stdout = await new Response(proc.stdout).text();
|
|
118772
|
+
const code = await proc.exited;
|
|
118773
|
+
if (code !== 0) {
|
|
118774
|
+
warn(`pgserve port exited with code ${code}`);
|
|
118775
|
+
return null;
|
|
118776
|
+
}
|
|
118777
|
+
const port = Number.parseInt(stdout.trim(), 10);
|
|
118778
|
+
if (!Number.isFinite(port) || port <= 0 || port > 65535) {
|
|
118779
|
+
warn(`pgserve port returned unexpected output ("${stdout.trim()}")`);
|
|
118780
|
+
return null;
|
|
118781
|
+
}
|
|
118782
|
+
return port;
|
|
118783
|
+
}
|
|
118784
|
+
function buildOmniDatabaseUrl(port) {
|
|
118785
|
+
return `postgresql://postgres:postgres@localhost:${port}/${OMNI_DATABASE_NAME}`;
|
|
118786
|
+
}
|
|
118787
|
+
async function setupCanonicalPgserve() {
|
|
118788
|
+
if (!await ensurePgserveBinary()) {
|
|
118789
|
+
warn("Canonical pgserve binary unavailable \u2014 install manually: bun add -g pgserve@^2.1.0");
|
|
118790
|
+
return null;
|
|
118791
|
+
}
|
|
118792
|
+
if (!await runPgserveInstall())
|
|
118793
|
+
return null;
|
|
118794
|
+
const port = await readPgservePort();
|
|
118795
|
+
if (port === null)
|
|
118796
|
+
return null;
|
|
118797
|
+
return buildOmniDatabaseUrl(port);
|
|
118798
|
+
}
|
|
118799
|
+
async function resolveCanonicalPgservePreference(isReinstall, cfg) {
|
|
118800
|
+
if (isReinstall) {
|
|
118801
|
+
const existing = loadServerConfig().useCanonicalPgserve === true;
|
|
118802
|
+
if (!existing)
|
|
118803
|
+
return false;
|
|
118804
|
+
raw(" Canonical pgserve mode (preserved from previous install)");
|
|
118805
|
+
const url2 = await setupCanonicalPgserve();
|
|
118806
|
+
if (!url2) {
|
|
118807
|
+
warn("Canonical pgserve refresh failed \u2014 keeping previous databaseUrl.");
|
|
118808
|
+
return true;
|
|
118809
|
+
}
|
|
118810
|
+
cfg.databaseUrl = url2;
|
|
118811
|
+
raw(` \u2713 omni-api will connect to ${url2}`);
|
|
118812
|
+
raw("");
|
|
118813
|
+
return true;
|
|
118814
|
+
}
|
|
118815
|
+
raw(" Canonical pgserve mode (default for new installs)");
|
|
118816
|
+
const url = await setupCanonicalPgserve();
|
|
118817
|
+
if (!url) {
|
|
118818
|
+
warn("Canonical pgserve setup did not complete \u2014 falling back to embedded pgserve. Run `omni doctor --fix` later to migrate.");
|
|
118819
|
+
raw("");
|
|
118820
|
+
return false;
|
|
118821
|
+
}
|
|
118822
|
+
cfg.databaseUrl = url;
|
|
118823
|
+
raw(` \u2713 omni-api will connect to ${url}`);
|
|
118824
|
+
raw(" \u2713 embedded pgserve will be skipped (PGSERVE_EMBEDDED=false)");
|
|
118825
|
+
raw("");
|
|
118826
|
+
return true;
|
|
118827
|
+
}
|
|
118828
|
+
|
|
118731
118829
|
// src/commands/doctor.ts
|
|
118732
118830
|
init_output();
|
|
118733
118831
|
|
|
@@ -118882,7 +118980,9 @@ function productionDeps() {
|
|
|
118882
118980
|
return [];
|
|
118883
118981
|
}
|
|
118884
118982
|
},
|
|
118885
|
-
cliHasSigningKey: () => loadSigningContext() !== null
|
|
118983
|
+
cliHasSigningKey: () => loadSigningContext() !== null,
|
|
118984
|
+
setupCanonicalPgserve,
|
|
118985
|
+
saveServerConfig
|
|
118886
118986
|
};
|
|
118887
118987
|
}
|
|
118888
118988
|
function scanForOrphans(dir, acc, depth, maxDepth = 4) {
|
|
@@ -119151,6 +119251,29 @@ async function fixCliKeyValid(deps) {
|
|
|
119151
119251
|
deps.saveCliConfig(updated);
|
|
119152
119252
|
return "rotated CLI key and re-validated";
|
|
119153
119253
|
}
|
|
119254
|
+
async function fixPgserveCanonical(deps) {
|
|
119255
|
+
const { serverConfig, cliConfig } = deps.loadState();
|
|
119256
|
+
await deps.runPm2(["stop", PM2_PROCESSES.api]);
|
|
119257
|
+
const url = await deps.setupCanonicalPgserve();
|
|
119258
|
+
if (!url) {
|
|
119259
|
+
await deps.runPm2(["start", PM2_PROCESSES.api]);
|
|
119260
|
+
throw new Error("canonical pgserve setup failed (pgserve binary unavailable or install failed) \u2014 install manually: bun add -g pgserve@^2.1.0");
|
|
119261
|
+
}
|
|
119262
|
+
deps.saveServerConfig({ databaseUrl: url, useCanonicalPgserve: true });
|
|
119263
|
+
const env2 = buildRuntimeEnv({ ...serverConfig, databaseUrl: url, useCanonicalPgserve: true }, cliConfig);
|
|
119264
|
+
await deps.runPm2(["delete", PM2_PROCESSES.api], env2);
|
|
119265
|
+
const startArgs = buildPm2StartArgs({
|
|
119266
|
+
kind: "api",
|
|
119267
|
+
script: getServerLauncherPath(),
|
|
119268
|
+
name: PM2_PROCESSES.api,
|
|
119269
|
+
interpreter: "bash"
|
|
119270
|
+
});
|
|
119271
|
+
const startCode = await deps.runPm2(startArgs, env2);
|
|
119272
|
+
if (startCode !== 0) {
|
|
119273
|
+
throw new Error(`pm2 start ${PM2_PROCESSES.api} exited ${startCode} after canonical migration`);
|
|
119274
|
+
}
|
|
119275
|
+
return `migrated to canonical pgserve@^2.1.0; omni-api now connects to ${url}`;
|
|
119276
|
+
}
|
|
119154
119277
|
function fixOrphanedDataDirs(deps) {
|
|
119155
119278
|
const found = deps.findOrphanedDataDirs();
|
|
119156
119279
|
if (found.length === 0) {
|
|
@@ -119189,6 +119312,21 @@ async function checkSigningKeyForLockedInstances(deps) {
|
|
|
119189
119312
|
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
119313
|
};
|
|
119191
119314
|
}
|
|
119315
|
+
function checkPgserveCanonical(deps) {
|
|
119316
|
+
const { serverConfig } = deps.loadState();
|
|
119317
|
+
if (serverConfig.useCanonicalPgserve === true) {
|
|
119318
|
+
return {
|
|
119319
|
+
id: "pgserve-canonical",
|
|
119320
|
+
level: "OK",
|
|
119321
|
+
detail: "using canonical pgserve@^2.1.0 (single shared backbone with genie + others)"
|
|
119322
|
+
};
|
|
119323
|
+
}
|
|
119324
|
+
return {
|
|
119325
|
+
id: "pgserve-canonical",
|
|
119326
|
+
level: "WARN",
|
|
119327
|
+
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)."
|
|
119328
|
+
};
|
|
119329
|
+
}
|
|
119192
119330
|
async function runAllChecks(deps) {
|
|
119193
119331
|
return [
|
|
119194
119332
|
await checkPm2EnvDrift(deps),
|
|
@@ -119200,7 +119338,8 @@ async function runAllChecks(deps) {
|
|
|
119200
119338
|
await checkPm2Status(deps),
|
|
119201
119339
|
await checkPm2MaxRestarts(deps),
|
|
119202
119340
|
await checkPm2LogrotateInstalled(deps),
|
|
119203
|
-
await checkSigningKeyForLockedInstances(deps)
|
|
119341
|
+
await checkSigningKeyForLockedInstances(deps),
|
|
119342
|
+
checkPgserveCanonical(deps)
|
|
119204
119343
|
];
|
|
119205
119344
|
}
|
|
119206
119345
|
async function applyFix(deps, check) {
|
|
@@ -119215,6 +119354,8 @@ async function applyFix(deps, check) {
|
|
|
119215
119354
|
return await fixPm2MaxRestarts(deps);
|
|
119216
119355
|
if (check.id === "pm2-logrotate-installed")
|
|
119217
119356
|
return await fixPm2LogrotateInstalled(deps);
|
|
119357
|
+
if (check.id === "pgserve-canonical")
|
|
119358
|
+
return await fixPgserveCanonical(deps);
|
|
119218
119359
|
return null;
|
|
119219
119360
|
} catch (err) {
|
|
119220
119361
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -119238,13 +119379,21 @@ async function runDoctor(options, depsOverride) {
|
|
|
119238
119379
|
let checks = await runAllChecks(deps);
|
|
119239
119380
|
const fixesApplied = [];
|
|
119240
119381
|
if (options.fix) {
|
|
119382
|
+
const canonicalCheck = checks.find((c2) => c2.id === "pgserve-canonical");
|
|
119383
|
+
if (canonicalCheck && canonicalCheck.level !== "OK") {
|
|
119384
|
+
const result = await applyFix(deps, canonicalCheck);
|
|
119385
|
+
if (result !== null)
|
|
119386
|
+
fixesApplied.push(result);
|
|
119387
|
+
checks = await runAllChecks(deps);
|
|
119388
|
+
}
|
|
119241
119389
|
for (const check of checks) {
|
|
119242
119390
|
if (check.level === "OK")
|
|
119243
119391
|
continue;
|
|
119392
|
+
if (check.id === "pgserve-canonical")
|
|
119393
|
+
continue;
|
|
119244
119394
|
const result = await applyFix(deps, check);
|
|
119245
|
-
if (result !== null)
|
|
119395
|
+
if (result !== null)
|
|
119246
119396
|
fixesApplied.push(result);
|
|
119247
|
-
}
|
|
119248
119397
|
}
|
|
119249
119398
|
checks = await runAllChecks(deps);
|
|
119250
119399
|
}
|
|
@@ -119281,6 +119430,7 @@ Checks:
|
|
|
119281
119430
|
pm2-status omni-api and omni-nats both online in pm2
|
|
119282
119431
|
pm2-max-restarts omni-api max_restarts is in the hardened range
|
|
119283
119432
|
pm2-logrotate-installed pm2-logrotate module installed with expected settings
|
|
119433
|
+
pgserve-canonical using canonical pgserve@^2.1.0 (shared backbone) vs. embedded
|
|
119284
119434
|
|
|
119285
119435
|
Safety:
|
|
119286
119436
|
--fix NEVER touches ~/.omni/data/pgserve \u2014 it only operates on the pm2
|
|
@@ -120324,19 +120474,20 @@ function resolveReinstallConfig(options) {
|
|
|
120324
120474
|
apiKey
|
|
120325
120475
|
};
|
|
120326
120476
|
}
|
|
120327
|
-
function buildInstallRuntimeEnv(cfg, forceCleanup) {
|
|
120477
|
+
function buildInstallRuntimeEnv(cfg, forceCleanup, useCanonicalPgserve) {
|
|
120328
120478
|
const serverConfig = {
|
|
120329
120479
|
...DEFAULT_SERVER_CONFIG,
|
|
120330
120480
|
port: cfg.port,
|
|
120331
120481
|
databaseUrl: cfg.databaseUrl,
|
|
120332
|
-
dataDir: cfg.dataDir
|
|
120482
|
+
dataDir: cfg.dataDir,
|
|
120483
|
+
useCanonicalPgserve
|
|
120333
120484
|
};
|
|
120334
120485
|
const env2 = buildRuntimeEnv(serverConfig, { apiKey: cfg.apiKey });
|
|
120335
120486
|
if (forceCleanup)
|
|
120336
120487
|
env2.OMNI_PGSERVE_FORCE_CLEANUP = "true";
|
|
120337
120488
|
return env2;
|
|
120338
120489
|
}
|
|
120339
|
-
async function startServices(cfg, forceCleanup, forceSystemd) {
|
|
120490
|
+
async function startServices(cfg, forceCleanup, forceSystemd, useCanonicalPgserve) {
|
|
120340
120491
|
if (forceSystemd) {
|
|
120341
120492
|
writeSystemdUnit(cfg.dataDir);
|
|
120342
120493
|
return false;
|
|
@@ -120356,7 +120507,7 @@ async function startServices(cfg, forceCleanup, forceSystemd) {
|
|
|
120356
120507
|
}
|
|
120357
120508
|
mkdirSync4(getPm2LogDir(), { recursive: true });
|
|
120358
120509
|
await installPm2Logrotate();
|
|
120359
|
-
const runtimeEnv = buildInstallRuntimeEnv(cfg, forceCleanup);
|
|
120510
|
+
const runtimeEnv = buildInstallRuntimeEnv(cfg, forceCleanup, useCanonicalPgserve);
|
|
120360
120511
|
await runPm2(["delete", PM2_PROCESSES.api]);
|
|
120361
120512
|
await runPm2(["delete", PM2_PROCESSES.nats]);
|
|
120362
120513
|
const apiSpinner = ora(`Starting ${PM2_PROCESSES.api} on port ${cfg.port}...`).start();
|
|
@@ -120392,7 +120543,7 @@ async function startServices(cfg, forceCleanup, forceSystemd) {
|
|
|
120392
120543
|
}
|
|
120393
120544
|
return true;
|
|
120394
120545
|
}
|
|
120395
|
-
function writeConfigFile(cfg) {
|
|
120546
|
+
function writeConfigFile(cfg, useCanonicalPgserve) {
|
|
120396
120547
|
const existing = loadConfig();
|
|
120397
120548
|
saveConfig({
|
|
120398
120549
|
...existing,
|
|
@@ -120400,7 +120551,12 @@ function writeConfigFile(cfg) {
|
|
|
120400
120551
|
apiKey: cfg.apiKey,
|
|
120401
120552
|
format: existing.format ?? "human"
|
|
120402
120553
|
});
|
|
120403
|
-
saveServerConfig({
|
|
120554
|
+
saveServerConfig({
|
|
120555
|
+
port: cfg.port,
|
|
120556
|
+
databaseUrl: cfg.databaseUrl,
|
|
120557
|
+
dataDir: cfg.dataDir,
|
|
120558
|
+
useCanonicalPgserve
|
|
120559
|
+
});
|
|
120404
120560
|
}
|
|
120405
120561
|
async function checkHealth(port) {
|
|
120406
120562
|
const spinner = ora(`Checking health at http://localhost:${port}/api/v2/health...`).start();
|
|
@@ -120485,9 +120641,10 @@ async function runInstall(options) {
|
|
|
120485
120641
|
raw("");
|
|
120486
120642
|
}
|
|
120487
120643
|
await runSystemChecks(cfg.port);
|
|
120644
|
+
const useCanonicalPgserve = await resolveCanonicalPgservePreference(signals2.isReinstall, cfg);
|
|
120488
120645
|
await ensureNats();
|
|
120489
|
-
const servicesStarted = await startServices(cfg, forceCleanup, forceSystemd);
|
|
120490
|
-
writeConfigFile(cfg);
|
|
120646
|
+
const servicesStarted = await startServices(cfg, forceCleanup, forceSystemd, useCanonicalPgserve);
|
|
120647
|
+
writeConfigFile(cfg, useCanonicalPgserve);
|
|
120491
120648
|
success(`Config written to ${getConfigPath()}`);
|
|
120492
120649
|
if (servicesStarted)
|
|
120493
120650
|
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;AAwHH;;;;;;GAMG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CASpE;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"}
|