decrypt 1.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.
- decrypt/__init__.py +0 -0
- decrypt/main.py +239 -0
- decrypt-1.1.0.dist-info/METADATA +109 -0
- decrypt-1.1.0.dist-info/RECORD +7 -0
- decrypt-1.1.0.dist-info/WHEEL +5 -0
- decrypt-1.1.0.dist-info/entry_points.txt +2 -0
- decrypt-1.1.0.dist-info/top_level.txt +1 -0
decrypt/__init__.py
ADDED
|
File without changes
|
decrypt/main.py
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import subprocess
|
|
5
|
+
|
|
6
|
+
#parser
|
|
7
|
+
parser = argparse.ArgumentParser(
|
|
8
|
+
description=(
|
|
9
|
+
"AI-powered CLI tool\n"
|
|
10
|
+
"• Conventional Commits\n"
|
|
11
|
+
"• Shell Commands\n"
|
|
12
|
+
"• Slang Decoder"
|
|
13
|
+
),
|
|
14
|
+
formatter_class=argparse.RawDescriptionHelpFormatter
|
|
15
|
+
)
|
|
16
|
+
parser.add_argument(
|
|
17
|
+
"text", nargs="?", type=str, help="Optional text input. Commit mode (default): if empty, uses git diff; if provided, generates commit from this description."
|
|
18
|
+
)
|
|
19
|
+
parser.add_argument(
|
|
20
|
+
"--lang",
|
|
21
|
+
type=str,
|
|
22
|
+
default=None,
|
|
23
|
+
help="Transcription language (default from .env)",
|
|
24
|
+
)
|
|
25
|
+
parser.add_argument(
|
|
26
|
+
"--config",
|
|
27
|
+
action="store_true",
|
|
28
|
+
help="Force re-configure API key and language"
|
|
29
|
+
)
|
|
30
|
+
parser.add_argument(
|
|
31
|
+
"-sl", "--slang",
|
|
32
|
+
action="store_true",
|
|
33
|
+
help="Mode: Accurately expand and decipher internet abbreviations and slang",
|
|
34
|
+
)
|
|
35
|
+
parser.add_argument(
|
|
36
|
+
"-s", "--shell",
|
|
37
|
+
action="store_true",
|
|
38
|
+
help="Mode: Generate an executable shell command from natural language"
|
|
39
|
+
)
|
|
40
|
+
parser.add_argument(
|
|
41
|
+
"-c", "--commit",
|
|
42
|
+
action="store_true",
|
|
43
|
+
help="Mode: Generate Git commit message from text or staged diffs (default)"
|
|
44
|
+
)
|
|
45
|
+
args = parser.parse_args()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
HOME_DIR = Path.home()
|
|
49
|
+
CONFIG_DIR = HOME_DIR / ".config" / "decrypt"
|
|
50
|
+
CONFIG_DIR.mkdir(parents=True, exist_ok=True)
|
|
51
|
+
class Settings(BaseSettings):
|
|
52
|
+
API_KEY: str | None = None
|
|
53
|
+
USER_LANGUAGE: str | None = "English"
|
|
54
|
+
model_config = SettingsConfigDict(env_file=CONFIG_DIR / ".env", env_file_encoding="utf-8", extra="ignore")
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
settings = Settings()
|
|
58
|
+
|
|
59
|
+
from google import genai
|
|
60
|
+
from google.genai import types
|
|
61
|
+
from google.genai.errors import APIError
|
|
62
|
+
from tenacity import retry, retry_if_exception, stop_after_attempt, wait_exponential
|
|
63
|
+
|
|
64
|
+
def is_retryable_error(exception):
|
|
65
|
+
#check HTTP status code
|
|
66
|
+
if getattr(exception, "http_status_code", None) in [429, 503]:
|
|
67
|
+
return True
|
|
68
|
+
|
|
69
|
+
#check string code gRPC (RESOURCE_EXHAUSTED — 429)
|
|
70
|
+
if getattr(exception, "code", None) in [429, 503, "RESOURCE_EXHAUSTED", "UNAVAILABLE"]:
|
|
71
|
+
return True
|
|
72
|
+
|
|
73
|
+
err_msg = str(exception).lower()
|
|
74
|
+
if "quota" in err_msg or "limit" in err_msg or "429" in err_msg:
|
|
75
|
+
return True
|
|
76
|
+
|
|
77
|
+
return False
|
|
78
|
+
|
|
79
|
+
@retry(
|
|
80
|
+
stop=stop_after_attempt(3),
|
|
81
|
+
wait=wait_exponential(multiplier=2, min=2, max=10),
|
|
82
|
+
retry=retry_if_exception(is_retryable_error),
|
|
83
|
+
reraise=True,
|
|
84
|
+
)
|
|
85
|
+
def _retry_request(client, model, contents, config):
|
|
86
|
+
return client.models.generate_content(
|
|
87
|
+
model=model, contents=contents, config=config
|
|
88
|
+
)
|
|
89
|
+
PROMPTS = {
|
|
90
|
+
"commit": (
|
|
91
|
+
"You are an expert Git assistant. Your task is to generate a highly professional commit message "
|
|
92
|
+
"following the Conventional Commits specification (e.g., feat(scope): message, fix(scope): message). "
|
|
93
|
+
"Analyze the provided code diff or raw user description. Use clear, concise English. "
|
|
94
|
+
"Return ONLY the raw text of the commit message. No markdown blocks, no quotation marks, no explanations."
|
|
95
|
+
),
|
|
96
|
+
"shell": (
|
|
97
|
+
"You are a DevOps and Linux Terminal expert. Convert the user's natural language request into a valid, "
|
|
98
|
+
"safe, and optimized shell command. Detect whether it looks like Windows PowerShell or Bash context if possible, "
|
|
99
|
+
"but default to cross-platform or standard syntax. "
|
|
100
|
+
"Return ONLY the executable command text. Do not wrap it in markdown code blocks, do not add comments."
|
|
101
|
+
),
|
|
102
|
+
"slang": (
|
|
103
|
+
"You are a linguistic assistant. Your job is to accurately expand and decipher "
|
|
104
|
+
"internet abbreviations, slang, and vowel-less text into normal, grammatically correct words "
|
|
105
|
+
"in the: {target_lang}. Maintain the original meaning. Do not invent unnecessary context. "
|
|
106
|
+
"Example: 'пр кд чд' should be translated as 'Привет, как дела, что делаешь?'. "
|
|
107
|
+
"Return ONLY the corrected text, without comments or formatting."
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
def decode_response(client: genai.Client, short_text:str, mode:str, target_lang: str):
|
|
111
|
+
models_pool = ["gemini-2.5-flash", "gemini-2.5-flash-lite"]
|
|
112
|
+
system_instruction = PROMPTS[mode]
|
|
113
|
+
if mode == "slang":
|
|
114
|
+
system_instruction = system_instruction.format(target_lang=target_lang)
|
|
115
|
+
|
|
116
|
+
config = types.GenerateContentConfig(
|
|
117
|
+
system_instruction=system_instruction,
|
|
118
|
+
temperature=0.2 if mode != "slang" else 0.4,
|
|
119
|
+
max_output_tokens=350,
|
|
120
|
+
)
|
|
121
|
+
for current_model in models_pool:
|
|
122
|
+
try:
|
|
123
|
+
response = _retry_request(
|
|
124
|
+
client=client,
|
|
125
|
+
model=current_model,
|
|
126
|
+
contents=short_text,
|
|
127
|
+
config=config,
|
|
128
|
+
)
|
|
129
|
+
if response and response.text:
|
|
130
|
+
return response.text.strip()
|
|
131
|
+
return short_text
|
|
132
|
+
except APIError as e:
|
|
133
|
+
is_critical = getattr(e, "code", None) in [429, 503] or "429" in str(e) or "503" in str(e)
|
|
134
|
+
|
|
135
|
+
if current_model == models_pool[-1] or not is_critical:
|
|
136
|
+
if getattr(e, "code", None) == 429 or "429" in str(e):
|
|
137
|
+
return "\n\033[31m[Exhaustion Limit] Google has limited requests. Please wait 30-60 seconds.\033[0m"
|
|
138
|
+
return f"\033[31mGemini API Error (Status {e.code}): {e.message}\033[0m"
|
|
139
|
+
|
|
140
|
+
print(f"\033[33m[Fallback] {current_model} failed (Status {e.code}). Switching to backup model...\033[0m")
|
|
141
|
+
continue
|
|
142
|
+
|
|
143
|
+
except Exception as e:
|
|
144
|
+
if current_model == models_pool[-1]:
|
|
145
|
+
return f"Unexpected error: {e}"
|
|
146
|
+
continue
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def get_git_diff():
|
|
150
|
+
try:
|
|
151
|
+
result = subprocess.run(
|
|
152
|
+
["git", "diff", "--staged"],
|
|
153
|
+
capture_output=True,
|
|
154
|
+
text=True,
|
|
155
|
+
check=True
|
|
156
|
+
)
|
|
157
|
+
return result.stdout.strip()
|
|
158
|
+
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
159
|
+
return None
|
|
160
|
+
|
|
161
|
+
GREEN = "\033[92m"
|
|
162
|
+
BOLD = "\033[1m"
|
|
163
|
+
DIM = "\033[2m"
|
|
164
|
+
RST = "\033[0m"
|
|
165
|
+
BANNER = f"""{GREEN}{BOLD}
|
|
166
|
+
██████╗ ███████╗ ██████╗██████╗ ██╗ ██╗██████╗ ████████╗
|
|
167
|
+
██╔══██╗██╔════╝██╔════╝██╔══██╗╚██╗ ██╔╝██╔══██╗╚══██╔══╝
|
|
168
|
+
██║ ██║█████╗ ██║ ██████╔╝ ╚████╔╝ ██████╔╝ ██║
|
|
169
|
+
██║ ██║██╔══╝ ██║ ██╔══██╗ ╚██╔╝ ██╔═══╝ ██║
|
|
170
|
+
██████╔╝███████╗╚██████╗██║ ██║ ██║ ██║ ██║
|
|
171
|
+
╚═════╝ ╚══════╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ {RST}
|
|
172
|
+
{DIM}AI-powered CLI tool: Conventional Commits · Shell Commands · Slang Decoder{RST}
|
|
173
|
+
{DIM}v1.1 Author: github.com/REvDl{RST}
|
|
174
|
+
"""
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def main():
|
|
178
|
+
env_file = CONFIG_DIR / ".env"
|
|
179
|
+
if not env_file.exists() or args.config:
|
|
180
|
+
print(f"Creating config file at {env_file}")
|
|
181
|
+
api_key = input("Enter your Gemini API Key: ").strip()
|
|
182
|
+
lang = input("Enter default language: ").strip() or "English"
|
|
183
|
+
env_file.write_text(f"API_KEY={api_key}\nUSER_LANGUAGE={lang}\n", encoding="utf-8")
|
|
184
|
+
if args.config and not args.text:
|
|
185
|
+
print("Configuration updated successfully!")
|
|
186
|
+
return
|
|
187
|
+
global settings
|
|
188
|
+
settings = Settings()
|
|
189
|
+
if not settings.API_KEY:
|
|
190
|
+
print("Error. API KEY is missing")
|
|
191
|
+
return
|
|
192
|
+
target_language = args.lang if args.lang is not None else settings.USER_LANGUAGE
|
|
193
|
+
|
|
194
|
+
client = genai.Client(api_key=settings.API_KEY)
|
|
195
|
+
if args.slang:
|
|
196
|
+
mode = "slang"
|
|
197
|
+
elif args.shell:
|
|
198
|
+
mode = "shell"
|
|
199
|
+
elif args.commit:
|
|
200
|
+
mode = "commit"
|
|
201
|
+
else:
|
|
202
|
+
mode = "commit"
|
|
203
|
+
diff = None
|
|
204
|
+
if mode == "commit" and not args.text:
|
|
205
|
+
diff = get_git_diff()
|
|
206
|
+
|
|
207
|
+
if args.text or diff:
|
|
208
|
+
input_data = args.text
|
|
209
|
+
if mode == "commit" and not input_data:
|
|
210
|
+
input_data = f"Generate commit message for this diff:\n{diff}"
|
|
211
|
+
|
|
212
|
+
result = decode_response(client, input_data, mode, target_language)
|
|
213
|
+
print(result)
|
|
214
|
+
return
|
|
215
|
+
|
|
216
|
+
else:
|
|
217
|
+
print(BANNER)
|
|
218
|
+
if mode == "commit":
|
|
219
|
+
print("\033[33m[Git Notice] No staged changes found. Starting interactive mode...\033[0m")
|
|
220
|
+
try:
|
|
221
|
+
import readline
|
|
222
|
+
except ImportError:
|
|
223
|
+
pass
|
|
224
|
+
print(f"Interactive mode ({mode.upper()}). Language: {target_language}. Type 'exit' to quit.")
|
|
225
|
+
while True:
|
|
226
|
+
try:
|
|
227
|
+
user_text = input("> ")
|
|
228
|
+
if user_text.lower() in ["exit", "break"]:
|
|
229
|
+
break
|
|
230
|
+
if not user_text.strip():
|
|
231
|
+
continue
|
|
232
|
+
result = decode_response(client, user_text, mode, target_language)
|
|
233
|
+
print(f"\033[92m{result}\033[0m")
|
|
234
|
+
except (KeyboardInterrupt, EOFError):
|
|
235
|
+
print()
|
|
236
|
+
break
|
|
237
|
+
|
|
238
|
+
if __name__ == "__main__":
|
|
239
|
+
main()
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: decrypt
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: CLI tool for deciphering internet abbreviations using Gemini API
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: google-genai
|
|
8
|
+
Requires-Dist: pydantic-settings
|
|
9
|
+
Requires-Dist: tenacity
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
██████╗ ███████╗ ██████╗██████╗ ██╗ ██╗██████╗ ████████╗
|
|
13
|
+
██╔══██╗██╔════╝██╔════╝██╔══██╗╚██╗ ██╔╝██╔══██╗╚══██╔══╝
|
|
14
|
+
██║ ██║█████╗ ██║ ██████╔╝ ╚████╔╝ ██████╔╝ ██║
|
|
15
|
+
██║ ██║██╔══╝ ██║ ██╔══██╗ ╚██╔╝ ██╔═══╝ ██║
|
|
16
|
+
██████╔╝███████╗╚██████╗██║ ██║ ██║ ██║ ██║
|
|
17
|
+
╚═════╝ ╚══════╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
AI-powered CLI utility providing an operational bridge between natural language instructions, automatic Git commit generation, and contextual slang decoding using the Google Gemini API. Built for high performance and strict output isolation.
|
|
21
|
+
|
|
22
|
+
## Features
|
|
23
|
+
|
|
24
|
+
- **Automated Commit Generation (Default Mode):** Automatically extracts and staging-analyses active local diffs via `git diff --staged` to generate professional, clean Conventional Commits messages.
|
|
25
|
+
- **Natural Language Shell Commands (`-s` / `--shell`):** Converts loose technical intents into valid, optimized, executable Bash or cross-platform terminal commands.
|
|
26
|
+
- **Accurate Slang & Internet Abbreviation Decoder (`-sl` / `--slang`):** Recovers structure, expands short forms, and normalizes text lacking vowels or proper grammar into standard text for specified target languages.
|
|
27
|
+
- **Fault-Tolerant Fallback System:** Uses a multi-model architecture pool (`gemini-2.5-flash` -> `gemini-2.5-flash-lite`) combined with exponential backoff retries via `tenacity` to stay operational during 429 quota limits or 503 errors.
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
git clone [https://github.com/REvDl/Scripts.git](https://github.com/REvDl/Scripts.git)
|
|
33
|
+
cd Scripts/automation_tool/DecrypMessage
|
|
34
|
+
pip install .
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Configuration
|
|
38
|
+
|
|
39
|
+
On the initial execution, the application will automatically prompt you to enter your **Gemini API Key** and preferred **default language**. These credentials are saved to a local configuration file.
|
|
40
|
+
|
|
41
|
+
- **Storage Location:** `~/.config/decrypt/.env`
|
|
42
|
+
- **Manual Reset Command:** `decrypt --config`
|
|
43
|
+
|
|
44
|
+
## Technical Reference & CLI Arguments
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
usage: decrypt [-h] [--lang LANG] [--config] [-sl] [-s] [-c] [text]
|
|
48
|
+
|
|
49
|
+
AI-powered CLI tool
|
|
50
|
+
• Conventional Commits
|
|
51
|
+
• Shell Commands
|
|
52
|
+
• Slang Decoder
|
|
53
|
+
|
|
54
|
+
positional arguments:
|
|
55
|
+
text Optional text input. Commit mode (default): if empty, uses git diff;
|
|
56
|
+
if provided, generates commit from this description.
|
|
57
|
+
|
|
58
|
+
options:
|
|
59
|
+
-h, --help show this help message and exit
|
|
60
|
+
--lang LANG Transcription language (default from .env)
|
|
61
|
+
--config Force re-configure API key and language
|
|
62
|
+
-sl, --slang Mode: Accurately expand and decipher internet abbreviations and slang
|
|
63
|
+
-s, --shell Mode: Generate an executable shell command from natural language
|
|
64
|
+
-c, --commit Mode: Generate Git commit message from text or staged diffs (default)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Usage Examples
|
|
68
|
+
|
|
69
|
+
### 1. Generating Conventional Commits
|
|
70
|
+
|
|
71
|
+
Stage your local changes and execute the default command pipeline:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
git add src/core.py
|
|
75
|
+
decrypt
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Alternatively, pass raw text input directly through standard arguments to format a manual draft:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
decrypt "fixed a broken connections pooling bug inside the database wrapper"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 2. Translating Natural Language to Terminal Syntax
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
decrypt -s "find all json files in the current folder larger than 50 megabytes and delete them"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 3. Expanding Slang / Chat History
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
decrypt -sl "hru btw" --lang "English"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 4. Interactive Mode (REPL)
|
|
97
|
+
|
|
98
|
+
Executing the engine without positional string parameters drops down into a low-overhead, persistent shell environment running standard loops:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
decrypt -s
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
```text
|
|
105
|
+
Interactive mode (SHELL). Language: English. Type 'exit' to quit.
|
|
106
|
+
> list all docker containers running on port 80
|
|
107
|
+
docker ps --filter "publish=80"
|
|
108
|
+
>
|
|
109
|
+
```
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
decrypt/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
decrypt/main.py,sha256=8bNaw8thdOZW7jL3Vks-lhrAVQVfLZvf3pW384BzlF4,9461
|
|
3
|
+
decrypt-1.1.0.dist-info/METADATA,sha256=BCURDtCaMEOQncusGGi8xQTbHmTq4lERpaZT3lxc_6g,4642
|
|
4
|
+
decrypt-1.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
5
|
+
decrypt-1.1.0.dist-info/entry_points.txt,sha256=fMFZsZ3VB8xLz7-oM99TY_XurhA2NlvSbdjfY06NiZc,46
|
|
6
|
+
decrypt-1.1.0.dist-info/top_level.txt,sha256=VpR96epk6XDQXZbrClSj4oF7FTPvVgb_u601JaTD4ko,8
|
|
7
|
+
decrypt-1.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
decrypt
|