@ibm/ixora 0.1.3 → 0.1.4

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.
@@ -6,7 +6,7 @@ import {
6
6
  IXORA_DIR,
7
7
  SYSTEMS_CONFIG,
8
8
  readSystems
9
- } from "./chunk-VCQRSQ4F.js";
9
+ } from "./chunk-WF33SPL6.js";
10
10
 
11
11
  // src/lib/compose.ts
12
12
  import { execa as execa2 } from "execa";
@@ -250,6 +250,7 @@ function section(title) {
250
250
 
251
251
  // src/lib/compose.ts
252
252
  async function runCompose(composeCmd, args, options = {}) {
253
+ const { throwOnError, ...execaOpts } = options;
253
254
  const [bin, subArgs] = getComposeParts(composeCmd);
254
255
  const fullArgs = [
255
256
  ...subArgs,
@@ -264,7 +265,7 @@ async function runCompose(composeCmd, args, options = {}) {
264
265
  try {
265
266
  const result = await execa2(bin, fullArgs, {
266
267
  stdio: "inherit",
267
- ...options
268
+ ...execaOpts
268
269
  });
269
270
  return {
270
271
  stdout: String(result.stdout ?? ""),
@@ -273,6 +274,11 @@ async function runCompose(composeCmd, args, options = {}) {
273
274
  };
274
275
  } catch (err) {
275
276
  const exitCode = err && typeof err === "object" && "exitCode" in err ? err.exitCode : 1;
277
+ if (throwOnError) {
278
+ throw new Error(
279
+ `Compose command failed (exit ${exitCode}): ${args.join(" ")}`
280
+ );
281
+ }
276
282
  error(`Command failed: ${composeCmd} ${args.join(" ")}`);
277
283
  console.log(` Check ${bold("ixora logs")} for details.`);
278
284
  process.exit(exitCode);
@@ -147,21 +147,28 @@ var KNOWN_KEYS = [
147
147
  "DB2_PORT",
148
148
  "IXORA_PROFILE",
149
149
  "IXORA_VERSION",
150
+ "IXORA_PREVIOUS_VERSION",
150
151
  "IXORA_AGENT_MODEL",
151
152
  "IXORA_TEAM_MODEL"
152
153
  ];
153
154
  function writeEnvFile(config, envFile = ENV_FILE) {
154
155
  mkdirSync(dirname(envFile), { recursive: true });
155
156
  let extra = "";
157
+ let prevVersionLine = "";
156
158
  if (existsSync(envFile)) {
157
159
  const existing = readFileSync(envFile, "utf-8");
158
- const extraLines = existing.split("\n").filter((line) => {
160
+ const lines = existing.split("\n");
161
+ const extraLines = lines.filter((line) => {
159
162
  const trimmed = line.trim();
160
163
  if (!trimmed || trimmed.startsWith("#")) return false;
161
164
  const lineKey = trimmed.split("=")[0];
162
165
  return !KNOWN_KEYS.includes(lineKey);
163
166
  });
164
167
  extra = extraLines.join("\n");
168
+ const pvLine = lines.find(
169
+ (l) => l.startsWith("IXORA_PREVIOUS_VERSION=")
170
+ );
171
+ if (pvLine) prevVersionLine = pvLine;
165
172
  }
166
173
  let content = `# Model provider
167
174
  IXORA_AGENT_MODEL='${sqEscape(config.agentModel)}'
@@ -186,6 +193,10 @@ DB2_PORT='${sqEscape(config.db2Port)}'
186
193
  IXORA_PROFILE='${sqEscape(config.profile)}'
187
194
  IXORA_VERSION='${sqEscape(config.version)}'
188
195
  `;
196
+ if (prevVersionLine) {
197
+ content += `${prevVersionLine}
198
+ `;
199
+ }
189
200
  if (extra) {
190
201
  content += `
191
202
  # Preserved user settings
package/dist/index.js CHANGED
@@ -22,7 +22,7 @@ import {
22
22
  waitForHealthy,
23
23
  warn,
24
24
  writeComposeFile
25
- } from "./chunk-4XGJZZ73.js";
25
+ } from "./chunk-6FUV5CEK.js";
26
26
  import {
27
27
  COMPOSE_FILE,
28
28
  ENV_FILE,
@@ -39,7 +39,7 @@ import {
39
39
  systemIdExists,
40
40
  updateEnvKey,
41
41
  writeEnvFile
42
- } from "./chunk-VCQRSQ4F.js";
42
+ } from "./chunk-WF33SPL6.js";
43
43
 
44
44
  // src/cli.ts
45
45
  import { Command } from "commander";
@@ -297,6 +297,12 @@ function normalizeVersion(version) {
297
297
  }
298
298
 
299
299
  // src/commands/upgrade.ts
300
+ function rollback(previousVersion) {
301
+ warn("Rolling back to previous version...");
302
+ updateEnvKey("IXORA_VERSION", previousVersion);
303
+ writeComposeFile();
304
+ info(`Reverted IXORA_VERSION to ${previousVersion}`);
305
+ }
300
306
  async function cmdUpgrade(opts) {
301
307
  try {
302
308
  requireInstalled();
@@ -335,7 +341,8 @@ async function cmdUpgrade(opts) {
335
341
  }))
336
342
  });
337
343
  }
338
- info(`Upgrading ixora: ${previousVersion} \u2192 ${targetVersion}`);
344
+ info(`Upgrading ixora: ${previousVersion} -> ${targetVersion}`);
345
+ updateEnvKey("IXORA_PREVIOUS_VERSION", previousVersion);
339
346
  info("Stopping services...");
340
347
  await runCompose(composeCmd, ["down", "--remove-orphans"]);
341
348
  updateEnvKey("IXORA_VERSION", targetVersion);
@@ -350,13 +357,31 @@ async function cmdUpgrade(opts) {
350
357
  info(`Setting profile: ${opts.profile}`);
351
358
  updateEnvKey("IXORA_PROFILE", opts.profile);
352
359
  }
353
- if (opts.pull !== false) {
354
- info("Pulling images...");
355
- await runCompose(composeCmd, ["pull"]);
360
+ try {
361
+ if (opts.pull !== false) {
362
+ info("Pulling images...");
363
+ await runCompose(composeCmd, ["pull"], { throwOnError: true });
364
+ }
365
+ info("Starting services...");
366
+ await runCompose(composeCmd, ["up", "-d"], { throwOnError: true });
367
+ const healthy = await waitForHealthy(composeCmd);
368
+ if (!healthy) {
369
+ throw new Error(
370
+ "Services did not become healthy after upgrade"
371
+ );
372
+ }
373
+ } catch (err) {
374
+ rollback(previousVersion);
375
+ try {
376
+ await runCompose(composeCmd, ["down", "--remove-orphans"]);
377
+ } catch {
378
+ }
379
+ error(err.message);
380
+ info(
381
+ `Run ${bold("ixora logs")} to investigate, then retry with ${bold(`ixora upgrade ${targetVersion}`)}`
382
+ );
383
+ process.exit(1);
356
384
  }
357
- info("Restarting services...");
358
- await runCompose(composeCmd, ["up", "-d"]);
359
- await waitForHealthy(composeCmd);
360
385
  const profile = envGet("IXORA_PROFILE") || "full";
361
386
  console.log();
362
387
  success("Upgrade complete!");
@@ -703,7 +728,7 @@ async function cmdInstall(opts) {
703
728
  writeEnvFile(envConfig);
704
729
  success("Wrote .env");
705
730
  if (systemIdExists("default")) {
706
- const { removeSystem: removeSystem2 } = await import("./systems-KIQ3KFX3.js");
731
+ const { removeSystem: removeSystem2 } = await import("./systems-CU5LAQOY.js");
707
732
  removeSystem2("default");
708
733
  }
709
734
  addSystem({
@@ -931,7 +956,7 @@ async function cmdSystemAdd() {
931
956
  default: true
932
957
  });
933
958
  if (shouldRestart) {
934
- const { cmdRestart: cmdRestart2 } = await import("./restart-7ECL2NPC.js");
959
+ const { cmdRestart: cmdRestart2 } = await import("./restart-YKLSM7VV.js");
935
960
  await cmdRestart2({});
936
961
  } else {
937
962
  console.log(` Restart to apply: ${bold("ixora restart")}`);
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  cmdRestart
4
- } from "./chunk-4XGJZZ73.js";
5
- import "./chunk-VCQRSQ4F.js";
4
+ } from "./chunk-6FUV5CEK.js";
5
+ import "./chunk-WF33SPL6.js";
6
6
  export {
7
7
  cmdRestart
8
8
  };
@@ -6,7 +6,7 @@ import {
6
6
  systemCount,
7
7
  systemIdExists,
8
8
  totalSystemCount
9
- } from "./chunk-VCQRSQ4F.js";
9
+ } from "./chunk-WF33SPL6.js";
10
10
  export {
11
11
  addSystem,
12
12
  readSystems,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ibm/ixora",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "CLI for managing ixora AI agent deployments on IBM i",
5
5
  "type": "module",
6
6
  "bin": {