ayechat-dev 0.36.8.20260126124453__py3-none-any.whl → 0.36.9.20260201141756__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.
- aye/controller/repl.py +42 -1
- aye/plugins/shell_executor.py +5 -3
- aye/presenter/repl_ui.py +1 -1
- {ayechat_dev-0.36.8.20260126124453.dist-info → ayechat_dev-0.36.9.20260201141756.dist-info}/METADATA +1 -1
- {ayechat_dev-0.36.8.20260126124453.dist-info → ayechat_dev-0.36.9.20260201141756.dist-info}/RECORD +9 -9
- {ayechat_dev-0.36.8.20260126124453.dist-info → ayechat_dev-0.36.9.20260201141756.dist-info}/WHEEL +0 -0
- {ayechat_dev-0.36.8.20260126124453.dist-info → ayechat_dev-0.36.9.20260201141756.dist-info}/entry_points.txt +0 -0
- {ayechat_dev-0.36.8.20260126124453.dist-info → ayechat_dev-0.36.9.20260201141756.dist-info}/licenses/LICENSE +0 -0
- {ayechat_dev-0.36.8.20260126124453.dist-info → ayechat_dev-0.36.9.20260201141756.dist-info}/top_level.txt +0 -0
aye/controller/repl.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import json
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import Optional, Any
|
|
4
|
+
from typing import Optional, Any, List
|
|
5
5
|
import shlex
|
|
6
6
|
import threading
|
|
7
7
|
import glob
|
|
@@ -252,6 +252,34 @@ def create_prompt_session(completer: Any, completion_style: str = "readline") ->
|
|
|
252
252
|
)
|
|
253
253
|
|
|
254
254
|
|
|
255
|
+
def _execute_forced_shell_command(command: str, args: List[str], conf: Any) -> None:
|
|
256
|
+
"""Execute a shell command with force flag (bypasses command validation).
|
|
257
|
+
|
|
258
|
+
Used when user prefixes input with '!' to force shell execution.
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
command: The command to execute
|
|
262
|
+
args: List of arguments to pass to the command
|
|
263
|
+
conf: Configuration object with plugin_manager
|
|
264
|
+
"""
|
|
265
|
+
telemetry.record_command(command, has_args=len(args) > 0, prefix=_CMD_PREFIX)
|
|
266
|
+
shell_response = conf.plugin_manager.handle_command(
|
|
267
|
+
"execute_shell_command",
|
|
268
|
+
{"command": command, "args": args, "force": True}
|
|
269
|
+
)
|
|
270
|
+
if shell_response is not None:
|
|
271
|
+
if "stdout" in shell_response or "stderr" in shell_response:
|
|
272
|
+
if shell_response.get("stdout", "").strip():
|
|
273
|
+
rprint(shell_response["stdout"])
|
|
274
|
+
if shell_response.get("stderr", "").strip():
|
|
275
|
+
rprint(f"[yellow]{shell_response['stderr']}[/]")
|
|
276
|
+
if "error" in shell_response:
|
|
277
|
+
rprint(f"[red]Error:[/] {shell_response['error']}")
|
|
278
|
+
elif "message" in shell_response:
|
|
279
|
+
rprint(shell_response["message"])
|
|
280
|
+
else:
|
|
281
|
+
rprint(f"[red]Error:[/] Failed to execute shell command")
|
|
282
|
+
|
|
255
283
|
|
|
256
284
|
def chat_repl(conf: Any) -> None:
|
|
257
285
|
is_first_run = run_first_time_tutorial_if_needed()
|
|
@@ -327,6 +355,14 @@ def chat_repl(conf: Any) -> None:
|
|
|
327
355
|
chat_id = new_chat_id
|
|
328
356
|
continue
|
|
329
357
|
|
|
358
|
+
# Check for '!' prefix - force shell execution
|
|
359
|
+
force_shell = False
|
|
360
|
+
if prompt.strip().startswith('!'):
|
|
361
|
+
force_shell = True
|
|
362
|
+
prompt = prompt.strip()[1:] # Remove the '!'
|
|
363
|
+
if not prompt.strip():
|
|
364
|
+
continue # Nothing after the '!', skip
|
|
365
|
+
|
|
330
366
|
if not prompt.strip():
|
|
331
367
|
continue
|
|
332
368
|
tokens = shlex.split(prompt.strip(), posix=False)
|
|
@@ -340,6 +376,11 @@ def chat_repl(conf: Any) -> None:
|
|
|
340
376
|
|
|
341
377
|
original_first, lowered_first = tokens[0], tokens[0].lower()
|
|
342
378
|
|
|
379
|
+
# If force_shell is True, execute as shell command directly and skip all other checks
|
|
380
|
+
if force_shell:
|
|
381
|
+
_execute_forced_shell_command(original_first, tokens[1:], conf)
|
|
382
|
+
continue
|
|
383
|
+
|
|
343
384
|
# Normalize slash-prefixed commands: /restore -> restore, /model -> model, etc.
|
|
344
385
|
if lowered_first.startswith('/'):
|
|
345
386
|
lowered_first = lowered_first[1:] # Remove leading slash
|
aye/plugins/shell_executor.py
CHANGED
|
@@ -10,7 +10,7 @@ from rich import print as rprint
|
|
|
10
10
|
|
|
11
11
|
class ShellExecutorPlugin(Plugin):
|
|
12
12
|
name = "shell_executor"
|
|
13
|
-
version = "1.0.
|
|
13
|
+
version = "1.0.3" # Added force parameter for ! prefix execution
|
|
14
14
|
premium = "free"
|
|
15
15
|
|
|
16
16
|
# Known interactive commands that require a TTY (add more as needed)
|
|
@@ -143,15 +143,17 @@ class ShellExecutorPlugin(Plugin):
|
|
|
143
143
|
"returncode": e.returncode
|
|
144
144
|
}
|
|
145
145
|
except FileNotFoundError:
|
|
146
|
-
return
|
|
146
|
+
return {"error": f"Command not found: {command}", "stdout": "", "stderr": "", "returncode": 127}
|
|
147
147
|
|
|
148
148
|
def on_command(self, command_name: str, params: Dict[str, Any]) -> Optional[Dict[str, Any]]:
|
|
149
149
|
"""Handle shell command execution through plugin system."""
|
|
150
150
|
if command_name == "execute_shell_command":
|
|
151
151
|
command = params.get("command", "")
|
|
152
152
|
args = params.get("args", [])
|
|
153
|
+
force = params.get("force", False)
|
|
153
154
|
|
|
154
|
-
|
|
155
|
+
# If force is False, validate the command exists first
|
|
156
|
+
if not force and not self._is_valid_command(command):
|
|
155
157
|
return None # Command not found or not executable
|
|
156
158
|
|
|
157
159
|
full_cmd_str = self._build_full_cmd(command, args)
|
aye/presenter/repl_ui.py
CHANGED
|
@@ -87,7 +87,7 @@ def print_help_message():
|
|
|
87
87
|
commands = [
|
|
88
88
|
# Some commands are intentionally undocumented: keep them as such.
|
|
89
89
|
("@filename", "Include a file in your prompt inline (e.g., \"explain @main.py\"). Supports wildcards (e.g., @*.py, @src/*.js)."),
|
|
90
|
-
("
|
|
90
|
+
("!command", "Force shell execution (e.g., \"!echo hello\")."),
|
|
91
91
|
("model", "Select a different model. Selection will persist between sessions."),
|
|
92
92
|
(r"verbose \[on|off]", "Toggle verbose mode to increase or decrease chattiness (on/off, persists between sessions)"),
|
|
93
93
|
(r"completion \[readline|multi]", "Switch auto-completion style (readline or multi, persists between sessions)"),
|
{ayechat_dev-0.36.8.20260126124453.dist-info → ayechat_dev-0.36.9.20260201141756.dist-info}/RECORD
RENAMED
|
@@ -8,7 +8,7 @@ aye/controller/commands.py,sha256=sXmK_sgNBrw9Fs7mKcr93-wsu740ZlvWSisQfS-1EUE,12
|
|
|
8
8
|
aye/controller/llm_handler.py,sha256=BSBab6onF9BYiFndYW1647eEy377Vt52trzu0Qjm4bQ,5075
|
|
9
9
|
aye/controller/llm_invoker.py,sha256=p_Vk2a3YrWKwDupLfSVRinR5llDfq1Fb_f7WrYozK6M,14127
|
|
10
10
|
aye/controller/plugin_manager.py,sha256=9ZuITyA5sQJJJU-IntLQ1SsxXsDnbgZKPOF4e9VmsEU,3018
|
|
11
|
-
aye/controller/repl.py,sha256=
|
|
11
|
+
aye/controller/repl.py,sha256=UCgH4bdL3AUYjgD6KPtIOeysCNaYbs0TvEwS3Zql8kY,26552
|
|
12
12
|
aye/controller/tutorial.py,sha256=lc92jOcJOYCVrrjTEF0Suk4-8jn-ku98kTJEIL8taUA,7254
|
|
13
13
|
aye/controller/util.py,sha256=gBmktDEaY63OKhgzZHA2IFrgcWUN_Iphn3e1daEeUBI,2828
|
|
14
14
|
aye/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -45,17 +45,17 @@ aye/plugins/completer.py,sha256=qhxke5Q76P2u0LojSIL3V48RTNG5tWL-5-TK5tNutrE,1389
|
|
|
45
45
|
aye/plugins/local_model.py,sha256=Jj4bHiPYaLMx6zTrKamBPrkiGQQ787jWz0F4ojRCjlQ,14394
|
|
46
46
|
aye/plugins/offline_llm.py,sha256=qFmd1e8Lbl7yiMgXpXjOQkQTNxOk0_WXU7km2DTKXGY,13357
|
|
47
47
|
aye/plugins/plugin_base.py,sha256=t5hTOnA0dZC237BnseAgdXbOqErlSCNLUo_Uul09TSw,1673
|
|
48
|
-
aye/plugins/shell_executor.py,sha256=
|
|
48
|
+
aye/plugins/shell_executor.py,sha256=a0mlZnQeURONdtPM7iageTcQ8PiNLQbjxoY54EsS32o,7502
|
|
49
49
|
aye/plugins/slash_completer.py,sha256=MyrDTC_KwVWhtD_kpHbu0WjSjmSAWp36PwOBQczSuXA,2252
|
|
50
50
|
aye/presenter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
51
51
|
aye/presenter/cli_ui.py,sha256=8oHqQiMHO8hHXCTdqWoquMkJBshl2_3-YWN6SQnlbKg,8449
|
|
52
52
|
aye/presenter/diff_presenter.py,sha256=cbxfOEqGomPTDvQpKdybfYeNUD2DYVAl85j1uy5--Ww,12512
|
|
53
|
-
aye/presenter/repl_ui.py,sha256=
|
|
53
|
+
aye/presenter/repl_ui.py,sha256=J6QlcFa_qvV00NP1OS5xyhDuJcfNcCrADZq9ZFY2GKQ,7917
|
|
54
54
|
aye/presenter/streaming_ui.py,sha256=_3tBEuNH9UQ9Gyq2yuvRfX4SWVkcGMYirEUGj-MXVJ0,12768
|
|
55
55
|
aye/presenter/ui_utils.py,sha256=6KXR4_ZZZUdF5pCHrPqO8yywlQk7AOzWe-2B4Wj_-ZQ,5441
|
|
56
|
-
ayechat_dev-0.36.
|
|
57
|
-
ayechat_dev-0.36.
|
|
58
|
-
ayechat_dev-0.36.
|
|
59
|
-
ayechat_dev-0.36.
|
|
60
|
-
ayechat_dev-0.36.
|
|
61
|
-
ayechat_dev-0.36.
|
|
56
|
+
ayechat_dev-0.36.9.20260201141756.dist-info/licenses/LICENSE,sha256=U1ou6lkMKmPo16-E9YowIu3goU7sOWKUprGo0AOA72s,1065
|
|
57
|
+
ayechat_dev-0.36.9.20260201141756.dist-info/METADATA,sha256=1whf_VoyU8Vt49wLxnbCTCtt6vLGS1NtXCsJDaRqFQI,7718
|
|
58
|
+
ayechat_dev-0.36.9.20260201141756.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
59
|
+
ayechat_dev-0.36.9.20260201141756.dist-info/entry_points.txt,sha256=KGsOma6szoefNN6vHozg3Pbf1fjZ7ZbmwrOiVwBd0Ik,41
|
|
60
|
+
ayechat_dev-0.36.9.20260201141756.dist-info/top_level.txt,sha256=7WZL0LOx4-GKKvgU1mtI5s4Dhk2OdieVZZvVnxFJHr8,4
|
|
61
|
+
ayechat_dev-0.36.9.20260201141756.dist-info/RECORD,,
|
{ayechat_dev-0.36.8.20260126124453.dist-info → ayechat_dev-0.36.9.20260201141756.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|