super-code-assistant 3.3.6__py3-none-any.whl

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 (61) hide show
  1. commands/__init__.py +859 -0
  2. core/__init__.py +0 -0
  3. core/config.py +263 -0
  4. core/config_template.json +7 -0
  5. core/context.py +271 -0
  6. core/engine.py +635 -0
  7. core/file_state.py +279 -0
  8. core/llm.py +309 -0
  9. core/model_capabilities.py +45 -0
  10. core/permissions.py +204 -0
  11. core/sandbox/__init__.py +15 -0
  12. core/sandbox/blacklist.py +176 -0
  13. core/sandbox/config.py +38 -0
  14. core/sandbox/network.py +136 -0
  15. core/sandbox/path_protection.py +126 -0
  16. core/session.py +295 -0
  17. core/tool.py +45 -0
  18. features/__init__.py +0 -0
  19. features/compact.py +945 -0
  20. features/coordinator.py +105 -0
  21. features/cost_tracker.py +184 -0
  22. features/extract_memories.py +326 -0
  23. features/find_relevant_memories.py +376 -0
  24. features/git_ai.py +256 -0
  25. features/memory.py +531 -0
  26. features/memory_age.py +66 -0
  27. features/memory_scan.py +153 -0
  28. features/memory_types.py +34 -0
  29. features/plan.py +327 -0
  30. features/skills.py +300 -0
  31. features/worker_manager.py +232 -0
  32. mcp/__init__.py +0 -0
  33. mcp/client.py +112 -0
  34. mcp/loader.py +80 -0
  35. mcp/tool_proxy.py +59 -0
  36. super_code_assistant-3.3.6.dist-info/METADATA +45 -0
  37. super_code_assistant-3.3.6.dist-info/RECORD +61 -0
  38. super_code_assistant-3.3.6.dist-info/WHEEL +5 -0
  39. super_code_assistant-3.3.6.dist-info/entry_points.txt +2 -0
  40. super_code_assistant-3.3.6.dist-info/top_level.txt +7 -0
  41. tools/__init__.py +21 -0
  42. tools/agent.py +132 -0
  43. tools/ask_user.py +111 -0
  44. tools/bash.py +77 -0
  45. tools/file_edit.py +269 -0
  46. tools/file_read.py +206 -0
  47. tools/file_write.py +78 -0
  48. tools/glob_tool.py +81 -0
  49. tools/grep_tool.py +134 -0
  50. tools/plan_tools.py +75 -0
  51. tools/skill.py +108 -0
  52. tools/tool.py +44 -0
  53. tools/web_fetch.py +129 -0
  54. tools/web_search.py +220 -0
  55. tui/__init__.py +0 -0
  56. tui/app.py +726 -0
  57. tui/clipboard_image.py +42 -0
  58. tui/keylistener.py +140 -0
  59. tui/prompt.py +752 -0
  60. tui/query.py +200 -0
  61. tui/rendering.py +135 -0
tui/clipboard_image.py ADDED
@@ -0,0 +1,42 @@
1
+ """Windows 剪贴板位图读取(P1 多模态):PowerShell 转 base64,零 Python 依赖。
2
+
3
+ PowerShell 链路:Clipboard.GetImage() → MemoryStream.Save(PNG) → base64。
4
+ 非 Windows / 剪贴板无图 / 超时 / 失败一律返回 None(静默跳过,不打扰主流程)。
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import os
9
+ import subprocess
10
+
11
+ _PS_SCRIPT = r"""
12
+ Add-Type -AssemblyName System.Windows.Forms
13
+ $img = [System.Windows.Forms.Clipboard]::GetImage()
14
+ if ($null -ne $img) {
15
+ $ms = New-Object System.IO.MemoryStream
16
+ $img.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png)
17
+ [System.Convert]::ToBase64String($ms.ToArray())
18
+ }
19
+ """
20
+
21
+
22
+ def get_clipboard_image() -> tuple[str, str] | None:
23
+ """探测剪贴板位图 → (media_type, base64)。
24
+
25
+ Returns:
26
+ ("image/png", base64)。剪贴板无图 / PowerShell 不可用 / 超时 → None。
27
+ """
28
+ if os.name != "nt":
29
+ return None
30
+ try:
31
+ proc = subprocess.run(
32
+ ["powershell", "-NoProfile", "-Command", _PS_SCRIPT],
33
+ capture_output=True,
34
+ text=True,
35
+ timeout=8,
36
+ )
37
+ except (subprocess.TimeoutExpired, OSError):
38
+ return None
39
+ if proc.returncode != 0:
40
+ return None
41
+ data = proc.stdout.strip()
42
+ return ("image/png", data) if data else None
tui/keylistener.py ADDED
@@ -0,0 +1,140 @@
1
+ """Background thread that listens for the Escape key (Windows + Unix)."""
2
+ from __future__ import annotations
3
+
4
+ import threading
5
+ from typing import Callable
6
+
7
+ try:
8
+ import os, signal, select
9
+ import termios, tty
10
+ _HAS_TERMIOS = True # Unix/ Mac /Linux
11
+ except ImportError:
12
+ _HAS_TERMIOS = False # Windows
13
+
14
+
15
+ if _HAS_TERMIOS:
16
+ class EscListener:
17
+ def __init__(self, on_cancel: Callable[[], None] | None = None):
18
+ self.pressed = False
19
+ self._on_cancel = on_cancel
20
+ self._stop = threading.Event()
21
+ self._paused = threading.Event()
22
+ self._thread: threading.Thread | None = None
23
+ self._tty_fd: int | None = None
24
+ self._old_settings = None
25
+
26
+ def __enter__(self):
27
+ self.pressed = False
28
+ self._stop.clear()
29
+ self._paused.clear()
30
+ try:
31
+ self._tty_fd = os.open("/dev/tty", os.O_RDONLY | os.O_NOCTTY)
32
+ except OSError:
33
+ import sys
34
+ self._tty_fd = sys.stdin.fileno()
35
+ try:
36
+ self._old_settings = termios.tcgetattr(self._tty_fd)
37
+ tty.setcbreak(self._tty_fd)
38
+ except termios.error:
39
+ self._old_settings = None
40
+ self._thread = threading.Thread(target=self._listen, daemon=True)
41
+ self._thread.start()
42
+ return self
43
+
44
+ def __exit__(self, *_exc):
45
+ self._stop.set()
46
+ if self._thread:
47
+ self._thread.join(timeout=0.5)
48
+ if self._old_settings is not None and self._tty_fd is not None:
49
+ try:
50
+ termios.tcsetattr(self._tty_fd, termios.TCSADRAIN, self._old_settings)
51
+ except termios.error:
52
+ pass
53
+ if self._tty_fd is not None and self._tty_fd > 2:
54
+ try:
55
+ os.close(self._tty_fd)
56
+ except OSError:
57
+ pass
58
+ self._tty_fd = None
59
+
60
+ def pause(self):
61
+ self._paused.set()
62
+
63
+ def resume(self):
64
+ self._paused.clear()
65
+
66
+ def _has_data(self, timeout: float) -> bool:
67
+ if self._tty_fd is None:
68
+ return False
69
+ try:
70
+ return bool(select.select([self._tty_fd], [], [], timeout)[0])
71
+ except (OSError, ValueError):
72
+ return False
73
+
74
+ def _listen(self):
75
+ while not self._stop.is_set():
76
+ if self._paused.is_set():
77
+ self._stop.wait(0.05)
78
+ continue
79
+ if not self._has_data(0.1):
80
+ continue
81
+ if self._paused.is_set():
82
+ continue
83
+ try:
84
+ b = os.read(self._tty_fd, 1)
85
+ except OSError:
86
+ break
87
+ if not b:
88
+ break
89
+ if b == b'\x1b':
90
+ if self._has_data(0.05):
91
+ continue
92
+ self.pressed = True
93
+ os.kill(os.getpid(), signal.SIGINT)
94
+ return
95
+
96
+ else:
97
+ import msvcrt # Windows 专用的控制台 I/O 模块
98
+
99
+ class EscListener: # type: ignore[no-redef]
100
+ def __init__(self, on_cancel: Callable[[], None] | None = None):
101
+ self.pressed = False
102
+ self._on_cancel = on_cancel
103
+ self._stop = threading.Event()
104
+ self._paused = threading.Event()
105
+ self._thread: threading.Thread | None = None
106
+
107
+ def __enter__(self):
108
+ self.pressed = False
109
+ self._stop.clear()
110
+ self._paused.clear()
111
+ self._thread = threading.Thread(target=self._listen, daemon=True)
112
+ self._thread.start()
113
+ return self
114
+
115
+ def __exit__(self, *_exc):
116
+ self._stop.set()
117
+ if self._thread:
118
+ self._thread.join(timeout=0.5)
119
+
120
+ def pause(self):
121
+ self._paused.set()
122
+
123
+ def resume(self):
124
+ self._paused.clear()
125
+
126
+ def _listen(self):
127
+ while not self._stop.is_set():
128
+ if self._paused.is_set():
129
+ self._stop.wait(0.05)
130
+ continue
131
+ if not msvcrt.kbhit():
132
+ self._stop.wait(0.05)
133
+ continue
134
+ if self._paused.is_set():
135
+ continue
136
+ if msvcrt.getch() == b'\x1b':
137
+ self.pressed = True
138
+ if self._on_cancel:
139
+ self._on_cancel()
140
+ return