@koed-labs/server 0.0.0-bootstrap.0 → 0.10.3
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/LICENSE +201 -0
- package/README.md +65 -0
- package/bin/koed.js +7 -0
- package/package.json +22 -4
- package/third-party-notices.json +92 -0
- package/vendor/chunk-2BWTLF7A.js +13883 -0
- package/vendor/chunk-2DA7EFZV.js +924 -0
- package/vendor/chunk-2S3OGPUC.js +58 -0
- package/vendor/chunk-473OA62O.js +26827 -0
- package/vendor/chunk-6JRWGOQG.js +236 -0
- package/vendor/chunk-7NOQSX4T.js +14 -0
- package/vendor/chunk-7NXKPDF3.js +1586 -0
- package/vendor/chunk-A4NKL2PK.js +153 -0
- package/vendor/chunk-A6WMU2GG.js +48 -0
- package/vendor/chunk-AFLKCQHF.js +73 -0
- package/vendor/chunk-BTS4ZTF3.js +43 -0
- package/vendor/chunk-C3N4N5HR.js +108 -0
- package/vendor/chunk-DXTAWHY3.js +25 -0
- package/vendor/chunk-G4IIVVJO.js +56 -0
- package/vendor/chunk-GELDEJJ2.js +4337 -0
- package/vendor/chunk-HFM6ROJL.js +188 -0
- package/vendor/chunk-HK2H3MVE.js +328 -0
- package/vendor/chunk-HZJK5RWC.js +5088 -0
- package/vendor/chunk-J2L726BC.js +2497 -0
- package/vendor/chunk-JBGD4JLR.js +3779 -0
- package/vendor/chunk-JJNLH5GA.js +2470 -0
- package/vendor/chunk-JKOG52PE.js +128 -0
- package/vendor/chunk-K2EIFEQF.js +89 -0
- package/vendor/chunk-KUIWH33N.js +16 -0
- package/vendor/chunk-NEWIOOM6.js +34 -0
- package/vendor/chunk-NM5NXCVM.js +2404 -0
- package/vendor/chunk-PT3AUPGE.js +459 -0
- package/vendor/chunk-PY5LYLV7.js +143 -0
- package/vendor/chunk-QIIKMG3M.js +103 -0
- package/vendor/chunk-QT24SAW6.js +110 -0
- package/vendor/chunk-RVYJKKWA.js +22 -0
- package/vendor/chunk-SKVYP7NY.js +1647 -0
- package/vendor/chunk-TSRPHKAC.js +780 -0
- package/vendor/chunk-UI5RLBKQ.js +30 -0
- package/vendor/chunk-VPC5NLZG.js +259 -0
- package/vendor/chunk-W2HNI6AA.js +75 -0
- package/vendor/chunk-X6M525ZJ.js +20 -0
- package/vendor/chunk-XIZVLPHZ.js +18 -0
- package/vendor/chunk-XNFVSVBS.js +242 -0
- package/vendor/chunk-YCDEMYY6.js +2076 -0
- package/vendor/chunk-YJ6XUZT6.js +292 -0
- package/vendor/chunk-YJWREXN6.js +26020 -0
- package/vendor/chunk-YK4F4VY2.js +173 -0
- package/vendor/chunk-YOFI4PCH.js +36 -0
- package/vendor/chunk-ZUGNCQZE.js +247 -0
- package/vendor/chunk-ZXX4ZNJY.js +21 -0
- package/vendor/cli.js +7 -0
- package/vendor/component-manifest-catalog.js +8 -0
- package/vendor/control-plane.js +23 -0
- package/vendor/package.json +1 -0
- package/vendor/privacy-service-bootstrap.js +6 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { createRequire as createKoedRequire } from "node:module"; const require = createKoedRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
isProcessRunning
|
|
4
|
+
} from "./chunk-G4IIVVJO.js";
|
|
5
|
+
import {
|
|
6
|
+
require_proper_lockfile
|
|
7
|
+
} from "./chunk-7NXKPDF3.js";
|
|
8
|
+
import {
|
|
9
|
+
__toESM
|
|
10
|
+
} from "./chunk-BTS4ZTF3.js";
|
|
11
|
+
|
|
12
|
+
// packages/koed-server/dist/ports.js
|
|
13
|
+
var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
|
|
14
|
+
import { createServer } from "node:net";
|
|
15
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
16
|
+
import { homedir } from "node:os";
|
|
17
|
+
import { dirname, resolve } from "node:path";
|
|
18
|
+
import { mkdirSync } from "node:fs";
|
|
19
|
+
var DEFAULT_PORTS = {
|
|
20
|
+
api: "43300",
|
|
21
|
+
postgres: "45432",
|
|
22
|
+
embedding: "43800",
|
|
23
|
+
privacy: "48092",
|
|
24
|
+
llamaEmbedding: "18080"
|
|
25
|
+
};
|
|
26
|
+
var localPortLeaseSchemaVersion = 1;
|
|
27
|
+
var ENV_KEYS = {
|
|
28
|
+
api: ["API_HOST_PORT"],
|
|
29
|
+
postgres: ["POSTGRES_HOST_PORT"],
|
|
30
|
+
embedding: ["EMBEDDING_SERVICE_HOST_PORT"],
|
|
31
|
+
privacy: ["PRIVACY_SERVICE_PORT"],
|
|
32
|
+
llamaEmbedding: [
|
|
33
|
+
"EMBEDDING_LLAMA_EMBEDDING_SERVER_PORT",
|
|
34
|
+
"LLAMA_EMBEDDING_SERVER_PORT"
|
|
35
|
+
]
|
|
36
|
+
};
|
|
37
|
+
var trim = (value) => {
|
|
38
|
+
const trimmed = value?.trim();
|
|
39
|
+
return trimmed ? trimmed : void 0;
|
|
40
|
+
};
|
|
41
|
+
var validPort = (value) => {
|
|
42
|
+
const trimmed = trim(value);
|
|
43
|
+
if (!trimmed)
|
|
44
|
+
return void 0;
|
|
45
|
+
const parsed = Number.parseInt(trimmed, 10);
|
|
46
|
+
return Number.isInteger(parsed) && parsed > 0 && parsed < 65536 ? String(parsed) : void 0;
|
|
47
|
+
};
|
|
48
|
+
var canListen = (port) => new Promise((resolve2) => {
|
|
49
|
+
const server = createServer();
|
|
50
|
+
server.once("error", () => resolve2(false));
|
|
51
|
+
server.listen(Number(port), "127.0.0.1", () => {
|
|
52
|
+
server.close(() => resolve2(true));
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
var nextFreePort = async (preferred, unavailablePorts, canListenOnPort) => {
|
|
56
|
+
const start = Number(preferred);
|
|
57
|
+
for (let port = start; port < Math.min(start + 1e3, 65536); port += 1) {
|
|
58
|
+
const candidate = String(port);
|
|
59
|
+
if (!unavailablePorts.has(candidate) && await canListenOnPort(candidate)) {
|
|
60
|
+
return candidate;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
throw new Error(`Could not find a free local port near ${preferred}.`);
|
|
64
|
+
};
|
|
65
|
+
var defaultLocalPortLeaseRegistryPath = () => resolve(homedir(), ".koed", "run", "local-port-leases.json");
|
|
66
|
+
var resolveLocalPortLeaseRegistryPath = (environment, dependencyPath) => {
|
|
67
|
+
const configured = environment.KOED_LOCAL_PORT_LEASES_PATH?.trim();
|
|
68
|
+
return resolve(dependencyPath ?? configured ?? defaultLocalPortLeaseRegistryPath());
|
|
69
|
+
};
|
|
70
|
+
var emptyLocalPortLeaseRegistry = () => ({
|
|
71
|
+
schemaVersion: localPortLeaseSchemaVersion,
|
|
72
|
+
leases: {}
|
|
73
|
+
});
|
|
74
|
+
var isLocalPortLease = (value) => typeof value === "object" && value !== null && typeof value.koedHome === "string" && typeof value.pid === "number" && typeof value.ports === "object" && value.ports !== null;
|
|
75
|
+
var ensureLocalPortLeaseRegistry = (path) => {
|
|
76
|
+
mkdirSync(dirname(path), { recursive: true, mode: 448 });
|
|
77
|
+
if (!existsSync(path)) {
|
|
78
|
+
writeFileSync(path, `${JSON.stringify(emptyLocalPortLeaseRegistry())}
|
|
79
|
+
`, {
|
|
80
|
+
mode: 384
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
var readLocalPortLeaseRegistry = (path) => {
|
|
85
|
+
try {
|
|
86
|
+
const parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
87
|
+
if (parsed.schemaVersion !== localPortLeaseSchemaVersion || !parsed.leases || typeof parsed.leases !== "object") {
|
|
88
|
+
return emptyLocalPortLeaseRegistry();
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
schemaVersion: localPortLeaseSchemaVersion,
|
|
92
|
+
leases: Object.fromEntries(Object.entries(parsed.leases).filter(([, lease]) => isLocalPortLease(lease)))
|
|
93
|
+
};
|
|
94
|
+
} catch {
|
|
95
|
+
return emptyLocalPortLeaseRegistry();
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
var writeLocalPortLeaseRegistry = (path, registry) => {
|
|
99
|
+
writeFileSync(path, `${JSON.stringify(registry, null, 2)}
|
|
100
|
+
`, {
|
|
101
|
+
mode: 384
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
var readPersistedLocalPorts = (paths) => {
|
|
105
|
+
if (!existsSync(paths.localPortsPath))
|
|
106
|
+
return {};
|
|
107
|
+
try {
|
|
108
|
+
const parsed = JSON.parse(readFileSync(paths.localPortsPath, "utf8"));
|
|
109
|
+
return {
|
|
110
|
+
...validPort(parsed.api) ? { api: validPort(parsed.api) } : {},
|
|
111
|
+
...validPort(parsed.postgres) ? { postgres: validPort(parsed.postgres) } : {},
|
|
112
|
+
...validPort(parsed.embedding) ? { embedding: validPort(parsed.embedding) } : {},
|
|
113
|
+
...validPort(parsed.privacy) ? { privacy: validPort(parsed.privacy) } : {},
|
|
114
|
+
...validPort(parsed.llamaEmbedding) ? { llamaEmbedding: validPort(parsed.llamaEmbedding) } : {}
|
|
115
|
+
};
|
|
116
|
+
} catch {
|
|
117
|
+
return {};
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
var writePersistedLocalPorts = (paths, ports) => {
|
|
121
|
+
mkdirSync(dirname(paths.localPortsPath), { recursive: true, mode: 448 });
|
|
122
|
+
writeFileSync(paths.localPortsPath, `${JSON.stringify(ports, null, 2)}
|
|
123
|
+
`, {
|
|
124
|
+
mode: 384
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
var applyPersistedLocalPorts = (paths, environment, options = {}) => {
|
|
128
|
+
if (!options.force && environment.KOED_AUTO_PORTS !== "1")
|
|
129
|
+
return environment;
|
|
130
|
+
const persisted = readPersistedLocalPorts(paths);
|
|
131
|
+
return {
|
|
132
|
+
...environment,
|
|
133
|
+
...persisted.api && !trim(environment.API_HOST_PORT) ? { API_HOST_PORT: persisted.api } : {},
|
|
134
|
+
...persisted.postgres && !trim(environment.POSTGRES_HOST_PORT) ? { POSTGRES_HOST_PORT: persisted.postgres } : {},
|
|
135
|
+
...persisted.embedding && !trim(environment.EMBEDDING_SERVICE_HOST_PORT) ? { EMBEDDING_SERVICE_HOST_PORT: persisted.embedding } : {},
|
|
136
|
+
...persisted.privacy && !trim(environment.PRIVACY_SERVICE_PORT) ? { PRIVACY_SERVICE_PORT: persisted.privacy } : {},
|
|
137
|
+
...persisted.llamaEmbedding && !ENV_KEYS.llamaEmbedding.some((key) => trim(environment[key])) ? { EMBEDDING_LLAMA_EMBEDDING_SERVER_PORT: persisted.llamaEmbedding } : {}
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
var allocateAndPersistLocalPorts = async (paths, environment, dependencies = {}) => {
|
|
141
|
+
if (environment.KOED_AUTO_PORTS !== "1")
|
|
142
|
+
return environment;
|
|
143
|
+
const registryPath = resolveLocalPortLeaseRegistryPath(environment, dependencies.leaseRegistryPath);
|
|
144
|
+
ensureLocalPortLeaseRegistry(registryPath);
|
|
145
|
+
const release = await import_proper_lockfile.default.lock(registryPath, {
|
|
146
|
+
realpath: false,
|
|
147
|
+
retries: { retries: 20, factor: 1.2, minTimeout: 25, maxTimeout: 250 }
|
|
148
|
+
});
|
|
149
|
+
try {
|
|
150
|
+
const processIsRunning = dependencies.isProcessRunning ?? isProcessRunning;
|
|
151
|
+
const canListenOnPort = dependencies.canListen ?? canListen;
|
|
152
|
+
const registry = readLocalPortLeaseRegistry(registryPath);
|
|
153
|
+
const activeLeases = Object.values(registry.leases).filter((lease) => lease.koedHome !== paths.koedHome && processIsRunning(lease.pid));
|
|
154
|
+
registry.leases = Object.fromEntries(Object.entries(registry.leases).filter(([, lease]) => lease.koedHome === paths.koedHome || processIsRunning(lease.pid)));
|
|
155
|
+
const unavailablePorts = new Set(activeLeases.flatMap((lease) => Object.keys(DEFAULT_PORTS).map((key) => lease.ports[key])));
|
|
156
|
+
const persisted = readPersistedLocalPorts(paths);
|
|
157
|
+
const allocated = { ...DEFAULT_PORTS, ...persisted };
|
|
158
|
+
for (const key of Object.keys(ENV_KEYS)) {
|
|
159
|
+
const fromEnv = ENV_KEYS[key].map((envKey) => validPort(environment[envKey])).find((port) => port !== void 0);
|
|
160
|
+
const preferred = fromEnv ?? validPort(allocated[key]) ?? DEFAULT_PORTS[key];
|
|
161
|
+
allocated[key] = !unavailablePorts.has(preferred) && await canListenOnPort(preferred) ? preferred : await nextFreePort(preferred, unavailablePorts, canListenOnPort);
|
|
162
|
+
unavailablePorts.add(allocated[key]);
|
|
163
|
+
}
|
|
164
|
+
writePersistedLocalPorts(paths, allocated);
|
|
165
|
+
registry.leases[paths.koedHome] = {
|
|
166
|
+
koedHome: paths.koedHome,
|
|
167
|
+
pid: dependencies.processId ?? process.pid,
|
|
168
|
+
ports: allocated,
|
|
169
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
170
|
+
};
|
|
171
|
+
writeLocalPortLeaseRegistry(registryPath, registry);
|
|
172
|
+
return {
|
|
173
|
+
...environment,
|
|
174
|
+
API_HOST_PORT: allocated.api,
|
|
175
|
+
POSTGRES_HOST_PORT: allocated.postgres,
|
|
176
|
+
EMBEDDING_SERVICE_HOST_PORT: allocated.embedding,
|
|
177
|
+
PRIVACY_SERVICE_PORT: allocated.privacy,
|
|
178
|
+
EMBEDDING_LLAMA_EMBEDDING_SERVER_PORT: allocated.llamaEmbedding
|
|
179
|
+
};
|
|
180
|
+
} finally {
|
|
181
|
+
await release();
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
export {
|
|
186
|
+
applyPersistedLocalPorts,
|
|
187
|
+
allocateAndPersistLocalPorts
|
|
188
|
+
};
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import { createRequire as createKoedRequire } from "node:module"; const require = createKoedRequire(import.meta.url);
|
|
2
|
+
import "./chunk-BTS4ZTF3.js";
|
|
3
|
+
|
|
4
|
+
// packages/koed-server/dist/runtime-homebrew.js
|
|
5
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { dirname, isAbsolute, resolve } from "node:path";
|
|
7
|
+
import { spawnSync as nodeSpawnSync } from "node:child_process";
|
|
8
|
+
var REQUIRED_PACKAGES = [
|
|
9
|
+
"postgresql@17",
|
|
10
|
+
"pgvector",
|
|
11
|
+
"llama.cpp"
|
|
12
|
+
];
|
|
13
|
+
var trim = (value) => {
|
|
14
|
+
const trimmed = value?.trim();
|
|
15
|
+
return trimmed ? trimmed : void 0;
|
|
16
|
+
};
|
|
17
|
+
var homebrewCommandCandidates = (platform, environment, exists) => {
|
|
18
|
+
const configuredPrefix = trim(environment.HOMEBREW_PREFIX);
|
|
19
|
+
const configuredCommand = configuredPrefix && isAbsolute(configuredPrefix) ? resolve(configuredPrefix, "bin", "brew") : void 0;
|
|
20
|
+
const platformCommands = platform === "darwin" ? ["/opt/homebrew/bin/brew", "/usr/local/bin/brew"] : platform === "linux" ? ["/home/linuxbrew/.linuxbrew/bin/brew"] : [];
|
|
21
|
+
return [
|
|
22
|
+
.../* @__PURE__ */ new Set([
|
|
23
|
+
...[configuredCommand, ...platformCommands].filter((command) => Boolean(command && exists(command))),
|
|
24
|
+
"brew"
|
|
25
|
+
])
|
|
26
|
+
];
|
|
27
|
+
};
|
|
28
|
+
var run = (command, args, spawnSync) => spawnSync(command, args, {
|
|
29
|
+
encoding: "utf8",
|
|
30
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
31
|
+
});
|
|
32
|
+
var brewPrefix = (formula, command, spawnSync) => {
|
|
33
|
+
const args = formula ? ["--prefix", formula] : ["--prefix"];
|
|
34
|
+
const result = run(command, args, spawnSync);
|
|
35
|
+
if (result.error) {
|
|
36
|
+
return { ok: false, error: result.error.message };
|
|
37
|
+
}
|
|
38
|
+
if (result.status !== 0) {
|
|
39
|
+
return {
|
|
40
|
+
ok: false,
|
|
41
|
+
error: result.stderr.trim() || `brew ${args.join(" ")} failed`
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return { ok: true, prefix: result.stdout.trim() };
|
|
45
|
+
};
|
|
46
|
+
var resolveHomebrewCommand = (platform, environment, exists, spawnSync) => {
|
|
47
|
+
let error = "Homebrew is not available";
|
|
48
|
+
for (const command of homebrewCommandCandidates(platform, environment, exists)) {
|
|
49
|
+
const result = brewPrefix(null, command, spawnSync);
|
|
50
|
+
if (result.ok && result.prefix) {
|
|
51
|
+
return { ok: true, command, prefix: result.prefix };
|
|
52
|
+
}
|
|
53
|
+
error = result.error ?? error;
|
|
54
|
+
}
|
|
55
|
+
return { ok: false, error };
|
|
56
|
+
};
|
|
57
|
+
var packageStatus = (name, command, spawnSync) => {
|
|
58
|
+
const listed = run(command, ["list", "--versions", name], spawnSync);
|
|
59
|
+
if (listed.error || listed.status !== 0 || !listed.stdout.trim()) {
|
|
60
|
+
return {
|
|
61
|
+
name,
|
|
62
|
+
installed: false,
|
|
63
|
+
missing: [
|
|
64
|
+
listed.stderr.trim() || listed.error?.message || "not installed"
|
|
65
|
+
]
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const result = brewPrefix(name, command, spawnSync);
|
|
69
|
+
return result.ok && result.prefix ? { name, installed: true, prefix: result.prefix } : { name, installed: false, missing: [result.error ?? "not installed"] };
|
|
70
|
+
};
|
|
71
|
+
var binary = (paths, key, path, exists) => {
|
|
72
|
+
paths[key] = path;
|
|
73
|
+
return { path, exists: exists(path) };
|
|
74
|
+
};
|
|
75
|
+
var candidatePgvectorControlPaths = (postgresPrefix, pgvectorPrefix, pgSharedir2) => [
|
|
76
|
+
pgSharedir2 ? resolve(pgSharedir2, "extension", "vector.control") : void 0,
|
|
77
|
+
postgresPrefix ? resolve(postgresPrefix, "share", "postgresql@17", "extension", "vector.control") : void 0,
|
|
78
|
+
postgresPrefix ? resolve(postgresPrefix, "share", "postgresql", "extension", "vector.control") : void 0,
|
|
79
|
+
pgvectorPrefix ? resolve(pgvectorPrefix, "share", "postgresql@17", "extension", "vector.control") : void 0,
|
|
80
|
+
pgvectorPrefix ? resolve(pgvectorPrefix, "share", "postgresql", "extension", "vector.control") : void 0
|
|
81
|
+
].filter((value) => Boolean(value));
|
|
82
|
+
var candidatePgvectorSqlPaths = (controlPath) => controlPath ? [resolve(dirname(controlPath), "vector--*.sql")] : [];
|
|
83
|
+
var pgSharedir = (pgConfigBin, exists, spawnSync) => {
|
|
84
|
+
if (!exists(pgConfigBin))
|
|
85
|
+
return void 0;
|
|
86
|
+
const result = run(pgConfigBin, ["--sharedir"], spawnSync);
|
|
87
|
+
if (result.status !== 0 || result.error)
|
|
88
|
+
return void 0;
|
|
89
|
+
return trim(result.stdout);
|
|
90
|
+
};
|
|
91
|
+
var runtimePaths = (paths) => ({
|
|
92
|
+
postgresBinDir: resolve(paths.koedHome, "runtime", "postgres", "bin"),
|
|
93
|
+
llamaServerBin: resolve(paths.koedHome, "runtime", "llama.cpp", "llama-server"),
|
|
94
|
+
metadataPath: resolve(paths.cacheDir, "runtime-homebrew.json")
|
|
95
|
+
});
|
|
96
|
+
var emptyBinaries = () => ({
|
|
97
|
+
initdb: { path: "", exists: false },
|
|
98
|
+
pg_ctl: { path: "", exists: false },
|
|
99
|
+
psql: { path: "", exists: false },
|
|
100
|
+
pg_dump: { path: "", exists: false },
|
|
101
|
+
pg_restore: { path: "", exists: false },
|
|
102
|
+
pg_config: { path: "", exists: false },
|
|
103
|
+
llama_server: { path: "", exists: false }
|
|
104
|
+
});
|
|
105
|
+
var binaryEntries = (binaries) => Object.entries(binaries);
|
|
106
|
+
var isSupportedHomebrewPlatform = (platform) => platform === "darwin" || platform === "linux";
|
|
107
|
+
var statusFrom = ({ paths, platform, environment, exists, spawnSync }) => {
|
|
108
|
+
const koedRuntime = runtimePaths(paths);
|
|
109
|
+
if (!isSupportedHomebrewPlatform(platform)) {
|
|
110
|
+
return {
|
|
111
|
+
ok: false,
|
|
112
|
+
state: "not_supported",
|
|
113
|
+
provider: "homebrew",
|
|
114
|
+
platform,
|
|
115
|
+
koedHome: paths.koedHome,
|
|
116
|
+
homebrew: { installed: false },
|
|
117
|
+
packages: [],
|
|
118
|
+
binaries: emptyBinaries(),
|
|
119
|
+
pgvector: { compatible: false, sqlPaths: [], missing: ["macOS/Linux"] },
|
|
120
|
+
koedRuntime: { ...koedRuntime, linked: false },
|
|
121
|
+
message: "Homebrew-backed bundled-local runtime provisioning is supported on macOS, Linux, and WSL only.",
|
|
122
|
+
action: "Use external dependency mode or a supported Homebrew/Linuxbrew environment on macOS, Linux, or WSL."
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
const homebrew = resolveHomebrewCommand(platform, environment, exists, spawnSync);
|
|
126
|
+
if (!homebrew.ok) {
|
|
127
|
+
return {
|
|
128
|
+
ok: false,
|
|
129
|
+
state: "missing",
|
|
130
|
+
provider: "homebrew",
|
|
131
|
+
platform,
|
|
132
|
+
koedHome: paths.koedHome,
|
|
133
|
+
homebrew: { installed: false, error: homebrew.error },
|
|
134
|
+
packages: REQUIRED_PACKAGES.map((name) => ({
|
|
135
|
+
name,
|
|
136
|
+
installed: false,
|
|
137
|
+
missing: ["Homebrew is not available"]
|
|
138
|
+
})),
|
|
139
|
+
binaries: emptyBinaries(),
|
|
140
|
+
pgvector: { compatible: false, sqlPaths: [], missing: ["Homebrew"] },
|
|
141
|
+
koedRuntime: { ...koedRuntime, linked: false },
|
|
142
|
+
message: "Homebrew is required for Homebrew-backed bundled-local runtime provisioning.",
|
|
143
|
+
action: "Install Homebrew or Linuxbrew on macOS, Linux, or WSL, then run koed runtime install --provider homebrew --dependency-mode bundled-local --json."
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
const command = homebrew.command;
|
|
147
|
+
const packages = REQUIRED_PACKAGES.map((name) => packageStatus(name, command, spawnSync));
|
|
148
|
+
const postgres = packages.find((pkg) => pkg.name === "postgresql@17");
|
|
149
|
+
const pgvectorPackage = packages.find((pkg) => pkg.name === "pgvector");
|
|
150
|
+
const llama = packages.find((pkg) => pkg.name === "llama.cpp");
|
|
151
|
+
const binaryPaths = {};
|
|
152
|
+
const postgresBin = (name) => postgres?.prefix ? resolve(postgres.prefix, "bin", name) : "";
|
|
153
|
+
const llamaBin = (name) => llama?.prefix ? resolve(llama.prefix, "bin", name) : "";
|
|
154
|
+
const binaries = {
|
|
155
|
+
initdb: binary(binaryPaths, "initdb", postgresBin("initdb"), exists),
|
|
156
|
+
pg_ctl: binary(binaryPaths, "pg_ctl", postgresBin("pg_ctl"), exists),
|
|
157
|
+
psql: binary(binaryPaths, "psql", postgresBin("psql"), exists),
|
|
158
|
+
pg_dump: binary(binaryPaths, "pg_dump", postgresBin("pg_dump"), exists),
|
|
159
|
+
pg_restore: binary(binaryPaths, "pg_restore", postgresBin("pg_restore"), exists),
|
|
160
|
+
pg_config: binary(binaryPaths, "pg_config", postgresBin("pg_config"), exists),
|
|
161
|
+
llama_server: binary(binaryPaths, "llama_server", llamaBin("llama-server"), exists)
|
|
162
|
+
};
|
|
163
|
+
const sharedir = pgSharedir(binaries.pg_config.path, exists, spawnSync);
|
|
164
|
+
const controlPath = candidatePgvectorControlPaths(postgres?.prefix, pgvectorPackage?.prefix, sharedir).find((candidate) => exists(candidate));
|
|
165
|
+
const missing = [
|
|
166
|
+
...packages.flatMap((pkg) => pkg.installed ? [] : [pkg.name]),
|
|
167
|
+
...binaryEntries(binaries).flatMap(([name, info]) => info.exists ? [] : [name]),
|
|
168
|
+
...controlPath ? [] : ["pgvector extension files"]
|
|
169
|
+
];
|
|
170
|
+
const linked = exists(resolve(koedRuntime.postgresBinDir, "initdb")) && exists(resolve(koedRuntime.postgresBinDir, "pg_ctl")) && exists(resolve(koedRuntime.postgresBinDir, "psql")) && exists(resolve(koedRuntime.postgresBinDir, "pg_dump")) && exists(resolve(koedRuntime.postgresBinDir, "pg_restore")) && exists(koedRuntime.llamaServerBin);
|
|
171
|
+
const ok = missing.length === 0 && linked;
|
|
172
|
+
return {
|
|
173
|
+
ok,
|
|
174
|
+
state: ok ? "installed" : missing.length === 0 ? "missing" : "missing",
|
|
175
|
+
provider: "homebrew",
|
|
176
|
+
platform,
|
|
177
|
+
koedHome: paths.koedHome,
|
|
178
|
+
homebrew: { installed: true, prefix: homebrew.prefix },
|
|
179
|
+
packages,
|
|
180
|
+
binaries,
|
|
181
|
+
pgvector: {
|
|
182
|
+
compatible: Boolean(controlPath),
|
|
183
|
+
controlPath,
|
|
184
|
+
sqlPaths: candidatePgvectorSqlPaths(controlPath),
|
|
185
|
+
...controlPath ? {} : { missing: ["vector.control"] }
|
|
186
|
+
},
|
|
187
|
+
koedRuntime: { ...koedRuntime, linked },
|
|
188
|
+
message: ok ? "Homebrew-backed bundled-local runtime is installed under KOED_HOME." : "Homebrew-backed bundled-local runtime is missing required assets or KOED_HOME links.",
|
|
189
|
+
action: ok ? void 0 : "Run koed runtime install --provider homebrew --dependency-mode bundled-local --json."
|
|
190
|
+
};
|
|
191
|
+
};
|
|
192
|
+
var collectHomebrewRuntimeStatus = (paths, environment = process.env, dependencies = {}) => {
|
|
193
|
+
return statusFrom({
|
|
194
|
+
paths,
|
|
195
|
+
platform: dependencies.platform ?? process.platform,
|
|
196
|
+
environment,
|
|
197
|
+
exists: dependencies.existsSync ?? existsSync,
|
|
198
|
+
spawnSync: dependencies.spawnSync ?? nodeSpawnSync
|
|
199
|
+
});
|
|
200
|
+
};
|
|
201
|
+
var linkRuntimePath = (source, target, koedHome, deps) => {
|
|
202
|
+
const resolvedTarget = resolve(target);
|
|
203
|
+
const resolvedKoedHome = resolve(koedHome);
|
|
204
|
+
if (resolvedTarget !== resolvedKoedHome && !resolvedTarget.startsWith(`${resolvedKoedHome}/`)) {
|
|
205
|
+
throw new Error(`Refusing to link runtime asset outside KOED_HOME: ${target}`);
|
|
206
|
+
}
|
|
207
|
+
deps.mkdirSync(dirname(resolvedTarget), { recursive: true, mode: 448 });
|
|
208
|
+
deps.rmSync(resolvedTarget, { force: true });
|
|
209
|
+
deps.symlinkSync(source, resolvedTarget);
|
|
210
|
+
};
|
|
211
|
+
var installHomebrewRuntime = (paths, environment = process.env, dependencies = {}) => {
|
|
212
|
+
const deps = {
|
|
213
|
+
platform: dependencies.platform ?? process.platform,
|
|
214
|
+
existsSync: dependencies.existsSync ?? existsSync,
|
|
215
|
+
mkdirSync: dependencies.mkdirSync ?? mkdirSync,
|
|
216
|
+
rmSync: dependencies.rmSync ?? rmSync,
|
|
217
|
+
symlinkSync: dependencies.symlinkSync ?? symlinkSync,
|
|
218
|
+
writeFileSync: dependencies.writeFileSync ?? writeFileSync,
|
|
219
|
+
readFileSync: dependencies.readFileSync ?? readFileSync,
|
|
220
|
+
spawnSync: dependencies.spawnSync ?? nodeSpawnSync
|
|
221
|
+
};
|
|
222
|
+
const before = collectHomebrewRuntimeStatus(paths, environment, deps);
|
|
223
|
+
if (before.state === "not_supported") {
|
|
224
|
+
return { ...before, installedPackages: [], linkedPaths: [] };
|
|
225
|
+
}
|
|
226
|
+
if (!before.homebrew.installed) {
|
|
227
|
+
return {
|
|
228
|
+
...before,
|
|
229
|
+
state: "needs_attention",
|
|
230
|
+
message: "Homebrew is required before installing bundled-local runtime assets.",
|
|
231
|
+
action: "Install Homebrew or Linuxbrew on macOS, Linux, or WSL, then rerun koed runtime install --provider homebrew --dependency-mode bundled-local --json.",
|
|
232
|
+
installedPackages: [],
|
|
233
|
+
linkedPaths: []
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
const missingPackages = before.packages.filter((pkg) => !pkg.installed).map((pkg) => pkg.name);
|
|
237
|
+
if (missingPackages.length > 0) {
|
|
238
|
+
const homebrew = resolveHomebrewCommand(deps.platform, environment, deps.existsSync, deps.spawnSync);
|
|
239
|
+
if (!homebrew.ok) {
|
|
240
|
+
return {
|
|
241
|
+
...before,
|
|
242
|
+
state: "needs_attention",
|
|
243
|
+
message: "Homebrew became unavailable before package installation.",
|
|
244
|
+
action: homebrew.error,
|
|
245
|
+
installedPackages: [],
|
|
246
|
+
linkedPaths: []
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
const result = run(homebrew.command, ["install", ...missingPackages], deps.spawnSync);
|
|
250
|
+
if (result.error || result.status !== 0) {
|
|
251
|
+
return {
|
|
252
|
+
...before,
|
|
253
|
+
state: "needs_attention",
|
|
254
|
+
message: "Homebrew package installation failed.",
|
|
255
|
+
action: result.stderr.trim() || result.error?.message || "Inspect Homebrew output and retry.",
|
|
256
|
+
installedPackages: [],
|
|
257
|
+
linkedPaths: []
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
const afterInstall = collectHomebrewRuntimeStatus(paths, environment, deps);
|
|
262
|
+
const missingAfterInstall = [
|
|
263
|
+
...afterInstall.packages.flatMap((pkg) => pkg.installed ? [] : [pkg.name]),
|
|
264
|
+
...binaryEntries(afterInstall.binaries).flatMap(([name, info]) => info.exists ? [] : [name]),
|
|
265
|
+
...afterInstall.pgvector.compatible ? [] : ["pgvector"]
|
|
266
|
+
];
|
|
267
|
+
if (missingAfterInstall.length > 0) {
|
|
268
|
+
return {
|
|
269
|
+
...afterInstall,
|
|
270
|
+
state: "needs_attention",
|
|
271
|
+
message: `Homebrew runtime assets are still missing: ${missingAfterInstall.join(", ")}.`,
|
|
272
|
+
installedPackages: missingPackages,
|
|
273
|
+
linkedPaths: []
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
const linkedPaths = [
|
|
277
|
+
[
|
|
278
|
+
afterInstall.binaries.initdb.path,
|
|
279
|
+
resolve(afterInstall.koedRuntime.postgresBinDir, "initdb")
|
|
280
|
+
],
|
|
281
|
+
[
|
|
282
|
+
afterInstall.binaries.pg_ctl.path,
|
|
283
|
+
resolve(afterInstall.koedRuntime.postgresBinDir, "pg_ctl")
|
|
284
|
+
],
|
|
285
|
+
[
|
|
286
|
+
afterInstall.binaries.psql.path,
|
|
287
|
+
resolve(afterInstall.koedRuntime.postgresBinDir, "psql")
|
|
288
|
+
],
|
|
289
|
+
[
|
|
290
|
+
afterInstall.binaries.pg_dump.path,
|
|
291
|
+
resolve(afterInstall.koedRuntime.postgresBinDir, "pg_dump")
|
|
292
|
+
],
|
|
293
|
+
[
|
|
294
|
+
afterInstall.binaries.pg_restore.path,
|
|
295
|
+
resolve(afterInstall.koedRuntime.postgresBinDir, "pg_restore")
|
|
296
|
+
],
|
|
297
|
+
[
|
|
298
|
+
afterInstall.binaries.pg_config.path,
|
|
299
|
+
resolve(afterInstall.koedRuntime.postgresBinDir, "pg_config")
|
|
300
|
+
],
|
|
301
|
+
[
|
|
302
|
+
afterInstall.binaries.llama_server.path,
|
|
303
|
+
afterInstall.koedRuntime.llamaServerBin
|
|
304
|
+
]
|
|
305
|
+
];
|
|
306
|
+
for (const [source, target] of linkedPaths) {
|
|
307
|
+
linkRuntimePath(source, target, paths.koedHome, deps);
|
|
308
|
+
}
|
|
309
|
+
deps.mkdirSync(paths.cacheDir, { recursive: true, mode: 448 });
|
|
310
|
+
deps.writeFileSync(afterInstall.koedRuntime.metadataPath, `${JSON.stringify({
|
|
311
|
+
provider: "homebrew",
|
|
312
|
+
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
313
|
+
packages: afterInstall.packages,
|
|
314
|
+
binaries: afterInstall.binaries,
|
|
315
|
+
pgvector: afterInstall.pgvector
|
|
316
|
+
}, null, 2)}
|
|
317
|
+
`, { mode: 384 });
|
|
318
|
+
const finalStatus = collectHomebrewRuntimeStatus(paths, environment, deps);
|
|
319
|
+
return {
|
|
320
|
+
...finalStatus,
|
|
321
|
+
installedPackages: missingPackages,
|
|
322
|
+
linkedPaths: linkedPaths.map(([, target]) => target)
|
|
323
|
+
};
|
|
324
|
+
};
|
|
325
|
+
export {
|
|
326
|
+
collectHomebrewRuntimeStatus,
|
|
327
|
+
installHomebrewRuntime
|
|
328
|
+
};
|