@andrebuzeli/git-mcp 4.0.21 → 5.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 (65) hide show
  1. package/README.md +59 -32
  2. package/dist/config.d.ts +0 -2
  3. package/dist/config.d.ts.map +1 -1
  4. package/dist/config.js +0 -27
  5. package/dist/config.js.map +1 -1
  6. package/dist/index.d.ts +0 -1
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +54 -3
  9. package/dist/index.js.map +1 -1
  10. package/dist/providers/gitea-provider.d.ts +5 -5
  11. package/dist/providers/gitea-provider.d.ts.map +1 -1
  12. package/dist/providers/gitea-provider.js +75 -220
  13. package/dist/providers/gitea-provider.js.map +1 -1
  14. package/dist/providers/github-provider.d.ts +0 -48
  15. package/dist/providers/github-provider.d.ts.map +1 -1
  16. package/dist/providers/github-provider.js +805 -849
  17. package/dist/providers/github-provider.js.map +1 -1
  18. package/dist/providers/provider-factory.d.ts +1 -1
  19. package/dist/providers/provider-factory.d.ts.map +1 -1
  20. package/dist/providers/provider-factory.js +4 -14
  21. package/dist/providers/provider-factory.js.map +1 -1
  22. package/dist/providers/types.d.ts +1 -1
  23. package/dist/providers/types.d.ts.map +1 -1
  24. package/dist/server.d.ts.map +1 -1
  25. package/dist/server.js +91 -37
  26. package/dist/server.js.map +1 -1
  27. package/dist/tools/git-files.d.ts.map +1 -1
  28. package/dist/tools/git-files.js +103 -5
  29. package/dist/tools/git-files.js.map +1 -1
  30. package/dist/tools/git-sync.d.ts.map +1 -1
  31. package/dist/tools/git-sync.js +104 -6
  32. package/dist/tools/git-sync.js.map +1 -1
  33. package/dist/tools/git-workflow.d.ts +55 -0
  34. package/dist/tools/git-workflow.d.ts.map +1 -1
  35. package/dist/tools/git-workflow.js +660 -7
  36. package/dist/tools/git-workflow.js.map +1 -1
  37. package/dist/utils/auto-detection.js +1 -1
  38. package/dist/utils/auto-detection.js.map +1 -1
  39. package/dist/utils/configuration-error-generator.d.ts +41 -0
  40. package/dist/utils/configuration-error-generator.d.ts.map +1 -0
  41. package/dist/utils/configuration-error-generator.js +168 -0
  42. package/dist/utils/configuration-error-generator.js.map +1 -0
  43. package/dist/utils/configuration-validator.d.ts +67 -0
  44. package/dist/utils/configuration-validator.d.ts.map +1 -0
  45. package/dist/utils/configuration-validator.js +257 -0
  46. package/dist/utils/configuration-validator.js.map +1 -0
  47. package/dist/utils/multi-provider-error-handler.d.ts +75 -0
  48. package/dist/utils/multi-provider-error-handler.d.ts.map +1 -0
  49. package/dist/utils/multi-provider-error-handler.js +276 -0
  50. package/dist/utils/multi-provider-error-handler.js.map +1 -0
  51. package/dist/utils/multi-provider-operation-handler.d.ts +113 -0
  52. package/dist/utils/multi-provider-operation-handler.d.ts.map +1 -0
  53. package/dist/utils/multi-provider-operation-handler.js +303 -0
  54. package/dist/utils/multi-provider-operation-handler.js.map +1 -0
  55. package/dist/utils/operation-error-handler.d.ts +69 -0
  56. package/dist/utils/operation-error-handler.d.ts.map +1 -0
  57. package/dist/utils/operation-error-handler.js +277 -0
  58. package/dist/utils/operation-error-handler.js.map +1 -0
  59. package/dist/utils/provider-operation-handler.d.ts +80 -0
  60. package/dist/utils/provider-operation-handler.d.ts.map +1 -0
  61. package/dist/utils/provider-operation-handler.js +201 -0
  62. package/dist/utils/provider-operation-handler.js.map +1 -0
  63. package/dist/utils/response-helper.js +1 -1
  64. package/dist/utils/response-helper.js.map +1 -1
  65. package/package.json +60 -60
@@ -2,6 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.gitWorkflowTool = void 0;
4
4
  const auto_detection_js_1 = require("../utils/auto-detection.js");
5
+ const configuration_validator_js_1 = require("../utils/configuration-validator.js");
6
+ const provider_operation_handler_js_1 = require("../utils/provider-operation-handler.js");
7
+ const operation_error_handler_js_1 = require("../utils/operation-error-handler.js");
5
8
  const terminal_controller_js_1 = require("../utils/terminal-controller.js");
6
9
  /**
7
10
  * Git Workflow Tool - Ferramenta Principal
@@ -18,13 +21,18 @@ const inputSchema = {
18
21
  properties: {
19
22
  action: {
20
23
  type: 'string',
21
- enum: ['init', 'commit', 'sync', 'status', 'backup'],
24
+ enum: ['init', 'commit', 'sync', 'status', 'backup', 'create', 'list', 'get', 'update', 'delete', 'fork', 'search'],
22
25
  description: 'Ação do workflow a executar'
23
26
  },
24
27
  projectPath: {
25
28
  type: 'string',
26
29
  description: 'Caminho do projeto (obrigatório)'
27
30
  },
31
+ provider: {
32
+ type: 'string',
33
+ enum: ['github', 'gitea', 'both'],
34
+ description: 'Provider para operações remotas (obrigatório para create, list, get, update, delete, fork, search)'
35
+ },
28
36
  message: {
29
37
  type: 'string',
30
38
  description: 'Mensagem de commit (para commit/sync)'
@@ -36,9 +44,61 @@ const inputSchema = {
36
44
  remote: {
37
45
  type: 'string',
38
46
  description: 'Remote para operações (padrão: origin)'
47
+ },
48
+ // Parâmetros para gerenciamento de repositórios
49
+ repoName: {
50
+ type: 'string',
51
+ description: 'Nome do repositório (para create/get/update/delete/fork)'
52
+ },
53
+ description: {
54
+ type: 'string',
55
+ description: 'Descrição do repositório (para create/update)'
56
+ },
57
+ private: {
58
+ type: 'boolean',
59
+ description: 'Repositório privado (para create/update)'
60
+ },
61
+ sourceRepo: {
62
+ type: 'string',
63
+ description: 'Repositório de origem (para fork)'
64
+ },
65
+ searchQuery: {
66
+ type: 'string',
67
+ description: 'Termo de busca (para search)'
68
+ },
69
+ language: {
70
+ type: 'string',
71
+ description: 'Filtrar por linguagem (para search)'
72
+ },
73
+ sort: {
74
+ type: 'string',
75
+ description: 'Ordenar por: stars, updated, created (padrão: stars)'
76
+ },
77
+ order: {
78
+ type: 'string',
79
+ description: 'Ordem: asc, desc (padrão: desc)'
80
+ },
81
+ page: {
82
+ type: 'number',
83
+ description: 'Página para paginação (padrão: 1)'
84
+ },
85
+ perPage: {
86
+ type: 'number',
87
+ description: 'Itens por página (padrão: 30)'
39
88
  }
40
89
  },
41
- required: ['action', 'projectPath']
90
+ required: ['action', 'projectPath'],
91
+ // Provider é obrigatório para operações remotas
92
+ if: {
93
+ properties: {
94
+ action: {
95
+ enum: ['create', 'list', 'get', 'update', 'delete', 'fork', 'search']
96
+ }
97
+ }
98
+ },
99
+ then: {
100
+ required: ['action', 'projectPath', 'provider']
101
+ }
42
102
  };
43
103
  async function handleInit(projectPath, detection) {
44
104
  try {
@@ -279,19 +339,559 @@ async function handleBackup(projectPath, detection) {
279
339
  throw new Error(`Falha ao criar backup: ${error instanceof Error ? error.message : String(error)}`);
280
340
  }
281
341
  }
342
+ // Funções para gerenciamento de repositórios remotos
343
+ async function handleCreateRepo(repoName, description, isPrivate, detection, projectPath, provider) {
344
+ try {
345
+ // Execute both local and remote operations simultaneously
346
+ const results = await Promise.allSettled([
347
+ // Local operation: initialize Git repository
348
+ handleInit(projectPath, detection),
349
+ // Remote operation: create repository on specified provider(s)
350
+ provider_operation_handler_js_1.ProviderOperationHandler.executeOperation(provider, (providerInstance) => providerInstance.createRepository(repoName, description || `Repositório ${repoName}`, isPrivate || false))
351
+ ]);
352
+ const localResult = results[0];
353
+ const remoteResult = results[1];
354
+ // Format results
355
+ const localData = localResult.status === 'fulfilled' ? localResult.value : null;
356
+ const localError = localResult.status === 'rejected' ? localResult.reason.message : null;
357
+ const remoteData = remoteResult.status === 'fulfilled' ? remoteResult.value : null;
358
+ const remoteError = remoteResult.status === 'rejected' ? remoteResult.reason.message : null;
359
+ // Determine overall success and message
360
+ const localSuccess = localResult.status === 'fulfilled';
361
+ const remoteSuccess = remoteResult.status === 'fulfilled' && remoteData?.success;
362
+ let message;
363
+ if (localSuccess && remoteSuccess) {
364
+ message = `Repositório '${repoName}' criado com sucesso (local e remoto)`;
365
+ }
366
+ else if (localSuccess && !remoteSuccess) {
367
+ message = `Repositório '${repoName}' criado localmente, falha na criação remota`;
368
+ }
369
+ else if (!localSuccess && remoteSuccess) {
370
+ message = `Repositório '${repoName}' criado remotamente, falha na inicialização local`;
371
+ }
372
+ else {
373
+ message = `Falha ao criar repositório '${repoName}' (local e remoto)`;
374
+ }
375
+ return {
376
+ success: localSuccess || remoteSuccess, // Success if at least one operation succeeded
377
+ action: 'create',
378
+ message,
379
+ data: {
380
+ repoName,
381
+ description: description || `Repositório ${repoName}`,
382
+ private: isPrivate || false,
383
+ local: {
384
+ success: localSuccess,
385
+ data: localData,
386
+ error: localError
387
+ },
388
+ remote: remoteData || {
389
+ success: false,
390
+ error: remoteError || 'Unknown remote operation error'
391
+ }
392
+ }
393
+ };
394
+ }
395
+ catch (error) {
396
+ throw new Error(`Falha ao criar repositório: ${error instanceof Error ? error.message : String(error)}`);
397
+ }
398
+ }
399
+ async function handleListRepos(detection, page = 1, perPage = 30, sort = 'updated', provider) {
400
+ try {
401
+ // Execute operation on specified provider(s)
402
+ const result = await provider_operation_handler_js_1.ProviderOperationHandler.executeOperation(provider, (providerInstance) => providerInstance.listRepositories(detection.owner, page, perPage));
403
+ if (!result.success) {
404
+ const errorMessage = 'message' in result
405
+ ? result.message
406
+ : ('error' in result ? result.error || 'Failed to list repositories' : 'Unknown error');
407
+ throw new Error(errorMessage);
408
+ }
409
+ // Handle single provider result
410
+ if ('provider' in result && result.data) {
411
+ const repositories = result.data;
412
+ return {
413
+ success: true,
414
+ action: 'list',
415
+ message: `${repositories.length} repositórios encontrados no ${result.provider}`,
416
+ data: {
417
+ repositories,
418
+ total: repositories.length,
419
+ page,
420
+ perPage,
421
+ sort,
422
+ owner: detection.owner,
423
+ provider: result.provider
424
+ }
425
+ };
426
+ }
427
+ // Handle multi-provider result
428
+ if ('message' in result && typeof result.data === 'object') {
429
+ const multiData = result.data;
430
+ const allRepositories = [];
431
+ const providerResults = {};
432
+ // Collect repositories from all successful providers
433
+ if (multiData.github?.success && multiData.github.data) {
434
+ allRepositories.push(...multiData.github.data);
435
+ providerResults.github = {
436
+ success: true,
437
+ count: multiData.github.data.length,
438
+ repositories: multiData.github.data
439
+ };
440
+ }
441
+ else if (multiData.github) {
442
+ providerResults.github = {
443
+ success: false,
444
+ error: multiData.github.error
445
+ };
446
+ }
447
+ if (multiData.gitea?.success && multiData.gitea.data) {
448
+ allRepositories.push(...multiData.gitea.data);
449
+ providerResults.gitea = {
450
+ success: true,
451
+ count: multiData.gitea.data.length,
452
+ repositories: multiData.gitea.data
453
+ };
454
+ }
455
+ else if (multiData.gitea) {
456
+ providerResults.gitea = {
457
+ success: false,
458
+ error: multiData.gitea.error
459
+ };
460
+ }
461
+ return {
462
+ success: true,
463
+ action: 'list',
464
+ message: result.message,
465
+ data: {
466
+ repositories: allRepositories,
467
+ total: allRepositories.length,
468
+ page,
469
+ perPage,
470
+ sort,
471
+ owner: detection.owner,
472
+ provider: 'both',
473
+ providerResults,
474
+ warnings: result.warnings
475
+ }
476
+ };
477
+ }
478
+ throw new Error('Unexpected result format from provider operation');
479
+ }
480
+ catch (error) {
481
+ throw new Error(`Falha ao listar repositórios: ${error instanceof Error ? error.message : String(error)}`);
482
+ }
483
+ }
484
+ async function handleGetRepo(repoName, detection, provider) {
485
+ try {
486
+ // Execute operation on specified provider(s)
487
+ const result = await provider_operation_handler_js_1.ProviderOperationHandler.executeOperation(provider, (providerInstance) => providerInstance.getRepository(detection.owner, repoName));
488
+ if (!result.success) {
489
+ const errorMessage = 'message' in result
490
+ ? result.message
491
+ : ('error' in result ? result.error || 'Failed to get repository' : 'Unknown error');
492
+ throw new Error(errorMessage);
493
+ }
494
+ // Handle single provider result
495
+ if ('provider' in result && result.data) {
496
+ return {
497
+ success: true,
498
+ action: 'get',
499
+ message: `Detalhes do repositório '${repoName}' obtidos do ${result.provider}`,
500
+ data: {
501
+ repository: result.data,
502
+ provider: result.provider
503
+ }
504
+ };
505
+ }
506
+ // Handle multi-provider result
507
+ if ('message' in result && typeof result.data === 'object') {
508
+ const multiData = result.data;
509
+ const repositories = {};
510
+ if (multiData.github?.success && multiData.github.data) {
511
+ repositories.github = multiData.github.data;
512
+ }
513
+ if (multiData.gitea?.success && multiData.gitea.data) {
514
+ repositories.gitea = multiData.gitea.data;
515
+ }
516
+ return {
517
+ success: true,
518
+ action: 'get',
519
+ message: result.message,
520
+ data: {
521
+ repositories,
522
+ provider: 'both',
523
+ providerResults: {
524
+ github: multiData.github ? {
525
+ success: multiData.github.success,
526
+ error: multiData.github.error
527
+ } : undefined,
528
+ gitea: multiData.gitea ? {
529
+ success: multiData.gitea.success,
530
+ error: multiData.gitea.error
531
+ } : undefined
532
+ },
533
+ warnings: 'warnings' in result ? result.warnings : undefined
534
+ }
535
+ };
536
+ }
537
+ throw new Error('Unexpected result format from provider operation');
538
+ }
539
+ catch (error) {
540
+ throw new Error(`Falha ao obter repositório: ${error instanceof Error ? error.message : String(error)}`);
541
+ }
542
+ }
543
+ async function handleSearchRepos(searchQuery, detection, provider, language, sort = 'stars', order = 'desc') {
544
+ try {
545
+ // Execute operation on specified provider(s)
546
+ const result = await provider_operation_handler_js_1.ProviderOperationHandler.executeOperation(provider, (providerInstance) => providerInstance.searchRepositories(searchQuery));
547
+ if (!result.success) {
548
+ const errorMessage = 'message' in result
549
+ ? result.message
550
+ : ('error' in result ? result.error || 'Failed to search repositories' : 'Unknown error');
551
+ throw new Error(errorMessage);
552
+ }
553
+ // Handle single provider result
554
+ if ('provider' in result && result.data) {
555
+ const searchResults = result.data;
556
+ return {
557
+ success: true,
558
+ action: 'search',
559
+ message: `${searchResults.length} repositórios encontrados para '${searchQuery}' no ${result.provider}`,
560
+ data: {
561
+ query: searchQuery,
562
+ language,
563
+ sort,
564
+ order,
565
+ results: searchResults,
566
+ total: searchResults.length,
567
+ provider: result.provider
568
+ }
569
+ };
570
+ }
571
+ // Handle multi-provider result
572
+ if ('message' in result && typeof result.data === 'object') {
573
+ const multiData = result.data;
574
+ const allResults = [];
575
+ const providerResults = {};
576
+ // Collect results from all successful providers
577
+ if (multiData.github?.success && multiData.github.data) {
578
+ const githubResults = multiData.github.data.map((repo) => ({
579
+ ...repo,
580
+ source: 'github'
581
+ }));
582
+ allResults.push(...githubResults);
583
+ providerResults.github = {
584
+ success: true,
585
+ count: multiData.github.data.length,
586
+ results: multiData.github.data
587
+ };
588
+ }
589
+ else if (multiData.github) {
590
+ providerResults.github = {
591
+ success: false,
592
+ error: multiData.github.error
593
+ };
594
+ }
595
+ if (multiData.gitea?.success && multiData.gitea.data) {
596
+ const giteaResults = multiData.gitea.data.map((repo) => ({
597
+ ...repo,
598
+ source: 'gitea'
599
+ }));
600
+ allResults.push(...giteaResults);
601
+ providerResults.gitea = {
602
+ success: true,
603
+ count: multiData.gitea.data.length,
604
+ results: multiData.gitea.data
605
+ };
606
+ }
607
+ else if (multiData.gitea) {
608
+ providerResults.gitea = {
609
+ success: false,
610
+ error: multiData.gitea.error
611
+ };
612
+ }
613
+ return {
614
+ success: true,
615
+ action: 'search',
616
+ message: result.message,
617
+ data: {
618
+ query: searchQuery,
619
+ language,
620
+ sort,
621
+ order,
622
+ results: allResults,
623
+ total: allResults.length,
624
+ provider: 'both',
625
+ providerResults,
626
+ warnings: 'warnings' in result ? result.warnings : undefined
627
+ }
628
+ };
629
+ }
630
+ throw new Error('Unexpected result format from provider operation');
631
+ }
632
+ catch (error) {
633
+ throw new Error(`Falha na busca: ${error instanceof Error ? error.message : String(error)}`);
634
+ }
635
+ }
636
+ async function handleUpdateRepo(repoName, detection, provider, description, isPrivate) {
637
+ try {
638
+ // Prepare update data
639
+ const updateData = {};
640
+ if (description !== undefined)
641
+ updateData.description = description;
642
+ if (isPrivate !== undefined)
643
+ updateData.private = isPrivate;
644
+ // Execute operation on specified provider(s)
645
+ const result = await provider_operation_handler_js_1.ProviderOperationHandler.executeOperation(provider, (providerInstance) => providerInstance.updateRepository(detection.owner, repoName, updateData));
646
+ if (!result.success) {
647
+ const errorMessage = 'message' in result
648
+ ? result.message
649
+ : ('error' in result ? result.error || 'Failed to update repository' : 'Unknown error');
650
+ throw new Error(errorMessage);
651
+ }
652
+ // Handle single provider result
653
+ if ('provider' in result && result.data) {
654
+ return {
655
+ success: true,
656
+ action: 'update',
657
+ message: `Repositório '${repoName}' atualizado com sucesso no ${result.provider}`,
658
+ data: {
659
+ repoUpdated: true,
660
+ repository: result.data,
661
+ provider: result.provider
662
+ }
663
+ };
664
+ }
665
+ // Handle multi-provider result
666
+ if ('message' in result && typeof result.data === 'object') {
667
+ const multiData = result.data;
668
+ const updatedRepositories = {};
669
+ if (multiData.github?.success && multiData.github.data) {
670
+ updatedRepositories.github = multiData.github.data;
671
+ }
672
+ if (multiData.gitea?.success && multiData.gitea.data) {
673
+ updatedRepositories.gitea = multiData.gitea.data;
674
+ }
675
+ return {
676
+ success: true,
677
+ action: 'update',
678
+ message: result.message,
679
+ data: {
680
+ repoUpdated: true,
681
+ repositories: updatedRepositories,
682
+ provider: 'both',
683
+ providerResults: {
684
+ github: multiData.github ? {
685
+ success: multiData.github.success,
686
+ error: multiData.github.error
687
+ } : undefined,
688
+ gitea: multiData.gitea ? {
689
+ success: multiData.gitea.success,
690
+ error: multiData.gitea.error
691
+ } : undefined
692
+ },
693
+ warnings: 'warnings' in result ? result.warnings : undefined
694
+ }
695
+ };
696
+ }
697
+ throw new Error('Unexpected result format from provider operation');
698
+ }
699
+ catch (error) {
700
+ throw new Error(`Falha ao atualizar repositório: ${error instanceof Error ? error.message : String(error)}`);
701
+ }
702
+ }
703
+ async function handleDeleteRepo(repoName, detection, provider) {
704
+ try {
705
+ // Execute operation on specified provider(s)
706
+ const result = await provider_operation_handler_js_1.ProviderOperationHandler.executeOperation(provider, (providerInstance) => providerInstance.deleteRepository(detection.owner, repoName));
707
+ if (!result.success) {
708
+ const errorMessage = 'message' in result
709
+ ? result.message
710
+ : ('error' in result ? result.error || 'Failed to delete repository' : 'Unknown error');
711
+ throw new Error(errorMessage);
712
+ }
713
+ const deletedAt = new Date().toISOString();
714
+ // Handle single provider result
715
+ if ('provider' in result) {
716
+ return {
717
+ success: true,
718
+ action: 'delete',
719
+ message: `Repositório '${repoName}' removido com sucesso do ${result.provider}`,
720
+ data: {
721
+ repoDeleted: true,
722
+ repoName,
723
+ owner: detection.owner,
724
+ provider: result.provider,
725
+ deletedAt,
726
+ warning: 'Esta ação é irreversível'
727
+ }
728
+ };
729
+ }
730
+ // Handle multi-provider result
731
+ if ('data' in result && typeof result.data === 'object') {
732
+ const multiData = result.data;
733
+ const deletionResults = {};
734
+ if (multiData.github) {
735
+ deletionResults.github = {
736
+ success: multiData.github.success,
737
+ error: multiData.github.error
738
+ };
739
+ }
740
+ if (multiData.gitea) {
741
+ deletionResults.gitea = {
742
+ success: multiData.gitea.success,
743
+ error: multiData.gitea.error
744
+ };
745
+ }
746
+ return {
747
+ success: true,
748
+ action: 'delete',
749
+ message: result.message,
750
+ data: {
751
+ repoDeleted: true,
752
+ repoName,
753
+ owner: detection.owner,
754
+ provider: 'both',
755
+ deletionResults,
756
+ deletedAt,
757
+ warning: 'Esta ação é irreversível',
758
+ warnings: 'warnings' in result ? result.warnings : undefined
759
+ }
760
+ };
761
+ }
762
+ throw new Error('Unexpected result format from provider operation');
763
+ }
764
+ catch (error) {
765
+ throw new Error(`Falha ao remover repositório: ${error instanceof Error ? error.message : String(error)}`);
766
+ }
767
+ }
768
+ async function handleForkRepo(sourceRepo, newRepoName, detection, provider) {
769
+ try {
770
+ // Parse sourceRepo (format: owner/repo)
771
+ const [sourceOwner, sourceRepoName] = sourceRepo.split('/');
772
+ if (!sourceOwner || !sourceRepoName) {
773
+ throw new Error('sourceRepo deve estar no formato "owner/repo"');
774
+ }
775
+ const forkName = newRepoName || sourceRepoName;
776
+ // Execute operation on specified provider(s)
777
+ const result = await provider_operation_handler_js_1.ProviderOperationHandler.executeOperation(provider, (providerInstance) => providerInstance.forkRepository(sourceOwner, sourceRepoName));
778
+ if (!result.success) {
779
+ const errorMessage = 'message' in result
780
+ ? result.message
781
+ : ('error' in result ? result.error || 'Failed to fork repository' : 'Unknown error');
782
+ throw new Error(errorMessage);
783
+ }
784
+ // Handle single provider result
785
+ if ('provider' in result && result.data) {
786
+ return {
787
+ success: true,
788
+ action: 'fork',
789
+ message: `Fork '${forkName}' criado com sucesso de '${sourceRepo}' no ${result.provider}`,
790
+ data: {
791
+ repoForked: true,
792
+ originalRepo: sourceRepo,
793
+ forkName,
794
+ repository: result.data,
795
+ provider: result.provider
796
+ }
797
+ };
798
+ }
799
+ // Handle multi-provider result
800
+ if ('message' in result && typeof result.data === 'object') {
801
+ const multiData = result.data;
802
+ const forkedRepositories = {};
803
+ if (multiData.github?.success && multiData.github.data) {
804
+ forkedRepositories.github = multiData.github.data;
805
+ }
806
+ if (multiData.gitea?.success && multiData.gitea.data) {
807
+ forkedRepositories.gitea = multiData.gitea.data;
808
+ }
809
+ return {
810
+ success: true,
811
+ action: 'fork',
812
+ message: result.message,
813
+ data: {
814
+ repoForked: true,
815
+ originalRepo: sourceRepo,
816
+ forkName,
817
+ repositories: forkedRepositories,
818
+ provider: 'both',
819
+ providerResults: {
820
+ github: multiData.github ? {
821
+ success: multiData.github.success,
822
+ error: multiData.github.error
823
+ } : undefined,
824
+ gitea: multiData.gitea ? {
825
+ success: multiData.gitea.success,
826
+ error: multiData.gitea.error
827
+ } : undefined
828
+ },
829
+ warnings: 'warnings' in result ? result.warnings : undefined
830
+ }
831
+ };
832
+ }
833
+ throw new Error('Unexpected result format from provider operation');
834
+ }
835
+ catch (error) {
836
+ throw new Error(`Falha ao criar fork: ${error instanceof Error ? error.message : String(error)}`);
837
+ }
838
+ }
282
839
  exports.gitWorkflowTool = {
283
840
  name: 'git-workflow',
284
- description: '🔄 WORKFLOW PRINCIPAL - Operações Git integradas: init, commit, sync, status, backup',
841
+ description: '🔄 WORKFLOW COMPLETO - Operações Git locais + gerenciamento completo de repositórios remotos: init, commit, sync, status, backup, create, list, get, update, delete, fork, search',
285
842
  inputSchema,
286
843
  async handler(input) {
287
844
  try {
288
- const { action, projectPath, message, branch, remote } = input;
845
+ const { action, projectPath, provider, message, branch, remote, repoName, description, private: isPrivate, sourceRepo, searchQuery, language, sort, order, page, perPage } = input;
289
846
  if (!projectPath) {
290
847
  throw new Error('projectPath é obrigatório');
291
848
  }
849
+ // Define remote operations that require provider parameter
850
+ const remoteOperations = ['create', 'list', 'get', 'update', 'delete', 'fork', 'search'];
851
+ // Validate provider parameter for remote operations
852
+ if (remoteOperations.includes(action)) {
853
+ if (!provider) {
854
+ const detection = (0, auto_detection_js_1.autoDetect)(projectPath);
855
+ return (0, auto_detection_js_1.createUniversalResponse)(false, action, 'Provider parameter is required for remote operations', detection, 'git-workflow', undefined, {
856
+ code: 'MISSING_PROVIDER_PARAMETER',
857
+ message: 'Provider parameter is required for remote operations',
858
+ cause: 'Provider parameter not provided for remote operation',
859
+ suggestion: 'Add provider parameter with one of: github, gitea, both'
860
+ });
861
+ }
862
+ // Validate provider parameter value
863
+ const providerValidation = configuration_validator_js_1.ConfigurationValidator.validateProvider(provider);
864
+ if (!providerValidation.valid) {
865
+ const detection = (0, auto_detection_js_1.autoDetect)(projectPath);
866
+ return (0, auto_detection_js_1.createUniversalResponse)(false, action, providerValidation.error.message, detection, 'git-workflow', undefined, {
867
+ code: providerValidation.error.code,
868
+ message: providerValidation.error.message,
869
+ cause: 'Invalid provider parameter value',
870
+ suggestion: providerValidation.error.suggestion
871
+ });
872
+ }
873
+ // Validate provider configuration
874
+ const configValidation = configuration_validator_js_1.ConfigurationValidator.validateProviderConfiguration(provider);
875
+ if (!configValidation.valid) {
876
+ const detection = (0, auto_detection_js_1.autoDetect)(projectPath);
877
+ const errorMessage = configuration_validator_js_1.ConfigurationValidator.formatValidationError(configValidation);
878
+ // Create comprehensive error response for configuration issues
879
+ const configError = configValidation.error.configuration;
880
+ const enhancedMessage = configError
881
+ ? `${configValidation.error.message}\n\n${configuration_validator_js_1.ConfigurationValidator.formatValidationError(configValidation)}`
882
+ : configValidation.error.message;
883
+ return (0, auto_detection_js_1.createUniversalResponse)(false, action, enhancedMessage, detection, 'git-workflow', undefined, {
884
+ code: configValidation.error.code,
885
+ message: errorMessage,
886
+ cause: 'Provider configuration validation failed',
887
+ suggestion: configValidation.error.suggestion
888
+ });
889
+ }
890
+ }
292
891
  const detection = (0, auto_detection_js_1.autoDetect)(projectPath);
293
892
  let result;
294
893
  switch (action) {
894
+ // Operações Git locais
295
895
  case 'init':
296
896
  result = await handleInit(projectPath, detection);
297
897
  break;
@@ -313,16 +913,69 @@ exports.gitWorkflowTool = {
313
913
  case 'backup':
314
914
  result = await handleBackup(projectPath, detection);
315
915
  break;
916
+ // Gerenciamento de repositórios remotos
917
+ case 'create':
918
+ if (!repoName) {
919
+ throw new Error('repoName é obrigatório para create');
920
+ }
921
+ result = await handleCreateRepo(repoName, description || '', isPrivate || false, detection, projectPath, provider);
922
+ break;
923
+ case 'list':
924
+ result = await handleListRepos(detection, page, perPage, sort, provider);
925
+ break;
926
+ case 'get':
927
+ if (!repoName) {
928
+ throw new Error('repoName é obrigatório para get');
929
+ }
930
+ result = await handleGetRepo(repoName, detection, provider);
931
+ break;
932
+ case 'search':
933
+ if (!searchQuery) {
934
+ throw new Error('searchQuery é obrigatório para search');
935
+ }
936
+ result = await handleSearchRepos(searchQuery, detection, provider, language, sort, order);
937
+ break;
938
+ case 'update':
939
+ if (!repoName) {
940
+ throw new Error('repoName é obrigatório para update');
941
+ }
942
+ result = await handleUpdateRepo(repoName, detection, provider, description, isPrivate);
943
+ break;
944
+ case 'delete':
945
+ if (!repoName) {
946
+ throw new Error('repoName é obrigatório para delete');
947
+ }
948
+ result = await handleDeleteRepo(repoName, detection, provider);
949
+ break;
950
+ case 'fork':
951
+ if (!sourceRepo) {
952
+ throw new Error('sourceRepo é obrigatório para fork');
953
+ }
954
+ result = await handleForkRepo(sourceRepo, repoName, detection, provider);
955
+ break;
316
956
  default:
317
- throw new Error(`Ação '${action}' não suportada. Use: init, commit, sync, status, backup`);
957
+ throw new Error(`Ação '${action}' não suportada. Use: init, commit, sync, status, backup, create, list, get, update, delete, fork, search`);
318
958
  }
319
959
  return (0, auto_detection_js_1.createUniversalResponse)(result.success, action, result.message, detection, 'git-workflow', result.data);
320
960
  }
321
961
  catch (error) {
322
962
  const detection = (0, auto_detection_js_1.autoDetect)(input.projectPath || '');
323
- return (0, auto_detection_js_1.createUniversalResponse)(false, input.action || 'unknown', error instanceof Error ? error.message : String(error), detection, 'git-workflow', undefined, {
963
+ const errorInstance = error instanceof Error ? error : new Error(String(error));
964
+ // For remote operations, provide comprehensive error handling
965
+ const remoteOperations = ['create', 'list', 'get', 'update', 'delete', 'fork', 'search'];
966
+ if (remoteOperations.includes(input.action) && input.provider) {
967
+ const operationError = operation_error_handler_js_1.OperationErrorHandler.analyzeAndHandleError(errorInstance, input.provider, input.action);
968
+ return (0, auto_detection_js_1.createUniversalResponse)(false, input.action || 'unknown', operationError.message, detection, 'git-workflow', undefined, {
969
+ code: operationError.code,
970
+ message: operation_error_handler_js_1.OperationErrorHandler.formatErrorMessage(operationError),
971
+ cause: operationError.cause,
972
+ suggestion: operationError.solution
973
+ });
974
+ }
975
+ // For local operations, provide generic error handling
976
+ return (0, auto_detection_js_1.createUniversalResponse)(false, input.action || 'unknown', errorInstance.message, detection, 'git-workflow', undefined, {
324
977
  code: 'WORKFLOW_ERROR',
325
- message: error instanceof Error ? error.message : String(error),
978
+ message: errorInstance.message,
326
979
  cause: 'Erro na execução do workflow Git',
327
980
  suggestion: 'Verifique os parâmetros e tente novamente'
328
981
  });