quoroom 0.1.36 → 0.1.38

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/README.md CHANGED
@@ -457,6 +457,11 @@ npm install # Install dependencies
457
457
  npm run build # Typecheck + bundle MCP server + build UI
458
458
  npm run build:mcp # Bundle MCP server only (esbuild)
459
459
  npm run build:ui # Build UI SPA only (Vite)
460
+ npm run dev # Local-only dev (links + room)
461
+ npm run dev:with-cloud # Local dev + cloud (requires ../cloud)
462
+ npm run dev:isolated # Isolated local dev (room :4700 + UI, no cloud)
463
+ npm run dev:isolated:with-cloud # Isolated local dev + cloud
464
+ npm run dev:cloud # Cloud-only (runs ../cloud on :3715)
460
465
  npm run dev:ui # UI dev server with hot reload
461
466
  npm run typecheck # Type-check only (tsc --noEmit)
462
467
  npm test # Run all tests (vitest, fork pool)
@@ -464,7 +469,10 @@ npm run test:watch # Watch mode
464
469
  npm run test:e2e # End-to-end tests (Playwright)
465
470
 
466
471
  # Windows
472
+ npm run dev:win # Local-only dev (same as npm run dev)
473
+ npm run dev:with-cloud:win # Local dev + cloud (requires ../cloud)
467
474
  npm run dev:isolated:win # Windows equivalent of dev:isolated
475
+ npm run dev:isolated:with-cloud:win # Windows isolated + cloud
468
476
  npm run build:windows:local # Local Windows build (PowerShell)
469
477
  ```
470
478
 
@@ -9914,7 +9914,7 @@ var require_package = __commonJS({
9914
9914
  "package.json"(exports2, module2) {
9915
9915
  module2.exports = {
9916
9916
  name: "quoroom",
9917
- version: "0.1.36",
9917
+ version: "0.1.38",
9918
9918
  description: "Open-source local AI agent framework \u2014 Queen, Workers, Quorum. Experimental research tool.",
9919
9919
  main: "./out/mcp/server.js",
9920
9920
  bin: {
@@ -9938,22 +9938,26 @@ var require_package = __commonJS({
9938
9938
  "build:parallel": "node scripts/build-parallel.js",
9939
9939
  "build:fast": "node scripts/build-parallel.js --skip-typecheck",
9940
9940
  "build:mcp": "node scripts/build-mcp.js",
9941
- "build:ui": "vite build --config src/ui/vite.config.ts && node scripts/copy-ui-to-app.js",
9941
+ "build:ui": "vite build --config src/ui/vite.config.ts",
9942
9942
  "kill:ports": "node scripts/kill-ports.js",
9943
9943
  "kill:dev-ports": "npm run kill:ports -- 3700 3702 4700 3715 5173 5174",
9944
9944
  "kill:quoroom-runtime": "node scripts/kill-quoroom-runtime.js",
9945
9945
  "kill:dev-runtime": "npm run kill:dev-ports && npm run kill:quoroom-runtime",
9946
9946
  "dev:links": "node scripts/dev-links.js",
9947
- dev: `sh -c 'npm run kill:dev-runtime && trap "kill 0" INT TERM EXIT; npm run dev:links & npm run dev:room & npm run dev:cloud & wait'`,
9947
+ dev: "node scripts/run-dev.js",
9948
9948
  "dev:win": "node scripts/run-dev.js",
9949
+ "dev:with-cloud": "node scripts/run-dev.js --with-cloud",
9950
+ "dev:with-cloud:win": "node scripts/run-dev.js --with-cloud",
9949
9951
  "dev:room": "sh -c 'npm run kill:dev-runtime && export QUOROOM_DATA_DIR=$HOME/.quoroom-dev QUOROOM_SKIP_MCP_REGISTER=1; npm run build:mcp && npm run build:ui && node scripts/dev-server.js --port 4700'",
9950
9952
  "dev:room:win": "node scripts/dev-room.js --port 4700",
9951
9953
  "dev:room:isolated:win": "node scripts/dev-room.js --isolated --port 4700",
9952
9954
  "dev:room:isolated": "sh -c 'npm run kill:dev-runtime && export QUOROOM_DATA_DIR=$HOME/.quoroom-dev QUOROOM_SKIP_MCP_REGISTER=1; npm run build:mcp && npm run build:ui && node scripts/dev-server.js --port 4700'",
9953
9955
  "dev:room:shared": "npm run kill:dev-runtime && npm run build:mcp && npm run build:ui && node scripts/dev-server.js",
9954
9956
  "doctor:split": "node scripts/doctor-split.js",
9955
- "dev:isolated": `sh -c 'npm run kill:dev-runtime && trap "kill 0" INT TERM EXIT; npm run dev:links & npm run dev:room:isolated & npm run dev:cloud & VITE_API_PORT=4700 npm run dev:ui & wait'`,
9957
+ "dev:isolated": "node scripts/run-dev.js --isolated",
9956
9958
  "dev:isolated:win": "node scripts/run-dev.js --isolated",
9959
+ "dev:isolated:with-cloud": "node scripts/run-dev.js --isolated --with-cloud",
9960
+ "dev:isolated:with-cloud:win": "node scripts/run-dev.js --isolated --with-cloud",
9957
9961
  "dev:cloud": `sh -c 'npm run kill:ports -- 3715 && cd ../cloud && PORT=3715 CLOUD_PUBLIC_URL=http://127.0.0.1:3715 CLOUD_ALLOWED_ORIGINS='"'"'http://127.0.0.1:3715,http://localhost:3715,http://localhost:5173,http://127.0.0.1:5173,https://quoroom.ai,https://www.quoroom.ai,https://app.quoroom.ai'"'"' npm start'`,
9958
9962
  "dev:cloud:win": "node scripts/dev-cloud.js",
9959
9963
  "dev:ui": "vite --config src/ui/vite.config.ts",
@@ -10928,6 +10932,7 @@ var require_node_cron = __commonJS({
10928
10932
  var index_exports = {};
10929
10933
  __export(index_exports, {
10930
10934
  _isLoopbackAddress: () => isLoopbackAddress,
10935
+ _resolveStaticDirForStart: () => resolveStaticDirForStart,
10931
10936
  _shellQuote: () => shellQuote,
10932
10937
  _windowsQuote: () => windowsQuote,
10933
10938
  createApiServer: () => createApiServer,
@@ -32381,6 +32386,13 @@ function getAutoUpdateStatus() {
32381
32386
  return status;
32382
32387
  }
32383
32388
  function initBootHealthCheck() {
32389
+ if (import_node_fs4.default.existsSync(USER_APP_DIR) && !import_node_fs4.default.existsSync(VERSION_FILE)) {
32390
+ try {
32391
+ console.error("[auto-update] Removing legacy unversioned user app cache");
32392
+ import_node_fs4.default.rmSync(USER_APP_DIR, { recursive: true, force: true });
32393
+ } catch {
32394
+ }
32395
+ }
32384
32396
  if (import_node_fs4.default.existsSync(VERSION_FILE)) {
32385
32397
  try {
32386
32398
  const info = JSON.parse(import_node_fs4.default.readFileSync(VERSION_FILE, "utf-8"));
@@ -32508,7 +32520,7 @@ function semverGt(a, b) {
32508
32520
  }
32509
32521
  function getCurrentVersion() {
32510
32522
  try {
32511
- return true ? "0.1.36" : null.version;
32523
+ return true ? "0.1.38" : null.version;
32512
32524
  } catch {
32513
32525
  return "0.0.0";
32514
32526
  }
@@ -32689,7 +32701,7 @@ var cachedVersion = null;
32689
32701
  function getVersion3() {
32690
32702
  if (cachedVersion) return cachedVersion;
32691
32703
  try {
32692
- cachedVersion = true ? "0.1.36" : null.version;
32704
+ cachedVersion = true ? "0.1.38" : null.version;
32693
32705
  } catch {
32694
32706
  cachedVersion = "unknown";
32695
32707
  }
@@ -34609,6 +34621,11 @@ var MIME_TYPES = {
34609
34621
  ".webp": "image/webp",
34610
34622
  ".webmanifest": "application/manifest+json"
34611
34623
  };
34624
+ var NO_CACHE_RESPONSE_HEADERS = {
34625
+ "Cache-Control": "no-cache, no-store, must-revalidate",
34626
+ "Pragma": "no-cache",
34627
+ "Expires": "0"
34628
+ };
34612
34629
  var PROFILE_HTTP = process.env.QUOROOM_PROFILE_HTTP === "1";
34613
34630
  var PROFILE_HTTP_SLOW_MS = Math.max(1, Number.parseInt(process.env.QUOROOM_PROFILE_HTTP_SLOW_MS ?? "300", 10) || 300);
34614
34631
  var PROFILE_HTTP_ENDPOINTS = /* @__PURE__ */ new Set([
@@ -34634,26 +34651,6 @@ function maybeLogHttpProfile(method, pathname, statusCode, durationMs) {
34634
34651
  const slowMark = durationMs >= PROFILE_HTTP_SLOW_MS ? " SLOW" : "";
34635
34652
  console.error(`[http-prof] ${method} ${normalized} -> ${statusCode} (${durationMs}ms)${slowMark}`);
34636
34653
  }
34637
- function getCacheControl(filePath, ext) {
34638
- const normalized = filePath.replace(/\\/g, "/");
34639
- const base2 = import_node_path9.default.basename(filePath);
34640
- if (base2 === "sw.js") return "no-cache, no-store, must-revalidate";
34641
- if (ext === ".html") return "no-cache, no-store, must-revalidate";
34642
- if (ext === ".webmanifest") return "public, max-age=3600";
34643
- if (base2 === "social.png" || base2.startsWith("social-")) {
34644
- return "no-cache, max-age=0, must-revalidate";
34645
- }
34646
- if (normalized.includes("/assets/") && /-[A-Za-z0-9_-]{8,}\./.test(base2)) {
34647
- return "public, max-age=31536000, immutable";
34648
- }
34649
- if (base2.startsWith("icon-") || base2 === "apple-touch-icon.png" || [".png", ".jpg", ".jpeg", ".svg", ".ico", ".webp", ".woff", ".woff2"].includes(ext)) {
34650
- return "public, max-age=604800";
34651
- }
34652
- if (ext === ".js" || ext === ".css") {
34653
- return "public, max-age=3600";
34654
- }
34655
- return "no-cache, max-age=0";
34656
- }
34657
34654
  function serveStatic(staticDir, pathname, res) {
34658
34655
  const safePath = import_node_path9.default.normalize(pathname).replace(/^(\.\.[/\\])+/, "");
34659
34656
  let filePath = import_node_path9.default.join(staticDir, safePath);
@@ -34666,7 +34663,7 @@ function serveStatic(staticDir, pathname, res) {
34666
34663
  if (import_node_path9.default.extname(safePath)) {
34667
34664
  res.writeHead(404, {
34668
34665
  "Content-Type": "text/plain; charset=utf-8",
34669
- "Cache-Control": "no-cache, no-store, must-revalidate"
34666
+ ...NO_CACHE_RESPONSE_HEADERS
34670
34667
  });
34671
34668
  res.end("Not Found");
34672
34669
  return;
@@ -34677,8 +34674,9 @@ function serveStatic(staticDir, pathname, res) {
34677
34674
  const contentType = MIME_TYPES[ext] ?? "application/octet-stream";
34678
34675
  const headers = {
34679
34676
  "Content-Type": contentType,
34680
- "Cache-Control": getCacheControl(filePath, ext)
34677
+ ...NO_CACHE_RESPONSE_HEADERS
34681
34678
  };
34679
+ if (ext === ".html") headers["Clear-Site-Data"] = '"cache"';
34682
34680
  const stream = import_node_fs6.default.createReadStream(filePath);
34683
34681
  stream.on("open", () => {
34684
34682
  res.writeHead(200, headers);
@@ -34686,11 +34684,26 @@ function serveStatic(staticDir, pathname, res) {
34686
34684
  });
34687
34685
  stream.on("error", () => {
34688
34686
  if (!res.headersSent) {
34689
- res.writeHead(404, { "Content-Type": "text/plain" });
34687
+ res.writeHead(404, {
34688
+ "Content-Type": "text/plain; charset=utf-8",
34689
+ ...NO_CACHE_RESPONSE_HEADERS
34690
+ });
34690
34691
  }
34691
34692
  res.end("Not Found");
34692
34693
  });
34693
34694
  }
34695
+ function resolveStaticDirForStart() {
34696
+ const userUiDir = import_node_path9.default.join(USER_APP_DIR, "ui");
34697
+ const bundledUiDir = import_node_path9.default.join(__dirname, "../ui");
34698
+ const readyVersion = getReadyUpdateVersion();
34699
+ if (readyVersion && import_node_fs6.default.existsSync(import_node_path9.default.join(userUiDir, "index.html"))) {
34700
+ return userUiDir;
34701
+ }
34702
+ if (import_node_fs6.default.existsSync(bundledUiDir)) {
34703
+ return bundledUiDir;
34704
+ }
34705
+ return void 0;
34706
+ }
34694
34707
  var RATE_LIMIT_WINDOW_MS2 = 6e4;
34695
34708
  var RATE_LIMIT_READ = 300;
34696
34709
  var RATE_LIMIT_WRITE = 120;
@@ -34748,14 +34761,15 @@ function createApiServer(options = {}) {
34748
34761
  });
34749
34762
  }
34750
34763
  if (req.method === "OPTIONS") {
34751
- const headers = {};
34764
+ const headers = { ...NO_CACHE_RESPONSE_HEADERS };
34752
34765
  setCorsHeaders(origin, headers);
34753
34766
  res.writeHead(204, headers);
34754
34767
  res.end();
34755
34768
  return;
34756
34769
  }
34757
34770
  const responseHeaders = {
34758
- "Content-Type": "application/json"
34771
+ "Content-Type": "application/json",
34772
+ ...NO_CACHE_RESPONSE_HEADERS
34759
34773
  };
34760
34774
  if (isCloudDeployment()) {
34761
34775
  Object.assign(responseHeaders, CLOUD_SECURITY_HEADERS);
@@ -34785,10 +34799,7 @@ function createApiServer(options = {}) {
34785
34799
  }
34786
34800
  if (pathname === "/api/auth/handshake" && req.method === "GET") {
34787
34801
  const handshakeHeaders = {
34788
- ...responseHeaders,
34789
- "Cache-Control": "no-store, no-cache, must-revalidate, proxy-revalidate",
34790
- "Pragma": "no-cache",
34791
- "Expires": "0"
34802
+ ...responseHeaders
34792
34803
  };
34793
34804
  if (isCloudDeployment()) {
34794
34805
  res.writeHead(403, handshakeHeaders);
@@ -34954,7 +34965,10 @@ function createApiServer(options = {}) {
34954
34965
  if (options.staticDir) {
34955
34966
  serveStatic(options.staticDir, pathname, res);
34956
34967
  } else {
34957
- res.writeHead(404, { "Content-Type": "text/plain" });
34968
+ res.writeHead(404, {
34969
+ "Content-Type": "text/plain; charset=utf-8",
34970
+ ...NO_CACHE_RESPONSE_HEADERS
34971
+ });
34958
34972
  res.end("Not Found");
34959
34973
  }
34960
34974
  });
@@ -35068,13 +35082,7 @@ function startServer(options = {}) {
35068
35082
  const bindHost = process.env.QUOROOM_BIND_HOST || (deploymentMode === "cloud" ? DEFAULT_BIND_HOST_CLOUD : DEFAULT_BIND_HOST_LOCAL);
35069
35083
  initBootHealthCheck();
35070
35084
  if (!options.staticDir) {
35071
- const userUiDir = import_node_path9.default.join(USER_APP_DIR, "ui");
35072
- const bundledUiDir = import_node_path9.default.join(__dirname, "../ui");
35073
- if (import_node_fs6.default.existsSync(import_node_path9.default.join(userUiDir, "index.html"))) {
35074
- options.staticDir = userUiDir;
35075
- } else if (import_node_fs6.default.existsSync(bundledUiDir)) {
35076
- options.staticDir = bundledUiDir;
35077
- }
35085
+ options.staticDir = resolveStaticDirForStart();
35078
35086
  }
35079
35087
  const dbPath = process.env.QUOROOM_DB_PATH || import_node_path9.default.join(options.dataDir ?? getDataDir(), "data.db");
35080
35088
  const { server, token, db: serverDb } = createApiServer(options);
@@ -35171,6 +35179,7 @@ function startServer(options = {}) {
35171
35179
  // Annotate the CommonJS export names for ESM import in node:
35172
35180
  0 && (module.exports = {
35173
35181
  _isLoopbackAddress,
35182
+ _resolveStaticDirForStart,
35174
35183
  _shellQuote,
35175
35184
  _windowsQuote,
35176
35185
  createApiServer,
package/out/mcp/cli.js CHANGED
@@ -52537,7 +52537,7 @@ var server_exports = {};
52537
52537
  async function main() {
52538
52538
  const server = new McpServer({
52539
52539
  name: "quoroom",
52540
- version: true ? "0.1.36" : "0.0.0"
52540
+ version: true ? "0.1.38" : "0.0.0"
52541
52541
  });
52542
52542
  registerMemoryTools(server);
52543
52543
  registerSchedulerTools(server);
@@ -54189,7 +54189,7 @@ var require_package = __commonJS({
54189
54189
  "package.json"(exports2, module2) {
54190
54190
  module2.exports = {
54191
54191
  name: "quoroom",
54192
- version: "0.1.36",
54192
+ version: "0.1.38",
54193
54193
  description: "Open-source local AI agent framework \u2014 Queen, Workers, Quorum. Experimental research tool.",
54194
54194
  main: "./out/mcp/server.js",
54195
54195
  bin: {
@@ -54213,22 +54213,26 @@ var require_package = __commonJS({
54213
54213
  "build:parallel": "node scripts/build-parallel.js",
54214
54214
  "build:fast": "node scripts/build-parallel.js --skip-typecheck",
54215
54215
  "build:mcp": "node scripts/build-mcp.js",
54216
- "build:ui": "vite build --config src/ui/vite.config.ts && node scripts/copy-ui-to-app.js",
54216
+ "build:ui": "vite build --config src/ui/vite.config.ts",
54217
54217
  "kill:ports": "node scripts/kill-ports.js",
54218
54218
  "kill:dev-ports": "npm run kill:ports -- 3700 3702 4700 3715 5173 5174",
54219
54219
  "kill:quoroom-runtime": "node scripts/kill-quoroom-runtime.js",
54220
54220
  "kill:dev-runtime": "npm run kill:dev-ports && npm run kill:quoroom-runtime",
54221
54221
  "dev:links": "node scripts/dev-links.js",
54222
- dev: `sh -c 'npm run kill:dev-runtime && trap "kill 0" INT TERM EXIT; npm run dev:links & npm run dev:room & npm run dev:cloud & wait'`,
54222
+ dev: "node scripts/run-dev.js",
54223
54223
  "dev:win": "node scripts/run-dev.js",
54224
+ "dev:with-cloud": "node scripts/run-dev.js --with-cloud",
54225
+ "dev:with-cloud:win": "node scripts/run-dev.js --with-cloud",
54224
54226
  "dev:room": "sh -c 'npm run kill:dev-runtime && export QUOROOM_DATA_DIR=$HOME/.quoroom-dev QUOROOM_SKIP_MCP_REGISTER=1; npm run build:mcp && npm run build:ui && node scripts/dev-server.js --port 4700'",
54225
54227
  "dev:room:win": "node scripts/dev-room.js --port 4700",
54226
54228
  "dev:room:isolated:win": "node scripts/dev-room.js --isolated --port 4700",
54227
54229
  "dev:room:isolated": "sh -c 'npm run kill:dev-runtime && export QUOROOM_DATA_DIR=$HOME/.quoroom-dev QUOROOM_SKIP_MCP_REGISTER=1; npm run build:mcp && npm run build:ui && node scripts/dev-server.js --port 4700'",
54228
54230
  "dev:room:shared": "npm run kill:dev-runtime && npm run build:mcp && npm run build:ui && node scripts/dev-server.js",
54229
54231
  "doctor:split": "node scripts/doctor-split.js",
54230
- "dev:isolated": `sh -c 'npm run kill:dev-runtime && trap "kill 0" INT TERM EXIT; npm run dev:links & npm run dev:room:isolated & npm run dev:cloud & VITE_API_PORT=4700 npm run dev:ui & wait'`,
54232
+ "dev:isolated": "node scripts/run-dev.js --isolated",
54231
54233
  "dev:isolated:win": "node scripts/run-dev.js --isolated",
54234
+ "dev:isolated:with-cloud": "node scripts/run-dev.js --isolated --with-cloud",
54235
+ "dev:isolated:with-cloud:win": "node scripts/run-dev.js --isolated --with-cloud",
54232
54236
  "dev:cloud": `sh -c 'npm run kill:ports -- 3715 && cd ../cloud && PORT=3715 CLOUD_PUBLIC_URL=http://127.0.0.1:3715 CLOUD_ALLOWED_ORIGINS='"'"'http://127.0.0.1:3715,http://localhost:3715,http://localhost:5173,http://127.0.0.1:5173,https://quoroom.ai,https://www.quoroom.ai,https://app.quoroom.ai'"'"' npm start'`,
54233
54237
  "dev:cloud:win": "node scripts/dev-cloud.js",
54234
54238
  "dev:ui": "vite --config src/ui/vite.config.ts",
@@ -59621,6 +59625,13 @@ function getAutoUpdateStatus() {
59621
59625
  return status;
59622
59626
  }
59623
59627
  function initBootHealthCheck() {
59628
+ if (import_node_fs4.default.existsSync(USER_APP_DIR) && !import_node_fs4.default.existsSync(VERSION_FILE)) {
59629
+ try {
59630
+ console.error("[auto-update] Removing legacy unversioned user app cache");
59631
+ import_node_fs4.default.rmSync(USER_APP_DIR, { recursive: true, force: true });
59632
+ } catch {
59633
+ }
59634
+ }
59624
59635
  if (import_node_fs4.default.existsSync(VERSION_FILE)) {
59625
59636
  try {
59626
59637
  const info = JSON.parse(import_node_fs4.default.readFileSync(VERSION_FILE, "utf-8"));
@@ -59748,7 +59759,7 @@ function semverGt(a, b) {
59748
59759
  }
59749
59760
  function getCurrentVersion() {
59750
59761
  try {
59751
- return true ? "0.1.36" : null.version;
59762
+ return true ? "0.1.38" : null.version;
59752
59763
  } catch {
59753
59764
  return "0.0.0";
59754
59765
  }
@@ -59955,7 +59966,7 @@ var init_updateChecker = __esm({
59955
59966
  function getVersion3() {
59956
59967
  if (cachedVersion) return cachedVersion;
59957
59968
  try {
59958
- cachedVersion = true ? "0.1.36" : null.version;
59969
+ cachedVersion = true ? "0.1.38" : null.version;
59959
59970
  } catch {
59960
59971
  cachedVersion = "unknown";
59961
59972
  }
@@ -65441,6 +65452,7 @@ var init_shell_path = __esm({
65441
65452
  var server_exports2 = {};
65442
65453
  __export(server_exports2, {
65443
65454
  _isLoopbackAddress: () => isLoopbackAddress,
65455
+ _resolveStaticDirForStart: () => resolveStaticDirForStart,
65444
65456
  _shellQuote: () => shellQuote,
65445
65457
  _windowsQuote: () => windowsQuote,
65446
65458
  createApiServer: () => createApiServer,
@@ -65615,26 +65627,6 @@ function maybeLogHttpProfile(method, pathname, statusCode, durationMs) {
65615
65627
  const slowMark = durationMs >= PROFILE_HTTP_SLOW_MS ? " SLOW" : "";
65616
65628
  console.error(`[http-prof] ${method} ${normalized} -> ${statusCode} (${durationMs}ms)${slowMark}`);
65617
65629
  }
65618
- function getCacheControl(filePath, ext) {
65619
- const normalized = filePath.replace(/\\/g, "/");
65620
- const base2 = import_node_path9.default.basename(filePath);
65621
- if (base2 === "sw.js") return "no-cache, no-store, must-revalidate";
65622
- if (ext === ".html") return "no-cache, no-store, must-revalidate";
65623
- if (ext === ".webmanifest") return "public, max-age=3600";
65624
- if (base2 === "social.png" || base2.startsWith("social-")) {
65625
- return "no-cache, max-age=0, must-revalidate";
65626
- }
65627
- if (normalized.includes("/assets/") && /-[A-Za-z0-9_-]{8,}\./.test(base2)) {
65628
- return "public, max-age=31536000, immutable";
65629
- }
65630
- if (base2.startsWith("icon-") || base2 === "apple-touch-icon.png" || [".png", ".jpg", ".jpeg", ".svg", ".ico", ".webp", ".woff", ".woff2"].includes(ext)) {
65631
- return "public, max-age=604800";
65632
- }
65633
- if (ext === ".js" || ext === ".css") {
65634
- return "public, max-age=3600";
65635
- }
65636
- return "no-cache, max-age=0";
65637
- }
65638
65630
  function serveStatic(staticDir, pathname, res) {
65639
65631
  const safePath = import_node_path9.default.normalize(pathname).replace(/^(\.\.[/\\])+/, "");
65640
65632
  let filePath = import_node_path9.default.join(staticDir, safePath);
@@ -65647,7 +65639,7 @@ function serveStatic(staticDir, pathname, res) {
65647
65639
  if (import_node_path9.default.extname(safePath)) {
65648
65640
  res.writeHead(404, {
65649
65641
  "Content-Type": "text/plain; charset=utf-8",
65650
- "Cache-Control": "no-cache, no-store, must-revalidate"
65642
+ ...NO_CACHE_RESPONSE_HEADERS
65651
65643
  });
65652
65644
  res.end("Not Found");
65653
65645
  return;
@@ -65658,8 +65650,9 @@ function serveStatic(staticDir, pathname, res) {
65658
65650
  const contentType = MIME_TYPES[ext] ?? "application/octet-stream";
65659
65651
  const headers = {
65660
65652
  "Content-Type": contentType,
65661
- "Cache-Control": getCacheControl(filePath, ext)
65653
+ ...NO_CACHE_RESPONSE_HEADERS
65662
65654
  };
65655
+ if (ext === ".html") headers["Clear-Site-Data"] = '"cache"';
65663
65656
  const stream = import_node_fs6.default.createReadStream(filePath);
65664
65657
  stream.on("open", () => {
65665
65658
  res.writeHead(200, headers);
@@ -65667,11 +65660,26 @@ function serveStatic(staticDir, pathname, res) {
65667
65660
  });
65668
65661
  stream.on("error", () => {
65669
65662
  if (!res.headersSent) {
65670
- res.writeHead(404, { "Content-Type": "text/plain" });
65663
+ res.writeHead(404, {
65664
+ "Content-Type": "text/plain; charset=utf-8",
65665
+ ...NO_CACHE_RESPONSE_HEADERS
65666
+ });
65671
65667
  }
65672
65668
  res.end("Not Found");
65673
65669
  });
65674
65670
  }
65671
+ function resolveStaticDirForStart() {
65672
+ const userUiDir = import_node_path9.default.join(USER_APP_DIR, "ui");
65673
+ const bundledUiDir = import_node_path9.default.join(__dirname, "../ui");
65674
+ const readyVersion = getReadyUpdateVersion();
65675
+ if (readyVersion && import_node_fs6.default.existsSync(import_node_path9.default.join(userUiDir, "index.html"))) {
65676
+ return userUiDir;
65677
+ }
65678
+ if (import_node_fs6.default.existsSync(bundledUiDir)) {
65679
+ return bundledUiDir;
65680
+ }
65681
+ return void 0;
65682
+ }
65675
65683
  function checkRateLimit2(ip, method) {
65676
65684
  const isWrite = method !== "GET" && method !== "HEAD" && method !== "OPTIONS";
65677
65685
  const limit = isWrite ? RATE_LIMIT_WRITE : RATE_LIMIT_READ;
@@ -65713,14 +65721,15 @@ function createApiServer(options = {}) {
65713
65721
  });
65714
65722
  }
65715
65723
  if (req.method === "OPTIONS") {
65716
- const headers = {};
65724
+ const headers = { ...NO_CACHE_RESPONSE_HEADERS };
65717
65725
  setCorsHeaders(origin, headers);
65718
65726
  res.writeHead(204, headers);
65719
65727
  res.end();
65720
65728
  return;
65721
65729
  }
65722
65730
  const responseHeaders = {
65723
- "Content-Type": "application/json"
65731
+ "Content-Type": "application/json",
65732
+ ...NO_CACHE_RESPONSE_HEADERS
65724
65733
  };
65725
65734
  if (isCloudDeployment()) {
65726
65735
  Object.assign(responseHeaders, CLOUD_SECURITY_HEADERS);
@@ -65750,10 +65759,7 @@ function createApiServer(options = {}) {
65750
65759
  }
65751
65760
  if (pathname === "/api/auth/handshake" && req.method === "GET") {
65752
65761
  const handshakeHeaders = {
65753
- ...responseHeaders,
65754
- "Cache-Control": "no-store, no-cache, must-revalidate, proxy-revalidate",
65755
- "Pragma": "no-cache",
65756
- "Expires": "0"
65762
+ ...responseHeaders
65757
65763
  };
65758
65764
  if (isCloudDeployment()) {
65759
65765
  res.writeHead(403, handshakeHeaders);
@@ -65919,7 +65925,10 @@ function createApiServer(options = {}) {
65919
65925
  if (options.staticDir) {
65920
65926
  serveStatic(options.staticDir, pathname, res);
65921
65927
  } else {
65922
- res.writeHead(404, { "Content-Type": "text/plain" });
65928
+ res.writeHead(404, {
65929
+ "Content-Type": "text/plain; charset=utf-8",
65930
+ ...NO_CACHE_RESPONSE_HEADERS
65931
+ });
65923
65932
  res.end("Not Found");
65924
65933
  }
65925
65934
  });
@@ -66033,13 +66042,7 @@ function startServer(options = {}) {
66033
66042
  const bindHost = process.env.QUOROOM_BIND_HOST || (deploymentMode === "cloud" ? DEFAULT_BIND_HOST_CLOUD : DEFAULT_BIND_HOST_LOCAL);
66034
66043
  initBootHealthCheck();
66035
66044
  if (!options.staticDir) {
66036
- const userUiDir = import_node_path9.default.join(USER_APP_DIR, "ui");
66037
- const bundledUiDir = import_node_path9.default.join(__dirname, "../ui");
66038
- if (import_node_fs6.default.existsSync(import_node_path9.default.join(userUiDir, "index.html"))) {
66039
- options.staticDir = userUiDir;
66040
- } else if (import_node_fs6.default.existsSync(bundledUiDir)) {
66041
- options.staticDir = bundledUiDir;
66042
- }
66045
+ options.staticDir = resolveStaticDirForStart();
66043
66046
  }
66044
66047
  const dbPath = process.env.QUOROOM_DB_PATH || import_node_path9.default.join(options.dataDir ?? getDataDir(), "data.db");
66045
66048
  const { server, token, db: serverDb } = createApiServer(options);
@@ -66133,7 +66136,7 @@ function startServer(options = {}) {
66133
66136
  process.on("SIGINT", () => shutdown(0));
66134
66137
  process.on("SIGTERM", () => shutdown(0));
66135
66138
  }
66136
- var import_node_http2, import_node_https3, import_node_url, import_node_fs6, import_node_path9, import_node_os8, import_node_child_process8, DEFAULT_PORT, DEFAULT_BIND_HOST_LOCAL, DEFAULT_BIND_HOST_CLOUD, requestProcessShutdown, MIME_TYPES, PROFILE_HTTP, PROFILE_HTTP_SLOW_MS, PROFILE_HTTP_ENDPOINTS, RATE_LIMIT_WINDOW_MS2, RATE_LIMIT_READ, RATE_LIMIT_WRITE, rateBuckets2, CLOUD_SECURITY_HEADERS;
66139
+ var import_node_http2, import_node_https3, import_node_url, import_node_fs6, import_node_path9, import_node_os8, import_node_child_process8, DEFAULT_PORT, DEFAULT_BIND_HOST_LOCAL, DEFAULT_BIND_HOST_CLOUD, requestProcessShutdown, MIME_TYPES, NO_CACHE_RESPONSE_HEADERS, PROFILE_HTTP, PROFILE_HTTP_SLOW_MS, PROFILE_HTTP_ENDPOINTS, RATE_LIMIT_WINDOW_MS2, RATE_LIMIT_READ, RATE_LIMIT_WRITE, rateBuckets2, CLOUD_SECURITY_HEADERS;
66137
66140
  var init_server4 = __esm({
66138
66141
  "src/server/index.ts"() {
66139
66142
  "use strict";
@@ -66184,6 +66187,11 @@ var init_server4 = __esm({
66184
66187
  ".webp": "image/webp",
66185
66188
  ".webmanifest": "application/manifest+json"
66186
66189
  };
66190
+ NO_CACHE_RESPONSE_HEADERS = {
66191
+ "Cache-Control": "no-cache, no-store, must-revalidate",
66192
+ "Pragma": "no-cache",
66193
+ "Expires": "0"
66194
+ };
66187
66195
  PROFILE_HTTP = process.env.QUOROOM_PROFILE_HTTP === "1";
66188
66196
  PROFILE_HTTP_SLOW_MS = Math.max(1, Number.parseInt(process.env.QUOROOM_PROFILE_HTTP_SLOW_MS ?? "300", 10) || 300);
66189
66197
  PROFILE_HTTP_ENDPOINTS = /* @__PURE__ */ new Set([
@@ -66224,7 +66232,7 @@ __export(update_exports, {
66224
66232
  });
66225
66233
  function getCurrentVersion2() {
66226
66234
  try {
66227
- return true ? "0.1.36" : null.version;
66235
+ return true ? "0.1.38" : null.version;
66228
66236
  } catch {
66229
66237
  return "0.0.0";
66230
66238
  }
package/out/mcp/server.js CHANGED
@@ -49085,7 +49085,7 @@ init_db();
49085
49085
  async function main() {
49086
49086
  const server = new McpServer({
49087
49087
  name: "quoroom",
49088
- version: true ? "0.1.36" : "0.0.0"
49088
+ version: true ? "0.1.38" : "0.0.0"
49089
49089
  });
49090
49090
  registerMemoryTools(server);
49091
49091
  registerSchedulerTools(server);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quoroom",
3
- "version": "0.1.36",
3
+ "version": "0.1.38",
4
4
  "description": "Open-source local AI agent framework — Queen, Workers, Quorum. Experimental research tool.",
5
5
  "main": "./out/mcp/server.js",
6
6
  "bin": {
@@ -24,22 +24,26 @@
24
24
  "build:parallel": "node scripts/build-parallel.js",
25
25
  "build:fast": "node scripts/build-parallel.js --skip-typecheck",
26
26
  "build:mcp": "node scripts/build-mcp.js",
27
- "build:ui": "vite build --config src/ui/vite.config.ts && node scripts/copy-ui-to-app.js",
27
+ "build:ui": "vite build --config src/ui/vite.config.ts",
28
28
  "kill:ports": "node scripts/kill-ports.js",
29
29
  "kill:dev-ports": "npm run kill:ports -- 3700 3702 4700 3715 5173 5174",
30
30
  "kill:quoroom-runtime": "node scripts/kill-quoroom-runtime.js",
31
31
  "kill:dev-runtime": "npm run kill:dev-ports && npm run kill:quoroom-runtime",
32
32
  "dev:links": "node scripts/dev-links.js",
33
- "dev": "sh -c 'npm run kill:dev-runtime && trap \"kill 0\" INT TERM EXIT; npm run dev:links & npm run dev:room & npm run dev:cloud & wait'",
33
+ "dev": "node scripts/run-dev.js",
34
34
  "dev:win": "node scripts/run-dev.js",
35
+ "dev:with-cloud": "node scripts/run-dev.js --with-cloud",
36
+ "dev:with-cloud:win": "node scripts/run-dev.js --with-cloud",
35
37
  "dev:room": "sh -c 'npm run kill:dev-runtime && export QUOROOM_DATA_DIR=$HOME/.quoroom-dev QUOROOM_SKIP_MCP_REGISTER=1; npm run build:mcp && npm run build:ui && node scripts/dev-server.js --port 4700'",
36
38
  "dev:room:win": "node scripts/dev-room.js --port 4700",
37
39
  "dev:room:isolated:win": "node scripts/dev-room.js --isolated --port 4700",
38
40
  "dev:room:isolated": "sh -c 'npm run kill:dev-runtime && export QUOROOM_DATA_DIR=$HOME/.quoroom-dev QUOROOM_SKIP_MCP_REGISTER=1; npm run build:mcp && npm run build:ui && node scripts/dev-server.js --port 4700'",
39
41
  "dev:room:shared": "npm run kill:dev-runtime && npm run build:mcp && npm run build:ui && node scripts/dev-server.js",
40
42
  "doctor:split": "node scripts/doctor-split.js",
41
- "dev:isolated": "sh -c 'npm run kill:dev-runtime && trap \"kill 0\" INT TERM EXIT; npm run dev:links & npm run dev:room:isolated & npm run dev:cloud & VITE_API_PORT=4700 npm run dev:ui & wait'",
43
+ "dev:isolated": "node scripts/run-dev.js --isolated",
42
44
  "dev:isolated:win": "node scripts/run-dev.js --isolated",
45
+ "dev:isolated:with-cloud": "node scripts/run-dev.js --isolated --with-cloud",
46
+ "dev:isolated:with-cloud:win": "node scripts/run-dev.js --isolated --with-cloud",
43
47
  "dev:cloud": "sh -c 'npm run kill:ports -- 3715 && cd ../cloud && PORT=3715 CLOUD_PUBLIC_URL=http://127.0.0.1:3715 CLOUD_ALLOWED_ORIGINS='\"'\"'http://127.0.0.1:3715,http://localhost:3715,http://localhost:5173,http://127.0.0.1:5173,https://quoroom.ai,https://www.quoroom.ai,https://app.quoroom.ai'\"'\"' npm start'",
44
48
  "dev:cloud:win": "node scripts/dev-cloud.js",
45
49
  "dev:ui": "vite --config src/ui/vite.config.ts",