handycode 2.2.0__tar.gz → 2.2.1__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.
Files changed (23) hide show
  1. {handycode-2.2.0 → handycode-2.2.1}/PKG-INFO +1 -1
  2. {handycode-2.2.0 → handycode-2.2.1}/handycode/__init__.py +1 -1
  3. {handycode-2.2.0 → handycode-2.2.1}/handycode/assistant.py +140 -16
  4. {handycode-2.2.0 → handycode-2.2.1}/handycode.egg-info/PKG-INFO +1 -1
  5. {handycode-2.2.0 → handycode-2.2.1}/setup.py +1 -1
  6. {handycode-2.2.0 → handycode-2.2.1}/LICENSE +0 -0
  7. {handycode-2.2.0 → handycode-2.2.1}/README.md +0 -0
  8. {handycode-2.2.0 → handycode-2.2.1}/handycode/__main__.py +0 -0
  9. {handycode-2.2.0 → handycode-2.2.1}/handycode/cli.py +0 -0
  10. {handycode-2.2.0 → handycode-2.2.1}/handycode/config.py +0 -0
  11. {handycode-2.2.0 → handycode-2.2.1}/handycode/file_manager.py +0 -0
  12. {handycode-2.2.0 → handycode-2.2.1}/handycode/logo.py +0 -0
  13. {handycode-2.2.0 → handycode-2.2.1}/handycode/main.py +0 -0
  14. {handycode-2.2.0 → handycode-2.2.1}/handycode/models.py +0 -0
  15. {handycode-2.2.0 → handycode-2.2.1}/handycode/project_templates.py +0 -0
  16. {handycode-2.2.0 → handycode-2.2.1}/handycode/security.py +0 -0
  17. {handycode-2.2.0 → handycode-2.2.1}/handycode/utils.py +0 -0
  18. {handycode-2.2.0 → handycode-2.2.1}/handycode.egg-info/SOURCES.txt +0 -0
  19. {handycode-2.2.0 → handycode-2.2.1}/handycode.egg-info/dependency_links.txt +0 -0
  20. {handycode-2.2.0 → handycode-2.2.1}/handycode.egg-info/entry_points.txt +0 -0
  21. {handycode-2.2.0 → handycode-2.2.1}/handycode.egg-info/requires.txt +0 -0
  22. {handycode-2.2.0 → handycode-2.2.1}/handycode.egg-info/top_level.txt +0 -0
  23. {handycode-2.2.0 → handycode-2.2.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: handycode
3
- Version: 2.2.0
3
+ Version: 2.2.1
4
4
  Summary: AI Code Assistant for DeepSeek
5
5
  Home-page: https://github.com/AuraTechno/HandyCode
6
6
  Author: AuraTechno
@@ -3,7 +3,7 @@ HandyCode - AI Ассистент для разработки
3
3
  Аналог Claude Code для командной строки
4
4
  """
5
5
 
6
- __version__ = "2.2.0"
6
+ __version__ = "2.2.1"
7
7
  __author__ = "AURA Tec."
8
8
  __license__ = "MIT"
9
9
 
@@ -1,8 +1,13 @@
1
1
  """
2
- Основной класс ассистента HandyCode с премиальным интерфейсом
2
+ Основной класс ассистента HandyCode с интерактивным меню
3
3
  """
4
4
 
5
- import os, re, json, sys, atexit, signal
5
+ import os
6
+ import re
7
+ import json
8
+ import sys
9
+ import atexit
10
+ import signal
6
11
  from pathlib import Path
7
12
  from typing import List, Dict, Optional
8
13
  from datetime import datetime
@@ -18,7 +23,9 @@ try:
18
23
  HAS_REQUESTS = True
19
24
  except ImportError:
20
25
  HAS_REQUESTS = False
21
- import urllib.request, urllib.error, ssl
26
+ import urllib.request
27
+ import urllib.error
28
+ import ssl
22
29
 
23
30
  from handycode.config import Config
24
31
  from handycode.models import MODELS, get_model_settings
@@ -26,10 +33,128 @@ from handycode.file_manager import FileManager
26
33
  from handycode.security import SecurityChecker
27
34
  from handycode.utils import (
28
35
  Colors, Theme, colorize, print_colored, print_header, print_success,
29
- print_error, print_warning, print_info, print_logo, print_install_logo,
36
+ print_error, print_warning, print_info, print_logo,
30
37
  print_divider, print_file_action, print_status, print_section, print_box
31
38
  )
32
39
 
40
+
41
+ def interactive_confirm(commands):
42
+ """
43
+ Интерактивное меню выбора команд.
44
+ Управление: ↑/↓ для навигации, ПРОБЕЛ для выбора, ENTER для подтверждения.
45
+ Возвращает список выбранных команд.
46
+ """
47
+ if not commands:
48
+ return []
49
+
50
+ # Настройка для Windows
51
+ if os.name == 'nt':
52
+ import msvcrt
53
+
54
+ def get_key():
55
+ key = msvcrt.getch()
56
+ if key == b'\xe0': # стрелки
57
+ key = msvcrt.getch()
58
+ if key == b'H': return 'up'
59
+ if key == b'P': return 'down'
60
+ if key == b'\r': return 'enter'
61
+ if key == b' ': return 'space'
62
+ if key == b'a': return 'a'
63
+ if key == b'A': return 'A'
64
+ if key == b's': return 's'
65
+ if key == b'S': return 'S'
66
+ if key == b'c': return 'c'
67
+ if key == b'C': return 'C'
68
+ if key == b'\x1b': return 'escape'
69
+ return key.decode('utf-8', errors='ignore')
70
+ else:
71
+ import tty
72
+ import termios
73
+
74
+ def get_key():
75
+ fd = sys.stdin.fileno()
76
+ old = termios.tcgetattr(fd)
77
+ try:
78
+ tty.setraw(fd)
79
+ key = sys.stdin.read(1)
80
+ if key == '\x1b':
81
+ key += sys.stdin.read(2)
82
+ if key == '\x1b[A': return 'up'
83
+ if key == '\x1b[B': return 'down'
84
+ return 'escape'
85
+ if key == '\r': return 'enter'
86
+ if key == ' ': return 'space'
87
+ return key
88
+ finally:
89
+ termios.tcsetattr(fd, termios.TCSADRAIN, old)
90
+
91
+ selected = [True] * len(commands) # все выбраны по умолчанию
92
+ current = 0
93
+
94
+ def render():
95
+ # Очищаем предыдущий вывод
96
+ print(f"\033[{len(commands) + 4}A\033[J", end="")
97
+
98
+ print()
99
+ print(colorize(" ⚡ Команды для выполнения:", Theme.HIGHLIGHT + Colors.BOLD))
100
+ print(colorize(" ─────────────────────────────────────────────────", Theme.MUTED))
101
+
102
+ for i, cmd in enumerate(commands):
103
+ if i == current:
104
+ prefix = colorize(" ›", Theme.PRIMARY + Colors.BOLD)
105
+ else:
106
+ prefix = " "
107
+
108
+ if selected[i]:
109
+ checkbox = colorize("◉", Theme.SUCCESS)
110
+ cmd_color = Theme.SUCCESS
111
+ else:
112
+ checkbox = colorize("○", Theme.MUTED)
113
+ cmd_color = Theme.MUTED
114
+
115
+ print(f"{prefix} {checkbox} {colorize(cmd, cmd_color)}")
116
+
117
+ print()
118
+ print(colorize(" Управление:", Theme.MUTED))
119
+ print(colorize(" ↑↓ Навигация ПРОБЕЛ Выбрать A Все S Пропустить ENTER Подтвердить", Theme.MUTED))
120
+
121
+ # Рендерим первый раз
122
+ print()
123
+ print()
124
+ print()
125
+ print()
126
+ print()
127
+ print()
128
+ for _ in range(len(commands) + 4):
129
+ print()
130
+
131
+ render()
132
+
133
+ while True:
134
+ key = get_key()
135
+
136
+ if key == 'up':
137
+ current = (current - 1) % len(commands)
138
+ render()
139
+ elif key == 'down':
140
+ current = (current + 1) % len(commands)
141
+ render()
142
+ elif key == 'space':
143
+ selected[current] = not selected[current]
144
+ render()
145
+ elif key in ['a', 'A']:
146
+ selected = [True] * len(commands)
147
+ render()
148
+ elif key in ['s', 'S']:
149
+ selected = [False] * len(commands)
150
+ render()
151
+ elif key in ['c', 'C', 'escape']:
152
+ return []
153
+ elif key == 'enter':
154
+ print()
155
+ return [cmd for cmd, sel in zip(commands, selected) if sel]
156
+
157
+
33
158
  class HandyCode:
34
159
  def __init__(self, project_path, model="deepseek", auto_approve=False, config=None):
35
160
  self.project_path = project_path
@@ -127,7 +252,6 @@ Speak Russian. Write code in English."""
127
252
 
128
253
  def reset_interrupt(self): self._interrupt_count = 0
129
254
 
130
- # Потоковая обработка
131
255
  def _process_stream_chunk(self, chunk):
132
256
  self.stream_buffer += chunk
133
257
  while True:
@@ -263,7 +387,6 @@ Speak Russian. Write code in English."""
263
387
  }
264
388
 
265
389
  try:
266
- # Заголовок ответа
267
390
  print_divider("─", 60, Theme.MUTED)
268
391
  print(colorize(" HandyCode", Theme.PRIMARY + Colors.BOLD), end="")
269
392
  print(colorize(" ● ответ", Theme.MUTED))
@@ -274,22 +397,23 @@ Speak Russian. Write code in English."""
274
397
  if response:
275
398
  self.conversation_history.append({"role": "assistant", "content": response})
276
399
 
277
- # Команды
278
400
  if self.pending_commands:
279
- print()
280
- print_section("⚡ Команды (требуют подтверждения)",
281
- [colorize(cmd, Theme.WARNING) for cmd in self.pending_commands])
282
401
  if self.auto_approve:
283
- choice = 'A'
402
+ selected_commands = self.pending_commands
284
403
  else:
285
- print(colorize(" [A] Выполнить все [S] Пропустить [C] Отмена", Theme.MUTED))
286
- choice = input(colorize(" > ", Theme.HIGHLIGHT)).strip().upper()
287
- if choice == 'A':
288
- for cmd in self.pending_commands:
404
+ selected_commands = interactive_confirm(self.pending_commands)
405
+
406
+ if selected_commands:
407
+ print()
408
+ print_section("⚡ Выполнение команд", [])
409
+ for cmd in selected_commands:
289
410
  if self.security.is_safe_command(cmd):
290
411
  print_status(f"Выполняется: {cmd}")
291
412
  self.file_manager.execute_command(cmd)
292
413
  self.stats["commands_executed"].append(cmd)
414
+ else:
415
+ print_warning("Команды пропущены")
416
+
293
417
  self.stats["messages_sent"] += 1
294
418
  return response
295
419
  except Exception as e:
@@ -310,7 +434,7 @@ Speak Russian. Write code in English."""
310
434
  "/exit Выход"
311
435
  ], Theme.PRIMARY)
312
436
  elif cmd in ['/scan', '/s']:
313
- print_section("📁 Проект", self.file_manager.scan_project().split('\n'))
437
+ print(self.file_manager.scan_project())
314
438
  elif cmd in ['/models', '/m']:
315
439
  lines = []
316
440
  for name, mid in MODELS.items():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: handycode
3
- Version: 2.2.0
3
+ Version: 2.2.1
4
4
  Summary: AI Code Assistant for DeepSeek
5
5
  Home-page: https://github.com/AuraTechno/HandyCode
6
6
  Author: AuraTechno
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="handycode",
5
- version="2.2.0",
5
+ version="2.2.1",
6
6
  author="AuraTechno",
7
7
  description="AI Code Assistant for DeepSeek",
8
8
  long_description="HandyCode - AI Code Assistant",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes