shellmate-cli 3.0.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.
- shellmate/__init__.py +0 -0
- shellmate/adapters/__init__.py +67 -0
- shellmate/adapters/bash_adapter.sh +7 -0
- shellmate/adapters/ble_adapter.sh +350 -0
- shellmate/adapters/powershell_adapter.ps1 +417 -0
- shellmate/adapters/powershell_predictor.ps1 +97 -0
- shellmate/adapters/zsh_adapter.zsh +8 -0
- shellmate/agents/__init__.py +23 -0
- shellmate/agents/base.py +248 -0
- shellmate/agents/chain_patterns.yaml +98 -0
- shellmate/agents/command_chain.py +322 -0
- shellmate/agents/context_gatherer.py +175 -0
- shellmate/agents/environment.py +363 -0
- shellmate/agents/librarian.py +502 -0
- shellmate/agents/query.py +415 -0
- shellmate/agents/repomix_backend.py +171 -0
- shellmate/agents/watcher.py +266 -0
- shellmate/cache/__init__.py +0 -0
- shellmate/cache/semantic_cache.py +41 -0
- shellmate/cli/__init__.py +0 -0
- shellmate/cli/commands/__init__.py +27 -0
- shellmate/cli/commands/analyze.py +5 -0
- shellmate/cli/commands/config.py +319 -0
- shellmate/cli/commands/configure.py +118 -0
- shellmate/cli/commands/disable.py +11 -0
- shellmate/cli/commands/enable.py +49 -0
- shellmate/cli/commands/init.py +412 -0
- shellmate/cli/commands/install.py +242 -0
- shellmate/cli/commands/migrate.py +147 -0
- shellmate/cli/commands/status.py +31 -0
- shellmate/cli/commands/uninstall.py +78 -0
- shellmate/cli/main.py +114 -0
- shellmate/cli/parser.py +184 -0
- shellmate/cli/version.py +1 -0
- shellmate/completion/__init__.py +4 -0
- shellmate/completion/bash_adapter.py +145 -0
- shellmate/config/__init__.py +33 -0
- shellmate/config/credentials.py +120 -0
- shellmate/config/defaults.py +88 -0
- shellmate/config/manager.py +94 -0
- shellmate/config/paths.py +77 -0
- shellmate/config/secrets.py +66 -0
- shellmate/daemon/__init__.py +0 -0
- shellmate/daemon/lifecycle.py +308 -0
- shellmate/daemon/observability.py +82 -0
- shellmate/daemon/pipeline.py +119 -0
- shellmate/daemon/server.py +605 -0
- shellmate/daemon/session.py +170 -0
- shellmate/daemon/startup_ui.py +43 -0
- shellmate/environment/__init__.py +0 -0
- shellmate/environment/detector.py +130 -0
- shellmate/ipc/__init__.py +0 -0
- shellmate/ipc/client.py +210 -0
- shellmate/ipc/ps_client.py +190 -0
- shellmate/orchestration/__init__.py +3 -0
- shellmate/orchestration/analysis_graph.py +1274 -0
- shellmate/orchestration/state.py +35 -0
- shellmate/parser/__init__.py +0 -0
- shellmate/parser/command_parser.py +111 -0
- shellmate/plugins/__init__.py +0 -0
- shellmate/plugins/base.py +80 -0
- shellmate/plugins/loader.py +41 -0
- shellmate/providers/__init__.py +0 -0
- shellmate/providers/base.py +97 -0
- shellmate/providers/groq_command_guide.py +108 -0
- shellmate/providers/groq_provider.py +127 -0
- shellmate/providers/groq_supervisor.py +78 -0
- shellmate/providers/openrouter_provider.py +149 -0
- shellmate/providers/router.py +272 -0
- shellmate/providers/validate_keys.py +98 -0
- shellmate/providers/xai_provider.py +142 -0
- shellmate/rules/__init__.py +0 -0
- shellmate/rules/catastrophic.yaml +96 -0
- shellmate/rules/catastrophic_matcher.py +167 -0
- shellmate/rules/definitions/__init__.py +0 -0
- shellmate/rules/definitions/file_deletion.yaml +54 -0
- shellmate/rules/definitions/filesystem.yaml +43 -0
- shellmate/rules/definitions/network_execution.yaml +46 -0
- shellmate/rules/definitions/permissions.yaml +54 -0
- shellmate/rules/definitions/process_control.yaml +37 -0
- shellmate/rules/definitions/system_destruction.yaml +67 -0
- shellmate/rules/engine.py +200 -0
- shellmate/sanitizer/__init__.py +0 -0
- shellmate/sanitizer/typo_detector.py +114 -0
- shellmate/ui/__init__.py +10 -0
- shellmate/ui/analysis.py +164 -0
- shellmate/ui/annotations.py +232 -0
- shellmate/ui/banner.py +49 -0
- shellmate/ui/progress.py +126 -0
- shellmate/ui/runtime/__init__.py +15 -0
- shellmate/ui/runtime/console_factory.py +65 -0
- shellmate/ui/runtime/live_scene.py +116 -0
- shellmate/ui/runtime/motion_policy.py +69 -0
- shellmate/ui/runtime/tokens.py +47 -0
- shellmate/ui/scenes/__init__.py +24 -0
- shellmate/ui/scenes/enable.py +316 -0
- shellmate/ui/scenes/help.py +53 -0
- shellmate/ui/scenes/stages.py +128 -0
- shellmate/ui/scenes/status.py +181 -0
- shellmate/ui/status.py +3 -0
- shellmate_cli-3.0.0.dist-info/METADATA +352 -0
- shellmate_cli-3.0.0.dist-info/RECORD +106 -0
- shellmate_cli-3.0.0.dist-info/WHEEL +5 -0
- shellmate_cli-3.0.0.dist-info/entry_points.txt +3 -0
- shellmate_cli-3.0.0.dist-info/licenses/LICENSE +21 -0
- shellmate_cli-3.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"""Status scene — quiet assemble, no hardcoded width."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import time
|
|
6
|
+
from typing import Callable, Optional
|
|
7
|
+
|
|
8
|
+
from rich.console import Console, Group
|
|
9
|
+
from rich.panel import Panel
|
|
10
|
+
from rich.table import Table
|
|
11
|
+
from rich.text import Text
|
|
12
|
+
|
|
13
|
+
from shellmate.ui.runtime import tokens
|
|
14
|
+
from shellmate.ui.runtime.console_factory import ConsoleFactory
|
|
15
|
+
from shellmate.ui.runtime.live_scene import LiveScene
|
|
16
|
+
from shellmate.ui.runtime.motion_policy import MotionPolicy
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _status_tag(status: str) -> Text:
|
|
20
|
+
if status in ("running", "ready"):
|
|
21
|
+
return Text(" * ", style="bold green") + Text("Running", style="green")
|
|
22
|
+
if status == "stopped":
|
|
23
|
+
return Text(" o ", style="bold red") + Text("Stopped", style="red")
|
|
24
|
+
if status == "error":
|
|
25
|
+
return Text(" x ", style="bold red") + Text("Error", style="red")
|
|
26
|
+
if status == "starting":
|
|
27
|
+
return Text(" ~ ", style="bold yellow") + Text("Starting", style="yellow")
|
|
28
|
+
return Text(f" {status}", style="dim")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def build_status_renderable(
|
|
32
|
+
daemon_status: dict,
|
|
33
|
+
provider_status: dict,
|
|
34
|
+
credential_status: dict,
|
|
35
|
+
agent_status: dict | None = None,
|
|
36
|
+
config: dict | None = None,
|
|
37
|
+
*,
|
|
38
|
+
console_width: int = 96,
|
|
39
|
+
) -> Group:
|
|
40
|
+
width = tokens.content_width(console_width)
|
|
41
|
+
daemon_stat = daemon_status.get("status", "stopped")
|
|
42
|
+
status_indicator = _status_tag(daemon_stat)
|
|
43
|
+
|
|
44
|
+
info_lines = [status_indicator]
|
|
45
|
+
if daemon_stat == "running":
|
|
46
|
+
pid = daemon_status.get("pid", "?")
|
|
47
|
+
cwd = daemon_status.get("cwd", "?")
|
|
48
|
+
uptime = daemon_status.get("uptime_seconds", 0)
|
|
49
|
+
last_check = daemon_status.get("last_health_check")
|
|
50
|
+
info_lines.append(Text(f" PID: {pid}", style=tokens.MUTED))
|
|
51
|
+
info_lines.append(Text(f" CWD: {cwd}", style=tokens.MUTED))
|
|
52
|
+
if uptime:
|
|
53
|
+
uptime_str = (
|
|
54
|
+
f"{int(uptime // 3600):02d}:"
|
|
55
|
+
f"{int((uptime % 3600) // 60):02d}:"
|
|
56
|
+
f"{int(uptime % 60):02d}"
|
|
57
|
+
)
|
|
58
|
+
info_lines.append(Text(f" Uptime: {uptime_str}", style=tokens.MUTED))
|
|
59
|
+
if last_check:
|
|
60
|
+
info_lines.append(Text(f" Health: {last_check:.0f}s ago", style=tokens.MUTED))
|
|
61
|
+
|
|
62
|
+
panels: list[Panel] = [
|
|
63
|
+
Panel(
|
|
64
|
+
Group(*info_lines),
|
|
65
|
+
border_style="green" if daemon_stat == "running" else "red",
|
|
66
|
+
title="[bold]Daemon[/]",
|
|
67
|
+
padding=(1, 2),
|
|
68
|
+
width=width,
|
|
69
|
+
expand=False,
|
|
70
|
+
)
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
if agent_status:
|
|
74
|
+
agent_table = Table(show_header=False, box=None, padding=(0, 2))
|
|
75
|
+
agent_table.add_column("Agent", style=tokens.ACCENT)
|
|
76
|
+
agent_table.add_column("Status")
|
|
77
|
+
for name, st in agent_status.items():
|
|
78
|
+
agent_table.add_row(f" {name}", _status_tag(st))
|
|
79
|
+
panels.append(
|
|
80
|
+
Panel(
|
|
81
|
+
Group(Text("Agent Status", style=tokens.TITLE), Text(""), agent_table),
|
|
82
|
+
border_style=tokens.ACCENT,
|
|
83
|
+
title="[bold]Agents[/]",
|
|
84
|
+
padding=(1, 2),
|
|
85
|
+
width=width,
|
|
86
|
+
expand=False,
|
|
87
|
+
)
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
provider_table = Table(show_header=False, box=None, padding=(0, 2))
|
|
91
|
+
provider_table.add_column("Provider", style=tokens.ACCENT)
|
|
92
|
+
provider_table.add_column("Configured")
|
|
93
|
+
provider_table.add_column("Status")
|
|
94
|
+
for name, info in provider_status.items():
|
|
95
|
+
configured = info.get("configured", False)
|
|
96
|
+
conf_tag = Text("+", style=tokens.SUCCESS) if configured else Text("x", style=tokens.ERROR)
|
|
97
|
+
provider_table.add_row(f" {name}", conf_tag, info.get("status", "unknown"))
|
|
98
|
+
panels.append(
|
|
99
|
+
Panel(
|
|
100
|
+
Group(Text("Providers", style=tokens.TITLE), Text(""), provider_table),
|
|
101
|
+
border_style=tokens.ACCENT,
|
|
102
|
+
title="[bold]Providers[/]",
|
|
103
|
+
padding=(1, 2),
|
|
104
|
+
width=width,
|
|
105
|
+
expand=False,
|
|
106
|
+
)
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
cred_table = Table(show_header=False, box=None, padding=(0, 2))
|
|
110
|
+
cred_table.add_column("Key", style=tokens.ACCENT)
|
|
111
|
+
cred_table.add_column("Configured")
|
|
112
|
+
cred_table.add_column("Label")
|
|
113
|
+
for key, info in credential_status.items():
|
|
114
|
+
configured = info.get("configured", False)
|
|
115
|
+
conf_tag = Text("+", style=tokens.SUCCESS) if configured else Text("x", style=tokens.ERROR)
|
|
116
|
+
cred_table.add_row(f" {key}", conf_tag, info.get("label", ""))
|
|
117
|
+
panels.append(
|
|
118
|
+
Panel(
|
|
119
|
+
Group(Text("Credentials", style=tokens.TITLE), Text(""), cred_table),
|
|
120
|
+
border_style=tokens.ACCENT,
|
|
121
|
+
title="[bold]Credentials[/]",
|
|
122
|
+
padding=(1, 2),
|
|
123
|
+
width=width,
|
|
124
|
+
expand=False,
|
|
125
|
+
)
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
if config:
|
|
129
|
+
latency = config.get("latency_targets", {})
|
|
130
|
+
lat_lines = [Text("Latency Targets", style=tokens.TITLE)]
|
|
131
|
+
for key, value in latency.items():
|
|
132
|
+
lat_lines.append(Text(f" {key}: {value}ms", style=tokens.MUTED))
|
|
133
|
+
panels.append(
|
|
134
|
+
Panel(Group(*lat_lines), border_style=tokens.ACCENT, padding=(1, 2), width=width, expand=False)
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
# Separate with blank lines via Group of panels + empty Text
|
|
138
|
+
parts: list = []
|
|
139
|
+
for i, p in enumerate(panels):
|
|
140
|
+
if i:
|
|
141
|
+
parts.append(Text(""))
|
|
142
|
+
parts.append(p)
|
|
143
|
+
return Group(*parts)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def render_status(
|
|
147
|
+
daemon_status: dict,
|
|
148
|
+
provider_status: dict,
|
|
149
|
+
credential_status: dict,
|
|
150
|
+
agent_status: dict = None,
|
|
151
|
+
config: dict = None,
|
|
152
|
+
*,
|
|
153
|
+
console: Console | None = None,
|
|
154
|
+
plain: bool | None = None,
|
|
155
|
+
sleep_fn: Callable[[float], None] = time.sleep,
|
|
156
|
+
):
|
|
157
|
+
"""Render status with a light assemble animation when interactive."""
|
|
158
|
+
cf = ConsoleFactory(no_color=bool(plain))
|
|
159
|
+
c = console or cf.create()
|
|
160
|
+
is_plain = cf.is_plain() if plain is None else plain
|
|
161
|
+
|
|
162
|
+
full = build_status_renderable(
|
|
163
|
+
daemon_status,
|
|
164
|
+
provider_status,
|
|
165
|
+
credential_status,
|
|
166
|
+
agent_status,
|
|
167
|
+
config,
|
|
168
|
+
console_width=c.width,
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
policy = MotionPolicy(plain=is_plain, min_dwell_ms=60, stagger_ms=20, max_artificial_ms_after_ready=400)
|
|
172
|
+
scene = LiveScene(c, plain=is_plain)
|
|
173
|
+
header = Text(f"ShellMate status", style=f"bold {tokens.ACCENT}")
|
|
174
|
+
try:
|
|
175
|
+
scene.start(header)
|
|
176
|
+
sleep_fn(policy.stagger_seconds())
|
|
177
|
+
scene.update(Group(header, Text(""), full))
|
|
178
|
+
sleep_fn(policy.dwell_seconds())
|
|
179
|
+
except Exception:
|
|
180
|
+
pass
|
|
181
|
+
scene.settle(full)
|
shellmate/ui/status.py
ADDED
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: shellmate-cli
|
|
3
|
+
Version: 3.0.0
|
|
4
|
+
Summary: Intelligent shell autocomplete with consequence preview
|
|
5
|
+
Author: ShellMate Contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/sayan-does/shellmate
|
|
8
|
+
Project-URL: Repository, https://github.com/sayan-does/shellmate
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Environment :: Console
|
|
17
|
+
Classifier: Topic :: Utilities
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: click>=8.0
|
|
22
|
+
Requires-Dist: pyyaml>=6.0
|
|
23
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
24
|
+
Requires-Dist: groq>=0.4.0
|
|
25
|
+
Requires-Dist: openai>=1.0.0
|
|
26
|
+
Requires-Dist: numpy>=1.24.0
|
|
27
|
+
Requires-Dist: langgraph>=1.2.0
|
|
28
|
+
Requires-Dist: langchain-core>=1.4.0
|
|
29
|
+
Requires-Dist: rich>=13.0.0
|
|
30
|
+
Requires-Dist: psutil>=5.9.0
|
|
31
|
+
Requires-Dist: watchdog>=4.0.0
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: build; extra == "dev"
|
|
34
|
+
Requires-Dist: twine; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest; extra == "dev"
|
|
36
|
+
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
37
|
+
Provides-Extra: windows-test
|
|
38
|
+
Requires-Dist: pywinpty>=2.0.0; sys_platform == "win32" and extra == "windows-test"
|
|
39
|
+
Requires-Dist: pyte>=0.8.1; extra == "windows-test"
|
|
40
|
+
Dynamic: license-file
|
|
41
|
+
|
|
42
|
+
# ShellMate
|
|
43
|
+
|
|
44
|
+
Intelligent shell autocomplete with consequence preview.
|
|
45
|
+
|
|
46
|
+
**Version:** 3.0.0
|
|
47
|
+
**Package:** [`shellmate-cli`](https://pypi.org/project/shellmate-cli/)
|
|
48
|
+
**License:** MIT
|
|
49
|
+
**Python:** 3.10+
|
|
50
|
+
|
|
51
|
+
ShellMate watches what you type and shows **inline risk annotations** before you press Enter. A background daemon analyzes commands with deterministic rules, an exact-match cache, and a LangGraph pipeline that pulls project context plus Groq / OpenRouter / Grok (xAI) for AI risk and remediation.
|
|
52
|
+
|
|
53
|
+
## How it works
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
You type in the shell
|
|
57
|
+
→ ble.sh (Linux/WSL) or PSReadLine (Windows) adapter
|
|
58
|
+
→ IPC to daemon (TCP 127.0.0.1:9823)
|
|
59
|
+
→ LangGraph analysis pipeline
|
|
60
|
+
→ Inline annotation / confirmation gate
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
1. **Instant catastrophic check** — local YAML rules (`rules/catastrophic.yaml`), no API.
|
|
64
|
+
2. **Debounced partial analysis** — after a short pause while typing.
|
|
65
|
+
3. **Full analysis** — rules → cache → AI + context agents when risk is unclear.
|
|
66
|
+
|
|
67
|
+
## Installation
|
|
68
|
+
|
|
69
|
+
### From PyPI
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install shellmate-cli
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### From source
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
git clone https://github.com/sayan-does/shellmate.git
|
|
79
|
+
cd shellmate
|
|
80
|
+
pip install -e .
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Quick start
|
|
84
|
+
|
|
85
|
+
### 1. Prerequisites
|
|
86
|
+
|
|
87
|
+
| Platform | Required |
|
|
88
|
+
|----------|----------|
|
|
89
|
+
| Linux / WSL | [ble.sh](https://github.com/akinomyoga/ble.sh) (e.g. under `~/.local/share/blesh/ble.sh`) |
|
|
90
|
+
| Windows | PowerShell with PSReadLine |
|
|
91
|
+
| All | At least one of `GROQ_API_KEY`, `OPENROUTER_API_KEY`, or `XAI_API_KEY` |
|
|
92
|
+
|
|
93
|
+
### 2. Install hooks and configure keys
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
sm install # copy adapter → ~/.shellmate/adapters/ and append RC/profile hook
|
|
97
|
+
sm config # select provider (Groq / OpenRouter / Grok xAI), paste API key
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Dry-run without changing files:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
sm install --dry-run
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 3. Start the daemon
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
sm enable
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Starts the daemon for the current directory (Watcher, Librarian, and other agents). Check with `sm status`.
|
|
113
|
+
|
|
114
|
+
### 4. Type normally
|
|
115
|
+
|
|
116
|
+
Inline annotations appear under the line as you type. Catastrophic commands require a second Enter to confirm.
|
|
117
|
+
|
|
118
|
+
### 5. Stop / remove
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
sm disable # stop daemon
|
|
122
|
+
sm uninstall # remove shell hooks (keeps config)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Autocomplete features
|
|
126
|
+
|
|
127
|
+
ShellMate’s main UX is **in-shell autocomplete annotations** (not a separate `sm -a` command). Adapters hook ble.sh or PSReadLine and talk to the daemon over IPC.
|
|
128
|
+
|
|
129
|
+
### Two-phase typing feedback
|
|
130
|
+
|
|
131
|
+
| Phase | Latency | What happens |
|
|
132
|
+
|-------|---------|--------------|
|
|
133
|
+
| **1 — Instant** | <10ms, no API | `/instant-check` against `rules/catastrophic.yaml`. Blocking commands get an immediate annotation. |
|
|
134
|
+
| **2 — Debounced** | ~300ms after you pause | `/analyze-partial` runs the analysis pipeline and **replaces** the annotation in place with risk + badges. |
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
$ git push --force
|
|
138
|
+
[!] rewrites history [PROD] BH
|
|
139
|
+
|
|
140
|
+
$ rm -rf /
|
|
141
|
+
[!] BLOCKING - Type again to confirm
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Consequence preview (Tab × 2)
|
|
145
|
+
|
|
146
|
+
1. **First Tab** — completion / ghost-text suggestion
|
|
147
|
+
2. **Second Tab** — accept suggestion and show a **consequence preview** below the prompt:
|
|
148
|
+
|
|
149
|
+
```text
|
|
150
|
+
→ Force-pushes and rewrites remote history
|
|
151
|
+
→ Reversible: No | remote: origin/main
|
|
152
|
+
→ Safe alt: git push --force-with-lease
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
On HIGH / CRITICAL / blocking severity, Enter is gated until you confirm again.
|
|
156
|
+
|
|
157
|
+
| Platform | Completion surface |
|
|
158
|
+
|----------|-------------------|
|
|
159
|
+
| Linux / WSL (ble.sh) | Tab bound to ShellMate complete widget |
|
|
160
|
+
| PowerShell 7.2+ | PSReadLine predictor (`powershell_predictor.ps1`) when available |
|
|
161
|
+
| PowerShell 5.1 | Tab handler ghost-text fallback |
|
|
162
|
+
|
|
163
|
+
### Double-Enter confirmation
|
|
164
|
+
|
|
165
|
+
Dangerous commands do not run on the first Enter:
|
|
166
|
+
|
|
167
|
+
1. First Enter → blocked; annotation asks you to confirm
|
|
168
|
+
2. Second Enter (same command) → allowed
|
|
169
|
+
|
|
170
|
+
Applies to catastrophic instant matches and to HIGH/CRITICAL consequence previews.
|
|
171
|
+
|
|
172
|
+
### Annotation badges
|
|
173
|
+
|
|
174
|
+
Short inline text under the command (ASCII-safe on all platforms):
|
|
175
|
+
|
|
176
|
+
| Kind | Examples |
|
|
177
|
+
|------|----------|
|
|
178
|
+
| Risk | `[OK]` `[i]` `[!]` `[!!]` `[X]` |
|
|
179
|
+
| Environment | `[PROD]` `[STAGE]` `[DEV]` `[CI]` |
|
|
180
|
+
| Time | `BH` (business hours) · `AH` (after hours) |
|
|
181
|
+
| Chain / consequence | `[BROKEN]` `[ESCALATION]` `[IRREVERSIBLE]` |
|
|
182
|
+
|
|
183
|
+
### Bracket syntax
|
|
184
|
+
|
|
185
|
+
Typed as part of the command line; adapters/daemon strip and honor them:
|
|
186
|
+
|
|
187
|
+
| Syntax | Purpose | Example |
|
|
188
|
+
|--------|---------|---------|
|
|
189
|
+
| `[?…]` | Ask a question about the command | `docker rm $(docker ps -aq) [?why dangerous]` |
|
|
190
|
+
| `[!…]` | Directive to the analyzer | `rm -rf /tmp [!force]` |
|
|
191
|
+
| `[@key=value]` | Override context (e.g. environment) | `git reset --hard [@env=production]` |
|
|
192
|
+
|
|
193
|
+
### Surfaces
|
|
194
|
+
|
|
195
|
+
| Adapter | Shell | Role |
|
|
196
|
+
|---------|-------|------|
|
|
197
|
+
| `ble_adapter.sh` | bash/zsh + ble.sh | Primary Linux/WSL autocomplete |
|
|
198
|
+
| `powershell_adapter.ps1` | PowerShell + PSReadLine | Primary Windows autocomplete |
|
|
199
|
+
| `powershell_predictor.ps1` | PowerShell 7.2+ | Optional ghost-text predictor |
|
|
200
|
+
| `bash_adapter.sh` / `zsh_adapter.zsh` | — | Deprecated stubs |
|
|
201
|
+
|
|
202
|
+
Requires at least one of `GROQ_API_KEY`, `OPENROUTER_API_KEY`, or `XAI_API_KEY` for AI annotations and consequence previews. Instant catastrophic checks still use local rules.
|
|
203
|
+
|
|
204
|
+
## CLI
|
|
205
|
+
|
|
206
|
+
| Command | Description |
|
|
207
|
+
|---------|-------------|
|
|
208
|
+
| `sm install` | Install shell hooks (bash/zsh → ble adapter, PowerShell → PS adapter) |
|
|
209
|
+
| `sm uninstall` | Remove shell hooks |
|
|
210
|
+
| `sm config` | Configure API keys and settings |
|
|
211
|
+
| `sm enable` | Start daemon (autocomplete mode) |
|
|
212
|
+
| `sm disable` | Stop daemon and clean session |
|
|
213
|
+
| `sm status` | Daemon, agents, providers, credentials |
|
|
214
|
+
| `sm --help` | Help |
|
|
215
|
+
| `sm --version` | Version |
|
|
216
|
+
| `sm --no-color <cmd>` | Plain text output |
|
|
217
|
+
|
|
218
|
+
### `sm config` usages
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
sm config # validate existing keys; select provider → paste key
|
|
222
|
+
sm config --show # masked credentials
|
|
223
|
+
sm config provider risk_analysis xai grok-3-mini # set provider role
|
|
224
|
+
sm config cache.max_entries 200 # YAML override (dotted key)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Interactive setup asks you to pick Groq, OpenRouter, or Grok (xAI), then paste the key. Existing keys are checked against the provider API.
|
|
228
|
+
### Exit codes
|
|
229
|
+
|
|
230
|
+
| Code | Meaning |
|
|
231
|
+
|------|---------|
|
|
232
|
+
| 0 | Success |
|
|
233
|
+
| 2 | Usage error |
|
|
234
|
+
| 3 | Temporary error (e.g. interrupt) |
|
|
235
|
+
| 4 | Internal error |
|
|
236
|
+
|
|
237
|
+
## Shell adapters
|
|
238
|
+
|
|
239
|
+
See [Autocomplete features](#autocomplete-features) for behavior. `sm install` copies the ble or PowerShell adapter into `~/.shellmate/adapters/` and appends a source line to your RC / profile.
|
|
240
|
+
|
|
241
|
+
## Architecture
|
|
242
|
+
|
|
243
|
+
### Analysis pipeline
|
|
244
|
+
|
|
245
|
+
Defined in `shellmate/orchestration/analysis_graph.py` (LangGraph `StateGraph`):
|
|
246
|
+
|
|
247
|
+
```mermaid
|
|
248
|
+
flowchart TD
|
|
249
|
+
START([start]) --> sanitize --> parse --> command_chain --> rules --> cache
|
|
250
|
+
cache -->|early exit| format
|
|
251
|
+
cache -->|needs AI| supervisor
|
|
252
|
+
supervisor -->|gather context| context_worker
|
|
253
|
+
supervisor -->|env only| env_context
|
|
254
|
+
context_worker --> risk_analyzer
|
|
255
|
+
env_context --> risk_analyzer
|
|
256
|
+
risk_analyzer --> consequence_builder --> remediation --> command_guide --> format
|
|
257
|
+
format --> query
|
|
258
|
+
query --> END([end])
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
| Node | Role |
|
|
262
|
+
|------|------|
|
|
263
|
+
| `sanitize` / `parse` | Typo / syntax checks; tokenize |
|
|
264
|
+
| `command_chain` | Multi-step / chain pattern detection |
|
|
265
|
+
| `rules` | YAML rules under `shellmate/rules/definitions/` |
|
|
266
|
+
| `cache` | Exact-match in-memory cache (no FAISS) |
|
|
267
|
+
| `supervisor` | Groq (or heuristic) decides context needs |
|
|
268
|
+
| `context_worker` / `env_context` | Parallel agent queries or env-only path |
|
|
269
|
+
| `risk_analyzer` | Groq risk assessment |
|
|
270
|
+
| `consequence_builder` | Structured consequence preview |
|
|
271
|
+
| `remediation` | OpenRouter safer alternatives |
|
|
272
|
+
| `command_guide` | Groq “what you meant” guide |
|
|
273
|
+
| `format` / `query` | Final payload; optional `[?…]` query handling |
|
|
274
|
+
|
|
275
|
+
**Early exits** (skip AI): sanitizer correction, high-confidence rule match, cache hit.
|
|
276
|
+
|
|
277
|
+
### Agents (daemon)
|
|
278
|
+
|
|
279
|
+
Started with `sm enable`:
|
|
280
|
+
|
|
281
|
+
| Agent | Purpose |
|
|
282
|
+
|-------|---------|
|
|
283
|
+
| Watcher | OS, shell, git, tech-stack snapshot |
|
|
284
|
+
| Librarian | Project file index + search |
|
|
285
|
+
| Environment | Environment / staging signals |
|
|
286
|
+
| CommandChain | Chain-pattern analysis |
|
|
287
|
+
| Query | Answers `[?…]` queries |
|
|
288
|
+
|
|
289
|
+
Repomix-style pack search runs alongside Librarian in the context worker when needed.
|
|
290
|
+
|
|
291
|
+
### Providers
|
|
292
|
+
|
|
293
|
+
| Stage | Default | Fallback |
|
|
294
|
+
|-------|---------|----------|
|
|
295
|
+
| Supervisor / risk / guide | Groq | Grok (xAI) / heuristic |
|
|
296
|
+
| Remediation | OpenRouter | Grok (xAI) / Groq guide / generic text |
|
|
297
|
+
|
|
298
|
+
Configure **at least one** of Groq, OpenRouter, or Grok (xAI). Groq covers risk analysis, supervisor routing, and command guide; OpenRouter covers remediation; xAI can cover both risk and remediation. Instant catastrophic gating still uses local rules either way.
|
|
299
|
+
## Configuration
|
|
300
|
+
|
|
301
|
+
### Directories
|
|
302
|
+
|
|
303
|
+
| Purpose | Linux / macOS | Windows |
|
|
304
|
+
|---------|---------------|---------|
|
|
305
|
+
| Config + `.env` | `~/.config/shellmate` | `%APPDATA%\ShellMate` |
|
|
306
|
+
| State / sessions / logs | `~/.local/state/shellmate` | `%LOCALAPPDATA%\ShellMate` |
|
|
307
|
+
| Cache dir | `~/.cache/shellmate` | `%LOCALAPPDATA%\ShellMate\cache` |
|
|
308
|
+
| Installed adapters | `~/.shellmate/adapters/` | `%USERPROFILE%\.shellmate\adapters\` |
|
|
309
|
+
|
|
310
|
+
Credentials file: `<config_dir>/.env` (permissions restricted on Unix).
|
|
311
|
+
|
|
312
|
+
### Environment variables
|
|
313
|
+
|
|
314
|
+
| Variable | Required | Purpose |
|
|
315
|
+
|----------|----------|---------|
|
|
316
|
+
| `GROQ_API_KEY` | At least one of Groq / OpenRouter / xAI | Risk analysis, supervisor, command guide |
|
|
317
|
+
| `OPENROUTER_API_KEY` | At least one of Groq / OpenRouter / xAI | Remediation alternatives |
|
|
318
|
+
| `XAI_API_KEY` | At least one of Groq / OpenRouter / xAI | Risk analysis and remediation via Grok |
|
|
319
|
+
| `CONTEXT7_API_KEY` | No | Optional docs lookup |
|
|
320
|
+
| `GROQ_SUPERVISOR_MODEL` | No | Override supervisor model (default `qwen/qwen3.8-27b`) |
|
|
321
|
+
| `XAI_MODEL` | No | Override Grok model (default `grok-3-mini`) |
|
|
322
|
+
|
|
323
|
+
Optional YAML overrides live in `<config_dir>/config.yaml`.
|
|
324
|
+
|
|
325
|
+
## Requirements
|
|
326
|
+
|
|
327
|
+
- Python 3.10+
|
|
328
|
+
- ble.sh (Linux/WSL) or PowerShell + PSReadLine (Windows)
|
|
329
|
+
- At least one of `GROQ_API_KEY`, `OPENROUTER_API_KEY`, or `XAI_API_KEY` (Groq + OpenRouter recommended for full risk + remediation)
|
|
330
|
+
|
|
331
|
+
### Dependencies (authoritative: `pyproject.toml`)
|
|
332
|
+
|
|
333
|
+
- `click`, `rich`, `pyyaml` — CLI / UI
|
|
334
|
+
- `langgraph`, `langchain-core` — orchestration
|
|
335
|
+
- `groq`, `openai`, `aiohttp` — providers
|
|
336
|
+
- `psutil`, `watchdog` — runtime monitoring
|
|
337
|
+
- `numpy` — declared runtime dependency
|
|
338
|
+
|
|
339
|
+
## Development
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
git clone https://github.com/sayan-does/shellmate.git
|
|
343
|
+
cd shellmate
|
|
344
|
+
pip install -e ".[dev]"
|
|
345
|
+
python -m build
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
CI builds and smoke-tests the wheel on Python 3.10–3.12. Publishing runs on `v*` tags via Trusted Publishing (`.github/workflows/publish.yml`).
|
|
349
|
+
|
|
350
|
+
## License
|
|
351
|
+
|
|
352
|
+
MIT
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
shellmate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
shellmate/adapters/__init__.py,sha256=4gnk5hxRGFfKS9NM0oHVFPczZe7wK-4pu7pVHDlhqWc,2292
|
|
3
|
+
shellmate/adapters/bash_adapter.sh,sha256=8n7DeBS_vy1_dwTmulY3wvsqhUEMYNy8Huz4gUh771M,312
|
|
4
|
+
shellmate/adapters/ble_adapter.sh,sha256=tBgsJmVDbFfIKtxwB8bx32W0lh1ybWEPxySTr09TLjk,11268
|
|
5
|
+
shellmate/adapters/powershell_adapter.ps1,sha256=4ngc0fFWfa46b5sOB5CPYzX5iPmMoAiect5KtPPmkzE,15782
|
|
6
|
+
shellmate/adapters/powershell_predictor.ps1,sha256=W3NAsqYI0gOQ-qyMAgplfgTz0VxpsWBf4MTNTHh1zWU,4136
|
|
7
|
+
shellmate/adapters/zsh_adapter.zsh,sha256=NBqP4d0JxkjlyAbRt95JqNe99o3YSHcT18R_nX2qeVg,342
|
|
8
|
+
shellmate/agents/__init__.py,sha256=L1p1AT5XqnijplQv23G4OrzyAGlGTGfVX4StsNj_6Cc,515
|
|
9
|
+
shellmate/agents/base.py,sha256=vfwvln6P2_qk054udxf0jGE921mMOxZJh0OjBYCH4JA,8140
|
|
10
|
+
shellmate/agents/chain_patterns.yaml,sha256=Qh_md7liAWdtC-Tk3AbxCGG1pz9xRcxeavVWBH66nRk,2752
|
|
11
|
+
shellmate/agents/command_chain.py,sha256=CW98s7Y1CtjvcOAA6D9yAS7qzLhWWq3ECs96-ST74Yk,10739
|
|
12
|
+
shellmate/agents/context_gatherer.py,sha256=mcdCoo6IspFqmGt4fGIgvA5-u5hoOFw9Mol1w5z9clo,5877
|
|
13
|
+
shellmate/agents/environment.py,sha256=BxKhIpJ_Zj2pFBO-8u-132y05-4y1oC3n8ilGRuvaXs,12510
|
|
14
|
+
shellmate/agents/librarian.py,sha256=SnJOHfuO-groBLKwKickiVNMEp9LUSku82E2l_CAjl0,17322
|
|
15
|
+
shellmate/agents/query.py,sha256=qFVVaVGupS_pd9bqSiMRct_3dnFUoHtLIChxcEuysj0,14752
|
|
16
|
+
shellmate/agents/repomix_backend.py,sha256=sJtYz4BVz_OjZzA88s8E-OWXUlKY020KJo0w32gxUTE,6484
|
|
17
|
+
shellmate/agents/watcher.py,sha256=M5KqrDmGk4WkA6zbZ_ByEq6_LU6GfJYdZbugNjRZZto,9363
|
|
18
|
+
shellmate/cache/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
+
shellmate/cache/semantic_cache.py,sha256=d9Je0gRFW1ASau8xemGBbbJfxk08C3QkIl_HtCIIMWI,937
|
|
20
|
+
shellmate/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
|
+
shellmate/cli/main.py,sha256=_gljAQLkDgYgukkyYNVjjow7d-FIOtWbFufnFhsNr7A,3815
|
|
22
|
+
shellmate/cli/parser.py,sha256=Lh3mo6aHwn6ISmXoFKMfROF--tSe7Rpig_3rpjTGgi0,5747
|
|
23
|
+
shellmate/cli/version.py,sha256=qckxTKowVHHdLYuDeVRWcIaYVKeKZEw0YwwUIm6QtNY,18
|
|
24
|
+
shellmate/cli/commands/__init__.py,sha256=MFJrPc6Yrhe6eFxTAJI8dnOnqUdILoh3JnBRCevVOwU,1032
|
|
25
|
+
shellmate/cli/commands/analyze.py,sha256=t5BxxGBrPizJvgsbrvOpsF327DxgunoN7QefaBXIc3k,270
|
|
26
|
+
shellmate/cli/commands/config.py,sha256=DI22jVKEwaFLqQIA3ps-ZFRz6lNML_DYBWBtyh70ISA,10168
|
|
27
|
+
shellmate/cli/commands/configure.py,sha256=KqHFlA_U1sW5-LhYpATErhDVXZjwV16LRcj_-DHm7sE,4179
|
|
28
|
+
shellmate/cli/commands/disable.py,sha256=-xqpNGERQjKetwx9wERtYrpxdqqXhblLc9cLfGjW32o,268
|
|
29
|
+
shellmate/cli/commands/enable.py,sha256=dNHMdAf-8_GHYoRDe6B8CaIVvAxFSBstADL1L4i38qU,1604
|
|
30
|
+
shellmate/cli/commands/init.py,sha256=lXX9TqnpVDfsHUqKDAzczgPVqgsoPrJWnvzYo5bsZhY,13740
|
|
31
|
+
shellmate/cli/commands/install.py,sha256=4DTTG7xwedETAIVydLSQcR99YHvT82zY0cTC7SLxoM4,9168
|
|
32
|
+
shellmate/cli/commands/migrate.py,sha256=WUjyCjWXuxYCER8IesSPXnVMdlmiYR1nUJm2kUQYC2A,5107
|
|
33
|
+
shellmate/cli/commands/status.py,sha256=m8QHQaKOfx1GJaFeU-6sJQeEojRYdJYF5bbWxNrKHbQ,1008
|
|
34
|
+
shellmate/cli/commands/uninstall.py,sha256=gZ6hyzFa22hjFOaN-OpOcijWgPMIpot1Quc9PGWi_sk,2385
|
|
35
|
+
shellmate/completion/__init__.py,sha256=YIa-Yd7bfwJv5GLDqMFY2nw5kzOfsNSsm5mihhVsQz0,148
|
|
36
|
+
shellmate/completion/bash_adapter.py,sha256=AXYpTcq5UdoPoUgkk-u4poIqw8SFVSPCYJtknbKgLhU,4829
|
|
37
|
+
shellmate/config/__init__.py,sha256=U3cXQSYsPuxDynOHfH5v32zVrWo9MinDXNlQSVIf5i0,900
|
|
38
|
+
shellmate/config/credentials.py,sha256=Nr4HXgG-a8oihSL4uGnrKfjDzE9rC67KFBn6lehdRt4,3634
|
|
39
|
+
shellmate/config/defaults.py,sha256=iMRxqfQndH0m36tW9SDjT_DJi77Nel8FiStaldOWX_o,2932
|
|
40
|
+
shellmate/config/manager.py,sha256=8XY-QEwC6CrFgJ7WnRezOHhl-bT4I7JZ1c_b3Y8Gf1Q,2801
|
|
41
|
+
shellmate/config/paths.py,sha256=EfeCLtTku_SZn4pw22Uks1V06-HoGQfU4KTaeMHc298,2299
|
|
42
|
+
shellmate/config/secrets.py,sha256=GkZnM22SC_0NpTaie0RmbuG_PcZuCciH3MzQk1DHB7Q,2649
|
|
43
|
+
shellmate/daemon/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
44
|
+
shellmate/daemon/lifecycle.py,sha256=UK6PTuIklIAuC2Iy8ycxHP7ZAtWPiKhMBiu31mw3HWs,10269
|
|
45
|
+
shellmate/daemon/observability.py,sha256=BQs_xob4OHYT_NWIX6E4twi-kvBPvWVT9oG8tRuQTFA,2175
|
|
46
|
+
shellmate/daemon/pipeline.py,sha256=x-mlr01vuqT-cXSzFUq5Fm_e1eOIn8R7NVKXcwC8qFQ,3615
|
|
47
|
+
shellmate/daemon/server.py,sha256=4BMe2mU7upgnf-WyMYLMhfg9RltiHiHZlFAXhItcVTA,24196
|
|
48
|
+
shellmate/daemon/session.py,sha256=xPijQIdoIG6ynsHaUL1sUnVLywqLYtvuQBk1WuBfX8w,4556
|
|
49
|
+
shellmate/daemon/startup_ui.py,sha256=eQwVmIrTRT9FJ3HVgB0o4ToWz4Mx9MbJXxMzAixT3fg,1488
|
|
50
|
+
shellmate/environment/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
51
|
+
shellmate/environment/detector.py,sha256=EMIKgaqoAcuibDzQSFRM98OpYTDl4tCzPI5uKpT8vGI,3315
|
|
52
|
+
shellmate/ipc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
53
|
+
shellmate/ipc/client.py,sha256=4tsEyTCLa2OCfL0dQDXMkcLQeG5Y_rqi9fcKIW5twUM,6914
|
|
54
|
+
shellmate/ipc/ps_client.py,sha256=QpEQV93oWj3e-aOlcHtvmSBIp702H8hw3p7pHDT3pas,7458
|
|
55
|
+
shellmate/orchestration/__init__.py,sha256=14x2HJSxgRBrO7tUI4W6-kFlF87VymM2a0fFNF1l6Gk,168
|
|
56
|
+
shellmate/orchestration/analysis_graph.py,sha256=uLKzKvrIQ72Y-yukCqazA2Vb53I2T8EP5P84O07_ReY,47126
|
|
57
|
+
shellmate/orchestration/state.py,sha256=zNMkdOtvxroYBJ5tpj-oYWpf0OjDXzkyZCnbVymAXLk,1509
|
|
58
|
+
shellmate/parser/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
59
|
+
shellmate/parser/command_parser.py,sha256=ck3sYbrjHEYedgYjuIoDvJYHuMGPiR9ia3ltiXW5JIM,4344
|
|
60
|
+
shellmate/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
61
|
+
shellmate/plugins/base.py,sha256=Fbl-Dyx7JPE0Hj2g9XI9U7jlaGzdqxbTKBk1Q9Vkt64,1785
|
|
62
|
+
shellmate/plugins/loader.py,sha256=jhd6utSiyEgRzXpn8lIZFUMMv_H5fTX-XNOX0-icLm8,1338
|
|
63
|
+
shellmate/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
64
|
+
shellmate/providers/base.py,sha256=FJLwM1Room8BSKo1GCY-aP5wqBPYJ_4vZJldq_nOBKg,3372
|
|
65
|
+
shellmate/providers/groq_command_guide.py,sha256=qrvPE-KCV3mh8RzODW6rodDX3qo4N6IcdnUBzLh9yj0,4067
|
|
66
|
+
shellmate/providers/groq_provider.py,sha256=MSZxZkFfF-8zsniJ2Av6v6eKxy2fiRxbd3HSUMorY4E,4808
|
|
67
|
+
shellmate/providers/groq_supervisor.py,sha256=TVCVB0xEkexIWH9RPKIkXPi8CEmOT8OC1tD0kYfixn0,2527
|
|
68
|
+
shellmate/providers/openrouter_provider.py,sha256=L1_8BtOVtuCV2SFRt08x2UoIKwpGytvVcW8f1blLcIo,5745
|
|
69
|
+
shellmate/providers/router.py,sha256=p3Hntwz5YKnLLn76ykIpJMYRUHYpOdUlMvQVo2W3wIg,9163
|
|
70
|
+
shellmate/providers/validate_keys.py,sha256=TcyJWhjh2S5oCGt7GX4nR8qPrRl4v_sCE115w21qBKE,3335
|
|
71
|
+
shellmate/providers/xai_provider.py,sha256=T6IvRXe_uAIG00LNZCqpa4s4DSTbm3gUama1FvcaZt8,5487
|
|
72
|
+
shellmate/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
73
|
+
shellmate/rules/catastrophic.yaml,sha256=prnRtEHyNCvAHwbY4lqBJCxRgflKiD3p871JlBMNSaE,2346
|
|
74
|
+
shellmate/rules/catastrophic_matcher.py,sha256=VLbzHjt-eUl-BsbjLpiRM4FBpKstqo6D0WHA3Lh9_vI,6212
|
|
75
|
+
shellmate/rules/engine.py,sha256=grDqUdCtm5K_IcyrJ6GGURoPoSu52EMVWpPzbajasOA,7068
|
|
76
|
+
shellmate/rules/definitions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
77
|
+
shellmate/rules/definitions/file_deletion.yaml,sha256=TC78X-j_VF9N3jwJ-6XFhQL81uatZPIrCOnOiojjqzI,1397
|
|
78
|
+
shellmate/rules/definitions/filesystem.yaml,sha256=fDKNf4MIBCKb7sXdpT7W0X8Ld_mUq5KTs386NWvG-so,1205
|
|
79
|
+
shellmate/rules/definitions/network_execution.yaml,sha256=34B982dCNW0qMZFXBiZrNk_Bg4ALQUzPnll_bYUHbqo,1357
|
|
80
|
+
shellmate/rules/definitions/permissions.yaml,sha256=4XlweCN9YcXYoAa79t5xg1Kb1JoaJLm1xtg7b1Ahp3M,1364
|
|
81
|
+
shellmate/rules/definitions/process_control.yaml,sha256=LAuqL_mw5O_3F1sBx_vBf2snpmkhfh9CqEdEqTBCWKk,1027
|
|
82
|
+
shellmate/rules/definitions/system_destruction.yaml,sha256=_iSmSwTnbWEmBcteuP6Gw2-gyXPSe3SW2oGnDLEz6X4,1719
|
|
83
|
+
shellmate/sanitizer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
84
|
+
shellmate/sanitizer/typo_detector.py,sha256=ZBhOzB7ZSv4hctbu60tu_iBMjcBIP4TLjQ20aoCLVVQ,2957
|
|
85
|
+
shellmate/ui/__init__.py,sha256=i8MvY7xFXCg9WRXFJcny3iiNBUnHoNW8U82t4tjqSrs,252
|
|
86
|
+
shellmate/ui/analysis.py,sha256=U5WrGXSrBfR2Q_xOZ_nxi6frouTU6CrmHu-t7afLpmc,5905
|
|
87
|
+
shellmate/ui/annotations.py,sha256=ztf3PlPcCeainX4Hi7qQW30pJ9T1zY5aaxC6IlyHwoI,6914
|
|
88
|
+
shellmate/ui/banner.py,sha256=gOT8hYnO6pRqPW_tWx5KPInw9TOcByLthdmKz8uneaI,1752
|
|
89
|
+
shellmate/ui/progress.py,sha256=5rLtBR4VM9CUs7phTz6VJqVSIou0hGTk9YDRE-E0nvc,4020
|
|
90
|
+
shellmate/ui/status.py,sha256=EmsWCd5R_h-rQ9nApBBUFPhhZurfKoXY3_te4h7LIJo,134
|
|
91
|
+
shellmate/ui/runtime/__init__.py,sha256=G2tRJWagzRJSUYRVmyb0cBVxPr5XKwoXibVmSdXkA4Y,448
|
|
92
|
+
shellmate/ui/runtime/console_factory.py,sha256=eg0t5Xek599qtDEGuWSk8dvyehbef2KUjs8uhvp-fVI,1745
|
|
93
|
+
shellmate/ui/runtime/live_scene.py,sha256=nzEFAK-RhP5CPrJ8DdBy9PHCKtLaqSpTb1QkaCMw3e0,3674
|
|
94
|
+
shellmate/ui/runtime/motion_policy.py,sha256=t5tvqv72LSLbqxxQd2GARg7GvoRggcjPu6kAvvVpq6o,2254
|
|
95
|
+
shellmate/ui/runtime/tokens.py,sha256=J9C6jq-7uNOn7v3gQLBBtJ4sOEnJJFUoMGEMdIPf7Dk,1127
|
|
96
|
+
shellmate/ui/scenes/__init__.py,sha256=Pn3xBCJgxweVk9TpT7c9J1-b-9wA1eDrDj99l3IyC0s,642
|
|
97
|
+
shellmate/ui/scenes/enable.py,sha256=wrKSyGg_aSU3anvCAMPQOBq9E13KDCtQT3GRDbCSalA,11087
|
|
98
|
+
shellmate/ui/scenes/help.py,sha256=ozg_JosfzpA4cNCSWHazETiRuU9gPO_-Y04arYmgUUU,1904
|
|
99
|
+
shellmate/ui/scenes/stages.py,sha256=pK396uMatWxJm_XbWCJTWsvx7W6Sx0s7G95S3ec1ffQ,4048
|
|
100
|
+
shellmate/ui/scenes/status.py,sha256=nC-wAC8cdE3UC2QXeK9zD8fOAMpdLogHK67h74a9Nek,6427
|
|
101
|
+
shellmate_cli-3.0.0.dist-info/licenses/LICENSE,sha256=_eDrSi0nYhgVjipoIJoiUEdbARagURo6nVbTGBzqvD4,1079
|
|
102
|
+
shellmate_cli-3.0.0.dist-info/METADATA,sha256=MjD_jybwTY6cc6eqjxQAgk-x0Qp4Ocdi0QiK-D72pDg,12187
|
|
103
|
+
shellmate_cli-3.0.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
104
|
+
shellmate_cli-3.0.0.dist-info/entry_points.txt,sha256=lBMog9g17_P4iSXr6Akfg_QTVzswLWXUeGnuq66Wwhw,83
|
|
105
|
+
shellmate_cli-3.0.0.dist-info/top_level.txt,sha256=0htuoy1ZSdVSt_0l2mO-mPPvSp2veo6dbr3h0K_AmIw,10
|
|
106
|
+
shellmate_cli-3.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 ShellMate Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
shellmate
|