bit-office 0.1.0 → 0.1.2

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/index.js CHANGED
@@ -4227,37 +4227,61 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
4227
4227
  import { homedir } from "os";
4228
4228
  import { randomBytes } from "crypto";
4229
4229
  var __dirname = dirname(fileURLToPath(import.meta.url));
4230
+ var CONFIG_DIR = resolve(homedir(), ".bit-office");
4231
+ var CONFIG_FILE = resolve(CONFIG_DIR, "config.json");
4232
+ function ensureConfigDir() {
4233
+ if (!existsSync(CONFIG_DIR)) {
4234
+ mkdirSync(CONFIG_DIR, { recursive: true });
4235
+ }
4236
+ }
4237
+ function loadSavedConfig() {
4238
+ if (!existsSync(CONFIG_FILE)) return {};
4239
+ try {
4240
+ return JSON.parse(readFileSync(CONFIG_FILE, "utf-8"));
4241
+ } catch {
4242
+ return {};
4243
+ }
4244
+ }
4245
+ function saveConfig(cfg) {
4246
+ ensureConfigDir();
4247
+ writeFileSync(CONFIG_FILE, JSON.stringify(cfg, null, 2), "utf-8");
4248
+ }
4249
+ function hasSetupRun() {
4250
+ return existsSync(CONFIG_FILE);
4251
+ }
4230
4252
  function getOrCreateMachineId() {
4231
- const configDir = resolve(homedir(), ".bit-office");
4232
- const configFile = resolve(configDir, "machine-id");
4233
- if (existsSync(configFile)) {
4234
- return readFileSync(configFile, "utf-8").trim();
4253
+ ensureConfigDir();
4254
+ const idFile = resolve(CONFIG_DIR, "machine-id");
4255
+ if (existsSync(idFile)) {
4256
+ return readFileSync(idFile, "utf-8").trim();
4235
4257
  }
4236
4258
  const id = `mac-${randomBytes(4).toString("hex")}`;
4237
- mkdirSync(configDir, { recursive: true });
4238
- writeFileSync(configFile, id, "utf-8");
4239
- console.log(`[Config] Generated machine ID: ${id} (saved to ${configFile})`);
4259
+ writeFileSync(idFile, id, "utf-8");
4260
+ console.log(`[Config] Generated machine ID: ${id}`);
4240
4261
  return id;
4241
4262
  }
4242
4263
  function resolveWebDir() {
4243
4264
  if (process.env.WEB_DIR) return process.env.WEB_DIR;
4244
- const bundled = resolve(__dirname, "web");
4265
+ const bundled = resolve(__dirname, "web/out");
4245
4266
  if (existsSync(bundled)) return bundled;
4246
4267
  return resolve(__dirname, "../../web/out");
4247
4268
  }
4248
- function parseTelegramTokens() {
4249
- const raw = process.env.TELEGRAM_BOT_TOKENS;
4250
- if (!raw) return [];
4251
- return raw.split(",").map((t) => t.trim() || void 0);
4269
+ function buildConfig() {
4270
+ const saved = loadSavedConfig();
4271
+ return {
4272
+ machineId: getOrCreateMachineId(),
4273
+ defaultWorkspace: process.cwd(),
4274
+ wsPort: 9090,
4275
+ ablyApiKey: process.env.ABLY_API_KEY || saved.ablyApiKey || void 0,
4276
+ webDir: resolveWebDir(),
4277
+ telegramBotTokens: process.env.TELEGRAM_BOT_TOKENS ? process.env.TELEGRAM_BOT_TOKENS.split(",").map((t) => t.trim() || void 0) : (saved.telegramBotTokens ?? []).map((t) => t || void 0)
4278
+ };
4279
+ }
4280
+ var config = buildConfig();
4281
+ function reloadConfig() {
4282
+ const fresh = buildConfig();
4283
+ Object.assign(config, fresh);
4252
4284
  }
4253
- var config = {
4254
- machineId: getOrCreateMachineId(),
4255
- defaultWorkspace: process.cwd(),
4256
- wsPort: 9090,
4257
- ablyApiKey: process.env.ABLY_API_KEY || void 0,
4258
- webDir: resolveWebDir(),
4259
- telegramBotTokens: parseTelegramTokens()
4260
- };
4261
4285
 
4262
4286
  // src/ws-server.ts
4263
4287
  import { networkInterfaces } from "os";
@@ -4386,42 +4410,44 @@ var wsChannel = {
4386
4410
  }
4387
4411
  await serveStatic(req, res);
4388
4412
  });
4389
- wss = new WebSocketServer({ server: httpServer });
4390
- wss.on("connection", (ws, req) => {
4391
- clients.add(ws);
4392
- console.log(`[WS] Client connected (total: ${clients.size})`);
4393
- ws.on("message", (data) => {
4394
- try {
4395
- const parsed = CommandSchema.parse(JSON.parse(data.toString()));
4396
- onCommand?.(parsed);
4397
- } catch (err) {
4398
- console.error("[WS] Invalid command:", err);
4399
- }
4400
- });
4401
- ws.on("close", () => {
4402
- clients.delete(ws);
4403
- console.log(`[WS] Client disconnected (total: ${clients.size})`);
4404
- });
4405
- });
4406
4413
  const maxRetries = 10;
4407
4414
  let port = config.wsPort;
4408
4415
  const tryListen = () => {
4416
+ httpServer.listen(port, () => {
4417
+ config.wsPort = port;
4418
+ wss = new WebSocketServer({ server: httpServer });
4419
+ wss.on("connection", (ws) => {
4420
+ clients.add(ws);
4421
+ console.log(`[WS] Client connected (total: ${clients.size})`);
4422
+ ws.on("message", (data) => {
4423
+ try {
4424
+ const parsed = CommandSchema.parse(JSON.parse(data.toString()));
4425
+ onCommand?.(parsed);
4426
+ } catch (err) {
4427
+ console.error("[WS] Invalid command:", err);
4428
+ }
4429
+ });
4430
+ ws.on("close", () => {
4431
+ clients.delete(ws);
4432
+ console.log(`[WS] Client disconnected (total: ${clients.size})`);
4433
+ });
4434
+ });
4435
+ console.log(`[WS] Server listening on port ${port}`);
4436
+ printLanAddresses();
4437
+ resolve2(true);
4438
+ });
4409
4439
  httpServer.once("error", (err) => {
4410
4440
  if (err.code === "EADDRINUSE" && port - config.wsPort < maxRetries) {
4441
+ const oldPort = port;
4411
4442
  port++;
4412
- console.log(`[WS] Port ${port - 1} in use, trying ${port}...`);
4443
+ console.log(`[WS] Port ${oldPort} in use, trying ${port}...`);
4444
+ httpServer.close();
4413
4445
  tryListen();
4414
4446
  } else {
4415
4447
  console.error(`[WS] Failed to start server:`, err.message);
4416
4448
  resolve2(false);
4417
4449
  }
4418
4450
  });
4419
- httpServer.listen(port, () => {
4420
- config.wsPort = port;
4421
- console.log(`[WS] Server listening on port ${port}`);
4422
- printLanAddresses();
4423
- resolve2(true);
4424
- });
4425
4451
  };
4426
4452
  tryListen();
4427
4453
  });
@@ -4926,6 +4952,45 @@ var telegramChannel = {
4926
4952
  }
4927
4953
  };
4928
4954
 
4955
+ // src/setup.ts
4956
+ import { createInterface } from "readline";
4957
+ var AGENT_NAMES = ["Alex (Frontend Dev)", "Mia (Backend Dev)", "Leo (Fullstack Dev)", "Sophie (Code Reviewer)", "Yuki (QA / Tester)", "Marcus (Architect)"];
4958
+ function ask(rl, question) {
4959
+ return new Promise((resolve2) => {
4960
+ rl.question(question, (answer) => resolve2(answer.trim()));
4961
+ });
4962
+ }
4963
+ async function runSetup() {
4964
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
4965
+ console.log("");
4966
+ console.log("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557");
4967
+ console.log("\u2551 Bit Office \u2014 First Setup \u2551");
4968
+ console.log("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D");
4969
+ console.log("");
4970
+ console.log("Press Enter to skip any step.\n");
4971
+ console.log("\u2500\u2500 Remote Access (Ably) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
4972
+ console.log("Enables access from outside your LAN.");
4973
+ const ablyApiKey = await ask(rl, "Ably API Key: ");
4974
+ console.log("\n\u2500\u2500 Telegram Bots \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
4975
+ console.log("Each bot becomes one AI agent.");
4976
+ console.log("Create bots via @BotFather on Telegram.\n");
4977
+ const tokens = [];
4978
+ for (let i = 0; i < 6; i++) {
4979
+ const token = await ask(rl, ` ${i + 1}. ${AGENT_NAMES[i]} token: `);
4980
+ tokens.push(token || null);
4981
+ }
4982
+ rl.close();
4983
+ saveConfig({
4984
+ ablyApiKey: ablyApiKey || void 0,
4985
+ telegramBotTokens: tokens
4986
+ });
4987
+ const activeCount = tokens.filter(Boolean).length;
4988
+ console.log("\n\u2713 Config saved to ~/.bit-office/config.json");
4989
+ if (ablyApiKey) console.log(" \u2022 Ably: enabled");
4990
+ if (activeCount > 0) console.log(` \u2022 Telegram: ${activeCount} bot(s)`);
4991
+ console.log(" \u2022 Run with --setup to reconfigure\n");
4992
+ }
4993
+
4929
4994
  // src/index.ts
4930
4995
  import { nanoid as nanoid3 } from "nanoid";
4931
4996
  import { exec } from "child_process";
@@ -5041,6 +5106,10 @@ function handleCommand(parsed) {
5041
5106
  }
5042
5107
  }
5043
5108
  async function main() {
5109
+ if (!hasSetupRun() || process.argv.includes("--setup")) {
5110
+ await runSetup();
5111
+ reloadConfig();
5112
+ }
5044
5113
  console.log(`[Gateway] Starting for machine: ${config.machineId}`);
5045
5114
  showPairCode();
5046
5115
  await initTransports(handleCommand);