archicore 0.3.4 → 0.3.5

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.
@@ -32,7 +32,14 @@ export async function getCurrentUser() {
32
32
  return null;
33
33
  }
34
34
  const data = await response.json();
35
- return data.user;
35
+ if (!data.user)
36
+ return null;
37
+ return {
38
+ id: data.user.id,
39
+ email: data.user.email,
40
+ name: data.user.name || data.user.username,
41
+ tier: data.user.tier || 'free'
42
+ };
36
43
  }
37
44
  catch {
38
45
  return null;
@@ -244,7 +244,7 @@ export function createSimpleAutocomplete(rl, commands, prompt) {
244
244
  }
245
245
  return [[], line];
246
246
  };
247
- // Return the completer function
247
+ // Return the completer function (accessing internal Node.js readline property)
248
248
  rl._completer = completer;
249
249
  }
250
250
  //# sourceMappingURL=autocomplete.js.map
@@ -22,7 +22,7 @@ export async function fetchUserProjects() {
22
22
  if (!response.ok)
23
23
  return [];
24
24
  const data = await response.json();
25
- return (data.projects || data || []).map((p) => ({
25
+ return (data.projects || []).map((p) => ({
26
26
  id: p.id,
27
27
  name: p.name,
28
28
  path: p.path,
@@ -50,12 +50,14 @@ if (process.env.GITHUB_OAUTH_CLIENT_ID && process.env.GITHUB_OAUTH_CLIENT_SECRET
50
50
  try {
51
51
  Logger.info(`[OAuth] GitHub authentication for user: ${profile.username}`);
52
52
  // GitHub might not provide email in profile, check emails array
53
- const email = profile.emails?.[0]?.value || profile._json?.email || '';
53
+ // _json contains raw GitHub API response (not typed in passport-github2)
54
+ const rawProfile = profile;
55
+ const email = profile.emails?.[0]?.value || rawProfile._json?.email || '';
54
56
  const oauthProfile = {
55
57
  id: profile.id,
56
58
  email,
57
59
  displayName: profile.displayName || profile.username || '',
58
- avatar: profile.photos?.[0]?.value || profile._json?.avatar_url,
60
+ avatar: profile.photos?.[0]?.value || rawProfile._json?.avatar_url,
59
61
  provider: 'github',
60
62
  };
61
63
  // Validate email
@@ -172,7 +172,7 @@ export class ArchiCoreServer {
172
172
  scriptSrcAttr: ["'unsafe-inline'", "'unsafe-hashes'"],
173
173
  imgSrc: ["'self'", "data:", "https:"],
174
174
  fontSrc: ["'self'", "https://fonts.gstatic.com"],
175
- connectSrc: ["'self'", "https://api.jina.ai", "https://api.openai.com", "https://api.anthropic.com"],
175
+ connectSrc: ["'self'", "https://api.jina.ai", "https://api.openai.com", "https://api.anthropic.com", "https://cdn.jsdelivr.net"],
176
176
  },
177
177
  },
178
178
  crossOriginResourcePolicy: { policy: 'cross-origin' },
@@ -90,6 +90,7 @@ adminRouter.get('/users/:id', async (req, res) => {
90
90
  res.status(404).json({ error: 'User not found' });
91
91
  return;
92
92
  }
93
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
93
94
  const { passwordHash, ...sanitized } = user;
94
95
  res.json({ user: sanitized });
95
96
  }
@@ -434,6 +435,7 @@ adminRouter.get('/export/all', async (_req, res) => {
434
435
  const auditLogs = await auditService.query({ limit: 1000, offset: 0 });
435
436
  // Sanitize user data (remove passwords)
436
437
  const sanitizedUsers = users.map(u => {
438
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
437
439
  const { passwordHash, ...safe } = u;
438
440
  return safe;
439
441
  });
@@ -333,7 +333,7 @@ apiRouter.post('/projects/:id/upload-index/finalize', authMiddleware, checkProje
333
333
  }
334
334
  Logger.info(`Finalizing chunked upload ${uploadId}: ${upload.asts.length} ASTs, ${upload.symbols.length} symbols`);
335
335
  // Собираем все данные и отправляем в projectService
336
- // Type cast because chunked data comes as unknown from JSON
336
+ // Type cast needed: chunked data comes as serialized JSON, types match at runtime
337
337
  const result = await projectService.uploadIndexedData(id, {
338
338
  asts: upload.asts,
339
339
  symbols: upload.symbols,
@@ -69,13 +69,25 @@ gitlabRouter.post('/connect', authMiddleware, async (req, res) => {
69
69
  res.status(400).json({ error: 'No GitLab instance available' });
70
70
  return;
71
71
  }
72
- // Find the project by path
73
- const projects = await gitlabService.listProjects(req.user.id, instance.id, { search: repoPath });
74
- const project = projects.find(p => p.path_with_namespace === repoPath);
72
+ // Find the project by path - try direct fetch first (works for private repos)
73
+ let project;
74
+ try {
75
+ // GitLab API accepts URL-encoded path like "owner%2Frepo"
76
+ project = await gitlabService.getProject(req.user.id, instance.id, repoPath);
77
+ }
78
+ catch (e) {
79
+ // If direct fetch fails, try searching
80
+ Logger.debug(`Direct project fetch failed, trying search: ${e}`);
81
+ const projects = await gitlabService.listProjects(req.user.id, instance.id, {
82
+ search: repoPath.split('/').pop(), // Search by repo name only
83
+ membership: false // Include all accessible repos
84
+ });
85
+ project = projects.find(p => p.path_with_namespace === repoPath);
86
+ }
75
87
  if (!project) {
76
88
  res.status(404).json({
77
89
  error: 'Repository not found',
78
- message: `Could not find repository "${repoPath}" on ${instanceUrl}`
90
+ message: `Could not find repository "${repoPath}" on ${instanceUrl}. Make sure the path is correct (e.g., "owner/repo") and your token has access to it.`
79
91
  });
80
92
  return;
81
93
  }
@@ -536,7 +536,7 @@ export class ProjectService {
536
536
  graphNodes.set(key, {
537
537
  id: node.id,
538
538
  name: node.name,
539
- type: node.type || 'file',
539
+ type: (node.type || 'file'),
540
540
  filePath: node.filePath,
541
541
  metadata: node.metadata || {}
542
542
  });
@@ -630,7 +630,7 @@ export class ProjectService {
630
630
  graphNodes.set(key, {
631
631
  id: node.id,
632
632
  name: node.name,
633
- type: node.type || 'file',
633
+ type: (node.type || 'file'),
634
634
  filePath: node.filePath,
635
635
  metadata: node.metadata || {}
636
636
  });
@@ -282,5 +282,92 @@ export interface UserProfileResponse {
282
282
  };
283
283
  error?: string;
284
284
  }
285
+ /** Generic error response from API */
286
+ export interface ErrorResponse {
287
+ error?: string;
288
+ message?: string;
289
+ success?: boolean;
290
+ }
291
+ /** Project data from API */
292
+ export interface ProjectData {
293
+ id: string;
294
+ name: string;
295
+ path: string;
296
+ status?: string;
297
+ indexed?: boolean;
298
+ lastAccess?: string;
299
+ updatedAt?: string;
300
+ lastIndexed?: string;
301
+ statistics?: {
302
+ codeIndex?: {
303
+ totalFiles?: number;
304
+ totalSymbols?: number;
305
+ };
306
+ };
307
+ stats?: {
308
+ filesCount?: number;
309
+ symbolsCount?: number;
310
+ };
311
+ }
312
+ /** Projects list response */
313
+ export interface ProjectsListData {
314
+ projects?: ProjectData[];
315
+ success?: boolean;
316
+ error?: string;
317
+ }
318
+ /** Single project response */
319
+ export interface ProjectDetailData {
320
+ project?: ProjectData;
321
+ success?: boolean;
322
+ error?: string;
323
+ }
324
+ /** User response from profile endpoint */
325
+ export interface UserData {
326
+ id: string;
327
+ email: string;
328
+ username?: string;
329
+ tier?: string;
330
+ provider?: string;
331
+ avatar?: string;
332
+ }
333
+ /** User profile response */
334
+ export interface UserProfileData {
335
+ user?: UserData;
336
+ success?: boolean;
337
+ error?: string;
338
+ }
339
+ /** Export response */
340
+ export interface ExportData {
341
+ success?: boolean;
342
+ export?: unknown;
343
+ error?: string;
344
+ }
345
+ /** Graph node for visualization */
346
+ export interface GraphNodeData {
347
+ id: string;
348
+ label?: string;
349
+ type?: string;
350
+ filePath?: string;
351
+ kind?: string;
352
+ size?: number;
353
+ group?: string;
354
+ }
355
+ /** Graph edge for visualization */
356
+ export interface GraphEdgeData {
357
+ from: string;
358
+ to: string;
359
+ type?: string;
360
+ }
361
+ /** Symbol data */
362
+ export interface SymbolData {
363
+ id: string;
364
+ name: string;
365
+ kind: string;
366
+ filePath: string;
367
+ startLine: number;
368
+ endLine: number;
369
+ references?: string[];
370
+ modifiers?: string[];
371
+ }
285
372
  export declare const DEFAULT_RATE_LIMITS: Record<string, RateLimitConfig>;
286
373
  //# sourceMappingURL=api.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archicore",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "description": "AI Software Architect - code analysis, impact prediction, semantic search",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",