@andrebuzeli/git-mcp 2.40.0 → 2.42.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.
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.gitUpdateProjectTool = void 0;
4
4
  const zod_1 = require("zod");
5
+ const index_js_1 = require("../providers/index.js");
6
+ const user_detection_js_1 = require("../utils/user-detection.js");
5
7
  const git_operations_js_1 = require("../utils/git-operations.js");
6
8
  const GitUpdateProjectInputSchema = zod_1.z.discriminatedUnion('action', [
7
9
  // Action: update - commit incremental
@@ -36,13 +38,6 @@ const GitUpdateProjectInputSchema = zod_1.z.discriminatedUnion('action', [
36
38
  oneline: zod_1.z.boolean().optional(),
37
39
  branch: zod_1.z.string().optional()
38
40
  }),
39
- // Action: reset - desfazer mudanças
40
- zod_1.z.object({
41
- action: zod_1.z.literal('reset'),
42
- projectPath: zod_1.z.string(),
43
- mode: zod_1.z.enum(['soft', 'mixed', 'hard']).optional(),
44
- commit: zod_1.z.string().optional()
45
- }),
46
41
  // Action: stash - gerenciar mudanças temporárias
47
42
  zod_1.z.object({
48
43
  action: zod_1.z.literal('stash'),
@@ -65,6 +60,18 @@ const GitUpdateProjectInputSchema = zod_1.z.discriminatedUnion('action', [
65
60
  message: zod_1.z.string().min(1, 'Commit message is required'),
66
61
  branch: zod_1.z.string().optional(),
67
62
  forcePush: zod_1.z.boolean().optional()
63
+ }),
64
+ // Action: init - upload inicial completo (substitui upload-project)
65
+ zod_1.z.object({
66
+ action: zod_1.z.literal('init'),
67
+ repo: zod_1.z.string(),
68
+ projectPath: zod_1.z.string(),
69
+ provider: zod_1.z.enum(['gitea', 'github']),
70
+ message: zod_1.z.string().min(1, 'Commit message is required'),
71
+ branch: zod_1.z.string().optional(),
72
+ createRepo: zod_1.z.boolean().optional(),
73
+ forcePush: zod_1.z.boolean().optional(),
74
+ granular: zod_1.z.boolean().optional() // commits granulares por tipo de arquivo
68
75
  })
69
76
  ]);
70
77
  const GitUpdateProjectResultSchema = zod_1.z.object({
@@ -76,30 +83,31 @@ const GitUpdateProjectResultSchema = zod_1.z.object({
76
83
  });
77
84
  exports.gitUpdateProjectTool = {
78
85
  name: 'git-update-project',
79
- description: 'tool: Gerenciamento completo de projetos Git locais\\n──────────────\\n8 ACTIONS DISPONÍVEIS:\\n• update: Commit incremental automático\\n• status: Verificar status do repositório\\n• diff: Mostrar diferenças entre versões\\n• log: Histórico de commits\\n• reset: Desfazer mudanças\\n• stash: Gerenciar mudanças temporárias\\n• pull: Atualizar do repositório remoto\\n• sync: Sincronização completa (pull+commit+push)\\n───────────────\\nCOMMITS REAIS: Todas operações funcionam localmente\\nFunciona com GitHub, Gitea e qualquer repositório Git',
86
+ description: 'tool: Gerenciamento COMPLETO de projetos Git (local + remoto)\\n──────────────\\n8 ACTIONS DISPONÍVEIS:\\n• init: UPLOAD INICIAL completo (substitui upload-project)\\n• update: Commit incremental automático\\n• status: Verificar status do repositório\\n• diff: Mostrar diferenças entre versões\\n• log: Histórico de commits\\n• stash: Gerenciar mudanças temporárias\\n• pull: Atualizar do repositório remoto\\n• sync: Sincronização completa (pull+commit+push)\\n───────────────\\nCOMMITS REAIS + RASTREABILIDADE TOTAL\\nFunciona com GitHub, Gitea e qualquer repositório Git',
80
87
  inputSchema: {
81
88
  type: 'object',
82
89
  properties: {
83
90
  action: {
84
91
  type: 'string',
85
- enum: ['update', 'status', 'diff', 'log', 'reset', 'stash', 'pull', 'sync'],
92
+ enum: ['init', 'update', 'status', 'diff', 'log', 'stash', 'pull', 'sync'],
86
93
  description: 'Action to perform'
87
94
  },
88
95
  // Parâmetros comuns
89
- repo: { type: 'string', description: 'Repository name (required for update/sync)' },
96
+ repo: { type: 'string', description: 'Repository name (required for init/update/sync)' },
90
97
  projectPath: { type: 'string', description: 'Local project path (required for all)' },
91
- provider: { type: 'string', enum: ['gitea', 'github'], description: 'Provider (required for update/sync)' },
98
+ provider: { type: 'string', enum: ['gitea', 'github'], description: 'Provider (required for init/update/sync)' },
92
99
  // Parâmetros específicos
93
- message: { type: 'string', description: 'Commit message (required for update/sync)' },
100
+ message: { type: 'string', description: 'Commit message (required for init/update/sync)' },
94
101
  branch: { type: 'string', description: 'Branch name', default: 'main' },
95
102
  forcePush: { type: 'boolean', description: 'Force push', default: false },
103
+ createRepo: { type: 'boolean', description: 'Create remote repository if not exists', default: false },
104
+ granular: { type: 'boolean', description: 'Create granular commits by file type for init', default: false },
96
105
  detailed: { type: 'boolean', description: 'Detailed output for status', default: false },
97
106
  staged: { type: 'boolean', description: 'Show staged changes for diff', default: false },
98
107
  nameOnly: { type: 'boolean', description: 'Show only filenames for diff', default: false },
99
108
  commit: { type: 'string', description: 'Target commit for reset/diff' },
100
109
  maxCount: { type: 'number', description: 'Max commits for log', default: 10 },
101
110
  oneline: { type: 'boolean', description: 'One line format for log', default: true },
102
- mode: { type: 'string', enum: ['soft', 'mixed', 'hard'], description: 'Reset mode', default: 'mixed' },
103
111
  operation: { type: 'string', enum: ['save', 'pop', 'apply', 'list', 'drop', 'clear'], description: 'Stash operation', default: 'save' }
104
112
  },
105
113
  required: ['action', 'projectPath']
@@ -109,6 +117,8 @@ exports.gitUpdateProjectTool = {
109
117
  const validatedInput = GitUpdateProjectInputSchema.parse(input);
110
118
  // Roteamento baseado na action
111
119
  switch (validatedInput.action) {
120
+ case 'init':
121
+ return await this.handleInit(validatedInput);
112
122
  case 'update':
113
123
  return await this.handleUpdate(validatedInput);
114
124
  case 'status':
@@ -117,8 +127,6 @@ exports.gitUpdateProjectTool = {
117
127
  return await this.handleDiff(validatedInput);
118
128
  case 'log':
119
129
  return await this.handleLog(validatedInput);
120
- case 'reset':
121
- return await this.handleReset(validatedInput);
122
130
  case 'stash':
123
131
  return await this.handleStash(validatedInput);
124
132
  case 'pull':
@@ -273,44 +281,21 @@ exports.gitUpdateProjectTool = {
273
281
  try {
274
282
  const { projectPath, detailed = false } = params;
275
283
  const gitOps = new git_operations_js_1.GitOperations(projectPath);
276
- // Verificar se é um repositório Git
277
284
  const isGitRepo = await gitOps.isGitRepository();
278
- if (!isGitRepo) {
279
- throw new Error(`Diretório '${projectPath}' não é um repositório Git válido`);
280
- }
281
- // Obter status detalhado
285
+ if (!isGitRepo)
286
+ throw new Error(`Diretório não é um repositório Git válido`);
282
287
  const statusResult = await gitOps.status({ porcelain: false });
283
- if (!statusResult.success) {
288
+ if (!statusResult.success)
284
289
  throw new Error(`Falha ao obter status: ${statusResult.error}`);
285
- }
286
- // Obter branch atual
287
290
  const branchResult = await gitOps.getCurrentBranch();
288
291
  const currentBranch = branchResult.success ? branchResult.output.trim() : 'unknown';
289
- // Contar mudanças
290
292
  const porcelainResult = await gitOps.status({ porcelain: true });
291
293
  const changes = porcelainResult.success ? porcelainResult.output.trim() : '';
292
294
  const filesChanged = changes ? changes.split('\n').filter(line => line.trim().length > 0).length : 0;
293
- return {
294
- success: true,
295
- action: 'status',
296
- message: `Status do repositório obtido com sucesso`,
297
- data: {
298
- currentBranch,
299
- filesChanged,
300
- hasChanges: filesChanged > 0,
301
- statusOutput: detailed ? statusResult.output : statusResult.output.split('\n').slice(0, 10).join('\n'),
302
- implementation: 'REAL_GIT_OPERATIONS_v2.38.0',
303
- detailed
304
- }
305
- };
295
+ return { success: true, action: 'status', message: 'Status obtido', data: { currentBranch, filesChanged, hasChanges: filesChanged > 0, statusOutput: detailed ? statusResult.output : statusResult.output.split('\n').slice(0, 10).join('\n'), implementation: 'REAL_GIT_OPERATIONS_v2.38.0', detailed } };
306
296
  }
307
297
  catch (error) {
308
- return {
309
- success: false,
310
- action: 'status',
311
- message: 'Erro ao verificar status do repositório',
312
- error: error instanceof Error ? error.message : String(error)
313
- };
298
+ return { success: false, action: 'status', message: 'Erro status', error: error instanceof Error ? error.message : String(error) };
314
299
  }
315
300
  },
316
301
  // Action: diff - mostrar diferenças
@@ -318,12 +303,9 @@ exports.gitUpdateProjectTool = {
318
303
  try {
319
304
  const { projectPath, staged = false, nameOnly = false, commit } = params;
320
305
  const gitOps = new git_operations_js_1.GitOperations(projectPath);
321
- // Verificar se é um repositório Git
322
306
  const isGitRepo = await gitOps.isGitRepository();
323
- if (!isGitRepo) {
324
- throw new Error(`Diretório '${projectPath}' não é um repositório Git válido`);
325
- }
326
- // Obter diferenças
307
+ if (!isGitRepo)
308
+ throw new Error(`Diretório não é um repositório Git válido`);
327
309
  const diffOptions = {};
328
310
  if (staged)
329
311
  diffOptions.cached = true;
@@ -332,31 +314,13 @@ exports.gitUpdateProjectTool = {
332
314
  if (commit)
333
315
  diffOptions.commit = commit;
334
316
  const diffResult = await gitOps.diff(diffOptions);
335
- if (!diffResult.success && diffResult.error) {
336
- throw new Error(`Falha ao obter diferenças: ${diffResult.error}`);
337
- }
317
+ if (!diffResult.success && diffResult.error)
318
+ throw new Error(`Falha diff: ${diffResult.error}`);
338
319
  const hasDifferences = diffResult.output.trim().length > 0;
339
- return {
340
- success: true,
341
- action: 'diff',
342
- message: hasDifferences ? 'Diferenças encontradas' : 'Nenhuma diferença encontrada',
343
- data: {
344
- hasDifferences,
345
- diffOutput: diffResult.output,
346
- staged,
347
- nameOnly,
348
- commit: commit || 'HEAD',
349
- implementation: 'REAL_GIT_OPERATIONS_v2.38.0'
350
- }
351
- };
320
+ return { success: true, action: 'diff', message: hasDifferences ? 'Diferenças encontradas' : 'Sem diferenças', data: { hasDifferences, diffOutput: diffResult.output, staged, nameOnly, commit: commit || 'HEAD', implementation: 'REAL_GIT_OPERATIONS_v2.38.0' } };
352
321
  }
353
322
  catch (error) {
354
- return {
355
- success: false,
356
- action: 'diff',
357
- message: 'Erro ao obter diferenças',
358
- error: error instanceof Error ? error.message : String(error)
359
- };
323
+ return { success: false, action: 'diff', message: 'Erro diff', error: error instanceof Error ? error.message : String(error) };
360
324
  }
361
325
  },
362
326
  // Action: log - histórico de commits
@@ -364,12 +328,9 @@ exports.gitUpdateProjectTool = {
364
328
  try {
365
329
  const { projectPath, maxCount = 10, oneline = true, branch } = params;
366
330
  const gitOps = new git_operations_js_1.GitOperations(projectPath);
367
- // Verificar se é um repositório Git
368
331
  const isGitRepo = await gitOps.isGitRepository();
369
- if (!isGitRepo) {
370
- throw new Error(`Diretório '${projectPath}' não é um repositório Git válido`);
371
- }
372
- // Obter histórico de commits
332
+ if (!isGitRepo)
333
+ throw new Error(`Diretório não é um repositório Git válido`);
373
334
  const logOptions = {};
374
335
  if (maxCount)
375
336
  logOptions.maxCount = maxCount;
@@ -378,32 +339,14 @@ exports.gitUpdateProjectTool = {
378
339
  if (branch)
379
340
  logOptions.branches = [branch];
380
341
  const logResult = await gitOps.log(logOptions);
381
- if (!logResult.success) {
382
- throw new Error(`Falha ao obter histórico: ${logResult.error}`);
383
- }
342
+ if (!logResult.success)
343
+ throw new Error(`Falha log: ${logResult.error}`);
384
344
  const commits = logResult.output.trim();
385
345
  const commitCount = commits ? commits.split('\n').filter(line => line.trim().length > 0).length : 0;
386
- return {
387
- success: true,
388
- action: 'log',
389
- message: `${commitCount} commits encontrados no histórico`,
390
- data: {
391
- commits: commits || 'Nenhum commit encontrado',
392
- commitCount,
393
- maxCount,
394
- oneline,
395
- branch: branch || 'all',
396
- implementation: 'REAL_GIT_OPERATIONS_v2.38.0'
397
- }
398
- };
346
+ return { success: true, action: 'log', message: `${commitCount} commits`, data: { commits: commits || 'Sem commits', commitCount, maxCount, oneline, branch: branch || 'all', implementation: 'REAL_GIT_OPERATIONS_v2.38.0' } };
399
347
  }
400
348
  catch (error) {
401
- return {
402
- success: false,
403
- action: 'log',
404
- message: 'Erro ao obter histórico de commits',
405
- error: error instanceof Error ? error.message : String(error)
406
- };
349
+ return { success: false, action: 'log', message: 'Erro log', error: error instanceof Error ? error.message : String(error) };
407
350
  }
408
351
  },
409
352
  // Action: reset - desfazer mudanças
@@ -411,39 +354,18 @@ exports.gitUpdateProjectTool = {
411
354
  try {
412
355
  const { projectPath, mode = 'mixed', commit } = params;
413
356
  const gitOps = new git_operations_js_1.GitOperations(projectPath);
414
- // Verificar se é um repositório Git
415
357
  const isGitRepo = await gitOps.isGitRepository();
416
- if (!isGitRepo) {
417
- throw new Error(`Diretório '${projectPath}' não é um repositório Git válido`);
418
- }
419
- // Executar reset
420
- const resetOptions = {};
421
- if (commit) {
422
- resetOptions.target = commit;
423
- }
424
- const resetResult = await gitOps.reset(mode, resetOptions);
425
- if (!resetResult.success) {
426
- throw new Error(`Falha no reset: ${resetResult.error}`);
427
- }
428
- return {
429
- success: true,
430
- action: 'reset',
431
- message: `Reset ${mode} executado com sucesso`,
432
- data: {
433
- mode,
434
- targetCommit: commit || 'HEAD',
435
- resetOutput: resetResult.output,
436
- implementation: 'REAL_GIT_OPERATIONS_v2.38.0'
437
- }
438
- };
358
+ if (!isGitRepo)
359
+ throw new Error(`Diretório não é um repositório Git válido`);
360
+ const target = commit || 'HEAD';
361
+ const resetOptions = { mode };
362
+ const resetResult = await gitOps.reset(target, resetOptions);
363
+ if (!resetResult.success)
364
+ throw new Error(`Falha reset: ${resetResult.error}`);
365
+ return { success: true, action: 'reset', message: `Reset ${mode} executado`, data: { mode, targetCommit: target, resetOutput: resetResult.output, implementation: 'REAL_GIT_OPERATIONS_v2.38.0' } };
439
366
  }
440
367
  catch (error) {
441
- return {
442
- success: false,
443
- action: 'reset',
444
- message: 'Erro ao executar reset',
445
- error: error instanceof Error ? error.message : String(error)
446
- };
368
+ return { success: false, action: 'reset', message: 'Erro reset', error: error instanceof Error ? error.message : String(error) };
447
369
  }
448
370
  },
449
371
  // Action: stash - gerenciar mudanças temporárias
@@ -451,11 +373,9 @@ exports.gitUpdateProjectTool = {
451
373
  try {
452
374
  const { projectPath, operation = 'save', message } = params;
453
375
  const gitOps = new git_operations_js_1.GitOperations(projectPath);
454
- // Verificar se é um repositório Git
455
376
  const isGitRepo = await gitOps.isGitRepository();
456
- if (!isGitRepo) {
457
- throw new Error(`Diretório '${projectPath}' não é um repositório Git válido`);
458
- }
377
+ if (!isGitRepo)
378
+ throw new Error(`Diretório não é um repositório Git válido`);
459
379
  let stashResult;
460
380
  switch (operation) {
461
381
  case 'save':
@@ -476,31 +396,14 @@ exports.gitUpdateProjectTool = {
476
396
  case 'clear':
477
397
  stashResult = await gitOps.stash('clear');
478
398
  break;
479
- default:
480
- throw new Error(`Operação de stash '${operation}' não suportada`);
481
- }
482
- if (!stashResult.success) {
483
- throw new Error(`Falha na operação stash ${operation}: ${stashResult.error}`);
399
+ default: throw new Error(`Operação stash '${operation}' não suportada`);
484
400
  }
485
- return {
486
- success: true,
487
- action: 'stash',
488
- message: `Operação stash '${operation}' executada com sucesso`,
489
- data: {
490
- operation,
491
- message: message || undefined,
492
- stashOutput: stashResult.output,
493
- implementation: 'REAL_GIT_OPERATIONS_v2.38.0'
494
- }
495
- };
401
+ if (!stashResult.success)
402
+ throw new Error(`Falha stash ${operation}: ${stashResult.error}`);
403
+ return { success: true, action: 'stash', message: `Stash ${operation} executado`, data: { operation, message: message || undefined, stashOutput: stashResult.output, implementation: 'REAL_GIT_OPERATIONS_v2.38.0' } };
496
404
  }
497
405
  catch (error) {
498
- return {
499
- success: false,
500
- action: 'stash',
501
- message: 'Erro na operação de stash',
502
- error: error instanceof Error ? error.message : String(error)
503
- };
406
+ return { success: false, action: 'stash', message: 'Erro stash', error: error instanceof Error ? error.message : String(error) };
504
407
  }
505
408
  },
506
409
  // Action: pull - atualizar do remoto
@@ -508,128 +411,180 @@ exports.gitUpdateProjectTool = {
508
411
  try {
509
412
  const { projectPath, branch } = params;
510
413
  const gitOps = new git_operations_js_1.GitOperations(projectPath);
511
- // Verificar se é um repositório Git
512
414
  const isGitRepo = await gitOps.isGitRepository();
513
- if (!isGitRepo) {
514
- throw new Error(`Diretório '${projectPath}' não é um repositório Git válido`);
515
- }
516
- // Executar pull
415
+ if (!isGitRepo)
416
+ throw new Error(`Diretório não é um repositório Git válido`);
517
417
  const pullResult = await gitOps.pull('origin', branch);
518
- if (!pullResult.success) {
519
- throw new Error(`Falha no pull: ${pullResult.error}`);
520
- }
521
- return {
522
- success: true,
523
- action: 'pull',
524
- message: `Pull do remoto executado com sucesso`,
525
- data: {
526
- remote: 'origin',
527
- branch: branch || 'current',
528
- pullOutput: pullResult.output,
529
- implementation: 'REAL_GIT_OPERATIONS_v2.38.0'
530
- }
531
- };
418
+ if (!pullResult.success)
419
+ throw new Error(`Falha pull: ${pullResult.error}`);
420
+ return { success: true, action: 'pull', message: 'Pull executado', data: { remote: 'origin', branch: branch || 'current', pullOutput: pullResult.output, implementation: 'REAL_GIT_OPERATIONS_v2.38.0' } };
532
421
  }
533
422
  catch (error) {
534
- return {
535
- success: false,
536
- action: 'pull',
537
- message: 'Erro ao executar pull',
538
- error: error instanceof Error ? error.message : String(error)
539
- };
423
+ return { success: false, action: 'pull', message: 'Erro pull', error: error instanceof Error ? error.message : String(error) };
540
424
  }
541
425
  },
542
- // Action: sync - sincronização completa (pull + commit + push)
426
+ // Action: sync - sincronização completa
543
427
  async handleSync(params) {
544
428
  try {
545
429
  const { repo, projectPath, message, branch = 'main', forcePush = false, provider: providerName } = params;
546
430
  const gitOps = new git_operations_js_1.GitOperations(projectPath);
547
- // Verificar se é um repositório Git
548
431
  const isGitRepo = await gitOps.isGitRepository();
549
- if (!isGitRepo) {
550
- throw new Error(`Diretório '${projectPath}' não é um repositório Git válido`);
551
- }
552
- const syncResults = {
553
- pull: { success: false, output: '', error: '' },
554
- commit: { success: false, output: '', error: '', created: false },
555
- push: { success: false, output: '', error: '' }
556
- };
557
- // 1. Pull do remoto
432
+ if (!isGitRepo)
433
+ throw new Error(`Diretório não é um repositório Git válido`);
434
+ const syncResults = { pull: { success: false, output: '', error: '' }, commit: { success: false, output: '', error: '', created: false }, push: { success: false, output: '', error: '' } };
558
435
  try {
559
436
  const pullResult = await gitOps.pull('origin', branch);
560
- syncResults.pull = {
561
- success: pullResult.success,
562
- output: pullResult.output,
563
- error: pullResult.error || ''
564
- };
437
+ syncResults.pull = { success: pullResult.success, output: pullResult.output, error: pullResult.error || '' };
565
438
  }
566
439
  catch (pullErr) {
567
440
  syncResults.pull.error = pullErr instanceof Error ? pullErr.message : String(pullErr);
568
441
  }
569
- // 2. Verificar se há mudanças após pull
570
442
  const statusResult = await gitOps.status({ porcelain: true });
571
443
  const hasChanges = statusResult.success && statusResult.output.trim().length > 0;
572
444
  if (hasChanges) {
573
- // Fazer commit das mudanças
574
445
  const addResult = await gitOps.addFiles(['.']);
575
446
  if (addResult.success) {
576
447
  const commitResult = await gitOps.commit(message);
577
- syncResults.commit = {
578
- success: commitResult.success,
579
- output: commitResult.output,
580
- error: commitResult.error || '',
581
- created: commitResult.success
582
- };
448
+ syncResults.commit = { success: commitResult.success, output: commitResult.output, error: commitResult.error || '', created: commitResult.success };
583
449
  }
584
450
  else {
585
- syncResults.commit.error = `Falha ao adicionar arquivos: ${addResult.error}`;
451
+ syncResults.commit.error = `Falha add: ${addResult.error}`;
586
452
  }
587
453
  }
588
- // 3. Push se commit foi criado
589
454
  if (syncResults.commit.created) {
590
455
  try {
591
456
  const pushOptions = {};
592
457
  if (forcePush)
593
458
  pushOptions.force = true;
594
459
  const pushResult = await gitOps.push('origin', branch, pushOptions);
595
- syncResults.push = {
596
- success: pushResult.success,
597
- output: pushResult.output,
598
- error: pushResult.error || ''
599
- };
460
+ syncResults.push = { success: pushResult.success, output: pushResult.output, error: pushResult.error || '' };
600
461
  }
601
462
  catch (pushErr) {
602
463
  syncResults.push.error = pushErr instanceof Error ? pushErr.message : String(pushErr);
603
464
  }
604
465
  }
605
466
  const overallSuccess = syncResults.pull.success && (!hasChanges || syncResults.commit.success);
606
- return {
607
- success: overallSuccess,
608
- action: 'sync',
609
- message: `Sincronização ${overallSuccess ? 'concluída' : 'com problemas'}`,
610
- data: {
611
- repo,
612
- branch,
613
- provider: providerName,
614
- syncResults,
615
- hasChanges,
616
- implementation: 'REAL_GIT_OPERATIONS_v2.38.0',
617
- summary: {
618
- pullSuccessful: syncResults.pull.success,
619
- commitCreated: syncResults.commit.created,
620
- pushSuccessful: syncResults.push.success
467
+ return { success: overallSuccess, action: 'sync', message: `Sincronização ${overallSuccess ? 'concluída' : 'problemas'}`, data: { repo, branch, provider: providerName, syncResults, hasChanges, implementation: 'REAL_GIT_OPERATIONS_v2.38.0', summary: { pullSuccessful: syncResults.pull.success, commitCreated: syncResults.commit.created, pushSuccessful: syncResults.push.success } } };
468
+ }
469
+ catch (error) {
470
+ return { success: false, action: 'sync', message: 'Erro sync', error: error instanceof Error ? error.message : String(error) };
471
+ }
472
+ },
473
+ // Action: init - upload inicial completo
474
+ async handleInit(params) {
475
+ try {
476
+ const { repo, projectPath, message, branch = 'main', forcePush = false, createRepo = false, granular = false, provider: providerName } = params;
477
+ const gitOps = new git_operations_js_1.GitOperations(projectPath);
478
+ const processedInput = await (0, user_detection_js_1.applyAutoUserDetection)(params, providerName);
479
+ const provider = index_js_1.globalProviderFactory.getProvider(processedInput.provider);
480
+ if (!provider)
481
+ throw new Error(`Provider '${providerName}' não encontrado`);
482
+ const currentUser = await provider.getCurrentUser();
483
+ const owner = currentUser.login;
484
+ const isGitRepo = await gitOps.isGitRepository();
485
+ if (!isGitRepo) {
486
+ const initResult = await gitOps.initRepository();
487
+ if (!initResult.success)
488
+ throw new Error(`Falha init: ${initResult.error}`);
489
+ }
490
+ let repoExists = true;
491
+ try {
492
+ await provider.getRepository(owner, repo);
493
+ }
494
+ catch (error) {
495
+ repoExists = false;
496
+ if (createRepo) {
497
+ try {
498
+ await provider.createRepository(repo, `Projeto ${repo}`, false);
499
+ repoExists = true;
500
+ }
501
+ catch (createError) {
502
+ console.warn(`Aviso: Falha criar repo: ${createError instanceof Error ? createError.message : String(createError)}`);
621
503
  }
622
504
  }
623
- };
505
+ else {
506
+ throw new Error(`Repositório '${repo}' não existe. Use createRepo: true.`);
507
+ }
508
+ }
509
+ let filesCommitted = 0;
510
+ let commitsCreated = 0;
511
+ const remoteUrl = provider.getRepositoryUrl(owner, repo);
512
+ if (granular) {
513
+ const fileGroups = await this.groupFilesByType(projectPath);
514
+ for (const [fileType, files] of Object.entries(fileGroups)) {
515
+ if (files.length > 0) {
516
+ const addResult = await gitOps.addFiles(files);
517
+ if (addResult.success) {
518
+ const statusResult = await gitOps.status({ porcelain: true });
519
+ if (statusResult.success && statusResult.output.trim()) {
520
+ const commitResult = await gitOps.commit(`${message} - ${fileType} files`);
521
+ if (commitResult.success) {
522
+ commitsCreated++;
523
+ filesCommitted += files.length;
524
+ }
525
+ }
526
+ }
527
+ }
528
+ }
529
+ }
530
+ else {
531
+ const addResult = await gitOps.addFiles(['.']);
532
+ if (addResult.success) {
533
+ const statusResult = await gitOps.status({ porcelain: true });
534
+ if (statusResult.success && statusResult.output.trim()) {
535
+ const commitResult = await gitOps.commit(message);
536
+ if (commitResult.success) {
537
+ commitsCreated++;
538
+ filesCommitted = statusResult.output.trim().split('\n').length;
539
+ }
540
+ }
541
+ }
542
+ }
543
+ let pushSuccessful = false;
544
+ if (commitsCreated > 0) {
545
+ try {
546
+ const pushOptions = { setUpstream: true };
547
+ if (forcePush)
548
+ pushOptions.force = true;
549
+ const pushResult = await gitOps.push('origin', branch, pushOptions);
550
+ pushSuccessful = pushResult.success;
551
+ }
552
+ catch (pushErr) {
553
+ console.warn(`Aviso push: ${pushErr instanceof Error ? pushErr.message : String(pushErr)}`);
554
+ }
555
+ }
556
+ return { success: true, action: 'init', message: `Upload concluído: ${commitsCreated} commits, ${filesCommitted} arquivos`, data: { repo, branch, provider: providerName, owner, remoteUrl, repositoryCreated: !repoExists && createRepo, gitInit: !isGitRepo, commitsCreated, filesCommitted, pushSuccessful, granular, implementation: 'REAL_GIT_OPERATIONS_v2.40.0', note: granular ? 'Commits granulares por tipo' : 'Commit único' } };
624
557
  }
625
558
  catch (error) {
626
- return {
627
- success: false,
628
- action: 'sync',
629
- message: 'Erro na sincronização completa',
630
- error: error instanceof Error ? error.message : String(error)
631
- };
559
+ return { success: false, action: 'init', message: 'Erro init', error: error instanceof Error ? error.message : String(error) };
560
+ }
561
+ },
562
+ async groupFilesByType(projectPath) {
563
+ const gitOps = new git_operations_js_1.GitOperations(projectPath);
564
+ const statusResult = await gitOps.status({ porcelain: true });
565
+ if (!statusResult.success)
566
+ return {};
567
+ const lines = statusResult.output.trim().split('\n').filter(line => line.trim());
568
+ const fileGroups = { 'config': [], 'source': [], 'documentation': [], 'assets': [], 'other': [] };
569
+ for (const line of lines) {
570
+ const fileName = line.substring(3).trim();
571
+ if (fileName.includes('package.json') || fileName.includes('.config.') || fileName.includes('tsconfig') || fileName.includes('.env')) {
572
+ fileGroups.config.push(fileName);
573
+ }
574
+ else if (fileName.endsWith('.ts') || fileName.endsWith('.js') || fileName.endsWith('.py') || fileName.endsWith('.java')) {
575
+ fileGroups.source.push(fileName);
576
+ }
577
+ else if (fileName.endsWith('.md') || fileName.endsWith('.txt') || fileName.includes('README') || fileName.includes('LICENSE')) {
578
+ fileGroups.documentation.push(fileName);
579
+ }
580
+ else if (fileName.endsWith('.png') || fileName.endsWith('.jpg') || fileName.endsWith('.svg') || fileName.endsWith('.css')) {
581
+ fileGroups.assets.push(fileName);
582
+ }
583
+ else {
584
+ fileGroups.other.push(fileName);
585
+ }
632
586
  }
587
+ return fileGroups;
633
588
  }
634
589
  };
635
590
  //# sourceMappingURL=git-update-project.js.map