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,81 @@
1
+ /**
2
+ * API Key Service for ArchiCore Developer API
3
+ *
4
+ * Управление API ключами для разработчиков
5
+ */
6
+ import { ApiKey, ApiPermission, RateLimitConfig, ApiKeyCreateRequest, ApiKeyCreateResponse, ApiKeyListResponse } from '../../types/api.js';
7
+ export declare class ApiKeyService {
8
+ private dataDir;
9
+ private keys;
10
+ private initialized;
11
+ constructor(dataDir?: string);
12
+ private ensureInitialized;
13
+ private saveKeys;
14
+ /**
15
+ * Генерация нового API ключа
16
+ * Формат: arc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (32 hex chars)
17
+ */
18
+ private generateApiKey;
19
+ /**
20
+ * Хэширование API ключа для хранения
21
+ */
22
+ private hashApiKey;
23
+ /**
24
+ * Получение префикса ключа для отображения
25
+ */
26
+ private getKeyPrefix;
27
+ /**
28
+ * Создание нового API ключа
29
+ */
30
+ createKey(userId: string, request: ApiKeyCreateRequest): Promise<ApiKeyCreateResponse>;
31
+ /**
32
+ * Валидация API ключа
33
+ */
34
+ validateKey(rawKey: string): Promise<ApiKey | null>;
35
+ /**
36
+ * Получение списка ключей пользователя
37
+ */
38
+ listKeys(userId: string): Promise<ApiKeyListResponse>;
39
+ /**
40
+ * Получение ключа по ID
41
+ */
42
+ getKey(keyId: string, userId: string): Promise<ApiKey | null>;
43
+ /**
44
+ * Деактивация API ключа
45
+ */
46
+ revokeKey(keyId: string, userId: string): Promise<boolean>;
47
+ /**
48
+ * Удаление API ключа
49
+ */
50
+ deleteKey(keyId: string, userId: string): Promise<boolean>;
51
+ /**
52
+ * Обновление permissions ключа
53
+ */
54
+ updatePermissions(keyId: string, userId: string, permissions: ApiPermission[]): Promise<boolean>;
55
+ /**
56
+ * Обновление rate limits ключа
57
+ */
58
+ updateRateLimits(keyId: string, userId: string, rateLimit: Partial<RateLimitConfig>): Promise<boolean>;
59
+ /**
60
+ * Переименование ключа
61
+ */
62
+ renameKey(keyId: string, userId: string, name: string): Promise<boolean>;
63
+ /**
64
+ * Проверка permission для ключа
65
+ */
66
+ hasPermission(apiKey: ApiKey, permission: ApiPermission): boolean;
67
+ /**
68
+ * Получение статистики использования ключей
69
+ */
70
+ getKeyStats(userId: string): Promise<{
71
+ totalKeys: number;
72
+ activeKeys: number;
73
+ expiredKeys: number;
74
+ revokedKeys: number;
75
+ }>;
76
+ /**
77
+ * Очистка истёкших ключей
78
+ */
79
+ cleanupExpiredKeys(): Promise<number>;
80
+ }
81
+ //# sourceMappingURL=api-key-service.d.ts.map
@@ -0,0 +1,281 @@
1
+ /**
2
+ * API Key Service for ArchiCore Developer API
3
+ *
4
+ * Управление API ключами для разработчиков
5
+ */
6
+ import { randomBytes, createHash } from 'crypto';
7
+ import { readFile, writeFile, mkdir } from 'fs/promises';
8
+ import { join } from 'path';
9
+ import { DEFAULT_RATE_LIMITS } from '../../types/api.js';
10
+ import { Logger } from '../../utils/logger.js';
11
+ const DATA_DIR = '.archicore';
12
+ const API_KEYS_FILE = 'api-keys.json';
13
+ export class ApiKeyService {
14
+ dataDir;
15
+ keys = [];
16
+ initialized = false;
17
+ constructor(dataDir = DATA_DIR) {
18
+ this.dataDir = dataDir;
19
+ }
20
+ async ensureInitialized() {
21
+ if (this.initialized)
22
+ return;
23
+ try {
24
+ await mkdir(this.dataDir, { recursive: true });
25
+ }
26
+ catch { }
27
+ try {
28
+ const keysPath = join(this.dataDir, API_KEYS_FILE);
29
+ const data = await readFile(keysPath, 'utf-8');
30
+ const parsed = JSON.parse(data);
31
+ this.keys = parsed.keys || [];
32
+ }
33
+ catch {
34
+ this.keys = [];
35
+ }
36
+ this.initialized = true;
37
+ }
38
+ async saveKeys() {
39
+ const keysPath = join(this.dataDir, API_KEYS_FILE);
40
+ await writeFile(keysPath, JSON.stringify({ keys: this.keys }, null, 2));
41
+ }
42
+ /**
43
+ * Генерация нового API ключа
44
+ * Формат: arc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (32 hex chars)
45
+ */
46
+ generateApiKey() {
47
+ const bytes = randomBytes(24);
48
+ return 'arc_' + bytes.toString('hex');
49
+ }
50
+ /**
51
+ * Хэширование API ключа для хранения
52
+ */
53
+ hashApiKey(key) {
54
+ return createHash('sha256').update(key).digest('hex');
55
+ }
56
+ /**
57
+ * Получение префикса ключа для отображения
58
+ */
59
+ getKeyPrefix(key) {
60
+ return key.substring(0, 12) + '...';
61
+ }
62
+ /**
63
+ * Создание нового API ключа
64
+ */
65
+ async createKey(userId, request) {
66
+ await this.ensureInitialized();
67
+ // Проверка лимита ключей (максимум 10 на пользователя)
68
+ const userKeys = this.keys.filter(k => k.userId === userId && k.isActive);
69
+ if (userKeys.length >= 10) {
70
+ return { success: false, error: 'Maximum API keys limit reached (10)' };
71
+ }
72
+ // Генерация ключа
73
+ const rawKey = this.generateApiKey();
74
+ const keyHash = this.hashApiKey(rawKey);
75
+ const keyPrefix = this.getKeyPrefix(rawKey);
76
+ // Дефолтные permissions если не указаны
77
+ const permissions = request.permissions || [
78
+ 'read:projects',
79
+ 'analyze:impact',
80
+ 'search:semantic',
81
+ 'ask:architect'
82
+ ];
83
+ // Rate limits по умолчанию (starter tier)
84
+ const rateLimit = {
85
+ ...DEFAULT_RATE_LIMITS.starter,
86
+ ...request.rateLimit
87
+ };
88
+ // Дата истечения
89
+ let expiresAt = null;
90
+ if (request.expiresIn) {
91
+ expiresAt = new Date(Date.now() + request.expiresIn * 24 * 60 * 60 * 1000);
92
+ }
93
+ const apiKey = {
94
+ id: 'key_' + randomBytes(12).toString('hex'),
95
+ userId,
96
+ name: request.name,
97
+ keyHash,
98
+ keyPrefix,
99
+ permissions,
100
+ rateLimit,
101
+ createdAt: new Date(),
102
+ lastUsedAt: null,
103
+ expiresAt,
104
+ isActive: true
105
+ };
106
+ this.keys.push(apiKey);
107
+ await this.saveKeys();
108
+ Logger.info(`API key created for user ${userId}: ${keyPrefix}`);
109
+ return {
110
+ success: true,
111
+ apiKey: {
112
+ id: apiKey.id,
113
+ name: apiKey.name,
114
+ key: rawKey, // Показываем полный ключ только при создании!
115
+ keyPrefix: apiKey.keyPrefix,
116
+ permissions: apiKey.permissions,
117
+ expiresAt: apiKey.expiresAt
118
+ }
119
+ };
120
+ }
121
+ /**
122
+ * Валидация API ключа
123
+ */
124
+ async validateKey(rawKey) {
125
+ await this.ensureInitialized();
126
+ if (!rawKey || !rawKey.startsWith('arc_')) {
127
+ return null;
128
+ }
129
+ const keyHash = this.hashApiKey(rawKey);
130
+ const apiKey = this.keys.find(k => k.keyHash === keyHash);
131
+ if (!apiKey) {
132
+ return null;
133
+ }
134
+ // Проверка активности
135
+ if (!apiKey.isActive) {
136
+ return null;
137
+ }
138
+ // Проверка срока действия
139
+ if (apiKey.expiresAt && new Date(apiKey.expiresAt) < new Date()) {
140
+ return null;
141
+ }
142
+ // Обновляем lastUsedAt
143
+ apiKey.lastUsedAt = new Date();
144
+ await this.saveKeys();
145
+ return apiKey;
146
+ }
147
+ /**
148
+ * Получение списка ключей пользователя
149
+ */
150
+ async listKeys(userId) {
151
+ await this.ensureInitialized();
152
+ const userKeys = this.keys
153
+ .filter(k => k.userId === userId)
154
+ .map(k => ({
155
+ id: k.id,
156
+ name: k.name,
157
+ keyPrefix: k.keyPrefix,
158
+ permissions: k.permissions,
159
+ createdAt: k.createdAt,
160
+ lastUsedAt: k.lastUsedAt,
161
+ expiresAt: k.expiresAt,
162
+ isActive: k.isActive
163
+ }));
164
+ return { success: true, keys: userKeys };
165
+ }
166
+ /**
167
+ * Получение ключа по ID
168
+ */
169
+ async getKey(keyId, userId) {
170
+ await this.ensureInitialized();
171
+ return this.keys.find(k => k.id === keyId && k.userId === userId) || null;
172
+ }
173
+ /**
174
+ * Деактивация API ключа
175
+ */
176
+ async revokeKey(keyId, userId) {
177
+ await this.ensureInitialized();
178
+ const key = this.keys.find(k => k.id === keyId && k.userId === userId);
179
+ if (!key) {
180
+ return false;
181
+ }
182
+ key.isActive = false;
183
+ await this.saveKeys();
184
+ Logger.info(`API key revoked: ${key.keyPrefix}`);
185
+ return true;
186
+ }
187
+ /**
188
+ * Удаление API ключа
189
+ */
190
+ async deleteKey(keyId, userId) {
191
+ await this.ensureInitialized();
192
+ const index = this.keys.findIndex(k => k.id === keyId && k.userId === userId);
193
+ if (index === -1) {
194
+ return false;
195
+ }
196
+ const key = this.keys[index];
197
+ this.keys.splice(index, 1);
198
+ await this.saveKeys();
199
+ Logger.info(`API key deleted: ${key.keyPrefix}`);
200
+ return true;
201
+ }
202
+ /**
203
+ * Обновление permissions ключа
204
+ */
205
+ async updatePermissions(keyId, userId, permissions) {
206
+ await this.ensureInitialized();
207
+ const key = this.keys.find(k => k.id === keyId && k.userId === userId);
208
+ if (!key) {
209
+ return false;
210
+ }
211
+ key.permissions = permissions;
212
+ await this.saveKeys();
213
+ return true;
214
+ }
215
+ /**
216
+ * Обновление rate limits ключа
217
+ */
218
+ async updateRateLimits(keyId, userId, rateLimit) {
219
+ await this.ensureInitialized();
220
+ const key = this.keys.find(k => k.id === keyId && k.userId === userId);
221
+ if (!key) {
222
+ return false;
223
+ }
224
+ key.rateLimit = { ...key.rateLimit, ...rateLimit };
225
+ await this.saveKeys();
226
+ return true;
227
+ }
228
+ /**
229
+ * Переименование ключа
230
+ */
231
+ async renameKey(keyId, userId, name) {
232
+ await this.ensureInitialized();
233
+ const key = this.keys.find(k => k.id === keyId && k.userId === userId);
234
+ if (!key) {
235
+ return false;
236
+ }
237
+ key.name = name;
238
+ await this.saveKeys();
239
+ return true;
240
+ }
241
+ /**
242
+ * Проверка permission для ключа
243
+ */
244
+ hasPermission(apiKey, permission) {
245
+ // Admin имеет все права
246
+ if (apiKey.permissions.includes('admin:all')) {
247
+ return true;
248
+ }
249
+ return apiKey.permissions.includes(permission);
250
+ }
251
+ /**
252
+ * Получение статистики использования ключей
253
+ */
254
+ async getKeyStats(userId) {
255
+ await this.ensureInitialized();
256
+ const userKeys = this.keys.filter(k => k.userId === userId);
257
+ const now = new Date();
258
+ return {
259
+ totalKeys: userKeys.length,
260
+ activeKeys: userKeys.filter(k => k.isActive && (!k.expiresAt || new Date(k.expiresAt) > now)).length,
261
+ expiredKeys: userKeys.filter(k => k.expiresAt && new Date(k.expiresAt) <= now).length,
262
+ revokedKeys: userKeys.filter(k => !k.isActive).length
263
+ };
264
+ }
265
+ /**
266
+ * Очистка истёкших ключей
267
+ */
268
+ async cleanupExpiredKeys() {
269
+ await this.ensureInitialized();
270
+ const now = new Date();
271
+ const initialLength = this.keys.length;
272
+ this.keys = this.keys.filter(k => !k.expiresAt || new Date(k.expiresAt) > now);
273
+ const removedCount = initialLength - this.keys.length;
274
+ if (removedCount > 0) {
275
+ await this.saveKeys();
276
+ Logger.info(`Cleaned up ${removedCount} expired API keys`);
277
+ }
278
+ return removedCount;
279
+ }
280
+ }
281
+ //# sourceMappingURL=api-key-service.js.map
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Authentication Service for ArchiCore
3
+ */
4
+ import { User, SubscriptionTier, AuthResponse } from '../../types/user.js';
5
+ export declare class AuthService {
6
+ private dataDir;
7
+ private users;
8
+ private sessions;
9
+ private initialized;
10
+ constructor(dataDir?: string);
11
+ private ensureInitialized;
12
+ private createDefaultAdmin;
13
+ private saveUsers;
14
+ private saveSessions;
15
+ private hashPassword;
16
+ private createEmptyUsage;
17
+ private generateToken;
18
+ private sanitizeUser;
19
+ register(email: string, username: string, password: string): Promise<AuthResponse>;
20
+ login(email: string, password: string): Promise<AuthResponse>;
21
+ oauthLogin(provider: 'github' | 'google', profile: {
22
+ id: string;
23
+ email: string;
24
+ name: string;
25
+ avatar?: string;
26
+ }): Promise<AuthResponse>;
27
+ validateToken(token: string): Promise<User | null>;
28
+ logout(token: string): Promise<void>;
29
+ getUser(userId: string): Promise<User | null>;
30
+ updateUserTier(userId: string, tier: SubscriptionTier): Promise<boolean>;
31
+ checkAndUpdateUsage(userId: string, type: 'request' | 'analysis' | 'project'): Promise<{
32
+ allowed: boolean;
33
+ remaining: number;
34
+ limit: number;
35
+ }>;
36
+ getAllUsers(): Promise<Omit<User, 'passwordHash'>[]>;
37
+ deleteUser(userId: string): Promise<boolean>;
38
+ updateUser(userId: string, updates: Partial<Pick<User, 'username' | 'email' | 'avatar'>>): Promise<boolean>;
39
+ }
40
+ //# sourceMappingURL=auth-service.d.ts.map