cyrus-ai 0.1.58 → 0.2.0-rc.1

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.
Files changed (59) hide show
  1. package/dist/app.js +166 -2
  2. package/dist/app.js.map +1 -1
  3. package/dist/src/Application.d.ts +69 -0
  4. package/dist/src/Application.d.ts.map +1 -0
  5. package/dist/src/Application.js +273 -0
  6. package/dist/src/Application.js.map +1 -0
  7. package/dist/src/app.d.ts +3 -0
  8. package/dist/src/app.d.ts.map +1 -0
  9. package/dist/src/app.js +101 -0
  10. package/dist/src/app.js.map +1 -0
  11. package/dist/src/commands/AuthCommand.d.ts +8 -0
  12. package/dist/src/commands/AuthCommand.d.ts.map +1 -0
  13. package/dist/src/commands/AuthCommand.js +69 -0
  14. package/dist/src/commands/AuthCommand.js.map +1 -0
  15. package/dist/src/commands/CheckTokensCommand.d.ts +8 -0
  16. package/dist/src/commands/CheckTokensCommand.d.ts.map +1 -0
  17. package/dist/src/commands/CheckTokensCommand.js +53 -0
  18. package/dist/src/commands/CheckTokensCommand.js.map +1 -0
  19. package/dist/src/commands/ICommand.d.ts +38 -0
  20. package/dist/src/commands/ICommand.d.ts.map +1 -0
  21. package/dist/src/commands/ICommand.js +37 -0
  22. package/dist/src/commands/ICommand.js.map +1 -0
  23. package/dist/src/commands/RefreshTokenCommand.d.ts +8 -0
  24. package/dist/src/commands/RefreshTokenCommand.d.ts.map +1 -0
  25. package/dist/src/commands/RefreshTokenCommand.js +152 -0
  26. package/dist/src/commands/RefreshTokenCommand.js.map +1 -0
  27. package/dist/src/commands/StartCommand.d.ts +8 -0
  28. package/dist/src/commands/StartCommand.d.ts.map +1 -0
  29. package/dist/src/commands/StartCommand.js +70 -0
  30. package/dist/src/commands/StartCommand.js.map +1 -0
  31. package/dist/src/config/constants.d.ts +12 -0
  32. package/dist/src/config/constants.d.ts.map +1 -0
  33. package/dist/src/config/constants.js +19 -0
  34. package/dist/src/config/constants.js.map +1 -0
  35. package/dist/src/config/types.d.ts +21 -0
  36. package/dist/src/config/types.d.ts.map +1 -0
  37. package/dist/src/config/types.js +2 -0
  38. package/dist/src/config/types.js.map +1 -0
  39. package/dist/src/services/ConfigService.d.ts +32 -0
  40. package/dist/src/services/ConfigService.d.ts.map +1 -0
  41. package/dist/src/services/ConfigService.js +72 -0
  42. package/dist/src/services/ConfigService.js.map +1 -0
  43. package/dist/src/services/GitService.d.ts +28 -0
  44. package/dist/src/services/GitService.d.ts.map +1 -0
  45. package/dist/src/services/GitService.js +339 -0
  46. package/dist/src/services/GitService.js.map +1 -0
  47. package/dist/src/services/Logger.d.ts +88 -0
  48. package/dist/src/services/Logger.d.ts.map +1 -0
  49. package/dist/src/services/Logger.js +146 -0
  50. package/dist/src/services/Logger.js.map +1 -0
  51. package/dist/src/services/WorkerService.d.ts +53 -0
  52. package/dist/src/services/WorkerService.d.ts.map +1 -0
  53. package/dist/src/services/WorkerService.js +173 -0
  54. package/dist/src/services/WorkerService.js.map +1 -0
  55. package/dist/src/ui/CLIPrompts.d.ts +18 -0
  56. package/dist/src/ui/CLIPrompts.d.ts.map +1 -0
  57. package/dist/src/ui/CLIPrompts.js +53 -0
  58. package/dist/src/ui/CLIPrompts.js.map +1 -0
  59. package/package.json +10 -9
@@ -0,0 +1,273 @@
1
+ import { existsSync, mkdirSync, watch } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { DEFAULT_PROXY_URL } from "cyrus-core";
4
+ import { SharedApplicationServer } from "cyrus-edge-worker";
5
+ import dotenv from "dotenv";
6
+ import { DEFAULT_SERVER_PORT, parsePort } from "./config/constants.js";
7
+ import { ConfigService } from "./services/ConfigService.js";
8
+ import { GitService } from "./services/GitService.js";
9
+ import { Logger } from "./services/Logger.js";
10
+ import { WorkerService } from "./services/WorkerService.js";
11
+ /**
12
+ * Main application context providing access to services
13
+ */
14
+ export class Application {
15
+ cyrusHome;
16
+ config;
17
+ git;
18
+ worker;
19
+ logger;
20
+ envWatcher;
21
+ configWatcher;
22
+ isInSetupWaitingMode = false;
23
+ constructor(cyrusHome) {
24
+ this.cyrusHome = cyrusHome;
25
+ // Initialize logger first
26
+ this.logger = new Logger();
27
+ // Ensure required directories exist
28
+ this.ensureRequiredDirectories();
29
+ // Load environment variables from CYRUS_HOME/.env
30
+ this.loadEnvFile();
31
+ // Watch .env file for changes and reload
32
+ this.setupEnvFileWatcher();
33
+ // Initialize services
34
+ this.config = new ConfigService(cyrusHome, this.logger);
35
+ this.git = new GitService(this.logger);
36
+ this.worker = new WorkerService(this.config, this.git, cyrusHome, this.logger);
37
+ }
38
+ /**
39
+ * Load environment variables from ~/.cyrus/.env file
40
+ */
41
+ loadEnvFile() {
42
+ const cyrusEnvPath = join(this.cyrusHome, ".env");
43
+ if (existsSync(cyrusEnvPath)) {
44
+ dotenv.config({ path: cyrusEnvPath, override: true });
45
+ this.logger.info(`🔧 Loaded environment variables from ${cyrusEnvPath}`);
46
+ }
47
+ }
48
+ /**
49
+ * Setup file watcher for .env file to reload on changes
50
+ */
51
+ setupEnvFileWatcher() {
52
+ const cyrusEnvPath = join(this.cyrusHome, ".env");
53
+ // Only watch if file exists
54
+ if (!existsSync(cyrusEnvPath)) {
55
+ return;
56
+ }
57
+ try {
58
+ this.envWatcher = watch(cyrusEnvPath, (eventType) => {
59
+ if (eventType === "change") {
60
+ this.logger.info("🔄 .env file changed, reloading...");
61
+ this.loadEnvFile();
62
+ }
63
+ });
64
+ this.logger.info(`👀 Watching .env file for changes: ${cyrusEnvPath}`);
65
+ }
66
+ catch (error) {
67
+ this.logger.error(`❌ Failed to watch .env file: ${error}`);
68
+ }
69
+ }
70
+ /**
71
+ * Ensure required Cyrus directories exist
72
+ * Creates: ~/.cyrus/repos, ~/.cyrus/worktrees, ~/.cyrus/mcp-configs
73
+ */
74
+ ensureRequiredDirectories() {
75
+ const requiredDirs = ["repos", "worktrees", "mcp-configs"];
76
+ for (const dir of requiredDirs) {
77
+ const dirPath = join(this.cyrusHome, dir);
78
+ if (!existsSync(dirPath)) {
79
+ try {
80
+ mkdirSync(dirPath, { recursive: true });
81
+ this.logger.info(`📁 Created directory: ${dirPath}`);
82
+ }
83
+ catch (error) {
84
+ this.logger.error(`❌ Failed to create directory ${dirPath}: ${error}`);
85
+ throw error;
86
+ }
87
+ }
88
+ }
89
+ }
90
+ /**
91
+ * Get proxy URL from environment or use default
92
+ */
93
+ getProxyUrl() {
94
+ return process.env.PROXY_URL || DEFAULT_PROXY_URL;
95
+ }
96
+ /**
97
+ * Check if using default proxy
98
+ */
99
+ isUsingDefaultProxy() {
100
+ return this.getProxyUrl() === DEFAULT_PROXY_URL;
101
+ }
102
+ /**
103
+ * Create a temporary SharedApplicationServer for OAuth
104
+ */
105
+ async createTempServer() {
106
+ const serverPort = parsePort(process.env.CYRUS_SERVER_PORT, DEFAULT_SERVER_PORT);
107
+ return new SharedApplicationServer(serverPort);
108
+ }
109
+ /**
110
+ * Enable setup waiting mode and start watching config.json for repositories
111
+ */
112
+ enableSetupWaitingMode() {
113
+ this.isInSetupWaitingMode = true;
114
+ this.startConfigWatcher();
115
+ }
116
+ /**
117
+ * Setup file watcher for config.json to detect when repositories are added
118
+ */
119
+ startConfigWatcher() {
120
+ const configPath = this.config.getConfigPath();
121
+ // Create empty config file if it doesn't exist
122
+ if (!existsSync(configPath)) {
123
+ try {
124
+ const configDir = dirname(configPath);
125
+ if (!existsSync(configDir)) {
126
+ mkdirSync(configDir, { recursive: true });
127
+ }
128
+ // Create empty config with empty repositories array
129
+ this.config.save({ repositories: [] });
130
+ this.logger.info(`📝 Created empty config file: ${configPath}`);
131
+ }
132
+ catch (error) {
133
+ this.logger.error(`❌ Failed to create config file: ${error}`);
134
+ return;
135
+ }
136
+ }
137
+ try {
138
+ this.configWatcher = watch(configPath, async (eventType) => {
139
+ if (eventType === "change" && this.isInSetupWaitingMode) {
140
+ this.logger.info("🔄 Configuration file changed, checking for repositories...");
141
+ // Reload config and check if repositories were added
142
+ const edgeConfig = this.config.load();
143
+ const repositories = edgeConfig.repositories || [];
144
+ if (repositories.length > 0) {
145
+ this.logger.success("✅ Configuration received!");
146
+ this.logger.info(`📦 Starting edge worker with ${repositories.length} repository(ies)...`);
147
+ // Remove CYRUS_SETUP_PENDING flag from .env
148
+ await this.removeSetupPendingFlag();
149
+ // Transition to normal operation mode
150
+ await this.transitionToNormalMode(repositories);
151
+ }
152
+ }
153
+ });
154
+ this.logger.info(`👀 Watching config.json for repository configuration: ${configPath}`);
155
+ }
156
+ catch (error) {
157
+ this.logger.error(`❌ Failed to watch config.json: ${error}`);
158
+ }
159
+ }
160
+ /**
161
+ * Remove CYRUS_SETUP_PENDING flag from .env file
162
+ */
163
+ async removeSetupPendingFlag() {
164
+ const { readFile, writeFile } = await import("node:fs/promises");
165
+ const envPath = join(this.cyrusHome, ".env");
166
+ if (!existsSync(envPath)) {
167
+ return;
168
+ }
169
+ try {
170
+ const envContent = await readFile(envPath, "utf-8");
171
+ const updatedContent = envContent
172
+ .split("\n")
173
+ .filter((line) => !line.startsWith("CYRUS_SETUP_PENDING="))
174
+ .join("\n");
175
+ await writeFile(envPath, updatedContent, "utf-8");
176
+ this.logger.info("✅ Removed CYRUS_SETUP_PENDING flag from .env");
177
+ // Reload environment variables
178
+ this.loadEnvFile();
179
+ }
180
+ catch (error) {
181
+ this.logger.error(`❌ Failed to remove CYRUS_SETUP_PENDING flag: ${error}`);
182
+ }
183
+ }
184
+ /**
185
+ * Transition from setup waiting mode to normal operation
186
+ */
187
+ async transitionToNormalMode(repositories) {
188
+ try {
189
+ this.isInSetupWaitingMode = false;
190
+ // Close config watcher
191
+ if (this.configWatcher) {
192
+ this.configWatcher.close();
193
+ this.configWatcher = undefined;
194
+ }
195
+ // Stop the setup waiting mode server before starting EdgeWorker
196
+ await this.worker.stopSetupWaitingMode();
197
+ // Start the EdgeWorker with the new configuration
198
+ await this.worker.startEdgeWorker({
199
+ repositories,
200
+ });
201
+ // Display server information
202
+ const serverPort = this.worker.getServerPort();
203
+ this.logger.raw("");
204
+ this.logger.divider(70);
205
+ this.logger.success("Edge worker started successfully");
206
+ this.logger.info(`🔗 Server running on port ${serverPort}`);
207
+ if (process.env.CLOUDFLARE_TOKEN) {
208
+ this.logger.info("🌩️ Cloudflare tunnel: Active");
209
+ }
210
+ this.logger.info(`\n📦 Managing ${repositories.length} repositories:`);
211
+ repositories.forEach((repo) => {
212
+ this.logger.info(` • ${repo.name} (${repo.repositoryPath})`);
213
+ });
214
+ this.logger.divider(70);
215
+ }
216
+ catch (error) {
217
+ this.logger.error(`❌ Failed to transition to normal mode: ${error}`);
218
+ process.exit(1);
219
+ }
220
+ }
221
+ /**
222
+ * Handle graceful shutdown
223
+ */
224
+ async shutdown() {
225
+ // Close .env file watcher
226
+ if (this.envWatcher) {
227
+ this.envWatcher.close();
228
+ }
229
+ // Close config file watcher
230
+ if (this.configWatcher) {
231
+ this.configWatcher.close();
232
+ }
233
+ await this.worker.stop();
234
+ process.exit(0);
235
+ }
236
+ /**
237
+ * Setup process signal handlers
238
+ */
239
+ setupSignalHandlers() {
240
+ process.on("SIGINT", () => {
241
+ this.logger.info("\nReceived SIGINT, shutting down gracefully...");
242
+ void this.shutdown();
243
+ });
244
+ process.on("SIGTERM", () => {
245
+ this.logger.info("\nReceived SIGTERM, shutting down gracefully...");
246
+ void this.shutdown();
247
+ });
248
+ // Handle uncaught exceptions and unhandled promise rejections
249
+ process.on("uncaughtException", (error) => {
250
+ this.logger.error(`🚨 Uncaught Exception: ${error.message}`);
251
+ this.logger.error(`Error type: ${error.constructor.name}`);
252
+ this.logger.error(`Stack: ${error.stack}`);
253
+ this.logger.error("This error was caught by the global handler, preventing application crash");
254
+ // Attempt graceful shutdown but don't wait indefinitely
255
+ this.shutdown().finally(() => {
256
+ this.logger.error("Process exiting due to uncaught exception");
257
+ process.exit(1);
258
+ });
259
+ });
260
+ process.on("unhandledRejection", (reason, promise) => {
261
+ this.logger.error(`🚨 Unhandled Promise Rejection at: ${promise}`);
262
+ this.logger.error(`Reason: ${reason}`);
263
+ this.logger.error("This rejection was caught by the global handler, continuing operation");
264
+ // Log stack trace if reason is an Error
265
+ if (reason instanceof Error && reason.stack) {
266
+ this.logger.error(`Stack: ${reason.stack}`);
267
+ }
268
+ // Log the error but don't exit the process for promise rejections
269
+ // as they might be recoverable
270
+ });
271
+ }
272
+ }
273
+ //# sourceMappingURL=Application.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Application.js","sourceRoot":"","sources":["../../src/Application.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D;;GAEG;AACH,MAAM,OAAO,WAAW;IASK;IARZ,MAAM,CAAgB;IACtB,GAAG,CAAa;IAChB,MAAM,CAAgB;IACtB,MAAM,CAAS;IACvB,UAAU,CAA4B;IACtC,aAAa,CAA4B;IACzC,oBAAoB,GAAG,KAAK,CAAC;IAErC,YAA4B,SAAiB;QAAjB,cAAS,GAAT,SAAS,CAAQ;QAC5C,0BAA0B;QAC1B,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QAE3B,oCAAoC;QACpC,IAAI,CAAC,yBAAyB,EAAE,CAAC;QAEjC,kDAAkD;QAClD,IAAI,CAAC,WAAW,EAAE,CAAC;QAEnB,yCAAyC;QACzC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAE3B,sBAAsB;QACtB,IAAI,CAAC,MAAM,GAAG,IAAI,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACxD,IAAI,CAAC,GAAG,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,GAAG,IAAI,aAAa,CAC9B,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,GAAG,EACR,SAAS,EACT,IAAI,CAAC,MAAM,CACX,CAAC;IACH,CAAC;IAED;;OAEG;IACK,WAAW;QAClB,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAClD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAC9B,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YACtD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,wCAAwC,YAAY,EAAE,CAAC,CAAC;QAC1E,CAAC;IACF,CAAC;IAED;;OAEG;IACK,mBAAmB;QAC1B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAElD,4BAA4B;QAC5B,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAC/B,OAAO;QACR,CAAC;QAED,IAAI,CAAC;YACJ,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC,SAAS,EAAE,EAAE;gBACnD,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;oBAC5B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;oBACvD,IAAI,CAAC,WAAW,EAAE,CAAC;gBACpB,CAAC;YACF,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sCAAsC,YAAY,EAAE,CAAC,CAAC;QACxE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,KAAK,EAAE,CAAC,CAAC;QAC5D,CAAC;IACF,CAAC;IAED;;;OAGG;IACK,yBAAyB;QAChC,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;QAE3D,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;YAChC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;YAC1C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1B,IAAI,CAAC;oBACJ,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;oBACxC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,OAAO,EAAE,CAAC,CAAC;gBACtD,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBAChB,IAAI,CAAC,MAAM,CAAC,KAAK,CAChB,gCAAgC,OAAO,KAAK,KAAK,EAAE,CACnD,CAAC;oBACF,MAAM,KAAK,CAAC;gBACb,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAED;;OAEG;IACH,WAAW;QACV,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,iBAAiB,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,mBAAmB;QAClB,OAAO,IAAI,CAAC,WAAW,EAAE,KAAK,iBAAiB,CAAC;IACjD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,gBAAgB;QACrB,MAAM,UAAU,GAAG,SAAS,CAC3B,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAC7B,mBAAmB,CACnB,CAAC;QACF,OAAO,IAAI,uBAAuB,CAAC,UAAU,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,sBAAsB;QACrB,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACjC,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACK,kBAAkB;QACzB,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;QAE/C,+CAA+C;QAC/C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACJ,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;gBACtC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC5B,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC3C,CAAC;gBACD,oDAAoD;gBACpD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC;gBACvC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iCAAiC,UAAU,EAAE,CAAC,CAAC;YACjE,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,KAAK,EAAE,CAAC,CAAC;gBAC9D,OAAO;YACR,CAAC;QACF,CAAC;QAED,IAAI,CAAC;YACJ,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE;gBAC1D,IAAI,SAAS,KAAK,QAAQ,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;oBACzD,IAAI,CAAC,MAAM,CAAC,IAAI,CACf,6DAA6D,CAC7D,CAAC;oBAEF,qDAAqD;oBACrD,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;oBACtC,MAAM,YAAY,GAAG,UAAU,CAAC,YAAY,IAAI,EAAE,CAAC;oBAEnD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC7B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;wBACjD,IAAI,CAAC,MAAM,CAAC,IAAI,CACf,gCAAgC,YAAY,CAAC,MAAM,qBAAqB,CACxE,CAAC;wBAEF,4CAA4C;wBAC5C,MAAM,IAAI,CAAC,sBAAsB,EAAE,CAAC;wBAEpC,sCAAsC;wBACtC,MAAM,IAAI,CAAC,sBAAsB,CAAC,YAAY,CAAC,CAAC;oBACjD,CAAC;gBACF,CAAC;YACF,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,IAAI,CACf,yDAAyD,UAAU,EAAE,CACrE,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kCAAkC,KAAK,EAAE,CAAC,CAAC;QAC9D,CAAC;IACF,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,sBAAsB;QACnC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACjE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAE7C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1B,OAAO;QACR,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACpD,MAAM,cAAc,GAAG,UAAU;iBAC/B,KAAK,CAAC,IAAI,CAAC;iBACX,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAC;iBAC1D,IAAI,CAAC,IAAI,CAAC,CAAC;YAEb,MAAM,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;YAClD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;YAEjE,+BAA+B;YAC/B,IAAI,CAAC,WAAW,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,KAAK,CAChB,gDAAgD,KAAK,EAAE,CACvD,CAAC;QACH,CAAC;IACF,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,sBAAsB,CACnC,YAAgC;QAEhC,IAAI,CAAC;YACJ,IAAI,CAAC,oBAAoB,GAAG,KAAK,CAAC;YAElC,uBAAuB;YACvB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACxB,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;gBAC3B,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;YAChC,CAAC;YAED,gEAAgE;YAChE,MAAM,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,CAAC;YAEzC,kDAAkD;YAClD,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;gBACjC,YAAY;aACZ,CAAC,CAAC;YAEH,6BAA6B;YAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YAE/C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACxB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;YACxD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,6BAA6B,UAAU,EAAE,CAAC,CAAC;YAE5D,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;gBAClC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;YACpD,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,YAAY,CAAC,MAAM,gBAAgB,CAAC,CAAC;YACvE,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;gBAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;YAChE,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0CAA0C,KAAK,EAAE,CAAC,CAAC;YACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;IACF,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ;QACb,0BAA0B;QAC1B,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACzB,CAAC;QAED,4BAA4B;QAC5B,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;QAC5B,CAAC;QAED,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,mBAAmB;QAClB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;YACnE,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YAC1B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;YACpE,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;QAEH,8DAA8D;QAC9D,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,EAAE;YACzC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC7D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;YAC3D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;YAC3C,IAAI,CAAC,MAAM,CAAC,KAAK,CAChB,2EAA2E,CAC3E,CAAC;YAEF,wDAAwD;YACxD,IAAI,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;gBAC5B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;gBAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACjB,CAAC,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;YACpD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,OAAO,EAAE,CAAC,CAAC;YACnE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,MAAM,EAAE,CAAC,CAAC;YACvC,IAAI,CAAC,MAAM,CAAC,KAAK,CAChB,uEAAuE,CACvE,CAAC;YAEF,wCAAwC;YACxC,IAAI,MAAM,YAAY,KAAK,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBAC7C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;YAC7C,CAAC;YAED,kEAAkE;YAClE,+BAA+B;QAChC,CAAC,CAAC,CAAC;IACJ,CAAC;CACD"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/app.ts"],"names":[],"mappings":""}
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { dirname, resolve } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ import { Application } from "./Application.js";
7
+ import { AuthCommand } from "./commands/AuthCommand.js";
8
+ import { CheckTokensCommand } from "./commands/CheckTokensCommand.js";
9
+ import { RefreshTokenCommand } from "./commands/RefreshTokenCommand.js";
10
+ import { StartCommand } from "./commands/StartCommand.js";
11
+ // Parse command line arguments
12
+ const args = process.argv.slice(2);
13
+ const cyrusHomeArg = args.find((arg) => arg.startsWith("--cyrus-home="));
14
+ // Determine the Cyrus home directory once at startup
15
+ let CYRUS_HOME;
16
+ if (cyrusHomeArg) {
17
+ const customPath = cyrusHomeArg.split("=")[1];
18
+ if (customPath) {
19
+ CYRUS_HOME = resolve(customPath);
20
+ }
21
+ else {
22
+ console.error("Error: --cyrus-home flag requires a directory path");
23
+ process.exit(1);
24
+ }
25
+ }
26
+ else {
27
+ CYRUS_HOME = resolve(homedir(), ".cyrus");
28
+ }
29
+ // Get the directory of the current module for reading package.json
30
+ const __filename = fileURLToPath(import.meta.url);
31
+ const __dirname = dirname(__filename);
32
+ // Read package.json to get the actual version
33
+ // When compiled, this is in dist/src/, so we need to go up two levels
34
+ const packageJsonPath = resolve(__dirname, "..", "..", "package.json");
35
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
36
+ // Handle --version argument
37
+ if (args.includes("--version")) {
38
+ console.log(packageJson.version);
39
+ process.exit(0);
40
+ }
41
+ // Handle --help argument
42
+ if (args.includes("--help") || args.includes("-h")) {
43
+ console.log(`
44
+ cyrus - AI-powered Linear issue automation using Claude
45
+
46
+ Usage: cyrus [command] [options]
47
+
48
+ Commands:
49
+ start Start the edge worker (default)
50
+ auth <auth-key> Authenticate with Cyrus using auth key
51
+ check-tokens Check the status of all Linear tokens
52
+ refresh-token Refresh a specific Linear token
53
+
54
+ Options:
55
+ --version Show version number
56
+ --help, -h Show help
57
+ --cyrus-home=<dir> Specify custom Cyrus config directory (default: ~/.cyrus)
58
+
59
+ Examples:
60
+ cyrus Start the edge worker
61
+ cyrus auth <your-auth-key> Authenticate and start
62
+ cyrus check-tokens Check all Linear token statuses
63
+ cyrus refresh-token Interactive token refresh
64
+ cyrus --cyrus-home=/tmp/cyrus Use custom config directory
65
+ `);
66
+ process.exit(0);
67
+ }
68
+ // Initialize application
69
+ const app = new Application(CYRUS_HOME);
70
+ // Parse command (remove flags from command name)
71
+ const commandArgs = args.filter((arg) => !arg.startsWith("--"));
72
+ const commandName = commandArgs[0] || "start";
73
+ const commandParams = commandArgs.slice(1);
74
+ // Execute command
75
+ (async () => {
76
+ try {
77
+ switch (commandName) {
78
+ case "start":
79
+ await new StartCommand(app).execute(commandParams);
80
+ break;
81
+ case "auth":
82
+ await new AuthCommand(app).execute(commandParams);
83
+ break;
84
+ case "check-tokens":
85
+ await new CheckTokensCommand(app).execute(commandParams);
86
+ break;
87
+ case "refresh-token":
88
+ await new RefreshTokenCommand(app).execute(commandParams);
89
+ break;
90
+ default:
91
+ console.error(`Unknown command: ${commandName}`);
92
+ console.log('Run "cyrus --help" for usage information');
93
+ process.exit(1);
94
+ }
95
+ }
96
+ catch (error) {
97
+ console.error("Fatal error:", error);
98
+ process.exit(1);
99
+ }
100
+ })();
101
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/app.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { BaseCommand } from "./ICommand.js";
2
+ /**
3
+ * Auth command - authenticate with Cyrus Pro plan using auth key
4
+ */
5
+ export declare class AuthCommand extends BaseCommand {
6
+ execute(args: string[]): Promise<void>;
7
+ }
8
+ //# sourceMappingURL=AuthCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/AuthCommand.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;GAEG;AACH,qBAAa,WAAY,SAAQ,WAAW;IACrC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAiF5C"}
@@ -0,0 +1,69 @@
1
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { BaseCommand } from "./ICommand.js";
4
+ /**
5
+ * Auth command - authenticate with Cyrus Pro plan using auth key
6
+ */
7
+ export class AuthCommand extends BaseCommand {
8
+ async execute(args) {
9
+ // Get auth key from command line arguments
10
+ const authKey = args[0];
11
+ if (!authKey ||
12
+ typeof authKey !== "string" ||
13
+ authKey.trim().length === 0) {
14
+ this.logError("Error: Auth key is required");
15
+ console.log("\nUsage: cyrus auth <auth-key>");
16
+ console.log("\nGet your auth key from: https://app.atcyrus.com/onboarding/auth-cyrus");
17
+ process.exit(1);
18
+ }
19
+ console.log("\n🔑 Authenticating with Cyrus...");
20
+ this.logDivider();
21
+ try {
22
+ // Import ConfigApiClient
23
+ const { ConfigApiClient } = await import("cyrus-cloudflare-tunnel-client");
24
+ // Call the config API to get credentials
25
+ console.log("Validating auth key...");
26
+ const configResponse = await ConfigApiClient.getConfig(authKey);
27
+ if (!ConfigApiClient.isValid(configResponse)) {
28
+ this.logError("Authentication failed");
29
+ console.error(configResponse.error || "Invalid response from server");
30
+ console.log("\nPlease verify your auth key is correct.");
31
+ console.log("Get your auth key from: https://app.atcyrus.com/onboarding/auth-cyrus");
32
+ process.exit(1);
33
+ }
34
+ this.logSuccess("Authentication successful!");
35
+ // Ensure CYRUS_HOME directory exists
36
+ if (!existsSync(this.app.cyrusHome)) {
37
+ mkdirSync(this.app.cyrusHome, { recursive: true });
38
+ }
39
+ // Store tokens in ~/.cyrus/.env file
40
+ const envPath = resolve(this.app.cyrusHome, ".env");
41
+ const envContent = `# Cyrus Authentication Credentials
42
+ # Generated on ${new Date().toISOString()}
43
+ CLOUDFLARE_TOKEN=${configResponse.config.cloudflareToken}
44
+ CYRUS_API_KEY=${configResponse.config.apiKey}
45
+ CYRUS_SETUP_PENDING=true
46
+ `;
47
+ writeFileSync(envPath, envContent, "utf-8");
48
+ this.logSuccess(`Credentials saved to ${envPath}`);
49
+ // Reload environment variables to pick up CYRUS_SETUP_PENDING
50
+ const dotenv = await import("dotenv");
51
+ dotenv.config({ path: envPath, override: true });
52
+ console.log("\n✨ Setup complete! Starting Cyrus...");
53
+ this.logDivider();
54
+ console.log();
55
+ // Start the edge app with the new configuration
56
+ // Import StartCommand to avoid circular dependency
57
+ const { StartCommand } = await import("./StartCommand.js");
58
+ const startCommand = new StartCommand(this.app);
59
+ await startCommand.execute([]);
60
+ }
61
+ catch (error) {
62
+ this.logError("Authentication failed:");
63
+ console.error(error.message);
64
+ console.log("\nPlease try again or contact support if the issue persists.");
65
+ process.exit(1);
66
+ }
67
+ }
68
+ }
69
+ //# sourceMappingURL=AuthCommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthCommand.js","sourceRoot":"","sources":["../../../src/commands/AuthCommand.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { BaseCommand } from "./ICommand.js";
2
+ /**
3
+ * Check tokens command - check the status of all Linear tokens
4
+ */
5
+ export declare class CheckTokensCommand extends BaseCommand {
6
+ execute(_args: string[]): Promise<void>;
7
+ }
8
+ //# sourceMappingURL=CheckTokensCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CheckTokensCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/CheckTokensCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAmC5C;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,WAAW;IAC5C,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAqB7C"}
@@ -0,0 +1,53 @@
1
+ import { BaseCommand } from "./ICommand.js";
2
+ /**
3
+ * Helper function to check Linear token status
4
+ */
5
+ async function checkLinearToken(token) {
6
+ try {
7
+ const response = await fetch("https://api.linear.app/graphql", {
8
+ method: "POST",
9
+ headers: {
10
+ "Content-Type": "application/json",
11
+ Authorization: token,
12
+ },
13
+ body: JSON.stringify({
14
+ query: "{ viewer { id email name } }",
15
+ }),
16
+ });
17
+ const data = (await response.json());
18
+ if (data.errors) {
19
+ return {
20
+ valid: false,
21
+ error: data.errors[0]?.message || "Unknown error",
22
+ };
23
+ }
24
+ return { valid: true };
25
+ }
26
+ catch (error) {
27
+ return { valid: false, error: error.message };
28
+ }
29
+ }
30
+ /**
31
+ * Check tokens command - check the status of all Linear tokens
32
+ */
33
+ export class CheckTokensCommand extends BaseCommand {
34
+ async execute(_args) {
35
+ if (!this.app.config.exists()) {
36
+ this.logError("No edge configuration found. Please run setup first.");
37
+ process.exit(1);
38
+ }
39
+ const config = this.app.config.load();
40
+ console.log("Checking Linear tokens...\n");
41
+ for (const repo of config.repositories) {
42
+ process.stdout.write(`${repo.name} (${repo.linearWorkspaceName}): `);
43
+ const result = await checkLinearToken(repo.linearToken);
44
+ if (result.valid) {
45
+ console.log("✅ Valid");
46
+ }
47
+ else {
48
+ console.log(`❌ Invalid - ${result.error}`);
49
+ }
50
+ }
51
+ }
52
+ }
53
+ //# sourceMappingURL=CheckTokensCommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CheckTokensCommand.js","sourceRoot":"","sources":["../../../src/commands/CheckTokensCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;GAEG;AACH,KAAK,UAAU,gBAAgB,CAC9B,KAAa;IAEb,IAAI,CAAC;QACJ,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,gCAAgC,EAAE;YAC9D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACR,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,KAAK;aACpB;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACpB,KAAK,EAAE,8BAA8B;aACrC,CAAC;SACF,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAQ,CAAC;QAE5C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO;gBACN,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,eAAe;aACjD,CAAC;QACH,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACxB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAG,KAAe,CAAC,OAAO,EAAE,CAAC;IAC1D,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,kBAAmB,SAAQ,WAAW;IAClD,KAAK,CAAC,OAAO,CAAC,KAAe;QAC5B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YAC/B,IAAI,CAAC,QAAQ,CAAC,sDAAsD,CAAC,CAAC;YACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAEtC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAE3C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,mBAAmB,KAAK,CAAC,CAAC;YACrE,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAExD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACxB,CAAC;iBAAM,CAAC;gBACP,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;YAC5C,CAAC;QACF,CAAC;IACF,CAAC;CACD"}
@@ -0,0 +1,38 @@
1
+ import type { Application } from "../Application.js";
2
+ import type { Logger } from "../services/Logger.js";
3
+ /**
4
+ * Interface for all CLI commands
5
+ */
6
+ export interface ICommand {
7
+ /**
8
+ * Execute the command
9
+ * @param args Command-line arguments
10
+ */
11
+ execute(args: string[]): Promise<void>;
12
+ }
13
+ /**
14
+ * Base class for commands with common functionality
15
+ */
16
+ export declare abstract class BaseCommand implements ICommand {
17
+ protected app: Application;
18
+ protected logger: Logger;
19
+ constructor(app: Application);
20
+ abstract execute(args: string[]): Promise<void>;
21
+ /**
22
+ * Helper to exit with error
23
+ */
24
+ protected exitWithError(message: string, code?: number): never;
25
+ /**
26
+ * Helper to log success
27
+ */
28
+ protected logSuccess(message: string): void;
29
+ /**
30
+ * Helper to log error
31
+ */
32
+ protected logError(message: string): void;
33
+ /**
34
+ * Helper to log section divider
35
+ */
36
+ protected logDivider(): void;
37
+ }
38
+ //# sourceMappingURL=ICommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ICommand.d.ts","sourceRoot":"","sources":["../../../src/commands/ICommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,QAAQ;IACxB;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED;;GAEG;AACH,8BAAsB,WAAY,YAAW,QAAQ;IAGxC,SAAS,CAAC,GAAG,EAAE,WAAW;IAFtC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEH,GAAG,EAAE,WAAW;IAItC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAE/C;;OAEG;IACH,SAAS,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,SAAI,GAAG,KAAK;IAKzD;;OAEG;IACH,SAAS,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI3C;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIzC;;OAEG;IACH,SAAS,CAAC,UAAU,IAAI,IAAI;CAG5B"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Base class for commands with common functionality
3
+ */
4
+ export class BaseCommand {
5
+ app;
6
+ logger;
7
+ constructor(app) {
8
+ this.app = app;
9
+ this.logger = app.logger;
10
+ }
11
+ /**
12
+ * Helper to exit with error
13
+ */
14
+ exitWithError(message, code = 1) {
15
+ this.logger.error(message);
16
+ process.exit(code);
17
+ }
18
+ /**
19
+ * Helper to log success
20
+ */
21
+ logSuccess(message) {
22
+ this.logger.success(message);
23
+ }
24
+ /**
25
+ * Helper to log error
26
+ */
27
+ logError(message) {
28
+ this.logger.error(message);
29
+ }
30
+ /**
31
+ * Helper to log section divider
32
+ */
33
+ logDivider() {
34
+ this.logger.divider(50);
35
+ }
36
+ }
37
+ //# sourceMappingURL=ICommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ICommand.js","sourceRoot":"","sources":["../../../src/commands/ICommand.ts"],"names":[],"mappings":"AAcA;;GAEG;AACH,MAAM,OAAgB,WAAW;IAGV;IAFZ,MAAM,CAAS;IAEzB,YAAsB,GAAgB;QAAhB,QAAG,GAAH,GAAG,CAAa;QACrC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAC1B,CAAC;IAID;;OAEG;IACO,aAAa,CAAC,OAAe,EAAE,IAAI,GAAG,CAAC;QAChD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;IAED;;OAEG;IACO,UAAU,CAAC,OAAe;QACnC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED;;OAEG;IACO,QAAQ,CAAC,OAAe;QACjC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IAED;;OAEG;IACO,UAAU;QACnB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC;CACD"}