@camstack/agent 1.1.18 → 1.1.19

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.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  import { createRequire as __cr } from 'node:module'; const require = globalThis.require ?? __cr(import.meta.url);
3
3
  import {
4
4
  startAgent
5
- } from "./chunk-XEHYJVPH.mjs";
5
+ } from "./chunk-ZGI2MAIL.mjs";
6
6
 
7
7
  // src/cli.ts
8
8
  import { existsSync } from "fs";
package/dist/index.js CHANGED
@@ -643,15 +643,45 @@ var path6 = __toESM(require("path"));
643
643
  var fs4 = __toESM(require("fs"));
644
644
  var path4 = __toESM(require("path"));
645
645
  var import_fastify = __toESM(require("fastify"));
646
- function resolveUiDistDir(dataDir) {
647
- const candidates = [
648
- path4.resolve(__dirname, "../../addon-agent-ui/dist"),
649
- path4.join(dataDir, "addons", "@camstack", "addon-agent-ui", "dist"),
650
- path4.join(dataDir, "agent-ui")
651
- ];
652
- for (const dir of candidates) {
653
- if (fs4.existsSync(path4.join(dir, "index.html"))) return dir;
646
+ function compareVersions(a, b) {
647
+ if (a === null && b === null) return 0;
648
+ if (a === null) return -1;
649
+ if (b === null) return 1;
650
+ const pa = a.split(".").map((s) => Number.parseInt(s, 10) || 0);
651
+ const pb = b.split(".").map((s) => Number.parseInt(s, 10) || 0);
652
+ const len = Math.max(pa.length, pb.length);
653
+ for (let i = 0; i < len; i++) {
654
+ const diff = (pa[i] ?? 0) - (pb[i] ?? 0);
655
+ if (diff !== 0) return diff;
656
+ }
657
+ return 0;
658
+ }
659
+ function readUiDistCandidate(baseDir) {
660
+ const dir = path4.join(baseDir, "dist");
661
+ if (!fs4.existsSync(path4.join(dir, "index.html"))) return null;
662
+ let version = null;
663
+ try {
664
+ const parsed = JSON.parse(fs4.readFileSync(path4.join(baseDir, "package.json"), "utf-8"));
665
+ version = typeof parsed.version === "string" ? parsed.version : null;
666
+ } catch {
667
+ version = null;
668
+ }
669
+ return { dir, version };
670
+ }
671
+ function pickUiDist(installed, bundled) {
672
+ if (installed && bundled) {
673
+ return compareVersions(bundled.version, installed.version) > 0 ? bundled.dir : installed.dir;
654
674
  }
675
+ return installed?.dir ?? bundled?.dir ?? null;
676
+ }
677
+ function resolveUiDistDir(dataDir, bundledAddonsDir, siblingDistDir = path4.resolve(__dirname, "../../addon-agent-ui/dist")) {
678
+ if (fs4.existsSync(path4.join(siblingDistDir, "index.html"))) return siblingDistDir;
679
+ const installed = readUiDistCandidate(path4.join(dataDir, "addons", "@camstack", "addon-agent-ui"));
680
+ const bundled = bundledAddonsDir ? readUiDistCandidate(path4.join(bundledAddonsDir, "addon-agent-ui")) : null;
681
+ const picked = pickUiDist(installed, bundled);
682
+ if (picked) return picked;
683
+ const legacy = path4.join(dataDir, "agent-ui");
684
+ if (fs4.existsSync(path4.join(legacy, "index.html"))) return legacy;
655
685
  return null;
656
686
  }
657
687
  function readConfigFile(configPath) {
@@ -830,19 +860,26 @@ async function createAgentHttpServer(getBroker, config) {
830
860
  const nodes = getRegistryNodes(b);
831
861
  return mapDiscoveredNodes(nodes, b.nodeID);
832
862
  });
833
- const uiDir = resolveUiDistDir(config.dataDir);
863
+ const uiDir = resolveUiDistDir(config.dataDir, process.env["CAMSTACK_BUNDLED_ADDONS_DIR"]);
834
864
  if (uiDir) {
835
865
  const fastifyStatic = await import("@fastify/static");
836
866
  await app.register(fastifyStatic.default, {
837
867
  root: uiDir,
838
868
  prefix: "/",
839
869
  wildcard: false,
840
- decorateReply: false
870
+ // MUST stay true: the SPA-fallback below uses `reply.sendFile`, which
871
+ // only exists when the plugin decorates Reply. With `false` every
872
+ // fallback request 500'd with "reply.sendFile is not a function".
873
+ decorateReply: true
841
874
  });
842
875
  app.setNotFoundHandler(async (req, reply) => {
843
876
  if (req.url.startsWith("/api/") || req.url.startsWith("/health")) {
844
877
  return reply.status(404).send({ error: "Not found" });
845
878
  }
879
+ if (req.url.startsWith("/assets/")) {
880
+ console.warn(`[Agent] UI asset not found (stale index.html?): ${req.url}`);
881
+ return reply.status(404).send({ error: "Asset not found" });
882
+ }
846
883
  return reply.type("text/html").sendFile("index.html");
847
884
  });
848
885
  console.log(`[Agent] UI served from: ${uiDir}`);