@cortex-context/cli 0.0.8 → 0.0.10
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 +137 -18
- package/dist/index.js.map +1 -1
- package/dist/templates/local/docker-compose.local.yml +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -18220,7 +18220,68 @@ function tryFixLxcSysctl() {
|
|
|
18220
18220
|
return { applied: false };
|
|
18221
18221
|
}
|
|
18222
18222
|
}
|
|
18223
|
-
|
|
18223
|
+
function tryConfigureCrunRuntime() {
|
|
18224
|
+
const result = {
|
|
18225
|
+
attempted: false,
|
|
18226
|
+
crunInstalled: false,
|
|
18227
|
+
daemonUpdated: false,
|
|
18228
|
+
dockerRestarted: false
|
|
18229
|
+
};
|
|
18230
|
+
if ((0, import_os3.platform)() !== "linux") return result;
|
|
18231
|
+
result.attempted = true;
|
|
18232
|
+
const hasCrun = (() => {
|
|
18233
|
+
try {
|
|
18234
|
+
(0, import_child_process.execSync)("which crun", { stdio: "ignore" });
|
|
18235
|
+
return true;
|
|
18236
|
+
} catch {
|
|
18237
|
+
return false;
|
|
18238
|
+
}
|
|
18239
|
+
})();
|
|
18240
|
+
if (hasCrun) {
|
|
18241
|
+
result.crunInstalled = true;
|
|
18242
|
+
} else {
|
|
18243
|
+
try {
|
|
18244
|
+
(0, import_child_process.execSync)("apt-get install -y crun", { stdio: "ignore" });
|
|
18245
|
+
result.crunInstalled = true;
|
|
18246
|
+
} catch (e) {
|
|
18247
|
+
result.error = `crun install: ${e instanceof Error ? e.message : String(e)}`;
|
|
18248
|
+
return result;
|
|
18249
|
+
}
|
|
18250
|
+
}
|
|
18251
|
+
const daemonPath = "/etc/docker/daemon.json";
|
|
18252
|
+
let cfg = {};
|
|
18253
|
+
try {
|
|
18254
|
+
if ((0, import_fs5.existsSync)(daemonPath)) {
|
|
18255
|
+
cfg = JSON.parse((0, import_fs5.readFileSync)(daemonPath, "utf-8"));
|
|
18256
|
+
}
|
|
18257
|
+
} catch {
|
|
18258
|
+
cfg = {};
|
|
18259
|
+
}
|
|
18260
|
+
if (cfg["default-runtime"] === "crun") {
|
|
18261
|
+
result.daemonUpdated = true;
|
|
18262
|
+
result.dockerRestarted = true;
|
|
18263
|
+
return result;
|
|
18264
|
+
}
|
|
18265
|
+
const runtimes = cfg["runtimes"] ?? {};
|
|
18266
|
+
runtimes["crun"] = { path: "/usr/bin/crun" };
|
|
18267
|
+
cfg["runtimes"] = runtimes;
|
|
18268
|
+
cfg["default-runtime"] = "crun";
|
|
18269
|
+
try {
|
|
18270
|
+
(0, import_fs5.writeFileSync)(daemonPath, JSON.stringify(cfg, null, 2) + "\n", "utf-8");
|
|
18271
|
+
result.daemonUpdated = true;
|
|
18272
|
+
} catch (e) {
|
|
18273
|
+
result.error = `daemon.json: ${e instanceof Error ? e.message : String(e)}`;
|
|
18274
|
+
return result;
|
|
18275
|
+
}
|
|
18276
|
+
try {
|
|
18277
|
+
(0, import_child_process.execSync)("systemctl restart docker", { stdio: "ignore" });
|
|
18278
|
+
result.dockerRestarted = true;
|
|
18279
|
+
} catch (e) {
|
|
18280
|
+
result.error = `docker restart: ${e instanceof Error ? e.message : String(e)}`;
|
|
18281
|
+
}
|
|
18282
|
+
return result;
|
|
18283
|
+
}
|
|
18284
|
+
async function deployLocalStack(workspacePath, opts = {}) {
|
|
18224
18285
|
const templatePath = (0, import_path5.join)(
|
|
18225
18286
|
__dirname,
|
|
18226
18287
|
"templates",
|
|
@@ -18234,22 +18295,29 @@ async function deployLocalStack(workspacePath) {
|
|
|
18234
18295
|
if (!(0, import_fs5.existsSync)(destPath)) {
|
|
18235
18296
|
(0, import_fs5.cpSync)(templatePath, destPath);
|
|
18236
18297
|
}
|
|
18298
|
+
const imageTag = opts.embeddings ? "latest-embeddings" : "latest";
|
|
18299
|
+
const cortexImage = `ghcr.io/rodrigoroldan/cortex-context:${imageTag}`;
|
|
18237
18300
|
try {
|
|
18238
18301
|
(0, import_child_process.execSync)(
|
|
18239
18302
|
`docker compose --project-name cortex-local -f "${destPath}" up -d`,
|
|
18240
18303
|
{
|
|
18241
18304
|
cwd: workspacePath,
|
|
18242
|
-
|
|
18305
|
+
// stdout → terminal (user sees progress), stderr → captured for error detection
|
|
18306
|
+
stdio: ["inherit", "inherit", "pipe"],
|
|
18307
|
+
env: { ...process.env, CORTEX_IMAGE: cortexImage }
|
|
18243
18308
|
}
|
|
18244
18309
|
);
|
|
18245
18310
|
return { started: true };
|
|
18246
18311
|
} catch (err) {
|
|
18312
|
+
const stderr = err instanceof Error && "stderr" in err ? err.stderr?.toString() ?? "" : "";
|
|
18247
18313
|
const msg = err instanceof Error ? err.message : String(err);
|
|
18248
|
-
const
|
|
18314
|
+
const combined = stderr + msg;
|
|
18315
|
+
const isLxcSysctlError = combined.includes("ip_unprivileged_port_start") || combined.includes("sysctl net.ipv4");
|
|
18249
18316
|
return {
|
|
18250
18317
|
started: false,
|
|
18251
18318
|
isLxcSysctlError,
|
|
18252
|
-
error: `docker compose failed: ${msg}`
|
|
18319
|
+
error: `docker compose failed: ${msg}${stderr ? `
|
|
18320
|
+
${stderr.trim()}` : ""}`
|
|
18253
18321
|
};
|
|
18254
18322
|
}
|
|
18255
18323
|
}
|
|
@@ -28056,6 +28124,13 @@ async function serverCommand(options) {
|
|
|
28056
28124
|
" Installs and starts the Cortex stack (Neo4j + Cortex API) via Docker."
|
|
28057
28125
|
)
|
|
28058
28126
|
);
|
|
28127
|
+
if (options.embeddings) {
|
|
28128
|
+
console.log(
|
|
28129
|
+
source_default.dim(
|
|
28130
|
+
" Mode: embeddings (sentence-transformers + all-MiniLM-L6-v2 baked in, ~1.5 GB image)"
|
|
28131
|
+
)
|
|
28132
|
+
);
|
|
28133
|
+
}
|
|
28059
28134
|
console.log("");
|
|
28060
28135
|
const defaultDir = (0, import_path13.join)((0, import_os4.homedir)(), ".cortex-context");
|
|
28061
28136
|
const workDir = options.dir ?? defaultDir;
|
|
@@ -28161,28 +28236,69 @@ async function serverCommand(options) {
|
|
|
28161
28236
|
console.log(source_default.bold(" Step 3: Starting Cortex stack"));
|
|
28162
28237
|
const sysctlFix = tryFixLxcSysctl();
|
|
28163
28238
|
if (sysctlFix.applied) {
|
|
28164
|
-
console.log(
|
|
28239
|
+
console.log(
|
|
28240
|
+
source_default.dim(
|
|
28241
|
+
" (applied net.ipv4.ip_unprivileged_port_start=0 for LXC compatibility)"
|
|
28242
|
+
)
|
|
28243
|
+
);
|
|
28244
|
+
}
|
|
28245
|
+
const crunSetup = tryConfigureCrunRuntime();
|
|
28246
|
+
if (crunSetup.attempted) {
|
|
28247
|
+
if (crunSetup.dockerRestarted) {
|
|
28248
|
+
console.log(
|
|
28249
|
+
source_default.dim(
|
|
28250
|
+
" (configured crun as Docker runtime for LXC compatibility \u2014 daemon restarted)"
|
|
28251
|
+
)
|
|
28252
|
+
);
|
|
28253
|
+
} else if (crunSetup.error) {
|
|
28254
|
+
console.log(
|
|
28255
|
+
source_default.dim(` (crun setup skipped: ${crunSetup.error})`)
|
|
28256
|
+
);
|
|
28257
|
+
}
|
|
28165
28258
|
}
|
|
28166
28259
|
const startSpinner = ora(" Running docker compose up -d...").start();
|
|
28167
|
-
const startResult = await deployLocalStack(workDir
|
|
28260
|
+
const startResult = await deployLocalStack(workDir, {
|
|
28261
|
+
embeddings: options.embeddings ?? false
|
|
28262
|
+
});
|
|
28168
28263
|
if (!startResult.started) {
|
|
28169
28264
|
startSpinner.fail(source_default.red(" \u2717 Docker Compose failed"));
|
|
28170
28265
|
if (startResult.isLxcSysctlError) {
|
|
28171
28266
|
console.log("");
|
|
28172
|
-
console.log(
|
|
28267
|
+
console.log(
|
|
28268
|
+
source_default.bold.yellow(" \u26A0 Proxmox LXC sysctl restriction detected")
|
|
28269
|
+
);
|
|
28173
28270
|
console.log("");
|
|
28174
|
-
console.log(
|
|
28175
|
-
|
|
28176
|
-
|
|
28271
|
+
console.log(
|
|
28272
|
+
source_default.dim(
|
|
28273
|
+
" runc >= 1.1 writes net.ipv4.ip_unprivileged_port_start in each new"
|
|
28274
|
+
)
|
|
28275
|
+
);
|
|
28276
|
+
console.log(
|
|
28277
|
+
source_default.dim(
|
|
28278
|
+
" Docker network namespace. Unprivileged Proxmox LXC blocks this write."
|
|
28279
|
+
)
|
|
28280
|
+
);
|
|
28177
28281
|
console.log("");
|
|
28178
|
-
console.log(
|
|
28282
|
+
console.log(
|
|
28283
|
+
source_default.dim(
|
|
28284
|
+
" Attempted automatic fix (crun) \u2014 but it was not enough."
|
|
28285
|
+
)
|
|
28286
|
+
);
|
|
28287
|
+
console.log(
|
|
28288
|
+
source_default.dim(
|
|
28289
|
+
" Manual fix: install crun and configure Docker daemon on this LXC:"
|
|
28290
|
+
)
|
|
28291
|
+
);
|
|
28179
28292
|
console.log("");
|
|
28180
|
-
console.log(source_default.cyan("
|
|
28181
|
-
console.log(source_default.cyan(
|
|
28182
|
-
console.log(source_default.cyan("
|
|
28183
|
-
console.log(source_default.cyan("
|
|
28293
|
+
console.log(source_default.cyan(" apt-get install -y crun"));
|
|
28294
|
+
console.log(source_default.cyan(" cat > /etc/docker/daemon.json << 'EOF'"));
|
|
28295
|
+
console.log(source_default.cyan(' {"default-runtime":"crun","runtimes":{"crun":{"path":"/usr/bin/crun"}}}'));
|
|
28296
|
+
console.log(source_default.cyan(" EOF"));
|
|
28297
|
+
console.log(source_default.cyan(" systemctl restart docker"));
|
|
28184
28298
|
console.log("");
|
|
28185
|
-
console.log(
|
|
28299
|
+
console.log(
|
|
28300
|
+
source_default.dim(" Then run cortex-context server again.")
|
|
28301
|
+
);
|
|
28186
28302
|
} else {
|
|
28187
28303
|
console.log(source_default.dim(` ${startResult.error}`));
|
|
28188
28304
|
}
|
|
@@ -28372,8 +28488,8 @@ async function uninstallCommand(options) {
|
|
|
28372
28488
|
if (!options.keepHook && hasHook) {
|
|
28373
28489
|
const hookPath = (0, import_path14.join)(workspacePath, ".git", "hooks", "post-commit");
|
|
28374
28490
|
try {
|
|
28375
|
-
const { readFileSync:
|
|
28376
|
-
const hookContent =
|
|
28491
|
+
const { readFileSync: readFileSync8 } = await import("fs");
|
|
28492
|
+
const hookContent = readFileSync8(hookPath, "utf-8");
|
|
28377
28493
|
if (hookContent.includes("cortex-context")) {
|
|
28378
28494
|
(0, import_fs13.unlinkSync)(hookPath);
|
|
28379
28495
|
console.log(source_default.green(" \u2713 .git/hooks/post-commit \u2014 removed"));
|
|
@@ -28454,6 +28570,9 @@ function createCli() {
|
|
|
28454
28570
|
).option(
|
|
28455
28571
|
"--skip-docker-install",
|
|
28456
28572
|
"Fail instead of auto-installing Docker when it is not found"
|
|
28573
|
+
).option(
|
|
28574
|
+
"--embeddings",
|
|
28575
|
+
"Use the embeddings-enabled image (includes sentence-transformers + all-MiniLM-L6-v2, ~1.5 GB)"
|
|
28457
28576
|
).action(serverCommand);
|
|
28458
28577
|
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);
|
|
28459
28578
|
program3.command("update").description(
|