@cortex-context/cli 0.0.15 → 0.0.17
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
|
@@ -18227,84 +18227,33 @@ var import_child_process = require("child_process");
|
|
|
18227
18227
|
var import_fs5 = require("fs");
|
|
18228
18228
|
var import_path5 = require("path");
|
|
18229
18229
|
var import_os3 = require("os");
|
|
18230
|
-
function
|
|
18230
|
+
function isLxcEnvironment() {
|
|
18231
|
+
if ((0, import_os3.platform)() !== "linux") return false;
|
|
18231
18232
|
try {
|
|
18232
|
-
(0,
|
|
18233
|
-
|
|
18234
|
-
});
|
|
18235
|
-
return { applied: true };
|
|
18233
|
+
const environ = (0, import_fs5.readFileSync)("/proc/1/environ", "utf-8");
|
|
18234
|
+
if (environ.includes("container=lxc")) return true;
|
|
18236
18235
|
} catch {
|
|
18237
|
-
return { applied: false };
|
|
18238
18236
|
}
|
|
18239
|
-
}
|
|
18240
|
-
function tryConfigureCrunRuntime() {
|
|
18241
|
-
const result = {
|
|
18242
|
-
attempted: false,
|
|
18243
|
-
crunInstalled: false,
|
|
18244
|
-
daemonUpdated: false,
|
|
18245
|
-
dockerRestarted: false
|
|
18246
|
-
};
|
|
18247
|
-
if ((0, import_os3.platform)() !== "linux") return result;
|
|
18248
|
-
result.attempted = true;
|
|
18249
|
-
const hasCrun = (() => {
|
|
18250
|
-
try {
|
|
18251
|
-
(0, import_child_process.execSync)("which crun", { stdio: "ignore" });
|
|
18252
|
-
return true;
|
|
18253
|
-
} catch {
|
|
18254
|
-
return false;
|
|
18255
|
-
}
|
|
18256
|
-
})();
|
|
18257
|
-
if (hasCrun) {
|
|
18258
|
-
result.crunInstalled = true;
|
|
18259
|
-
} else {
|
|
18260
|
-
try {
|
|
18261
|
-
(0, import_child_process.execSync)("apt-get install -y crun", { stdio: "ignore" });
|
|
18262
|
-
result.crunInstalled = true;
|
|
18263
|
-
} catch (e) {
|
|
18264
|
-
result.error = `crun install: ${e instanceof Error ? e.message : String(e)}`;
|
|
18265
|
-
return result;
|
|
18266
|
-
}
|
|
18267
|
-
}
|
|
18268
|
-
const daemonPath = "/etc/docker/daemon.json";
|
|
18269
|
-
let cfg = {};
|
|
18270
18237
|
try {
|
|
18271
|
-
|
|
18272
|
-
|
|
18273
|
-
|
|
18238
|
+
const virt = (0, import_child_process.execSync)("systemd-detect-virt 2>/dev/null", {
|
|
18239
|
+
encoding: "utf-8",
|
|
18240
|
+
stdio: ["pipe", "pipe", "ignore"],
|
|
18241
|
+
timeout: 1e3
|
|
18242
|
+
}).trim();
|
|
18243
|
+
if (virt === "lxc" || virt === "lxc-libvirt") return true;
|
|
18274
18244
|
} catch {
|
|
18275
|
-
cfg = {};
|
|
18276
|
-
}
|
|
18277
|
-
if (cfg["default-runtime"] === "crun") {
|
|
18278
|
-
result.daemonUpdated = true;
|
|
18279
|
-
result.dockerRestarted = true;
|
|
18280
|
-
return result;
|
|
18281
18245
|
}
|
|
18282
|
-
const runtimes = cfg["runtimes"] ?? {};
|
|
18283
|
-
runtimes["crun"] = { path: "/usr/bin/crun" };
|
|
18284
|
-
cfg["runtimes"] = runtimes;
|
|
18285
|
-
cfg["default-runtime"] = "crun";
|
|
18286
18246
|
try {
|
|
18287
|
-
(0, import_fs5.
|
|
18288
|
-
|
|
18289
|
-
} catch
|
|
18290
|
-
result.error = `daemon.json: ${e instanceof Error ? e.message : String(e)}`;
|
|
18291
|
-
return result;
|
|
18292
|
-
}
|
|
18293
|
-
try {
|
|
18294
|
-
(0, import_child_process.execSync)("systemctl restart docker", { stdio: "ignore" });
|
|
18295
|
-
result.dockerRestarted = true;
|
|
18296
|
-
} catch (e) {
|
|
18297
|
-
result.error = `docker restart: ${e instanceof Error ? e.message : String(e)}`;
|
|
18247
|
+
const cgroup = (0, import_fs5.readFileSync)("/proc/1/cgroup", "utf-8");
|
|
18248
|
+
if (/\/lxc\//.test(cgroup)) return true;
|
|
18249
|
+
} catch {
|
|
18298
18250
|
}
|
|
18299
|
-
return
|
|
18251
|
+
return false;
|
|
18300
18252
|
}
|
|
18301
18253
|
async function deployLocalStack(workspacePath, opts = {}) {
|
|
18302
|
-
const
|
|
18303
|
-
|
|
18304
|
-
|
|
18305
|
-
"local",
|
|
18306
|
-
"docker-compose.local.yml"
|
|
18307
|
-
);
|
|
18254
|
+
const lxc = isLxcEnvironment();
|
|
18255
|
+
const templateFile = lxc ? "docker-compose.host-network.yml" : "docker-compose.local.yml";
|
|
18256
|
+
const templatePath = (0, import_path5.join)(__dirname, "templates", "local", templateFile);
|
|
18308
18257
|
const destPath = (0, import_path5.join)(workspacePath, "docker-compose.local.yml");
|
|
18309
18258
|
if (!(0, import_fs5.existsSync)(templatePath)) {
|
|
18310
18259
|
return { started: false, error: `Template not found: ${templatePath}` };
|
|
@@ -18326,11 +18275,19 @@ async function deployLocalStack(workspacePath, opts = {}) {
|
|
|
18326
18275
|
};
|
|
18327
18276
|
let envContent = existingEnv;
|
|
18328
18277
|
envContent = setEnvVar(envContent, "CORTEX_API_TOKEN", opts.token ?? "");
|
|
18329
|
-
envContent = setEnvVar(
|
|
18330
|
-
|
|
18278
|
+
envContent = setEnvVar(
|
|
18279
|
+
envContent,
|
|
18280
|
+
"SPECS_DIR_HOST",
|
|
18281
|
+
opts.specsDir ?? "./specs-sample"
|
|
18282
|
+
);
|
|
18283
|
+
envContent = setEnvVar(
|
|
18284
|
+
envContent,
|
|
18285
|
+
"REPOS_DIR_HOST",
|
|
18286
|
+
opts.reposDir ?? "./repos-sample"
|
|
18287
|
+
);
|
|
18331
18288
|
if (!envContent.endsWith("\n")) envContent += "\n";
|
|
18332
18289
|
(0, import_fs5.writeFileSync)(envPath, envContent, { encoding: "utf-8" });
|
|
18333
|
-
const imageTag = opts.embeddings ? "latest-embeddings" : "latest";
|
|
18290
|
+
const imageTag = opts.gpu ? "latest-gpu" : opts.embeddings ? "latest-embeddings" : "latest";
|
|
18334
18291
|
const cortexImage = `ghcr.io/rodrigoroldan/cortex-context:${imageTag}`;
|
|
18335
18292
|
try {
|
|
18336
18293
|
(0, import_child_process.execSync)(
|
|
@@ -18342,7 +18299,7 @@ async function deployLocalStack(workspacePath, opts = {}) {
|
|
|
18342
18299
|
env: { ...process.env, CORTEX_IMAGE: cortexImage }
|
|
18343
18300
|
}
|
|
18344
18301
|
);
|
|
18345
|
-
return { started: true };
|
|
18302
|
+
return { started: true, usedHostNetwork: lxc };
|
|
18346
18303
|
} catch (err) {
|
|
18347
18304
|
const stderr = err instanceof Error && "stderr" in err ? err.stderr?.toString() ?? "" : "";
|
|
18348
18305
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -18364,7 +18321,7 @@ async function upgradeLocalStack(workspacePath, opts = {}) {
|
|
|
18364
18321
|
error: `docker-compose.local.yml not found in ${workspacePath}. Run: cortex-context server`
|
|
18365
18322
|
};
|
|
18366
18323
|
}
|
|
18367
|
-
const imageTag = opts.embeddings ? "latest-embeddings" : "latest";
|
|
18324
|
+
const imageTag = opts.gpu ? "latest-gpu" : opts.embeddings ? "latest-embeddings" : "latest";
|
|
18368
18325
|
const cortexImage = `ghcr.io/rodrigoroldan/cortex-context:${imageTag}`;
|
|
18369
18326
|
const composeCmd = `docker compose --project-name cortex-local -f "${composePath}"`;
|
|
18370
18327
|
try {
|
|
@@ -18693,7 +18650,9 @@ async function initCommand(options) {
|
|
|
18693
18650
|
const spinner2 = ora(
|
|
18694
18651
|
" Starting Cortex stack with Docker Compose..."
|
|
18695
18652
|
).start();
|
|
18696
|
-
const dockerResult = await deployLocalStack(workspacePath, {
|
|
18653
|
+
const dockerResult = await deployLocalStack(workspacePath, {
|
|
18654
|
+
token: cortexToken
|
|
18655
|
+
});
|
|
18697
18656
|
if (!dockerResult.started) {
|
|
18698
18657
|
spinner2.fail(
|
|
18699
18658
|
source_default.red(` \u2717 Docker deploy failed: ${dockerResult.error}`)
|
|
@@ -28221,7 +28180,13 @@ async function serverCommand(options) {
|
|
|
28221
28180
|
" Installs and starts the Cortex stack (Neo4j + Cortex API) via Docker."
|
|
28222
28181
|
)
|
|
28223
28182
|
);
|
|
28224
|
-
if (options.
|
|
28183
|
+
if (options.gpu) {
|
|
28184
|
+
console.log(
|
|
28185
|
+
source_default.dim(
|
|
28186
|
+
" Mode: gpu (sentence-transformers + PyTorch CUDA, ~2 GB image \u2014 requer nvidia GPU no host)"
|
|
28187
|
+
)
|
|
28188
|
+
);
|
|
28189
|
+
} else if (options.embeddings) {
|
|
28225
28190
|
console.log(
|
|
28226
28191
|
source_default.dim(
|
|
28227
28192
|
" Mode: embeddings (sentence-transformers + all-MiniLM-L6-v2 baked in, ~1.5 GB image)"
|
|
@@ -28397,75 +28362,24 @@ async function serverCommand(options) {
|
|
|
28397
28362
|
writeConfig({ url: CORTEX_URL2, token: serverToken });
|
|
28398
28363
|
console.log("");
|
|
28399
28364
|
console.log(source_default.bold(" Step 4: Starting Cortex stack"));
|
|
28400
|
-
|
|
28401
|
-
if (sysctlFix.applied) {
|
|
28365
|
+
if (isLxcEnvironment()) {
|
|
28402
28366
|
console.log(
|
|
28403
28367
|
source_default.dim(
|
|
28404
|
-
" (
|
|
28368
|
+
" (Proxmox LXC detected \u2014 using host network mode automatically)"
|
|
28405
28369
|
)
|
|
28406
28370
|
);
|
|
28407
28371
|
}
|
|
28408
|
-
const crunSetup = tryConfigureCrunRuntime();
|
|
28409
|
-
if (crunSetup.attempted) {
|
|
28410
|
-
if (crunSetup.dockerRestarted) {
|
|
28411
|
-
console.log(
|
|
28412
|
-
source_default.dim(
|
|
28413
|
-
" (configured crun as Docker runtime for LXC compatibility \u2014 daemon restarted)"
|
|
28414
|
-
)
|
|
28415
|
-
);
|
|
28416
|
-
} else if (crunSetup.error) {
|
|
28417
|
-
console.log(source_default.dim(` (crun setup skipped: ${crunSetup.error})`));
|
|
28418
|
-
}
|
|
28419
|
-
}
|
|
28420
28372
|
console.log(source_default.dim(" $ docker compose up -d"));
|
|
28421
28373
|
console.log("");
|
|
28422
28374
|
const startResult = await deployLocalStack(workDir, {
|
|
28423
28375
|
embeddings: options.embeddings ?? false,
|
|
28376
|
+
gpu: options.gpu ?? false,
|
|
28424
28377
|
token: serverToken
|
|
28425
28378
|
});
|
|
28426
28379
|
console.log("");
|
|
28427
28380
|
if (!startResult.started) {
|
|
28428
28381
|
console.log(source_default.red(" \u2717 Docker Compose failed"));
|
|
28429
|
-
|
|
28430
|
-
console.log("");
|
|
28431
|
-
console.log(
|
|
28432
|
-
source_default.bold.yellow(" \u26A0 Proxmox LXC sysctl restriction detected")
|
|
28433
|
-
);
|
|
28434
|
-
console.log("");
|
|
28435
|
-
console.log(
|
|
28436
|
-
source_default.dim(
|
|
28437
|
-
" runc >= 1.1 writes net.ipv4.ip_unprivileged_port_start in each new"
|
|
28438
|
-
)
|
|
28439
|
-
);
|
|
28440
|
-
console.log(
|
|
28441
|
-
source_default.dim(
|
|
28442
|
-
" Docker network namespace. Unprivileged Proxmox LXC blocks this write."
|
|
28443
|
-
)
|
|
28444
|
-
);
|
|
28445
|
-
console.log("");
|
|
28446
|
-
console.log(
|
|
28447
|
-
source_default.dim(" Attempted automatic fix (crun) \u2014 but it was not enough.")
|
|
28448
|
-
);
|
|
28449
|
-
console.log(
|
|
28450
|
-
source_default.dim(
|
|
28451
|
-
" Manual fix: install crun and configure Docker daemon on this LXC:"
|
|
28452
|
-
)
|
|
28453
|
-
);
|
|
28454
|
-
console.log("");
|
|
28455
|
-
console.log(source_default.cyan(" apt-get install -y crun"));
|
|
28456
|
-
console.log(source_default.cyan(" cat > /etc/docker/daemon.json << 'EOF'"));
|
|
28457
|
-
console.log(
|
|
28458
|
-
source_default.cyan(
|
|
28459
|
-
' {"default-runtime":"crun","runtimes":{"crun":{"path":"/usr/bin/crun"}}}'
|
|
28460
|
-
)
|
|
28461
|
-
);
|
|
28462
|
-
console.log(source_default.cyan(" EOF"));
|
|
28463
|
-
console.log(source_default.cyan(" systemctl restart docker"));
|
|
28464
|
-
console.log("");
|
|
28465
|
-
console.log(source_default.dim(" Then run cortex-context server again."));
|
|
28466
|
-
} else {
|
|
28467
|
-
console.log(source_default.dim(` ${startResult.error}`));
|
|
28468
|
-
}
|
|
28382
|
+
console.log(source_default.dim(` ${startResult.error}`));
|
|
28469
28383
|
process.exit(1);
|
|
28470
28384
|
}
|
|
28471
28385
|
console.log(source_default.green(" \u2713 Containers started"));
|
|
@@ -29067,6 +28981,9 @@ function createCli() {
|
|
|
29067
28981
|
).option(
|
|
29068
28982
|
"--embeddings",
|
|
29069
28983
|
"Use the embeddings-enabled image (includes sentence-transformers + all-MiniLM-L6-v2, ~1.5 GB)"
|
|
28984
|
+
).option(
|
|
28985
|
+
"--gpu",
|
|
28986
|
+
"Use the GPU image (embeddings + PyTorch CUDA, ~2 GB \u2014 requires nvidia GPU on host)"
|
|
29070
28987
|
).action(serverCommand);
|
|
29071
28988
|
program3.command("sync").description("Ingest latest git diff into the Cortex Knowledge Graph").option("--repo <path>", "Repository path (defaults to current directory)").option("--dry-run", "Show diff without sending to Cortex API").action(syncCommand);
|
|
29072
28989
|
program3.command("update").description(
|