@chrishdx/llm-dev-server 1.0.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 (184) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +164 -0
  3. package/backend/bin/llm-dev-server.js +3 -0
  4. package/backend/dist/cli.d.ts +15 -0
  5. package/backend/dist/cli.d.ts.map +1 -0
  6. package/backend/dist/cli.js +326 -0
  7. package/backend/dist/cli.js.map +1 -0
  8. package/backend/dist/config/database.d.ts +10 -0
  9. package/backend/dist/config/database.d.ts.map +1 -0
  10. package/backend/dist/config/database.js +61 -0
  11. package/backend/dist/config/database.js.map +1 -0
  12. package/backend/dist/config/environment.d.ts +20 -0
  13. package/backend/dist/config/environment.d.ts.map +1 -0
  14. package/backend/dist/config/environment.js +77 -0
  15. package/backend/dist/config/environment.js.map +1 -0
  16. package/backend/dist/controllers/AuthController.d.ts +18 -0
  17. package/backend/dist/controllers/AuthController.d.ts.map +1 -0
  18. package/backend/dist/controllers/AuthController.js +282 -0
  19. package/backend/dist/controllers/AuthController.js.map +1 -0
  20. package/backend/dist/controllers/ConversationController.d.ts +44 -0
  21. package/backend/dist/controllers/ConversationController.d.ts.map +1 -0
  22. package/backend/dist/controllers/ConversationController.js +193 -0
  23. package/backend/dist/controllers/ConversationController.js.map +1 -0
  24. package/backend/dist/controllers/JobController.d.ts +49 -0
  25. package/backend/dist/controllers/JobController.d.ts.map +1 -0
  26. package/backend/dist/controllers/JobController.js +227 -0
  27. package/backend/dist/controllers/JobController.js.map +1 -0
  28. package/backend/dist/index.d.ts +2 -0
  29. package/backend/dist/index.d.ts.map +1 -0
  30. package/backend/dist/index.js +160 -0
  31. package/backend/dist/index.js.map +1 -0
  32. package/backend/dist/middleware/auth.middleware.d.ts +25 -0
  33. package/backend/dist/middleware/auth.middleware.d.ts.map +1 -0
  34. package/backend/dist/middleware/auth.middleware.js +116 -0
  35. package/backend/dist/middleware/auth.middleware.js.map +1 -0
  36. package/backend/dist/middleware/authelia.middleware.d.ts +26 -0
  37. package/backend/dist/middleware/authelia.middleware.d.ts.map +1 -0
  38. package/backend/dist/middleware/authelia.middleware.js +165 -0
  39. package/backend/dist/middleware/authelia.middleware.js.map +1 -0
  40. package/backend/dist/middleware/error.middleware.d.ts +23 -0
  41. package/backend/dist/middleware/error.middleware.d.ts.map +1 -0
  42. package/backend/dist/middleware/error.middleware.js +59 -0
  43. package/backend/dist/middleware/error.middleware.js.map +1 -0
  44. package/backend/dist/models/AuthToken.d.ts +42 -0
  45. package/backend/dist/models/AuthToken.d.ts.map +1 -0
  46. package/backend/dist/models/AuthToken.js +97 -0
  47. package/backend/dist/models/AuthToken.js.map +1 -0
  48. package/backend/dist/models/Conversation.d.ts +36 -0
  49. package/backend/dist/models/Conversation.d.ts.map +1 -0
  50. package/backend/dist/models/Conversation.js +100 -0
  51. package/backend/dist/models/Conversation.js.map +1 -0
  52. package/backend/dist/models/FileOperation.d.ts +36 -0
  53. package/backend/dist/models/FileOperation.d.ts.map +1 -0
  54. package/backend/dist/models/FileOperation.js +117 -0
  55. package/backend/dist/models/FileOperation.js.map +1 -0
  56. package/backend/dist/models/Job.d.ts +48 -0
  57. package/backend/dist/models/Job.d.ts.map +1 -0
  58. package/backend/dist/models/Job.js +87 -0
  59. package/backend/dist/models/Job.js.map +1 -0
  60. package/backend/dist/models/Message.d.ts +38 -0
  61. package/backend/dist/models/Message.d.ts.map +1 -0
  62. package/backend/dist/models/Message.js +87 -0
  63. package/backend/dist/models/Message.js.map +1 -0
  64. package/backend/dist/models/User.d.ts +26 -0
  65. package/backend/dist/models/User.d.ts.map +1 -0
  66. package/backend/dist/models/User.js +67 -0
  67. package/backend/dist/models/User.js.map +1 -0
  68. package/backend/dist/models/index.d.ts +13 -0
  69. package/backend/dist/models/index.d.ts.map +1 -0
  70. package/backend/dist/models/index.js +24 -0
  71. package/backend/dist/models/index.js.map +1 -0
  72. package/backend/dist/routes/auth.routes.d.ts +3 -0
  73. package/backend/dist/routes/auth.routes.d.ts.map +1 -0
  74. package/backend/dist/routes/auth.routes.js +27 -0
  75. package/backend/dist/routes/auth.routes.js.map +1 -0
  76. package/backend/dist/routes/conversation.routes.d.ts +3 -0
  77. package/backend/dist/routes/conversation.routes.d.ts.map +1 -0
  78. package/backend/dist/routes/conversation.routes.js +17 -0
  79. package/backend/dist/routes/conversation.routes.js.map +1 -0
  80. package/backend/dist/routes/filesystem.routes.d.ts +3 -0
  81. package/backend/dist/routes/filesystem.routes.d.ts.map +1 -0
  82. package/backend/dist/routes/filesystem.routes.js +64 -0
  83. package/backend/dist/routes/filesystem.routes.js.map +1 -0
  84. package/backend/dist/routes/index.d.ts +3 -0
  85. package/backend/dist/routes/index.d.ts.map +1 -0
  86. package/backend/dist/routes/index.js +27 -0
  87. package/backend/dist/routes/index.js.map +1 -0
  88. package/backend/dist/routes/job.routes.d.ts +3 -0
  89. package/backend/dist/routes/job.routes.d.ts.map +1 -0
  90. package/backend/dist/routes/job.routes.js +18 -0
  91. package/backend/dist/routes/job.routes.js.map +1 -0
  92. package/backend/dist/services/auth/BaseAuthService.d.ts +49 -0
  93. package/backend/dist/services/auth/BaseAuthService.d.ts.map +1 -0
  94. package/backend/dist/services/auth/BaseAuthService.js +97 -0
  95. package/backend/dist/services/auth/BaseAuthService.js.map +1 -0
  96. package/backend/dist/services/auth/ClaudeAuthService.d.ts +69 -0
  97. package/backend/dist/services/auth/ClaudeAuthService.d.ts.map +1 -0
  98. package/backend/dist/services/auth/ClaudeAuthService.js +401 -0
  99. package/backend/dist/services/auth/ClaudeAuthService.js.map +1 -0
  100. package/backend/dist/services/auth/CodexAuthService.d.ts +37 -0
  101. package/backend/dist/services/auth/CodexAuthService.d.ts.map +1 -0
  102. package/backend/dist/services/auth/CodexAuthService.js +186 -0
  103. package/backend/dist/services/auth/CodexAuthService.js.map +1 -0
  104. package/backend/dist/services/auth/GeminiAuthService.d.ts +50 -0
  105. package/backend/dist/services/auth/GeminiAuthService.d.ts.map +1 -0
  106. package/backend/dist/services/auth/GeminiAuthService.js +284 -0
  107. package/backend/dist/services/auth/GeminiAuthService.js.map +1 -0
  108. package/backend/dist/services/auth/JwtService.d.ts +27 -0
  109. package/backend/dist/services/auth/JwtService.d.ts.map +1 -0
  110. package/backend/dist/services/auth/JwtService.js +65 -0
  111. package/backend/dist/services/auth/JwtService.js.map +1 -0
  112. package/backend/dist/services/auth/TokenRefreshService.d.ts +36 -0
  113. package/backend/dist/services/auth/TokenRefreshService.d.ts.map +1 -0
  114. package/backend/dist/services/auth/TokenRefreshService.js +178 -0
  115. package/backend/dist/services/auth/TokenRefreshService.js.map +1 -0
  116. package/backend/dist/services/conversation/ConversationService.d.ts +89 -0
  117. package/backend/dist/services/conversation/ConversationService.d.ts.map +1 -0
  118. package/backend/dist/services/conversation/ConversationService.js +255 -0
  119. package/backend/dist/services/conversation/ConversationService.js.map +1 -0
  120. package/backend/dist/services/job/JobService.d.ts +83 -0
  121. package/backend/dist/services/job/JobService.d.ts.map +1 -0
  122. package/backend/dist/services/job/JobService.js +213 -0
  123. package/backend/dist/services/job/JobService.js.map +1 -0
  124. package/backend/dist/services/job/WorkingDirectoryService.d.ts +73 -0
  125. package/backend/dist/services/job/WorkingDirectoryService.d.ts.map +1 -0
  126. package/backend/dist/services/job/WorkingDirectoryService.js +289 -0
  127. package/backend/dist/services/job/WorkingDirectoryService.js.map +1 -0
  128. package/backend/dist/services/llm/ClaudeProvider.d.ts +16 -0
  129. package/backend/dist/services/llm/ClaudeProvider.d.ts.map +1 -0
  130. package/backend/dist/services/llm/ClaudeProvider.js +229 -0
  131. package/backend/dist/services/llm/ClaudeProvider.js.map +1 -0
  132. package/backend/dist/services/llm/CodexProvider.d.ts +15 -0
  133. package/backend/dist/services/llm/CodexProvider.d.ts.map +1 -0
  134. package/backend/dist/services/llm/CodexProvider.js +301 -0
  135. package/backend/dist/services/llm/CodexProvider.js.map +1 -0
  136. package/backend/dist/services/llm/GeminiProvider.d.ts +17 -0
  137. package/backend/dist/services/llm/GeminiProvider.d.ts.map +1 -0
  138. package/backend/dist/services/llm/GeminiProvider.js +190 -0
  139. package/backend/dist/services/llm/GeminiProvider.js.map +1 -0
  140. package/backend/dist/services/llm/LLMProviderBase.d.ts +76 -0
  141. package/backend/dist/services/llm/LLMProviderBase.d.ts.map +1 -0
  142. package/backend/dist/services/llm/LLMProviderBase.js +34 -0
  143. package/backend/dist/services/llm/LLMProviderBase.js.map +1 -0
  144. package/backend/dist/services/llm/ProviderFactory.d.ts +17 -0
  145. package/backend/dist/services/llm/ProviderFactory.d.ts.map +1 -0
  146. package/backend/dist/services/llm/ProviderFactory.js +58 -0
  147. package/backend/dist/services/llm/ProviderFactory.js.map +1 -0
  148. package/backend/dist/utils/crypto.d.ts +33 -0
  149. package/backend/dist/utils/crypto.d.ts.map +1 -0
  150. package/backend/dist/utils/crypto.js +165 -0
  151. package/backend/dist/utils/crypto.js.map +1 -0
  152. package/backend/dist/utils/logger.d.ts +4 -0
  153. package/backend/dist/utils/logger.d.ts.map +1 -0
  154. package/backend/dist/utils/logger.js +44 -0
  155. package/backend/dist/utils/logger.js.map +1 -0
  156. package/backend/dist/utils/validators.d.ts +22 -0
  157. package/backend/dist/utils/validators.d.ts.map +1 -0
  158. package/backend/dist/utils/validators.js +127 -0
  159. package/backend/dist/utils/validators.js.map +1 -0
  160. package/backend/package.json +45 -0
  161. package/backend/public/assets/index-C207-KqP.js +188 -0
  162. package/backend/public/index.html +12 -0
  163. package/package.json +96 -0
  164. package/shared/dist/index.d.ts +5 -0
  165. package/shared/dist/index.d.ts.map +1 -0
  166. package/shared/dist/index.js +25 -0
  167. package/shared/dist/index.js.map +1 -0
  168. package/shared/dist/types/api.d.ts +27 -0
  169. package/shared/dist/types/api.d.ts.map +1 -0
  170. package/shared/dist/types/api.js +3 -0
  171. package/shared/dist/types/api.js.map +1 -0
  172. package/shared/dist/types/auth.d.ts +62 -0
  173. package/shared/dist/types/auth.d.ts.map +1 -0
  174. package/shared/dist/types/auth.js +3 -0
  175. package/shared/dist/types/auth.js.map +1 -0
  176. package/shared/dist/types/conversation.d.ts +98 -0
  177. package/shared/dist/types/conversation.d.ts.map +1 -0
  178. package/shared/dist/types/conversation.js +3 -0
  179. package/shared/dist/types/conversation.js.map +1 -0
  180. package/shared/dist/types/job.d.ts +93 -0
  181. package/shared/dist/types/job.d.ts.map +1 -0
  182. package/shared/dist/types/job.js +3 -0
  183. package/shared/dist/types/job.js.map +1 -0
  184. package/shared/package.json +15 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Christian Schindler
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,164 @@
1
+ # LLM Dev Server
2
+
3
+ A unified Multi-LLM Development Server supporting Claude, Codex, and Gemini. Provides a web-based interface to interact with multiple AI coding assistants from a single dashboard.
4
+
5
+ ## Features
6
+
7
+ - 🤖 **Multi-LLM Support**: Claude (Anthropic), Codex (OpenAI), Gemini (Google)
8
+ - 💬 **Unified Chat Interface**: Single UI to interact with all providers
9
+ - 📁 **File Operations**: AI-assisted file management and editing
10
+ - 🔒 **Authentication**: Built-in user management with JWT
11
+ - 🔄 **Token Management**: Automatic credential refresh
12
+ - 🏠 **Local Data Storage**: All data stored in `~/.dev_server`
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install -g @chrishdx/llm-dev-server
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ```bash
23
+ # Start the server (first run initializes configuration)
24
+ llm-dev-server
25
+
26
+ # Or with custom port
27
+ llm-dev-server start --port 8080
28
+ ```
29
+
30
+ On first run, the server will:
31
+
32
+ 1. Create `~/.dev_server` directory
33
+ 2. Generate a configuration file at `~/.dev_server/.env`
34
+ 3. Create an admin user (credentials shown in console)
35
+ 4. Start the web server at http://localhost:3000
36
+
37
+ ## Commands
38
+
39
+ ```bash
40
+ llm-dev-server # Start server (default)
41
+ llm-dev-server start # Start server
42
+ llm-dev-server init # Initialize configuration only
43
+ llm-dev-server config # Show current configuration
44
+ llm-dev-server help # Show help
45
+ ```
46
+
47
+ ## Configuration
48
+
49
+ All configuration is stored in `~/.dev_server/.env`:
50
+
51
+ ```env
52
+ # Server Settings
53
+ NODE_ENV=production
54
+ PORT=3000
55
+ LOG_LEVEL=info
56
+
57
+ # Security (auto-generated)
58
+ JWT_SECRET=your-jwt-secret
59
+ ENCRYPTION_KEY=your-encryption-key
60
+
61
+ # CORS
62
+ ALLOWED_ORIGINS=http://localhost:3000
63
+
64
+ # Proxy Settings (for reverse proxy)
65
+ # TRUST_PROXY=true
66
+
67
+ # Authelia SSO (optional)
68
+ # AUTHELIA_ENABLED=false
69
+ # AUTHELIA_ADMIN_GROUPS=admins
70
+ ```
71
+
72
+ ## Data Directory Structure
73
+
74
+ ```
75
+ ~/.dev_server/
76
+ ├── .env # Configuration file
77
+ ├── data/
78
+ │ ├── dev-server.db # SQLite database
79
+ │ ├── claude/ # Claude credentials & cache
80
+ │ ├── codex/ # Codex credentials
81
+ │ └── gemini/ # Gemini credentials
82
+ ├── workspaces/ # Project workspaces
83
+ └── logs/ # Server logs
84
+ ```
85
+
86
+ ## Environment Variables
87
+
88
+ | Variable | Default | Description |
89
+ | ----------------- | ----------------------- | --------------------------- |
90
+ | `DEV_SERVER_HOME` | `~/.dev_server` | Base directory for all data |
91
+ | `PORT` | `3000` | Server port |
92
+ | `NODE_ENV` | `production` | Environment mode |
93
+ | `JWT_SECRET` | auto-generated | JWT signing secret |
94
+ | `ENCRYPTION_KEY` | auto-generated | Data encryption key |
95
+ | `ALLOWED_ORIGINS` | `http://localhost:3000` | CORS allowed origins |
96
+ | `TRUST_PROXY` | `false` | Trust reverse proxy headers |
97
+ | `LOG_LEVEL` | `info` | Logging level |
98
+
99
+ ## LLM Provider Setup
100
+
101
+ ### Claude (Anthropic)
102
+
103
+ 1. Navigate to Settings > Providers in the web UI
104
+ 2. Click "Login with Claude"
105
+ 3. Follow the OAuth flow to authenticate
106
+
107
+ ### Codex (OpenAI)
108
+
109
+ 1. Navigate to Settings > Providers
110
+ 2. Click "Login with Codex"
111
+ 3. Authenticate via browser
112
+
113
+ ### Gemini (Google)
114
+
115
+ 1. Navigate to Settings > Providers
116
+ 2. Click "Login with Gemini"
117
+ 3. Complete Google OAuth
118
+
119
+ ## Development
120
+
121
+ ```bash
122
+ # Clone repository
123
+ git clone https://github.com/chrishdx/llm-dev-server.git
124
+ cd llm-dev-server
125
+
126
+ # Install dependencies
127
+ npm install
128
+
129
+ # Run in development mode (with hot reload)
130
+ npm run dev
131
+
132
+ # Build for production
133
+ npm run build
134
+
135
+ # Run production build locally
136
+ npm start
137
+ ```
138
+
139
+ ## API Endpoints
140
+
141
+ | Endpoint | Description |
142
+ | -------------------------------------- | -------------------- |
143
+ | `GET /api/health` | Health check |
144
+ | `POST /api/auth/login` | User login |
145
+ | `GET /api/conversations` | List conversations |
146
+ | `POST /api/conversations` | Create conversation |
147
+ | `POST /api/conversations/:id/messages` | Send message |
148
+ | `GET /api/jobs` | List background jobs |
149
+
150
+ ## Tech Stack
151
+
152
+ - **Backend**: Node.js, Express, TypeScript, SQLite, Sequelize
153
+ - **Frontend**: React, TypeScript, Material-UI, Vite
154
+ - **Auth**: JWT, bcrypt
155
+ - **LLM SDKs**: Claude Agent SDK, Codex SDK, Gemini CLI
156
+
157
+ ## Requirements
158
+
159
+ - Node.js >= 20.0.0
160
+ - npm >= 10.0.0
161
+
162
+ ## License
163
+
164
+ MIT © Christian Schindler
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ const path = require("path");
3
+ require(path.join(__dirname, "..", "dist", "cli.js"));
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI Entry Point for llm-dev-server
4
+ *
5
+ * Handles:
6
+ * - First-time setup (creates ~/.dev_server directory)
7
+ * - Environment file initialization
8
+ * - Server startup
9
+ */
10
+ declare const DEV_SERVER_HOME: string;
11
+ declare const DATA_DIR: string;
12
+ declare const WORKSPACES_DIR: string;
13
+ declare const ENV_FILE: string;
14
+ export { DEV_SERVER_HOME, DATA_DIR, WORKSPACES_DIR, ENV_FILE };
15
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AAQH,QAAA,MAAM,eAAe,QACkD,CAAC;AAGxE,QAAA,MAAM,QAAQ,QAAqC,CAAC;AACpD,QAAA,MAAM,cAAc,QAA2C,CAAC;AAEhE,QAAA,MAAM,QAAQ,QAAqC,CAAC;AAwSpD,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,326 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * CLI Entry Point for llm-dev-server
5
+ *
6
+ * Handles:
7
+ * - First-time setup (creates ~/.dev_server directory)
8
+ * - Environment file initialization
9
+ * - Server startup
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ var __importDefault = (this && this.__importDefault) || function (mod) {
45
+ return (mod && mod.__esModule) ? mod : { "default": mod };
46
+ };
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.ENV_FILE = exports.WORKSPACES_DIR = exports.DATA_DIR = exports.DEV_SERVER_HOME = void 0;
49
+ const fs_1 = __importDefault(require("fs"));
50
+ const path_1 = __importDefault(require("path"));
51
+ const os_1 = __importDefault(require("os"));
52
+ const crypto_1 = require("./utils/crypto");
53
+ // Define home directory for persistent data
54
+ const DEV_SERVER_HOME = process.env.DEV_SERVER_HOME || path_1.default.join(os_1.default.homedir(), ".dev_server");
55
+ exports.DEV_SERVER_HOME = DEV_SERVER_HOME;
56
+ // Subdirectories
57
+ const DATA_DIR = path_1.default.join(DEV_SERVER_HOME, "data");
58
+ exports.DATA_DIR = DATA_DIR;
59
+ const WORKSPACES_DIR = path_1.default.join(DEV_SERVER_HOME, "workspaces");
60
+ exports.WORKSPACES_DIR = WORKSPACES_DIR;
61
+ const LOGS_DIR = path_1.default.join(DEV_SERVER_HOME, "logs");
62
+ const ENV_FILE = path_1.default.join(DEV_SERVER_HOME, ".env");
63
+ exports.ENV_FILE = ENV_FILE;
64
+ /**
65
+ * Ensure all required directories exist
66
+ */
67
+ function ensureDirectories() {
68
+ const dirs = [DEV_SERVER_HOME, DATA_DIR, WORKSPACES_DIR, LOGS_DIR];
69
+ for (const dir of dirs) {
70
+ if (!fs_1.default.existsSync(dir)) {
71
+ fs_1.default.mkdirSync(dir, { recursive: true });
72
+ console.log(`✓ Created directory: ${dir}`);
73
+ }
74
+ }
75
+ }
76
+ /**
77
+ * Generate default .env file content
78
+ */
79
+ function generateDefaultEnvContent() {
80
+ const jwtSecret = (0, crypto_1.generateRandomHex)(64);
81
+ const encryptionKey = (0, crypto_1.generateRandomHex)(32);
82
+ return `# LLM Dev Server Configuration
83
+ # Generated on ${new Date().toISOString()}
84
+ # Location: ${ENV_FILE}
85
+
86
+ # Server Settings
87
+ NODE_ENV=production
88
+ PORT=3000
89
+ LOG_LEVEL=info
90
+
91
+ # Security (auto-generated - keep these secret!)
92
+ JWT_SECRET=${jwtSecret}
93
+ ENCRYPTION_KEY=${encryptionKey}
94
+
95
+ # CORS - Add your frontend URLs here
96
+ ALLOWED_ORIGINS=http://localhost:3000
97
+
98
+ # Data Directories (auto-configured)
99
+ DATA_DIR=${DATA_DIR}
100
+ DATABASE_URL=${path_1.default.join(DATA_DIR, "dev-server.db")}
101
+ WORKING_DIR_BASE=${WORKSPACES_DIR}
102
+
103
+ # Proxy Settings (for reverse proxy like Traefik/Nginx)
104
+ # TRUST_PROXY=true
105
+
106
+ # Authelia SSO Integration (optional)
107
+ # AUTHELIA_ENABLED=false
108
+ # AUTHELIA_ADMIN_GROUPS=admins
109
+
110
+ # LLM CLI Paths (optional - auto-detected if in PATH)
111
+ # CLAUDE_CLI_PATH=/path/to/claude
112
+ # CODEX_CLI_PATH=/path/to/codex
113
+ # GEMINI_CLI_PATH=/path/to/gemini
114
+ `;
115
+ }
116
+ /**
117
+ * Initialize environment file if not exists
118
+ */
119
+ function initializeEnvFile() {
120
+ if (fs_1.default.existsSync(ENV_FILE)) {
121
+ return false; // Already exists
122
+ }
123
+ const content = generateDefaultEnvContent();
124
+ fs_1.default.writeFileSync(ENV_FILE, content, "utf-8");
125
+ console.log(`✓ Created configuration file: ${ENV_FILE}`);
126
+ return true;
127
+ }
128
+ /**
129
+ * Load environment variables from .env file
130
+ */
131
+ function loadEnvFile() {
132
+ if (fs_1.default.existsSync(ENV_FILE)) {
133
+ // Parse .env file manually to avoid circular dependency with dotenv
134
+ const content = fs_1.default.readFileSync(ENV_FILE, "utf-8");
135
+ const lines = content.split("\n");
136
+ for (const line of lines) {
137
+ const trimmed = line.trim();
138
+ // Skip comments and empty lines
139
+ if (!trimmed || trimmed.startsWith("#"))
140
+ continue;
141
+ const equalIndex = trimmed.indexOf("=");
142
+ if (equalIndex === -1)
143
+ continue;
144
+ const key = trimmed.substring(0, equalIndex).trim();
145
+ let value = trimmed.substring(equalIndex + 1).trim();
146
+ // Remove surrounding quotes if present
147
+ if ((value.startsWith('"') && value.endsWith('"')) ||
148
+ (value.startsWith("'") && value.endsWith("'"))) {
149
+ value = value.slice(1, -1);
150
+ }
151
+ // Only set if not already defined (environment takes precedence)
152
+ if (!process.env[key]) {
153
+ process.env[key] = value;
154
+ }
155
+ }
156
+ }
157
+ }
158
+ /**
159
+ * Display startup banner
160
+ */
161
+ function displayBanner() {
162
+ console.log(`
163
+ ╔══════════════════════════════════════════════════════════════╗
164
+ ║ LLM Dev Server ║
165
+ ║ Multi-LLM Development Platform ║
166
+ ╚══════════════════════════════════════════════════════════════╝
167
+ `);
168
+ }
169
+ /**
170
+ * Display help message
171
+ */
172
+ function displayHelp() {
173
+ console.log(`
174
+ Usage: llm-dev-server [command] [options]
175
+
176
+ Commands:
177
+ start Start the server (default)
178
+ init Initialize configuration only (don't start server)
179
+ config Show current configuration
180
+ help Show this help message
181
+
182
+ Options:
183
+ --port, -p Override server port
184
+ --help, -h Show help
185
+
186
+ Configuration:
187
+ Config file: ${ENV_FILE}
188
+ Data directory: ${DATA_DIR}
189
+ Workspaces: ${WORKSPACES_DIR}
190
+
191
+ Environment Variables:
192
+ DEV_SERVER_HOME Override home directory (default: ~/.dev_server)
193
+ PORT Server port (default: 3000)
194
+ NODE_ENV Environment (development/production)
195
+
196
+ Examples:
197
+ llm-dev-server # Start server
198
+ llm-dev-server start --port 8080 # Start on port 8080
199
+ llm-dev-server init # Initialize config only
200
+ llm-dev-server config # Show config
201
+ `);
202
+ }
203
+ /**
204
+ * Display current configuration
205
+ */
206
+ function displayConfig() {
207
+ console.log(`
208
+ Current Configuration:
209
+ ─────────────────────────────────────────────────────
210
+ Home Directory: ${DEV_SERVER_HOME}
211
+ Config File: ${ENV_FILE}
212
+ Data Directory: ${DATA_DIR}
213
+ Database: ${path_1.default.join(DATA_DIR, "dev-server.db")}
214
+ Workspaces: ${WORKSPACES_DIR}
215
+ Logs: ${LOGS_DIR}
216
+
217
+ Config file exists: ${fs_1.default.existsSync(ENV_FILE) ? "Yes" : "No"}
218
+ ─────────────────────────────────────────────────────
219
+ `);
220
+ if (fs_1.default.existsSync(ENV_FILE)) {
221
+ console.log("Configuration values (from .env):");
222
+ const content = fs_1.default.readFileSync(ENV_FILE, "utf-8");
223
+ const lines = content.split("\n");
224
+ for (const line of lines) {
225
+ const trimmed = line.trim();
226
+ if (!trimmed || trimmed.startsWith("#"))
227
+ continue;
228
+ const equalIndex = trimmed.indexOf("=");
229
+ if (equalIndex === -1)
230
+ continue;
231
+ const key = trimmed.substring(0, equalIndex).trim();
232
+ let value = trimmed.substring(equalIndex + 1).trim();
233
+ // Mask sensitive values
234
+ if (key.includes("SECRET") ||
235
+ key.includes("KEY") ||
236
+ key.includes("PASSWORD")) {
237
+ value = "****" + value.slice(-4);
238
+ }
239
+ console.log(` ${key}: ${value}`);
240
+ }
241
+ }
242
+ }
243
+ /**
244
+ * Parse command line arguments
245
+ */
246
+ function parseArgs() {
247
+ const args = process.argv.slice(2);
248
+ let command = "start";
249
+ let port;
250
+ for (let i = 0; i < args.length; i++) {
251
+ const arg = args[i];
252
+ if (arg === "start" ||
253
+ arg === "init" ||
254
+ arg === "config" ||
255
+ arg === "help") {
256
+ command = arg;
257
+ }
258
+ else if (arg === "--help" || arg === "-h") {
259
+ command = "help";
260
+ }
261
+ else if (arg === "--port" || arg === "-p") {
262
+ port = parseInt(args[++i], 10);
263
+ }
264
+ }
265
+ return { command, port };
266
+ }
267
+ /**
268
+ * Main CLI entry point
269
+ */
270
+ async function main() {
271
+ const { command, port } = parseArgs();
272
+ // Handle help before anything else
273
+ if (command === "help") {
274
+ displayHelp();
275
+ process.exit(0);
276
+ }
277
+ displayBanner();
278
+ // Setup directories
279
+ ensureDirectories();
280
+ // Initialize or load .env
281
+ const isNewInstall = initializeEnvFile();
282
+ loadEnvFile();
283
+ // Override port if specified via CLI
284
+ if (port) {
285
+ process.env.PORT = port.toString();
286
+ }
287
+ // Handle commands
288
+ switch (command) {
289
+ case "init":
290
+ if (isNewInstall) {
291
+ console.log("\n✓ Configuration initialized successfully!");
292
+ console.log(`\nEdit your configuration at: ${ENV_FILE}`);
293
+ }
294
+ else {
295
+ console.log("\n✓ Configuration already exists.");
296
+ console.log(`\nEdit your configuration at: ${ENV_FILE}`);
297
+ }
298
+ displayConfig();
299
+ break;
300
+ case "config":
301
+ displayConfig();
302
+ break;
303
+ case "start":
304
+ default:
305
+ if (isNewInstall) {
306
+ console.log("─────────────────────────────────────────────────────");
307
+ console.log(" First time setup complete!");
308
+ console.log(` Configuration file created at: ${ENV_FILE}`);
309
+ console.log(" You can customize settings there.");
310
+ console.log("─────────────────────────────────────────────────────\n");
311
+ }
312
+ console.log(`Starting server from: ${DEV_SERVER_HOME}`);
313
+ console.log(`Port: ${process.env.PORT || 3000}`);
314
+ console.log("");
315
+ // Import and start the actual server
316
+ // This must be done after env vars are loaded
317
+ await Promise.resolve().then(() => __importStar(require("./index")));
318
+ break;
319
+ }
320
+ }
321
+ // Run if executed directly
322
+ main().catch((error) => {
323
+ console.error("Failed to start LLM Dev Server:", error);
324
+ process.exit(1);
325
+ });
326
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { Sequelize } from 'sequelize';
2
+ declare class Database {
3
+ sequelize: Sequelize;
4
+ constructor();
5
+ initialize(): Promise<void>;
6
+ close(): Promise<void>;
7
+ }
8
+ export declare const database: Database;
9
+ export default database;
10
+ //# sourceMappingURL=database.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/config/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAMtC,cAAM,QAAQ;IACL,SAAS,EAAE,SAAS,CAAC;;IAqBtB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA4B3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B;AAED,eAAO,MAAM,QAAQ,UAAiB,CAAC;AACvC,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.database = void 0;
7
+ const sequelize_1 = require("sequelize");
8
+ const path_1 = __importDefault(require("path"));
9
+ const promises_1 = __importDefault(require("fs/promises"));
10
+ const environment_1 = __importDefault(require("./environment"));
11
+ const logger_1 = __importDefault(require("../utils/logger"));
12
+ class Database {
13
+ constructor() {
14
+ // Resolve database path
15
+ const dbPath = path_1.default.isAbsolute(environment_1.default.DATABASE_URL)
16
+ ? environment_1.default.DATABASE_URL
17
+ : path_1.default.join(process.cwd(), environment_1.default.DATABASE_URL);
18
+ logger_1.default.info(`Initializing database at: ${dbPath}`);
19
+ this.sequelize = new sequelize_1.Sequelize({
20
+ dialect: 'sqlite',
21
+ storage: dbPath,
22
+ logging: environment_1.default.NODE_ENV === 'development' ? (msg) => logger_1.default.debug(msg) : false,
23
+ define: {
24
+ underscored: false,
25
+ timestamps: true,
26
+ },
27
+ });
28
+ }
29
+ async initialize() {
30
+ try {
31
+ // Ensure data directory exists
32
+ const dataDir = path_1.default.dirname(path_1.default.isAbsolute(environment_1.default.DATABASE_URL)
33
+ ? environment_1.default.DATABASE_URL
34
+ : path_1.default.join(process.cwd(), environment_1.default.DATABASE_URL));
35
+ await promises_1.default.mkdir(dataDir, { recursive: true, mode: 0o700 });
36
+ // Test connection
37
+ await this.sequelize.authenticate();
38
+ logger_1.default.info('Database connection established successfully');
39
+ // Sync models (in development, use migrations in production)
40
+ if (environment_1.default.NODE_ENV === 'development') {
41
+ await this.sequelize.sync({ alter: true });
42
+ logger_1.default.info('Database synchronized');
43
+ }
44
+ else {
45
+ await this.sequelize.sync();
46
+ logger_1.default.info('Database synced');
47
+ }
48
+ }
49
+ catch (error) {
50
+ logger_1.default.error('Unable to connect to database:', error);
51
+ throw error;
52
+ }
53
+ }
54
+ async close() {
55
+ await this.sequelize.close();
56
+ logger_1.default.info('Database connection closed');
57
+ }
58
+ }
59
+ exports.database = new Database();
60
+ exports.default = exports.database;
61
+ //# sourceMappingURL=database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/config/database.ts"],"names":[],"mappings":";;;;;;AAAA,yCAAsC;AACtC,gDAAwB;AACxB,2DAA6B;AAC7B,gEAAmC;AACnC,6DAAqC;AAErC,MAAM,QAAQ;IAGZ;QACE,wBAAwB;QACxB,MAAM,MAAM,GAAG,cAAI,CAAC,UAAU,CAAC,qBAAM,CAAC,YAAY,CAAC;YACjD,CAAC,CAAC,qBAAM,CAAC,YAAY;YACrB,CAAC,CAAC,cAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,qBAAM,CAAC,YAAY,CAAC,CAAC;QAElD,gBAAM,CAAC,IAAI,CAAC,6BAA6B,MAAM,EAAE,CAAC,CAAC;QAEnD,IAAI,CAAC,SAAS,GAAG,IAAI,qBAAS,CAAC;YAC7B,OAAO,EAAE,QAAQ;YACjB,OAAO,EAAE,MAAM;YACf,OAAO,EAAE,qBAAM,CAAC,QAAQ,KAAK,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,gBAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK;YAC/E,MAAM,EAAE;gBACN,WAAW,EAAE,KAAK;gBAClB,UAAU,EAAE,IAAI;aACjB;SACF,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,CAAC;YACH,+BAA+B;YAC/B,MAAM,OAAO,GAAG,cAAI,CAAC,OAAO,CAC1B,cAAI,CAAC,UAAU,CAAC,qBAAM,CAAC,YAAY,CAAC;gBAClC,CAAC,CAAC,qBAAM,CAAC,YAAY;gBACrB,CAAC,CAAC,cAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,qBAAM,CAAC,YAAY,CAAC,CAClD,CAAC;YACF,MAAM,kBAAE,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YAE1D,kBAAkB;YAClB,MAAM,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;YACpC,gBAAM,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;YAE5D,6DAA6D;YAC7D,IAAI,qBAAM,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;gBACtC,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC3C,gBAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;YACvC,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;gBAC5B,gBAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,gBAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;YACtD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QAC7B,gBAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAC5C,CAAC;CACF;AAEY,QAAA,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;AACvC,kBAAe,gBAAQ,CAAC"}
@@ -0,0 +1,20 @@
1
+ interface Environment {
2
+ NODE_ENV: string;
3
+ PORT: number;
4
+ DATABASE_URL: string;
5
+ JWT_SECRET: string;
6
+ ENCRYPTION_KEY: string;
7
+ ALLOWED_ORIGINS: string[];
8
+ DATA_DIR: string;
9
+ WORKING_DIR_BASE: string;
10
+ CLAUDE_CLI_PATH?: string;
11
+ CODEX_CLI_PATH?: string;
12
+ GEMINI_CLI_PATH?: string;
13
+ LOG_LEVEL: string;
14
+ TRUST_PROXY: boolean | number | string;
15
+ AUTHELIA_ENABLED: boolean;
16
+ AUTHELIA_ADMIN_GROUPS: string[];
17
+ }
18
+ export declare const config: Environment;
19
+ export default config;
20
+ //# sourceMappingURL=environment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/config/environment.ts"],"names":[],"mappings":"AAgCA,UAAU,WAAW;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAElB,WAAW,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACvC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qBAAqB,EAAE,MAAM,EAAE,CAAC;CACjC;AA+CD,eAAO,MAAM,MAAM,aAAwB,CAAC;AAC5C,eAAe,MAAM,CAAC"}