sinapse-ai 1.12.2 → 1.14.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 (244) hide show
  1. package/.claude/CLAUDE.md +2 -2
  2. package/.claude/rules/agent-memory-imports.md +4 -0
  3. package/.sinapse-ai/cli/commands/pro/index.js +8 -48
  4. package/.sinapse-ai/constitution.md +6 -2
  5. package/.sinapse-ai/data/entity-registry.yaml +63 -429
  6. package/.sinapse-ai/development/agents/analyst/MEMORY.md +19 -0
  7. package/.sinapse-ai/development/agents/architect/MEMORY.md +52 -0
  8. package/.sinapse-ai/development/agents/data-engineer/MEMORY.md +55 -0
  9. package/.sinapse-ai/development/agents/developer/MEMORY.md +53 -0
  10. package/.sinapse-ai/development/agents/devops/MEMORY.md +56 -0
  11. package/.sinapse-ai/development/agents/product-lead/MEMORY.md +53 -0
  12. package/.sinapse-ai/development/agents/project-lead/MEMORY.md +53 -0
  13. package/.sinapse-ai/development/agents/quality-gate/MEMORY.md +52 -0
  14. package/.sinapse-ai/development/agents/snps-orqx.md +15 -0
  15. package/.sinapse-ai/development/agents/sprint-lead/MEMORY.md +53 -0
  16. package/.sinapse-ai/development/agents/squad-creator.md +15 -0
  17. package/.sinapse-ai/development/agents/ux/MEMORY.md +21 -0
  18. package/.sinapse-ai/development/templates/chrome-brain/knowledge-base/chrome-brain.md +2 -2
  19. package/.sinapse-ai/infrastructure/scripts/ide-sync/index.js +15 -0
  20. package/.sinapse-ai/infrastructure/scripts/validate-agents.js +159 -8
  21. package/.sinapse-ai/install-manifest.yaml +16 -152
  22. package/AGENTS.md +13 -2
  23. package/CHANGELOG.md +135 -3
  24. package/README.en.md +1 -1
  25. package/README.md +6 -26
  26. package/bin/cli.js +2 -7
  27. package/bin/commands/install.js +19 -257
  28. package/bin/commands/update.js +18 -78
  29. package/bin/lib/command-generator.js +261 -0
  30. package/bin/lib/prompts.js +2 -65
  31. package/bin/modules/chrome-brain-installer.js +2 -1
  32. package/bin/postinstall.js +6 -6
  33. package/docs/getting-started.md +0 -1
  34. package/docs/pt/getting-started.md +1 -1
  35. package/docs/security/dependabot-triage.md +17 -17
  36. package/package.json +6 -3
  37. package/packages/installer/src/wizard/i18n.js +3 -204
  38. package/packages/installer/src/wizard/index.js +1 -1
  39. package/packages/installer/src/wizard/questions.js +5 -368
  40. package/packages/installer/src/wizard/wizard.js +0 -9
  41. package/scripts/generate-install-manifest.js +6 -0
  42. package/scripts/validate-changelog-tags.js +97 -0
  43. package/scripts/validate-no-personal-leaks.js +184 -28
  44. package/scripts/validate-schemas.js +55 -10
  45. package/scripts/validate-story-meta.js +25 -12
  46. package/squads/claude-code-mastery/agents/claude-mastery-chief.md +15 -1
  47. package/squads/claude-code-mastery/agents/config-engineer.md +15 -0
  48. package/squads/claude-code-mastery/agents/hooks-architect.md +27 -20
  49. package/squads/claude-code-mastery/agents/mcp-integrator.md +15 -0
  50. package/squads/claude-code-mastery/agents/project-integrator.md +15 -0
  51. package/squads/claude-code-mastery/agents/roadmap-sentinel.md +15 -0
  52. package/squads/claude-code-mastery/agents/skill-craftsman.md +15 -0
  53. package/squads/claude-code-mastery/agents/swarm-orqx.md +15 -0
  54. package/squads/claude-code-mastery/tasks/audit-setup.md +1 -1
  55. package/squads/squad-animations/agents/animation-interpreter.md +15 -0
  56. package/squads/squad-animations/agents/animation-performance-engineer.md +15 -0
  57. package/squads/squad-animations/agents/animations-orqx.md +13 -0
  58. package/squads/squad-animations/agents/css-motion-artist.md +15 -0
  59. package/squads/squad-animations/agents/generative-particle-engineer.md +15 -0
  60. package/squads/squad-animations/agents/motion-choreographer.md +15 -0
  61. package/squads/squad-animations/agents/scroll-narrative-engineer.md +15 -0
  62. package/squads/squad-animations/agents/shader-artist.md +15 -0
  63. package/squads/squad-animations/agents/threejs-architect.md +15 -0
  64. package/squads/squad-brand/agents/brand-archetype-strategist.md +13 -0
  65. package/squads/squad-brand/agents/brand-auditor.md +15 -0
  66. package/squads/squad-brand/agents/brand-collateral-designer.md +15 -0
  67. package/squads/squad-brand/agents/brand-compiler.md +13 -0
  68. package/squads/squad-brand/agents/brand-creative-engineer.md +15 -0
  69. package/squads/squad-brand/agents/brand-culture-architect.md +15 -0
  70. package/squads/squad-brand/agents/brand-growth-strategist.md +15 -0
  71. package/squads/squad-brand/agents/brand-identity-designer.md +15 -0
  72. package/squads/squad-brand/agents/brand-motion-vfx.md +15 -0
  73. package/squads/squad-brand/agents/brand-naming-specialist.md +15 -0
  74. package/squads/squad-brand/agents/brand-orqx.md +13 -0
  75. package/squads/squad-brand/agents/brand-positioning-strategist.md +15 -0
  76. package/squads/squad-brand/agents/brand-sonic-designer.md +15 -0
  77. package/squads/squad-brand/agents/brand-strategist.md +15 -0
  78. package/squads/squad-brand/agents/brand-system-architect.md +15 -0
  79. package/squads/squad-cloning/agents/agent-forger.md +15 -0
  80. package/squads/squad-cloning/agents/cloning-orqx.md +15 -0
  81. package/squads/squad-cloning/agents/cognitive-extractor.md +15 -0
  82. package/squads/squad-cloning/agents/content-capturer.md +15 -0
  83. package/squads/squad-cloning/agents/kb-architect.md +15 -0
  84. package/squads/squad-cloning/agents/mind-synthesizer.md +15 -0
  85. package/squads/squad-cloning/agents/sop-extractor.md +15 -0
  86. package/squads/squad-cloning/agents/source-hunter.md +13 -0
  87. package/squads/squad-cloning/agents/squad-assembler.md +15 -0
  88. package/squads/squad-commercial/agents/commercial-orqx.md +13 -0
  89. package/squads/squad-commercial/agents/cs-business-auditor.md +15 -0
  90. package/squads/squad-commercial/agents/cs-client-success.md +15 -0
  91. package/squads/squad-commercial/agents/cs-crm-specialist.md +15 -0
  92. package/squads/squad-commercial/agents/cs-funnel-architect.md +15 -0
  93. package/squads/squad-commercial/agents/cs-lead-generation-strategist.md +15 -0
  94. package/squads/squad-commercial/agents/cs-offer-designer.md +15 -0
  95. package/squads/squad-commercial/agents/cs-revops-analyst.md +15 -0
  96. package/squads/squad-commercial/agents/cs-sales-closer.md +13 -0
  97. package/squads/squad-commercial/agents/cs-sales-enablement.md +15 -0
  98. package/squads/squad-content/agents/content-analyst.md +13 -0
  99. package/squads/squad-content/agents/content-engineer.md +15 -0
  100. package/squads/squad-content/agents/content-governor.md +13 -0
  101. package/squads/squad-content/agents/content-orqx.md +13 -0
  102. package/squads/squad-content/agents/editorial-strategist.md +15 -0
  103. package/squads/squad-content/agents/platform-specialist.md +15 -0
  104. package/squads/squad-content/agents/signal-intelligence.md +13 -0
  105. package/squads/squad-copy/agents/ad-copywriter.md +13 -0
  106. package/squads/squad-copy/agents/brand-voice-writer.md +15 -0
  107. package/squads/squad-copy/agents/conversion-writer.md +13 -0
  108. package/squads/squad-copy/agents/copy-editor.md +15 -0
  109. package/squads/squad-copy/agents/copy-orqx.md +13 -0
  110. package/squads/squad-copy/agents/copy-strategist.md +15 -0
  111. package/squads/squad-copy/agents/direct-response-writer.md +15 -0
  112. package/squads/squad-copy/agents/email-sequence-strategist.md +15 -0
  113. package/squads/squad-copy/agents/funnel-copywriter.md +15 -0
  114. package/squads/squad-copy/agents/headline-specialist.md +13 -0
  115. package/squads/squad-copy/agents/long-form-writer.md +15 -0
  116. package/squads/squad-copy/agents/persuasion-psychologist.md +15 -0
  117. package/squads/squad-copy/agents/proof-architect.md +15 -0
  118. package/squads/squad-council/agents/brene-brown.md +13 -0
  119. package/squads/squad-council/agents/charlie-munger.md +13 -0
  120. package/squads/squad-council/agents/council-orqx.md +13 -0
  121. package/squads/squad-council/agents/derek-sivers.md +13 -0
  122. package/squads/squad-council/agents/naval-ravikant.md +13 -0
  123. package/squads/squad-council/agents/patrick-lencioni.md +15 -0
  124. package/squads/squad-council/agents/peter-thiel.md +13 -0
  125. package/squads/squad-council/agents/ray-dalio.md +13 -0
  126. package/squads/squad-council/agents/reid-hoffman.md +13 -0
  127. package/squads/squad-council/agents/simon-sinek.md +15 -0
  128. package/squads/squad-council/agents/yvon-chouinard.md +13 -0
  129. package/squads/squad-courses/agents/assessment-creator.md +15 -0
  130. package/squads/squad-courses/agents/content-writer.md +15 -0
  131. package/squads/squad-courses/agents/courses-orqx.md +15 -0
  132. package/squads/squad-courses/agents/curriculum-designer.md +15 -0
  133. package/squads/squad-courses/agents/launch-strategist.md +15 -0
  134. package/squads/squad-courses/agents/lesson-architect.md +15 -0
  135. package/squads/squad-courses/agents/production-director.md +13 -0
  136. package/squads/squad-courses/agents/slide-designer.md +15 -0
  137. package/squads/squad-cybersecurity/agents/cloud-security-engineer.md +15 -0
  138. package/squads/squad-cybersecurity/agents/compliance-officer.md +15 -0
  139. package/squads/squad-cybersecurity/agents/cyber-orqx.md +15 -0
  140. package/squads/squad-cybersecurity/agents/incident-responder.md +15 -0
  141. package/squads/squad-cybersecurity/agents/network-security-engineer.md +15 -0
  142. package/squads/squad-cybersecurity/agents/penetration-tester.md +15 -0
  143. package/squads/squad-cybersecurity/agents/soc-analyst.md +15 -0
  144. package/squads/squad-cybersecurity/agents/threat-analyst.md +15 -0
  145. package/squads/squad-design/agents/cro-persuasion.md +15 -0
  146. package/squads/squad-design/agents/design-orqx.md +13 -0
  147. package/squads/squad-design/agents/design-system.md +15 -0
  148. package/squads/squad-design/agents/dx-accessibility-specialist.md +15 -0
  149. package/squads/squad-design/agents/dx-design-system-architect.md +15 -0
  150. package/squads/squad-design/agents/dx-frontend-engineer.md +15 -0
  151. package/squads/squad-design/agents/dx-interaction-designer.md +15 -0
  152. package/squads/squad-design/agents/dx-performance-engineer.md +15 -0
  153. package/squads/squad-design/agents/dx-ui-designer.md +15 -0
  154. package/squads/squad-design/agents/dx-ux-strategist.md +15 -0
  155. package/squads/squad-design/agents/platform-aesthetic-director.md +15 -0
  156. package/squads/squad-design/agents/premium-packaging-strategist.md +15 -0
  157. package/squads/squad-design/agents/product-surface-director.md +15 -0
  158. package/squads/squad-design/agents/ux-designer.md +15 -0
  159. package/squads/squad-finance/agents/budget-controller.md +15 -0
  160. package/squads/squad-finance/agents/cost-optimizer.md +15 -0
  161. package/squads/squad-finance/agents/finance-orqx.md +15 -0
  162. package/squads/squad-finance/agents/fiscal-compliance-br.md +15 -0
  163. package/squads/squad-finance/agents/forecast-strategist.md +15 -0
  164. package/squads/squad-finance/agents/pricing-strategist.md +15 -0
  165. package/squads/squad-finance/agents/profitability-analyst.md +15 -0
  166. package/squads/squad-finance/agents/revenue-analyst.md +15 -0
  167. package/squads/squad-growth/agents/ga-analytics-engineer.md +15 -0
  168. package/squads/squad-growth/agents/ga-campaign-analyst.md +15 -0
  169. package/squads/squad-growth/agents/ga-cro-specialist.md +15 -0
  170. package/squads/squad-growth/agents/ga-data-analyst.md +13 -0
  171. package/squads/squad-growth/agents/ga-growth-hacker.md +15 -0
  172. package/squads/squad-growth/agents/ga-seo-strategist.md +15 -0
  173. package/squads/squad-growth/agents/growth-orqx.md +15 -0
  174. package/squads/squad-paidmedia/agents/campaign-analyst.md +15 -0
  175. package/squads/squad-paidmedia/agents/creative-strategist.md +15 -0
  176. package/squads/squad-paidmedia/agents/cro-specialist.md +15 -0
  177. package/squads/squad-paidmedia/agents/google-ads-specialist.md +15 -0
  178. package/squads/squad-paidmedia/agents/meta-ads-specialist.md +15 -0
  179. package/squads/squad-paidmedia/agents/paidmedia-orqx.md +15 -0
  180. package/squads/squad-paidmedia/agents/performance-engineer.md +15 -0
  181. package/squads/squad-paidmedia/agents/pm-creative-performance-analyst.md +15 -0
  182. package/squads/squad-paidmedia/agents/pm-youtube-ads-specialist.md +15 -0
  183. package/squads/squad-product/agents/product-orqx.md +13 -1
  184. package/squads/squad-product/agents/ps-client-product-manager.md +13 -1
  185. package/squads/squad-product/agents/ps-delivery-manager.md +13 -1
  186. package/squads/squad-product/agents/ps-discovery-lead.md +15 -1
  187. package/squads/squad-product/agents/ps-product-analyst.md +15 -1
  188. package/squads/squad-product/agents/ps-product-ops-specialist.md +15 -1
  189. package/squads/squad-product/agents/ps-product-strategist.md +15 -1
  190. package/squads/squad-research/agents/audience-intelligence.md +15 -0
  191. package/squads/squad-research/agents/competitive-intelligence.md +15 -0
  192. package/squads/squad-research/agents/data-synthesizer.md +15 -0
  193. package/squads/squad-research/agents/deep-researcher.md +15 -0
  194. package/squads/squad-research/agents/market-analyst.md +15 -0
  195. package/squads/squad-research/agents/research-orqx.md +15 -0
  196. package/squads/squad-research/agents/trend-forecaster.md +15 -0
  197. package/squads/squad-storytelling/agents/blake-snyder.md +13 -0
  198. package/squads/squad-storytelling/agents/dan-harmon.md +13 -0
  199. package/squads/squad-storytelling/agents/joseph-campbell.md +13 -0
  200. package/squads/squad-storytelling/agents/keith-johnstone.md +13 -0
  201. package/squads/squad-storytelling/agents/kindra-hall.md +15 -0
  202. package/squads/squad-storytelling/agents/marshall-ganz.md +15 -0
  203. package/squads/squad-storytelling/agents/nancy-duarte.md +15 -0
  204. package/squads/squad-storytelling/agents/oren-klaff.md +15 -0
  205. package/squads/squad-storytelling/agents/park-howell.md +13 -0
  206. package/squads/squad-storytelling/agents/storytelling-orqx.md +13 -0
  207. package/.sinapse-ai/core/grounding/README.md +0 -83
  208. package/.sinapse-ai/core/grounding/brand.cjs +0 -29
  209. package/.sinapse-ai/core/grounding/config-loader.cjs +0 -52
  210. package/.sinapse-ai/core/grounding/design-system.cjs +0 -29
  211. package/.sinapse-ai/core/grounding/vault.cjs +0 -36
  212. package/.sinapse-ai/development/scripts/approval-workflow.js +0 -643
  213. package/.sinapse-ai/development/scripts/backup-manager.js +0 -607
  214. package/.sinapse-ai/development/scripts/branch-manager.js +0 -390
  215. package/.sinapse-ai/development/scripts/code-quality-improver.js +0 -1329
  216. package/.sinapse-ai/development/scripts/commit-message-generator.js +0 -850
  217. package/.sinapse-ai/development/scripts/conflict-resolver.js +0 -675
  218. package/.sinapse-ai/development/scripts/dependency-analyzer.js +0 -638
  219. package/.sinapse-ai/development/scripts/diff-generator.js +0 -352
  220. package/.sinapse-ai/development/scripts/git-wrapper.js +0 -462
  221. package/.sinapse-ai/development/scripts/modification-validator.js +0 -555
  222. package/.sinapse-ai/development/scripts/performance-analyzer.js +0 -758
  223. package/.sinapse-ai/development/scripts/refactoring-suggester.js +0 -1148
  224. package/.sinapse-ai/development/scripts/rollback-handler.js +0 -531
  225. package/.sinapse-ai/development/scripts/security-checker.js +0 -359
  226. package/.sinapse-ai/development/scripts/template-engine.js +0 -240
  227. package/.sinapse-ai/development/scripts/template-validator.js +0 -279
  228. package/.sinapse-ai/development/scripts/test-generator.js +0 -844
  229. package/.sinapse-ai/development/scripts/transaction-manager.js +0 -590
  230. package/.sinapse-ai/development/scripts/yaml-validator.js +0 -397
  231. package/.sinapse-ai/hooks/sinapse-brand-grounding.cjs +0 -162
  232. package/.sinapse-ai/hooks/sinapse-ds-grounding.cjs +0 -211
  233. package/.sinapse-ai/hooks/sinapse-vault-grounding.cjs +0 -194
  234. package/bin/lib/register-grounding-hooks.js +0 -145
  235. package/docs/guides/agents/traces/execution-traces.zip +0 -0
  236. package/docs/guides/grounding-setup.md +0 -154
  237. package/docs/guides/workflows/SINAPSE-WORKFLOWS.zip +0 -0
  238. package/packages/installer/src/pro/pro-scaffolder.js +0 -449
  239. package/packages/installer/src/wizard/grounding-config.js +0 -131
  240. package/packages/installer/src/wizard/pro-setup.js +0 -1439
  241. package/packages/installer/templates/README.md +0 -16
  242. package/packages/installer/templates/brand-routing.example.json +0 -12
  243. package/packages/installer/templates/ds-routing.example.json +0 -12
  244. package/packages/installer/templates/vault-routing.example.json +0 -12
@@ -1,675 +0,0 @@
1
- const fs = require('fs').promises;
2
- const path = require('path');
3
- const chalk = require('chalk');
4
- const _diffLib = require('diff');
5
- const inquirer = require('inquirer');
6
- const GitWrapper = require('./git-wrapper');
7
-
8
- /**
9
- * Handles conflict detection and resolution for meta-agent modifications
10
- */
11
- class ConflictResolver {
12
- constructor(options = {}) {
13
- this.git = new GitWrapper(options);
14
- this.rootPath = options.rootPath || process.cwd();
15
- this.strategies = {
16
- 'ours': this.resolveOurs.bind(this),
17
- 'theirs': this.resolveTheirs.bind(this),
18
- 'manual': this.resolveManual.bind(this),
19
- 'auto': this.resolveAuto.bind(this),
20
- 'interactive': this.resolveInteractive.bind(this)
21
- };
22
- }
23
-
24
- /**
25
- * Detect conflicts in the repository
26
- * @returns {Promise<Object>} Conflict information
27
- */
28
- async detectConflicts() {
29
- try {
30
- const conflicts = await this.git.getConflicts();
31
-
32
- if (conflicts.length === 0) {
33
- return {
34
- hasConflicts: false,
35
- files: []
36
- };
37
- }
38
-
39
- const conflictDetails = [];
40
- for (const file of conflicts) {
41
- const content = await fs.readFile(
42
- path.join(this.rootPath, file),
43
- 'utf-8'
44
- );
45
-
46
- const conflictInfo = this.parseConflictMarkers(_content);
47
- conflictDetails.push({
48
- file,
49
- conflicts: conflictInfo.conflicts,
50
- conflictCount: conflictInfo.conflicts.length,
51
- type: this.detectConflictType(file, conflictInfo)
52
- });
53
- }
54
-
55
- return {
56
- hasConflicts: true,
57
- files: conflictDetails,
58
- totalConflicts: conflictDetails.reduce((sum, f) => sum + f.conflictCount, 0)
59
- };
60
- } catch (error) {
61
- console.error(chalk.red(`Error detecting conflicts: ${error.message}`));
62
- return {
63
- hasConflicts: false,
64
- error: error.message
65
- };
66
- }
67
- }
68
-
69
- /**
70
- * Parse conflict markers in file content
71
- * @private
72
- */
73
- parseConflictMarkers(_content) {
74
- const conflicts = [];
75
- const lines = content.split('\n');
76
- let inConflict = false;
77
- let currentConflict = null;
78
- let lineNumber = 0;
79
-
80
- for (const line of lines) {
81
- lineNumber++;
82
-
83
- if (line.startsWith('<<<<<<<')) {
84
- inConflict = true;
85
- currentConflict = {
86
- startLine: lineNumber,
87
- ours: [],
88
- theirs: [],
89
- separator: null,
90
- endLine: null,
91
- branch: line.substring(8).trim()
92
- };
93
- } else if (inConflict && line.startsWith('=======')) {
94
- currentConflict.separator = lineNumber;
95
- } else if (inConflict && line.startsWith('>>>>>>>')) {
96
- currentConflict.endLine = lineNumber;
97
- currentConflict.theirBranch = line.substring(8).trim();
98
- conflicts.push(currentConflict);
99
- inConflict = false;
100
- currentConflict = null;
101
- } else if (inConflict && currentConflict) {
102
- if (currentConflict.separator === null) {
103
- currentConflict.ours.push(line);
104
- } else {
105
- currentConflict.theirs.push(line);
106
- }
107
- }
108
- }
109
-
110
- return { conflicts, totalLines: lineNumber };
111
- }
112
-
113
- /**
114
- * Detect the type of conflict
115
- * @private
116
- */
117
- detectConflictType(file, conflictInfo) {
118
- const ext = path.extname(file);
119
- const conflicts = conflictInfo.conflicts;
120
-
121
- // Check for specific conflict patterns
122
- for (const _conflict of conflicts) {
123
- const oursContent = conflict.ours.join('\n');
124
- const theirsContent = conflict.theirs.join('\n');
125
-
126
- // Whitespace only conflict
127
- if (oursContent.trim() === theirsContent.trim()) {
128
- return 'whitespace';
129
- }
130
-
131
- // Import/require conflict
132
- if ((oursContent.includes('import') || oursContent.includes('require')) &&
133
- (theirsContent.includes('import') || theirsContent.includes('require'))) {
134
- return 'imports';
135
- }
136
-
137
- // Version number conflict
138
- if (oursContent.match(/\d+\.\d+\.\d+/) && theirsContent.match(/\d+\.\d+\.\d+/)) {
139
- return 'version';
140
- }
141
- }
142
-
143
- // File type specific
144
- if (ext === '.json') return 'json';
145
- if (ext === '.yaml' || ext === '.yml') return 'yaml';
146
- if (['.js', '.ts', '.jsx', '.tsx'].includes(ext)) return 'code';
147
- if (ext === '.md') return 'markdown';
148
-
149
- return 'general';
150
- }
151
-
152
- /**
153
- * Resolve conflicts using a specific strategy
154
- * @param {string} strategy - Resolution strategy
155
- * @param {Object} options - Resolution options
156
- * @returns {Promise<Object>} Resolution result
157
- */
158
- async resolveConflicts(strategy = 'interactive', options = {}) {
159
- const conflictInfo = await this.detectConflicts();
160
-
161
- if (!conflictInfo.hasConflicts) {
162
- console.log(chalk.green('✅ No conflicts detected'));
163
- return { success: true, resolved: 0 };
164
- }
165
-
166
- console.log(chalk.yellow(
167
- `Found ${conflictInfo.totalConflicts} conflicts in ${conflictInfo.files.length} files`
168
- ));
169
-
170
- const resolver = this.strategies[strategy];
171
- if (!resolver) {
172
- throw new Error(`Unknown resolution strategy: ${strategy}`);
173
- }
174
-
175
- const results = {
176
- resolved: 0,
177
- failed: 0,
178
- files: []
179
- };
180
-
181
- for (const fileInfo of conflictInfo.files) {
182
- try {
183
- console.log(chalk.blue(`\nResolving conflicts in: ${fileInfo.file}`));
184
- const resolved = await resolver(_fileInfo, options);
185
-
186
- if (resolved.success) {
187
- results.resolved += resolved.conflictsResolved;
188
- results.files.push({
189
- file: fileInfo.file,
190
- status: 'resolved',
191
- method: resolved.method
192
- });
193
- } else {
194
- results.failed++;
195
- results.files.push({
196
- file: fileInfo.file,
197
- status: 'failed',
198
- error: resolved.error
199
- });
200
- }
201
- } catch (error) {
202
- results.failed++;
203
- results.files.push({
204
- file: fileInfo.file,
205
- status: 'error',
206
- error: error.message
207
- });
208
- }
209
- }
210
-
211
- return results;
212
- }
213
-
214
- /**
215
- * Resolve using 'ours' strategy (keep current branch changes)
216
- * @private
217
- */
218
- async resolveOurs(_fileInfo) {
219
- try {
220
- await this.git.execGit(`checkout --ours "${fileInfo.file}"`);
221
- await this.git.execGit(`add "${fileInfo.file}"`);
222
-
223
- return {
224
- success: true,
225
- conflictsResolved: fileInfo.conflictCount,
226
- method: 'ours'
227
- };
228
- } catch (error) {
229
- return {
230
- success: false,
231
- error: error.message
232
- };
233
- }
234
- }
235
-
236
- /**
237
- * Resolve using 'theirs' strategy (keep incoming branch changes)
238
- * @private
239
- */
240
- async resolveTheirs(_fileInfo) {
241
- try {
242
- await this.git.execGit(`checkout --theirs "${fileInfo.file}"`);
243
- await this.git.execGit(`add "${fileInfo.file}"`);
244
-
245
- return {
246
- success: true,
247
- conflictsResolved: fileInfo.conflictCount,
248
- method: 'theirs'
249
- };
250
- } catch (error) {
251
- return {
252
- success: false,
253
- error: error.message
254
- };
255
- }
256
- }
257
-
258
- /**
259
- * Resolve conflicts manually by editing the file
260
- * @private
261
- */
262
- async resolveManual(_fileInfo) {
263
- const filePath = path.join(this.rootPath, fileInfo.file);
264
- const content = await fs.readFile(filePath, 'utf-8');
265
-
266
- console.log(chalk.yellow(
267
- `Manual resolution required for ${fileInfo.file}`
268
- ));
269
- console.log(chalk.gray(
270
- 'Edit the file to resolve conflicts, then mark as resolved'
271
- ));
272
-
273
- // In a real implementation, this would open an editor
274
- // For now, we'll return a message
275
- return {
276
- success: false,
277
- error: 'Manual resolution required',
278
- instruction: `Edit ${filePath} and run: git add "${fileInfo.file}"`
279
- };
280
- }
281
-
282
- /**
283
- * Automatically resolve conflicts based on type
284
- * @private
285
- */
286
- async resolveAuto(_fileInfo) {
287
- const filePath = path.join(this.rootPath, fileInfo.file);
288
- const content = await fs.readFile(filePath, 'utf-8');
289
-
290
- let resolved = content;
291
- let resolvedCount = 0;
292
-
293
- switch (fileInfo.type) {
294
- case 'whitespace':
295
- // For whitespace conflicts, keep theirs
296
- resolved = await this.autoResolveWhitespace(_content, fileInfo);
297
- resolvedCount = fileInfo.conflictCount;
298
- break;
299
-
300
- case 'imports':
301
- // For import conflicts, merge both
302
- resolved = await this.autoResolveImports(_content, fileInfo);
303
- resolvedCount = fileInfo.conflictCount;
304
- break;
305
-
306
- case 'version':
307
- // For version conflicts, keep higher version
308
- resolved = await this.autoResolveVersion(_content, fileInfo);
309
- resolvedCount = fileInfo.conflictCount;
310
- break;
311
-
312
- case 'json':
313
- // For JSON conflicts, attempt to merge
314
- resolved = await this.autoResolveJSON(_content, fileInfo);
315
- resolvedCount = fileInfo.conflictCount;
316
- break;
317
-
318
- default:
319
- // Can't auto-resolve
320
- return {
321
- success: false,
322
- error: `Cannot auto-resolve ${fileInfo.type} conflicts`
323
- };
324
- }
325
-
326
- // Write resolved content
327
- await fs.writeFile(filePath, resolved);
328
- await this.git.execGit(`add "${fileInfo.file}"`);
329
-
330
- return {
331
- success: true,
332
- conflictsResolved: resolvedCount,
333
- method: `auto-${fileInfo.type}`
334
- };
335
- }
336
-
337
- /**
338
- * Interactive conflict resolution
339
- * @private
340
- */
341
- async resolveInteractive(_fileInfo) {
342
- const filePath = path.join(this.rootPath, fileInfo.file);
343
- const content = await fs.readFile(filePath, 'utf-8');
344
- const conflicts = this.parseConflictMarkers(_content).conflicts;
345
-
346
- let resolvedContent = content;
347
- let resolvedCount = 0;
348
-
349
- console.log(chalk.blue(`\nResolving ${fileInfo.file} (${conflicts.length} conflicts)`));
350
-
351
- for (let i = 0; i < conflicts.length; i++) {
352
- const _conflict = conflicts[i];
353
- console.log(chalk.yellow(`\nConflict ${i + 1}/${conflicts.length}:`));
354
-
355
- // Show conflict preview
356
- console.log(chalk.red('<<<< OURS:'));
357
- console.log(conflict.ours.slice(0, 5).join('\n'));
358
- if (conflict.ours.length > 5) console.log(chalk.gray('...'));
359
-
360
- console.log(chalk.green('\n>>>> THEIRS:'));
361
- console.log(conflict.theirs.slice(0, 5).join('\n'));
362
- if (conflict.theirs.length > 5) console.log(chalk.gray('...'));
363
-
364
- const { resolution } = await inquirer.prompt([{
365
- type: 'list',
366
- name: 'resolution',
367
- message: 'How to resolve this conflict?',
368
- choices: [
369
- { name: 'Keep ours (current branch)', value: 'ours' },
370
- { name: 'Keep theirs (incoming)', value: 'theirs' },
371
- { name: 'Keep both (ours first)', value: 'both-ours' },
372
- { name: 'Keep both (theirs first)', value: 'both-theirs' },
373
- { name: 'Custom merge', value: 'custom' },
374
- { name: 'Skip this conflict', value: 'skip' }
375
- ]
376
- }]);
377
-
378
- if (resolution !== 'skip') {
379
- resolvedContent = await this.applyResolution(
380
- resolvedContent,
381
- _conflict,
382
- resolution
383
- );
384
- resolvedCount++;
385
- }
386
- }
387
-
388
- if (resolvedCount > 0) {
389
- await fs.writeFile(filePath, resolvedContent);
390
- await this.git.execGit(`add "${fileInfo.file}"`);
391
- }
392
-
393
- return {
394
- success: true,
395
- conflictsResolved: resolvedCount,
396
- method: 'interactive'
397
- };
398
- }
399
-
400
- /**
401
- * Apply a specific resolution to content
402
- * @private
403
- */
404
- async applyResolution(_content, _conflict, resolution) {
405
- const lines = content.split('\n');
406
- let newLines = [];
407
- let skipUntil = null;
408
-
409
- for (let i = 0; i < lines.length; i++) {
410
- if (skipUntil && i < skipUntil) continue;
411
-
412
- if (i === conflict.startLine - 1) {
413
- switch (resolution) {
414
- case 'ours':
415
- newLines.push(...conflict.ours);
416
- break;
417
- case 'theirs':
418
- newLines.push(...conflict.theirs);
419
- break;
420
- case 'both-ours':
421
- newLines.push(...conflict.ours);
422
- newLines.push(...conflict.theirs);
423
- break;
424
- case 'both-theirs':
425
- newLines.push(...conflict.theirs);
426
- newLines.push(...conflict.ours);
427
- break;
428
- case 'custom':
429
- const { custom } = await inquirer.prompt([{
430
- type: 'editor',
431
- name: 'custom',
432
- message: 'Enter custom resolution:',
433
- default: conflict.ours.join('\n')
434
- }]);
435
- newLines.push(...custom.split('\n'));
436
- break;
437
- }
438
- skipUntil = conflict.endLine;
439
- } else {
440
- newLines.push(lines[i]);
441
- }
442
- }
443
-
444
- return newLines.join('\n');
445
- }
446
-
447
- /**
448
- * Auto-resolve whitespace conflicts
449
- * @private
450
- */
451
- async autoResolveWhitespace(_content, fileInfo) {
452
- // Remove conflict markers and keep theirs (usually has correct formatting)
453
- let resolved = content;
454
-
455
- for (const _conflict of fileInfo.conflicts) {
456
- const pattern = new RegExp(
457
- `<<<<<<<[^\\n]*\\n[\\s\\S]*?=======\\n([\\s\\S]*?)>>>>>>>[^\\n]*\\n`,
458
- 'g'
459
- );
460
- resolved = resolved.replace(pattern, '$1');
461
- }
462
-
463
- return resolved;
464
- }
465
-
466
- /**
467
- * Auto-resolve import conflicts
468
- * @private
469
- */
470
- async autoResolveImports(_content, fileInfo) {
471
- // Merge imports from both sides, removing duplicates
472
- const imports = new Set();
473
-
474
- for (const _conflict of fileInfo.conflicts) {
475
- // Extract imports from both sides
476
- const oursImports = conflict.ours
477
- .filter(line => line.includes('import') || line.includes('require'))
478
- .map(line => line.trim());
479
-
480
- const theirsImports = conflict.theirs
481
- .filter(line => line.includes('import') || line.includes('require'))
482
- .map(line => line.trim());
483
-
484
- // Add all unique imports
485
- [...oursImports, ...theirsImports].forEach(imp => imports.add(imp));
486
- }
487
-
488
- // Replace conflicts with merged imports
489
- let resolved = content;
490
- for (const _conflict of fileInfo.conflicts) {
491
- const pattern = new RegExp(
492
- `<<<<<<<[^\\n]*\\n[\\s\\S]*?>>>>>>>[^\\n]*\\n`,
493
- 'g'
494
- );
495
- resolved = resolved.replace(pattern, Array.from(imports).join('\n') + '\n');
496
- }
497
-
498
- return resolved;
499
- }
500
-
501
- /**
502
- * Auto-resolve version conflicts
503
- * @private
504
- */
505
- async autoResolveVersion(_content, fileInfo) {
506
- let resolved = content;
507
-
508
- for (const _conflict of fileInfo.conflicts) {
509
- const oursVersion = conflict.ours.join('').match(/(\d+)\.(\d+)\.(\d+)/);
510
- const theirsVersion = conflict.theirs.join('').match(/(\d+)\.(\d+)\.(\d+)/);
511
-
512
- if (oursVersion && theirsVersion) {
513
- // Compare versions and keep higher
514
- const ours = oursVersion.slice(1, 4).map(Number);
515
- const theirs = theirsVersion.slice(1, 4).map(Number);
516
-
517
- let useTheirs = false;
518
- for (let i = 0; i < 3; i++) {
519
- if (theirs[i] > ours[i]) {
520
- useTheirs = true;
521
- break;
522
- } else if (ours[i] > theirs[i]) {
523
- break;
524
- }
525
- }
526
-
527
- const pattern = new RegExp(
528
- `<<<<<<<[^\\n]*\\n[\\s\\S]*?=======\\n([\\s\\S]*?)>>>>>>>[^\\n]*\\n`
529
- );
530
-
531
- if (useTheirs) {
532
- resolved = resolved.replace(pattern, '$1');
533
- } else {
534
- resolved = resolved.replace(pattern, conflict.ours.join('\n') + '\n');
535
- }
536
- }
537
- }
538
-
539
- return resolved;
540
- }
541
-
542
- /**
543
- * Auto-resolve JSON conflicts
544
- * @private
545
- */
546
- async autoResolveJSON(_content, fileInfo) {
547
- try {
548
- // Try to parse and merge JSON objects
549
- const oursMatch = content.match(/<<<<<<<[^{]*({[\s\S]*?})[\s\S]*?=======/);
550
- const theirsMatch = content.match(/=======[\s\S]*?({[\s\S]*?})[\s\S]*?>>>>>>>/);
551
-
552
- if (oursMatch && theirsMatch) {
553
- const oursObj = JSON.parse(oursMatch[1]);
554
- const theirsObj = JSON.parse(theirsMatch[1]);
555
-
556
- // Deep merge objects
557
- const merged = this.deepMerge(oursObj, theirsObj);
558
-
559
- // Replace entire file with merged JSON
560
- return JSON.stringify(merged, null, 2);
561
- }
562
- } catch (error) {
563
- console.error(chalk.red('Failed to auto-resolve JSON:', error.message));
564
- }
565
-
566
- // Fallback to manual resolution
567
- return content;
568
- }
569
-
570
- /**
571
- * Deep merge two objects
572
- * @private
573
- */
574
- deepMerge(obj1, obj2) {
575
- const result = { ...obj1 };
576
-
577
- for (const key in obj2) {
578
- if (obj2.hasOwnProperty(key)) {
579
- if (typeof obj2[key] === 'object' && !Array.isArray(obj2[key]) &&
580
- obj1[key] && typeof obj1[key] === 'object') {
581
- result[key] = this.deepMerge(obj1[key], obj2[key]);
582
- } else {
583
- result[key] = obj2[key];
584
- }
585
- }
586
- }
587
-
588
- return result;
589
- }
590
-
591
- /**
592
- * Generate conflict report
593
- * @returns {Promise<Object>} Conflict report
594
- */
595
- async generateConflictReport() {
596
- const conflictInfo = await this.detectConflicts();
597
-
598
- if (!conflictInfo.hasConflicts) {
599
- return {
600
- summary: 'No conflicts detected',
601
- details: []
602
- };
603
- }
604
-
605
- const report = {
606
- summary: `${conflictInfo.totalConflicts} conflicts in ${conflictInfo.files.length} files`,
607
- timestamp: new Date().toISOString(),
608
- details: conflictInfo.files.map(file => ({
609
- file: file.file,
610
- type: file.type,
611
- conflicts: file.conflictCount,
612
- preview: file.conflicts.map(c => ({
613
- lines: `${c.startLine}-${c.endLine}`,
614
- oursPreview: c.ours.slice(0, 2).join('\n'),
615
- theirsPreview: c.theirs.slice(0, 2).join('\n')
616
- }))
617
- })),
618
- recommendations: this.generateRecommendations(conflictInfo)
619
- };
620
-
621
- return report;
622
- }
623
-
624
- /**
625
- * Generate resolution recommendations
626
- * @private
627
- */
628
- generateRecommendations(conflictInfo) {
629
- const recommendations = [];
630
- const types = {};
631
-
632
- // Count conflict types
633
- conflictInfo.files.forEach(file => {
634
- types[file.type] = (types[file.type] || 0) + file.conflictCount;
635
- });
636
-
637
- // Generate recommendations based on types
638
- if (types.whitespace > 0) {
639
- recommendations.push({
640
- type: 'whitespace',
641
- suggestion: 'Use auto-resolution for whitespace conflicts',
642
- command: "resolver.resolveConflicts('auto', { type: 'whitespace' })"
643
- });
644
- }
645
-
646
- if (types.imports > 0) {
647
- recommendations.push({
648
- type: 'imports',
649
- suggestion: 'Merge import statements from both branches',
650
- command: "resolver.resolveConflicts('auto', { type: 'imports' })"
651
- });
652
- }
653
-
654
- if (types.version > 0) {
655
- recommendations.push({
656
- type: 'version',
657
- suggestion: 'Keep the higher version number',
658
- command: "resolver.resolveConflicts('auto', { type: 'version' })"
659
- });
660
- }
661
-
662
- // General recommendation
663
- if (conflictInfo.totalConflicts > 10) {
664
- recommendations.push({
665
- type: 'general',
666
- suggestion: 'Consider reviewing branch merge strategy',
667
- command: 'Use smaller, more focused branches'
668
- });
669
- }
670
-
671
- return recommendations;
672
- }
673
- }
674
-
675
- module.exports = ConflictResolver;