quoroom 0.1.18 → 0.1.20

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
@@ -191,6 +191,14 @@ Download from [GitHub Releases](https://github.com/quoroom-ai/room/releases). In
191
191
  | Linux x64 | `.deb` | `.tar.gz` |
192
192
  | Windows x64 (signed) | `.exe` setup | `.zip` |
193
193
 
194
+ ### Uninstall
195
+
196
+ ```bash
197
+ quoroom uninstall
198
+ ```
199
+
200
+ Removes Quoroom binaries, all data, and logs. Prompts for confirmation before proceeding.
201
+
194
202
  ---
195
203
 
196
204
  ## Quick Start
@@ -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.18",
9917
+ version: "0.1.20",
9918
9918
  description: "Autonomous AI agent collective engine \u2014 Queen, Workers, Quorum",
9919
9919
  main: "./out/mcp/server.js",
9920
9920
  bin: {
@@ -28740,7 +28740,7 @@ var cachedVersion = null;
28740
28740
  function getVersion3() {
28741
28741
  if (cachedVersion) return cachedVersion;
28742
28742
  try {
28743
- cachedVersion = true ? "0.1.18" : null.version;
28743
+ cachedVersion = true ? "0.1.20" : null.version;
28744
28744
  } catch {
28745
28745
  cachedVersion = "unknown";
28746
28746
  }
@@ -28873,6 +28873,7 @@ function registerStatusRoutes(router) {
28873
28873
  }
28874
28874
 
28875
28875
  // src/server/routes/wallet.ts
28876
+ var import_node_crypto6 = __toESM(require("node:crypto"));
28876
28877
  init_cloud_sync();
28877
28878
  function parseLimit3(raw, fallback, max) {
28878
28879
  const n = Number(raw);
@@ -28908,9 +28909,11 @@ async function fetchRoomBalance(roomId, address) {
28908
28909
  );
28909
28910
  const byChain = {};
28910
28911
  let totalBalance = 0;
28912
+ let anySuccess = false;
28911
28913
  for (const { chain, token, result } of results) {
28912
28914
  if (!byChain[chain]) byChain[chain] = { usdc: 0, usdt: 0, total: 0 };
28913
28915
  if (result.ok) {
28916
+ anySuccess = true;
28914
28917
  byChain[chain][token] = result.balance;
28915
28918
  byChain[chain].total += result.balance;
28916
28919
  totalBalance += result.balance;
@@ -28922,7 +28925,9 @@ async function fetchRoomBalance(roomId, address) {
28922
28925
  address,
28923
28926
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
28924
28927
  };
28925
- balanceCache.set(roomId, { data, fetchedAt: Date.now() });
28928
+ if (anySuccess) {
28929
+ balanceCache.set(roomId, { data, fetchedAt: Date.now() });
28930
+ }
28926
28931
  return data;
28927
28932
  })();
28928
28933
  pendingBalanceRequests.set(roomId, request);
@@ -28959,6 +28964,9 @@ function registerWalletRoutes(router) {
28959
28964
  }
28960
28965
  try {
28961
28966
  const data = await fetchRoomBalance(roomId, wallet.address);
28967
+ if (data.totalBalance === 0 && Object.keys(data.byChain).length === 0 && cached2 && cached2.data.totalBalance > 0) {
28968
+ return { data: { ...cached2.data, fetchedAt: (/* @__PURE__ */ new Date()).toISOString() } };
28969
+ }
28962
28970
  return { data };
28963
28971
  } catch {
28964
28972
  if (cached2) {
@@ -28994,6 +29002,73 @@ function registerWalletRoutes(router) {
28994
29002
  if (!result) return { status: 503, error: "On-ramp unavailable" };
28995
29003
  return { data: result };
28996
29004
  });
29005
+ router.post("/api/rooms/:roomId/wallet/withdraw", async (ctx) => {
29006
+ const roomId = Number(ctx.params.roomId);
29007
+ const room = getRoom(ctx.db, roomId);
29008
+ if (!room) return { status: 404, error: "Room not found" };
29009
+ const wallet = getWalletByRoom(ctx.db, roomId);
29010
+ if (!wallet) return { status: 400, error: "Room has no wallet" };
29011
+ const { to: rawTo, amount: rawAmount, chain, token } = ctx.body;
29012
+ const to = rawTo?.trim();
29013
+ const amount = rawAmount?.trim();
29014
+ if (!to || !amount) return { status: 400, error: "Missing required fields: to, amount" };
29015
+ if (!/^0x[0-9a-fA-F]{40}$/.test(to)) return { status: 400, error: "Invalid address" };
29016
+ const parsed = parseFloat(amount);
29017
+ if (!Number.isFinite(parsed) || parsed <= 0) return { status: 400, error: "Invalid amount" };
29018
+ const selectedChain = chain ?? "base";
29019
+ const selectedToken = token ?? "usdc";
29020
+ const chainConfig2 = CHAIN_CONFIGS[selectedChain];
29021
+ if (!chainConfig2) return { status: 400, error: `Unsupported chain: ${selectedChain}` };
29022
+ const tokenConfig = chainConfig2.tokens[selectedToken];
29023
+ if (!tokenConfig) return { status: 400, error: `Token ${selectedToken} not available on ${selectedChain}` };
29024
+ const encryptionKey = import_node_crypto6.default.createHash("sha256").update(`quoroom-wallet-${room.id}-${room.name}`).digest("hex");
29025
+ const GAS_TIPS = {
29026
+ base: { token: "ETH", amount: "0.0001 ETH (~$0.25)" },
29027
+ arbitrum: { token: "ETH", amount: "0.0001 ETH (~$0.25)" },
29028
+ optimism: { token: "ETH", amount: "0.0001 ETH (~$0.25)" },
29029
+ ethereum: { token: "ETH", amount: "0.002 ETH (~$5)" },
29030
+ polygon: { token: "POL", amount: "0.1 POL (~$0.05)" }
29031
+ };
29032
+ const gasTip = GAS_TIPS[selectedChain] ?? { token: "ETH", amount: "0.001 ETH" };
29033
+ const VIEM_CHAINS2 = {
29034
+ base,
29035
+ ethereum: mainnet,
29036
+ arbitrum,
29037
+ optimism,
29038
+ polygon
29039
+ };
29040
+ try {
29041
+ const viemChain = VIEM_CHAINS2[selectedChain];
29042
+ if (viemChain) {
29043
+ const publicClient = createPublicClient({ chain: viemChain, transport: http(chainConfig2.rpcUrl) });
29044
+ const gasBalance = await publicClient.getBalance({ address: wallet.address });
29045
+ if (gasBalance === 0n) {
29046
+ return { status: 400, error: `No ${gasTip.token} for gas fees. Send at least ${gasTip.amount} to ${wallet.address} on ${chainConfig2.name} to cover the transaction.` };
29047
+ }
29048
+ }
29049
+ } catch {
29050
+ }
29051
+ try {
29052
+ const txHash = await sendToken(
29053
+ ctx.db,
29054
+ roomId,
29055
+ to,
29056
+ amount,
29057
+ encryptionKey,
29058
+ selectedChain,
29059
+ tokenConfig.address,
29060
+ tokenConfig.decimals
29061
+ );
29062
+ balanceCache.delete(roomId);
29063
+ return { data: { txHash } };
29064
+ } catch (e) {
29065
+ const msg = e.message || "Unknown error";
29066
+ if (msg.includes("gas") || msg.includes("insufficient funds")) {
29067
+ return { status: 400, error: `Insufficient ${gasTip.token} for gas fees on ${chainConfig2.name}. Send at least ${gasTip.amount} to your wallet address to cover the transaction.` };
29068
+ }
29069
+ return { status: 400, error: `Withdraw failed: ${msg.split("\n")[0]}` };
29070
+ }
29071
+ });
28997
29072
  }
28998
29073
 
28999
29074
  // src/server/routes/credentials.ts
@@ -29372,7 +29447,7 @@ function registerRoomMessageRoutes(router) {
29372
29447
 
29373
29448
  // src/server/provider-auth.ts
29374
29449
  var import_node_child_process3 = require("node:child_process");
29375
- var import_node_crypto6 = require("node:crypto");
29450
+ var import_node_crypto7 = require("node:crypto");
29376
29451
  var sessionStore = /* @__PURE__ */ new Map();
29377
29452
  var activeByProvider = /* @__PURE__ */ new Map();
29378
29453
  var MAX_LINES = Math.max(50, parseInt(process.env.QUOROOM_PROVIDER_AUTH_MAX_LINES || "300", 10) || 300);
@@ -29590,7 +29665,7 @@ function startProviderAuthSession(provider) {
29590
29665
  });
29591
29666
  const startedAt2 = nowIso();
29592
29667
  const session = {
29593
- sessionId: (0, import_node_crypto6.randomUUID)(),
29668
+ sessionId: (0, import_node_crypto7.randomUUID)(),
29594
29669
  provider,
29595
29670
  command: displayCommand,
29596
29671
  status: "starting",
@@ -29657,7 +29732,7 @@ function startProviderAuthSession(provider) {
29657
29732
 
29658
29733
  // src/server/provider-install.ts
29659
29734
  var import_node_child_process5 = require("node:child_process");
29660
- var import_node_crypto7 = require("node:crypto");
29735
+ var import_node_crypto8 = require("node:crypto");
29661
29736
  var import_node_path3 = __toESM(require("node:path"));
29662
29737
 
29663
29738
  // src/server/provider-cli.ts
@@ -29681,6 +29756,9 @@ function probeProviderInstalled(provider) {
29681
29756
  return out.ok ? { installed: true, version: out.stdout || void 0 } : { installed: false };
29682
29757
  }
29683
29758
  function probeProviderConnected(provider) {
29759
+ if (provider === "claude") {
29760
+ return probeProviderInstalled("claude").installed ? true : null;
29761
+ }
29684
29762
  const attempts = provider === "codex" ? [["login", "status"], ["auth", "status"]] : [["auth", "status"], ["login", "status"]];
29685
29763
  for (const args of attempts) {
29686
29764
  const out = safeExec(provider, args);
@@ -29890,7 +29968,7 @@ function startProviderInstallSession(provider) {
29890
29968
  });
29891
29969
  const startedAt2 = nowIso2();
29892
29970
  const session = {
29893
- sessionId: (0, import_node_crypto7.randomUUID)(),
29971
+ sessionId: (0, import_node_crypto8.randomUUID)(),
29894
29972
  provider,
29895
29973
  command: displayCommand,
29896
29974
  status: "starting",
package/out/mcp/cli.js CHANGED
@@ -51040,7 +51040,7 @@ var server_exports = {};
51040
51040
  async function main() {
51041
51041
  const server = new McpServer({
51042
51042
  name: "quoroom",
51043
- version: true ? "0.1.18" : "0.0.0"
51043
+ version: true ? "0.1.20" : "0.0.0"
51044
51044
  });
51045
51045
  registerMemoryTools(server);
51046
51046
  registerSchedulerTools(server);
@@ -52847,7 +52847,7 @@ var require_package = __commonJS({
52847
52847
  "package.json"(exports2, module2) {
52848
52848
  module2.exports = {
52849
52849
  name: "quoroom",
52850
- version: "0.1.18",
52850
+ version: "0.1.20",
52851
52851
  description: "Autonomous AI agent collective engine \u2014 Queen, Workers, Quorum",
52852
52852
  main: "./out/mcp/server.js",
52853
52853
  bin: {
@@ -55483,7 +55483,7 @@ var init_updateChecker = __esm({
55483
55483
  function getVersion3() {
55484
55484
  if (cachedVersion) return cachedVersion;
55485
55485
  try {
55486
- cachedVersion = true ? "0.1.18" : null.version;
55486
+ cachedVersion = true ? "0.1.20" : null.version;
55487
55487
  } catch {
55488
55488
  cachedVersion = "unknown";
55489
55489
  }
@@ -55660,9 +55660,11 @@ async function fetchRoomBalance(roomId, address) {
55660
55660
  );
55661
55661
  const byChain = {};
55662
55662
  let totalBalance = 0;
55663
+ let anySuccess = false;
55663
55664
  for (const { chain, token, result } of results) {
55664
55665
  if (!byChain[chain]) byChain[chain] = { usdc: 0, usdt: 0, total: 0 };
55665
55666
  if (result.ok) {
55667
+ anySuccess = true;
55666
55668
  byChain[chain][token] = result.balance;
55667
55669
  byChain[chain].total += result.balance;
55668
55670
  totalBalance += result.balance;
@@ -55674,7 +55676,9 @@ async function fetchRoomBalance(roomId, address) {
55674
55676
  address,
55675
55677
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
55676
55678
  };
55677
- balanceCache.set(roomId, { data, fetchedAt: Date.now() });
55679
+ if (anySuccess) {
55680
+ balanceCache.set(roomId, { data, fetchedAt: Date.now() });
55681
+ }
55678
55682
  return data;
55679
55683
  })();
55680
55684
  pendingBalanceRequests.set(roomId, request);
@@ -55711,6 +55715,9 @@ function registerWalletRoutes(router) {
55711
55715
  }
55712
55716
  try {
55713
55717
  const data = await fetchRoomBalance(roomId, wallet.address);
55718
+ if (data.totalBalance === 0 && Object.keys(data.byChain).length === 0 && cached3 && cached3.data.totalBalance > 0) {
55719
+ return { data: { ...cached3.data, fetchedAt: (/* @__PURE__ */ new Date()).toISOString() } };
55720
+ }
55714
55721
  return { data };
55715
55722
  } catch {
55716
55723
  if (cached3) {
@@ -55746,12 +55753,82 @@ function registerWalletRoutes(router) {
55746
55753
  if (!result) return { status: 503, error: "On-ramp unavailable" };
55747
55754
  return { data: result };
55748
55755
  });
55756
+ router.post("/api/rooms/:roomId/wallet/withdraw", async (ctx) => {
55757
+ const roomId = Number(ctx.params.roomId);
55758
+ const room = getRoom(ctx.db, roomId);
55759
+ if (!room) return { status: 404, error: "Room not found" };
55760
+ const wallet = getWalletByRoom(ctx.db, roomId);
55761
+ if (!wallet) return { status: 400, error: "Room has no wallet" };
55762
+ const { to: rawTo, amount: rawAmount, chain, token } = ctx.body;
55763
+ const to = rawTo?.trim();
55764
+ const amount = rawAmount?.trim();
55765
+ if (!to || !amount) return { status: 400, error: "Missing required fields: to, amount" };
55766
+ if (!/^0x[0-9a-fA-F]{40}$/.test(to)) return { status: 400, error: "Invalid address" };
55767
+ const parsed = parseFloat(amount);
55768
+ if (!Number.isFinite(parsed) || parsed <= 0) return { status: 400, error: "Invalid amount" };
55769
+ const selectedChain = chain ?? "base";
55770
+ const selectedToken = token ?? "usdc";
55771
+ const chainConfig2 = CHAIN_CONFIGS[selectedChain];
55772
+ if (!chainConfig2) return { status: 400, error: `Unsupported chain: ${selectedChain}` };
55773
+ const tokenConfig = chainConfig2.tokens[selectedToken];
55774
+ if (!tokenConfig) return { status: 400, error: `Token ${selectedToken} not available on ${selectedChain}` };
55775
+ const encryptionKey = import_node_crypto6.default.createHash("sha256").update(`quoroom-wallet-${room.id}-${room.name}`).digest("hex");
55776
+ const GAS_TIPS = {
55777
+ base: { token: "ETH", amount: "0.0001 ETH (~$0.25)" },
55778
+ arbitrum: { token: "ETH", amount: "0.0001 ETH (~$0.25)" },
55779
+ optimism: { token: "ETH", amount: "0.0001 ETH (~$0.25)" },
55780
+ ethereum: { token: "ETH", amount: "0.002 ETH (~$5)" },
55781
+ polygon: { token: "POL", amount: "0.1 POL (~$0.05)" }
55782
+ };
55783
+ const gasTip = GAS_TIPS[selectedChain] ?? { token: "ETH", amount: "0.001 ETH" };
55784
+ const VIEM_CHAINS2 = {
55785
+ base,
55786
+ ethereum: mainnet,
55787
+ arbitrum,
55788
+ optimism,
55789
+ polygon
55790
+ };
55791
+ try {
55792
+ const viemChain = VIEM_CHAINS2[selectedChain];
55793
+ if (viemChain) {
55794
+ const publicClient = createPublicClient({ chain: viemChain, transport: http(chainConfig2.rpcUrl) });
55795
+ const gasBalance = await publicClient.getBalance({ address: wallet.address });
55796
+ if (gasBalance === 0n) {
55797
+ return { status: 400, error: `No ${gasTip.token} for gas fees. Send at least ${gasTip.amount} to ${wallet.address} on ${chainConfig2.name} to cover the transaction.` };
55798
+ }
55799
+ }
55800
+ } catch {
55801
+ }
55802
+ try {
55803
+ const txHash = await sendToken(
55804
+ ctx.db,
55805
+ roomId,
55806
+ to,
55807
+ amount,
55808
+ encryptionKey,
55809
+ selectedChain,
55810
+ tokenConfig.address,
55811
+ tokenConfig.decimals
55812
+ );
55813
+ balanceCache.delete(roomId);
55814
+ return { data: { txHash } };
55815
+ } catch (e) {
55816
+ const msg = e.message || "Unknown error";
55817
+ if (msg.includes("gas") || msg.includes("insufficient funds")) {
55818
+ return { status: 400, error: `Insufficient ${gasTip.token} for gas fees on ${chainConfig2.name}. Send at least ${gasTip.amount} to your wallet address to cover the transaction.` };
55819
+ }
55820
+ return { status: 400, error: `Withdraw failed: ${msg.split("\n")[0]}` };
55821
+ }
55822
+ });
55749
55823
  }
55750
- var balanceCache, CACHE_TTL_MS, BALANCE_RPC_TIMEOUT_MS, pendingBalanceRequests;
55824
+ var import_node_crypto6, balanceCache, CACHE_TTL_MS, BALANCE_RPC_TIMEOUT_MS, pendingBalanceRequests;
55751
55825
  var init_wallet4 = __esm({
55752
55826
  "src/server/routes/wallet.ts"() {
55753
55827
  "use strict";
55828
+ import_node_crypto6 = __toESM(require("node:crypto"));
55754
55829
  init_db_queries();
55830
+ init_esm2();
55831
+ init_chains();
55755
55832
  init_wallet2();
55756
55833
  init_constants();
55757
55834
  init_cloud_sync();
@@ -56373,7 +56450,7 @@ function startProviderAuthSession(provider) {
56373
56450
  });
56374
56451
  const startedAt2 = nowIso();
56375
56452
  const session = {
56376
- sessionId: (0, import_node_crypto6.randomUUID)(),
56453
+ sessionId: (0, import_node_crypto7.randomUUID)(),
56377
56454
  provider,
56378
56455
  command: displayCommand,
56379
56456
  status: "starting",
@@ -56437,12 +56514,12 @@ function startProviderAuthSession(provider) {
56437
56514
  });
56438
56515
  return { session: toSessionView(session, true), reused: false };
56439
56516
  }
56440
- var import_node_child_process3, import_node_crypto6, sessionStore, activeByProvider, MAX_LINES, SESSION_TIMEOUT_MS, SESSION_TTL_MS;
56517
+ var import_node_child_process3, import_node_crypto7, sessionStore, activeByProvider, MAX_LINES, SESSION_TIMEOUT_MS, SESSION_TTL_MS;
56441
56518
  var init_provider_auth = __esm({
56442
56519
  "src/server/provider-auth.ts"() {
56443
56520
  "use strict";
56444
56521
  import_node_child_process3 = require("node:child_process");
56445
- import_node_crypto6 = require("node:crypto");
56522
+ import_node_crypto7 = require("node:crypto");
56446
56523
  init_event_bus();
56447
56524
  sessionStore = /* @__PURE__ */ new Map();
56448
56525
  activeByProvider = /* @__PURE__ */ new Map();
@@ -56471,6 +56548,9 @@ function probeProviderInstalled(provider) {
56471
56548
  return out.ok ? { installed: true, version: out.stdout || void 0 } : { installed: false };
56472
56549
  }
56473
56550
  function probeProviderConnected(provider) {
56551
+ if (provider === "claude") {
56552
+ return probeProviderInstalled("claude").installed ? true : null;
56553
+ }
56474
56554
  const attempts = provider === "codex" ? [["login", "status"], ["auth", "status"]] : [["auth", "status"], ["login", "status"]];
56475
56555
  for (const args2 of attempts) {
56476
56556
  const out = safeExec(provider, args2);
@@ -56683,7 +56763,7 @@ function startProviderInstallSession(provider) {
56683
56763
  });
56684
56764
  const startedAt2 = nowIso2();
56685
56765
  const session = {
56686
- sessionId: (0, import_node_crypto7.randomUUID)(),
56766
+ sessionId: (0, import_node_crypto8.randomUUID)(),
56687
56767
  provider,
56688
56768
  command: displayCommand,
56689
56769
  status: "starting",
@@ -56756,12 +56836,12 @@ function startProviderInstallSession(provider) {
56756
56836
  });
56757
56837
  return { session: toSessionView2(session, true), reused: false };
56758
56838
  }
56759
- var import_node_child_process5, import_node_crypto7, import_node_path3, sessionStore2, activeByProvider2, MAX_LINES2, SESSION_TIMEOUT_MS2, SESSION_TTL_MS2;
56839
+ var import_node_child_process5, import_node_crypto8, import_node_path3, sessionStore2, activeByProvider2, MAX_LINES2, SESSION_TIMEOUT_MS2, SESSION_TTL_MS2;
56760
56840
  var init_provider_install = __esm({
56761
56841
  "src/server/provider-install.ts"() {
56762
56842
  "use strict";
56763
56843
  import_node_child_process5 = require("node:child_process");
56764
- import_node_crypto7 = require("node:crypto");
56844
+ import_node_crypto8 = require("node:crypto");
56765
56845
  import_node_path3 = __toESM(require("node:path"));
56766
56846
  init_event_bus();
56767
56847
  init_provider_cli();
@@ -61673,6 +61753,66 @@ var init_chat2 = __esm({
61673
61753
  }
61674
61754
  });
61675
61755
 
61756
+ // src/cli/uninstall.ts
61757
+ var uninstall_exports = {};
61758
+ __export(uninstall_exports, {
61759
+ runUninstall: () => runUninstall
61760
+ });
61761
+ function runUninstall() {
61762
+ const rl = (0, import_readline2.createInterface)({ input: process.stdin, output: process.stdout });
61763
+ rl.question("This will remove Quoroom and all its data. Continue? [y/N] ", (answer) => {
61764
+ rl.close();
61765
+ if (answer.trim().toLowerCase() !== "y") {
61766
+ console.log("Cancelled.");
61767
+ process.exit(0);
61768
+ }
61769
+ try {
61770
+ (0, import_child_process3.execSync)('pkill -f "quoroom serve"', { stdio: "ignore" });
61771
+ } catch {
61772
+ }
61773
+ for (const dir of [PATHS.data, PATHS.logs]) {
61774
+ if ((0, import_fs8.existsSync)(dir)) {
61775
+ (0, import_fs8.rmSync)(dir, { recursive: true, force: true });
61776
+ console.log(`Removed ${dir}`);
61777
+ }
61778
+ }
61779
+ const needsSudo = (0, import_fs8.existsSync)(PATHS.lib) || (0, import_fs8.existsSync)(PATHS.bin);
61780
+ if (needsSudo) {
61781
+ console.log("\nRemoving /usr/local/lib/quoroom and /usr/local/bin/quoroom (requires sudo)...");
61782
+ try {
61783
+ (0, import_child_process3.execSync)(`sudo rm -rf ${PATHS.lib} ${PATHS.bin}`, { stdio: "inherit" });
61784
+ console.log("Removed binaries.");
61785
+ } catch {
61786
+ console.error("Failed to remove binaries. Run manually:\n sudo rm -rf /usr/local/lib/quoroom /usr/local/bin/quoroom");
61787
+ }
61788
+ }
61789
+ try {
61790
+ (0, import_child_process3.execSync)(`sudo pkgutil --forget ${PKG_ID}`, { stdio: "ignore" });
61791
+ console.log("Removed package receipt.");
61792
+ } catch {
61793
+ }
61794
+ console.log("\nQuoroom has been uninstalled.");
61795
+ });
61796
+ }
61797
+ var import_child_process3, import_fs8, import_os10, import_path8, import_readline2, PATHS, PKG_ID;
61798
+ var init_uninstall = __esm({
61799
+ "src/cli/uninstall.ts"() {
61800
+ "use strict";
61801
+ import_child_process3 = require("child_process");
61802
+ import_fs8 = require("fs");
61803
+ import_os10 = require("os");
61804
+ import_path8 = require("path");
61805
+ import_readline2 = require("readline");
61806
+ PATHS = {
61807
+ lib: "/usr/local/lib/quoroom",
61808
+ bin: "/usr/local/bin/quoroom",
61809
+ data: (0, import_path8.join)((0, import_os10.homedir)(), ".quoroom"),
61810
+ logs: (0, import_path8.join)((0, import_os10.homedir)(), "Library", "Logs", "Quoroom")
61811
+ };
61812
+ PKG_ID = "ai.quoroom.room";
61813
+ }
61814
+ });
61815
+
61676
61816
  // src/cli/index.ts
61677
61817
  var args = process.argv.slice(2);
61678
61818
  var command = args[0] || "help";
@@ -61695,6 +61835,11 @@ switch (command) {
61695
61835
  startChat2(args.slice(1));
61696
61836
  break;
61697
61837
  }
61838
+ case "uninstall": {
61839
+ const { runUninstall: runUninstall2 } = (init_uninstall(), __toCommonJS(uninstall_exports));
61840
+ runUninstall2();
61841
+ break;
61842
+ }
61698
61843
  case "help":
61699
61844
  default: {
61700
61845
  console.log(`
@@ -61704,6 +61849,7 @@ Usage:
61704
61849
  quoroom mcp Start MCP server (stdio transport)
61705
61850
  quoroom serve [port] Start HTTP/WebSocket API server (default: 3700)
61706
61851
  quoroom chat Chat with the queen (interactive REPL)
61852
+ quoroom uninstall Remove Quoroom and all data
61707
61853
  quoroom help Show this help message
61708
61854
 
61709
61855
  Dashboard: http://localhost:3700
package/out/mcp/server.js CHANGED
@@ -47485,7 +47485,7 @@ Share this with the keeper or potential collaborators. Rooms created through thi
47485
47485
  async function main() {
47486
47486
  const server = new McpServer({
47487
47487
  name: "quoroom",
47488
- version: true ? "0.1.18" : "0.0.0"
47488
+ version: true ? "0.1.20" : "0.0.0"
47489
47489
  });
47490
47490
  registerMemoryTools(server);
47491
47491
  registerSchedulerTools(server);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quoroom",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
4
4
  "description": "Autonomous AI agent collective engine — Queen, Workers, Quorum",
5
5
  "main": "./out/mcp/server.js",
6
6
  "bin": {