camstack 1.2.164 → 1.2.165

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/cli.js CHANGED
@@ -38,7 +38,7 @@ async function runServe(args) {
38
38
  ...typeof values.data === "string" ? { data: values.data } : {}
39
39
  };
40
40
  Object.assign(process.env, buildServeEnv(opts));
41
- await import("./launcher-BMA4X5ZT.js");
41
+ await import("./launcher-FGWCDMKJ.js");
42
42
  }
43
43
 
44
44
  // src/commands/agent.ts
@@ -83,7 +83,7 @@ async function runAgent(args) {
83
83
  ...typeof values.port === "string" ? { port: values.port } : {}
84
84
  };
85
85
  Object.assign(process.env, buildAgentEnv(opts));
86
- await import("./launcher-BMA4X5ZT.js");
86
+ await import("./launcher-FGWCDMKJ.js");
87
87
  }
88
88
 
89
89
  // src/commands/setup.ts
@@ -6445,6 +6445,62 @@ var require_first_boot_addon_plan = __commonJS({
6445
6445
  }
6446
6446
  });
6447
6447
 
6448
+ // ../../server/backend/dist/core/addon/addon-realign-plan.js
6449
+ var require_addon_realign_plan = __commonJS({
6450
+ "../../server/backend/dist/core/addon/addon-realign-plan.js"(exports) {
6451
+ "use strict";
6452
+ Object.defineProperty(exports, "__esModule", { value: true });
6453
+ exports.planAddonRealignment = planAddonRealignment;
6454
+ function isStrictlyNewer(a, b) {
6455
+ const pa = a.split(".").map((p) => Number.parseInt(p, 10));
6456
+ const pb = b.split(".").map((p) => Number.parseInt(p, 10));
6457
+ const len = Math.max(pa.length, pb.length);
6458
+ for (let i = 0; i < len; i += 1) {
6459
+ const x = pa[i] ?? 0;
6460
+ const y = pb[i] ?? 0;
6461
+ if (!Number.isFinite(x) || !Number.isFinite(y))
6462
+ return false;
6463
+ if (x !== y)
6464
+ return x > y;
6465
+ }
6466
+ return false;
6467
+ }
6468
+ function planAddonRealignment(candidates) {
6469
+ return candidates.map((c) => {
6470
+ if (c.closureVersion === null) {
6471
+ return { pkg: c.pkg, action: "keep", reason: "not carried by this closure" };
6472
+ }
6473
+ if (!isStrictlyNewer(c.closureVersion, c.installedVersion)) {
6474
+ return {
6475
+ pkg: c.pkg,
6476
+ action: "keep",
6477
+ reason: `installed ${c.installedVersion}, closure ${c.closureVersion} \u2014 not strictly newer`
6478
+ };
6479
+ }
6480
+ if (c.installedUpdatedAtMs === null || c.closureLandedAtMs === null) {
6481
+ return {
6482
+ pkg: c.pkg,
6483
+ action: "keep",
6484
+ reason: "cannot date the install or the closure \u2014 an unknown is not evidence of being stale"
6485
+ };
6486
+ }
6487
+ if (c.installedUpdatedAtMs >= c.closureLandedAtMs) {
6488
+ return {
6489
+ pkg: c.pkg,
6490
+ action: "keep",
6491
+ reason: `installed ${c.installedVersion} was deployed AFTER this closure landed \u2014 better informed than ${c.closureVersion}`
6492
+ };
6493
+ }
6494
+ return {
6495
+ pkg: c.pkg,
6496
+ action: "realign",
6497
+ reason: `installed ${c.installedVersion} predates this closure, which carries ${c.closureVersion}`
6498
+ };
6499
+ });
6500
+ }
6501
+ }
6502
+ });
6503
+
6448
6504
  // ../../server/backend/dist/framework-nodepath.js
6449
6505
  var require_framework_nodepath = __commonJS({
6450
6506
  "../../server/backend/dist/framework-nodepath.js"(exports) {
@@ -140227,6 +140283,32 @@ var require_dist3 = __commonJS({
140227
140283
  * into `addonsDir/<pkg>/`. The Electron bundled-addons path
140228
140284
  * uses this so the runtime owns its on-disk copy.
140229
140285
  */
140286
+ /**
140287
+ * Re-install one addon from the running server closure.
140288
+ *
140289
+ * The closure carries a copy of every addon it declares as a dependency, and
140290
+ * NOTHING loads an addon from there — `AddonLoader` reads the addon root and
140291
+ * only the addon root, on every role. So those copies are transport, and
140292
+ * this is the only thing that moves them into the place that runs code.
140293
+ *
140294
+ * Without it a server update advances the closure and changes nothing: six
140295
+ * addons on the hub were behind by up to nineteen versions on 2026-09-17,
140296
+ * each frozen at whenever somebody last ran `camstack deploy`.
140297
+ *
140298
+ * WHICH addons deserve this is not decided here — see `planAddonRealignment`,
140299
+ * which needs two gates because a version comparison alone would overwrite a
140300
+ * deliberate deploy. This only carries out a decision already made.
140301
+ */
140302
+ async realignFromClosure(packageName, closureDir) {
140303
+ const targetDir = node_path.join(this.addonsDir, packageName);
140304
+ const result = await this.installLocal(packageName, closureDir);
140305
+ await node_fs.promises.writeFile(node_path.join(targetDir, ".install-source"), "closure");
140306
+ this.manifest.upsert(result.name, {
140307
+ version: result.version,
140308
+ source: "closure"
140309
+ });
140310
+ return result;
140311
+ }
140230
140312
  async installLocal(packageName, sourceDir) {
140231
140313
  const pkgView = readPackageJson(node_path.join(sourceDir, "package.json"));
140232
140314
  if (!pkgView) throw new Error(`Invalid package.json at ${sourceDir}`);
@@ -306439,9 +306521,7 @@ var require_agent_http = __commonJS({
306439
306521
  }
306440
306522
  return installed?.dir ?? bundled?.dir ?? null;
306441
306523
  }
306442
- function resolveUiDistDir(dataDir, bundledAddonsDir, siblingDistDir = path.resolve(__dirname, "../../addon-agent-ui/dist")) {
306443
- if (fs.existsSync(path.join(siblingDistDir, "index.html")))
306444
- return siblingDistDir;
306524
+ function resolveUiDistDir(dataDir, bundledAddonsDir) {
306445
306525
  const installed = readUiDistCandidate(path.join(dataDir, "addons", "@camstack", "addon-agent-ui"));
306446
306526
  const bundled = bundledAddonsDir ? readUiDistCandidate(path.join(bundledAddonsDir, "addon-agent-ui")) : null;
306447
306527
  const picked = pickUiDist(installed, bundled);
@@ -439897,6 +439977,7 @@ var require_launcher = __commonJS({
439897
439977
  var addon_root_inventory_js_1 = require_addon_root_inventory();
439898
439978
  var bootstrap_packages_js_1 = require_bootstrap_packages();
439899
439979
  var first_boot_addon_plan_js_1 = require_first_boot_addon_plan();
439980
+ var addon_realign_plan_js_1 = require_addon_realign_plan();
439900
439981
  var framework_nodepath_js_1 = require_framework_nodepath();
439901
439982
  var package_inventory_js_1 = require_package_inventory();
439902
439983
  var ARCHIVE_MANIFEST_NAME = ".camstack-backup-manifest.json";
@@ -439996,6 +440077,13 @@ var require_launcher = __commonJS({
439996
440077
  return null;
439997
440078
  }
439998
440079
  }
440080
+ function readDirTimeMs(dir) {
440081
+ try {
440082
+ return fs.statSync(dir).mtimeMs;
440083
+ } catch {
440084
+ return null;
440085
+ }
440086
+ }
439999
440087
  function readInstalledAddonVersions(addonRoot, packages) {
440000
440088
  const out = {};
440001
440089
  for (const name of packages) {
@@ -440094,6 +440182,37 @@ var require_launcher = __commonJS({
440094
440182
  console.warn(`[launcher] first-boot addon plan failed: ${err instanceof Error ? err.message : String(err)}`);
440095
440183
  }
440096
440184
  await installer.ensureRequiredPackages(bootstrapRequired);
440185
+ try {
440186
+ const closureNodeModules = path.resolve(__dirname, "..", "node_modules");
440187
+ const decisions = (0, addon_realign_plan_js_1.planAddonRealignment)(bootstrapRequired.flatMap((pkg) => {
440188
+ const installedVersion = readInstalledAddonVersions(addonsDir, [pkg])[pkg];
440189
+ if (typeof installedVersion !== "string")
440190
+ return [];
440191
+ return [
440192
+ {
440193
+ pkg,
440194
+ installedVersion,
440195
+ installedUpdatedAtMs: readDirTimeMs(path.join(addonsDir, pkg)),
440196
+ closureVersion: readInstalledAddonVersions(closureNodeModules, [pkg])[pkg] ?? null,
440197
+ closureLandedAtMs: readDirTimeMs(path.join(closureNodeModules, pkg))
440198
+ }
440199
+ ];
440200
+ }));
440201
+ for (const d of decisions) {
440202
+ if (d.action !== "realign")
440203
+ continue;
440204
+ try {
440205
+ const done = await installer.realignFromClosure(d.pkg, path.join(closureNodeModules, d.pkg));
440206
+ console.log(`[launcher] re-aligned ${d.pkg} \u2192 ${done.version} \u2014 ${d.reason}`);
440207
+ } catch (err) {
440208
+ console.warn(`[launcher] re-align FAILED for ${d.pkg}: ${err instanceof Error ? err.message : String(err)}`);
440209
+ }
440210
+ }
440211
+ const kept = decisions.filter((d) => d.action === "keep").length;
440212
+ console.log(`[launcher] addon re-alignment: ${decisions.length - kept} re-aligned, ${kept} kept as they are`);
440213
+ } catch (err) {
440214
+ console.warn(`[launcher] addon re-alignment failed: ${err instanceof Error ? err.message : String(err)}`);
440215
+ }
440097
440216
  if (typeof installer.ensureAddonRuntimeDeps === "function") {
440098
440217
  try {
440099
440218
  const depsResult = await installer.ensureAddonRuntimeDeps();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camstack",
3
- "version": "1.2.164",
3
+ "version": "1.2.165",
4
4
  "description": "CLI tool for managing and running CamStack server",
5
5
  "keywords": [
6
6
  "camstack",