@cortex-context/cli 0.0.13 → 0.0.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/index.js CHANGED
@@ -18342,6 +18342,66 @@ ${stderr.trim()}` : ""}`
18342
18342
  };
18343
18343
  }
18344
18344
  }
18345
+ async function upgradeLocalStack(workspacePath, opts = {}) {
18346
+ const composePath = (0, import_path5.join)(workspacePath, "docker-compose.local.yml");
18347
+ if (!(0, import_fs5.existsSync)(composePath)) {
18348
+ return {
18349
+ upgraded: false,
18350
+ error: `docker-compose.local.yml not found in ${workspacePath}. Run: cortex-context server`
18351
+ };
18352
+ }
18353
+ const imageTag = opts.embeddings ? "latest-embeddings" : "latest";
18354
+ const cortexImage = `ghcr.io/rodrigoroldan/cortex-context:${imageTag}`;
18355
+ const composeCmd = `docker compose --project-name cortex-local -f "${composePath}"`;
18356
+ try {
18357
+ (0, import_child_process.execSync)(`${composeCmd} pull cortex-api`, {
18358
+ cwd: workspacePath,
18359
+ stdio: ["inherit", "inherit", "pipe"],
18360
+ env: { ...process.env, CORTEX_IMAGE: cortexImage }
18361
+ });
18362
+ } catch (err) {
18363
+ const stderr = err instanceof Error && "stderr" in err ? err.stderr?.toString() ?? "" : "";
18364
+ const msg = err instanceof Error ? err.message : String(err);
18365
+ return {
18366
+ upgraded: false,
18367
+ error: `docker compose pull failed: ${msg}${stderr ? `
18368
+ ${stderr.trim()}` : ""}`
18369
+ };
18370
+ }
18371
+ try {
18372
+ (0, import_child_process.execSync)(`${composeCmd} up -d --force-recreate cortex-api`, {
18373
+ cwd: workspacePath,
18374
+ stdio: ["inherit", "inherit", "pipe"],
18375
+ env: { ...process.env, CORTEX_IMAGE: cortexImage }
18376
+ });
18377
+ } catch (err) {
18378
+ const stderr = err instanceof Error && "stderr" in err ? err.stderr?.toString() ?? "" : "";
18379
+ const msg = err instanceof Error ? err.message : String(err);
18380
+ return {
18381
+ upgraded: false,
18382
+ error: `docker compose up failed: ${msg}${stderr ? `
18383
+ ${stderr.trim()}` : ""}`
18384
+ };
18385
+ }
18386
+ return { upgraded: true };
18387
+ }
18388
+ function restartCortexApi(workspacePath) {
18389
+ const composePath = (0, import_path5.join)(workspacePath, "docker-compose.local.yml");
18390
+ if (!(0, import_fs5.existsSync)(composePath))
18391
+ return { restarted: false, error: "docker-compose.local.yml not found" };
18392
+ try {
18393
+ (0, import_child_process.execSync)(
18394
+ `docker compose --project-name cortex-local -f "${composePath}" restart cortex-api`,
18395
+ { cwd: workspacePath, stdio: "ignore" }
18396
+ );
18397
+ return { restarted: true };
18398
+ } catch (err) {
18399
+ return {
18400
+ restarted: false,
18401
+ error: err instanceof Error ? err.message : String(err)
18402
+ };
18403
+ }
18404
+ }
18345
18405
  function isDockerAvailable() {
18346
18406
  try {
18347
18407
  (0, import_child_process.execSync)("docker --version", { stdio: "ignore" });
@@ -28720,6 +28780,39 @@ var import_os5 = require("os");
28720
28780
  var import_prompts6 = __toESM(require_prompts3());
28721
28781
  var CORTEX_DIR = (0, import_path15.join)((0, import_os5.homedir)(), ".cortex-context");
28722
28782
  var ENV_FILE = (0, import_path15.join)(CORTEX_DIR, ".env");
28783
+ async function applyTokenRestart() {
28784
+ if (!isDockerAvailable()) return;
28785
+ console.log(
28786
+ source_default.dim(" Restarting cortex-api container to apply new token...")
28787
+ );
28788
+ const result = restartCortexApi(CORTEX_DIR);
28789
+ if (!result.restarted) {
28790
+ console.log(
28791
+ source_default.yellow(
28792
+ ` \u26A0 Could not restart container: ${result.error ?? "unknown error"}`
28793
+ )
28794
+ );
28795
+ console.log(
28796
+ source_default.dim(
28797
+ " docker compose -f ~/.cortex-context/docker-compose.local.yml restart cortex-api"
28798
+ )
28799
+ );
28800
+ return;
28801
+ }
28802
+ const config2 = readConfig();
28803
+ const url = config2.url ?? "http://localhost:8082";
28804
+ console.log(source_default.dim(` Waiting for Cortex API at ${url}...`));
28805
+ const { healthy } = await waitForCortexHealth(url, 6e4);
28806
+ if (healthy) {
28807
+ console.log(source_default.green(" \u2713 Container restarted and healthy"));
28808
+ } else {
28809
+ console.log(
28810
+ source_default.yellow(
28811
+ " \u26A0 Container restarted but did not become healthy within 60s"
28812
+ )
28813
+ );
28814
+ }
28815
+ }
28723
28816
  function readEnvToken() {
28724
28817
  if (!(0, import_fs14.existsSync)(ENV_FILE)) return "";
28725
28818
  const content = (0, import_fs14.readFileSync)(ENV_FILE, "utf-8");
@@ -28756,15 +28849,8 @@ async function tokenCommand(options) {
28756
28849
  console.log(
28757
28850
  source_default.green(newToken ? " \u2713 Token updated" : " \u2713 Token cleared")
28758
28851
  );
28759
- if (newToken) {
28760
- console.log("");
28761
- console.log(source_default.dim(" Restart the Cortex container to apply:"));
28762
- console.log(
28763
- source_default.cyan(
28764
- " docker compose -f ~/.cortex-context/docker-compose.local.yml restart cortex-api"
28765
- )
28766
- );
28767
- }
28852
+ console.log("");
28853
+ await applyTokenRestart();
28768
28854
  console.log("");
28769
28855
  return;
28770
28856
  }
@@ -28805,12 +28891,8 @@ async function tokenCommand(options) {
28805
28891
  ` cortex-context init --url ${config3.url ?? "http://localhost:8082"} --token ${newToken}`
28806
28892
  )
28807
28893
  );
28808
- console.log(source_default.dim(" Restart the Cortex container:"));
28809
- console.log(
28810
- source_default.cyan(
28811
- " docker compose -f ~/.cortex-context/docker-compose.local.yml restart cortex-api"
28812
- )
28813
- );
28894
+ console.log("");
28895
+ await applyTokenRestart();
28814
28896
  console.log("");
28815
28897
  return;
28816
28898
  }
@@ -28834,11 +28916,114 @@ async function tokenCommand(options) {
28834
28916
  console.log("");
28835
28917
  }
28836
28918
 
28837
- // src/cli.ts
28838
- var import_fs15 = require("fs");
28919
+ // src/commands/upgrade.ts
28839
28920
  var import_path16 = require("path");
28921
+ var import_os6 = require("os");
28922
+ var import_fs15 = require("fs");
28923
+ async function upgradeCommand(options) {
28924
+ console.log("");
28925
+ console.log(source_default.bold.cyan(" \u25C6 Cortex Context \u2014 Upgrade"));
28926
+ console.log(
28927
+ source_default.dim(
28928
+ " Pulls the latest backend image and recreates the cortex-api container."
28929
+ )
28930
+ );
28931
+ console.log("");
28932
+ if (!isDockerAvailable()) {
28933
+ console.error(source_default.red(" \u2717 Docker is not available on $PATH."));
28934
+ console.log(
28935
+ source_default.dim(" Install Docker or ensure it is running, then retry.")
28936
+ );
28937
+ process.exit(1);
28938
+ }
28939
+ const workDir = options.dir ?? (0, import_path16.join)((0, import_os6.homedir)(), ".cortex-context");
28940
+ const composePath = (0, import_path16.join)(workDir, "docker-compose.local.yml");
28941
+ if (!(0, import_fs15.existsSync)(composePath)) {
28942
+ console.error(
28943
+ source_default.red(` \u2717 docker-compose.local.yml not found in ${workDir}`)
28944
+ );
28945
+ console.log(
28946
+ source_default.dim(" The local Cortex stack has not been set up yet. Run:")
28947
+ );
28948
+ console.log(source_default.cyan(" cortex-context server"));
28949
+ console.log("");
28950
+ process.exit(1);
28951
+ }
28952
+ const imageTag = options.embeddings ? "latest-embeddings" : "latest";
28953
+ const cortexImage = `ghcr.io/rodrigoroldan/cortex-context:${imageTag}`;
28954
+ console.log(source_default.dim(` Target image: ${cortexImage}`));
28955
+ console.log(source_default.dim(` Compose dir: ${workDir}`));
28956
+ console.log("");
28957
+ console.log(source_default.bold(" Step 1 \u2014 Pulling latest image..."));
28958
+ if (options.pullOnly) {
28959
+ const { execSync: execSync3 } = await import("child_process");
28960
+ try {
28961
+ execSync3(
28962
+ `docker compose --project-name cortex-local -f "${composePath}" pull cortex-api`,
28963
+ {
28964
+ cwd: workDir,
28965
+ stdio: ["inherit", "inherit", "pipe"],
28966
+ env: { ...process.env, CORTEX_IMAGE: cortexImage }
28967
+ }
28968
+ );
28969
+ console.log("");
28970
+ console.log(
28971
+ source_default.green(" \u2713 Image pulled successfully (--pull-only mode)")
28972
+ );
28973
+ console.log(
28974
+ source_default.dim(
28975
+ " Run without --pull-only to recreate the container with the new image."
28976
+ )
28977
+ );
28978
+ console.log("");
28979
+ } catch (err) {
28980
+ const msg = err instanceof Error ? err.message : String(err);
28981
+ console.error(source_default.red(` \u2717 Pull failed: ${msg}`));
28982
+ process.exit(1);
28983
+ }
28984
+ return;
28985
+ }
28986
+ const result = await upgradeLocalStack(workDir, {
28987
+ embeddings: options.embeddings
28988
+ });
28989
+ if (!result.upgraded) {
28990
+ console.error(source_default.red(` \u2717 Upgrade failed: ${result.error}`));
28991
+ process.exit(1);
28992
+ }
28993
+ console.log("");
28994
+ console.log(source_default.bold(" Step 2 \u2014 Waiting for Cortex API to be healthy..."));
28995
+ const config2 = readConfig();
28996
+ const cortexUrl = config2.url ?? "http://localhost:8082";
28997
+ const { healthy } = await waitForCortexHealth(cortexUrl, 12e4);
28998
+ console.log("");
28999
+ if (healthy) {
29000
+ console.log(source_default.green(" \u2713 Cortex API is healthy"));
29001
+ console.log("");
29002
+ console.log(source_default.bold(" \u25C6 Upgrade complete!"));
29003
+ console.log(source_default.dim(` API running at ${cortexUrl}`));
29004
+ console.log("");
29005
+ } else {
29006
+ console.log(
29007
+ source_default.yellow(
29008
+ " \u26A0 Container is up but did not become healthy within 120s"
29009
+ )
29010
+ );
29011
+ console.log(source_default.dim(" Check container logs:"));
29012
+ console.log(
29013
+ source_default.cyan(
29014
+ ` docker compose -f ${workDir}/docker-compose.local.yml logs cortex-api`
29015
+ )
29016
+ );
29017
+ console.log("");
29018
+ process.exit(1);
29019
+ }
29020
+ }
29021
+
29022
+ // src/cli.ts
29023
+ var import_fs16 = require("fs");
29024
+ var import_path17 = require("path");
28840
29025
  var pkg = JSON.parse(
28841
- (0, import_fs15.readFileSync)((0, import_path16.join)(__dirname, "..", "package.json"), "utf-8")
29026
+ (0, import_fs16.readFileSync)((0, import_path17.join)(__dirname, "..", "package.json"), "utf-8")
28842
29027
  );
28843
29028
  function createCli() {
28844
29029
  const program3 = new Command();
@@ -28892,6 +29077,15 @@ function createCli() {
28892
29077
  "--set <value>",
28893
29078
  "Set a specific token value (empty string clears auth)"
28894
29079
  ).action(tokenCommand);
29080
+ program3.command("upgrade").description(
29081
+ "Pull the latest Cortex backend image and restart the local stack"
29082
+ ).option(
29083
+ "--dir <path>",
29084
+ "Directory with docker-compose.local.yml (defaults to ~/.cortex-context)"
29085
+ ).option("--embeddings", "Use the embeddings-enabled image variant").option(
29086
+ "--pull-only",
29087
+ "Pull the latest image without recreating the container"
29088
+ ).action(upgradeCommand);
28895
29089
  return program3;
28896
29090
  }
28897
29091