@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
@@ -0,0 +1,77 @@
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.config = void 0;
7
+ const dotenv_1 = __importDefault(require("dotenv"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const os_1 = __importDefault(require("os"));
10
+ const fs_1 = __importDefault(require("fs"));
11
+ const crypto_1 = require("../utils/crypto");
12
+ // Determine home directory for persistent data
13
+ const DEV_SERVER_HOME = process.env.DEV_SERVER_HOME || path_1.default.join(os_1.default.homedir(), ".dev_server");
14
+ const DEFAULT_DATA_DIR = path_1.default.join(DEV_SERVER_HOME, "data");
15
+ const DEFAULT_WORKSPACES_DIR = path_1.default.join(DEV_SERVER_HOME, "workspaces");
16
+ const ENV_FILE = path_1.default.join(DEV_SERVER_HOME, ".env");
17
+ // Load environment variables from home directory first, then local .env
18
+ if (fs_1.default.existsSync(ENV_FILE)) {
19
+ dotenv_1.default.config({ path: ENV_FILE });
20
+ }
21
+ // Also load local .env for development override
22
+ dotenv_1.default.config();
23
+ /**
24
+ * Parse TRUST_PROXY value - can be boolean, number, or string
25
+ */
26
+ function parseTrustProxy(value) {
27
+ if (!value)
28
+ return false;
29
+ if (value === "true")
30
+ return true;
31
+ if (value === "false")
32
+ return false;
33
+ const num = parseInt(value, 10);
34
+ if (!isNaN(num))
35
+ return num;
36
+ return value; // e.g., 'loopback', 'linklocal', 'uniquelocal'
37
+ }
38
+ function validateEnvironment() {
39
+ const env = process.env;
40
+ // Generate secrets if missing (both dev and first-time production)
41
+ if (!env.JWT_SECRET) {
42
+ env.JWT_SECRET = (0, crypto_1.generateRandomHex)(64);
43
+ console.warn("[WARN] Generated JWT_SECRET. Set it in ~/.dev_server/.env for persistence!");
44
+ }
45
+ if (!env.ENCRYPTION_KEY) {
46
+ env.ENCRYPTION_KEY = (0, crypto_1.generateRandomHex)(32);
47
+ console.warn("[WARN] Generated ENCRYPTION_KEY. Set it in ~/.dev_server/.env for persistence!");
48
+ }
49
+ // Use home directory defaults
50
+ const dataDir = env.DATA_DIR || DEFAULT_DATA_DIR;
51
+ const databaseUrl = env.DATABASE_URL || path_1.default.join(dataDir, "dev-server.db");
52
+ return {
53
+ NODE_ENV: env.NODE_ENV || "development",
54
+ PORT: parseInt(env.PORT || "3000", 10),
55
+ DATABASE_URL: databaseUrl,
56
+ JWT_SECRET: env.JWT_SECRET,
57
+ ENCRYPTION_KEY: env.ENCRYPTION_KEY,
58
+ ALLOWED_ORIGINS: env.ALLOWED_ORIGINS
59
+ ? env.ALLOWED_ORIGINS.split(",")
60
+ : ["http://localhost:3000", "http://localhost:5173"],
61
+ DATA_DIR: dataDir,
62
+ WORKING_DIR_BASE: env.WORKING_DIR_BASE || DEFAULT_WORKSPACES_DIR,
63
+ CLAUDE_CLI_PATH: env.CLAUDE_CLI_PATH,
64
+ CODEX_CLI_PATH: env.CODEX_CLI_PATH,
65
+ GEMINI_CLI_PATH: env.GEMINI_CLI_PATH,
66
+ LOG_LEVEL: env.LOG_LEVEL || "info",
67
+ // Proxy & Authelia
68
+ TRUST_PROXY: parseTrustProxy(env.TRUST_PROXY),
69
+ AUTHELIA_ENABLED: env.AUTHELIA_ENABLED === "true",
70
+ AUTHELIA_ADMIN_GROUPS: env.AUTHELIA_ADMIN_GROUPS
71
+ ? env.AUTHELIA_ADMIN_GROUPS.split(",")
72
+ : ["admins"],
73
+ };
74
+ }
75
+ exports.config = validateEnvironment();
76
+ exports.default = exports.config;
77
+ //# sourceMappingURL=environment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.js","sourceRoot":"","sources":["../../src/config/environment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { Request, Response } from "express";
2
+ export declare class AuthController {
3
+ static register(req: Request, res: Response): Promise<void>;
4
+ static login(req: Request, res: Response): Promise<void>;
5
+ static me(req: Request, res: Response): Promise<void>;
6
+ static claudeLoginRedirect(req: Request, res: Response): Promise<void>;
7
+ static claudeCallback(req: Request, res: Response): Promise<void>;
8
+ static claudeStatus(req: Request, res: Response): Promise<void>;
9
+ static claudeManualLoginStart(req: Request, res: Response): Promise<void>;
10
+ static claudeManualLoginComplete(req: Request, res: Response): Promise<void>;
11
+ static codexLoginStart(req: Request, res: Response): Promise<void>;
12
+ static codexLoginPoll(req: Request, res: Response): Promise<void>;
13
+ static codexStatus(req: Request, res: Response): Promise<void>;
14
+ static geminiLoginStart(req: Request, res: Response): Promise<void>;
15
+ static geminiLoginComplete(req: Request, res: Response): Promise<void>;
16
+ static geminiStatus(req: Request, res: Response): Promise<void>;
17
+ }
18
+ //# sourceMappingURL=AuthController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthController.d.ts","sourceRoot":"","sources":["../../src/controllers/AuthController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAW5C,qBAAa,cAAc;WAEZ,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAyBpC,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAwCjC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAY9B,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAmB/C,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAiC1C,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAaxC,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAgClD,yBAAyB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAuCrD,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAW3C,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAW1C,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAavC,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAsB5C,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WA2B/C,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;CAUtD"}
@@ -0,0 +1,282 @@
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.AuthController = void 0;
7
+ const models_1 = require("../models");
8
+ const JwtService_1 = require("../services/auth/JwtService");
9
+ const ClaudeAuthService_1 = require("../services/auth/ClaudeAuthService");
10
+ const CodexAuthService_1 = require("../services/auth/CodexAuthService");
11
+ const GeminiAuthService_1 = require("../services/auth/GeminiAuthService");
12
+ const TokenRefreshService_1 = require("../services/auth/TokenRefreshService");
13
+ const crypto_1 = require("../utils/crypto");
14
+ const validators_1 = require("../utils/validators");
15
+ const logger_1 = __importDefault(require("../utils/logger"));
16
+ class AuthController {
17
+ // User Registration
18
+ static async register(req, res) {
19
+ try {
20
+ const { username, password } = (0, validators_1.validate)(validators_1.userCreateSchema, req.body);
21
+ const passwordHash = await (0, crypto_1.hashPassword)(password);
22
+ const user = await models_1.User.create({ username, passwordHash, role: "user" });
23
+ res.status(201).json({
24
+ data: {
25
+ id: user.id,
26
+ username: user.username,
27
+ role: user.role,
28
+ createdAt: user.createdAt.toISOString(),
29
+ },
30
+ });
31
+ }
32
+ catch (error) {
33
+ const message = error instanceof Error ? error.message : String(error);
34
+ res.status(400).json({ error: "Registration failed", message });
35
+ }
36
+ }
37
+ // User Login
38
+ static async login(req, res) {
39
+ try {
40
+ const { username, password } = (0, validators_1.validate)(validators_1.loginSchema, req.body);
41
+ const user = await models_1.User.findOne({ where: { username } });
42
+ // Check if user exists and has a password (Authelia users don't have passwords)
43
+ if (!user || !user.passwordHash) {
44
+ res.status(401).json({ error: "Invalid credentials" });
45
+ return;
46
+ }
47
+ if (!(await (0, crypto_1.comparePassword)(password, user.passwordHash))) {
48
+ res.status(401).json({ error: "Invalid credentials" });
49
+ return;
50
+ }
51
+ const token = JwtService_1.JwtService.generateToken(user);
52
+ res.json({
53
+ data: {
54
+ token,
55
+ expiresIn: JwtService_1.JwtService.getExpiresIn(),
56
+ user: {
57
+ id: user.id,
58
+ username: user.username,
59
+ role: user.role,
60
+ },
61
+ },
62
+ });
63
+ }
64
+ catch (error) {
65
+ const message = error instanceof Error ? error.message : String(error);
66
+ res.status(400).json({ error: "Login failed", message });
67
+ }
68
+ }
69
+ // Get current user
70
+ static async me(req, res) {
71
+ try {
72
+ const user = await models_1.User.findByPk(req.user.userId);
73
+ res.json({ data: user });
74
+ }
75
+ catch (error) {
76
+ const message = error instanceof Error ? error.message : String(error);
77
+ res.status(500).json({ error: "Failed to get user", message });
78
+ }
79
+ }
80
+ // ==================== Claude OAuth with Redirects ====================
81
+ static async claudeLoginRedirect(req, res) {
82
+ try {
83
+ const service = new ClaudeAuthService_1.ClaudeAuthService();
84
+ // Get server base URL from request
85
+ const protocol = req.protocol;
86
+ const host = req.get("host");
87
+ const redirectUri = `${protocol}://${host}/api/auth/claude/callback`;
88
+ const result = await service.startLoginWithRedirect(redirectUri);
89
+ // Redirect user to OAuth provider
90
+ res.redirect(result.loginUrl);
91
+ }
92
+ catch (error) {
93
+ const message = error instanceof Error ? error.message : String(error);
94
+ res.status(500).send(`Failed to start Claude login: ${message}`);
95
+ }
96
+ }
97
+ static async claudeCallback(req, res) {
98
+ try {
99
+ const { code, state, session_state } = req.query;
100
+ if (!code || !state) {
101
+ res.status(400).send("Missing code or state parameter");
102
+ return;
103
+ }
104
+ const service = new ClaudeAuthService_1.ClaudeAuthService();
105
+ const token = await service.completeLoginFromCallback(code, state);
106
+ TokenRefreshService_1.TokenRefreshService.getInstance().start(token.id);
107
+ // Redirect back to frontend with success
108
+ const frontendUrl = req.get("origin") || "http://localhost:5174";
109
+ res.redirect(`${frontendUrl}/?auth=claude&status=success`);
110
+ }
111
+ catch (error) {
112
+ const message = error instanceof Error ? error.message : String(error);
113
+ logger_1.default.error("Claude callback error:", message);
114
+ const frontendUrl = req.get("origin") || "http://localhost:5174";
115
+ res.redirect(`${frontendUrl}/?auth=claude&status=error&message=${encodeURIComponent(message)}`);
116
+ }
117
+ }
118
+ static async claudeStatus(req, res) {
119
+ try {
120
+ const service = new ClaudeAuthService_1.ClaudeAuthService();
121
+ const status = await service.getStatus();
122
+ res.json({ data: status });
123
+ }
124
+ catch (error) {
125
+ const message = error instanceof Error ? error.message : String(error);
126
+ res.status(500).json({ error: "Failed to get Claude status", message });
127
+ }
128
+ }
129
+ // ==================== Claude Manual Code Entry Flow ====================
130
+ static async claudeManualLoginStart(req, res) {
131
+ try {
132
+ const service = new ClaudeAuthService_1.ClaudeAuthService();
133
+ const { loginWithClaudeAi } = req.body;
134
+ const result = await service.startLoginWithRedirect(undefined, loginWithClaudeAi !== false);
135
+ // Return login URL and state to frontend
136
+ // Frontend will open URL in new tab and show code input
137
+ res.json({
138
+ data: {
139
+ loginUrl: result.loginUrl,
140
+ state: result.state,
141
+ redirectUri: "https://console.anthropic.com/oauth/code/callback",
142
+ scopes: [
143
+ "org:create_api_key",
144
+ "user:profile",
145
+ "user:inference",
146
+ "user:sessions:claude_code",
147
+ ],
148
+ instructions: "After authenticating, copy the entire callback URL from the browser and paste it in the application.",
149
+ },
150
+ });
151
+ }
152
+ catch (error) {
153
+ const message = error instanceof Error ? error.message : String(error);
154
+ res.status(500).json({ error: "Failed to start Claude login", message });
155
+ }
156
+ }
157
+ static async claudeManualLoginComplete(req, res) {
158
+ try {
159
+ let { code, state } = req.body;
160
+ if (!code || !state) {
161
+ res.status(400).json({ error: "Missing code or state parameter" });
162
+ return;
163
+ }
164
+ // Parse callback input (user might paste full URL)
165
+ const parsed = ClaudeAuthService_1.ClaudeAuthService.parseCallbackInput(code);
166
+ if (parsed.code) {
167
+ code = parsed.code;
168
+ }
169
+ if (parsed.state && !state) {
170
+ state = parsed.state;
171
+ }
172
+ const service = new ClaudeAuthService_1.ClaudeAuthService();
173
+ const token = await service.completeLoginFromCallback(code, state);
174
+ res.json({
175
+ data: {
176
+ tokenId: token.id,
177
+ email: token.email,
178
+ expiresAt: token.expiresAt?.toISOString(),
179
+ },
180
+ });
181
+ }
182
+ catch (error) {
183
+ const message = error instanceof Error ? error.message : String(error);
184
+ logger_1.default.error("Claude login complete error:", message);
185
+ res
186
+ .status(500)
187
+ .json({ error: "Failed to complete Claude login", message });
188
+ }
189
+ }
190
+ // ==================== Codex Device Auth (unchanged) ====================
191
+ static async codexLoginStart(req, res) {
192
+ try {
193
+ const service = new CodexAuthService_1.CodexAuthService();
194
+ const result = await service.startLogin();
195
+ res.json({ data: result });
196
+ }
197
+ catch (error) {
198
+ const message = error instanceof Error ? error.message : String(error);
199
+ res.status(500).json({ error: "Failed to start Codex login", message });
200
+ }
201
+ }
202
+ static async codexLoginPoll(req, res) {
203
+ try {
204
+ const service = new CodexAuthService_1.CodexAuthService();
205
+ const token = await service.pollForToken(req.body);
206
+ res.json({ data: { tokenId: token.id, email: token.email } });
207
+ }
208
+ catch (error) {
209
+ const message = error instanceof Error ? error.message : String(error);
210
+ res.status(400).json({ error: "Device auth not yet approved", message });
211
+ }
212
+ }
213
+ static async codexStatus(req, res) {
214
+ try {
215
+ const service = new CodexAuthService_1.CodexAuthService();
216
+ const status = await service.getStatus();
217
+ res.json({ data: status });
218
+ }
219
+ catch (error) {
220
+ const message = error instanceof Error ? error.message : String(error);
221
+ res.status(500).json({ error: "Failed to get Codex status", message });
222
+ }
223
+ }
224
+ // ==================== Gemini OAuth with Manual Code ====================
225
+ static async geminiLoginStart(req, res) {
226
+ try {
227
+ const service = new GeminiAuthService_1.GeminiAuthService();
228
+ const result = await service.startLoginWithRedirect("");
229
+ // Return login URL and state to frontend
230
+ // Frontend will open URL in new tab and show code input
231
+ res.json({
232
+ data: {
233
+ loginUrl: result.loginUrl,
234
+ state: result.state,
235
+ verificationUrl: "https://codeassist.google.com/authcode",
236
+ instructions: "After authenticating, Google will show you an authorization code. Copy it and paste it in the application.",
237
+ },
238
+ });
239
+ }
240
+ catch (error) {
241
+ const message = error instanceof Error ? error.message : String(error);
242
+ res.status(500).json({ error: "Failed to start Gemini login", message });
243
+ }
244
+ }
245
+ static async geminiLoginComplete(req, res) {
246
+ try {
247
+ const { code, state } = req.body;
248
+ if (!code || !state) {
249
+ res.status(400).json({ error: "Missing code or state parameter" });
250
+ return;
251
+ }
252
+ const service = new GeminiAuthService_1.GeminiAuthService();
253
+ const token = await service.completeLoginFromCallback(code, state);
254
+ res.json({
255
+ data: {
256
+ tokenId: token.id,
257
+ email: token.email,
258
+ },
259
+ });
260
+ }
261
+ catch (error) {
262
+ const message = error instanceof Error ? error.message : String(error);
263
+ logger_1.default.error("Gemini login complete error:", message);
264
+ res
265
+ .status(500)
266
+ .json({ error: "Failed to complete Gemini login", message });
267
+ }
268
+ }
269
+ static async geminiStatus(req, res) {
270
+ try {
271
+ const service = new GeminiAuthService_1.GeminiAuthService();
272
+ const status = await service.getStatus();
273
+ res.json({ data: status });
274
+ }
275
+ catch (error) {
276
+ const message = error instanceof Error ? error.message : String(error);
277
+ res.status(500).json({ error: "Failed to get Gemini status", message });
278
+ }
279
+ }
280
+ }
281
+ exports.AuthController = AuthController;
282
+ //# sourceMappingURL=AuthController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthController.js","sourceRoot":"","sources":["../../src/controllers/AuthController.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { Request, Response } from "express";
2
+ export declare class ConversationController {
3
+ /**
4
+ * Create a new conversation
5
+ * POST /api/conversations
6
+ */
7
+ static create(req: Request, res: Response): Promise<void>;
8
+ /**
9
+ * Get a conversation by ID
10
+ * GET /api/conversations/:conversationId
11
+ */
12
+ static get(req: Request, res: Response): Promise<void>;
13
+ /**
14
+ * Update a conversation
15
+ * PATCH /api/conversations/:conversationId
16
+ */
17
+ static update(req: Request, res: Response): Promise<void>;
18
+ /**
19
+ * Get available providers
20
+ * GET /api/conversations/providers
21
+ */
22
+ static getProviders(req: Request, res: Response): Promise<void>;
23
+ /**
24
+ * Get conversation messages
25
+ * GET /api/conversations/:conversationId/messages
26
+ */
27
+ static getMessages(req: Request, res: Response): Promise<void>;
28
+ /**
29
+ * Send a message in a conversation
30
+ * POST /api/conversations/:conversationId/messages
31
+ */
32
+ static sendMessage(req: Request, res: Response): Promise<void>;
33
+ /**
34
+ * Stream a conversation (SSE)
35
+ * GET /api/conversations/:conversationId/stream
36
+ */
37
+ static stream(req: Request, res: Response): Promise<void>;
38
+ /**
39
+ * Delete a conversation
40
+ * DELETE /api/conversations/:conversationId
41
+ */
42
+ static delete(req: Request, res: Response): Promise<void>;
43
+ }
44
+ //# sourceMappingURL=ConversationController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConversationController.d.ts","sourceRoot":"","sources":["../../src/controllers/ConversationController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAS5C,qBAAa,sBAAsB;IACjC;;;OAGG;WACU,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAsC/D;;;OAGG;WACU,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB5D;;;OAGG;WACU,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB/D;;;OAGG;WACU,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAWrE;;;OAGG;WACU,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBpE;;;OAGG;WACU,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BpE;;;OAGG;WACU,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAkC/D;;;OAGG;WACU,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAahE"}
@@ -0,0 +1,193 @@
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.ConversationController = void 0;
7
+ const ConversationService_1 = require("../services/conversation/ConversationService");
8
+ const logger_1 = __importDefault(require("../utils/logger"));
9
+ class ConversationController {
10
+ /**
11
+ * Create a new conversation
12
+ * POST /api/conversations
13
+ */
14
+ static async create(req, res) {
15
+ try {
16
+ const { jobId, provider, model, title, systemPrompt } = req.body;
17
+ if (!jobId || !provider) {
18
+ res.status(400).json({ error: "jobId and provider are required" });
19
+ return;
20
+ }
21
+ const { conversation, provider: llmProvider } = await ConversationService_1.ConversationService.createConversation({
22
+ jobId,
23
+ provider,
24
+ model,
25
+ title,
26
+ systemPrompt,
27
+ });
28
+ res.status(201).json({
29
+ conversation,
30
+ providerInfo: {
31
+ type: llmProvider.constructor.name,
32
+ model: llmProvider.model,
33
+ },
34
+ });
35
+ }
36
+ catch (error) {
37
+ const message = error instanceof Error ? error.message : String(error);
38
+ logger_1.default.error("Error creating conversation:", message);
39
+ res.status(500).json({ error: message });
40
+ }
41
+ }
42
+ /**
43
+ * Get a conversation by ID
44
+ * GET /api/conversations/:conversationId
45
+ */
46
+ static async get(req, res) {
47
+ try {
48
+ const { conversationId } = req.params;
49
+ const conversation = await ConversationService_1.ConversationService.getConversation(conversationId);
50
+ if (!conversation) {
51
+ res.status(404).json({ error: "Conversation not found" });
52
+ return;
53
+ }
54
+ res.json(conversation);
55
+ }
56
+ catch (error) {
57
+ const message = error instanceof Error ? error.message : String(error);
58
+ logger_1.default.error("Error getting conversation:", message);
59
+ res.status(500).json({ error: message });
60
+ }
61
+ }
62
+ /**
63
+ * Update a conversation
64
+ * PATCH /api/conversations/:conversationId
65
+ */
66
+ static async update(req, res) {
67
+ try {
68
+ const { conversationId } = req.params;
69
+ const params = req.body;
70
+ const conversation = await ConversationService_1.ConversationService.updateConversation(conversationId, params);
71
+ res.json(conversation);
72
+ }
73
+ catch (error) {
74
+ const message = error instanceof Error ? error.message : String(error);
75
+ logger_1.default.error("Error updating conversation:", message);
76
+ res.status(500).json({ error: message });
77
+ }
78
+ }
79
+ /**
80
+ * Get available providers
81
+ * GET /api/conversations/providers
82
+ */
83
+ static async getProviders(req, res) {
84
+ try {
85
+ const providers = await ConversationService_1.ConversationService.getAvailableProviders();
86
+ res.json({ providers });
87
+ }
88
+ catch (error) {
89
+ const message = error instanceof Error ? error.message : String(error);
90
+ logger_1.default.error("Error getting providers:", message);
91
+ res.status(500).json({ error: message });
92
+ }
93
+ }
94
+ /**
95
+ * Get conversation messages
96
+ * GET /api/conversations/:conversationId/messages
97
+ */
98
+ static async getMessages(req, res) {
99
+ try {
100
+ const { conversationId } = req.params;
101
+ const limit = req.query.limit
102
+ ? parseInt(req.query.limit, 10)
103
+ : undefined;
104
+ const offset = req.query.offset
105
+ ? parseInt(req.query.offset, 10)
106
+ : undefined;
107
+ const result = await ConversationService_1.ConversationService.getMessages(conversationId, {
108
+ limit,
109
+ offset,
110
+ });
111
+ res.json(result);
112
+ }
113
+ catch (error) {
114
+ const message = error instanceof Error ? error.message : String(error);
115
+ logger_1.default.error("Error getting messages:", message);
116
+ res.status(500).json({ error: message });
117
+ }
118
+ }
119
+ /**
120
+ * Send a message in a conversation
121
+ * POST /api/conversations/:conversationId/messages
122
+ */
123
+ static async sendMessage(req, res) {
124
+ try {
125
+ const { conversationId } = req.params;
126
+ const { content, attachments } = req.body;
127
+ if (!content) {
128
+ res.status(400).json({ error: "content is required" });
129
+ return;
130
+ }
131
+ const result = await ConversationService_1.ConversationService.sendMessage({
132
+ conversationId,
133
+ content,
134
+ attachments,
135
+ });
136
+ res.json(result);
137
+ }
138
+ catch (error) {
139
+ const message = error instanceof Error ? error.message : String(error);
140
+ logger_1.default.error("Error sending message:", message);
141
+ res.status(500).json({ error: message });
142
+ }
143
+ }
144
+ /**
145
+ * Stream a conversation (SSE)
146
+ * GET /api/conversations/:conversationId/stream
147
+ */
148
+ static async stream(req, res) {
149
+ try {
150
+ const { conversationId } = req.params;
151
+ // Set up SSE
152
+ res.setHeader("Content-Type", "text/event-stream");
153
+ res.setHeader("Cache-Control", "no-cache");
154
+ res.setHeader("Connection", "keep-alive");
155
+ // Send chunks as SSE events
156
+ const result = await ConversationService_1.ConversationService.sendMessage({
157
+ conversationId,
158
+ content: req.body.content,
159
+ attachments: req.body.attachments,
160
+ onChunk: (chunk) => {
161
+ res.write(`data: ${JSON.stringify({ type: "chunk", content: chunk })}\n\n`);
162
+ },
163
+ });
164
+ // Send final message
165
+ res.write(`data: ${JSON.stringify({ type: "done", result })}\n\n`);
166
+ res.end();
167
+ }
168
+ catch (error) {
169
+ const message = error instanceof Error ? error.message : String(error);
170
+ logger_1.default.error("Error streaming conversation:", message);
171
+ res.write(`data: ${JSON.stringify({ type: "error", error: message })}\n\n`);
172
+ res.end();
173
+ }
174
+ }
175
+ /**
176
+ * Delete a conversation
177
+ * DELETE /api/conversations/:conversationId
178
+ */
179
+ static async delete(req, res) {
180
+ try {
181
+ const { conversationId } = req.params;
182
+ await ConversationService_1.ConversationService.deleteConversation(conversationId);
183
+ res.status(204).send();
184
+ }
185
+ catch (error) {
186
+ const message = error instanceof Error ? error.message : String(error);
187
+ logger_1.default.error("Error deleting conversation:", message);
188
+ res.status(500).json({ error: message });
189
+ }
190
+ }
191
+ }
192
+ exports.ConversationController = ConversationController;
193
+ //# sourceMappingURL=ConversationController.js.map