archicore 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/README.md +530 -0
  2. package/dist/analyzers/dead-code.d.ts +95 -0
  3. package/dist/analyzers/dead-code.js +327 -0
  4. package/dist/analyzers/duplication.d.ts +90 -0
  5. package/dist/analyzers/duplication.js +344 -0
  6. package/dist/analyzers/security.d.ts +79 -0
  7. package/dist/analyzers/security.js +484 -0
  8. package/dist/architecture/index.d.ts +35 -0
  9. package/dist/architecture/index.js +249 -0
  10. package/dist/cli/commands/analyzers.d.ts +6 -0
  11. package/dist/cli/commands/analyzers.js +431 -0
  12. package/dist/cli/commands/export.d.ts +6 -0
  13. package/dist/cli/commands/export.js +78 -0
  14. package/dist/cli/commands/index.d.ts +8 -0
  15. package/dist/cli/commands/index.js +8 -0
  16. package/dist/cli/commands/init.d.ts +26 -0
  17. package/dist/cli/commands/init.js +140 -0
  18. package/dist/cli/commands/interactive.d.ts +7 -0
  19. package/dist/cli/commands/interactive.js +522 -0
  20. package/dist/cli/commands/projects.d.ts +6 -0
  21. package/dist/cli/commands/projects.js +249 -0
  22. package/dist/cli/index.d.ts +7 -0
  23. package/dist/cli/index.js +7 -0
  24. package/dist/cli/ui/box.d.ts +17 -0
  25. package/dist/cli/ui/box.js +62 -0
  26. package/dist/cli/ui/colors.d.ts +49 -0
  27. package/dist/cli/ui/colors.js +86 -0
  28. package/dist/cli/ui/index.d.ts +9 -0
  29. package/dist/cli/ui/index.js +9 -0
  30. package/dist/cli/ui/prompt.d.ts +34 -0
  31. package/dist/cli/ui/prompt.js +122 -0
  32. package/dist/cli/ui/spinner.d.ts +29 -0
  33. package/dist/cli/ui/spinner.js +80 -0
  34. package/dist/cli/ui/table.d.ts +33 -0
  35. package/dist/cli/ui/table.js +84 -0
  36. package/dist/cli/utils/config.d.ts +23 -0
  37. package/dist/cli/utils/config.js +73 -0
  38. package/dist/cli/utils/index.d.ts +6 -0
  39. package/dist/cli/utils/index.js +6 -0
  40. package/dist/cli/utils/session.d.ts +27 -0
  41. package/dist/cli/utils/session.js +117 -0
  42. package/dist/cli.d.ts +8 -0
  43. package/dist/cli.js +295 -0
  44. package/dist/code-index/ast-parser.d.ts +16 -0
  45. package/dist/code-index/ast-parser.js +330 -0
  46. package/dist/code-index/dependency-graph.d.ts +16 -0
  47. package/dist/code-index/dependency-graph.js +161 -0
  48. package/dist/code-index/index.d.ts +44 -0
  49. package/dist/code-index/index.js +124 -0
  50. package/dist/code-index/symbol-extractor.d.ts +13 -0
  51. package/dist/code-index/symbol-extractor.js +150 -0
  52. package/dist/export/index.d.ts +92 -0
  53. package/dist/export/index.js +676 -0
  54. package/dist/github/github-service.d.ts +146 -0
  55. package/dist/github/github-service.js +609 -0
  56. package/dist/impact-engine/index.d.ts +25 -0
  57. package/dist/impact-engine/index.js +284 -0
  58. package/dist/index.d.ts +60 -0
  59. package/dist/index.js +149 -0
  60. package/dist/metrics/index.d.ts +136 -0
  61. package/dist/metrics/index.js +525 -0
  62. package/dist/orchestrator/deepseek-optimizer.d.ts +67 -0
  63. package/dist/orchestrator/deepseek-optimizer.js +320 -0
  64. package/dist/orchestrator/index.d.ts +34 -0
  65. package/dist/orchestrator/index.js +305 -0
  66. package/dist/pr-guardian/index.d.ts +143 -0
  67. package/dist/pr-guardian/index.js +553 -0
  68. package/dist/refactoring/index.d.ts +108 -0
  69. package/dist/refactoring/index.js +580 -0
  70. package/dist/rules-engine/index.d.ts +129 -0
  71. package/dist/rules-engine/index.js +482 -0
  72. package/dist/semantic-memory/embedding-service.d.ts +24 -0
  73. package/dist/semantic-memory/embedding-service.js +120 -0
  74. package/dist/semantic-memory/index.d.ts +45 -0
  75. package/dist/semantic-memory/index.js +206 -0
  76. package/dist/semantic-memory/vector-store.d.ts +27 -0
  77. package/dist/semantic-memory/vector-store.js +166 -0
  78. package/dist/server/index.d.ts +28 -0
  79. package/dist/server/index.js +141 -0
  80. package/dist/server/middleware/api-auth.d.ts +43 -0
  81. package/dist/server/middleware/api-auth.js +256 -0
  82. package/dist/server/routes/admin.d.ts +5 -0
  83. package/dist/server/routes/admin.js +123 -0
  84. package/dist/server/routes/api.d.ts +7 -0
  85. package/dist/server/routes/api.js +362 -0
  86. package/dist/server/routes/auth.d.ts +16 -0
  87. package/dist/server/routes/auth.js +191 -0
  88. package/dist/server/routes/developer.d.ts +8 -0
  89. package/dist/server/routes/developer.js +439 -0
  90. package/dist/server/routes/github.d.ts +7 -0
  91. package/dist/server/routes/github.js +495 -0
  92. package/dist/server/routes/upload.d.ts +7 -0
  93. package/dist/server/routes/upload.js +196 -0
  94. package/dist/server/services/api-key-service.d.ts +81 -0
  95. package/dist/server/services/api-key-service.js +281 -0
  96. package/dist/server/services/auth-service.d.ts +40 -0
  97. package/dist/server/services/auth-service.js +315 -0
  98. package/dist/server/services/project-service.d.ts +123 -0
  99. package/dist/server/services/project-service.js +533 -0
  100. package/dist/server/services/token-service.d.ts +107 -0
  101. package/dist/server/services/token-service.js +416 -0
  102. package/dist/server/services/upload-service.d.ts +93 -0
  103. package/dist/server/services/upload-service.js +464 -0
  104. package/dist/types/api.d.ts +188 -0
  105. package/dist/types/api.js +86 -0
  106. package/dist/types/github.d.ts +335 -0
  107. package/dist/types/github.js +5 -0
  108. package/dist/types/index.d.ts +265 -0
  109. package/dist/types/index.js +32 -0
  110. package/dist/types/user.d.ts +69 -0
  111. package/dist/types/user.js +42 -0
  112. package/dist/utils/file-utils.d.ts +20 -0
  113. package/dist/utils/file-utils.js +163 -0
  114. package/dist/utils/logger.d.ts +17 -0
  115. package/dist/utils/logger.js +41 -0
  116. package/dist/watcher/index.d.ts +125 -0
  117. package/dist/watcher/index.js +397 -0
  118. package/package.json +71 -0
@@ -0,0 +1,439 @@
1
+ /**
2
+ * Developer API Routes for ArchiCore
3
+ *
4
+ * REST API для разработчиков с токенизированной тарификацией
5
+ * Формат ответов совместим с OpenAI/Anthropic API
6
+ */
7
+ import { Router } from 'express';
8
+ import { ApiKeyService } from '../services/api-key-service.js';
9
+ import { TokenService } from '../services/token-service.js';
10
+ import { ProjectService } from '../services/project-service.js';
11
+ import { authMiddleware } from './auth.js';
12
+ import { apiKeyAuth, requirePermission, trackUsage, apiErrorHandler } from '../middleware/api-auth.js';
13
+ import { Logger } from '../../utils/logger.js';
14
+ export const developerRouter = Router();
15
+ // Services
16
+ const apiKeyService = new ApiKeyService();
17
+ const tokenService = new TokenService();
18
+ const projectService = new ProjectService();
19
+ // ========================================
20
+ // API KEY MANAGEMENT (requires user auth)
21
+ // ========================================
22
+ /**
23
+ * POST /api/developer/keys
24
+ * Создание нового API ключа
25
+ */
26
+ developerRouter.post('/keys', authMiddleware, async (req, res) => {
27
+ try {
28
+ if (!req.user) {
29
+ res.status(401).json({ error: { message: 'Not authenticated' } });
30
+ return;
31
+ }
32
+ const request = {
33
+ name: req.body.name || 'Default Key',
34
+ permissions: req.body.permissions,
35
+ expiresIn: req.body.expiresIn,
36
+ rateLimit: req.body.rateLimit
37
+ };
38
+ const result = await apiKeyService.createKey(req.user.id, request);
39
+ if (!result.success) {
40
+ res.status(400).json({ error: { message: result.error } });
41
+ return;
42
+ }
43
+ res.status(201).json({
44
+ success: true,
45
+ data: result.apiKey,
46
+ message: 'API key created successfully. Save the key now - it will not be shown again!'
47
+ });
48
+ }
49
+ catch (error) {
50
+ Logger.error('Create API key error:', error);
51
+ res.status(500).json({ error: { message: 'Failed to create API key' } });
52
+ }
53
+ });
54
+ /**
55
+ * GET /api/developer/keys
56
+ * Получение списка API ключей
57
+ */
58
+ developerRouter.get('/keys', authMiddleware, async (req, res) => {
59
+ try {
60
+ if (!req.user) {
61
+ res.status(401).json({ error: { message: 'Not authenticated' } });
62
+ return;
63
+ }
64
+ const result = await apiKeyService.listKeys(req.user.id);
65
+ res.json({ success: true, data: result.keys });
66
+ }
67
+ catch (error) {
68
+ Logger.error('List API keys error:', error);
69
+ res.status(500).json({ error: { message: 'Failed to list API keys' } });
70
+ }
71
+ });
72
+ /**
73
+ * DELETE /api/developer/keys/:keyId
74
+ * Удаление API ключа
75
+ */
76
+ developerRouter.delete('/keys/:keyId', authMiddleware, async (req, res) => {
77
+ try {
78
+ if (!req.user) {
79
+ res.status(401).json({ error: { message: 'Not authenticated' } });
80
+ return;
81
+ }
82
+ const deleted = await apiKeyService.deleteKey(req.params.keyId, req.user.id);
83
+ if (!deleted) {
84
+ res.status(404).json({ error: { message: 'API key not found' } });
85
+ return;
86
+ }
87
+ res.json({ success: true, message: 'API key deleted' });
88
+ }
89
+ catch (error) {
90
+ Logger.error('Delete API key error:', error);
91
+ res.status(500).json({ error: { message: 'Failed to delete API key' } });
92
+ }
93
+ });
94
+ /**
95
+ * POST /api/developer/keys/:keyId/revoke
96
+ * Отзыв API ключа (деактивация без удаления)
97
+ */
98
+ developerRouter.post('/keys/:keyId/revoke', authMiddleware, async (req, res) => {
99
+ try {
100
+ if (!req.user) {
101
+ res.status(401).json({ error: { message: 'Not authenticated' } });
102
+ return;
103
+ }
104
+ const revoked = await apiKeyService.revokeKey(req.params.keyId, req.user.id);
105
+ if (!revoked) {
106
+ res.status(404).json({ error: { message: 'API key not found' } });
107
+ return;
108
+ }
109
+ res.json({ success: true, message: 'API key revoked' });
110
+ }
111
+ catch (error) {
112
+ Logger.error('Revoke API key error:', error);
113
+ res.status(500).json({ error: { message: 'Failed to revoke API key' } });
114
+ }
115
+ });
116
+ // ========================================
117
+ // USAGE & BILLING (requires user auth)
118
+ // ========================================
119
+ /**
120
+ * GET /api/developer/usage
121
+ * Получение статистики использования
122
+ */
123
+ developerRouter.get('/usage', authMiddleware, async (req, res) => {
124
+ try {
125
+ if (!req.user) {
126
+ res.status(401).json({ error: { message: 'Not authenticated' } });
127
+ return;
128
+ }
129
+ const period = req.query.period || 'month';
130
+ const stats = await tokenService.getUsageStats(req.user.id, period);
131
+ const billing = await tokenService.getBillingAccount(req.user.id);
132
+ res.json({
133
+ success: true,
134
+ data: {
135
+ stats,
136
+ billing: {
137
+ tier: billing.pricingTier,
138
+ balance: billing.balance / 100, // в долларах
139
+ tokensUsed: billing.tokensUsedThisMonth,
140
+ tokensIncluded: billing.tokensIncludedThisMonth,
141
+ tokensRemaining: Math.max(0, billing.tokensIncludedThisMonth - billing.tokensUsedThisMonth),
142
+ billingCycleEnd: billing.billingCycleEnd
143
+ }
144
+ }
145
+ });
146
+ }
147
+ catch (error) {
148
+ Logger.error('Get usage error:', error);
149
+ res.status(500).json({ error: { message: 'Failed to get usage stats' } });
150
+ }
151
+ });
152
+ /**
153
+ * GET /api/developer/usage/history
154
+ * История использования
155
+ */
156
+ developerRouter.get('/usage/history', authMiddleware, async (req, res) => {
157
+ try {
158
+ if (!req.user) {
159
+ res.status(401).json({ error: { message: 'Not authenticated' } });
160
+ return;
161
+ }
162
+ const history = await tokenService.getUsageHistory(req.user.id, {
163
+ limit: parseInt(req.query.limit) || 100,
164
+ offset: parseInt(req.query.offset) || 0,
165
+ apiKeyId: req.query.keyId,
166
+ operation: req.query.operation
167
+ });
168
+ res.json({ success: true, data: history });
169
+ }
170
+ catch (error) {
171
+ Logger.error('Get usage history error:', error);
172
+ res.status(500).json({ error: { message: 'Failed to get usage history' } });
173
+ }
174
+ });
175
+ /**
176
+ * POST /api/developer/billing/credits
177
+ * Пополнение баланса (интеграция с платёжной системой)
178
+ */
179
+ developerRouter.post('/billing/credits', authMiddleware, async (req, res) => {
180
+ try {
181
+ if (!req.user) {
182
+ res.status(401).json({ error: { message: 'Not authenticated' } });
183
+ return;
184
+ }
185
+ const { amount } = req.body; // в центах
186
+ if (!amount || amount < 500) { // минимум $5
187
+ res.status(400).json({ error: { message: 'Minimum amount is $5 (500 cents)' } });
188
+ return;
189
+ }
190
+ // TODO: Интеграция с Stripe/PayPal
191
+ // Сейчас просто добавляем кредиты
192
+ const billing = await tokenService.addCredits(req.user.id, amount);
193
+ res.json({
194
+ success: true,
195
+ data: {
196
+ newBalance: billing.balance / 100,
197
+ message: 'Credits added successfully'
198
+ }
199
+ });
200
+ }
201
+ catch (error) {
202
+ Logger.error('Add credits error:', error);
203
+ res.status(500).json({ error: { message: 'Failed to add credits' } });
204
+ }
205
+ });
206
+ // ========================================
207
+ // PUBLIC API (requires API key)
208
+ // ========================================
209
+ /**
210
+ * POST /api/v1/projects
211
+ * Создание проекта через API
212
+ */
213
+ developerRouter.post('/v1/projects', apiKeyAuth, requirePermission('write:projects'), trackUsage('index'), async (req, res) => {
214
+ try {
215
+ const { name, repositoryUrl, localPath } = req.body;
216
+ if (!name) {
217
+ res.status(400).json({ error: { message: 'Project name is required' } });
218
+ return;
219
+ }
220
+ // Для API создаём проект по URL или пути
221
+ const project = await projectService.createProject(name, localPath || repositoryUrl);
222
+ res.status(201).json({
223
+ success: true,
224
+ data: { project }
225
+ });
226
+ }
227
+ catch (error) {
228
+ Logger.error('Create project error:', error);
229
+ res.status(500).json({ error: { message: 'Failed to create project' } });
230
+ }
231
+ });
232
+ /**
233
+ * GET /api/v1/projects
234
+ * Список проектов
235
+ */
236
+ developerRouter.get('/v1/projects', apiKeyAuth, requirePermission('read:projects'), async (_req, res) => {
237
+ try {
238
+ const projects = await projectService.listProjects();
239
+ res.json({ success: true, data: { projects } });
240
+ }
241
+ catch (error) {
242
+ Logger.error('List projects error:', error);
243
+ res.status(500).json({ error: { message: 'Failed to list projects' } });
244
+ }
245
+ });
246
+ /**
247
+ * POST /api/v1/projects/:id/index
248
+ * Индексация проекта
249
+ */
250
+ developerRouter.post('/v1/projects/:id/index', apiKeyAuth, requirePermission('write:projects'), trackUsage('index'), async (req, res) => {
251
+ try {
252
+ const result = await projectService.indexProject(req.params.id);
253
+ res.json({ success: true, data: result });
254
+ }
255
+ catch (error) {
256
+ Logger.error('Index project error:', error);
257
+ res.status(500).json({ error: { message: 'Failed to index project' } });
258
+ }
259
+ });
260
+ /**
261
+ * POST /api/v1/analyze/impact
262
+ * Анализ влияния изменений
263
+ */
264
+ developerRouter.post('/v1/analyze/impact', apiKeyAuth, requirePermission('analyze:impact'), trackUsage('analyze'), async (req, res) => {
265
+ try {
266
+ const { projectId, description, files, symbols, type } = req.body;
267
+ if (!projectId || !description) {
268
+ res.status(400).json({
269
+ error: { message: 'projectId and description are required' }
270
+ });
271
+ return;
272
+ }
273
+ const impact = await projectService.analyzeImpact(projectId, {
274
+ description,
275
+ files: files || [],
276
+ symbols: symbols || [],
277
+ type: type || 'modify'
278
+ });
279
+ res.json({ success: true, data: impact });
280
+ }
281
+ catch (error) {
282
+ Logger.error('Analyze impact error:', error);
283
+ res.status(500).json({ error: { message: 'Failed to analyze impact' } });
284
+ }
285
+ });
286
+ /**
287
+ * POST /api/v1/analyze/security
288
+ * Анализ безопасности
289
+ */
290
+ developerRouter.post('/v1/analyze/security', apiKeyAuth, requirePermission('analyze:security'), trackUsage('analyze'), async (req, res) => {
291
+ try {
292
+ const { projectId } = req.body;
293
+ if (!projectId) {
294
+ res.status(400).json({ error: { message: 'projectId is required' } });
295
+ return;
296
+ }
297
+ const result = await projectService.analyzeSecurity(projectId);
298
+ res.json({ success: true, data: result });
299
+ }
300
+ catch (error) {
301
+ Logger.error('Analyze security error:', error);
302
+ res.status(500).json({ error: { message: 'Failed to analyze security' } });
303
+ }
304
+ });
305
+ /**
306
+ * POST /api/v1/analyze/full
307
+ * Полный анализ проекта
308
+ */
309
+ developerRouter.post('/v1/analyze/full', apiKeyAuth, requirePermission('analyze:full'), trackUsage('analyze'), async (req, res) => {
310
+ try {
311
+ const { projectId } = req.body;
312
+ if (!projectId) {
313
+ res.status(400).json({ error: { message: 'projectId is required' } });
314
+ return;
315
+ }
316
+ const result = await projectService.runFullAnalysis(projectId);
317
+ res.json({ success: true, data: result });
318
+ }
319
+ catch (error) {
320
+ Logger.error('Full analysis error:', error);
321
+ res.status(500).json({ error: { message: 'Failed to run full analysis' } });
322
+ }
323
+ });
324
+ /**
325
+ * POST /api/v1/search
326
+ * Семантический поиск
327
+ */
328
+ developerRouter.post('/v1/search', apiKeyAuth, requirePermission('search:semantic'), trackUsage('search'), async (req, res) => {
329
+ try {
330
+ const { projectId, query, limit } = req.body;
331
+ if (!projectId || !query) {
332
+ res.status(400).json({
333
+ error: { message: 'projectId and query are required' }
334
+ });
335
+ return;
336
+ }
337
+ const results = await projectService.semanticSearch(projectId, query, limit || 10);
338
+ res.json({ success: true, data: { results } });
339
+ }
340
+ catch (error) {
341
+ Logger.error('Semantic search error:', error);
342
+ res.status(500).json({ error: { message: 'Failed to search' } });
343
+ }
344
+ });
345
+ /**
346
+ * POST /api/v1/ask
347
+ * Вопрос архитектору
348
+ */
349
+ developerRouter.post('/v1/ask', apiKeyAuth, requirePermission('ask:architect'), trackUsage('ask'), async (req, res) => {
350
+ try {
351
+ const { projectId, question, language } = req.body;
352
+ if (!projectId || !question) {
353
+ res.status(400).json({
354
+ error: { message: 'projectId and question are required' }
355
+ });
356
+ return;
357
+ }
358
+ const answer = await projectService.askArchitect(projectId, question, language || 'en');
359
+ res.json({
360
+ success: true,
361
+ data: {
362
+ question,
363
+ answer,
364
+ model: 'archicore-v1'
365
+ }
366
+ });
367
+ }
368
+ catch (error) {
369
+ Logger.error('Ask architect error:', error);
370
+ res.status(500).json({ error: { message: 'Failed to process question' } });
371
+ }
372
+ });
373
+ /**
374
+ * GET /api/v1/projects/:id/architecture
375
+ * Получение архитектурной модели
376
+ */
377
+ developerRouter.get('/v1/projects/:id/architecture', apiKeyAuth, requirePermission('read:projects'), async (req, res) => {
378
+ try {
379
+ const architecture = await projectService.getArchitecture(req.params.id);
380
+ res.json({ success: true, data: architecture });
381
+ }
382
+ catch (error) {
383
+ Logger.error('Get architecture error:', error);
384
+ res.status(500).json({ error: { message: 'Failed to get architecture' } });
385
+ }
386
+ });
387
+ /**
388
+ * GET /api/v1/projects/:id/graph
389
+ * Получение графа зависимостей
390
+ */
391
+ developerRouter.get('/v1/projects/:id/graph', apiKeyAuth, requirePermission('read:projects'), async (req, res) => {
392
+ try {
393
+ const graph = await projectService.getDependencyGraph(req.params.id);
394
+ res.json({ success: true, data: graph });
395
+ }
396
+ catch (error) {
397
+ Logger.error('Get graph error:', error);
398
+ res.status(500).json({ error: { message: 'Failed to get dependency graph' } });
399
+ }
400
+ });
401
+ /**
402
+ * GET /api/v1/projects/:id/metrics
403
+ * Получение метрик
404
+ */
405
+ developerRouter.get('/v1/projects/:id/metrics', apiKeyAuth, requirePermission('read:projects'), async (req, res) => {
406
+ try {
407
+ const metrics = await projectService.getMetrics(req.params.id);
408
+ res.json({ success: true, data: metrics });
409
+ }
410
+ catch (error) {
411
+ Logger.error('Get metrics error:', error);
412
+ res.status(500).json({ error: { message: 'Failed to get metrics' } });
413
+ }
414
+ });
415
+ /**
416
+ * POST /api/v1/export
417
+ * Экспорт данных
418
+ */
419
+ developerRouter.post('/v1/export', apiKeyAuth, requirePermission('export:data'), trackUsage('export'), async (req, res) => {
420
+ try {
421
+ const { projectId, format } = req.body;
422
+ if (!projectId || !format) {
423
+ res.status(400).json({
424
+ error: { message: 'projectId and format are required' }
425
+ });
426
+ return;
427
+ }
428
+ const exportData = await projectService.getExportData(projectId);
429
+ // Здесь можно добавить разные форматы экспорта
430
+ res.json({ success: true, data: exportData });
431
+ }
432
+ catch (error) {
433
+ Logger.error('Export error:', error);
434
+ res.status(500).json({ error: { message: 'Failed to export data' } });
435
+ }
436
+ });
437
+ // Error handler
438
+ developerRouter.use(apiErrorHandler);
439
+ //# sourceMappingURL=developer.js.map
@@ -0,0 +1,7 @@
1
+ /**
2
+ * GitHub Integration Routes for ArchiCore
3
+ *
4
+ * OAuth flow, repository management, webhooks
5
+ */
6
+ export declare const githubRouter: import("express-serve-static-core").Router;
7
+ //# sourceMappingURL=github.d.ts.map