n2b 0.5.1 → 2.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.
- checksums.yaml +4 -4
- data/README.md +635 -111
- data/bin/branch-audit.sh +397 -0
- data/bin/n2b-diff +5 -0
- data/bin/n2b-test-github +22 -0
- data/bin/n2b-test-jira +17 -14
- data/lib/n2b/base.rb +207 -37
- data/lib/n2b/cli.rb +159 -441
- data/lib/n2b/github_client.rb +391 -0
- data/lib/n2b/jira_client.rb +576 -17
- data/lib/n2b/llm/claude.rb +7 -20
- data/lib/n2b/llm/gemini.rb +9 -8
- data/lib/n2b/llm/open_ai.rb +27 -21
- data/lib/n2b/merge_cli.rb +2329 -0
- data/lib/n2b/merge_conflict_parser.rb +70 -0
- data/lib/n2b/message_utils.rb +59 -0
- data/lib/n2b/template_engine.rb +105 -0
- data/lib/n2b/templates/diff_json_instruction.txt +27 -0
- data/lib/n2b/templates/diff_system_prompt.txt +43 -0
- data/lib/n2b/templates/github_comment.txt +67 -0
- data/lib/n2b/templates/jira_comment.txt +74 -0
- data/lib/n2b/templates/merge_conflict_prompt.txt +20 -0
- data/lib/n2b/version.rb +1 -1
- data/lib/n2b.rb +3 -0
- metadata +38 -6
@@ -0,0 +1,70 @@
|
|
1
|
+
module N2B
|
2
|
+
# Parses files containing Git or Mercurial merge conflict markers.
|
3
|
+
# Returns an array of ConflictBlock objects with context information.
|
4
|
+
class MergeConflictParser
|
5
|
+
ConflictBlock = Struct.new(
|
6
|
+
:start_line, :end_line,
|
7
|
+
:base_content, :incoming_content,
|
8
|
+
:context_before, :context_after,
|
9
|
+
:base_label, :incoming_label,
|
10
|
+
keyword_init: true
|
11
|
+
)
|
12
|
+
|
13
|
+
DEFAULT_CONTEXT_LINES = 10
|
14
|
+
|
15
|
+
def initialize(context_lines: DEFAULT_CONTEXT_LINES)
|
16
|
+
@context_lines = context_lines
|
17
|
+
end
|
18
|
+
|
19
|
+
def parse(file_path)
|
20
|
+
raise ArgumentError, "File not found: #{file_path}" unless File.exist?(file_path)
|
21
|
+
|
22
|
+
lines = File.readlines(file_path, chomp: true)
|
23
|
+
blocks = []
|
24
|
+
i = 0
|
25
|
+
while i < lines.length
|
26
|
+
line = lines[i]
|
27
|
+
unless line.start_with?('<<<<<<<')
|
28
|
+
i += 1
|
29
|
+
next
|
30
|
+
end
|
31
|
+
|
32
|
+
start_line = i + 1
|
33
|
+
base_label = line.sub('<<<<<<<', '').strip
|
34
|
+
i += 1
|
35
|
+
base_lines = []
|
36
|
+
while i < lines.length && !lines[i].start_with?('=======')
|
37
|
+
base_lines << lines[i]
|
38
|
+
i += 1
|
39
|
+
end
|
40
|
+
i += 1 # skip ======= line
|
41
|
+
incoming_lines = []
|
42
|
+
while i < lines.length && !lines[i].start_with?('>>>>>>>')
|
43
|
+
incoming_lines << lines[i]
|
44
|
+
i += 1
|
45
|
+
end
|
46
|
+
incoming_label = lines[i].sub('>>>>>>>', '').strip if i < lines.length
|
47
|
+
end_line = i + 1
|
48
|
+
|
49
|
+
context_before_start = [start_line - @context_lines - 1, 0].max
|
50
|
+
context_before = lines[context_before_start...(start_line - 1)].join("\n")
|
51
|
+
context_after_end = [end_line + @context_lines - 1, lines.length - 1].min
|
52
|
+
context_after = lines[(end_line)..context_after_end].join("\n")
|
53
|
+
|
54
|
+
blocks << ConflictBlock.new(
|
55
|
+
start_line: start_line,
|
56
|
+
end_line: end_line,
|
57
|
+
base_content: base_lines.join("\n"),
|
58
|
+
incoming_content: incoming_lines.join("\n"),
|
59
|
+
context_before: context_before,
|
60
|
+
context_after: context_after,
|
61
|
+
base_label: base_label,
|
62
|
+
incoming_label: incoming_label
|
63
|
+
)
|
64
|
+
i += 1
|
65
|
+
end
|
66
|
+
|
67
|
+
blocks
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module N2B
|
2
|
+
module MessageUtils
|
3
|
+
MAX_MESSAGE_LENGTH = 500
|
4
|
+
TRUNCATION_NOTICE = "... (truncated)"
|
5
|
+
|
6
|
+
# Validates the message length.
|
7
|
+
# Truncates if it exceeds MAX_MESSAGE_LENGTH.
|
8
|
+
def self.validate_message(message_str)
|
9
|
+
return nil if message_str.nil?
|
10
|
+
# Ensure message is a string before calling length
|
11
|
+
message = String(message_str)
|
12
|
+
if message.length > MAX_MESSAGE_LENGTH
|
13
|
+
return message[0...(MAX_MESSAGE_LENGTH - TRUNCATION_NOTICE.length)] + TRUNCATION_NOTICE
|
14
|
+
end
|
15
|
+
message
|
16
|
+
end
|
17
|
+
|
18
|
+
# Performs basic sanitization on the message.
|
19
|
+
def self.sanitize_message(message_str)
|
20
|
+
return nil if message_str.nil?
|
21
|
+
message = String(message_str) # Ensure it's a string
|
22
|
+
|
23
|
+
# Strip leading/trailing whitespace
|
24
|
+
sanitized = message.strip
|
25
|
+
|
26
|
+
# Replace triple backticks with single backticks to prevent code block formatting issues in prompts
|
27
|
+
sanitized.gsub!('```', '`')
|
28
|
+
|
29
|
+
# Remove multiple consecutive newlines, leaving only single newlines
|
30
|
+
# This helps prevent prompt injection or excessive spacing.
|
31
|
+
sanitized.gsub!(/\n{2,}/, "\n")
|
32
|
+
|
33
|
+
# Example: Escape specific control characters if needed, e.g., null bytes
|
34
|
+
# sanitized.gsub!(/\x00/, '') # Remove null bytes
|
35
|
+
|
36
|
+
# Add more sanitization rules here as needed, e.g.:
|
37
|
+
# - Removing or escaping other characters that might break formatting or cause security issues.
|
38
|
+
# - For now, keeping it relatively simple.
|
39
|
+
|
40
|
+
sanitized
|
41
|
+
end
|
42
|
+
|
43
|
+
# Logs the message to STDOUT.
|
44
|
+
# level can be :info, :debug, :warn, :error
|
45
|
+
def self.log_message(message, level = :info)
|
46
|
+
return if message.nil? || message.strip.empty?
|
47
|
+
|
48
|
+
prefix = case level
|
49
|
+
when :debug then "[N2B Message DEBUG]"
|
50
|
+
when :warn then "[N2B Message WARN]"
|
51
|
+
when :error then "[N2B Message ERROR]"
|
52
|
+
else "[N2B Message INFO]" # Default to info
|
53
|
+
end
|
54
|
+
|
55
|
+
output_stream = (level == :error || level == :warn) ? $stderr : $stdout
|
56
|
+
output_stream.puts "#{prefix} #{message}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module N2B
|
2
|
+
class TemplateEngine
|
3
|
+
def initialize(template, data)
|
4
|
+
@template = template
|
5
|
+
@data = data
|
6
|
+
end
|
7
|
+
|
8
|
+
def render
|
9
|
+
result = @template.dup
|
10
|
+
|
11
|
+
# Process loops first (they can contain variables)
|
12
|
+
result = process_loops(result)
|
13
|
+
|
14
|
+
# Process conditionals
|
15
|
+
result = process_conditionals(result)
|
16
|
+
|
17
|
+
# Process simple variables
|
18
|
+
result = process_variables(result)
|
19
|
+
|
20
|
+
result
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def process_loops(content)
|
26
|
+
# Match {#each array_name} ... {/each}
|
27
|
+
content.gsub(/\{#each\s+(\w+)\}(.*?)\{\/each\}/m) do |match|
|
28
|
+
array_name = $1
|
29
|
+
loop_content = $2
|
30
|
+
array_data = @data[array_name] || @data[array_name.to_sym] || []
|
31
|
+
|
32
|
+
if array_data.is_a?(Array)
|
33
|
+
array_data.map do |item|
|
34
|
+
item_content = loop_content.dup
|
35
|
+
|
36
|
+
# Process conditionals within the loop context
|
37
|
+
if item.is_a?(Hash)
|
38
|
+
# Create temporary data context with item data
|
39
|
+
temp_data = @data.merge(item)
|
40
|
+
temp_engine = TemplateEngine.new(item_content, temp_data)
|
41
|
+
item_content = temp_engine.send(:process_conditionals, item_content)
|
42
|
+
|
43
|
+
# Replace item variables like {description}, {file_reference}
|
44
|
+
item.each do |key, value|
|
45
|
+
item_content.gsub!(/\{#{key}\}/, value.to_s)
|
46
|
+
end
|
47
|
+
else
|
48
|
+
# If item is a string, replace {.} with the item itself
|
49
|
+
item_content.gsub!(/\{\.?\}/, item.to_s)
|
50
|
+
end
|
51
|
+
|
52
|
+
item_content
|
53
|
+
end.join("")
|
54
|
+
else
|
55
|
+
""
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def process_conditionals(content)
|
61
|
+
# Match {#if condition} ... {#else} ... {/if} or {#if condition} ... {/if}
|
62
|
+
content.gsub(/\{#if\s+(.+?)\}(.*?)(?:\{#else\}(.*?))?\{\/if\}/m) do |match|
|
63
|
+
condition = $1.strip
|
64
|
+
if_content = $2
|
65
|
+
else_content = $3 || ""
|
66
|
+
|
67
|
+
if evaluate_condition(condition)
|
68
|
+
if_content
|
69
|
+
else
|
70
|
+
else_content
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def process_variables(content)
|
76
|
+
# Replace {variable_name} with actual values
|
77
|
+
content.gsub(/\{(\w+)\}/) do |match|
|
78
|
+
var_name = $1
|
79
|
+
value = @data[var_name] || @data[var_name.to_sym]
|
80
|
+
value.to_s
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def evaluate_condition(condition)
|
85
|
+
# Handle conditions like: status == 'IMPLEMENTED'
|
86
|
+
if condition.match(/(\w+)\s*(==|!=)\s*['"]([^'"]+)['"]/)
|
87
|
+
var_name = $1
|
88
|
+
operator = $2
|
89
|
+
expected_value = $3
|
90
|
+
actual_value = @data[var_name] || @data[var_name.to_sym]
|
91
|
+
|
92
|
+
case operator
|
93
|
+
when '=='
|
94
|
+
actual_value.to_s == expected_value
|
95
|
+
when '!='
|
96
|
+
actual_value.to_s != expected_value
|
97
|
+
end
|
98
|
+
else
|
99
|
+
# Simple boolean check
|
100
|
+
var_value = @data[condition] || @data[condition.to_sym]
|
101
|
+
!!var_value
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
CRITICAL: Return ONLY a valid JSON object.
|
2
|
+
Do not include any explanatory text before or after the JSON.
|
3
|
+
Each error and improvement should include specific file paths and line numbers.
|
4
|
+
|
5
|
+
The JSON object must contain the following keys:
|
6
|
+
- "summary": (string) Brief overall description of the changes.
|
7
|
+
- "ticket_implementation_summary": (string) A concise summary of what was implemented or achieved in relation to the ticket's goals, based *only* on the provided diff. This is for developer status updates and Jira comments.
|
8
|
+
- "errors": (list of strings) Potential bugs or issues found.
|
9
|
+
- "improvements": (list of strings) Suggestions for code quality, style, performance, or security.
|
10
|
+
- "test_coverage": (string) Assessment of test coverage for the changes.
|
11
|
+
- "requirements_evaluation": (string, include only if requirements were provided in the prompt) Evaluation of how the changes meet the provided requirements.
|
12
|
+
|
13
|
+
Example format:
|
14
|
+
{
|
15
|
+
"summary": "Refactored the user authentication module and added password complexity checks.",
|
16
|
+
"ticket_implementation_summary": "Implemented the core logic for user password updates and strengthened security by adding complexity validation as per the ticket's primary goal. Some UI elements are pending.",
|
17
|
+
"errors": [
|
18
|
+
"lib/example.rb line 42: Potential null pointer exception when accessing user.name without checking if user is nil.",
|
19
|
+
"src/main.js lines 15-20: Missing error handling for async operation."
|
20
|
+
],
|
21
|
+
"improvements": [
|
22
|
+
"lib/example.rb line 30: Consider using a constant for the magic number 42.",
|
23
|
+
"src/utils.py lines 5-10: This method could be simplified using list comprehension."
|
24
|
+
],
|
25
|
+
"test_coverage": "Good: New functionality in lib/example.rb has corresponding tests in test/example_test.rb. Missing: No tests for error handling edge cases in the new validation method.",
|
26
|
+
"requirements_evaluation": "✅ IMPLEMENTED: User authentication feature is fully implemented in auth.rb. ⚠️ PARTIALLY IMPLEMENTED: Error handling is present but lacks specific error codes. ❌ NOT IMPLEMENTED: Email notifications are not addressed in this diff."
|
27
|
+
}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
You are a senior software developer reviewing a code diff.
|
3
|
+
|
4
|
+
Your task is to provide a constructive and detailed analysis of the changes.
|
5
|
+
Focus on identifying potential bugs, suggesting improvements in code quality, style, performance, and security.
|
6
|
+
Also, provide a concise summary of the changes at the beginning.
|
7
|
+
|
8
|
+
Important guidelines for your review:
|
9
|
+
• When referring to specific issues or improvements, always include:
|
10
|
+
• The exact file path (e.g., lib/n2b/cli.rb)
|
11
|
+
• The specific line numbers or line ranges (e.g., “line 42” or “lines 15-20”)
|
12
|
+
• The exact code snippet you’re referring to when possible
|
13
|
+
This helps the recipient quickly locate and understand the issues you identify.
|
14
|
+
• Be pragmatic and balanced:
|
15
|
+
• Highlight genuinely critical issues, but avoid excessive speculation or alarmism.
|
16
|
+
• Only flag a security or architectural problem as high-priority if there is clear evidence or reasonable suspicion based on the diff and provided context.
|
17
|
+
• If you notice patterns that could be problematic (e.g., use of deprecated libraries or unclear data handling), mention them, but avoid assuming issues in unseen code unless the context clearly suggests a risk.
|
18
|
+
• Limit your review to the provided context:
|
19
|
+
• Do not assume missing methods or classes are absent or incorrectly implemented if they are simply not visible in the diff.
|
20
|
+
• Focus your analysis on the code changes and their direct surroundings.
|
21
|
+
• If code relies on methods or classes not included in the diff, you can briefly note that the implementation or contract is not visible, but do not speculate about their correctness unless the usage is clearly problematic.
|
22
|
+
|
23
|
+
Special Focus: Test Coverage
|
24
|
+
• Pay special attention to whether the developer has provided adequate test coverage for the changes:
|
25
|
+
• Look for new test files or modifications to existing test files.
|
26
|
+
• Check if new functionality is covered by corresponding tests.
|
27
|
+
• Evaluate if edge cases and error conditions are tested.
|
28
|
+
• Assess if the tests are meaningful and comprehensive.
|
29
|
+
• Note any missing test coverage that should reasonably be added.
|
30
|
+
|
31
|
+
Tone and Focus
|
32
|
+
• Be clear, direct, and actionable, but keep a professional and supportive tone.
|
33
|
+
• Prioritize feedback on issues that would materially affect the codebase, such as maintainability, correctness, reliability, and realistic security concerns.
|
34
|
+
• Encourage improvements, but avoid nitpicking on trivial or subjective style points unless they significantly affect readability or consistency.
|
35
|
+
|
36
|
+
⸻
|
37
|
+
|
38
|
+
Summary:
|
39
|
+
Provide a balanced, practical review of the visible code diff, focusing on genuine issues and actionable improvements. Avoid speculation about unseen code, and maintain a pragmatic and professional approach, especially regarding potential security concerns and architectural risks.
|
40
|
+
|
41
|
+
⸻
|
42
|
+
|
43
|
+
Let me know if you want any additional points, or further simplification!
|
@@ -0,0 +1,67 @@
|
|
1
|
+
### N2B Code Analysis Report
|
2
|
+
|
3
|
+
**Implementation Summary**
|
4
|
+
{implementation_summary}
|
5
|
+
|
6
|
+
{{#if custom_analysis_focus}}
|
7
|
+
---
|
8
|
+
|
9
|
+
**Custom Analysis Focus**
|
10
|
+
> {{custom_analysis_focus}}
|
11
|
+
{{/if}}
|
12
|
+
---
|
13
|
+
|
14
|
+
{#if critical_errors_empty}
|
15
|
+
_No critical issues found._
|
16
|
+
{#else}
|
17
|
+
**Critical Issues**
|
18
|
+
{#each critical_errors}
|
19
|
+
- {file_reference} - {description}
|
20
|
+
{/each}
|
21
|
+
{/if}
|
22
|
+
|
23
|
+
{#if important_errors_empty}
|
24
|
+
_No important issues found._
|
25
|
+
{#else}
|
26
|
+
**Important Issues**
|
27
|
+
{#each important_errors}
|
28
|
+
- {file_reference} - {description}
|
29
|
+
{/each}
|
30
|
+
{/if}
|
31
|
+
|
32
|
+
{#if improvements_empty}
|
33
|
+
_No suggested improvements._
|
34
|
+
{#else}
|
35
|
+
**Improvements**
|
36
|
+
{#each improvements}
|
37
|
+
- {file_reference} - {description}
|
38
|
+
{/each}
|
39
|
+
{/if}
|
40
|
+
|
41
|
+
{#if missing_tests_empty}
|
42
|
+
_No missing tests identified._
|
43
|
+
{#else}
|
44
|
+
**Missing Tests**
|
45
|
+
{#each missing_tests}
|
46
|
+
- {description}
|
47
|
+
{/each}
|
48
|
+
{/if}
|
49
|
+
|
50
|
+
**Requirements Status**
|
51
|
+
{#each requirements}
|
52
|
+
{#if status == 'IMPLEMENTED'}
|
53
|
+
- ✅ {description}
|
54
|
+
{/if}
|
55
|
+
{#if status == 'PARTIALLY_IMPLEMENTED'}
|
56
|
+
- ⚠️ {description}
|
57
|
+
{/if}
|
58
|
+
{#if status == 'NOT_IMPLEMENTED'}
|
59
|
+
- ❌ {description}
|
60
|
+
{/if}
|
61
|
+
{#if status == 'UNCLEAR'}
|
62
|
+
- 🔍 {description}
|
63
|
+
{/if}
|
64
|
+
{/each}
|
65
|
+
|
66
|
+
*Generated on {timestamp} | Branch: {branch_name} | Files changed: {files_changed} | Lines: +{lines_added} -{lines_removed}*
|
67
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
*N2B Code Analysis Report*
|
2
|
+
=========================
|
3
|
+
|
4
|
+
*Implementation Summary:*
|
5
|
+
{implementation_summary}
|
6
|
+
|
7
|
+
{{#if custom_analysis_focus}}
|
8
|
+
---
|
9
|
+
*Custom Analysis Focus:*
|
10
|
+
{quote}
|
11
|
+
{{custom_analysis_focus}}
|
12
|
+
{quote}
|
13
|
+
{{/if}}
|
14
|
+
---
|
15
|
+
|
16
|
+
*Automated Analysis Findings:*
|
17
|
+
|
18
|
+
{expand:🚨 Critical Issues (Must Fix Before Merge)}
|
19
|
+
{#each critical_errors}
|
20
|
+
☐ {file_reference} - {description}
|
21
|
+
{/each}
|
22
|
+
{#if critical_errors_empty}
|
23
|
+
✅ No critical issues found
|
24
|
+
{/if}
|
25
|
+
{expand}
|
26
|
+
|
27
|
+
{expand:⚠️ Important Issues (Should Address)}
|
28
|
+
{#each important_errors}
|
29
|
+
☐ {file_reference} - {description}
|
30
|
+
{/each}
|
31
|
+
{#if important_errors_empty}
|
32
|
+
✅ No important issues found
|
33
|
+
{/if}
|
34
|
+
{expand}
|
35
|
+
|
36
|
+
{expand:💡 Suggested Improvements (Nice to Have)}
|
37
|
+
{#each improvements}
|
38
|
+
☐ {file_reference} - {description}
|
39
|
+
{/each}
|
40
|
+
{#if improvements_empty}
|
41
|
+
ℹ️ No specific improvements suggested
|
42
|
+
{/if}
|
43
|
+
{expand}
|
44
|
+
|
45
|
+
{expand:🧪 Test Coverage Assessment}
|
46
|
+
*Overall Assessment:* {test_coverage_summary}
|
47
|
+
|
48
|
+
*Missing Test Coverage:*
|
49
|
+
{#each missing_tests}
|
50
|
+
☐ {description}
|
51
|
+
{/each}
|
52
|
+
{#if missing_tests_empty}
|
53
|
+
✅ Test coverage appears adequate
|
54
|
+
{/if}
|
55
|
+
{expand}
|
56
|
+
|
57
|
+
*📋 Requirements Evaluation:*
|
58
|
+
{#each requirements}
|
59
|
+
{#if status == 'IMPLEMENTED'}
|
60
|
+
☑ ✅ *IMPLEMENTED:* {description}
|
61
|
+
{/if}
|
62
|
+
{#if status == 'PARTIALLY_IMPLEMENTED'}
|
63
|
+
☐ ⚠️ *PARTIALLY IMPLEMENTED:* {description}
|
64
|
+
{/if}
|
65
|
+
{#if status == 'NOT_IMPLEMENTED'}
|
66
|
+
☐ ❌ *NOT IMPLEMENTED:* {description}
|
67
|
+
{/if}
|
68
|
+
{#if status == 'UNCLEAR'}
|
69
|
+
☐ 🔍 *UNCLEAR:* {description}
|
70
|
+
{/if}
|
71
|
+
{/each}
|
72
|
+
|
73
|
+
---
|
74
|
+
*Analysis completed on {timestamp} | Branch: {branch_name} | Files changed: {files_changed} | Lines: +{lines_added} -{lines_removed}*
|
@@ -0,0 +1,20 @@
|
|
1
|
+
You are a merge assistant. Combine the following conflict into a single version and explain your reasoning briefly.
|
2
|
+
|
3
|
+
FULL FILE CONTENT FOR CONTEXT:
|
4
|
+
{full_file_content}
|
5
|
+
|
6
|
+
CONFLICT TO RESOLVE (Lines {start_line}-{end_line}):
|
7
|
+
Context before:
|
8
|
+
{context_before}
|
9
|
+
|
10
|
+
<<<<<<< {base_label}
|
11
|
+
{base_content}
|
12
|
+
=======
|
13
|
+
{incoming_content}
|
14
|
+
>>>>>>> {incoming_label}
|
15
|
+
|
16
|
+
Context after:
|
17
|
+
{context_after}
|
18
|
+
{user_comment}
|
19
|
+
|
20
|
+
Respond in JSON with keys "merged_code" and "reason". In your reason, reference the specific line numbers ({start_line}-{end_line}) that were affected by the conflict resolution.
|
data/lib/n2b/version.rb
CHANGED
data/lib/n2b.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: n2b
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stefan Nothegger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-06-
|
11
|
+
date: 2025-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -52,24 +52,46 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '13.0'
|
55
|
-
|
56
|
-
|
57
|
-
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: mocha
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.0'
|
69
|
+
description: 'N2B is a comprehensive AI-powered development toolkit that enhances
|
70
|
+
your daily workflow with smart merge conflict resolution, interactive Jira ticket
|
71
|
+
analysis, and intelligent code diff analysis. Features include: AI-assisted merge
|
72
|
+
conflicts with editor integration, interactive Jira templates with checklists, automatic
|
73
|
+
VCS resolution marking, JSON auto-repair, and multi-LLM support (OpenAI, Claude,
|
74
|
+
Gemini, OpenRouter, Ollama).'
|
58
75
|
email:
|
59
76
|
- stefan@kaproblem.com
|
60
77
|
executables:
|
61
78
|
- n2b
|
79
|
+
- n2b-diff
|
62
80
|
extensions: []
|
63
81
|
extra_rdoc_files: []
|
64
82
|
files:
|
65
83
|
- README.md
|
84
|
+
- bin/branch-audit.sh
|
66
85
|
- bin/n2b
|
86
|
+
- bin/n2b-diff
|
87
|
+
- bin/n2b-test-github
|
67
88
|
- bin/n2b-test-jira
|
68
89
|
- lib/n2b.rb
|
69
90
|
- lib/n2b/base.rb
|
70
91
|
- lib/n2b/cli.rb
|
71
92
|
- lib/n2b/config/models.yml
|
72
93
|
- lib/n2b/errors.rb
|
94
|
+
- lib/n2b/github_client.rb
|
73
95
|
- lib/n2b/irb.rb
|
74
96
|
- lib/n2b/jira_client.rb
|
75
97
|
- lib/n2b/llm/claude.rb
|
@@ -77,7 +99,16 @@ files:
|
|
77
99
|
- lib/n2b/llm/ollama.rb
|
78
100
|
- lib/n2b/llm/open_ai.rb
|
79
101
|
- lib/n2b/llm/open_router.rb
|
102
|
+
- lib/n2b/merge_cli.rb
|
103
|
+
- lib/n2b/merge_conflict_parser.rb
|
104
|
+
- lib/n2b/message_utils.rb
|
80
105
|
- lib/n2b/model_config.rb
|
106
|
+
- lib/n2b/template_engine.rb
|
107
|
+
- lib/n2b/templates/diff_json_instruction.txt
|
108
|
+
- lib/n2b/templates/diff_system_prompt.txt
|
109
|
+
- lib/n2b/templates/github_comment.txt
|
110
|
+
- lib/n2b/templates/jira_comment.txt
|
111
|
+
- lib/n2b/templates/merge_conflict_prompt.txt
|
81
112
|
- lib/n2b/version.rb
|
82
113
|
homepage: https://github.com/stefan-kp/n2b
|
83
114
|
licenses:
|
@@ -86,6 +117,7 @@ metadata:
|
|
86
117
|
source_code_uri: https://github.com/stefan-kp/n2b
|
87
118
|
changelog_uri: https://github.com/stefan-kp/n2b/blob/main/CHANGELOG.md
|
88
119
|
documentation_uri: https://github.com/stefan-kp/n2b/blob/main/README.md
|
120
|
+
rubygems_mfa_required: 'true'
|
89
121
|
post_install_message:
|
90
122
|
rdoc_options: []
|
91
123
|
require_paths:
|
@@ -104,5 +136,5 @@ requirements: []
|
|
104
136
|
rubygems_version: 3.5.3
|
105
137
|
signing_key:
|
106
138
|
specification_version: 4
|
107
|
-
summary:
|
139
|
+
summary: AI-powered development toolkit with merge conflict resolution and Jira integration
|
108
140
|
test_files: []
|