relay-code 0.1.0__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.
ui/format.py ADDED
@@ -0,0 +1,145 @@
1
+ from pathlib import Path
2
+ from typing import Any, Tuple
3
+ import re
4
+
5
+ HEADLINE_KEYS = ("path", "command", "pattern", "url", "query", "action")
6
+
7
+ BULKY_KEYS = frozenset({"content", "old_string", "new_string"})
8
+
9
+ ARG_ORDER = {
10
+ "read": ["path", "offset", "limit"],
11
+ "write": ["path", "create_directories", "content"],
12
+ "edit": ["path", "replace_all", "old_string", "new_string"],
13
+ "shell": ['command', 'timeout', 'cwd'],
14
+ "list_dir": ['path', 'inclide_hidden'],
15
+ "grep": ['path', 'case_insensitive', 'pattern'],
16
+ "glob": ['path', 'pattern'],
17
+ "todo": ['action', 'id', 'content'],
18
+ "memory": ['action', 'key', 'value'],
19
+ }
20
+
21
+ _EXTENSION_LANGUAGES = {
22
+ ".py": "python",
23
+ ".js": "javascript",
24
+ ".jsx": "jsx",
25
+ ".ts": "typescript",
26
+ ".tsx": "tsx",
27
+ ".json": "json",
28
+ ".toml": "toml",
29
+ ".yaml": "yaml",
30
+ ".yml": "yaml",
31
+ ".md": "markdown",
32
+ ".sh": "bash",
33
+ ".bash": "bash",
34
+ ".zsh": "bash",
35
+ ".rs": "rust",
36
+ ".go": "go",
37
+ ".java": "java",
38
+ ".kt": "kotlin",
39
+ ".swift": "swift",
40
+ ".c": "c",
41
+ ".h": "c",
42
+ ".cpp": "cpp",
43
+ ".hpp": "cpp",
44
+ ".css": "css",
45
+ ".html": "html",
46
+ ".xml": "xml",
47
+ ".sql": "sql",
48
+ }
49
+
50
+ HEADLINE_MAX_WIDTH = 64
51
+
52
+
53
+ def format_elapsed(seconds: float) -> str:
54
+ if seconds < 1:
55
+ return f"{seconds * 1000:.0f}ms"
56
+ if seconds < 60:
57
+ return f"{seconds:.1f}s"
58
+ minutes, secs = divmod(int(seconds), 60)
59
+ return f"{minutes}m{secs:02d}s"
60
+
61
+
62
+ def guess_language(path: str | None) -> str:
63
+ if not path:
64
+ return "text"
65
+ return _EXTENSION_LANGUAGES.get(Path(path).suffix.lower(), "text")
66
+
67
+
68
+ def ordered_args(tool_name: str, args: dict[str, Any]) -> list[Tuple[str, Any]]:
69
+ preferred = ARG_ORDER.get(tool_name, [])
70
+ ordered: list[Tuple[str, Any]] = []
71
+ seen: set[str] = set()
72
+
73
+ for key in preferred:
74
+ if key in args:
75
+ ordered.append((key, args[key]))
76
+ seen.add(key)
77
+
78
+ ordered.extend((key, args[key]) for key in sorted(args.keys() - seen))
79
+ return ordered
80
+
81
+
82
+ def summarise_value(key: str, value: Any) -> str:
83
+ if isinstance(value, str) and key in BULKY_KEYS:
84
+ line_count = len(value.splitlines())
85
+ byte_count = len(value.encode("utf-8", errors="replace"))
86
+ return f"{line_count} lines ┈ {byte_count} bytes"
87
+
88
+ if isinstance(value, bool):
89
+ value = str(value)
90
+
91
+ return str(value)
92
+
93
+
94
+ def headline(args: dict[str, Any]) -> tuple[str, str] | None:
95
+ for key in HEADLINE_KEYS:
96
+ value = args.get(key)
97
+ if isinstance(value, str) and value.strip():
98
+ first_line = value.strip().splitlines()[0]
99
+ if len(first_line) > HEADLINE_MAX_WIDTH:
100
+ first_line = f"{first_line[:HEADLINE_MAX_WIDTH - 1]}…"
101
+ return key, first_line
102
+ return None
103
+
104
+
105
+ def secondary_args(args: dict[str, Any], headline_key: str | None) -> dict[str, Any]:
106
+ return {
107
+ key: value
108
+ for key, value in args.items()
109
+ if key != headline_key and not (key == "cwd" and value == ".")
110
+ }
111
+
112
+
113
+ def extract_read_code(text: str) -> tuple[int, str] | None:
114
+ body = text
115
+ header_match = re.match(
116
+ r"^Showing lines (\d+)-(\d+) of (\d+)[^\n]*\n\n", text, re.IGNORECASE
117
+ )
118
+ if header_match:
119
+ body = text[header_match.end():]
120
+
121
+ code_lines: list[str] = []
122
+ start_line: int | None = None
123
+
124
+ for line in body.splitlines():
125
+ match = re.match(r"^\s*(\d+)\|(.*)$", line)
126
+ if not match:
127
+ return None
128
+ if start_line is None:
129
+ start_line = int(match.group(1))
130
+ code_lines.append(match.group(2))
131
+
132
+ if start_line is None:
133
+ return None
134
+
135
+ return start_line, "\n".join(code_lines)
136
+
137
+
138
+ def diff_stat(diff: str) -> str:
139
+ added = removed = 0
140
+ for line in diff.splitlines():
141
+ if line.startswith("+") and not line.startswith("+++"):
142
+ added += 1
143
+ elif line.startswith("-") and not line.startswith("---"):
144
+ removed += 1
145
+ return f"+{added} -{removed}"
ui/logo.py ADDED
@@ -0,0 +1,46 @@
1
+ from rich.text import Text
2
+ import math
3
+
4
+ RELAY_VERSION = "0.2"
5
+
6
+ RELAY_LOGO = """\
7
+ ⣠⣤⣤⡤⠤⢤⣤⣀⡀⠀⠐⠒⡄⠀⡠⠒⠀⠀⢀⣀⣤⠤⠤⣤⣤⣤⡄
8
+ ⠈⠻⣿⡤⠤⡏⠀⠉⠙⠲⣄⠀⢰⢠⠃⢀⡤⠞⠋⠉⠈⢹⠤⢼⣿⠏⠀
9
+ ⠀⠀⠘⣿⡅⠓⢒⡤⠤⠀⡈⠱⣄⣼⡴⠋⡀⠀⠤⢤⡒⠓⢬⣿⠃⠀⠀
10
+ ⠀⠀⠀⠹⣿⣯⣐⢷⣀⣀⢤⡥⢾⣿⠷⢥⠤⣀⣀⣞⣢⣽⡿⠃⠀⠀⠀
11
+ ⠀⠀⠀⠀⠈⢙⣿⠝⠀⢁⠔⡨⡺⡿⡕⢔⠀⡈⠐⠹⣟⠋⠀⠀⠀⠀⠀
12
+ ⠀⠀⠀⠀⠀⢼⣟⢦⢶⢅⠜⢰⠃⠀⢹⡌⢢⣸⠦⠴⣿⡇⠀⠀⠀⠀⠀
13
+ ⠀⠀⠀⠀⠀⠘⣿⣇⡬⡌⢀⡟⠀⠀⠀⢷⠀⣧⢧⣵⣿⠂⠀⠀⠀⠀⠀
14
+ ⠀⠀⠀⠀⠀⠀⠈⢻⠛⠋⠉⠀⠀⠀⠀⠈⠉⠙⢻⡏⠀⠀⠀⠀⠀⠀⠀
15
+ ⠀⠀⠀⠀⠀⠀⢰⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠄⠀⠀⠀⠀⠀⠀"""
16
+
17
+ _WHITE = (255, 255, 255)
18
+ _SILVER = (168, 174, 186)
19
+
20
+ _PIXEL = "██"
21
+ _LETTER_GAP = 1
22
+
23
+ def small_wordmark(justify: str = "center") -> Text:
24
+ r, g, b = _SILVER
25
+ return Text(" ".join("relay"), style=f"rgb({r},{g},{b})", justify=justify, no_wrap=True)
26
+
27
+
28
+ def gradient_logo(justify: str = "center") -> Text:
29
+ rows = RELAY_LOGO.split("\n")
30
+ height = len(rows)
31
+ width = max((len(row) for row in rows), default=1)
32
+ cx = (width - 1) / 2
33
+ cy = (height - 1) / 2
34
+ max_dist = math.hypot(cx, cy) or 1.0
35
+
36
+ text = Text(justify=justify, no_wrap=True)
37
+ for y, row in enumerate(rows):
38
+ for x, char in enumerate(row):
39
+ t = min(math.hypot(x - cx, y - cy) / max_dist, 1.0)
40
+ r = round(_WHITE[0] + (_SILVER[0] - _WHITE[0]) * t)
41
+ g = round(_WHITE[1] + (_SILVER[1] - _WHITE[1]) * t)
42
+ b = round(_WHITE[2] + (_SILVER[2] - _WHITE[2]) * t)
43
+ text.append(char, style=f"rgb({r},{g},{b})")
44
+ if y != height - 1:
45
+ text.append("\n")
46
+ return text