@sarkar-ai/deskmate 0.2.0

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.
@@ -0,0 +1,387 @@
1
+ "use strict";
2
+ /**
3
+ * Interactive Setup Wizard
4
+ *
5
+ * Self-contained setup: writes .env, optionally installs a background service
6
+ * (launchd on macOS, systemd on Linux), and guides through macOS permissions.
7
+ *
8
+ * For an alternative shell-based installer, see ./install.sh.
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.runInitWizard = runInitWizard;
45
+ const readline = __importStar(require("readline"));
46
+ const fs = __importStar(require("fs/promises"));
47
+ const path = __importStar(require("path"));
48
+ const os = __importStar(require("os"));
49
+ const child_process_1 = require("child_process");
50
+ // ---------------------------------------------------------------------------
51
+ // Helpers
52
+ // ---------------------------------------------------------------------------
53
+ function createPrompt() {
54
+ return readline.createInterface({
55
+ input: process.stdin,
56
+ output: process.stdout,
57
+ });
58
+ }
59
+ function ask(rl, question) {
60
+ return new Promise((resolve) => {
61
+ rl.question(question, (answer) => resolve(answer.trim()));
62
+ });
63
+ }
64
+ async function askYesNo(rl, question, defaultYes = true) {
65
+ const hint = defaultYes ? "[Y/n]" : "[y/N]";
66
+ const answer = await ask(rl, `${question} ${hint}: `);
67
+ if (answer === "")
68
+ return defaultYes;
69
+ return answer.toLowerCase() === "y";
70
+ }
71
+ async function checkClaudeCLI() {
72
+ try {
73
+ (0, child_process_1.execSync)("which claude", { stdio: "ignore" });
74
+ return true;
75
+ }
76
+ catch {
77
+ return false;
78
+ }
79
+ }
80
+ function detectPlatform() {
81
+ switch (process.platform) {
82
+ case "darwin":
83
+ return "macos";
84
+ case "linux":
85
+ return "linux";
86
+ case "win32":
87
+ return "windows";
88
+ default:
89
+ return "unsupported";
90
+ }
91
+ }
92
+ // ---------------------------------------------------------------------------
93
+ // Service installation helpers
94
+ // ---------------------------------------------------------------------------
95
+ const PLIST_NAME = "com.deskmate.service";
96
+ function plistPath() {
97
+ return path.join(os.homedir(), "Library", "LaunchAgents", `${PLIST_NAME}.plist`);
98
+ }
99
+ function systemdDir() {
100
+ return path.join(os.homedir(), ".config", "systemd", "user");
101
+ }
102
+ function systemdPath() {
103
+ return path.join(systemdDir(), "deskmate.service");
104
+ }
105
+ function buildPlist(nodePath, projectDir, logsDir, runMode) {
106
+ return `<?xml version="1.0" encoding="UTF-8"?>
107
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
108
+ <plist version="1.0">
109
+ <dict>
110
+ <key>Label</key>
111
+ <string>${PLIST_NAME}</string>
112
+
113
+ <key>ProgramArguments</key>
114
+ <array>
115
+ <string>${nodePath}</string>
116
+ <string>${projectDir}/dist/index.js</string>
117
+ <string>${runMode}</string>
118
+ </array>
119
+
120
+ <key>WorkingDirectory</key>
121
+ <string>${projectDir}</string>
122
+
123
+ <key>EnvironmentVariables</key>
124
+ <dict>
125
+ <key>PATH</key>
126
+ <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:${os.homedir()}/.local/bin</string>
127
+ </dict>
128
+
129
+ <key>RunAtLoad</key>
130
+ <true/>
131
+
132
+ <key>KeepAlive</key>
133
+ <true/>
134
+
135
+ <key>StandardOutPath</key>
136
+ <string>${logsDir}/stdout.log</string>
137
+
138
+ <key>StandardErrorPath</key>
139
+ <string>${logsDir}/stderr.log</string>
140
+ </dict>
141
+ </plist>`;
142
+ }
143
+ function buildSystemdUnit(nodePath, projectDir, logsDir, runMode) {
144
+ return `[Unit]
145
+ Description=Deskmate - Local Machine Assistant
146
+ After=network-online.target
147
+ Wants=network-online.target
148
+
149
+ [Service]
150
+ Type=simple
151
+ ExecStart=${nodePath} ${projectDir}/dist/index.js ${runMode}
152
+ WorkingDirectory=${projectDir}
153
+ Environment=PATH=/usr/local/bin:/usr/bin:/bin:${os.homedir()}/.local/bin
154
+ Restart=always
155
+ RestartSec=5
156
+
157
+ InhibitDelayMaxSec=5
158
+
159
+ StandardOutput=append:${logsDir}/stdout.log
160
+ StandardError=append:${logsDir}/stderr.log
161
+
162
+ [Install]
163
+ WantedBy=default.target`;
164
+ }
165
+ async function installMacosService(projectDir, logsDir, runMode) {
166
+ const nodePath = process.execPath;
167
+ const dest = plistPath();
168
+ // Unload existing
169
+ try {
170
+ (0, child_process_1.execSync)(`launchctl list 2>/dev/null | grep -q "${PLIST_NAME}" && launchctl unload "${dest}"`, {
171
+ stdio: "ignore",
172
+ shell: "/bin/bash",
173
+ });
174
+ }
175
+ catch {
176
+ // not loaded — fine
177
+ }
178
+ await fs.mkdir(path.dirname(dest), { recursive: true });
179
+ await fs.mkdir(logsDir, { recursive: true });
180
+ await fs.writeFile(dest, buildPlist(nodePath, projectDir, logsDir, runMode), "utf-8");
181
+ (0, child_process_1.execSync)(`launchctl load "${dest}"`);
182
+ console.log("\n Service installed and started via launchd.");
183
+ console.log(` Plist: ${dest}`);
184
+ }
185
+ async function installLinuxService(projectDir, logsDir, runMode) {
186
+ const nodePath = process.execPath;
187
+ const dest = systemdPath();
188
+ // Stop existing
189
+ try {
190
+ (0, child_process_1.execSync)("systemctl --user stop deskmate.service", { stdio: "ignore" });
191
+ }
192
+ catch {
193
+ // not running — fine
194
+ }
195
+ await fs.mkdir(systemdDir(), { recursive: true });
196
+ await fs.mkdir(logsDir, { recursive: true });
197
+ await fs.writeFile(dest, buildSystemdUnit(nodePath, projectDir, logsDir, runMode), "utf-8");
198
+ (0, child_process_1.execSync)("systemctl --user daemon-reload");
199
+ (0, child_process_1.execSync)("systemctl --user enable deskmate.service");
200
+ (0, child_process_1.execSync)("systemctl --user start deskmate.service");
201
+ // Enable lingering so the service survives logout
202
+ try {
203
+ (0, child_process_1.execSync)(`loginctl enable-linger "$(whoami)"`, { stdio: "ignore", shell: "/bin/bash" });
204
+ }
205
+ catch {
206
+ // loginctl may not be available
207
+ }
208
+ console.log("\n Service installed and started via systemd.");
209
+ console.log(` Unit file: ${dest}`);
210
+ }
211
+ // ---------------------------------------------------------------------------
212
+ // macOS permissions helper
213
+ // ---------------------------------------------------------------------------
214
+ async function offerMacosPermissions(rl) {
215
+ console.log("\n--- macOS Permissions ---\n");
216
+ console.log(" Deskmate works best with the following permissions:");
217
+ console.log(" - Screen Recording (screenshots)");
218
+ console.log(" - Accessibility (system control)");
219
+ console.log(" - Full Disk Access (read/write anywhere)");
220
+ console.log(" - Automation (AppleScript)");
221
+ console.log("");
222
+ if (await askYesNo(rl, "Trigger Screen Recording permission dialog?")) {
223
+ try {
224
+ (0, child_process_1.execSync)("screencapture -x /tmp/deskmate-test-screenshot.png", { stdio: "ignore" });
225
+ (0, child_process_1.execSync)("rm -f /tmp/deskmate-test-screenshot.png", { stdio: "ignore" });
226
+ }
227
+ catch {
228
+ // permission dialog may have appeared
229
+ }
230
+ console.log(" If a dialog appeared, click Allow.\n");
231
+ }
232
+ if (await askYesNo(rl, "Open Accessibility settings?")) {
233
+ (0, child_process_1.execSync)('open "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"');
234
+ await ask(rl, " Press Enter when done...");
235
+ }
236
+ if (await askYesNo(rl, "Open Full Disk Access settings?")) {
237
+ (0, child_process_1.execSync)('open "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles"');
238
+ await ask(rl, " Press Enter when done...");
239
+ }
240
+ if (await askYesNo(rl, "Open Automation settings?")) {
241
+ (0, child_process_1.execSync)('open "x-apple.systempreferences:com.apple.preference.security?Privacy_Automation"');
242
+ await ask(rl, " Press Enter when done...");
243
+ }
244
+ }
245
+ // ---------------------------------------------------------------------------
246
+ // Management commands summary
247
+ // ---------------------------------------------------------------------------
248
+ function printManagementCommands(platform, logsDir) {
249
+ console.log("\nManagement commands:\n");
250
+ console.log(` View logs: tail -f ${logsDir}/stdout.log`);
251
+ if (platform === "macos") {
252
+ const dest = plistPath();
253
+ console.log(` Stop service: launchctl unload "${dest}"`);
254
+ console.log(` Start service: launchctl load "${dest}"`);
255
+ console.log(` Check status: launchctl list | grep deskmate`);
256
+ }
257
+ else if (platform === "linux") {
258
+ console.log(" Stop service: systemctl --user stop deskmate.service");
259
+ console.log(" Start service: systemctl --user start deskmate.service");
260
+ console.log(" Restart service: systemctl --user restart deskmate.service");
261
+ console.log(" Check status: systemctl --user status deskmate.service");
262
+ }
263
+ else if (platform === "windows") {
264
+ console.log(" On Windows (WSL2), manage the service from inside your WSL2 terminal.");
265
+ console.log(" Stop service: systemctl --user stop deskmate.service");
266
+ console.log(" Start service: systemctl --user start deskmate.service");
267
+ }
268
+ }
269
+ // ---------------------------------------------------------------------------
270
+ // Main wizard
271
+ // ---------------------------------------------------------------------------
272
+ async function runInitWizard() {
273
+ const rl = createPrompt();
274
+ console.log("\n========================================");
275
+ console.log(" Deskmate Setup Wizard");
276
+ console.log("========================================\n");
277
+ const platform = detectPlatform();
278
+ console.log(`Detected platform: ${platform}\n`);
279
+ if (platform === "windows") {
280
+ console.log("Native Windows is not directly supported.");
281
+ console.log("Please run this wizard inside a WSL2 terminal.\n");
282
+ }
283
+ const hasClaude = await checkClaudeCLI();
284
+ if (!hasClaude) {
285
+ console.log("WARNING: 'claude' CLI not found in PATH.");
286
+ console.log("Install it from: https://docs.anthropic.com/en/docs/claude-code");
287
+ console.log("");
288
+ }
289
+ // ----- Step 1: .env wizard -----
290
+ const env = {};
291
+ env.AGENT_PROVIDER = "claude-code";
292
+ const apiKey = await ask(rl, "Anthropic API Key (for Claude Code): ");
293
+ if (apiKey)
294
+ env.ANTHROPIC_API_KEY = apiKey;
295
+ console.log("\n--- Telegram Configuration ---\n");
296
+ console.log(" Bot token → message @BotFather on Telegram, send /newbot");
297
+ console.log(" User ID → message @userinfobot on Telegram, copy the number");
298
+ console.log("");
299
+ const token = await ask(rl, "Telegram Bot Token (from @BotFather): ");
300
+ if (token)
301
+ env.TELEGRAM_BOT_TOKEN = token;
302
+ const userId = await ask(rl, "Your Telegram User ID (from @userinfobot): ");
303
+ if (userId) {
304
+ env.ALLOWED_USER_ID = userId;
305
+ env.ALLOWED_USERS = `telegram:${userId}`;
306
+ }
307
+ console.log("\n--- General Configuration ---\n");
308
+ const workingDir = await ask(rl, `Working directory (default: ${os.homedir()}): `);
309
+ if (workingDir)
310
+ env.WORKING_DIR = workingDir;
311
+ const botName = await ask(rl, "Bot name (default: Deskmate): ");
312
+ if (botName)
313
+ env.BOT_NAME = botName;
314
+ // ----- Step 2: Write .env -----
315
+ const envPath = path.join(process.cwd(), ".env");
316
+ let envContent = "# Deskmate Configuration (generated by deskmate init)\n\n";
317
+ for (const [key, value] of Object.entries(env)) {
318
+ envContent += `${key}=${value}\n`;
319
+ }
320
+ if (!env.LOG_LEVEL)
321
+ envContent += "LOG_LEVEL=info\n";
322
+ if (!env.REQUIRE_APPROVAL_FOR_ALL)
323
+ envContent += "REQUIRE_APPROVAL_FOR_ALL=false\n";
324
+ try {
325
+ let envExists = false;
326
+ try {
327
+ await fs.access(envPath);
328
+ envExists = true;
329
+ }
330
+ catch {
331
+ // does not exist
332
+ }
333
+ if (envExists) {
334
+ console.log(`\nWARNING: .env file already exists at ${envPath}`);
335
+ const newPath = envPath + ".new";
336
+ await fs.writeFile(newPath, envContent, "utf-8");
337
+ console.log(`Configuration saved to ${newPath}`);
338
+ console.log("Review and rename it to .env when ready.");
339
+ }
340
+ else {
341
+ await fs.writeFile(envPath, envContent, "utf-8");
342
+ console.log(`\nConfiguration saved to ${envPath}`);
343
+ }
344
+ }
345
+ catch (error) {
346
+ console.error(`\nFailed to write config: ${error.message}`);
347
+ console.log("\nHere is your configuration:\n");
348
+ console.log(envContent);
349
+ }
350
+ // ----- Step 3: Service installation -----
351
+ if (platform === "macos" || platform === "linux") {
352
+ console.log("");
353
+ const installService = await askYesNo(rl, "Install as background service?");
354
+ if (installService) {
355
+ // Determine project root (where package.json lives)
356
+ const projectDir = path.resolve(__dirname, "..");
357
+ const logsDir = path.join(projectDir, "logs");
358
+ const runMode = "gateway";
359
+ try {
360
+ if (platform === "macos") {
361
+ await installMacosService(projectDir, logsDir, runMode);
362
+ }
363
+ else {
364
+ await installLinuxService(projectDir, logsDir, runMode);
365
+ }
366
+ }
367
+ catch (err) {
368
+ console.error(`\n Failed to install service: ${err.message}`);
369
+ console.log(" You can install manually with ./install.sh");
370
+ }
371
+ // macOS permissions
372
+ if (platform === "macos") {
373
+ const setupPerms = await askYesNo(rl, "\nConfigure macOS permissions?");
374
+ if (setupPerms) {
375
+ await offerMacosPermissions(rl);
376
+ }
377
+ }
378
+ printManagementCommands(platform, logsDir);
379
+ }
380
+ }
381
+ else if (platform === "windows") {
382
+ console.log("\nTo run as a service on Windows, open a WSL2 terminal and run: deskmate init");
383
+ }
384
+ rl.close();
385
+ console.log("\nSetup complete! Your bot is ready.");
386
+ console.log("");
387
+ }
package/dist/cli.js ADDED
@@ -0,0 +1,184 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.buildAllowedUsers = buildAllowedUsers;
38
+ require("dotenv/config");
39
+ const fs = __importStar(require("fs"));
40
+ const path = __importStar(require("path"));
41
+ const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "..", "package.json"), "utf-8"));
42
+ const VERSION = pkg.version;
43
+ const BOT_NAME = process.env.BOT_NAME || "Deskmate";
44
+ function printHelp() {
45
+ console.log(`
46
+ ${BOT_NAME} - Control your machine from anywhere using natural language
47
+
48
+ Usage:
49
+ deskmate <command> [options]
50
+
51
+ Commands:
52
+ telegram Start the Telegram bot (default)
53
+ mcp Start the MCP server
54
+ both Start both Telegram bot and MCP server
55
+ gateway Start the multi-client gateway
56
+ init Interactive setup wizard
57
+
58
+ Options:
59
+ -h, --help Show this help message
60
+ -v, --version Show version number
61
+
62
+ Examples:
63
+ deskmate Start in Telegram mode
64
+ deskmate telegram Start the Telegram bot
65
+ deskmate mcp Start the MCP server
66
+ deskmate gateway Start multi-client gateway
67
+ deskmate init Run the setup wizard
68
+ deskmate --version Print version
69
+
70
+ Environment:
71
+ AGENT_PROVIDER Agent provider (default: claude-code)
72
+ TELEGRAM_BOT_TOKEN Telegram bot token
73
+ ANTHROPIC_API_KEY Anthropic API key
74
+ ALLOWED_USERS Multi-client allowlist (e.g. telegram:123,discord:456)
75
+ `);
76
+ }
77
+ function buildAllowedUsers() {
78
+ const users = [];
79
+ const multiClient = process.env.ALLOWED_USERS;
80
+ if (multiClient) {
81
+ for (const entry of multiClient.split(",").map((s) => s.trim()).filter(Boolean)) {
82
+ const colonIdx = entry.indexOf(":");
83
+ if (colonIdx > 0) {
84
+ users.push({
85
+ clientType: entry.slice(0, colonIdx),
86
+ platformUserId: entry.slice(colonIdx + 1),
87
+ });
88
+ }
89
+ }
90
+ }
91
+ const legacyId = process.env.ALLOWED_USER_ID;
92
+ if (legacyId && legacyId !== "0") {
93
+ const alreadyHas = users.some((u) => u.clientType === "telegram" && u.platformUserId === legacyId);
94
+ if (!alreadyHas) {
95
+ users.push({ clientType: "telegram", platformUserId: legacyId });
96
+ }
97
+ }
98
+ return users;
99
+ }
100
+ async function main() {
101
+ const args = process.argv.slice(2);
102
+ const command = args.find((a) => !a.startsWith("-")) || "telegram";
103
+ const flags = new Set(args.filter((a) => a.startsWith("-")));
104
+ if (flags.has("--help") || flags.has("-h")) {
105
+ printHelp();
106
+ process.exit(0);
107
+ }
108
+ if (flags.has("--version") || flags.has("-v")) {
109
+ console.log(VERSION);
110
+ process.exit(0);
111
+ }
112
+ // If no explicit command and no .env found, suggest running init
113
+ if (!args.find((a) => !a.startsWith("-")) &&
114
+ !fs.existsSync(path.join(process.cwd(), ".env"))) {
115
+ console.log(`No .env file found. Run "deskmate init" to get started.\n`);
116
+ }
117
+ switch (command) {
118
+ case "telegram": {
119
+ console.log(`Starting ${BOT_NAME} in telegram mode...`);
120
+ const { startTelegramBot } = await Promise.resolve().then(() => __importStar(require("./telegram/bot")));
121
+ await startTelegramBot();
122
+ break;
123
+ }
124
+ case "mcp": {
125
+ console.log(`Starting ${BOT_NAME} in mcp mode...`);
126
+ const { startMcpServer } = await Promise.resolve().then(() => __importStar(require("./mcp/server")));
127
+ await startMcpServer();
128
+ break;
129
+ }
130
+ case "both": {
131
+ console.log(`Starting ${BOT_NAME} in both mode...`);
132
+ const [{ startTelegramBot: startBot }, { startMcpServer: startMcp }] = await Promise.all([
133
+ Promise.resolve().then(() => __importStar(require("./telegram/bot"))),
134
+ Promise.resolve().then(() => __importStar(require("./mcp/server"))),
135
+ ]);
136
+ startBot().catch(console.error);
137
+ await startMcp();
138
+ break;
139
+ }
140
+ case "gateway": {
141
+ console.log(`Starting ${BOT_NAME} in gateway mode...`);
142
+ const { Gateway } = await Promise.resolve().then(() => __importStar(require("./gateway")));
143
+ const { TelegramClient } = await Promise.resolve().then(() => __importStar(require("./clients/telegram")));
144
+ const allowedUsers = buildAllowedUsers();
145
+ if (allowedUsers.length === 0) {
146
+ console.error("No allowed users configured. Set ALLOWED_USERS or ALLOWED_USER_ID in your .env");
147
+ process.exit(1);
148
+ }
149
+ const gateway = new Gateway({
150
+ botName: BOT_NAME,
151
+ workingDir: process.env.WORKING_DIR || process.env.HOME || "/",
152
+ allowedUsers,
153
+ maxTurns: 10,
154
+ });
155
+ if (process.env.TELEGRAM_BOT_TOKEN) {
156
+ gateway.registerClient(new TelegramClient(process.env.TELEGRAM_BOT_TOKEN));
157
+ }
158
+ await gateway.start();
159
+ break;
160
+ }
161
+ case "setup":
162
+ case "init": {
163
+ const { runInitWizard } = await Promise.resolve().then(() => __importStar(require("./cli/init")));
164
+ await runInitWizard();
165
+ break;
166
+ }
167
+ default:
168
+ console.error(`Unknown command: ${command}`);
169
+ console.error('Run "deskmate --help" for usage information.');
170
+ process.exit(1);
171
+ }
172
+ }
173
+ main().catch((error) => {
174
+ console.error("Fatal error:", error);
175
+ process.exit(1);
176
+ });
177
+ process.on("SIGINT", () => {
178
+ console.log("\nShutting down...");
179
+ process.exit(0);
180
+ });
181
+ process.on("SIGTERM", () => {
182
+ console.log("\nShutting down...");
183
+ process.exit(0);
184
+ });