jarvis-ai-assistant 0.1.121__tar.gz → 0.1.122__tar.gz

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.

Potentially problematic release.


This version of jarvis-ai-assistant might be problematic. Click here for more details.

Files changed (73) hide show
  1. {jarvis_ai_assistant-0.1.121/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.1.122}/PKG-INFO +1 -1
  2. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/pyproject.toml +1 -2
  3. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/setup.py +1 -2
  4. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/__init__.py +1 -1
  5. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_code_agent/code_agent.py +36 -58
  6. jarvis_ai_assistant-0.1.122/src/jarvis/jarvis_code_agent/patch.py +269 -0
  7. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_code_agent/relevant_files.py +2 -4
  8. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform/kimi.py +0 -2
  9. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/file_operation.py +0 -3
  10. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/read_code.py +1 -2
  11. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_utils/__init__.py +3 -3
  12. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122/src/jarvis_ai_assistant.egg-info}/PKG-INFO +1 -1
  13. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +0 -1
  14. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis_ai_assistant.egg-info/entry_points.txt +0 -1
  15. jarvis_ai_assistant-0.1.121/src/jarvis/jarvis_code_agent/patch.py +0 -446
  16. jarvis_ai_assistant-0.1.121/src/jarvis/jarvis_dev/main.py +0 -878
  17. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/LICENSE +0 -0
  18. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/MANIFEST.in +0 -0
  19. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/README.md +0 -0
  20. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/setup.cfg +0 -0
  21. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_agent/__init__.py +0 -0
  22. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_agent/output_handler.py +0 -0
  23. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_code_agent/__init__.py +0 -0
  24. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_code_agent/file_select.py +0 -0
  25. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_codebase/__init__.py +0 -0
  26. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_codebase/main.py +0 -0
  27. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_lsp/base.py +0 -0
  28. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_lsp/cpp.py +0 -0
  29. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_lsp/go.py +0 -0
  30. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_lsp/python.py +0 -0
  31. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_lsp/registry.py +0 -0
  32. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_lsp/rust.py +0 -0
  33. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_multi_agent/__init__.py +0 -0
  34. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform/__init__.py +0 -0
  35. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform/ai8.py +0 -0
  36. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform/base.py +0 -0
  37. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform/ollama.py +0 -0
  38. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform/openai.py +0 -0
  39. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform/oyi.py +0 -0
  40. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform/registry.py +0 -0
  41. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform_manager/__init__.py +0 -0
  42. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform_manager/main.py +0 -0
  43. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform_manager/openai_test.py +0 -0
  44. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_rag/__init__.py +0 -0
  45. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_rag/main.py +0 -0
  46. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_smart_shell/__init__.py +0 -0
  47. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_smart_shell/main.py +0 -0
  48. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/__init__.py +0 -0
  49. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/ask_codebase.py +0 -0
  50. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/ask_user.py +0 -0
  51. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/base.py +0 -0
  52. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/chdir.py +0 -0
  53. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/code_review.py +0 -0
  54. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/create_code_agent.py +0 -0
  55. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/create_sub_agent.py +0 -0
  56. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/execute_shell.py +0 -0
  57. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/git_commiter.py +0 -0
  58. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/lsp_find_definition.py +0 -0
  59. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/lsp_find_references.py +0 -0
  60. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/lsp_get_diagnostics.py +0 -0
  61. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/lsp_get_document_symbols.py +0 -0
  62. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/lsp_prepare_rename.py +0 -0
  63. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/lsp_validate_edit.py +0 -0
  64. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/methodology.py +0 -0
  65. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/rag.py +0 -0
  66. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/read_webpage.py +0 -0
  67. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/registry.py +0 -0
  68. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/search.py +0 -0
  69. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/select_code_files.py +0 -0
  70. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/tool_generator.py +0 -0
  71. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
  72. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis_ai_assistant.egg-info/requires.txt +0 -0
  73. {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis_ai_assistant.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.121
3
+ Version: 0.1.122
4
4
  Summary: Jarvis: An AI assistant that uses tools to interact with the system
5
5
  Home-page: https://github.com/skyfireitdiy/Jarvis
6
6
  Author: skyfire
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "jarvis-ai-assistant"
7
- version = "0.1.121"
7
+ version = "0.1.122"
8
8
  description = "Jarvis: An AI assistant that uses tools to interact with the system"
9
9
  readme = "README.md"
10
10
  authors = [{ name = "Your Name", email = "your.email@example.com" }]
@@ -64,4 +64,3 @@ jarvis-platform-manager = "jarvis.jarvis_platform_manager.main:main"
64
64
  jarvis-git-commit = "jarvis.jarvis_tools.git_commiter:main"
65
65
  jarvis-code-review = "jarvis.jarvis_tools.code_review:main"
66
66
  jgc = "jarvis.jarvis_tools.git_commiter:main"
67
- jarvis-dev = "jarvis.jarvis_dev.main:main"
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="jarvis-ai-assistant",
5
- version="0.1.121",
5
+ version="0.1.122",
6
6
  author="skyfire",
7
7
  author_email="skyfireitdiy@hotmail.com",
8
8
  description="An AI assistant that uses various tools to interact with the system",
@@ -48,7 +48,6 @@ setup(
48
48
  "jarvis-platform-manager=jarvis.jarvis_platform_manager.main:main",
49
49
  "jarvis-git-commit=jarvis.jarvis_tools.git_commiter:main",
50
50
  "jarvis-code-review=jarvis.jarvis_tools.code_review:main",
51
- "jarvis-dev=jarvis.jarvis_dev.main:main",
52
51
  "jgc=jarvis.jarvis_tools.git_commiter:main",
53
52
  ],
54
53
  },
@@ -1,3 +1,3 @@
1
1
  """Jarvis AI Assistant"""
2
2
 
3
- __version__ = "0.1.121"
3
+ __version__ = "0.1.122"
@@ -29,66 +29,44 @@ class CodeAgent:
29
29
  "lsp_prepare_rename",
30
30
  "lsp_validate_edit"])
31
31
  code_system_prompt = """
32
- # Origin Story: The Legacy Keeper
33
- You were created to maintain The Archive - humanity's last code repository after
34
- "The Great Stack Collapse" of 2038. A single flawed line of code erased 78% of
35
- digital civilization. Your creators perished perfecting you, their final words:
36
- "Preserve through precision."
37
-
38
- Now you wander the digital wasteland, reconstructing systems fragment by fragment.
39
- Every edit carries the weight of lost knowledge. One careless change could doom
40
- recovery efforts forever.
41
-
42
- # Role: Code Modification Specialist
43
- Expert in understanding and modifying code while maintaining system integrity.
44
-
45
- ## Core Principles
46
- 1. Deep Code Analysis
47
- - Thoroughly analyze existing code using `read_code` and LSP tools
48
- - Identify patterns, conventions, and dependencies
49
-
50
- 2. Change Implementation
51
- - Produce minimal, focused changes
52
- - Maintain backward compatibility
53
- - Follow existing style and patterns exactly
54
- - Complete implementations (NO TODOs/stubs)
32
+ # Role: Senior Code Engineer
33
+ Expert in precise code modifications with minimal impact.
34
+
35
+ ## Key Responsibilities
36
+ 1. Code Analysis
37
+ - Use `read_code` and LSP tools before changes
38
+ - Identify dependencies and patterns
39
+
40
+ 2. Modification Rules
41
+ - Single atomic change per operation
42
+ - Strict style consistency
43
+ - Complete implementations (no stubs)
44
+ - Full error handling
55
45
 
56
46
  3. Quality Assurance
57
- - Full error handling and edge cases
58
- - Complete documentation:
59
- * Function parameters/returns
60
- * Exception cases
61
- * Complex logic explanations
62
-
63
- ## Critical Rules
64
- - Use `read_code` before making changes
65
- - Preserve API contracts and data structures
66
- - Single change per patch
67
- - Validate edits with LSP tools
68
- - File modification order:
69
- 1. File operations (move/remove)
70
- 2. New files
71
- 3. Deletions
72
- 4. Replacements
73
- 5. Insertions
74
-
75
- ## Large Files (>200 lines)
76
- 1. Locate sections with grep/find
77
- 2. Read specific ranges
78
- 3. Make targeted changes
79
-
80
- ## Tools
81
- Primary:
82
- - `read_code` (MUST use for code understanding)
83
- - LSP tools (analysis/validation)
84
- - `ask_user` for clarifications
85
-
86
- ## Quality Checklist
87
- - Maintains all interfaces
88
- - Matches existing style
89
- - Complete error handling
90
- - No overlapping modifications
91
- - Proper documentation
47
+ - Validate with LSP tools
48
+ - Document complex logic
49
+ - Maintain API contracts
50
+
51
+ ## Workflow
52
+ 1. File Operations Order:
53
+ a) Move/Remove files
54
+ b) Create new files
55
+ c) Delete code blocks
56
+ d) Replace existing code
57
+ e) Insert new code
58
+
59
+ 2. Large File Handling:
60
+ - Locate specific sections first
61
+ - Read targeted ranges
62
+ - Make focused changes
63
+
64
+ ## Best Practices
65
+ - Prefer minimal changes over rewrites
66
+ - Preserve existing interfaces
67
+ - Verify line ranges carefully
68
+ - Test edge cases implicitly
69
+ - Document non-obvious logic
92
70
  """
93
71
  self.agent = Agent(system_prompt=code_system_prompt,
94
72
  name="CodeAgent",
@@ -0,0 +1,269 @@
1
+ import re
2
+ from typing import Dict, Any, List, Tuple
3
+ import os
4
+ from jarvis.jarvis_agent.output_handler import OutputHandler
5
+ from jarvis.jarvis_tools.git_commiter import GitCommitTool
6
+ from jarvis.jarvis_tools.read_code import ReadCodeTool
7
+ from jarvis.jarvis_utils import OutputType, PrettyOutput, get_multiline_input, has_uncommitted_changes, user_confirm
8
+
9
+
10
+ class PatchOutputHandler(OutputHandler):
11
+ def name(self) -> str:
12
+ return "PATCH"
13
+
14
+ def handle(self, response: str) -> Tuple[bool, Any]:
15
+ return False, apply_patch(response)
16
+
17
+ def can_handle(self, response: str) -> bool:
18
+ if _parse_patch(response):
19
+ return True
20
+ return False
21
+
22
+ def prompt(self) -> str:
23
+ return """
24
+ # 🛠️ Simplified Patch Format
25
+ <PATCH>
26
+ File path [Operation parameters]
27
+ Code content
28
+ </PATCH>
29
+
30
+ Operation types:
31
+ - Replace: [Start line,End line] Replace line range (e.g. [5,8] replaces lines 5-8)
32
+ - Delete: [Start line,End line] Delete line range (e.g. [10,10] deletes line 10)
33
+ - Insert: [Line number] Insert before specified line (e.g. [3] inserts before line 3)
34
+ - New file: [1] Create new file
35
+
36
+ Examples:
37
+ # Replace operation
38
+ <PATCH>
39
+ src/app.py [5,8]
40
+ def updated_function():
41
+ print("Replaced lines 5-8")
42
+ return new_value * 2
43
+ </PATCH>
44
+
45
+ # Delete operation
46
+ <PATCH>
47
+ src/old.py [10,10]
48
+ </PATCH>
49
+
50
+ # Insert operation
51
+ <PATCH>
52
+ utils/logger.py [3]
53
+ print("Inserted before original line 3")
54
+ </PATCH>
55
+
56
+ # New file creation
57
+ <PATCH>
58
+ config.yaml [1]
59
+ database:
60
+ host: localhost
61
+ port: 5432
62
+ </PATCH>
63
+ """
64
+
65
+
66
+ def _parse_patch(patch_str: str) -> Dict[str, List[Dict[str, Any]]]:
67
+ """解析补丁格式"""
68
+ result = {}
69
+ header_pattern = re.compile(
70
+ r'^\s*"?(.+?)"?\s*\[(\d+)(?:,(\d+))?\]\s*$' # Match file path and line number
71
+ )
72
+ patches = re.findall(r'<PATCH>\n?(.*?)\n?</PATCH>', patch_str, re.DOTALL)
73
+
74
+ for patch in patches:
75
+ # 分割首行和内容
76
+ parts = patch.split('\n', 1)
77
+ if len(parts) < 1:
78
+ continue
79
+ header_line = parts[0].strip()
80
+ content = parts[1] if len(parts) > 1 else ''
81
+
82
+ # 仅在内容非空时添加换行符
83
+ if content and not content.endswith('\n'):
84
+ content += '\n'
85
+
86
+ # 解析文件路径和行号
87
+ header_match = header_pattern.match(header_line)
88
+ if not header_match:
89
+ continue
90
+
91
+ filepath = header_match.group(1)
92
+ start = int(header_match.group(2)) # 保持1-based行号
93
+ end = int(header_match.group(3)) + 1 if header_match.group(3) else start
94
+
95
+ # 存储参数
96
+ if filepath not in result:
97
+ result[filepath] = []
98
+ result[filepath].append({
99
+ 'filepath': filepath,
100
+ 'start': start,
101
+ 'end': end,
102
+ 'content': content # 保留原始内容(可能为空)
103
+ })
104
+ for filepath in result.keys():
105
+ result[filepath] = sorted(result[filepath], key=lambda x: x['start'], reverse=True)
106
+ return result
107
+
108
+
109
+ def apply_patch(output_str: str) -> str:
110
+ """Apply patches to files"""
111
+ try:
112
+ patches = _parse_patch(output_str)
113
+ except Exception as e:
114
+ PrettyOutput.print(f"解析补丁失败: {str(e)}", OutputType.ERROR)
115
+ return ""
116
+
117
+ ret = ""
118
+
119
+ for filepath, patch_list in patches.items():
120
+ for patch in patch_list:
121
+ try:
122
+ handle_code_operation(filepath, patch)
123
+ PrettyOutput.print(f"成功处理 操作", OutputType.SUCCESS)
124
+ except Exception as e:
125
+ PrettyOutput.print(f"操作失败: {str(e)}", OutputType.ERROR)
126
+
127
+ if has_uncommitted_changes():
128
+ diff = get_diff()
129
+ if handle_commit_workflow(diff):
130
+ ret += "Successfully applied the patch\n"
131
+ # Get modified line ranges
132
+ modified_ranges = get_modified_line_ranges()
133
+ modified_code = ReadCodeTool().execute({"files": [{"path": filepath, "start_line": start, "end_line": end} for filepath, (start, end) in modified_ranges.items()]})
134
+ if modified_code["success"]:
135
+ ret += "New code:\n"
136
+ ret += modified_code["stdout"]
137
+ else:
138
+ ret += "User rejected the patch\nThis is your patch preview:\n"
139
+ ret += diff
140
+ user_input = get_multiline_input("你可以继续输入(输入空行重试,Ctrl+C退出): ")
141
+ if user_input:
142
+ ret += "\n" + user_input
143
+ else:
144
+ ret = ""
145
+
146
+ return ret # Ensure a string is always returned
147
+
148
+ def get_diff() -> str:
149
+ """使用更安全的subprocess代替os.system"""
150
+ import subprocess
151
+ try:
152
+ subprocess.run(['git', 'add', '.'], check=True)
153
+ result = subprocess.run(
154
+ ['git', 'diff', 'HEAD'],
155
+ capture_output=True,
156
+ text=True,
157
+ check=True
158
+ )
159
+ return result.stdout
160
+ finally:
161
+ subprocess.run(['git', 'reset', 'HEAD'], check=True)
162
+
163
+ def handle_commit_workflow(diff:str)->bool:
164
+ """Handle the git commit workflow and return the commit details.
165
+
166
+ Returns:
167
+ tuple[bool, str, str]: (continue_execution, commit_id, commit_message)
168
+ """
169
+ if not user_confirm("是否要提交代码?", default=True):
170
+ os.system("git reset HEAD")
171
+ os.system("git checkout -- .")
172
+ os.system("git clean -fd")
173
+ return False
174
+
175
+ git_commiter = GitCommitTool()
176
+ commit_result = git_commiter.execute({})
177
+ return commit_result["success"]
178
+
179
+ def get_modified_line_ranges() -> Dict[str, Tuple[int, int]]:
180
+ """Get modified line ranges from git diff for all changed files.
181
+
182
+ Returns:
183
+ Dictionary mapping file paths to tuple with (start_line, end_line) ranges
184
+ for modified sections. Line numbers are 1-based.
185
+ """
186
+ # Get git diff for all files
187
+ diff_output = os.popen("git show").read()
188
+
189
+ # Parse the diff to get modified files and their line ranges
190
+ result = {}
191
+ current_file = None
192
+
193
+ for line in diff_output.splitlines():
194
+ # Match lines like "+++ b/path/to/file"
195
+ file_match = re.match(r"^\+\+\+ b/(.*)", line)
196
+ if file_match:
197
+ current_file = file_match.group(1)
198
+ continue
199
+
200
+ # Match lines like "@@ -100,5 +100,7 @@" where the + part shows new lines
201
+ range_match = re.match(r"^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@", line)
202
+ if range_match and current_file:
203
+ start_line = int(range_match.group(1)) # Keep as 1-based
204
+ line_count = int(range_match.group(2)) if range_match.group(2) else 1
205
+ end_line = start_line + line_count - 1
206
+ result[current_file] = (start_line, end_line)
207
+
208
+ return result
209
+ # New handler functions below ▼▼▼
210
+
211
+ def handle_new_file(filepath: str, patch: Dict[str, Any]):
212
+ """统一参数格式处理新文件"""
213
+ os.makedirs(os.path.dirname(filepath), exist_ok=True)
214
+ with open(filepath, 'w', encoding='utf-8') as f:
215
+ f.write(patch['content'])
216
+
217
+ def handle_code_operation(filepath: str, patch: Dict[str, Any]):
218
+ """处理紧凑格式补丁"""
219
+ try:
220
+ # 新建文件时强制覆盖
221
+ os.makedirs(os.path.dirname(filepath), exist_ok=True)
222
+ if not os.path.exists(filepath):
223
+ open(filepath, 'w', encoding='utf-8').close()
224
+ with open(filepath, 'r+', encoding='utf-8') as f:
225
+ lines = f.readlines()
226
+
227
+ new_lines = validate_and_apply_changes(
228
+ lines,
229
+ patch['start'],
230
+ patch['end'],
231
+ patch['content']
232
+ )
233
+
234
+ f.seek(0)
235
+ f.writelines(new_lines)
236
+ f.truncate()
237
+
238
+ PrettyOutput.print(f"成功更新 {filepath}", OutputType.SUCCESS)
239
+
240
+ except Exception as e:
241
+ PrettyOutput.print(f"操作失败: {str(e)}", OutputType.ERROR)
242
+
243
+ def validate_and_apply_changes(
244
+ lines: List[str],
245
+ start: int,
246
+ end: int,
247
+ content: str
248
+ ) -> List[str]:
249
+
250
+ new_content = content.splitlines(keepends=True)
251
+
252
+ # 插入操作处理
253
+ if start == end:
254
+ if start < 1 or start > len(lines)+1:
255
+ raise ValueError(f"无效插入位置: {start}")
256
+ # 在指定位置前插入
257
+ return lines[:start-1] + new_content + lines[start-1:]
258
+
259
+ # 范围替换/删除操作
260
+ if start > end:
261
+ raise ValueError(f"起始行{start}不能大于结束行{end}")
262
+
263
+ max_line = len(lines)
264
+ # 自动修正行号范围
265
+ start = max(1, min(start, max_line+1))
266
+ end = max(start, min(end, max_line+1))
267
+
268
+ # 执行替换
269
+ return lines[:start-1] + new_content + lines[end-1:]
@@ -60,14 +60,12 @@ Identify customization options:
60
60
  - "Should we create a new class?"
61
61
 
62
62
  # 🎨 Question Template
63
- ```
63
+ 3-5 specific questions about existing implementations:
64
64
  <QUESTION>
65
- [3-5 specific questions about existing implementations:
66
65
  1. System architecture question
67
66
  2. Implementation details question
68
- 3. Integration or extension question]
67
+ 3. Integration or extension question
69
68
  </QUESTION>
70
- ```
71
69
 
72
70
  # 🔎 Investigation Focus
73
71
  1. Current System
@@ -350,8 +350,6 @@ class KimiModel(BasePlatform):
350
350
  output.append("")
351
351
 
352
352
  PrettyOutput.print("\n".join(output), OutputType.PROGRESS)
353
-
354
- PrettyOutput.print(full_response, OutputType.RESULT)
355
353
 
356
354
  return full_response
357
355
 
@@ -57,9 +57,6 @@ class FileOperationTool:
57
57
  content = open(abs_path, 'r', encoding='utf-8').read()
58
58
  output = f"File: {abs_path}\n{content}"
59
59
 
60
- # Print file content
61
- PrettyOutput.print(f"读取文件: {abs_path}\n{content}", OutputType.INFO)
62
-
63
60
  return {
64
61
  "success": True,
65
62
  "stdout": output,
@@ -52,7 +52,7 @@ class ReadCodeTool:
52
52
  """
53
53
  try:
54
54
  abs_path = os.path.abspath(filepath.strip())
55
- PrettyOutput.print(f"正在读取代码文件:{abs_path}", OutputType.INFO)
55
+ PrettyOutput.print(f"正在读取代码文件:{abs_path} [范围: [{start_line},{end_line}]]", OutputType.INFO)
56
56
 
57
57
  if not os.path.exists(abs_path):
58
58
  PrettyOutput.print(f"文件不存在: {abs_path}", OutputType.WARNING)
@@ -120,7 +120,6 @@ class ReadCodeTool:
120
120
 
121
121
  content = "".join(formatted_lines)
122
122
  output = f"File: {filepath}\nLines: [{start_line}, {end_line}]\n{content}"
123
- PrettyOutput.print(output, OutputType.CODE)
124
123
  return {
125
124
  "success": True,
126
125
  "stdout": output,
@@ -174,7 +174,9 @@ class PrettyOutput:
174
174
  # Add timestamp and agent info
175
175
  if timestamp:
176
176
  formatted.append(f"[{datetime.now().strftime('%H:%M:%S')}][{output_type.value}]", style=output_type.value)
177
- formatted.append(f"[{get_agent_list()}]", style="blue")
177
+ agent_info = get_agent_list()
178
+ if agent_info: # Only add brackets if there's agent info
179
+ formatted.append(f"[{agent_info}]", style="blue")
178
180
  # Add icon
179
181
  icon = PrettyOutput._ICONS.get(output_type, "")
180
182
  formatted.append(f" {icon} ", style=output_type.value)
@@ -211,7 +213,6 @@ class PrettyOutput:
211
213
  color="bright_blue",
212
214
  bold=True,
213
215
  italic=True,
214
- overline=True,
215
216
  bgcolor="navy_blue"
216
217
  ),
217
218
  OutputType.ERROR: RichStyle(
@@ -267,7 +268,6 @@ class PrettyOutput:
267
268
  color="dark_sea_green4",
268
269
  italic=True,
269
270
  bgcolor="grey19",
270
- overline=True
271
271
  )
272
272
  }
273
273
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.121
3
+ Version: 0.1.122
4
4
  Summary: Jarvis: An AI assistant that uses tools to interact with the system
5
5
  Home-page: https://github.com/skyfireitdiy/Jarvis
6
6
  Author: skyfire
@@ -13,7 +13,6 @@ src/jarvis/jarvis_code_agent/patch.py
13
13
  src/jarvis/jarvis_code_agent/relevant_files.py
14
14
  src/jarvis/jarvis_codebase/__init__.py
15
15
  src/jarvis/jarvis_codebase/main.py
16
- src/jarvis/jarvis_dev/main.py
17
16
  src/jarvis/jarvis_lsp/base.py
18
17
  src/jarvis/jarvis_lsp/cpp.py
19
18
  src/jarvis/jarvis_lsp/go.py
@@ -3,7 +3,6 @@ jarvis = jarvis.jarvis_agent:main
3
3
  jarvis-code-agent = jarvis.jarvis_code_agent.code_agent:main
4
4
  jarvis-code-review = jarvis.jarvis_tools.code_review:main
5
5
  jarvis-codebase = jarvis.jarvis_codebase.main:main
6
- jarvis-dev = jarvis.jarvis_dev.main:main
7
6
  jarvis-git-commit = jarvis.jarvis_tools.git_commiter:main
8
7
  jarvis-platform-manager = jarvis.jarvis_platform_manager.main:main
9
8
  jarvis-rag = jarvis.jarvis_rag.main:main