ai-vault 2.0.1 → 3.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 (94) hide show
  1. package/dist/api/middleware/error-handler.d.ts +12 -0
  2. package/dist/api/middleware/error-handler.d.ts.map +1 -0
  3. package/dist/api/middleware/error-handler.js +29 -0
  4. package/dist/api/middleware/error-handler.js.map +1 -0
  5. package/dist/api/middleware/logger.d.ts +6 -0
  6. package/dist/api/middleware/logger.d.ts.map +1 -0
  7. package/dist/api/middleware/logger.js +17 -0
  8. package/dist/api/middleware/logger.js.map +1 -0
  9. package/dist/api/middleware/rate-limiter.d.ts +6 -0
  10. package/dist/api/middleware/rate-limiter.d.ts.map +1 -0
  11. package/dist/api/middleware/rate-limiter.js +41 -0
  12. package/dist/api/middleware/rate-limiter.js.map +1 -0
  13. package/dist/api/routes/archive.d.ts +6 -0
  14. package/dist/api/routes/archive.d.ts.map +1 -0
  15. package/dist/api/routes/archive.js +140 -0
  16. package/dist/api/routes/archive.js.map +1 -0
  17. package/dist/api/routes/conversations.d.ts +6 -0
  18. package/dist/api/routes/conversations.d.ts.map +1 -0
  19. package/dist/api/routes/conversations.js +193 -0
  20. package/dist/api/routes/conversations.js.map +1 -0
  21. package/dist/api/routes/media.d.ts +6 -0
  22. package/dist/api/routes/media.d.ts.map +1 -0
  23. package/dist/api/routes/media.js +152 -0
  24. package/dist/api/routes/media.js.map +1 -0
  25. package/dist/api/routes/providers.d.ts +6 -0
  26. package/dist/api/routes/providers.d.ts.map +1 -0
  27. package/dist/api/routes/providers.js +111 -0
  28. package/dist/api/routes/providers.js.map +1 -0
  29. package/dist/api/routes/schedules.d.ts +6 -0
  30. package/dist/api/routes/schedules.d.ts.map +1 -0
  31. package/dist/api/routes/schedules.js +119 -0
  32. package/dist/api/routes/schedules.js.map +1 -0
  33. package/dist/api/routes/search.d.ts +6 -0
  34. package/dist/api/routes/search.d.ts.map +1 -0
  35. package/dist/api/routes/search.js +107 -0
  36. package/dist/api/routes/search.js.map +1 -0
  37. package/dist/api/routes/settings.d.ts +6 -0
  38. package/dist/api/routes/settings.d.ts.map +1 -0
  39. package/dist/api/routes/settings.js +82 -0
  40. package/dist/api/routes/settings.js.map +1 -0
  41. package/dist/api/server.d.ts +28 -0
  42. package/dist/api/server.d.ts.map +1 -0
  43. package/dist/api/server.js +161 -0
  44. package/dist/api/server.js.map +1 -0
  45. package/dist/api/services/search-service.d.ts +71 -0
  46. package/dist/api/services/search-service.d.ts.map +1 -0
  47. package/dist/api/services/search-service.js +259 -0
  48. package/dist/api/services/search-service.js.map +1 -0
  49. package/dist/cli.js +15 -0
  50. package/dist/cli.js.map +1 -1
  51. package/dist/commands/archive.d.ts +1 -0
  52. package/dist/commands/archive.d.ts.map +1 -1
  53. package/dist/commands/archive.js +158 -126
  54. package/dist/commands/archive.js.map +1 -1
  55. package/dist/commands/ui.d.ts +6 -0
  56. package/dist/commands/ui.d.ts.map +1 -0
  57. package/dist/commands/ui.js +48 -0
  58. package/dist/commands/ui.js.map +1 -0
  59. package/dist/providers/auth/base-strategy-provider.d.ts +67 -0
  60. package/dist/providers/auth/base-strategy-provider.d.ts.map +1 -0
  61. package/dist/providers/auth/base-strategy-provider.js +158 -0
  62. package/dist/providers/auth/base-strategy-provider.js.map +1 -0
  63. package/dist/providers/auth/index.d.ts +8 -0
  64. package/dist/providers/auth/index.d.ts.map +1 -0
  65. package/dist/providers/auth/index.js +8 -0
  66. package/dist/providers/auth/index.js.map +1 -0
  67. package/dist/providers/auth/strategies.d.ts +138 -0
  68. package/dist/providers/auth/strategies.d.ts.map +1 -0
  69. package/dist/providers/auth/strategies.js +283 -0
  70. package/dist/providers/auth/strategies.js.map +1 -0
  71. package/dist/providers/chatgpt/api-provider.d.ts +51 -0
  72. package/dist/providers/chatgpt/api-provider.d.ts.map +1 -0
  73. package/dist/providers/chatgpt/api-provider.js +435 -0
  74. package/dist/providers/chatgpt/api-provider.js.map +1 -0
  75. package/dist/providers/claude/api-provider.d.ts +49 -0
  76. package/dist/providers/claude/api-provider.d.ts.map +1 -0
  77. package/dist/providers/claude/api-provider.js +357 -0
  78. package/dist/providers/claude/api-provider.js.map +1 -0
  79. package/dist/providers/grok-web/api-provider.d.ts +57 -0
  80. package/dist/providers/grok-web/api-provider.d.ts.map +1 -0
  81. package/dist/providers/grok-web/api-provider.js +393 -0
  82. package/dist/providers/grok-web/api-provider.js.map +1 -0
  83. package/dist/providers/grok-x/api-provider.d.ts +41 -0
  84. package/dist/providers/grok-x/api-provider.d.ts.map +1 -0
  85. package/dist/providers/grok-x/api-provider.js +173 -0
  86. package/dist/providers/grok-x/api-provider.js.map +1 -0
  87. package/dist/utils/scheduler.d.ts.map +1 -1
  88. package/dist/utils/scheduler.js +20 -3
  89. package/dist/utils/scheduler.js.map +1 -1
  90. package/dist/utils/scheduler.spec.d.ts +5 -0
  91. package/dist/utils/scheduler.spec.d.ts.map +1 -0
  92. package/dist/utils/scheduler.spec.js +163 -0
  93. package/dist/utils/scheduler.spec.js.map +1 -0
  94. package/package.json +5 -1
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Global error handler middleware
3
+ */
4
+ import type { Request, Response, NextFunction } from 'express';
5
+ export interface ApiError extends Error {
6
+ statusCode?: number;
7
+ details?: unknown;
8
+ }
9
+ export declare function errorHandler(err: ApiError, _req: Request, res: Response, _next: NextFunction): void;
10
+ export declare function createError(message: string, statusCode?: number, details?: unknown): ApiError;
11
+ export declare function isApiError(error: unknown): error is ApiError;
12
+ //# sourceMappingURL=error-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../../src/api/middleware/error-handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG/D,MAAM,WAAW,QAAS,SAAQ,KAAK;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,YAAY,CAC1B,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE,YAAY,GAClB,IAAI,CAgBN;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,UAAU,GAAE,MAAY,EACxB,OAAO,CAAC,EAAE,OAAO,GAChB,QAAQ,CAKV;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Global error handler middleware
3
+ */
4
+ import chalk from 'chalk';
5
+ export function errorHandler(err, _req, res, _next) {
6
+ const statusCode = err.statusCode || 500;
7
+ const message = err.message || 'Internal server error';
8
+ // Log error
9
+ console.error(chalk.red(`[API Error] ${statusCode}: ${message}`));
10
+ if (err.stack) {
11
+ console.error(chalk.gray(err.stack));
12
+ }
13
+ // Send error response
14
+ res.status(statusCode).json({
15
+ error: message,
16
+ details: err.details,
17
+ ...(process.env.NODE_ENV === 'development' && { stack: err.stack }),
18
+ });
19
+ }
20
+ export function createError(message, statusCode = 500, details) {
21
+ const error = new Error(message);
22
+ error.statusCode = statusCode;
23
+ error.details = details;
24
+ return error;
25
+ }
26
+ export function isApiError(error) {
27
+ return typeof error === 'object' && error !== null && 'statusCode' in error;
28
+ }
29
+ //# sourceMappingURL=error-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../../src/api/middleware/error-handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,MAAM,UAAU,YAAY,CAC1B,GAAa,EACb,IAAa,EACb,GAAa,EACb,KAAmB;IAEnB,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC;IACzC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,uBAAuB,CAAC;IAEvD,YAAY;IACZ,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,UAAU,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;IAClE,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,sBAAsB;IACtB,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;QAC1B,KAAK,EAAE,OAAO;QACd,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC;KACpE,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,OAAe,EACf,aAAqB,GAAG,EACxB,OAAiB;IAEjB,MAAM,KAAK,GAAa,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3C,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC;IAC9B,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,YAAY,IAAI,KAAK,CAAC;AAC9E,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Request logging middleware
3
+ */
4
+ import type { Request, Response, NextFunction } from 'express';
5
+ export declare function requestLogger(req: Request, res: Response, next: NextFunction): void;
6
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/api/middleware/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG/D,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAkBnF"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Request logging middleware
3
+ */
4
+ import chalk from 'chalk';
5
+ export function requestLogger(req, res, next) {
6
+ const start = Date.now();
7
+ // Log request
8
+ console.log(chalk.gray(`[${new Date().toISOString()}] ${req.method} ${req.path}`));
9
+ // Log response when finished
10
+ res.on('finish', () => {
11
+ const duration = Date.now() - start;
12
+ const statusColor = res.statusCode >= 400 ? chalk.red : chalk.green;
13
+ console.log(chalk.gray(`[${new Date().toISOString()}] ${req.method} ${req.path} ${statusColor(res.statusCode)} - ${duration}ms`));
14
+ });
15
+ next();
16
+ }
17
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/api/middleware/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,UAAU,aAAa,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB;IAC3E,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB,cAAc;IACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAEnF,6BAA6B;IAC7B,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QACpC,MAAM,WAAW,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC;QACpE,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CACR,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,QAAQ,IAAI,CACzG,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAI,EAAE,CAAC;AACT,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Simple rate limiting middleware
3
+ */
4
+ import type { Request, Response, NextFunction } from 'express';
5
+ export declare function rateLimiter(req: Request, res: Response, next: NextFunction): void;
6
+ //# sourceMappingURL=rate-limiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../../src/api/middleware/rate-limiter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAY/D,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAuCjF"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Simple rate limiting middleware
3
+ */
4
+ const rateLimitStore = new Map();
5
+ const RATE_LIMIT_WINDOW = 60 * 1000; // 1 minute
6
+ const RATE_LIMIT_MAX_REQUESTS = 100; // 100 requests per minute
7
+ export function rateLimiter(req, res, next) {
8
+ const clientId = req.ip || 'unknown';
9
+ const now = Date.now();
10
+ // Clean up expired entries
11
+ for (const [key, entry] of rateLimitStore.entries()) {
12
+ if (now > entry.resetTime) {
13
+ rateLimitStore.delete(key);
14
+ }
15
+ }
16
+ // Get or create entry for this client
17
+ let entry = rateLimitStore.get(clientId);
18
+ if (!entry || now > entry.resetTime) {
19
+ entry = {
20
+ count: 0,
21
+ resetTime: now + RATE_LIMIT_WINDOW,
22
+ };
23
+ rateLimitStore.set(clientId, entry);
24
+ }
25
+ // Increment request count
26
+ entry.count++;
27
+ // Check if rate limit exceeded
28
+ if (entry.count > RATE_LIMIT_MAX_REQUESTS) {
29
+ res.status(429).json({
30
+ error: 'Too many requests',
31
+ retryAfter: Math.ceil((entry.resetTime - now) / 1000),
32
+ });
33
+ return;
34
+ }
35
+ // Set rate limit headers
36
+ res.setHeader('X-RateLimit-Limit', RATE_LIMIT_MAX_REQUESTS);
37
+ res.setHeader('X-RateLimit-Remaining', RATE_LIMIT_MAX_REQUESTS - entry.count);
38
+ res.setHeader('X-RateLimit-Reset', entry.resetTime);
39
+ next();
40
+ }
41
+ //# sourceMappingURL=rate-limiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../../src/api/middleware/rate-limiter.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,MAAM,cAAc,GAAG,IAAI,GAAG,EAA0B,CAAC;AAEzD,MAAM,iBAAiB,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW;AAChD,MAAM,uBAAuB,GAAG,GAAG,CAAC,CAAC,0BAA0B;AAE/D,MAAM,UAAU,WAAW,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB;IACzE,MAAM,QAAQ,GAAG,GAAG,CAAC,EAAE,IAAI,SAAS,CAAC;IACrC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEvB,2BAA2B;IAC3B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,cAAc,CAAC,OAAO,EAAE,EAAE,CAAC;QACpD,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YAC1B,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,sCAAsC;IACtC,IAAI,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,KAAK,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;QACpC,KAAK,GAAG;YACN,KAAK,EAAE,CAAC;YACR,SAAS,EAAE,GAAG,GAAG,iBAAiB;SACnC,CAAC;QACF,cAAc,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,0BAA0B;IAC1B,KAAK,CAAC,KAAK,EAAE,CAAC;IAEd,+BAA+B;IAC/B,IAAI,KAAK,CAAC,KAAK,GAAG,uBAAuB,EAAE,CAAC;QAC1C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,KAAK,EAAE,mBAAmB;YAC1B,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC;SACtD,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,yBAAyB;IACzB,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,uBAAuB,CAAC,CAAC;IAC5D,GAAG,CAAC,SAAS,CAAC,uBAAuB,EAAE,uBAAuB,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9E,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAEpD,IAAI,EAAE,CAAC;AACT,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Archive operations API endpoints
3
+ */
4
+ import { Router } from 'express';
5
+ export declare function createArchiveRouter(): Router;
6
+ //# sourceMappingURL=archive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../../src/api/routes/archive.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAA+B,MAAM,SAAS,CAAC;AAgK9D,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Archive operations API endpoints
3
+ */
4
+ import { Router } from 'express';
5
+ import { loadConfig } from '../../utils/config.js';
6
+ import { getProvider } from '../../providers/index.js';
7
+ import { Archiver } from '../../core/archiver.js';
8
+ import { Storage, getDefaultStorageConfig } from '../../core/storage.js';
9
+ import { MediaManager } from '../../core/media.js';
10
+ import { createError, isApiError } from '../middleware/error-handler.js';
11
+ const router = Router();
12
+ // Track running archive operations
13
+ const runningOperations = new Map();
14
+ /**
15
+ * GET /api/archive/status
16
+ * Get current archive status for all providers
17
+ */
18
+ router.get('/status', async (_req, res) => {
19
+ try {
20
+ const operations = Array.from(runningOperations.entries()).map(([id, op]) => ({
21
+ id,
22
+ ...op,
23
+ }));
24
+ res.json({ operations });
25
+ }
26
+ catch (error) {
27
+ throw createError('Failed to get archive status', 500, error);
28
+ }
29
+ });
30
+ /**
31
+ * POST /api/archive/start
32
+ * Start an archive operation
33
+ */
34
+ router.post('/start', async (req, res) => {
35
+ try {
36
+ const { provider: providerName, options = {} } = req.body;
37
+ if (!providerName) {
38
+ throw createError('Provider name is required', 400);
39
+ }
40
+ const config = await loadConfig();
41
+ const providerConfig = config.providers?.[providerName];
42
+ if (!providerConfig) {
43
+ throw createError(`Provider ${providerName} not configured`, 404);
44
+ }
45
+ const provider = getProvider(providerName);
46
+ if (!provider) {
47
+ throw createError(`Provider ${providerName} not found`, 404);
48
+ }
49
+ // Create operation ID
50
+ const operationId = `${providerName}-${Date.now()}`;
51
+ // Initialize operation tracking
52
+ runningOperations.set(operationId, {
53
+ provider: providerName,
54
+ startTime: new Date(),
55
+ status: 'running',
56
+ });
57
+ // Start archive in background
58
+ (async () => {
59
+ try {
60
+ await provider.authenticate(providerConfig);
61
+ const storageConfig = getDefaultStorageConfig();
62
+ if (config.settings?.archiveDir) {
63
+ storageConfig.baseDir = config.settings.archiveDir;
64
+ }
65
+ const storage = new Storage(storageConfig);
66
+ const mediaManager = new MediaManager(storageConfig.baseDir);
67
+ const archiver = new Archiver(storage, mediaManager);
68
+ await archiver.init();
69
+ const result = await archiver.archive(provider, {
70
+ ...options,
71
+ silent: true, // Suppress console output for API
72
+ });
73
+ const operation = runningOperations.get(operationId);
74
+ if (operation) {
75
+ operation.status = 'completed';
76
+ operation.result = result;
77
+ }
78
+ }
79
+ catch (error) {
80
+ const operation = runningOperations.get(operationId);
81
+ if (operation) {
82
+ operation.status = 'failed';
83
+ operation.error = error instanceof Error ? error.message : 'Unknown error';
84
+ }
85
+ }
86
+ })();
87
+ res.json({
88
+ success: true,
89
+ operationId,
90
+ message: 'Archive operation started',
91
+ });
92
+ }
93
+ catch (error) {
94
+ if (isApiError(error)) {
95
+ throw error;
96
+ }
97
+ throw createError('Failed to start archive', 500, error);
98
+ }
99
+ });
100
+ /**
101
+ * GET /api/archive/operation/:id
102
+ * Get status of a specific archive operation
103
+ */
104
+ router.get('/operation/:id', async (req, res) => {
105
+ try {
106
+ const { id } = req.params;
107
+ const operation = runningOperations.get(id);
108
+ if (!operation) {
109
+ throw createError('Operation not found', 404);
110
+ }
111
+ res.json({ id, ...operation });
112
+ }
113
+ catch (error) {
114
+ if (isApiError(error)) {
115
+ throw error;
116
+ }
117
+ throw createError('Failed to get operation status', 500, error);
118
+ }
119
+ });
120
+ /**
121
+ * GET /api/archive/history
122
+ * Get archive operation history
123
+ */
124
+ router.get('/history', async (_req, res) => {
125
+ try {
126
+ const history = Array.from(runningOperations.entries())
127
+ .filter(([_, op]) => op.status !== 'running')
128
+ .map(([id, op]) => ({ id, ...op }))
129
+ .sort((a, b) => b.startTime.getTime() - a.startTime.getTime())
130
+ .slice(0, 50); // Last 50 operations
131
+ res.json({ history });
132
+ }
133
+ catch (error) {
134
+ throw createError('Failed to get archive history', 500, error);
135
+ }
136
+ });
137
+ export function createArchiveRouter() {
138
+ return router;
139
+ }
140
+ //# sourceMappingURL=archive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive.js","sourceRoot":"","sources":["../../../src/api/routes/archive.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Conversation browsing and detail API endpoints
3
+ */
4
+ import { Router } from 'express';
5
+ export declare function createConversationsRouter(): Router;
6
+ //# sourceMappingURL=conversations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversations.d.ts","sourceRoot":"","sources":["../../../src/api/routes/conversations.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAA+B,MAAM,SAAS,CAAC;AAiO9D,wBAAgB,yBAAyB,IAAI,MAAM,CAElD"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Conversation browsing and detail API endpoints
3
+ */
4
+ import { Router } from 'express';
5
+ import { getDefaultStorageConfig } from '../../core/storage.js';
6
+ import { loadConfig } from '../../utils/config.js';
7
+ import { createError, isApiError } from '../middleware/error-handler.js';
8
+ import path from 'path';
9
+ import fs from 'fs/promises';
10
+ import { existsSync } from 'fs';
11
+ const router = Router();
12
+ /**
13
+ * GET /api/conversations
14
+ * List all archived conversations with pagination and filtering
15
+ */
16
+ router.get('/', async (req, res) => {
17
+ try {
18
+ const config = await loadConfig();
19
+ const storageConfig = getDefaultStorageConfig();
20
+ if (config.settings?.archiveDir) {
21
+ storageConfig.baseDir = config.settings.archiveDir;
22
+ }
23
+ const { provider, limit = 50, offset = 0, sortBy = 'updatedAt', sortOrder = 'desc', since, until, } = req.query;
24
+ // Get all conversations
25
+ const allConversations = [];
26
+ // Determine which providers to query
27
+ const providers = provider ? [provider] : Object.keys(config.providers || {});
28
+ for (const providerName of providers) {
29
+ const providerPath = path.join(storageConfig.baseDir, providerName);
30
+ if (!existsSync(providerPath)) {
31
+ continue;
32
+ }
33
+ // Load index
34
+ const indexPath = path.join(providerPath, 'index.json');
35
+ if (!existsSync(indexPath)) {
36
+ continue;
37
+ }
38
+ const indexData = await fs.readFile(indexPath, 'utf-8');
39
+ const index = JSON.parse(indexData);
40
+ // Add conversations from index
41
+ for (const [conversationId, entry] of Object.entries(index)) {
42
+ const conv = {
43
+ id: conversationId,
44
+ provider: providerName,
45
+ ...entry,
46
+ };
47
+ // Apply date filters
48
+ if (since && new Date(conv.updatedAt) < new Date(since)) {
49
+ continue;
50
+ }
51
+ if (until && new Date(conv.updatedAt) > new Date(until)) {
52
+ continue;
53
+ }
54
+ allConversations.push(conv);
55
+ }
56
+ }
57
+ // Sort conversations
58
+ allConversations.sort((a, b) => {
59
+ const aVal = a[sortBy];
60
+ const bVal = b[sortBy];
61
+ const order = sortOrder === 'asc' ? 1 : -1;
62
+ if (typeof aVal === 'string' && typeof bVal === 'string') {
63
+ return aVal.localeCompare(bVal) * order;
64
+ }
65
+ return ((aVal > bVal ? 1 : -1) * order);
66
+ });
67
+ // Apply pagination
68
+ const total = allConversations.length;
69
+ const limitNum = parseInt(limit);
70
+ const offsetNum = parseInt(offset);
71
+ const conversations = allConversations.slice(offsetNum, offsetNum + limitNum);
72
+ res.json({
73
+ conversations,
74
+ pagination: {
75
+ total,
76
+ limit: limitNum,
77
+ offset: offsetNum,
78
+ hasMore: offsetNum + limitNum < total,
79
+ },
80
+ });
81
+ }
82
+ catch (error) {
83
+ throw createError('Failed to list conversations', 500, error);
84
+ }
85
+ });
86
+ /**
87
+ * GET /api/conversations/:provider/:id
88
+ * Get detailed conversation by ID
89
+ */
90
+ router.get('/:provider/:id', async (req, res) => {
91
+ try {
92
+ const { provider, id } = req.params;
93
+ const config = await loadConfig();
94
+ const storageConfig = getDefaultStorageConfig();
95
+ if (config.settings?.archiveDir) {
96
+ storageConfig.baseDir = config.settings.archiveDir;
97
+ }
98
+ // Find conversation file
99
+ const providerPath = path.join(storageConfig.baseDir, provider);
100
+ if (!existsSync(providerPath)) {
101
+ throw createError(`Provider ${provider} not found`, 404);
102
+ }
103
+ // Load index to find conversation location
104
+ const indexPath = path.join(providerPath, 'index.json');
105
+ if (!existsSync(indexPath)) {
106
+ throw createError('No conversations found', 404);
107
+ }
108
+ const indexData = await fs.readFile(indexPath, 'utf-8');
109
+ const index = JSON.parse(indexData);
110
+ const entry = index[id];
111
+ if (!entry) {
112
+ throw createError(`Conversation ${id} not found`, 404);
113
+ }
114
+ // Load conversation data
115
+ const conversationPath = path.join(providerPath, entry.filePath);
116
+ if (!existsSync(conversationPath)) {
117
+ throw createError(`Conversation file not found`, 404);
118
+ }
119
+ const conversationData = await fs.readFile(conversationPath, 'utf-8');
120
+ const conversation = JSON.parse(conversationData);
121
+ // Load markdown if available
122
+ const markdownPath = conversationPath.replace('.json', '.md');
123
+ let markdown;
124
+ if (existsSync(markdownPath)) {
125
+ markdown = await fs.readFile(markdownPath, 'utf-8');
126
+ }
127
+ res.json({
128
+ conversation,
129
+ markdown,
130
+ metadata: entry,
131
+ });
132
+ }
133
+ catch (error) {
134
+ if (isApiError(error)) {
135
+ throw error;
136
+ }
137
+ throw createError('Failed to get conversation', 500, error);
138
+ }
139
+ });
140
+ /**
141
+ * GET /api/conversations/stats
142
+ * Get conversation statistics
143
+ */
144
+ router.get('/stats', async (_req, res) => {
145
+ try {
146
+ const config = await loadConfig();
147
+ const storageConfig = getDefaultStorageConfig();
148
+ if (config.settings?.archiveDir) {
149
+ storageConfig.baseDir = config.settings.archiveDir;
150
+ }
151
+ const stats = {
152
+ totalConversations: 0,
153
+ byProvider: {},
154
+ totalMessages: 0,
155
+ totalMedia: 0,
156
+ storageUsed: 0,
157
+ };
158
+ const providers = Object.keys(config.providers || {});
159
+ for (const provider of providers) {
160
+ const providerPath = path.join(storageConfig.baseDir, provider);
161
+ if (!existsSync(providerPath)) {
162
+ continue;
163
+ }
164
+ const indexPath = path.join(providerPath, 'index.json');
165
+ if (!existsSync(indexPath)) {
166
+ continue;
167
+ }
168
+ const indexData = await fs.readFile(indexPath, 'utf-8');
169
+ const index = JSON.parse(indexData);
170
+ const providerConvCount = Object.keys(index).length;
171
+ stats.totalConversations += providerConvCount;
172
+ stats.byProvider[provider] = {
173
+ conversations: providerConvCount,
174
+ messages: 0,
175
+ };
176
+ // Count messages
177
+ for (const entry of Object.values(index)) {
178
+ if (entry.messageCount) {
179
+ stats.totalMessages += entry.messageCount;
180
+ stats.byProvider[provider].messages += entry.messageCount;
181
+ }
182
+ }
183
+ }
184
+ res.json(stats);
185
+ }
186
+ catch (error) {
187
+ throw createError('Failed to get conversation stats', 500, error);
188
+ }
189
+ });
190
+ export function createConversationsRouter() {
191
+ return router;
192
+ }
193
+ //# sourceMappingURL=conversations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversations.js","sourceRoot":"","sources":["../../../src/api/routes/conversations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Media file browsing API endpoints
3
+ */
4
+ import { Router } from 'express';
5
+ export declare function createMediaRouter(): Router;
6
+ //# sourceMappingURL=media.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../../src/api/routes/media.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAA+B,MAAM,SAAS,CAAC;AAkL9D,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C"}