cyrus-docker 0.1.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.
Files changed (91) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +245 -0
  3. package/dist/Application.d.ts +64 -0
  4. package/dist/Application.d.ts.map +1 -0
  5. package/dist/Application.js +104 -0
  6. package/dist/Application.js.map +1 -0
  7. package/dist/app.d.ts +3 -0
  8. package/dist/app.d.ts.map +1 -0
  9. package/dist/app.js +150 -0
  10. package/dist/app.js.map +1 -0
  11. package/dist/commands/AddRepoCommand.d.ts +11 -0
  12. package/dist/commands/AddRepoCommand.d.ts.map +1 -0
  13. package/dist/commands/AddRepoCommand.js +45 -0
  14. package/dist/commands/AddRepoCommand.js.map +1 -0
  15. package/dist/commands/AuthCommand.d.ts +16 -0
  16. package/dist/commands/AuthCommand.d.ts.map +1 -0
  17. package/dist/commands/AuthCommand.js +85 -0
  18. package/dist/commands/AuthCommand.js.map +1 -0
  19. package/dist/commands/BuildCommand.d.ts +21 -0
  20. package/dist/commands/BuildCommand.d.ts.map +1 -0
  21. package/dist/commands/BuildCommand.js +65 -0
  22. package/dist/commands/BuildCommand.js.map +1 -0
  23. package/dist/commands/ICommand.d.ts +37 -0
  24. package/dist/commands/ICommand.d.ts.map +1 -0
  25. package/dist/commands/ICommand.js +46 -0
  26. package/dist/commands/ICommand.js.map +1 -0
  27. package/dist/commands/InitCommand.d.ts +21 -0
  28. package/dist/commands/InitCommand.d.ts.map +1 -0
  29. package/dist/commands/InitCommand.js +209 -0
  30. package/dist/commands/InitCommand.js.map +1 -0
  31. package/dist/commands/LogsCommand.d.ts +11 -0
  32. package/dist/commands/LogsCommand.d.ts.map +1 -0
  33. package/dist/commands/LogsCommand.js +35 -0
  34. package/dist/commands/LogsCommand.js.map +1 -0
  35. package/dist/commands/ShellCommand.d.ts +8 -0
  36. package/dist/commands/ShellCommand.d.ts.map +1 -0
  37. package/dist/commands/ShellCommand.js +30 -0
  38. package/dist/commands/ShellCommand.js.map +1 -0
  39. package/dist/commands/StartCommand.d.ts +19 -0
  40. package/dist/commands/StartCommand.d.ts.map +1 -0
  41. package/dist/commands/StartCommand.js +147 -0
  42. package/dist/commands/StartCommand.js.map +1 -0
  43. package/dist/commands/StatusCommand.d.ts +8 -0
  44. package/dist/commands/StatusCommand.d.ts.map +1 -0
  45. package/dist/commands/StatusCommand.js +89 -0
  46. package/dist/commands/StatusCommand.js.map +1 -0
  47. package/dist/commands/StopCommand.d.ts +8 -0
  48. package/dist/commands/StopCommand.d.ts.map +1 -0
  49. package/dist/commands/StopCommand.js +45 -0
  50. package/dist/commands/StopCommand.js.map +1 -0
  51. package/dist/commands/ToolsCommand.d.ts +18 -0
  52. package/dist/commands/ToolsCommand.d.ts.map +1 -0
  53. package/dist/commands/ToolsCommand.js +158 -0
  54. package/dist/commands/ToolsCommand.js.map +1 -0
  55. package/dist/config/constants.d.ts +38 -0
  56. package/dist/config/constants.d.ts.map +1 -0
  57. package/dist/config/constants.js +100 -0
  58. package/dist/config/constants.js.map +1 -0
  59. package/dist/config/types.d.ts +142 -0
  60. package/dist/config/types.d.ts.map +1 -0
  61. package/dist/config/types.js +2 -0
  62. package/dist/config/types.js.map +1 -0
  63. package/dist/services/DockerService.d.ts +119 -0
  64. package/dist/services/DockerService.d.ts.map +1 -0
  65. package/dist/services/DockerService.js +371 -0
  66. package/dist/services/DockerService.js.map +1 -0
  67. package/dist/services/Logger.d.ts +64 -0
  68. package/dist/services/Logger.d.ts.map +1 -0
  69. package/dist/services/Logger.js +118 -0
  70. package/dist/services/Logger.js.map +1 -0
  71. package/dist/services/StateService.d.ts +68 -0
  72. package/dist/services/StateService.d.ts.map +1 -0
  73. package/dist/services/StateService.js +137 -0
  74. package/dist/services/StateService.js.map +1 -0
  75. package/dist/services/ToolConfigService.d.ts +66 -0
  76. package/dist/services/ToolConfigService.d.ts.map +1 -0
  77. package/dist/services/ToolConfigService.js +201 -0
  78. package/dist/services/ToolConfigService.js.map +1 -0
  79. package/dist/services/TunnelService.d.ts +43 -0
  80. package/dist/services/TunnelService.d.ts.map +1 -0
  81. package/dist/services/TunnelService.js +129 -0
  82. package/dist/services/TunnelService.js.map +1 -0
  83. package/docker/.env.docker +73 -0
  84. package/docker/.env.docker.example +71 -0
  85. package/docker/Dockerfile +62 -0
  86. package/docker/Dockerfile.custom +18 -0
  87. package/docker/Dockerfile.dev +78 -0
  88. package/docker/docker-compose.yml +59 -0
  89. package/docker/entrypoint.sh +209 -0
  90. package/docker/healthcheck.sh +23 -0
  91. package/package.json +75 -0
package/dist/app.js ADDED
@@ -0,0 +1,150 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from "node:fs";
3
+ import { dirname, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { Command } from "commander";
6
+ import { Application } from "./Application.js";
7
+ import { AddRepoCommand } from "./commands/AddRepoCommand.js";
8
+ import { AuthCommand } from "./commands/AuthCommand.js";
9
+ import { BuildCommand } from "./commands/BuildCommand.js";
10
+ import { InitCommand } from "./commands/InitCommand.js";
11
+ import { LogsCommand } from "./commands/LogsCommand.js";
12
+ import { ShellCommand } from "./commands/ShellCommand.js";
13
+ import { StartCommand } from "./commands/StartCommand.js";
14
+ import { StatusCommand } from "./commands/StatusCommand.js";
15
+ import { StopCommand } from "./commands/StopCommand.js";
16
+ import { ToolsCommand } from "./commands/ToolsCommand.js";
17
+ import { DEFAULT_LOG_LINES } from "./config/constants.js";
18
+ // Get the directory of the current module for reading package.json
19
+ const __filename = fileURLToPath(import.meta.url);
20
+ const __dirname = dirname(__filename);
21
+ // Read package.json to get the actual version
22
+ // When compiled, this is in dist/, so we need to go up one level
23
+ const packageJsonPath = resolve(__dirname, "..", "package.json");
24
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
25
+ // Create Commander program
26
+ const program = new Command();
27
+ program
28
+ .name("cyrus-docker")
29
+ .description("CLI tool for managing Docker-based Cyrus deployments")
30
+ .version(packageJson.version);
31
+ // init - Interactive setup wizard
32
+ program
33
+ .command("init")
34
+ .description("Interactive setup wizard for credentials and configuration")
35
+ .action(async () => {
36
+ const app = new Application(packageJson.version);
37
+ await new InitCommand(app).execute();
38
+ });
39
+ // start - Start ngrok tunnel and Docker container
40
+ program
41
+ .command("start")
42
+ .description("Start ngrok tunnel and Docker container")
43
+ .option("-d, --detach", "Run in detached mode (don't follow logs)")
44
+ .option("-b, --build", "Force rebuild of the Docker image")
45
+ .action(async (options) => {
46
+ const app = new Application(packageJson.version);
47
+ await new StartCommand(app, { detach: options.detach, build: options.build }).execute();
48
+ });
49
+ // stop - Stop Docker container and ngrok tunnel
50
+ program
51
+ .command("stop")
52
+ .description("Stop Docker container and ngrok tunnel")
53
+ .action(async () => {
54
+ const app = new Application(packageJson.version);
55
+ await new StopCommand(app).execute();
56
+ });
57
+ // status - Show container and tunnel status
58
+ program
59
+ .command("status")
60
+ .description("Show container and tunnel status")
61
+ .action(async () => {
62
+ const app = new Application(packageJson.version);
63
+ await new StatusCommand(app).execute();
64
+ });
65
+ // logs - Show container logs
66
+ program
67
+ .command("logs")
68
+ .description("Show container logs")
69
+ .option("-f, --follow", "Follow log output")
70
+ .option("-n, --lines <number>", `Number of lines to show (default: ${DEFAULT_LOG_LINES})`, String(DEFAULT_LOG_LINES))
71
+ .action(async (options) => {
72
+ const app = new Application(packageJson.version);
73
+ await new LogsCommand(app, {
74
+ follow: options.follow,
75
+ lines: options.lines ? parseInt(options.lines, 10) : undefined,
76
+ }).execute();
77
+ });
78
+ // shell - Open interactive shell in container
79
+ program
80
+ .command("shell")
81
+ .description("Open interactive bash shell in the container")
82
+ .action(async () => {
83
+ const app = new Application(packageJson.version);
84
+ await new ShellCommand(app).execute();
85
+ });
86
+ // auth - Run Linear OAuth flow
87
+ program
88
+ .command("auth")
89
+ .description("Run Linear OAuth authentication flow")
90
+ .action(async () => {
91
+ const app = new Application(packageJson.version);
92
+ await new AuthCommand(app).execute();
93
+ });
94
+ // add-repo - Add repository
95
+ program
96
+ .command("add-repo [url] [workspace]")
97
+ .description("Add a repository to Cyrus. URL is the git clone address, workspace is the Linear workspace name.")
98
+ .action(async (url, workspace) => {
99
+ const app = new Application(packageJson.version);
100
+ await new AddRepoCommand(app, url, workspace).execute();
101
+ });
102
+ // tools - Configure container development tools
103
+ program
104
+ .command("tools")
105
+ .description("Configure development tools in the container")
106
+ .action(async () => {
107
+ const app = new Application(packageJson.version);
108
+ await new ToolsCommand(app).execute();
109
+ });
110
+ // build - Build Docker image
111
+ program
112
+ .command("build")
113
+ .description("Build the Docker image (for debugging or CI)")
114
+ .option("-f, --force", "Force rebuild even if image is up-to-date")
115
+ .action(async (options) => {
116
+ const app = new Application(packageJson.version);
117
+ await new BuildCommand(app, { force: options.force }).execute();
118
+ });
119
+ /**
120
+ * Check if error is a user cancellation (Ctrl+C during prompts)
121
+ */
122
+ function isUserCancellation(error) {
123
+ if (error instanceof Error) {
124
+ // Inquirer's ExitPromptError when user presses Ctrl+C
125
+ if (error.name === "ExitPromptError") {
126
+ return true;
127
+ }
128
+ // Check message as fallback
129
+ if (error.message.includes("User force closed the prompt")) {
130
+ return true;
131
+ }
132
+ }
133
+ return false;
134
+ }
135
+ // Parse and execute
136
+ (async () => {
137
+ try {
138
+ await program.parseAsync(process.argv);
139
+ }
140
+ catch (error) {
141
+ // Handle user cancellation gracefully
142
+ if (isUserCancellation(error)) {
143
+ console.log("\nCancelled.");
144
+ process.exit(0);
145
+ }
146
+ console.error("Error:", error);
147
+ process.exit(1);
148
+ }
149
+ })();
150
+ //# 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,11 @@
1
+ import { BaseCommand } from "./ICommand.js";
2
+ /**
3
+ * Add a repository inside the container
4
+ */
5
+ export declare class AddRepoCommand extends BaseCommand {
6
+ private url?;
7
+ private workspace?;
8
+ constructor(app: import("../Application.js").Application, url?: string | undefined, workspace?: string | undefined);
9
+ execute(): Promise<void>;
10
+ }
11
+ //# sourceMappingURL=AddRepoCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AddRepoCommand.d.ts","sourceRoot":"","sources":["../../src/commands/AddRepoCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;GAEG;AACH,qBAAa,cAAe,SAAQ,WAAW;IAG7C,OAAO,CAAC,GAAG,CAAC;IACZ,OAAO,CAAC,SAAS,CAAC;gBAFlB,GAAG,EAAE,OAAO,mBAAmB,EAAE,WAAW,EACpC,GAAG,CAAC,EAAE,MAAM,YAAA,EACZ,SAAS,CAAC,EAAE,MAAM,YAAA;IAKrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAqC9B"}
@@ -0,0 +1,45 @@
1
+ import { BaseCommand } from "./ICommand.js";
2
+ /**
3
+ * Add a repository inside the container
4
+ */
5
+ export class AddRepoCommand extends BaseCommand {
6
+ url;
7
+ workspace;
8
+ constructor(app, url, workspace) {
9
+ super(app);
10
+ this.url = url;
11
+ this.workspace = workspace;
12
+ }
13
+ async execute() {
14
+ // Check if container is running
15
+ const status = await this.app.docker.getStatus();
16
+ if (!status.running) {
17
+ this.exitWithError("Container is not running. Start it with: cyrus-docker start");
18
+ }
19
+ this.logger.header("Add Repository");
20
+ this.logger.blank();
21
+ // Build command args
22
+ const args = ["cyrus", "self-add-repo"];
23
+ if (this.url) {
24
+ args.push(this.url);
25
+ }
26
+ if (this.workspace) {
27
+ args.push(this.workspace);
28
+ }
29
+ this.logger.info(`Running '${args.join(" ")}' inside container...`);
30
+ this.logger.divider();
31
+ try {
32
+ await this.app.docker.exec(args, { interactive: true });
33
+ }
34
+ catch (error) {
35
+ const exitError = error;
36
+ if (exitError.exitCode !== undefined && exitError.exitCode !== 0) {
37
+ this.logger.error("Failed to add repository.");
38
+ process.exit(exitError.exitCode);
39
+ }
40
+ }
41
+ this.logger.divider();
42
+ this.logger.success("Repository added!");
43
+ }
44
+ }
45
+ //# sourceMappingURL=AddRepoCommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AddRepoCommand.js","sourceRoot":"","sources":["../../src/commands/AddRepoCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;GAEG;AACH,MAAM,OAAO,cAAe,SAAQ,WAAW;IAGrC;IACA;IAHT,YACC,GAA4C,EACpC,GAAY,EACZ,SAAkB;QAE1B,KAAK,CAAC,GAAG,CAAC,CAAC;QAHH,QAAG,GAAH,GAAG,CAAS;QACZ,cAAS,GAAT,SAAS,CAAS;IAG3B,CAAC;IAED,KAAK,CAAC,OAAO;QACZ,gCAAgC;QAChC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACjD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACrB,IAAI,CAAC,aAAa,CACjB,6DAA6D,CAC7D,CAAC;QACH,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAEpB,qBAAqB;QACrB,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QACxC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACd,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACpE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAEtB,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,SAAS,GAAG,KAA8B,CAAC;YACjD,IAAI,SAAS,CAAC,QAAQ,KAAK,SAAS,IAAI,SAAS,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;gBAClE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;gBAC/C,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAClC,CAAC;QACF,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC1C,CAAC;CACD"}
@@ -0,0 +1,16 @@
1
+ import { BaseCommand } from "./ICommand.js";
2
+ /**
3
+ * Run Linear OAuth flow inside the container
4
+ */
5
+ export declare class AuthCommand extends BaseCommand {
6
+ execute(): Promise<void>;
7
+ /**
8
+ * Build the Linear OAuth authorization URL
9
+ */
10
+ private buildAuthUrl;
11
+ /**
12
+ * Open URL in the default browser on the host
13
+ */
14
+ private openBrowser;
15
+ }
16
+ //# sourceMappingURL=AuthCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthCommand.d.ts","sourceRoot":"","sources":["../../src/commands/AuthCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;GAEG;AACH,qBAAa,WAAY,SAAQ,WAAW;IACrC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAwC9B;;OAEG;IACH,OAAO,CAAC,YAAY;IAsBpB;;OAEG;YACW,WAAW;CAuBzB"}
@@ -0,0 +1,85 @@
1
+ import { BaseCommand } from "./ICommand.js";
2
+ /**
3
+ * Run Linear OAuth flow inside the container
4
+ */
5
+ export class AuthCommand extends BaseCommand {
6
+ async execute() {
7
+ // Check if container is running
8
+ const status = await this.app.docker.getStatus();
9
+ if (!status.running) {
10
+ this.exitWithError("Container is not running. Start it with: cyrus-docker start");
11
+ }
12
+ this.logger.header("Linear OAuth Authentication");
13
+ this.logger.blank();
14
+ // Build and open OAuth URL on the host
15
+ const authUrl = this.buildAuthUrl();
16
+ if (authUrl) {
17
+ this.logger.info("Opening browser for Linear authorization...");
18
+ await this.openBrowser(authUrl);
19
+ this.logger.blank();
20
+ }
21
+ this.logger.info("Running 'cyrus self-auth' inside container...");
22
+ this.logger.info("Waiting for authorization callback...");
23
+ this.logger.divider();
24
+ try {
25
+ await this.app.docker.exec(["cyrus", "self-auth"], {
26
+ interactive: true,
27
+ });
28
+ }
29
+ catch (error) {
30
+ const exitError = error;
31
+ if (exitError.exitCode !== undefined && exitError.exitCode !== 0) {
32
+ this.logger.error("Authentication failed.");
33
+ process.exit(exitError.exitCode);
34
+ }
35
+ }
36
+ this.logger.divider();
37
+ this.logger.success("Authentication complete!");
38
+ }
39
+ /**
40
+ * Build the Linear OAuth authorization URL
41
+ */
42
+ buildAuthUrl() {
43
+ const envConfig = this.app.docker.readEnvFile();
44
+ const tunnelUrl = this.app.state.getTunnelUrl();
45
+ if (!envConfig.LINEAR_CLIENT_ID || !tunnelUrl) {
46
+ this.logger.warn("Could not build auth URL - missing CLIENT_ID or tunnel URL");
47
+ return null;
48
+ }
49
+ const params = new URLSearchParams({
50
+ client_id: envConfig.LINEAR_CLIENT_ID,
51
+ redirect_uri: `${tunnelUrl}/callback`,
52
+ response_type: "code",
53
+ scope: "write,app:assignable,app:mentionable",
54
+ actor: "app",
55
+ });
56
+ return `https://linear.app/oauth/authorize?${params.toString()}`;
57
+ }
58
+ /**
59
+ * Open URL in the default browser on the host
60
+ */
61
+ async openBrowser(url) {
62
+ const { exec } = await import("node:child_process");
63
+ const { promisify } = await import("node:util");
64
+ const execAsync = promisify(exec);
65
+ try {
66
+ // macOS
67
+ if (process.platform === "darwin") {
68
+ await execAsync(`open "${url}"`);
69
+ }
70
+ // Linux
71
+ else if (process.platform === "linux") {
72
+ await execAsync(`xdg-open "${url}"`);
73
+ }
74
+ // Windows
75
+ else if (process.platform === "win32") {
76
+ await execAsync(`start "" "${url}"`);
77
+ }
78
+ }
79
+ catch {
80
+ this.logger.warn("Could not open browser automatically.");
81
+ this.logger.info(`Please visit: ${url}`);
82
+ }
83
+ }
84
+ }
85
+ //# sourceMappingURL=AuthCommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthCommand.js","sourceRoot":"","sources":["../../src/commands/AuthCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;GAEG;AACH,MAAM,OAAO,WAAY,SAAQ,WAAW;IAC3C,KAAK,CAAC,OAAO;QACZ,gCAAgC;QAChC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACjD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACrB,IAAI,CAAC,aAAa,CACjB,6DAA6D,CAC7D,CAAC;QACH,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,6BAA6B,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAEpB,uCAAuC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACpC,IAAI,OAAO,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;YAChE,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YAChC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;QAClE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAEtB,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE;gBAClD,WAAW,EAAE,IAAI;aACjB,CAAC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,SAAS,GAAG,KAA8B,CAAC;YACjD,IAAI,SAAS,CAAC,QAAQ,KAAK,SAAS,IAAI,SAAS,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;gBAClE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;gBAC5C,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAClC,CAAC;QACF,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IACjD,CAAC;IAED;;OAEG;IACK,YAAY;QACnB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QAChD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;QAEhD,IAAI,CAAC,SAAS,CAAC,gBAAgB,IAAI,CAAC,SAAS,EAAE,CAAC;YAC/C,IAAI,CAAC,MAAM,CAAC,IAAI,CACf,4DAA4D,CAC5D,CAAC;YACF,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YAClC,SAAS,EAAE,SAAS,CAAC,gBAAgB;YACrC,YAAY,EAAE,GAAG,SAAS,WAAW;YACrC,aAAa,EAAE,MAAM;YACrB,KAAK,EAAE,sCAAsC;YAC7C,KAAK,EAAE,KAAK;SACZ,CAAC,CAAC;QAEH,OAAO,sCAAsC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;IAClE,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,WAAW,CAAC,GAAW;QACpC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACpD,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;QAChD,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAElC,IAAI,CAAC;YACJ,QAAQ;YACR,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBACnC,MAAM,SAAS,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC;YAClC,CAAC;YACD,QAAQ;iBACH,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;gBACvC,MAAM,SAAS,CAAC,aAAa,GAAG,GAAG,CAAC,CAAC;YACtC,CAAC;YACD,UAAU;iBACL,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;gBACvC,MAAM,SAAS,CAAC,aAAa,GAAG,GAAG,CAAC,CAAC;YACtC,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;YACR,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;YAC1D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,CAAC;QAC1C,CAAC;IACF,CAAC;CACD"}
@@ -0,0 +1,21 @@
1
+ import { BaseCommand } from "./ICommand.js";
2
+ /**
3
+ * Options for the build command
4
+ */
5
+ export interface BuildOptions {
6
+ /** Force rebuild even if image is up-to-date */
7
+ force?: boolean;
8
+ }
9
+ /**
10
+ * Build the Docker image (standalone command for debugging/CI)
11
+ */
12
+ export declare class BuildCommand extends BaseCommand {
13
+ private options;
14
+ constructor(app: import("../Application.js").Application, options?: BuildOptions);
15
+ execute(): Promise<void>;
16
+ /**
17
+ * Print success message with image info
18
+ */
19
+ private printSuccess;
20
+ }
21
+ //# sourceMappingURL=BuildCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BuildCommand.d.ts","sourceRoot":"","sources":["../../src/commands/BuildCommand.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B,gDAAgD;IAChD,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,WAAW;IAG3C,OAAO,CAAC,OAAO;gBADf,GAAG,EAAE,OAAO,mBAAmB,EAAE,WAAW,EACpC,OAAO,GAAE,YAAiB;IAK7B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAgD9B;;OAEG;IACH,OAAO,CAAC,YAAY;CAcpB"}
@@ -0,0 +1,65 @@
1
+ import { ToolConfigService } from "../services/ToolConfigService.js";
2
+ import { BaseCommand } from "./ICommand.js";
3
+ /**
4
+ * Build the Docker image (standalone command for debugging/CI)
5
+ */
6
+ export class BuildCommand extends BaseCommand {
7
+ options;
8
+ constructor(app, options = {}) {
9
+ super(app);
10
+ this.options = options;
11
+ }
12
+ async execute() {
13
+ this.logger.header("Building Cyrus Docker Image");
14
+ // Check prerequisites
15
+ await this.requirePrerequisites();
16
+ const toolConfigService = new ToolConfigService(this.logger);
17
+ const toolConfig = toolConfigService.readConfig();
18
+ const toolsHash = toolConfigService.getConfigHash();
19
+ // Check if rebuild is needed (unless --force flag)
20
+ if (!this.options.force) {
21
+ this.logger.info("Checking if image rebuild is needed...");
22
+ const { needsRebuild, reason } = await this.app.docker.checkImageStatus(toolsHash);
23
+ if (!needsRebuild) {
24
+ this.logger.success(`${reason} - no rebuild needed`);
25
+ this.logger.blank();
26
+ this.logger.info("Use --force to rebuild anyway");
27
+ return;
28
+ }
29
+ this.logger.info(`${reason} - rebuilding image...`);
30
+ }
31
+ else {
32
+ this.logger.info("Force rebuild requested...");
33
+ }
34
+ this.logger.blank();
35
+ // Build with tools if configured
36
+ if (toolConfig) {
37
+ const resolvedConfig = toolConfigService.resolveConfig(toolConfig);
38
+ if (toolConfigService.hasTools(resolvedConfig)) {
39
+ await this.app.docker.buildWithTools(resolvedConfig, toolConfigService.generateDockerfile.bind(toolConfigService), toolsHash);
40
+ this.printSuccess(toolsHash);
41
+ return;
42
+ }
43
+ }
44
+ // No tools config or empty config - build normally
45
+ await this.app.docker.build();
46
+ this.printSuccess(null);
47
+ }
48
+ /**
49
+ * Print success message with image info
50
+ */
51
+ printSuccess(toolsHash) {
52
+ this.logger.blank();
53
+ this.logger.header("Build Complete");
54
+ this.logger.blank();
55
+ if (toolsHash) {
56
+ this.logger.keyValue("Tools hash", toolsHash);
57
+ }
58
+ else {
59
+ this.logger.info("Built base image (no tools configured)");
60
+ }
61
+ this.logger.blank();
62
+ this.logger.info("Run 'cyrus-docker start' to start the container");
63
+ }
64
+ }
65
+ //# sourceMappingURL=BuildCommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BuildCommand.js","sourceRoot":"","sources":["../../src/commands/BuildCommand.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
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
+ */
10
+ execute(): Promise<void>;
11
+ }
12
+ /**
13
+ * Base class for commands with common functionality
14
+ */
15
+ export declare abstract class BaseCommand implements ICommand {
16
+ protected app: Application;
17
+ protected logger: Logger;
18
+ constructor(app: Application);
19
+ abstract execute(): Promise<void>;
20
+ /**
21
+ * Exit with error message and code
22
+ */
23
+ protected exitWithError(message: string, code?: number): never;
24
+ /**
25
+ * Check prerequisites and exit if not met
26
+ */
27
+ protected requirePrerequisites(): Promise<void>;
28
+ /**
29
+ * Check if Cyrus is running and exit if not
30
+ */
31
+ protected requireRunning(): void;
32
+ /**
33
+ * Check if Cyrus is not running and exit if it is
34
+ */
35
+ protected requireNotRunning(): void;
36
+ }
37
+ //# 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;;OAEG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;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,IAAI,OAAO,CAAC,IAAI,CAAC;IAEjC;;OAEG;IACH,SAAS,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,SAAI,GAAG,KAAK;IAKzD;;OAEG;cACa,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAUrD;;OAEG;IACH,SAAS,CAAC,cAAc,IAAI,IAAI;IAQhC;;OAEG;IACH,SAAS,CAAC,iBAAiB,IAAI,IAAI;CAOnC"}
@@ -0,0 +1,46 @@
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
+ * Exit with error message and code
13
+ */
14
+ exitWithError(message, code = 1) {
15
+ this.logger.error(message);
16
+ process.exit(code);
17
+ }
18
+ /**
19
+ * Check prerequisites and exit if not met
20
+ */
21
+ async requirePrerequisites() {
22
+ const prereqs = await this.app.checkPrerequisites();
23
+ if (!this.app.allPrerequisitesMet(prereqs)) {
24
+ this.app.printPrerequisiteStatus(prereqs);
25
+ this.app.printMissingPrerequisites(prereqs);
26
+ process.exit(1);
27
+ }
28
+ }
29
+ /**
30
+ * Check if Cyrus is running and exit if not
31
+ */
32
+ requireRunning() {
33
+ if (!this.app.state.isRunning()) {
34
+ this.exitWithError("Cyrus is not running. Start it with: cyrus-docker start");
35
+ }
36
+ }
37
+ /**
38
+ * Check if Cyrus is not running and exit if it is
39
+ */
40
+ requireNotRunning() {
41
+ if (this.app.state.isRunning()) {
42
+ this.exitWithError("Cyrus is already running. Stop it first with: cyrus-docker stop");
43
+ }
44
+ }
45
+ }
46
+ //# sourceMappingURL=ICommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ICommand.js","sourceRoot":"","sources":["../../src/commands/ICommand.ts"],"names":[],"mappings":"AAaA;;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,KAAK,CAAC,oBAAoB;QACnC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC;QAEpD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC,GAAG,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;YAC1C,IAAI,CAAC,GAAG,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC;YAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;IACF,CAAC;IAED;;OAEG;IACO,cAAc;QACvB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC;YACjC,IAAI,CAAC,aAAa,CACjB,yDAAyD,CACzD,CAAC;QACH,CAAC;IACF,CAAC;IAED;;OAEG;IACO,iBAAiB;QAC1B,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC;YAChC,IAAI,CAAC,aAAa,CACjB,iEAAiE,CACjE,CAAC;QACH,CAAC;IACF,CAAC;CACD"}
@@ -0,0 +1,21 @@
1
+ import { BaseCommand } from "./ICommand.js";
2
+ /**
3
+ * Interactive setup wizard for cyrus-docker
4
+ * Prompts for credentials and creates .env.docker
5
+ */
6
+ export declare class InitCommand extends BaseCommand {
7
+ execute(): Promise<void>;
8
+ /**
9
+ * Prompt user for all required and optional credentials
10
+ */
11
+ private promptForCredentials;
12
+ /**
13
+ * Prompt user to optionally configure container tools
14
+ */
15
+ private promptForTools;
16
+ /**
17
+ * Print next steps after successful init
18
+ */
19
+ private printNextSteps;
20
+ }
21
+ //# sourceMappingURL=InitCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InitCommand.d.ts","sourceRoot":"","sources":["../../src/commands/InitCommand.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;;GAGG;AACH,qBAAa,WAAY,SAAQ,WAAW;IACrC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAqD9B;;OAEG;YACW,oBAAoB;IAqHlC;;OAEG;YACW,cAAc;IA2C5B;;OAEG;IACH,OAAO,CAAC,cAAc;CAyBtB"}