quoroom 0.1.8 → 0.1.9
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/out/mcp/api-server.js +57 -10
- package/out/mcp/cli.js +59 -12
- package/out/mcp/server.js +1 -1
- package/package.json +6 -2
package/out/mcp/api-server.js
CHANGED
|
@@ -9382,7 +9382,7 @@ var require_package = __commonJS({
|
|
|
9382
9382
|
"package.json"(exports2, module2) {
|
|
9383
9383
|
module2.exports = {
|
|
9384
9384
|
name: "quoroom",
|
|
9385
|
-
version: "0.1.
|
|
9385
|
+
version: "0.1.9",
|
|
9386
9386
|
description: "Autonomous AI agent collective engine \u2014 Queen, Workers, Quorum",
|
|
9387
9387
|
main: "./out/mcp/server.js",
|
|
9388
9388
|
bin: {
|
|
@@ -9405,7 +9405,11 @@ var require_package = __commonJS({
|
|
|
9405
9405
|
"build:mcp": "node scripts/build-mcp.js",
|
|
9406
9406
|
"build:ui": "vite build --config src/ui/vite.config.ts",
|
|
9407
9407
|
dev: `sh -c 'trap "kill 0" INT TERM EXIT; npm run dev:room & npm run dev:cloud & wait'`,
|
|
9408
|
-
"dev:room": "npm run build:mcp && npm run build:ui && node scripts/dev-server.js",
|
|
9408
|
+
"dev:room": "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",
|
|
9409
|
+
"dev:room:isolated": "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",
|
|
9410
|
+
"dev:room:shared": "npm run build:mcp && npm run build:ui && node scripts/dev-server.js",
|
|
9411
|
+
"doctor:split": "node scripts/doctor-split.js",
|
|
9412
|
+
"dev:isolated": `sh -c 'trap "kill 0" INT TERM EXIT; npm run dev:room:isolated & npm run dev:cloud & wait'`,
|
|
9409
9413
|
"dev:cloud": "cd ../cloud && PORT=3710 CLOUD_PUBLIC_URL=http://127.0.0.1:3710 CLOUD_ALLOWED_ORIGINS='http://127.0.0.1:3710,http://localhost:3710,http://localhost:5173,http://127.0.0.1:5173,https://quoroom.ai,https://www.quoroom.ai,https://app.quoroom.ai' npm start",
|
|
9410
9414
|
"dev:ui": "vite --config src/ui/vite.config.ts",
|
|
9411
9415
|
"seed:style-demo": "node scripts/seed-style-demo.js",
|
|
@@ -10453,9 +10457,6 @@ function getCloudAllowedOrigins() {
|
|
|
10453
10457
|
const origins = configured.length > 0 ? configured : DEFAULT_CLOUD_ALLOWED_ORIGINS;
|
|
10454
10458
|
return new Set(origins.map(normalizeOrigin).filter(Boolean));
|
|
10455
10459
|
}
|
|
10456
|
-
function getCloudUserToken() {
|
|
10457
|
-
return (process.env.QUOROOM_CLOUD_USER_TOKEN || "").trim();
|
|
10458
|
-
}
|
|
10459
10460
|
function getCloudJwtSecret() {
|
|
10460
10461
|
return (process.env.QUOROOM_CLOUD_JWT_SECRET || "").trim();
|
|
10461
10462
|
}
|
|
@@ -10554,9 +10555,9 @@ function generateToken(dataDir) {
|
|
|
10554
10555
|
return agentToken;
|
|
10555
10556
|
}
|
|
10556
10557
|
}
|
|
10557
|
-
agentToken = dataDir ? readLegacyAgentToken(dataDir) ?? import_node_crypto.default.randomBytes(32).toString("hex") : import_node_crypto.default.randomBytes(32).toString("hex");
|
|
10558
|
+
agentToken = dataDir && !isCloudDeployment() ? readLegacyAgentToken(dataDir) ?? import_node_crypto.default.randomBytes(32).toString("hex") : import_node_crypto.default.randomBytes(32).toString("hex");
|
|
10558
10559
|
userToken = import_node_crypto.default.randomBytes(32).toString("hex");
|
|
10559
|
-
if (dataDir) writePersistedTokens(dataDir, agentToken, userToken);
|
|
10560
|
+
if (dataDir && !isCloudDeployment()) writePersistedTokens(dataDir, agentToken, userToken);
|
|
10560
10561
|
return agentToken;
|
|
10561
10562
|
}
|
|
10562
10563
|
function getUserToken() {
|
|
@@ -10572,10 +10573,10 @@ function validateToken(authHeader) {
|
|
|
10572
10573
|
const cloudRole = validateCloudJwt(provided);
|
|
10573
10574
|
if (cloudRole) return cloudRole;
|
|
10574
10575
|
}
|
|
10575
|
-
if (isCloudDeployment() && tokenEquals(getCloudUserToken(), provided)) return "user";
|
|
10576
10576
|
return null;
|
|
10577
10577
|
}
|
|
10578
10578
|
function writeTokenFile(dataDir, token, port) {
|
|
10579
|
+
if (isCloudDeployment()) return;
|
|
10579
10580
|
(0, import_node_fs.mkdirSync)(dataDir, { recursive: true });
|
|
10580
10581
|
(0, import_node_fs.writeFileSync)((0, import_node_path.join)(dataDir, "api.token"), token, { mode: 384 });
|
|
10581
10582
|
(0, import_node_fs.writeFileSync)((0, import_node_path.join)(dataDir, "api.port"), String(port));
|
|
@@ -26227,12 +26228,12 @@ function registerStatusRoutes(router) {
|
|
|
26227
26228
|
const ollama = await checkOllama();
|
|
26228
26229
|
const resources = getResources();
|
|
26229
26230
|
const deploymentMode = getDeploymentMode();
|
|
26231
|
+
const isCloud = deploymentMode === "cloud";
|
|
26230
26232
|
return {
|
|
26231
26233
|
data: {
|
|
26232
26234
|
version: getVersion3(),
|
|
26233
26235
|
uptime: Math.floor((Date.now() - startedAt) / 1e3),
|
|
26234
|
-
dataDir,
|
|
26235
|
-
dbPath,
|
|
26236
|
+
...!isCloud && { dataDir, dbPath },
|
|
26236
26237
|
claude,
|
|
26237
26238
|
codex,
|
|
26238
26239
|
ollama,
|
|
@@ -27745,6 +27746,39 @@ function serveStatic(staticDir, pathname, res) {
|
|
|
27745
27746
|
res.end("Not Found");
|
|
27746
27747
|
}
|
|
27747
27748
|
}
|
|
27749
|
+
var RATE_LIMIT_WINDOW_MS = 6e4;
|
|
27750
|
+
var RATE_LIMIT_READ = 300;
|
|
27751
|
+
var RATE_LIMIT_WRITE = 120;
|
|
27752
|
+
var rateBuckets = /* @__PURE__ */ new Map();
|
|
27753
|
+
setInterval(() => {
|
|
27754
|
+
const now = Date.now();
|
|
27755
|
+
for (const [key, bucket] of rateBuckets) {
|
|
27756
|
+
if (now >= bucket.resetAt) rateBuckets.delete(key);
|
|
27757
|
+
}
|
|
27758
|
+
}, 12e4).unref();
|
|
27759
|
+
function checkRateLimit2(ip, method) {
|
|
27760
|
+
const isWrite = method !== "GET" && method !== "HEAD" && method !== "OPTIONS";
|
|
27761
|
+
const limit = isWrite ? RATE_LIMIT_WRITE : RATE_LIMIT_READ;
|
|
27762
|
+
const key = `${ip}:${isWrite ? "w" : "r"}`;
|
|
27763
|
+
const now = Date.now();
|
|
27764
|
+
let bucket = rateBuckets.get(key);
|
|
27765
|
+
if (!bucket || now >= bucket.resetAt) {
|
|
27766
|
+
bucket = { count: 0, resetAt: now + RATE_LIMIT_WINDOW_MS };
|
|
27767
|
+
rateBuckets.set(key, bucket);
|
|
27768
|
+
}
|
|
27769
|
+
bucket.count++;
|
|
27770
|
+
if (bucket.count > limit) {
|
|
27771
|
+
const retryAfter = Math.ceil((bucket.resetAt - now) / 1e3);
|
|
27772
|
+
return { allowed: false, retryAfter };
|
|
27773
|
+
}
|
|
27774
|
+
return { allowed: true, retryAfter: 0 };
|
|
27775
|
+
}
|
|
27776
|
+
var CLOUD_SECURITY_HEADERS = {
|
|
27777
|
+
"Strict-Transport-Security": "max-age=31536000; includeSubDomains",
|
|
27778
|
+
"X-Content-Type-Options": "nosniff",
|
|
27779
|
+
"X-Frame-Options": "DENY",
|
|
27780
|
+
"Referrer-Policy": "strict-origin-when-cross-origin"
|
|
27781
|
+
};
|
|
27748
27782
|
function createApiServer(options = {}) {
|
|
27749
27783
|
const db2 = options.db ?? getServerDatabase();
|
|
27750
27784
|
const port = options.port ?? DEFAULT_PORT;
|
|
@@ -27769,7 +27803,20 @@ function createApiServer(options = {}) {
|
|
|
27769
27803
|
const responseHeaders = {
|
|
27770
27804
|
"Content-Type": "application/json"
|
|
27771
27805
|
};
|
|
27806
|
+
if (isCloudDeployment()) {
|
|
27807
|
+
Object.assign(responseHeaders, CLOUD_SECURITY_HEADERS);
|
|
27808
|
+
}
|
|
27772
27809
|
setCorsHeaders(origin, responseHeaders);
|
|
27810
|
+
if (isCloudDeployment() && pathname.startsWith("/api/")) {
|
|
27811
|
+
const clientIp = req.socket.remoteAddress || "unknown";
|
|
27812
|
+
const rl = checkRateLimit2(clientIp, req.method || "GET");
|
|
27813
|
+
if (!rl.allowed) {
|
|
27814
|
+
responseHeaders["Retry-After"] = String(rl.retryAfter);
|
|
27815
|
+
res.writeHead(429, responseHeaders);
|
|
27816
|
+
res.end(JSON.stringify({ error: "Too many requests" }));
|
|
27817
|
+
return;
|
|
27818
|
+
}
|
|
27819
|
+
}
|
|
27773
27820
|
const isSameOrigin = origin && req.headers.host && (() => {
|
|
27774
27821
|
try {
|
|
27775
27822
|
return new import_node_url.URL(origin).host === req.headers.host;
|
package/out/mcp/cli.js
CHANGED
|
@@ -49800,7 +49800,7 @@ var server_exports = {};
|
|
|
49800
49800
|
async function main() {
|
|
49801
49801
|
const server = new McpServer({
|
|
49802
49802
|
name: "quoroom",
|
|
49803
|
-
version: true ? "0.1.
|
|
49803
|
+
version: true ? "0.1.9" : "0.0.0"
|
|
49804
49804
|
});
|
|
49805
49805
|
registerMemoryTools(server);
|
|
49806
49806
|
registerSchedulerTools(server);
|
|
@@ -49934,9 +49934,6 @@ function getCloudAllowedOrigins() {
|
|
|
49934
49934
|
const origins = configured.length > 0 ? configured : DEFAULT_CLOUD_ALLOWED_ORIGINS;
|
|
49935
49935
|
return new Set(origins.map(normalizeOrigin).filter(Boolean));
|
|
49936
49936
|
}
|
|
49937
|
-
function getCloudUserToken() {
|
|
49938
|
-
return (process.env.QUOROOM_CLOUD_USER_TOKEN || "").trim();
|
|
49939
|
-
}
|
|
49940
49937
|
function getCloudJwtSecret() {
|
|
49941
49938
|
return (process.env.QUOROOM_CLOUD_JWT_SECRET || "").trim();
|
|
49942
49939
|
}
|
|
@@ -50035,9 +50032,9 @@ function generateToken(dataDir) {
|
|
|
50035
50032
|
return agentToken;
|
|
50036
50033
|
}
|
|
50037
50034
|
}
|
|
50038
|
-
agentToken = dataDir ? readLegacyAgentToken(dataDir) ?? import_node_crypto2.default.randomBytes(32).toString("hex") : import_node_crypto2.default.randomBytes(32).toString("hex");
|
|
50035
|
+
agentToken = dataDir && !isCloudDeployment() ? readLegacyAgentToken(dataDir) ?? import_node_crypto2.default.randomBytes(32).toString("hex") : import_node_crypto2.default.randomBytes(32).toString("hex");
|
|
50039
50036
|
userToken = import_node_crypto2.default.randomBytes(32).toString("hex");
|
|
50040
|
-
if (dataDir) writePersistedTokens(dataDir, agentToken, userToken);
|
|
50037
|
+
if (dataDir && !isCloudDeployment()) writePersistedTokens(dataDir, agentToken, userToken);
|
|
50041
50038
|
return agentToken;
|
|
50042
50039
|
}
|
|
50043
50040
|
function getUserToken() {
|
|
@@ -50053,10 +50050,10 @@ function validateToken(authHeader) {
|
|
|
50053
50050
|
const cloudRole = validateCloudJwt(provided);
|
|
50054
50051
|
if (cloudRole) return cloudRole;
|
|
50055
50052
|
}
|
|
50056
|
-
if (isCloudDeployment() && tokenEquals(getCloudUserToken(), provided)) return "user";
|
|
50057
50053
|
return null;
|
|
50058
50054
|
}
|
|
50059
50055
|
function writeTokenFile(dataDir, token, port) {
|
|
50056
|
+
if (isCloudDeployment()) return;
|
|
50060
50057
|
(0, import_node_fs.mkdirSync)(dataDir, { recursive: true });
|
|
50061
50058
|
(0, import_node_fs.writeFileSync)((0, import_node_path.join)(dataDir, "api.token"), token, { mode: 384 });
|
|
50062
50059
|
(0, import_node_fs.writeFileSync)((0, import_node_path.join)(dataDir, "api.port"), String(port));
|
|
@@ -50744,7 +50741,7 @@ var require_package = __commonJS({
|
|
|
50744
50741
|
"package.json"(exports2, module2) {
|
|
50745
50742
|
module2.exports = {
|
|
50746
50743
|
name: "quoroom",
|
|
50747
|
-
version: "0.1.
|
|
50744
|
+
version: "0.1.9",
|
|
50748
50745
|
description: "Autonomous AI agent collective engine \u2014 Queen, Workers, Quorum",
|
|
50749
50746
|
main: "./out/mcp/server.js",
|
|
50750
50747
|
bin: {
|
|
@@ -50767,7 +50764,11 @@ var require_package = __commonJS({
|
|
|
50767
50764
|
"build:mcp": "node scripts/build-mcp.js",
|
|
50768
50765
|
"build:ui": "vite build --config src/ui/vite.config.ts",
|
|
50769
50766
|
dev: `sh -c 'trap "kill 0" INT TERM EXIT; npm run dev:room & npm run dev:cloud & wait'`,
|
|
50770
|
-
"dev:room": "npm run build:mcp && npm run build:ui && node scripts/dev-server.js",
|
|
50767
|
+
"dev:room": "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",
|
|
50768
|
+
"dev:room:isolated": "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",
|
|
50769
|
+
"dev:room:shared": "npm run build:mcp && npm run build:ui && node scripts/dev-server.js",
|
|
50770
|
+
"doctor:split": "node scripts/doctor-split.js",
|
|
50771
|
+
"dev:isolated": `sh -c 'trap "kill 0" INT TERM EXIT; npm run dev:room:isolated & npm run dev:cloud & wait'`,
|
|
50771
50772
|
"dev:cloud": "cd ../cloud && PORT=3710 CLOUD_PUBLIC_URL=http://127.0.0.1:3710 CLOUD_ALLOWED_ORIGINS='http://127.0.0.1:3710,http://localhost:3710,http://localhost:5173,http://127.0.0.1:5173,https://quoroom.ai,https://www.quoroom.ai,https://app.quoroom.ai' npm start",
|
|
50772
50773
|
"dev:ui": "vite --config src/ui/vite.config.ts",
|
|
50773
50774
|
"seed:style-demo": "node scripts/seed-style-demo.js",
|
|
@@ -52713,12 +52714,12 @@ function registerStatusRoutes(router) {
|
|
|
52713
52714
|
const ollama = await checkOllama();
|
|
52714
52715
|
const resources = getResources();
|
|
52715
52716
|
const deploymentMode = getDeploymentMode();
|
|
52717
|
+
const isCloud = deploymentMode === "cloud";
|
|
52716
52718
|
return {
|
|
52717
52719
|
data: {
|
|
52718
52720
|
version: getVersion3(),
|
|
52719
52721
|
uptime: Math.floor((Date.now() - startedAt) / 1e3),
|
|
52720
|
-
dataDir,
|
|
52721
|
-
dbPath,
|
|
52722
|
+
...!isCloud && { dataDir, dbPath },
|
|
52722
52723
|
claude,
|
|
52723
52724
|
codex,
|
|
52724
52725
|
ollama,
|
|
@@ -57952,6 +57953,23 @@ function serveStatic(staticDir, pathname, res) {
|
|
|
57952
57953
|
res.end("Not Found");
|
|
57953
57954
|
}
|
|
57954
57955
|
}
|
|
57956
|
+
function checkRateLimit2(ip, method) {
|
|
57957
|
+
const isWrite = method !== "GET" && method !== "HEAD" && method !== "OPTIONS";
|
|
57958
|
+
const limit = isWrite ? RATE_LIMIT_WRITE : RATE_LIMIT_READ;
|
|
57959
|
+
const key = `${ip}:${isWrite ? "w" : "r"}`;
|
|
57960
|
+
const now = Date.now();
|
|
57961
|
+
let bucket = rateBuckets.get(key);
|
|
57962
|
+
if (!bucket || now >= bucket.resetAt) {
|
|
57963
|
+
bucket = { count: 0, resetAt: now + RATE_LIMIT_WINDOW_MS };
|
|
57964
|
+
rateBuckets.set(key, bucket);
|
|
57965
|
+
}
|
|
57966
|
+
bucket.count++;
|
|
57967
|
+
if (bucket.count > limit) {
|
|
57968
|
+
const retryAfter = Math.ceil((bucket.resetAt - now) / 1e3);
|
|
57969
|
+
return { allowed: false, retryAfter };
|
|
57970
|
+
}
|
|
57971
|
+
return { allowed: true, retryAfter: 0 };
|
|
57972
|
+
}
|
|
57955
57973
|
function createApiServer(options = {}) {
|
|
57956
57974
|
const db3 = options.db ?? getServerDatabase();
|
|
57957
57975
|
const port = options.port ?? DEFAULT_PORT;
|
|
@@ -57976,7 +57994,20 @@ function createApiServer(options = {}) {
|
|
|
57976
57994
|
const responseHeaders = {
|
|
57977
57995
|
"Content-Type": "application/json"
|
|
57978
57996
|
};
|
|
57997
|
+
if (isCloudDeployment()) {
|
|
57998
|
+
Object.assign(responseHeaders, CLOUD_SECURITY_HEADERS);
|
|
57999
|
+
}
|
|
57979
58000
|
setCorsHeaders(origin, responseHeaders);
|
|
58001
|
+
if (isCloudDeployment() && pathname.startsWith("/api/")) {
|
|
58002
|
+
const clientIp = req.socket.remoteAddress || "unknown";
|
|
58003
|
+
const rl = checkRateLimit2(clientIp, req.method || "GET");
|
|
58004
|
+
if (!rl.allowed) {
|
|
58005
|
+
responseHeaders["Retry-After"] = String(rl.retryAfter);
|
|
58006
|
+
res.writeHead(429, responseHeaders);
|
|
58007
|
+
res.end(JSON.stringify({ error: "Too many requests" }));
|
|
58008
|
+
return;
|
|
58009
|
+
}
|
|
58010
|
+
}
|
|
57980
58011
|
const isSameOrigin = origin && req.headers.host && (() => {
|
|
57981
58012
|
try {
|
|
57982
58013
|
return new import_node_url.URL(origin).host === req.headers.host;
|
|
@@ -58210,7 +58241,7 @@ function startServer(options = {}) {
|
|
|
58210
58241
|
process.exit(0);
|
|
58211
58242
|
});
|
|
58212
58243
|
}
|
|
58213
|
-
var import_node_http, import_node_https2, import_node_url, import_node_fs3, import_node_path4, import_node_os5, import_node_child_process6, DEFAULT_PORT, DEFAULT_BIND_HOST_LOCAL, DEFAULT_BIND_HOST_CLOUD, MIME_TYPES;
|
|
58244
|
+
var import_node_http, import_node_https2, import_node_url, import_node_fs3, import_node_path4, import_node_os5, import_node_child_process6, DEFAULT_PORT, DEFAULT_BIND_HOST_LOCAL, DEFAULT_BIND_HOST_CLOUD, MIME_TYPES, RATE_LIMIT_WINDOW_MS, RATE_LIMIT_READ, RATE_LIMIT_WRITE, rateBuckets, CLOUD_SECURITY_HEADERS;
|
|
58214
58245
|
var init_server4 = __esm({
|
|
58215
58246
|
"src/server/index.ts"() {
|
|
58216
58247
|
"use strict";
|
|
@@ -58254,6 +58285,22 @@ var init_server4 = __esm({
|
|
|
58254
58285
|
".webp": "image/webp",
|
|
58255
58286
|
".webmanifest": "application/manifest+json"
|
|
58256
58287
|
};
|
|
58288
|
+
RATE_LIMIT_WINDOW_MS = 6e4;
|
|
58289
|
+
RATE_LIMIT_READ = 300;
|
|
58290
|
+
RATE_LIMIT_WRITE = 120;
|
|
58291
|
+
rateBuckets = /* @__PURE__ */ new Map();
|
|
58292
|
+
setInterval(() => {
|
|
58293
|
+
const now = Date.now();
|
|
58294
|
+
for (const [key, bucket] of rateBuckets) {
|
|
58295
|
+
if (now >= bucket.resetAt) rateBuckets.delete(key);
|
|
58296
|
+
}
|
|
58297
|
+
}, 12e4).unref();
|
|
58298
|
+
CLOUD_SECURITY_HEADERS = {
|
|
58299
|
+
"Strict-Transport-Security": "max-age=31536000; includeSubDomains",
|
|
58300
|
+
"X-Content-Type-Options": "nosniff",
|
|
58301
|
+
"X-Frame-Options": "DENY",
|
|
58302
|
+
"Referrer-Policy": "strict-origin-when-cross-origin"
|
|
58303
|
+
};
|
|
58257
58304
|
}
|
|
58258
58305
|
});
|
|
58259
58306
|
|
package/out/mcp/server.js
CHANGED
|
@@ -47101,7 +47101,7 @@ function registerResourceTools(server) {
|
|
|
47101
47101
|
async function main() {
|
|
47102
47102
|
const server = new McpServer({
|
|
47103
47103
|
name: "quoroom",
|
|
47104
|
-
version: true ? "0.1.
|
|
47104
|
+
version: true ? "0.1.9" : "0.0.0"
|
|
47105
47105
|
});
|
|
47106
47106
|
registerMemoryTools(server);
|
|
47107
47107
|
registerSchedulerTools(server);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "quoroom",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Autonomous AI agent collective engine — Queen, Workers, Quorum",
|
|
5
5
|
"main": "./out/mcp/server.js",
|
|
6
6
|
"bin": {
|
|
@@ -23,7 +23,11 @@
|
|
|
23
23
|
"build:mcp": "node scripts/build-mcp.js",
|
|
24
24
|
"build:ui": "vite build --config src/ui/vite.config.ts",
|
|
25
25
|
"dev": "sh -c 'trap \"kill 0\" INT TERM EXIT; npm run dev:room & npm run dev:cloud & wait'",
|
|
26
|
-
"dev:room": "npm run build:mcp && npm run build:ui && node scripts/dev-server.js",
|
|
26
|
+
"dev:room": "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",
|
|
27
|
+
"dev:room:isolated": "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",
|
|
28
|
+
"dev:room:shared": "npm run build:mcp && npm run build:ui && node scripts/dev-server.js",
|
|
29
|
+
"doctor:split": "node scripts/doctor-split.js",
|
|
30
|
+
"dev:isolated": "sh -c 'trap \"kill 0\" INT TERM EXIT; npm run dev:room:isolated & npm run dev:cloud & wait'",
|
|
27
31
|
"dev:cloud": "cd ../cloud && PORT=3710 CLOUD_PUBLIC_URL=http://127.0.0.1:3710 CLOUD_ALLOWED_ORIGINS='http://127.0.0.1:3710,http://localhost:3710,http://localhost:5173,http://127.0.0.1:5173,https://quoroom.ai,https://www.quoroom.ai,https://app.quoroom.ai' npm start",
|
|
28
32
|
"dev:ui": "vite --config src/ui/vite.config.ts",
|
|
29
33
|
"seed:style-demo": "node scripts/seed-style-demo.js",
|